[
  {
    "path": ".github/ISSUE_TEMPLATE/add-to-website.yml",
    "content": "---\nname: \"🌐 Add a project to the list of project using Ace on its website.\"\ndescription: Add a project to the list of projects using Ace, displayed on the website.\ntitle: \"Add project (project name) to the list of projects using Ace on its website\"\nlabels: [website, needs-triage]\nassignees: []\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        The fastest way to get your project to be displayed on the website is to create a PR. \n        Examples: https://github.com/ajaxorg/ace/pull/5014, https://github.com/ajaxorg/ace/pull/5222.\n        If for any reason creating a PR is not an option for you, please proceed with filling out this issue. Thanks!\n  - type: input\n    id: name\n    attributes:\n      label: Project name\n      description: A name of the project to be used on Ace website.\n    validations:\n      required: true\n  - type: input\n    id: project-link\n    attributes:\n      label: Project link\n      description: A link to the project's website.\n    validations:\n      required: true\n  - type: input\n    id: logo-link\n    attributes:\n      label: Logo link\n      description: |\n        A link to the logo image to be used on the website for the project. If not provided, only the name of the project will be displayed.\n\n        By submitting this link, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.\n    validations:\n      required: false\n  - type: textarea\n    id: info\n    attributes:\n      label: Additional information\n      description: Any additional information you would like to share.\n    validations:\n      required: false\n  - type: checkboxes\n    id: ack\n    attributes:\n      label: Acknowledgements\n      options:\n        - label: I may be able to implement this request.\n          required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "---\nname: \"🐞 Bug Report\"\ndescription: Report a bug\ntitle: \"(module name): (short issue description)\"\nlabels: [bug, needs-triage]\nassignees: []\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Describe the bug\n      description: What is the problem? A clear and concise description of the bug.\n    validations:\n      required: true\n  - type: textarea\n    id: expected\n    attributes:\n      label: Expected Behavior\n      description: |\n        What did you expect to happen?\n    validations:\n      required: true\n  - type: textarea\n    id: current\n    attributes:\n      label: Current Behavior\n      description: |\n        What actually happened?\n\n        Please include full errors, uncaught exceptions, stack traces, and relevant logs.\n    validations:\n      required: true\n  - type: textarea\n    id: reproduction\n    attributes:\n      label: Reproduction Steps\n      description: |\n        Provide a self-contained, concise snippet of code that can be used to reproduce the issue.\n        For more complex issues provide a repo with the smallest sample that reproduces the bug.\n\n        Avoid including business logic or unrelated code, it makes diagnosis more difficult.\n    validations:\n      required: true\n  - type: textarea\n    id: solution\n    attributes:\n      label: Possible Solution\n      description: |\n        Suggest a fix/reason for the bug\n    validations:\n      required: false\n  - type: textarea\n    id: context\n    attributes:\n      label: Additional Information/Context\n      description: |\n        Anything else that might be relevant for troubleshooting this bug. Providing context helps us come up with a solution that is most useful in the real world.\n    validations:\n      required: false\n\n  - type: input\n    id: ace-version\n    attributes:\n      label: Ace Version / Browser / OS / Keyboard layout\n      description: Information about software versions and keyboard configuration that can be relevant for reproducing the issue\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "---\nblank_issues_enabled: false\ncontact_links:\n  - name: 🤔 General Question\n    url: https://github.com/ajaxorg/ace/discussions/categories/q-a\n    about: Please ask and answer questions as a discussion thread\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.yml",
    "content": "---\nname: \"📕 Documentation Issue\"\ndescription: Report an issue in the documentation\ntitle: \"(short issue description)\"\nlabels: [documentation, needs-triage]\nassignees: []\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Describe the issue\n      description: A clear and concise description of the issue.\n    validations:\n      required: true\n\n  - type: textarea\n    id: links\n    attributes:\n      label: Links\n      description: |\n        Include links to affected documentation page(s).\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "content": "---\nname: 🚀 Feature Request\ndescription: Suggest an idea for this project\ntitle: \"(short issue description)\"\nlabels: [feature-request, needs-triage]\nassignees: []\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Describe the feature\n      description: A clear and concise description of the feature you are proposing.\n    validations:\n      required: true\n  - type: textarea\n    id: use-case\n    attributes:\n      label: Use Case\n      description: |\n        Why do you need this feature? For example: \"I'm always frustrated when...\"\n    validations:\n      required: true\n  - type: textarea\n    id: solution\n    attributes:\n      label: Proposed Solution\n      description: |\n        Suggest how to implement the addition or change. Please include prototype/workaround/sketch/reference implementation.\n    validations:\n      required: false\n  - type: textarea\n    id: other\n    attributes:\n      label: Other Information\n      description: |\n        Any alternative solutions or features you considered, a more detailed explanation, stack traces, related issues, links for context, etc.\n    validations:\n      required: false\n  - type: checkboxes\n    id: ack\n    attributes:\n      label: Acknowledgements\n      options:\n        - label: I may be able to implement this feature request\n          required: false\n        - label: This feature might incur a breaking change\n          required: false\n  - type: input\n    id: ace-version\n    attributes:\n      label: ACE version used\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "*Issue #, if available:*\n\n*Description of changes:*\n\n\nBy submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.\n\nPull Request Checklist:\n* [ ] No backwards incompatible changes were made to Ace's public interface which is defined through the main typings file (`ace.d.ts`) and its references:\n    * https://github.com/ajaxorg/ace/blob/master/ace.d.ts \n    * https://github.com/ajaxorg/ace/blob/master/ace-modes.d.ts \n    * https://github.com/ajaxorg/ace/blob/master/ace-extensions.d.ts\n\n"
  },
  {
    "path": ".github/workflows/backwards-compatibility-commenter.yml",
    "content": "name: Comments for ensuring backward compatibility\n\non:\n  pull_request_target:\n    paths:\n      - 'ace.d.ts'\n      - 'ace-modes.d.ts'\n      - 'ace-extensions.d.ts'\n\npermissions:\n  pull-requests: write\n\njobs:\n  comment:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Comment on PR\n        uses: peter-evans/create-or-update-comment@v1\n        with:\n          issue-number: ${{ github.event.pull_request.number }}\n          body: |\n            One of the public type files has been updated, plase make sure there are no backwards incompatible changes done in the PR.\n          token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/close-stale-issues.yml",
    "content": "name: \"Close Stale Issues\"\n\n# Controls when the action will run.\non:\n  workflow_dispatch:\n  schedule:\n    - cron: \"0 */4 * * *\"\n\njobs:\n  cleanup:\n    permissions:\n      issues: write\n      contents: read\n      pull-requests: write\n    runs-on: ubuntu-latest\n    name: Stale issue job\n    steps:\n      - uses: aws-actions/stale-issue-cleanup@v5\n        with:\n          issue-types: issues\n          # Setting messages to an empty string will cause the automation to skip\n          # that category\n          ancient-issue-message: This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.\n          stale-issue-message: This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.\n\n          # These labels are required\n          stale-issue-label: closing-soon\n          exempt-issue-labels: no-autoclose, p1\n          response-requested-label: response-requested\n\n          # Don't set closed-for-staleness label to skip closing very old issues\n          # regardless of label\n          closed-for-staleness-label: closed-for-staleness\n\n          # Issue timing\n          days-before-stale: 7\n          days-before-close: 2\n          days-before-ancient: 365\n\n          # If you don't want to mark a issue as being ancient based on a\n          # threshold of \"upvotes\", you can set this here. An \"upvote\" is\n          # the total number of +1, heart, hooray, and rocket reactions\n          # on an issue.\n          minimum-upvotes-to-exempt: 5\n\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n          loglevel: DEBUG\n          # Set dry-run to true to not perform label or close actions.\n          dry-run: false\n"
  },
  {
    "path": ".github/workflows/issue-reprioritization.yml",
    "content": "name: issue-reprioritization\non:\n  schedule:\n    - cron: \"0 0 * * 0\"\n\njobs:\n  issue-reprioritization:\n    permissions:\n      issues: write\n    runs-on: ubuntu-latest\n    steps:\n      - uses: kaizencc/issue-reprioritization-manager@main\n        id: reprioritization-manager\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          original-label: p2\n          new-label: p1\n          reprioritization-threshold: 5\n      - uses: kaizencc/pr-triage-manager@main\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          on-pulls: ${{ steps.reprioritization-manager.outputs.linked-pulls }}\n"
  },
  {
    "path": ".github/workflows/link-comment.yml",
    "content": "name: Update PR Description\n\non:\n  pull_request_target: # use this trigger to run on external pull requests too\n    types: [opened, synchronize]\n\njobs:\n  update-description:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    steps:\n      - name: Update PR description\n        uses: actions/github-script@v6\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          script: |\n            const prNumber = context.payload.pull_request.number;\n            const owner = context.payload.pull_request.head.repo.owner.login;\n            const repo = context.payload.pull_request.head.repo.name;\n            const commit = context.payload.pull_request.head.sha;\n            const link = `https://raw.githack.com/${owner}/${repo}/${commit}/kitchen-sink.html`;\n\n            const { data: pullRequest } = await github.rest.pulls.get({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              pull_number: prNumber,\n            });\n\n            if (!pullRequest.body.includes(link)) {\n              const updatedBody = `${pullRequest.body}\\n\\n[Open kitchen-sink @ ${commit}](${link})`;\n\n              await github.rest.pulls.update({\n                owner: context.repo.owner,\n                repo: context.repo.repo,\n                pull_number: prNumber,\n                body: updatedBody,\n              });\n            }\n"
  },
  {
    "path": ".github/workflows/nodejs.yml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\npermissions:\n  contents: read # to fetch code (actions/checkout)\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [16.x]\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: Fetch the master branch\n      run: git fetch origin HEAD:refs/remotes/origin/HEAD --depth 1\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v1\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm i\n    - run: npm run cover-json && mv ./coverage/coverage-final.json ./coverage/coverage.json\n    - run: | \n        # eslint\n        set -x;\n        git status;\n        git checkout HEAD -- package.json;\n        changes=$(git diff --name-only origin/HEAD --no-renames --diff-filter=ACMR);\n        if [ \"$changes\" == \"\" ]; then\n            echo \"checking all files\";\n            node node_modules/eslint/bin/eslint \"lib/ace/**/*.js\";\n        else\n            jsChanges=$(echo \"$changes\" | grep -P '.js$' || :);\n            if [ \"$jsChanges\" == \"\" ]; then\n                echo \"nothing to check\";\n            else\n                echo \"checking $jsChanges\";\n                node node_modules/eslint/bin/eslint $jsChanges;\n            fi\n        fi\n    - run: | \n        # check types\n        set -x;\n        npx tsc -v;\n        npm run update-types;\n        git diff --color --exit-code ./ace*d.ts;\n        npm run typecheck;\n        node_modules/.bin/tsc --noImplicitAny --strict --noUnusedLocals --noImplicitReturns --noUnusedParameters --noImplicitThis ace.d.ts;\n    - run: | \n        # test-npm-package\n        set -x;\n        ./tool/test-npm-package.sh\n    # upload to codecov\n    - uses: codecov/codecov-action@v3\n      with:\n        token: d8edca4b-8e97-41e5-b54e-34c7cf3b2d47\n        file: ./coverage/coverage.json\n        flags: unittests\n        name: codecov-umbrella\n        fail_ci_if_error: true\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: Publish to NPM\non:\n  push:\n    tags:\n      - v*\n  workflow_dispatch:\npermissions:\n  id-token: write  # Required for OIDC\n  contents: read # to fetch code (actions/checkout)\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    # Setup .npmrc file to publish to npm\n    - uses: actions/setup-node@v4\n      with:\n        node-version: '24'\n        registry-url: 'https://registry.npmjs.org'\n    - run: npm install\n    - run: npm run test\n    - run: npm publish\n"
  },
  {
    "path": ".gitignore",
    "content": "# Junk that could exist anywhere:\n.DS_Store\n*.swp\n*.tmp\n*~\n\n# Project files that should not be in the repo\n.*\n\\#*\n!/.github\n!/.gitignore\n.*.gz\n*.tmTheme.js\npackage-lock.json\n\n# A handy place to put stuff that git should ignore:\n/coverage\n/ignore/\nnode_modules/\njam/\n* *\n\n.git-ref\nnpm-debug.log\ndeps/\ndist\n\nlib/ace\nstyles"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n\n### [1.43.6](https://github.com/ajaxorg/ace/compare/v1.43.5...v1.43.6) (2026-01-23)\n\n\n### Bug Fixes\n\n* the text completer didn't export its id ([#5847](https://github.com/ajaxorg/ace/issues/5847)) ([b256c10](https://github.com/ajaxorg/ace/commit/b256c10691e6ba9296d18dcdea15441189971d1e))\n\n### [1.43.5](https://github.com/ajaxorg/ace/compare/v1.43.4...v1.43.5) (2025-12-02)\n\n### [1.43.4](https://github.com/ajaxorg/ace/compare/v1.43.3...v1.43.4) (2025-10-17)\n\n\n### Bug Fixes\n\n* Update for compliance with typescript 5.9.2 ([#5855](https://github.com/ajaxorg/ace/issues/5855)) ([6e110b0](https://github.com/ajaxorg/ace/commit/6e110b0061b56b72db7478762036a1ba39251102))\n\n### [1.43.3](https://github.com/ajaxorg/ace/compare/v1.43.2...v1.43.3) (2025-09-02)\n\n\n### Bug Fixes\n\n* firefox textarea autocomplete corruption ([#5860](https://github.com/ajaxorg/ace/issues/5860)) ([23ac02f](https://github.com/ajaxorg/ace/commit/23ac02f7602b84cc4ea30f6ed4f889d3802affde))\n\n### [1.43.2](https://github.com/ajaxorg/ace/compare/v1.43.1...v1.43.2) (2025-07-15)\n\n\n### Features\n\n* Implement text markers ([#5835](https://github.com/ajaxorg/ace/issues/5835)) ([085730f](https://github.com/ajaxorg/ace/commit/085730fff987ec88c2350146f18b42b17532d47f))\n\n### [1.43.1](https://github.com/ajaxorg/ace/compare/v1.43.0...v1.43.1) (2025-07-02)\n\n\n### Bug Fixes\n\n* **a11y:** aria-describedby to gutter elements ([#5838](https://github.com/ajaxorg/ace/issues/5838)) ([bf27c15](https://github.com/ajaxorg/ace/commit/bf27c151685ac486a991a61d67fa04adf8891c76))\n\n### [1.42.1](https://github.com/ajaxorg/ace/compare/v1.42.0...v1.42.1) (2025-06-20)\n\n\n### Features\n\n* Add scroll diff decorators ([#5807](https://github.com/ajaxorg/ace/issues/5807)) ([b45e94c](https://github.com/ajaxorg/ace/commit/b45e94cb92d757b5f09ee0966a764ed0d245ed70))\n\n## [1.42.0](https://github.com/ajaxorg/ace/compare/v1.41.0...v1.42.0) (2025-06-03)\n\n\n### Features\n\n* update mouse selection at user's refresh rate ([#5717](https://github.com/ajaxorg/ace/issues/5717)) ([90d72fc](https://github.com/ajaxorg/ace/commit/90d72fc95ed2a3e35725a39fa2b88c2fe6d0a44c)), closes [#5716](https://github.com/ajaxorg/ace/issues/5716)\n\n\n### Bug Fixes\n\n* editor.completer would init on `enableBasicAutocompletion` option `true` ([#5756](https://github.com/ajaxorg/ace/issues/5756)) ([25a471a](https://github.com/ajaxorg/ace/commit/25a471a3ec0a7c657646a54d034709f0d3283f19))\n* missing type aliases and MarkerGroup in `ace-builds` ([#5782](https://github.com/ajaxorg/ace/issues/5782)) ([b20be1a](https://github.com/ajaxorg/ace/commit/b20be1a4591e1c566fdb0e205a75fa580885e7c6))\n\n### [1.40.2](https://github.com/ajaxorg/ace/compare/v1.40.1...v1.40.2) (2025-05-02)\n\n### [1.40.1](https://github.com/ajaxorg/ace/compare/v1.40.0...v1.40.1) (2025-04-23)\n\n\n### Bug Fixes\n\n* **gutter:** add null check for session.foldWdigets  ([#5801](https://github.com/ajaxorg/ace/issues/5801)) ([6ca40e9](https://github.com/ajaxorg/ace/commit/6ca40e93623ed1d4d04c8ce7ffb45186092c2198))\n\n## [1.40.0](https://github.com/ajaxorg/ace/compare/v1.39.1...v1.40.0) (2025-04-15)\n\n\n### Features\n\n* **gutter:** added keyboard handling for experimental feature custom widgets ([#5796](https://github.com/ajaxorg/ace/issues/5796)) ([8037400](https://github.com/ajaxorg/ace/commit/803740045ca73555b01116b582791fce940cbe00))\n\n### [1.39.1](https://github.com/ajaxorg/ace/compare/v1.39.0...v1.39.1) (2025-03-20)\n\n\n### Features\n\n* Editing is disabled tooltip in readonly mode ([#5771](https://github.com/ajaxorg/ace/issues/5771)) ([1098e53](https://github.com/ajaxorg/ace/commit/1098e5306fdc02e873cdadc85d2e13228abfe80c))\n\n\n### Bug Fixes\n\n* Fix is check in xml FoldMode ([#5752](https://github.com/ajaxorg/ace/issues/5752)) ([810c465](https://github.com/ajaxorg/ace/commit/810c4650288d32b119239f7731a3b3be0c25376c))\n* replace NodeList.foreach with for loop ([#5769](https://github.com/ajaxorg/ace/issues/5769)) ([b3de3c1](https://github.com/ajaxorg/ace/commit/b3de3c1d99540bd94df122cedb7c5e3a792986a7))\n* updateDocTooltip with undefined this.completions ([#5754](https://github.com/ajaxorg/ace/issues/5754)) ([adde072](https://github.com/ajaxorg/ace/commit/adde072dd4810aa8f99bb1e16a6ab7dfc81a6e9d))\n* wrong java keywords ([#5759](https://github.com/ajaxorg/ace/issues/5759)) ([6b4c7a0](https://github.com/ajaxorg/ace/commit/6b4c7a09d844a2e16d664d3e9fbb384b543bcfcb))\n\n## [1.39.0](https://github.com/ajaxorg/ace/compare/v1.38.0...v1.39.0) (2025-02-21)\n\n\n### Features\n\n* Multiline Search Support: line breaks `\\n` ([#5675](https://github.com/ajaxorg/ace/issues/5675)) ([06d51b9](https://github.com/ajaxorg/ace/commit/06d51b9164dc9dc39fbd6df26b7132f4b9580a4c))\n\n\n### Bug Fixes\n\n* check if row is present when setting aria label of popup elements ([#5750](https://github.com/ajaxorg/ace/issues/5750)) ([ff16482](https://github.com/ajaxorg/ace/commit/ff16482101965fc4fce488a61a3cd0f9454d8e87))\n* gutter hover tooltip a11y improvements ([#5747](https://github.com/ajaxorg/ace/issues/5747)) ([fbe3ddc](https://github.com/ajaxorg/ace/commit/fbe3ddccb1248c9f8f4a6524d2ded7235d225b41))\n* narrowing platform to be either win or mac ([#5707](https://github.com/ajaxorg/ace/issues/5707)) ([18cc336](https://github.com/ajaxorg/ace/commit/18cc336187519107f47bb15e989008f48f0b1563))\n* set score completion item when skipfilter true ([#5749](https://github.com/ajaxorg/ace/issues/5749)) ([a27e1e8](https://github.com/ajaxorg/ace/commit/a27e1e8a5d3d912b3b554cd2b5916b58750e8e71))\n\n## [1.38.0](https://github.com/ajaxorg/ace/compare/v1.37.5...v1.38.0) (2025-02-12)\n\n\n### Features\n\n* **popup:** add supporting skipFilter flag for popup item ([#5740](https://github.com/ajaxorg/ace/issues/5740)) ([0db7585](https://github.com/ajaxorg/ace/commit/0db7585ae0ccbd353091426f60ac3d9e53e182c4))\n\n\n### Bug Fixes\n\n* **AcePopup:** fix aria-posinset issue on google chrome ([#5719](https://github.com/ajaxorg/ace/issues/5719)) ([09a0c5a](https://github.com/ajaxorg/ace/commit/09a0c5a11106754916a4fc324a35e8daf84055ba))\n* calling setMode just before destroy causes error reading getLength ([#5727](https://github.com/ajaxorg/ace/issues/5727)) ([62b973e](https://github.com/ajaxorg/ace/commit/62b973ef2247debdd51cf6a41a3b24b97277efdb))\n* highlight indent guides with wrapped lines ([#5621](https://github.com/ajaxorg/ace/issues/5621)) ([77b9fe1](https://github.com/ajaxorg/ace/commit/77b9fe1bc0b10b4c3fb2780d65f9d256d60634ce))\n* improve aria attributes of popup elements ([#5739](https://github.com/ajaxorg/ace/issues/5739)) ([09fba2e](https://github.com/ajaxorg/ace/commit/09fba2e7347cd499c979e53ec7a8d8ee1fd48918))\n* types for setTimeout/setInterval calls ([#5726](https://github.com/ajaxorg/ace/issues/5726)) ([9a76656](https://github.com/ajaxorg/ace/commit/9a76656acc9528a4a2e92a3b72c4d6598d3a0a8c))\n* **VirtualRenderer:** fix scrollbar overlap on autocompletion ([#5713](https://github.com/ajaxorg/ace/issues/5713)) ([5acea6d](https://github.com/ajaxorg/ace/commit/5acea6d9200f4ca0c8495350cda6e41e8351913f))\n* wrong type of paste event and missing types for themelist extension ([#5725](https://github.com/ajaxorg/ace/issues/5725)) ([a4b9d2d](https://github.com/ajaxorg/ace/commit/a4b9d2d91a2be841320030d93afde46ae723c8c3))\n\n### [1.37.5](https://github.com/ajaxorg/ace/compare/v1.37.4...v1.37.5) (2025-01-16)\n\n\n### Bug Fixes\n\n* update aria-roledescription gutter ([#5718](https://github.com/ajaxorg/ace/issues/5718)) ([7ae3a4c](https://github.com/ajaxorg/ace/commit/7ae3a4c5f6f6e9bd31ae491f1fcef71fc5ae62fa))\n\n### [1.37.4](https://github.com/ajaxorg/ace/compare/v1.37.3...v1.37.4) (2025-01-09)\n\n\n### Bug Fixes\n\n* Remove unnecesary `typeof` from type imports in declarations ([#5715](https://github.com/ajaxorg/ace/issues/5715)) ([2c8bf91](https://github.com/ajaxorg/ace/commit/2c8bf916d75b086b958c205896bc2adc1747d241))\n\n### [1.37.3](https://github.com/ajaxorg/ace/compare/v1.37.2...v1.37.3) (2025-01-07)\n\n### [1.37.2](https://github.com/ajaxorg/ace/compare/v1.37.1...v1.37.2) (2025-01-06)\n\n\n### Bug Fixes\n\n* fix return type of supportsFile modelist ([#5705](https://github.com/ajaxorg/ace/issues/5705)) ([de21d50](https://github.com/ajaxorg/ace/commit/de21d50656bd874e1626265b8853923cb8da7c8b))\n\n### [1.37.1](https://github.com/ajaxorg/ace/compare/v1.37.0...v1.37.1) (2024-12-20)\n\n\n### Bug Fixes\n\n* hide gutter tooltip event missing from editor signal ([#5701](https://github.com/ajaxorg/ace/issues/5701)) ([66a6736](https://github.com/ajaxorg/ace/commit/66a673643d5d128eaf59d4fb6e5907fa6fa68773))\n\n### [1.36.6](https://github.com/ajaxorg/ace/compare/v1.36.5...v1.36.6) (2024-12-17)\n\n\n### Bug Fixes\n\n* update contribuition guide to mandate test cases ([#5694](https://github.com/ajaxorg/ace/issues/5694)) ([e6533b3](https://github.com/ajaxorg/ace/commit/e6533b3972d5adbf5995646c44894466b3b7f40f))\n* wrong behaviour rules in modes ([#5682](https://github.com/ajaxorg/ace/issues/5682)) ([442680c](https://github.com/ajaxorg/ace/commit/442680c68e66531c2d5ac80d80444ed600262ec1))\n\n### [1.36.5](https://github.com/ajaxorg/ace/compare/v1.36.4...v1.36.5) (2024-11-14)\n\n\n### Features\n\n* exposing getter setter for widget manager created using line widgets ([#5673](https://github.com/ajaxorg/ace/issues/5673)) ([f5d0c19](https://github.com/ajaxorg/ace/commit/f5d0c196c69d06a9dda1bdeb379fa20ecbf75590))\n\n\n### Bug Fixes\n\n* vue-directives regex bug ([#5671](https://github.com/ajaxorg/ace/issues/5671)) ([5e1e524](https://github.com/ajaxorg/ace/commit/5e1e524d7ef04e13291b5a979fb4166e973e61f0))\n\n### [1.36.4](https://github.com/ajaxorg/ace/compare/v1.36.3...v1.36.4) (2024-11-04)\n\n\n### Bug Fixes\n\n* **a11y:** update aria-label of textinput on cursor move ([#5665](https://github.com/ajaxorg/ace/issues/5665)) ([6ff93a8](https://github.com/ajaxorg/ace/commit/6ff93a86fe8c4855789ee7e7c156f7b376c0f935))\n\n### [1.36.3](https://github.com/ajaxorg/ace/compare/v1.36.2...v1.36.3) (2024-10-21)\n\n\n### Bug Fixes\n\n* `readdirSync` options `recursive: true` was added only in NodeJs v20.1.0 ([#5645](https://github.com/ajaxorg/ace/issues/5645)) ([2953f72](https://github.com/ajaxorg/ace/commit/2953f72877a90691432373cfe9182e60ea9b2d8f))\n\n### [1.36.2](https://github.com/ajaxorg/ace/compare/v1.36.1...v1.36.2) (2024-08-30)\n\n\n### Bug Fixes\n\n* apply padding to right side multi-line markers ([#5636](https://github.com/ajaxorg/ace/issues/5636)) ([c7549aa](https://github.com/ajaxorg/ace/commit/c7549aa5d53fb62f134b31a44d09029ceee3c800))\n\n### [1.36.1](https://github.com/ajaxorg/ace/compare/v1.36.0...v1.36.1) (2024-08-29)\n\n\n### Bug Fixes\n\n* improve type getMarkerAtPosition markergroup ([#5631](https://github.com/ajaxorg/ace/issues/5631)) ([89bd40a](https://github.com/ajaxorg/ace/commit/89bd40a66a2f06fb8806f174e5559021540a5b1e))\n* update cloudeditor light colours ([#5633](https://github.com/ajaxorg/ace/issues/5633)) ([0e2813e](https://github.com/ajaxorg/ace/commit/0e2813ed9e858d9359c2a79f2a9255d675308ad1))\n\n## [1.36.0](https://github.com/ajaxorg/ace/compare/v1.35.5...v1.36.0) (2024-08-21)\n\n\n### Features\n\n* allow setting marker type for MarkerGroups ([#5630](https://github.com/ajaxorg/ace/issues/5630)) ([214df9c](https://github.com/ajaxorg/ace/commit/214df9cea8d729f3071f9c02889cba2b2e7051b3))\n* **forced-color:** do not adjust the forced colors for the editor ([#5624](https://github.com/ajaxorg/ace/issues/5624)) ([c8f9df8](https://github.com/ajaxorg/ace/commit/c8f9df84e70ee29e8e989966985bcea95a9bef9b))\n\n### [1.35.5](https://github.com/ajaxorg/ace/compare/v1.35.4...v1.35.5) (2024-08-20)\n\n### [1.35.4](https://github.com/ajaxorg/ace/compare/v1.35.3...v1.35.4) (2024-07-22)\n\n\n### Bug Fixes\n\n* move right of cursor tokens to end of ghost text. ([#5616](https://github.com/ajaxorg/ace/issues/5616)) ([063ef9b](https://github.com/ajaxorg/ace/commit/063ef9bbe0934dfe75d9b447e8a92b69bfa41a3a))\n\n### [1.35.3](https://github.com/ajaxorg/ace/compare/v1.35.2...v1.35.3) (2024-07-18)\n\n\n### Bug Fixes\n\n* ghost text rendering of empty lines ([#5615](https://github.com/ajaxorg/ace/issues/5615)) ([1ae0bdc](https://github.com/ajaxorg/ace/commit/1ae0bdcfb9da4078713d116e93a9c9a935a1258d))\n\n### [1.35.2](https://github.com/ajaxorg/ace/compare/v1.35.1...v1.35.2) (2024-07-01)\n\n### [1.35.1](https://github.com/ajaxorg/ace/compare/v1.35.0...v1.35.1) (2024-06-27)\n\n\n### Bug Fixes\n\n* explicitly construct Number from window zoom attribute ([#5600](https://github.com/ajaxorg/ace/issues/5600)) ([2591c36](https://github.com/ajaxorg/ace/commit/2591c36b9e768305a9f837bf74c828c2d8d76e05))\n* use dom builder for gutter tooltip and inline widget ([#5601](https://github.com/ajaxorg/ace/issues/5601)) ([e81a299](https://github.com/ajaxorg/ace/commit/e81a299a8be39a7245a334ebc844eaeac6864bb3))\n* workaround for safari rendering bug ([#5573](https://github.com/ajaxorg/ace/issues/5573)) ([f9a152f](https://github.com/ajaxorg/ace/commit/f9a152fd925a8a16b10c65c909201100486c71e8))\n* wrong doc comment * insert behaviour ([#5571](https://github.com/ajaxorg/ace/issues/5571)) ([16c95b3](https://github.com/ajaxorg/ace/commit/16c95b32197c0ec952e52be85d21269005875940))\n\n## [1.35.0](https://github.com/ajaxorg/ace/compare/v1.34.2...v1.35.0) (2024-06-11)\n\n\n### Features\n\n* allow '{n}' as placeholder for translated strings ([#5581](https://github.com/ajaxorg/ace/issues/5581)) ([2206024](https://github.com/ajaxorg/ace/commit/220602488b95748c74141d647e13114c7a4569fb))\n\n\n### Bug Fixes\n\n* allow setting the placeholder type for nls ([#5584](https://github.com/ajaxorg/ace/issues/5584)) ([3e2d50f](https://github.com/ajaxorg/ace/commit/3e2d50f5307e201c20825311585e1f612f1ff23c))\n* not closed generic state in case of left-shift operator ([#5572](https://github.com/ajaxorg/ace/issues/5572)) ([e5bea6f](https://github.com/ajaxorg/ace/commit/e5bea6f63290003ff3270d56dbf9610e8a3091a8))\n* wrong vue-directives regexp ([#5586](https://github.com/ajaxorg/ace/issues/5586)) ([5f89a33](https://github.com/ajaxorg/ace/commit/5f89a334e69640bb395e74ae86530217d08f141c))\n\n### [1.34.2](https://github.com/ajaxorg/ace/compare/v1.34.1...v1.34.2) (2024-05-27)\n\n### [1.34.1](https://github.com/ajaxorg/ace/compare/v1.34.0...v1.34.1) (2024-05-24)\n\n\n### Bug Fixes\n\n* always set aria-label to text input in a11y mode ([#5563](https://github.com/ajaxorg/ace/issues/5563)) ([00346fd](https://github.com/ajaxorg/ace/commit/00346fde824beabb69f677631ad52815665eaef4))\n* Folding for comments and different modes ([#5533](https://github.com/ajaxorg/ace/issues/5533)) ([f4d0e33](https://github.com/ajaxorg/ace/commit/f4d0e33dac270ce21df09a96a39f50e16d6354db))\n\n## [1.34.0](https://github.com/ajaxorg/ace/compare/v1.33.3...v1.34.0) (2024-05-22)\n\n\n### Features\n\n* allow users to add arialabel to text input ([#5560](https://github.com/ajaxorg/ace/issues/5560)) ([8d7dfb6](https://github.com/ajaxorg/ace/commit/8d7dfb69392960aba61def982f4bea8f3a5caa70))\n\n### [1.33.3](https://github.com/ajaxorg/ace/compare/v1.33.2...v1.33.3) (2024-05-21)\n\n\n### Bug Fixes\n\n* contrast completion meta contrast cloud editor themes ([#5558](https://github.com/ajaxorg/ace/issues/5558)) ([b8877f0](https://github.com/ajaxorg/ace/commit/b8877f0f725b3973961cb639127402c9f56609de))\n\n### [1.33.2](https://github.com/ajaxorg/ace/compare/v1.33.1...v1.33.2) (2024-05-13)\n\n\n### Bug Fixes\n\n* Add soft wrap for ghost text ([#5540](https://github.com/ajaxorg/ace/issues/5540)) ([6a26b27](https://github.com/ajaxorg/ace/commit/6a26b277d0050b38cd766e00f93be4b9f3170f68))\n* generator function's determination; wrong parameter highlighting ([#5538](https://github.com/ajaxorg/ace/issues/5538)) ([ceca6f7](https://github.com/ajaxorg/ace/commit/ceca6f7b38f6b3347988f17579ae6a2e758137dd))\n* incorrect spans style ([#5539](https://github.com/ajaxorg/ace/issues/5539)) ([65a7f38](https://github.com/ajaxorg/ace/commit/65a7f38713cffb729dab530711351c0a17c5801f))\n* not determined folding widgets for html tags ([#5548](https://github.com/ajaxorg/ace/issues/5548)) ([7a51992](https://github.com/ajaxorg/ace/commit/7a5199292f55dfa1a8ea8830ea1a9d98be097161))\n* wrong token type ([#5535](https://github.com/ajaxorg/ace/issues/5535)) ([4041489](https://github.com/ajaxorg/ace/commit/4041489bb38ffe609d5f9b43b4a7637e47fc4739))\n\n### [1.33.1](https://github.com/ajaxorg/ace/compare/v1.33.0...v1.33.1) (2024-04-23)\n\n\n### Bug Fixes\n\n* account for `this.popup` being potentially undefined in completion mousewheel listener ([#5537](https://github.com/ajaxorg/ace/issues/5537)) ([6c3a9a6](https://github.com/ajaxorg/ace/commit/6c3a9a66a7a0ab0dd493ad2c281c9dd343d5301f))\n\n## [1.33.0](https://github.com/ajaxorg/ace/compare/v1.32.9...v1.33.0) (2024-04-12)\n\n\n### Features\n\n* Make translation system key based and add annotation type to gutter icon aria labels ([#5524](https://github.com/ajaxorg/ace/issues/5524)) ([bb8256d](https://github.com/ajaxorg/ace/commit/bb8256d5a5b5e989e3fb1bb80f326b8564fbbc20))\n\n\n### Bug Fixes\n\n* Contrast is too low for searched items ([#5523](https://github.com/ajaxorg/ace/issues/5523)) ([507ae2f](https://github.com/ajaxorg/ace/commit/507ae2f872a2b2f1a14fdffbf6530f4046df44c0))\n\n### [1.32.9](https://github.com/ajaxorg/ace/compare/v1.32.8...v1.32.9) (2024-03-29)\n\n\n### Bug Fixes\n\n* apply class to autocomplete popup for no suggestions state ([#5522](https://github.com/ajaxorg/ace/issues/5522)) ([a66f861](https://github.com/ajaxorg/ace/commit/a66f8619953eecd85833d97715e479d3b211c4cd))\n\n### [1.32.8](https://github.com/ajaxorg/ace/compare/v1.32.7...v1.32.8) (2024-03-22)\n\n\n### Bug Fixes\n\n* allow completers to trigger on newline characters ([#5519](https://github.com/ajaxorg/ace/issues/5519)) ([6e870fd](https://github.com/ajaxorg/ace/commit/6e870fd08e06be47f9da971743d13b25c41f99c2))\n* don't detach completion popup while typing when prefix is empty ([#5517](https://github.com/ajaxorg/ace/issues/5517)) ([7937e53](https://github.com/ajaxorg/ace/commit/7937e53babb9b327902e9dab4b18c04a907883be))\n* scroll cursor line to top editor for long inline preview ([#5514](https://github.com/ajaxorg/ace/issues/5514)) ([529473b](https://github.com/ajaxorg/ace/commit/529473b6959d5f7a70ada1d20feb0c87b432f766))\n* SwiftHighlightRules exports ([#5516](https://github.com/ajaxorg/ace/issues/5516)) ([f493ab0](https://github.com/ajaxorg/ace/commit/f493ab03bb50fe089c927b7a50a4a327c8dcec4c))\n\n### [1.32.7](https://github.com/ajaxorg/ace/compare/v1.32.6...v1.32.7) (2024-03-01)\n\n\n### Bug Fixes\n\n* swap blue/red in cloudeditor themes to reduces usage of red ([#5492](https://github.com/ajaxorg/ace/issues/5492)) ([0e8f549](https://github.com/ajaxorg/ace/commit/0e8f549a16481f8bb7573ac9edaae377cb9e3972))\n\n### [1.32.6](https://github.com/ajaxorg/ace/compare/v1.32.5...v1.32.6) (2024-02-07)\n\n### [1.32.5](https://github.com/ajaxorg/ace/compare/v1.32.4...v1.32.5) (2024-01-30)\n\n### [1.32.4](https://github.com/ajaxorg/ace/compare/v1.32.3...v1.32.4) (2024-01-29)\n\n\n### Bug Fixes\n\n* Improve contrast of completion popup in CloudEditor theme ([#5473](https://github.com/ajaxorg/ace/issues/5473)) ([273c7f1](https://github.com/ajaxorg/ace/commit/273c7f159ded7dc9403266c6501e16a35e4101c6))\n* update JSX mode to reflect React JSX ([#5451](https://github.com/ajaxorg/ace/issues/5451)) ([66789a7](https://github.com/ajaxorg/ace/commit/66789a79ce1b7791c65886d8aecddd7efc0415e8))\n\n### [1.32.3](https://github.com/ajaxorg/ace/compare/v1.32.2...v1.32.3) (2023-12-29)\n\n\n### Bug Fixes\n\n* improve prefixing for inline preview ([#5439](https://github.com/ajaxorg/ace/issues/5439)) ([51006bb](https://github.com/ajaxorg/ace/commit/51006bba9c60b97251ddb04ed74f68ba4e7f6b54))\n* update ghost text if on same line popup ([12f4664](https://github.com/ajaxorg/ace/commit/12f466460d7187cfe37593dab1fbe275403fedd3))\n* updated red color in cloud-editor dark theme ([#5432](https://github.com/ajaxorg/ace/issues/5432)) ([142b607](https://github.com/ajaxorg/ace/commit/142b607578f5d071a5026691ff6662c11e9f186b))\n\n### [1.32.2](https://github.com/ajaxorg/ace/compare/v1.32.1...v1.32.2) (2023-12-14)\n\n\n### Bug Fixes\n\n* **themes:** changed the solarized theme primary color from `[#93](https://github.com/ajaxorg/ace/issues/93)A1A1` to `[#839496](https://github.com/ajaxorg/ace/issues/839496)`. ([#5422](https://github.com/ajaxorg/ace/issues/5422)) ([114a5c1](https://github.com/ajaxorg/ace/commit/114a5c163fd875b4fab332dadfadeeae41e4097a)), closes [#93A1A1](https://github.com/ajaxorg/ace/issues/93A1A1)\n\n### [1.32.1](https://github.com/ajaxorg/ace/compare/v1.32.0...v1.32.1) (2023-12-11)\n\n\n### Bug Fixes\n\n* don't show loading state when empty completer array is provided ([7a8a929](https://github.com/ajaxorg/ace/commit/7a8a92933b3fde75907612d106643d28efa2d776))\n* prevent browser scroll while scrolling over the tooltip ([#5414](https://github.com/ajaxorg/ace/issues/5414)) ([c6475c0](https://github.com/ajaxorg/ace/commit/c6475c00bcfa49dde37ef9de06ebba82ba5ba15d))\n* switch aria-selected to aria-current for webkit ([#5416](https://github.com/ajaxorg/ace/issues/5416)) ([bf1a4ea](https://github.com/ajaxorg/ace/commit/bf1a4ea607ed09b5a299390dd2daa5c1d0019e00)), closes [#5403](https://github.com/ajaxorg/ace/issues/5403)\n* yaml worker errors at undefined row/column ([06cc12a](https://github.com/ajaxorg/ace/commit/06cc12aad98176d931a1c1cf9a701f4ac0c33de5))\n\n## [1.32.0](https://github.com/ajaxorg/ace/compare/v1.31.2...v1.32.0) (2023-11-30)\n\n\n### Features\n\n* adding CloudEditor theme ([#5404](https://github.com/ajaxorg/ace/issues/5404)) ([b0ee067](https://github.com/ajaxorg/ace/commit/b0ee067fadaf9593ed2207f363a402eb9ab8d57a))\n\n\n### Bug Fixes\n\n* autocomplete tests ([#5407](https://github.com/ajaxorg/ace/issues/5407)) ([cf6999d](https://github.com/ajaxorg/ace/commit/cf6999d9cb4103df16dc38a8cbfd40ab2a999e6d))\n* set completion popup role to 'menu' for safari ([6845905](https://github.com/ajaxorg/ace/commit/684590546746fa2ef090c10c140e01e43974d8f4))\n* stop rendering the completion popup disconnected from the editor for long ghost text ([#5401](https://github.com/ajaxorg/ace/issues/5401)) ([94d68a7](https://github.com/ajaxorg/ace/commit/94d68a73042c61a786d253fd0838e62cc5770a31))\n* try to scroll inline preview into view ([#5400](https://github.com/ajaxorg/ace/issues/5400)) ([95af560](https://github.com/ajaxorg/ace/commit/95af5608b655259d12cdbc4ca28cf450f9e649c7))\n\n### [1.31.2](https://github.com/ajaxorg/ace/compare/v1.31.1...v1.31.2) (2023-11-15)\n\n\n### Bug Fixes\n\n* inline preview with loading state ([05db94f](https://github.com/ajaxorg/ace/commit/05db94f53774f64318de757347f7217043744fe6))\n\n### [1.31.1](https://github.com/ajaxorg/ace/compare/v1.31.0...v1.31.1) (2023-10-30)\n\n\n### Bug Fixes\n\n* improve yaml folding ([5c80e3c](https://github.com/ajaxorg/ace/commit/5c80e3cdd716b4ad26ee6958c9137278530b7816))\n\n## [1.31.0](https://github.com/ajaxorg/ace/compare/v1.30.0...v1.31.0) (2023-10-23)\n\n\n### Features\n\n* add nasal language ([#5342](https://github.com/ajaxorg/ace/issues/5342)) ([4fff99e](https://github.com/ajaxorg/ace/commit/4fff99e320539a1472ce0512cd1fd3e5fc7f2ca6))\n\n\n### Bug Fixes\n\n* doc tooltip not filtering properly ([e5034c7](https://github.com/ajaxorg/ace/commit/e5034c7b58fb47fe57b28dbb001e72a567ef9abe))\n\n## [1.30.0](https://github.com/ajaxorg/ace/compare/v1.29.0...v1.30.0) (2023-10-13)\n\n\n### Features\n\n* Add support for time units in PRQL ([#5324](https://github.com/ajaxorg/ace/issues/5324)) ([8b9175b](https://github.com/ajaxorg/ace/commit/8b9175bc780fade64bed1570fa1cd34d022b337b))\n\n## [1.29.0](https://github.com/ajaxorg/ace/compare/v1.28.0...v1.29.0) (2023-10-09)\n\n\n### Features\n\n* allow setting completion.ignoreCaption ([5618046](https://github.com/ajaxorg/ace/commit/56180467e12c300850da89cc13c1c8648fb5e342))\n\n## [1.28.0](https://github.com/ajaxorg/ace/compare/v1.27.0...v1.28.0) (2023-09-22)\n\n\n### Features\n\n* Keep focus on same item in completion popup when slow completer delivers results. ([#5322](https://github.com/ajaxorg/ace/issues/5322)) ([0983134](https://github.com/ajaxorg/ace/commit/09831343ccd450326cffb4b0f26ce3a8b830c7fb))\n\n## [1.27.0](https://github.com/ajaxorg/ace/compare/v1.26.0...v1.27.0) (2023-09-19)\n\n\n### Features\n\n* Allow not showing inline preview for completers when `inlineEnabled` is set to `true`. ([#5315](https://github.com/ajaxorg/ace/issues/5315)) ([f3e3330](https://github.com/ajaxorg/ace/commit/f3e333041fc1a687b3ce35a44f1bf00bcc15a236))\n\n## [1.26.0](https://github.com/ajaxorg/ace/compare/v1.25.1...v1.26.0) (2023-09-15)\n\n\n### Features\n\n* Allow to set setSelectOnHover for Autocomplete ([#5317](https://github.com/ajaxorg/ace/issues/5317)) ([dccbcc2](https://github.com/ajaxorg/ace/commit/dccbcc20288a48403f10aa29b6b9b6181dc8a66f))\n\n\n### Bug Fixes\n\n* Improve PRQL syntax highlightning ([#5313](https://github.com/ajaxorg/ace/issues/5313)) ([7d677f1](https://github.com/ajaxorg/ace/commit/7d677f1019ea5c81f3d9ae36ed1e71ac7a08fb30))\n\n### [1.25.1](https://github.com/ajaxorg/ace/compare/v1.25.0...v1.25.1) (2023-09-14)\n\n## [1.25.0](https://github.com/ajaxorg/ace/compare/v1.24.2...v1.25.0) (2023-09-14)\n\n\n### Features\n\n* Add syntax highlighting for PRQL ([#5307](https://github.com/ajaxorg/ace/issues/5307)) ([24862cd](https://github.com/ajaxorg/ace/commit/24862cdc83694bbe541c6f8be6fbaaff80d44bf7))\n\n### [1.24.2](https://github.com/ajaxorg/ace/compare/v1.24.1...v1.24.2) (2023-09-08)\n\n\n### Bug Fixes\n\n* Added project details in index.html file ([#5300](https://github.com/ajaxorg/ace/issues/5300)) ([6e83505](https://github.com/ajaxorg/ace/commit/6e835059dd13e95178b15ce9b06a2f2444c2e731))\n* autocompletion threshold doesn't apply to trigger characters ([84bbc88](https://github.com/ajaxorg/ace/commit/84bbc888e1c0304c0160bb19fc46cf5539d079cf))\n* Update php_highlight_rules.js ([#5288](https://github.com/ajaxorg/ace/issues/5288)) ([caedd0c](https://github.com/ajaxorg/ace/commit/caedd0cf22d5a7644ceb418562ebcab801011c88))\n\n### [1.24.1](https://github.com/ajaxorg/ace/compare/v1.24.0...v1.24.1) (2023-08-15)\n\n## [1.24.0](https://github.com/ajaxorg/ace/compare/v1.23.4...v1.24.0) (2023-08-09)\n\n\n### Features\n\n* Add support for Unicode boundaries ([#5265](https://github.com/ajaxorg/ace/issues/5265)) ([1e6fcf3](https://github.com/ajaxorg/ace/commit/1e6fcf349d222715429ddc9fe6a38ec1f6d72ab1))\n* Allow more lines in hidden textarea to improve screen reader experience on Windows ([#5225](https://github.com/ajaxorg/ace/issues/5225)) ([bccff5a](https://github.com/ajaxorg/ace/commit/bccff5ae21b86004c2a4ab4a86a989c61e728ebf))\n* Cuttlefish mode ([#5278](https://github.com/ajaxorg/ace/issues/5278)) ([9cddf64](https://github.com/ajaxorg/ace/commit/9cddf64ac51fc5e7c5474e7aeaa2ef8f069220db))\n\n\n### Bug Fixes\n\n* add missing SQL keywords: IS and IN ([#5263](https://github.com/ajaxorg/ace/issues/5263)) ([c731164](https://github.com/ajaxorg/ace/commit/c731164315a757a5e0380f82eeef105a17b24b03))\n* bug in lua.lua example file kitchen-sink ([#5258](https://github.com/ajaxorg/ace/issues/5258)) ([6549570](https://github.com/ajaxorg/ace/commit/6549570310983999a1fd3ce52bc5bf8b4004402f))\n* support more environments ([#5266](https://github.com/ajaxorg/ace/issues/5266)) ([b196806](https://github.com/ajaxorg/ace/commit/b196806eb2937e7ee56e42b482b7b3bd5e3c9d79))\n\n### [1.23.4](https://github.com/ajaxorg/ace/compare/v1.23.3...v1.23.4) (2023-07-12)\n\n\n### Bug Fixes\n\n* filterText triggered selection range removal when completions range was present ([#5249](https://github.com/ajaxorg/ace/issues/5249)) ([b586e4d](https://github.com/ajaxorg/ace/commit/b586e4d574bf780fc38f1ac0d034276272b36ad3))\n\n### [1.23.3](https://github.com/ajaxorg/ace/compare/v1.23.2...v1.23.3) (2023-07-10)\n\n\n### Bug Fixes\n\n* android bug when deleting multiple lines ([#5248](https://github.com/ajaxorg/ace/issues/5248)) ([bd066ff](https://github.com/ajaxorg/ace/commit/bd066ffef88ca74f5ac32349d3e868cfa875a47b)), closes [#5087](https://github.com/ajaxorg/ace/issues/5087)\n* update jshint version to 2.13.6; change esversion to target ECMAScript 11 ([#5243](https://github.com/ajaxorg/ace/issues/5243)) ([301aee9](https://github.com/ajaxorg/ace/commit/301aee91b5974d9fb31d646466ed301c5c3b8249))\n\n### [1.23.2](https://github.com/ajaxorg/ace/compare/v1.23.1...v1.23.2) (2023-07-07)\n\n\n### Bug Fixes\n\n* **autocomplete:** fix a11y violations ([#5241](https://github.com/ajaxorg/ace/issues/5241)) ([decb615](https://github.com/ajaxorg/ace/commit/decb6154198105289170303b7434c524eaf9fda8))\n* bug in guttertooltip when `tooltipsFollowsMouse` set to false ([#5217](https://github.com/ajaxorg/ace/issues/5217)) ([67d318e](https://github.com/ajaxorg/ace/commit/67d318ed25d5b45789462850e6b96aac2931591f))\n* typo in function name ([#5229](https://github.com/ajaxorg/ace/issues/5229)) ([6e99055](https://github.com/ajaxorg/ace/commit/6e99055c46f443271161e40fe15372d1d8ae9f42))\n\n### [1.23.1](https://github.com/ajaxorg/ace/compare/v1.23.0...v1.23.1) (2023-06-27)\n\n## [1.23.0](https://github.com/ajaxorg/ace/compare/v1.22.1...v1.23.0) (2023-06-21)\n\n\n### Features\n\n* **autocomplete:** ellipsis is shown when suggestions is longer than popover width ([#5204](https://github.com/ajaxorg/ace/issues/5204)) ([de4234b](https://github.com/ajaxorg/ace/commit/de4234be62be264b78bd4dd19b09cf20fb4d0f28))\n* signal gutterkeydown in keyboard accessibility mode ([#5202](https://github.com/ajaxorg/ace/issues/5202)) ([538b18c](https://github.com/ajaxorg/ace/commit/538b18cf86e21c810910d286c820bac399927cd7))\n\n\n### Bug Fixes\n\n* Fix vite build and webpack warning ([#5192](https://github.com/ajaxorg/ace/issues/5192)) ([e14902e](https://github.com/ajaxorg/ace/commit/e14902e0c2b281346d062d6a5c84d05bd3590fe3))\n* gutter tooltip class fix ([#5211](https://github.com/ajaxorg/ace/issues/5211)) ([5bdb944](https://github.com/ajaxorg/ace/commit/5bdb944714e7787632914aeef521e3e5024a1d1f))\n* Improve ARIA labelling fold controls ([#5205](https://github.com/ajaxorg/ace/issues/5205)) ([dad5e6f](https://github.com/ajaxorg/ace/commit/dad5e6f6e445b805f7b470ef7892442a83d342e5))\n* regression in setting breakpoints on folded lines ([51326eb](https://github.com/ajaxorg/ace/commit/51326ebfe9b3e97925ab1be05246e0f2646c8687))\n\n### [1.22.1](https://github.com/ajaxorg/ace/compare/v1.22.0...v1.22.1) (2023-06-11)\n\n\n### Bug Fixes\n\n* don't throw unhandled errors in TabstopManager when EditSession becomes `undefined` ([#5193](https://github.com/ajaxorg/ace/issues/5193)) ([cd55932](https://github.com/ajaxorg/ace/commit/cd55932ac7161fcd45e2ee4f1ea8e22b5ff8c3c4))\n* include ace-modes to the npm package ([a074fa4](https://github.com/ajaxorg/ace/commit/a074fa41334314169075b66cd77dd2d9a191c73f))\n* jsdoc comment foldings ([#5197](https://github.com/ajaxorg/ace/issues/5197)) ([065af41](https://github.com/ajaxorg/ace/commit/065af4175f7c7426c9e8f798a0ec64c390a03259))\n\n## [1.22.0](https://github.com/ajaxorg/ace/compare/v1.21.1...v1.22.0) (2023-05-22)\n\n\n### Features\n\n* add odin mode ([#5169](https://github.com/ajaxorg/ace/issues/5169)) ([d455e9b](https://github.com/ajaxorg/ace/commit/d455e9b16efb6030a8b0b6c1189b72516b205b40))\n\n### [1.21.1](https://github.com/ajaxorg/ace/compare/v1.21.0...v1.21.1) (2023-05-16)\n\n\n### Bug Fixes\n\n* console error when hovering over empty gutter cell with tooltipFollowsMouse set to false ([#5173](https://github.com/ajaxorg/ace/issues/5173)) ([5ff8d4c](https://github.com/ajaxorg/ace/commit/5ff8d4cc064ac647a2f40bf977f88b2972ae17ef))\n\n## [1.21.0](https://github.com/ajaxorg/ace/compare/v1.20.0...v1.21.0) (2023-05-15)\n\n\n### Features\n\n* Custom empty message when no completion found ([#5158](https://github.com/ajaxorg/ace/issues/5158)) ([204aafa](https://github.com/ajaxorg/ace/commit/204aafa04c268e98655fb83b4877302a0f82fa4d))\n* Special trigger characters to start autocomplete ([#5147](https://github.com/ajaxorg/ace/issues/5147)) ([c2cfc5a](https://github.com/ajaxorg/ace/commit/c2cfc5a9f1448f64e62f7652c995a48c4ea31ab3))\n\n\n### Bug Fixes\n\n* command bar command type ([#5168](https://github.com/ajaxorg/ace/issues/5168)) ([64c8253](https://github.com/ajaxorg/ace/commit/64c8253e3cd4348b7ecd3684dae057c8fd5f79b9))\n\n## [1.20.0](https://github.com/ajaxorg/ace/compare/v1.19.0...v1.20.0) (2023-05-10)\n\n\n### Features\n\n* Add gutter controls to keyboard accessibility mode ([#5146](https://github.com/ajaxorg/ace/issues/5146)) ([5f2face](https://github.com/ajaxorg/ace/commit/5f2face8febe7c260a42bc30c67195f6a5a46085))\n* Inline autocomplete tooltip UX redesign ([#5149](https://github.com/ajaxorg/ace/issues/5149)) ([8d56c84](https://github.com/ajaxorg/ace/commit/8d56c841ef980527a1ebe4cf73442766f5f97208))\n\n## [1.19.0](https://github.com/ajaxorg/ace/compare/v1.18.1...v1.19.0) (2023-05-03)\n\n\n### Features\n\n* publishing generated styling files to ace-code package ([1fa223e](https://github.com/ajaxorg/ace/commit/1fa223e4ca0df16c9a0e0a6df2996fa010189666))\n\n### [1.18.1](https://github.com/ajaxorg/ace/compare/v1.18.0...v1.18.1) (2023-05-03)\n\n\n### Bug Fixes\n\n* add mode types, improve type definitions ([e22bd5c](https://github.com/ajaxorg/ace/commit/e22bd5c860451c000187941991c0047db4e701a2))\n* hide `$getindent` from the SyntaxMode ([2b1c65b](https://github.com/ajaxorg/ace/commit/2b1c65bceb290db74f26a5c59158f93830bc6111))\n* remove '$' fields for types that don't require exposing them ([2db9d4e](https://github.com/ajaxorg/ace/commit/2db9d4e88441f2932ce6c6f91e7f5ed36c590d2f))\n* remove or update badly formatted declarations ([1e7b022](https://github.com/ajaxorg/ace/commit/1e7b022908cdf6fef0a28419c464874ce6433e6e))\n* replaceRange could now be implemented as an instance of the Range interface, rather than being an instance of the Range class ([e1bdccc](https://github.com/ajaxorg/ace/commit/e1bdcccb4ed3179734aa534b37a9dade2e207f07))\n* wrong next state in regex state ([c5ed709](https://github.com/ajaxorg/ace/commit/c5ed7092f0151d4aa00c7060ecf0111fc37bfebb))\n\n## [1.18.0](https://github.com/ajaxorg/ace/compare/v1.17.0...v1.18.0) (2023-04-21)\n\n\n### Features\n\n* marker groups ([#5113](https://github.com/ajaxorg/ace/issues/5113)) ([01d4605](https://github.com/ajaxorg/ace/commit/01d4605c0dcf7bcbb4f1a09a243f7ef6d16d7d43))\n* summary of annotations in folded lines ([#5117](https://github.com/ajaxorg/ace/issues/5117)) ([dc63ba9](https://github.com/ajaxorg/ace/commit/dc63ba900d3641284d7d11cbb5ccad7c3039f3a4))\n\n## [1.17.0](https://github.com/ajaxorg/ace/compare/v1.16.0...v1.17.0) (2023-04-12)\n\n\n### Features\n\n* Add annotation level information to gutter tooltip ([#5101](https://github.com/ajaxorg/ace/issues/5101)) ([3cd28b8](https://github.com/ajaxorg/ace/commit/3cd28b88a51176c791e045f405cdf842916697ab))\n* Add option to prevent keyboard focus trapping ([#5114](https://github.com/ajaxorg/ace/issues/5114)) ([fe5d1bf](https://github.com/ajaxorg/ace/commit/fe5d1bfbf0a3432b78a5e503d1db680181ef48b8))\n* Add option to use SVG gutter icons ([#5107](https://github.com/ajaxorg/ace/issues/5107)) ([82eb439](https://github.com/ajaxorg/ace/commit/82eb439709773a71515fbe97c4e89890ea77e752))\n* add ResizeObserver to make calling editor.resize optional ([51d5e4d](https://github.com/ajaxorg/ace/commit/51d5e4d4308ba98921b1d6ea8cf946d0e17d0a7a))\n\n\n### Bug Fixes\n\n* adds missing 'on' method for 'guttermousedown' ([7212042](https://github.com/ajaxorg/ace/commit/721204292907549fd4fd02d6672afd2b63d1e168))\n* Fix bracket highlighting for brackets in open/close tags ([#5108](https://github.com/ajaxorg/ace/issues/5108)) ([3c149a9](https://github.com/ajaxorg/ace/commit/3c149a97acedd9c9ad52daebaf944aa26534d37f))\n* Improves Liquid Support ([#5098](https://github.com/ajaxorg/ace/issues/5098)) ([0ae8dbb](https://github.com/ajaxorg/ace/commit/0ae8dbb0fe017cfb8321307e5bfe5959eb121754))\n\n## [1.16.0](https://github.com/ajaxorg/ace/compare/v1.14.0...v1.16.0) (2023-03-17)\n\n\n### Features\n\n* Added Editor API to set the ghost text ([#5036](https://github.com/ajaxorg/ace/issues/5036)) ([958d573](https://github.com/ajaxorg/ace/commit/958d57383c4ebfacd414eb817aecc2e0982d1b36))\n* Inline autocompletion ([#5084](https://github.com/ajaxorg/ace/issues/5084)) ([eb834a1](https://github.com/ajaxorg/ace/commit/eb834a1f1ca7f922437a90f2f14d935d75f31ac8))\n\n\n### Bug Fixes\n\n* add updated monospace font for Windows ([#5091](https://github.com/ajaxorg/ace/issues/5091)) ([a981972](https://github.com/ajaxorg/ace/commit/a9819722cec6ff60b028deaa7b70d7fefabac531))\n* Added highlighting for TIES keyword introduced in PostgreSQL 13 ([#5033](https://github.com/ajaxorg/ace/issues/5033)) ([9588086](https://github.com/ajaxorg/ace/commit/95880868c2a9912f7c6a2c3942d67fc2a980094e))\n* Added lateral keyword introduced in MySQL 8.0.14 ([#5053](https://github.com/ajaxorg/ace/issues/5053)) ([3250956](https://github.com/ajaxorg/ace/commit/32509568010d8b881cc9f1a6d6bd76e6f69360ea))\n* editor shadow appears under the selected line background when horizontal scroll is active ([#5020](https://github.com/ajaxorg/ace/issues/5020)) ([ab4f788](https://github.com/ajaxorg/ace/commit/ab4f788455ae182ae133fa202d737efa5461ff79))\n* Fix bug with missing token in latex folding ([#5093](https://github.com/ajaxorg/ace/issues/5093)) ([44b3a3e](https://github.com/ajaxorg/ace/commit/44b3a3ef2de40f5cc71c3dedc1ed8d596cfadeec)), closes [#5090](https://github.com/ajaxorg/ace/issues/5090)\n* Implement highlight mode for PL/SQL (Oracle) dialect ([#5037](https://github.com/ajaxorg/ace/issues/5037)) ([159aa70](https://github.com/ajaxorg/ace/commit/159aa70d551530f2866fb0006fad37bd75e60dda))\n* Improve MySQL highlighting mode ([#5050](https://github.com/ajaxorg/ace/issues/5050)) ([00f6089](https://github.com/ajaxorg/ace/commit/00f60890a36121d7c705445514dcf79a81055f55))\n* Option to determine specific prefixes for quote insertion ([#5067](https://github.com/ajaxorg/ace/issues/5067)) ([34e769c](https://github.com/ajaxorg/ace/commit/34e769c5b29a68a3c4201fecc75d1287c99f9d51)), closes [#5063](https://github.com/ajaxorg/ace/issues/5063)\n* Remove broken keybinding from vscode mode ([#5032](https://github.com/ajaxorg/ace/issues/5032)) ([68ff964](https://github.com/ajaxorg/ace/commit/68ff964a214cc2da66e4a35b313ff66dd4490e34))\n\n### [1.15.3](https://github.com/ajaxorg/ace/compare/v1.15.2...v1.15.3) (2023-03-02)\n\n### [1.15.2](https://github.com/ajaxorg/ace/compare/v1.15.1...v1.15.2) (2023-02-16)\n\n### [1.15.1](https://github.com/ajaxorg/ace/compare/v1.15.0...v1.15.1) (2023-02-13)\n\n\n### Bug Fixes\n\n* Added lateral keyword introduced in MySQL 8.0.14 ([#5053](https://github.com/ajaxorg/ace/issues/5053)) ([3250956](https://github.com/ajaxorg/ace/commit/32509568010d8b881cc9f1a6d6bd76e6f69360ea))\n* Implement highlight mode for PL/SQL (Oracle) dialect ([#5037](https://github.com/ajaxorg/ace/issues/5037)) ([159aa70](https://github.com/ajaxorg/ace/commit/159aa70d551530f2866fb0006fad37bd75e60dda))\n* Improve MySQL highlighting mode ([#5050](https://github.com/ajaxorg/ace/issues/5050)) ([00f6089](https://github.com/ajaxorg/ace/commit/00f60890a36121d7c705445514dcf79a81055f55))\n\n## [1.15.0](https://github.com/ajaxorg/ace/compare/v1.14.0...v1.15.0) (2023-01-25)\n\n\n### Features\n\n* Added Editor API to set the ghost text ([#5036](https://github.com/ajaxorg/ace/issues/5036)) ([958d573](https://github.com/ajaxorg/ace/commit/958d57383c4ebfacd414eb817aecc2e0982d1b36))\n\n\n### Bug Fixes\n\n* Added highlighting for TIES keyword introduced in PostgreSQL 13 ([#5033](https://github.com/ajaxorg/ace/issues/5033)) ([9588086](https://github.com/ajaxorg/ace/commit/95880868c2a9912f7c6a2c3942d67fc2a980094e))\n* editor shadow appears under the selected line background when horizontal scroll is active ([#5020](https://github.com/ajaxorg/ace/issues/5020)) ([ab4f788](https://github.com/ajaxorg/ace/commit/ab4f788455ae182ae133fa202d737efa5461ff79))\n* Remove broken keybinding from vscode mode ([#5032](https://github.com/ajaxorg/ace/issues/5032)) ([68ff964](https://github.com/ajaxorg/ace/commit/68ff964a214cc2da66e4a35b313ff66dd4490e34))\n\n## [1.14.0](https://github.com/ajaxorg/ace/compare/v1.13.1...v1.14.0) (2022-12-12)\n\n\n### Features\n\n* Autocomplete accessibility features ([#5008](https://github.com/ajaxorg/ace/issues/5008)) ([3b7bb5e](https://github.com/ajaxorg/ace/commit/3b7bb5e4afbad0f2bdbc7f8487442a5cb78b8284))\n\n\n### Bug Fixes\n\n* Add missing options to `EditorOptions` ([#5003](https://github.com/ajaxorg/ace/issues/5003)) ([451b63f](https://github.com/ajaxorg/ace/commit/451b63f2243762d6de2fc5b9ee8c580c348b933c))\n* added GREATEST|LEAST logical functions added in SQL Server 2022 ([#5009](https://github.com/ajaxorg/ace/issues/5009)) ([e3f3e7a](https://github.com/ajaxorg/ace/commit/e3f3e7ab3efe540ac345325f06278a8ab1871371))\n* Better ES6 support for JavaScript Mode ([6fb39e3](https://github.com/ajaxorg/ace/commit/6fb39e38c79dd966233e48ed06be800c59c4c101))\n* Fix vim keybindings scroll to the selected line ([#4980](https://github.com/ajaxorg/ace/issues/4980)) ([8562f94](https://github.com/ajaxorg/ace/commit/8562f9493e0ebef865064992f0526fdc6df8535a))\n* show 2 context characters of a line when moving to it ([#4998](https://github.com/ajaxorg/ace/issues/4998)) ([743190e](https://github.com/ajaxorg/ace/commit/743190ea71841c0186b2f513b3d1e1a9e30d3de3))\n* Update ace.d.ts typings for navigate ([#5011](https://github.com/ajaxorg/ace/issues/5011)) ([a302709](https://github.com/ajaxorg/ace/commit/a30270990cc0041edb6985059915f96524ebb154))\n\n### [1.13.2](https://github.com/ajaxorg/ace/compare/v1.13.1...v1.13.2) (2022-12-07)\n\n\n### Bug Fixes\n\n* Add missing options to `EditorOptions` ([#5003](https://github.com/ajaxorg/ace/issues/5003)) ([451b63f](https://github.com/ajaxorg/ace/commit/451b63f2243762d6de2fc5b9ee8c580c348b933c))\n* Better ES6 support for JavaScript Mode ([6fb39e3](https://github.com/ajaxorg/ace/commit/6fb39e38c79dd966233e48ed06be800c59c4c101))\n* Fix vim keybindings scroll to the selected line ([#4980](https://github.com/ajaxorg/ace/issues/4980)) ([8562f94](https://github.com/ajaxorg/ace/commit/8562f9493e0ebef865064992f0526fdc6df8535a))\n* show 2 context characters of a line when moving to it ([#4998](https://github.com/ajaxorg/ace/issues/4998)) ([743190e](https://github.com/ajaxorg/ace/commit/743190ea71841c0186b2f513b3d1e1a9e30d3de3))\n\n### [1.13.1](https://github.com/ajaxorg/ace/compare/v1.13.0...v1.13.1) (2022-11-16)\n\n\n### Bug Fixes\n\n* Change curly braces insertion behavior for Markdown to act the same as for other braces ([#4994](https://github.com/ajaxorg/ace/issues/4994)) ([2760234](https://github.com/ajaxorg/ace/commit/2760234d3d8d1acba72a42df7763482655af5ebc))\n* incorrect cursor position for very long lines ([#4996](https://github.com/ajaxorg/ace/issues/4996)) ([e57a9d9](https://github.com/ajaxorg/ace/commit/e57a9d9eef0c056cd38a07c77c460bea39cc9551))\n\n## [1.13.0](https://github.com/ajaxorg/ace/compare/v1.12.5...v1.13.0) (2022-11-11)\n\n\n### Features\n\n* add highlight mode for Apache JEXL ([#4979](https://github.com/ajaxorg/ace/issues/4979)) ([4e8926e](https://github.com/ajaxorg/ace/commit/4e8926ef9f9207e57529e07cdbe2305b09e712e2))\n\n\n### Bug Fixes\n\n* Add missing options to `VirtualRendererOptions` and `EditorOptions` ([#4983](https://github.com/ajaxorg/ace/issues/4983)) ([19dd2ec](https://github.com/ajaxorg/ace/commit/19dd2ecc178bef2fedd6a53900f2db58ea7a3c23))\n* Fix of scroll while interrupting animation ([#4993](https://github.com/ajaxorg/ace/issues/4993)) ([0092f3f](https://github.com/ajaxorg/ace/commit/0092f3f8c1f0d9c8a0b8bebe58cc3517931697b7))\n* rare case when document passed to `dom.scrollbarWidth` doesn't have `documentElement` ([#4981](https://github.com/ajaxorg/ace/issues/4981)) ([df44158](https://github.com/ajaxorg/ace/commit/df441585ef44e17a027141e3ceed648e104e9cf9))\n\n### [1.12.5](https://github.com/ajaxorg/ace/compare/v1.12.4...v1.12.5) (2022-11-01)\n\n\n### Bug Fixes\n\n* enableLiveAutocompletion documentation ([#4976](https://github.com/ajaxorg/ace/issues/4976)) ([987ab76](https://github.com/ajaxorg/ace/commit/987ab7602e06acc9b08c75914f5c1335d5cdc8cc))\n* vim \"normal\" mode brackets highlighting ([0fbc54c](https://github.com/ajaxorg/ace/commit/0fbc54cc5130b0271928995660413ba0fab678cb))\n\n### [1.12.4](https://github.com/ajaxorg/ace/compare/v1.12.3...v1.12.4) (2022-10-31)\n\n\n### Bug Fixes\n\n* Open valid url under cursor ([#4970](https://github.com/ajaxorg/ace/issues/4970)) ([bf2913a](https://github.com/ajaxorg/ace/commit/bf2913a71624e94d13727115b2aa0ef0c279c89f))\n* Update for Csound 6.18.0 ([#4974](https://github.com/ajaxorg/ace/issues/4974)) ([6886b02](https://github.com/ajaxorg/ace/commit/6886b0233e9e1d8d6cce5d3ade7b27fe4527c940))\n* update/add missing demo samples ([#4975](https://github.com/ajaxorg/ace/issues/4975)) ([2b8236e](https://github.com/ajaxorg/ace/commit/2b8236eaf1df10caa9ff45a06902df14947cd968))\n\n### [1.12.3](https://github.com/ajaxorg/ace/compare/v1.12.2...v1.12.3) (2022-10-18)\n\n\n### Bug Fixes\n\n* Fix syntax error in the custom scroll CSS ([#4968](https://github.com/ajaxorg/ace/issues/4968)) ([f2a424a](https://github.com/ajaxorg/ace/commit/f2a424a649f655b9511b1bb6047097634edb0e3f))\n\n### [1.12.2](https://github.com/ajaxorg/ace/compare/v1.12.1...v1.12.2) (2022-10-18)\n\n\n### Bug Fixes\n\n* custom scrollbar breaks csp mode ([#4967](https://github.com/ajaxorg/ace/issues/4967)) ([be8eb12](https://github.com/ajaxorg/ace/commit/be8eb1236fb7e1d27cedf033d301f094ec6764e5))\n* find all in range bug ([13bd553](https://github.com/ajaxorg/ace/commit/13bd55348dc8de5c547c74ec0e48c52b6db96a26))\n* Namespace-relative names for php ([#4963](https://github.com/ajaxorg/ace/issues/4963)) ([96e4066](https://github.com/ajaxorg/ace/commit/96e4066341fb7b82d02ad8272929711073d3bfc4))\n\n### [1.12.1](https://github.com/ajaxorg/ace/compare/v1.12.0...v1.12.1) (2022-10-17)\n\n\n### Bug Fixes\n\n* php worker rules for T_NAME_FULLY_QUALIFIED ([#4960](https://github.com/ajaxorg/ace/issues/4960)) ([52dbb05](https://github.com/ajaxorg/ace/commit/52dbb0577693e29f124a1f16008b4e11e2ce7c02))\n* recognisition of uppercase hex numbers for stylus mode ([#4962](https://github.com/ajaxorg/ace/issues/4962)) ([87e0dc7](https://github.com/ajaxorg/ace/commit/87e0dc7b868798300e874e39304aeda18d3d1a76))\n\n## [1.12.0](https://github.com/ajaxorg/ace/compare/v1.11.2...v1.12.0) (2022-10-15)\n\n\n### Features\n\n* implement BibTeX mode highlighting ([ab9e191](https://github.com/ajaxorg/ace/commit/ab9e1916cb3363260de58b808bdc21fd6bc01618))\n\n\n### Bug Fixes\n\n* `MockDom's` `ClassList` `toggle` and `contains` methods return `boolean` instead of `void` ([e8c0a1f](https://github.com/ajaxorg/ace/commit/e8c0a1f35d302966626896aaf84b056e76a8e66e))\n* change lua version to 5.3 ([#4954](https://github.com/ajaxorg/ace/issues/4954)) ([fc56af5](https://github.com/ajaxorg/ace/commit/fc56af5936a2ebfdfa0871ca6a68ccf7ecc7dbf0))\n* documentation for TokenIterator methods ([#4955](https://github.com/ajaxorg/ace/issues/4955)) ([6bff7b4](https://github.com/ajaxorg/ace/commit/6bff7b43c7ad34dd5fafc81c5de773e9d709026d))\n* Fixed comment folding bugs for html (xml like languages) ([#4910](https://github.com/ajaxorg/ace/issues/4910)) ([5279a8a](https://github.com/ajaxorg/ace/commit/5279a8a71719bf5c7099db1774a3d9669d9e5694))\n* mode change for vim tests ([236a31e](https://github.com/ajaxorg/ace/commit/236a31e5d69fd4fd874b667b38dd1bf0685f75c5))\n* php worker rules for `T_NAME_FULLY_QUALIFIED`, `T_NAME_QUALIFIED`, `T_NAME_RELATIVE` namespaced names tokens ([#4948](https://github.com/ajaxorg/ace/issues/4948)) ([059ff71](https://github.com/ajaxorg/ace/commit/059ff7186ac95d38fa11821488c847d3786d3486))\n* tools to work with new ace project structure ([7894c4b](https://github.com/ajaxorg/ace/commit/7894c4bbc6da5eb3521efb3b89b1a189202c2497))\n\n### [1.11.2](https://github.com/ajaxorg/ace/compare/v1.11.1...v1.11.2) (2022-09-26)\n\n\n### Bug Fixes\n\n* Fixed handling surrogare characters in insert, replace, delete mode in Vim ([72fd4b7](https://github.com/ajaxorg/ace/commit/72fd4b7b616f070be198dc8fc437d48a74637a53))\n* Fixed handling surrogate characters in insert-after mode in Vim ([38f893a](https://github.com/ajaxorg/ace/commit/38f893a13b1f1dedea4407a8f3ef1d6098873269))\n\n### [1.11.1](https://github.com/ajaxorg/ace/compare/v1.11.0...v1.11.1) (2022-09-23)\n\n\n### Bug Fixes\n\n* Discrepancy between keywords used by mode-aql.js in the current version and the version used by arangodb ([1503dd0](https://github.com/ajaxorg/ace/commit/1503dd06f2d651d16af964978fb8c62e0304b6d6))\n* The editor can be crashed by passing in undefined into the setValue method ([56e6e56](https://github.com/ajaxorg/ace/commit/56e6e56137ea5717009e3687019f64dae7f88da2))\n* Update vim mode ([#4933](https://github.com/ajaxorg/ace/issues/4933)) ([3b89ed0](https://github.com/ajaxorg/ace/commit/3b89ed06069cb45edb59b7442b5cc6c15b33cfa4))\n\n## [1.11.0](https://github.com/ajaxorg/ace/compare/v1.10.1...v1.11.0) (2022-09-20)\n\n\n### Features\n\n* add gutter indicators for annotations; add custom scrollbar to display gutter indicators ([62fb0d8](https://github.com/ajaxorg/ace/commit/62fb0d8fba813241d01356962ed20ac868a29ede))\n\n\n### Bug Fixes\n\n* change scroll behaviour for `onmousedown` to immediate scroll to point ([392b224](https://github.com/ajaxorg/ace/commit/392b224ceb4e82b4d906c36aef2ea4953e3d440e))\n* Do not try apply highlight indent guide if the file is empty ([#4928](https://github.com/ajaxorg/ace/issues/4928)) ([a90ef27](https://github.com/ajaxorg/ace/commit/a90ef275298b524c493076e47aae13036f6e6271))\n* restrict annotation mark max height and optimise marks coords on canvas ([a6e2259](https://github.com/ajaxorg/ace/commit/a6e2259eb0a282c62fd9e6fde31d86b6c14ec06d))\n\n### [1.10.1](https://github.com/ajaxorg/ace/compare/v1.10.0...v1.10.1) (2022-09-06)\n\n\n### Bug Fixes\n\n* prevent javascript snippets file confusing old packagers ([#4917](https://github.com/ajaxorg/ace/issues/4917)) ([5d7b65c](https://github.com/ajaxorg/ace/commit/5d7b65c30aff0106a7001f68ecdf13a23893eaad))\n\n## [1.10.0](https://github.com/ajaxorg/ace/compare/v1.9.6...v1.10.0) (2022-08-31)\n\n\n### Features\n\n* editor option for indent guide highlighting ([f1f6517](https://github.com/ajaxorg/ace/commit/f1f6517a30d6819d1c8ca045744cdeb2925ccf0a))\n\n\n### Bug Fixes\n\n* add mock `getHighlightIndentGuides` and `setHighlightIndentGuides` for old tests to work ([4067512](https://github.com/ajaxorg/ace/commit/4067512a72934b23a0866eca33812425c37a7363))\n* added \"flex-start\" and \"flex-end\" ([#4912](https://github.com/ajaxorg/ace/issues/4912)) ([3e14988](https://github.com/ajaxorg/ace/commit/3e14988209354f94483307f168705690e15adaf5))\n* Fix problematic semicolon in CSS media queries ([#4849](https://github.com/ajaxorg/ace/issues/4849)) ([18a459a](https://github.com/ajaxorg/ace/commit/18a459a26430bfa58e0f798c4bacce6a799c77bd))\n* more optimal way to accessing an element's list of classes; mark `highlightIndentGuide` as internal property ([855a874](https://github.com/ajaxorg/ace/commit/855a874ffde4824bb8de6e56cb44fad64d49725b))\n* strictly equal instead of loosely ([d4c1ab8](https://github.com/ajaxorg/ace/commit/d4c1ab8ef6ee608e2570b7ca6d1d941c5a6628a9))\n* Updated Jshint to 2.13.5 ([#4911](https://github.com/ajaxorg/ace/issues/4911)) ([2401fbd](https://github.com/ajaxorg/ace/commit/2401fbd93f0d61cc01150c1071145e974dd6693f))\n\n### [1.9.6](https://github.com/ajaxorg/ace/compare/v1.9.5...v1.9.6) (2022-08-17)\n\n\n### Bug Fixes\n\n* better way to extract css for csp environments ([1b0612b](https://github.com/ajaxorg/ace/commit/1b0612b5a5ed33a2f1931e4aa08cb2d54ec8585c))\n\n### [1.9.5](https://github.com/ajaxorg/ace/compare/v1.9.4...v1.9.5) (2022-08-10)\n\n\n### Bug Fixes\n\n* reverted fix build script CSS extract with `options.compress` ([#4894](https://github.com/ajaxorg/ace/issues/4894)) ([8fa4500](https://github.com/ajaxorg/ace/commit/8fa45008887c957bc9c78c65e805e73240f2b33f))\n\n### [1.9.4](https://github.com/ajaxorg/ace/compare/v1.9.2...v1.9.4) (2022-08-09)\n\n### [1.9.3](https://github.com/ajaxorg/ace/compare/v1.9.2...v1.9.3) (2022-08-08)\n\n### [1.9.2](https://github.com/ajaxorg/ace/compare/v1.9.1...v1.9.2) (2022-08-08)\n\n### [1.9.1](https://github.com/ajaxorg/ace/compare/v1.9.0...v1.9.1) (2022-08-08)\n\n## [1.9.0](https://github.com/ajaxorg/ace/compare/v1.8.1...v1.9.0) (2022-08-08)\n\n\n### Features\n\n* added ability to limit amount of undos/redos ([#4872](https://github.com/ajaxorg/ace/issues/4872)) ([897ee0a](https://github.com/ajaxorg/ace/commit/897ee0a071ef4341338a285a1d9d8781fe5689de))\n* publish Ace source code to ace-code NPM package ([#4881](https://github.com/ajaxorg/ace/issues/4881)) ([66cf041](https://github.com/ajaxorg/ace/commit/66cf0418bedf221a507d9a173583538c97885410))\n\n\n### Bug Fixes\n\n* Fix determination of anonymous code blocks in Postgres Mode (fixes [#4790](https://github.com/ajaxorg/ace/issues/4790)) ([06f7e22](https://github.com/ajaxorg/ace/commit/06f7e2290543ca6566aab56228a8fc8daddfcf55))\n* Fixed Ace typings ([23208f2](https://github.com/ajaxorg/ace/commit/23208f2f19020d1f69b90bc3b02460bda8422072))\n* Fixed jsDoc annotations ([e15abb4](https://github.com/ajaxorg/ace/commit/e15abb443abfad2de59c620ce49fc5498ce6d33e)), closes [#4879](https://github.com/ajaxorg/ace/issues/4879)\n* refactor of kotlin mode to simplify states and resolve incorrect highlights ([a30a99d](https://github.com/ajaxorg/ace/commit/a30a99df731c2f10c2006181ca58a96e7fc21155))\n* returned precise highlight for functions params, generics and types ([967aa6b](https://github.com/ajaxorg/ace/commit/967aa6b05c4a69a5deac1b20c297648444ade7d6))\n* Rust identifiers normally recognised now; generics highlight support; doc comments support ([#4868](https://github.com/ajaxorg/ace/issues/4868)) ([bbb5800](https://github.com/ajaxorg/ace/commit/bbb5800b4cf56d2996691edc63edc2783e19f427))\n\n### [1.8.1](https://github.com/ajaxorg/ace/compare/v1.8.0...v1.8.1) (2022-07-21)\n\n\n### Bug Fixes\n\n* prevent race condition when creating css files in build ([1777bfb](https://github.com/ajaxorg/ace/commit/1777bfb7dca4dcaf575293ac9cacbc284f692351))\n\n## [1.8.0](https://github.com/ajaxorg/ace/compare/v1.7.1...v1.8.0) (2022-07-20)\n\n\n### Features\n\n* Use mini require ([#4845](https://github.com/ajaxorg/ace/issues/4845)) ([b9fabd4](https://github.com/ajaxorg/ace/commit/b9fabd47c0765d40117809cd3978b95d593370fb))\n\n\n### Bug Fixes\n\n* add undocumented Target command ([62e8e9e](https://github.com/ajaxorg/ace/commit/62e8e9e4d3b21552dd83d454b7fd55d4981d096a)), closes [#4839](https://github.com/ajaxorg/ace/issues/4839)\n* added NSIS 3.08 commands ([acad68c](https://github.com/ajaxorg/ace/commit/acad68cf92f5372257b061e300e31f71df9c62e9)), closes [#4838](https://github.com/ajaxorg/ace/issues/4838)\n* **bidihandler:** check for undefined before access length property on `splits` variable ([457b657](https://github.com/ajaxorg/ace/commit/457b65748f331740ded529fd7bbd06b86819fa4e))\n* correct highlight of php heredoc strings with one word on line ([ae4564c](https://github.com/ajaxorg/ace/commit/ae4564c2961b006ca849625a0dee1093061eba5a))\n* Fixed typo in Nord Dark theme. ([#4843](https://github.com/ajaxorg/ace/issues/4843)) ([38bf666](https://github.com/ajaxorg/ace/commit/38bf6663f43be1c45bfba3dc68c4a4820fb2661d))\n* Move session.onChange and placeholder.onChange handlers to be first in the change event handler queue ([bcb51f2](https://github.com/ajaxorg/ace/commit/bcb51f2b2a2ba2e1f30ebf543d97e7450574763f))\n* reuse `getTargetDir` function ([b89c4db](https://github.com/ajaxorg/ace/commit/b89c4db3424687856ff9c9e732435c35438b0cb9))\n* type declarations ([a8830fc](https://github.com/ajaxorg/ace/commit/a8830fc83708a7e51053038f1c6d7fde23e82e9d))\n\n### [1.7.1](https://github.com/ajaxorg/ace/compare/v1.7.0...v1.7.1) (2022-06-29)\n\n\n### Bug Fixes\n\n* Fixed accessing properties when err is null in onerror handler ([3b62a07](https://github.com/ajaxorg/ace/commit/3b62a0713e68fd76bfa9c52fa2112b56888d2349))\n* Uncaught TypeError: Cannot read properties of undefined in worker code ([ce068ac](https://github.com/ajaxorg/ace/commit/ce068ac29f0056f6a10d0fc99181b8ba3e274cfe))\n\n## [1.7.0](https://github.com/ajaxorg/ace/compare/v1.6.1...v1.7.0) (2022-06-28)\n\n\n### Features\n\n* Add Robot Framework syntax highlighting ([773c0c5](https://github.com/ajaxorg/ace/commit/773c0c5d8b87fabb643d8c1e2053f536c53318e8)), closes [#4614](https://github.com/ajaxorg/ace/issues/4614)\n* Added YAML language linter ([451f915](https://github.com/ajaxorg/ace/commit/451f915e645f8a172098316196ae2e029fc26aed)), closes [#3979](https://github.com/ajaxorg/ace/issues/3979)\n\n\n### Bug Fixes\n\n* Added two tmthemes gruvbox dark (hard) and light (hard) ([6b1e67f](https://github.com/ajaxorg/ace/commit/6b1e67f844056fd238a35094e8f4e4b197e0a9a4)), closes [#3673](https://github.com/ajaxorg/ace/issues/3673)\n* adds ignore browserified dir to eslintignore ([56b591b](https://github.com/ajaxorg/ace/commit/56b591b49673fcd062fd53325f74629d4cf45e3f))\n* Allow setAnnotations to use custom className ([f505879](https://github.com/ajaxorg/ace/commit/f505879d0463a8b2781e0e7caaaa857444d51f85)), closes [#4362](https://github.com/ajaxorg/ace/issues/4362)\n* Avoid substitutions when Webpack was introduced ([a540323](https://github.com/ajaxorg/ace/commit/a540323e933c6bad164bdc9f103d8de744ee1546)), closes [#4476](https://github.com/ajaxorg/ace/issues/4476)\n* Highlighting DISTINCT keyword in SQL ([fb3820a](https://github.com/ajaxorg/ace/commit/fb3820a9c1624c49a149d388bf26aa3d504704bb)), closes [#4399](https://github.com/ajaxorg/ace/issues/4399)\n* Make sure completions aren't null or undefined ([a78e127](https://github.com/ajaxorg/ace/commit/a78e127e8fd7d724b96208447caa384783616323)), closes [#4608](https://github.com/ajaxorg/ace/issues/4608)\n\n### [1.6.1](https://github.com/ajaxorg/ace/compare/v1.6.0...v1.6.1) (2022-06-24)\n\n\n### Bug Fixes\n\n* Highlight unicode characters in Python function and class names ([be6f2d1](https://github.com/ajaxorg/ace/commit/be6f2d125a8ffe70ceb336051da6a161ce9cf1bc))\n* Incorrect YAML syntax highlighting for version numbers with multiple periods ([049d761](https://github.com/ajaxorg/ace/commit/049d76131e6122f7397fb30cc341db34baaf2813))\n* Incorrect YAML syntax highlighting for version numbers with multiple periods [#4827](https://github.com/ajaxorg/ace/issues/4827) ([915fcaf](https://github.com/ajaxorg/ace/commit/915fcaf542469a7dc0e3e7235f23a66a3abaadb9))\n\n## [1.6.0](https://github.com/ajaxorg/ace/compare/v1.5.3...v1.6.0) (2022-06-10)\n\n\n### Bug Fixes\n\n* Add class to tooltip DOM element distinguish errors from warnings ([#4810](https://github.com/ajaxorg/ace/issues/4810)) ([d2446d6](https://github.com/ajaxorg/ace/commit/d2446d68e7ace4d1a860de6a5a3e5031f074161b))\n* Autocomplete stopped working after upgrade to v1.5.2 ([48e6b60](https://github.com/ajaxorg/ace/commit/48e6b601ad5ae03a99a341843194c3854d2376c2))\n* Fix css EOF duplicate errors [#4816](https://github.com/ajaxorg/ace/issues/4816) ([48176f6](https://github.com/ajaxorg/ace/commit/48176f66c8ca0dd239968329b471f55b548ee467))\n* Fix overflow button for long lines with one token ([#4818](https://github.com/ajaxorg/ace/issues/4818)) ([3f93451](https://github.com/ajaxorg/ace/commit/3f934510514a25c53edf64bb80911a96b7133908))\n\n### [1.5.3](https://github.com/ajaxorg/ace/compare/v1.5.2...v1.5.3) (2022-05-31)\n\n\n### Bug Fixes\n\n* Colors for variable, function and constant should be different ([#4802](https://github.com/ajaxorg/ace/issues/4802)) ([9e81bda](https://github.com/ajaxorg/ace/commit/9e81bdafc3d563421cae458259d4c4e1b449a237))\n\n### [1.5.2](https://github.com/ajaxorg/ace/compare/v1.5.1...v1.5.2) (2022-05-30)\n\n\n### Bug Fixes\n\n* Added es6-shim library to fix old browsers ([#4720](https://github.com/ajaxorg/ace/issues/4720)) ([5ba71a0](https://github.com/ajaxorg/ace/commit/5ba71a0b8b0804d8cb385f7b2ee6b63e9bd1c3b8))\n* Added mockdom.before method ([#4724](https://github.com/ajaxorg/ace/issues/4724)) ([ffedba3](https://github.com/ajaxorg/ace/commit/ffedba3e18138d7739285d1a9b945d01d384948e))\n* Added support for cjs, mjs and log modes ([#4718](https://github.com/ajaxorg/ace/issues/4718)) ([375498a](https://github.com/ajaxorg/ace/commit/375498a12ff28cf955224baf60d242421817220d))\n* Adds missed functions into `php_completions.js` ([#4726](https://github.com/ajaxorg/ace/issues/4726)) ([7d5f4b8](https://github.com/ajaxorg/ace/commit/7d5f4b83f3ecc854e70f1508e9247e39ca9de30a))\n* Cannot read property of null for bgTokenizer after session is destroyed ([#4713](https://github.com/ajaxorg/ace/issues/4713)) ([d604f52](https://github.com/ajaxorg/ace/commit/d604f52d60e3ec2dced126337ad46a2cf71bf294))\n* Do not render selected word markers for the same range multiple times ([#4727](https://github.com/ajaxorg/ace/issues/4727)) ([cd30f59](https://github.com/ajaxorg/ace/commit/cd30f591e40d5286fdabaa9f688f3c6066fbffff))\n* Fixed popup CSS styling ([#4728](https://github.com/ajaxorg/ace/issues/4728)) ([045a3e6](https://github.com/ajaxorg/ace/commit/045a3e652ec37b1ab3b716cdf2bc24967a75eb77))\n* Fixed scrolling code lenses into view ([#4717](https://github.com/ajaxorg/ace/issues/4717)) ([710b14a](https://github.com/ajaxorg/ace/commit/710b14a7709d7499a4d182ad707b3cbbb6e73a64))\n* Multiple improvements for Ace themes ([#4715](https://github.com/ajaxorg/ace/issues/4715)) ([87ad55d](https://github.com/ajaxorg/ace/commit/87ad55daf243bdc619e15fbf220dc5ded235ed4c))\n* Only send postMessage through worker if it's defined ([#4722](https://github.com/ajaxorg/ace/issues/4722)) ([2afa4bf](https://github.com/ajaxorg/ace/commit/2afa4bf91bbc99f29bd0a7c1f0adc600af2ceeae))\n* Pass additional arguments for command.exec ([#4723](https://github.com/ajaxorg/ace/issues/4723)) ([3b36762](https://github.com/ajaxorg/ace/commit/3b36762c045246efbc2e11eaa08d20a90142d26f))\n* Removed focussing after timeout in text input ([#4716](https://github.com/ajaxorg/ace/issues/4716)) ([f8ea48f](https://github.com/ajaxorg/ace/commit/f8ea48f1fe6362696ed30e01030e75c117ce4323))\n* Throw invalid delta error if change is out of range and added V2 for worker and worker client ([#4721](https://github.com/ajaxorg/ace/issues/4721)) ([f269889](https://github.com/ajaxorg/ace/commit/f2698895d6617f1c7ebeed14b7ecbb1c5d71bb51))\n* Updated ace typings ([#4714](https://github.com/ajaxorg/ace/issues/4714)) ([d5d6f9a](https://github.com/ajaxorg/ace/commit/d5d6f9a32ad443d02aa89d9f140917637f5f52ab))\n\n### [1.5.1](https://github.com/ajaxorg/ace/compare/v1.5.0...v1.5.1) (2022-05-23)\n\n\n### Bug Fixes\n\n* Correctly tokenize YAML meta tags with non alphabetical characters after multiline string ([#4706](https://github.com/ajaxorg/ace/issues/4706)) ([0164811](https://github.com/ajaxorg/ace/commit/0164811fd95ecae9a46ce6fd7278e9c8b0b48eed))\n* Made commas be tokenized as punctuation operator instead of text in JSON ([#4703](https://github.com/ajaxorg/ace/issues/4703)) ([4c4883a](https://github.com/ajaxorg/ace/commit/4c4883a854836b652dbb798b78f207ae4b1924b8))\n* Multiple Partiql and Amazon Ion textual notation fixes ([#4686](https://github.com/ajaxorg/ace/issues/4686)) ([bffba8d](https://github.com/ajaxorg/ace/commit/bffba8d934773bc9236d741f1a1ce2237a971b3e))\n* PHP syntax fix for AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG ([#4705](https://github.com/ajaxorg/ace/issues/4705)) ([d59c22b](https://github.com/ajaxorg/ace/commit/d59c22b603eaa9d688249a3cc11812e641f25426))\n* Python functions should be highlighted as functions ([#4708](https://github.com/ajaxorg/ace/issues/4708)) ([b2aaf1f](https://github.com/ajaxorg/ace/commit/b2aaf1f5644397959bd8c94e9e705da176242edd))\n* Updated PHP mode to support PHP8.1 syntax ([#4696](https://github.com/ajaxorg/ace/issues/4696)) ([33cf1c6](https://github.com/ajaxorg/ace/commit/33cf1c66af970edaf7eb0a468276fca249b8a5c8))\n\n## [1.5.0](https://github.com/ajaxorg/ace/compare/v1.4.14...v1.5.0) (2022-05-12)\n\n\n### Features\n\n* Added ability to configure certain format options for beautify extension ([20275de](https://github.com/ajaxorg/ace/commit/20275de79c40636d27d5ce293cf528c915338fbd))\n\n\n### Bug Fixes\n\n* Modify syntax ([b78d772](https://github.com/ajaxorg/ace/commit/b78d77240e1909b9d91fcd2ac35a4c17af05f56b))\n* Render bidirectional unicode characters as control characters ([#4693](https://github.com/ajaxorg/ace/issues/4693)) ([4d2ecf0](https://github.com/ajaxorg/ace/commit/4d2ecf08afeb1556f2511a1423729c2549802da8))\n\n2022.01.26 Version 1.4.14\n\n- update vim mode\n- remove slow regex in beautify extension\n\n  2021.09.30 Version 1.4.13\n\n- added useStrictCSP global option to use in environments where dynamic style creation is disabled\n  see demo/csp.html for an example of a page which loads external css files instead of generating styles with javascript\n- updated vim mode, added support for gqq command\n\n  2020.07.06 Version 1.4.12\n\n- removed unused es5-shim\n- imporved ruby and vbscript highlighting and folding\n- workaround for double space being converted to dot on mobile keyboards\n\n  2020.04.15 Version 1.4.10\n\n- added workaround for chrome bug causing memory leak after calling editor.destroy\n- added code folding support for vbscript mode\n\n  2020.04.01 Version 1.4.9\n\n- added option to disable autoindent\n- added new language modes\n- fixed backspace not working with some mobile keyboards\n\n  2020.01.14 Version 1.4.8\n\n- highlight both matched braces, and highlight unmatched brace in red\n- improve snippet manager\n- compatibility with webpack file-loader v5\n- improve vim mode\n\n  2019.10.17 Version 1.4.7\n\n- add placeholder option\n\n  2019.09.08 Version 1.4.6\n\n- restore native behavior of ctrl-p on mac (jumptomatching command is moved to cmd-\\)\n- improve snippet manager\n- fix backspace handling on mobile\n\n  2019.06.17 Version 1.4.5\n\n- improve scrolling and selection on mobile\n- improve type definitions\n\n  2019.04.24 Version 1.4.4\n\n- add experimental command prompt\n- add chrystal, nim and nginx highlight rules\n- fix regression in vim mode on ios\n\n  2019.02.21 Version 1.4.3\n\n- add sublime keybindings\n- add rtl option\n- implement ` and < textobjects in vim mode\n\n  2018.11.21 Version 1.4.2\n\n- fix regression in vim mode\n- improve keyboard input handling on ipad and IE\n- add new syntax highlighters\n\n  2018.08.07 Version 1.4.1\n\n- fix regression in autocomplete\n\n  2018.08.06 Version 1.4.0\n\n- remove usage of innerHTML\n- improved handling of textinput for IME and mobile\n- add support for relative line numbers\n- improve autocompletion popup\n\n  2018.03.26 Version 1.3.3\n\n- fix regession in static-highlight extension\n- use css animation for cursor blinking\n\n  2018.03.21 Version 1.3.2\n\n- add experimental support for using ace-builds with webpack\n\n  2018.02.11 Version 1.3.1\n\n- fixed regression with selectionChange event not firing some times\n- improved handling of non-ascii characters in vim normal mode\n\n  2018.01.31 Version 1.3.0\n\n- added copy copyWithEmptySelection option\n- improved undoManager\n- improved settings_menu plugin\n- improved handling of files with very long lines\n- fixed bug with scrolling editor out of view in transformed elements\n\n  2017.10.17 Version 1.2.9\n\n- added support for bidirectional text, with monospace font (Alex Shensis)\n- added support for emoji 😊\n\n- new language modes\n\n  - Red (Toomas Vooglaid)\n  - CSound (Nathan Whetsell)\n  - JSSM (John Haugeland)\n\n- New Themes\n\n  - Dracula (Austin Schwartz)\n\n    2017.07.02 Version 1.2.8\n\n- Fixed small bugs in searchbox and autocompleter\n\n  2017.06.18 Version 1.2.7\n\n- Added Support for arrow keys on external IPad keyboard (Emanuele Tamponi)\n- added match counter to searchbox extension\n\n* implemented higlighting of multiline strings in yaml mode (Maxim Trushin)\n* improved haml syntax highlighter (Andrés Álvarez)\n\n  2016.12.03 Version 1.2.6\n\n- Fixed IME handling on new Chrome\n- Support for php 7 in the syntax checker\n\n  2016.08.16 Version 1.2.5\n\n- Fixed regression in noconflict mode\n\n  2016.07.27 Version 1.2.4\n\n- Maintenance release with several new modes and small bugfixes\n\n  2016.01.17 Version 1.2.3\n\n- Bugfixes\n  - fix memory leak in setSession (Tyler Stalder)\n  - double click not working on linux/mac\n- new language modes\n\n  - reStructuredText (Robin Jarry)\n  - NSIS (Jan T. Sott)\n\n    2015.10.28 Version 1.2.1\n\n- new language modes\n\n  - Swift\n  - JSX\n\n    2015.07.11 Version 1.2.0\n\n- New Features\n\n  - Indented soft wrap (danyaPostfactum)\n  - Rounded borders on selections\n\n- API Changes\n\n  - unified delta types `{start, end, action, lines}` (Alden Daniels https://github.com/ajaxorg/ace/pull/1745)\n  - \"change\" event listeners on session and editor get delta objects directly\n\n- new language modes\n\n  - SQLServer (Morgan Yarbrough)\n\n    2015.04.03 Version 1.1.9\n\n  - Small Enhancements and Bugfixes\n\n    2014.11.08 Version 1.1.8\n\n- API Changes\n  - `editor.commands.commandKeyBinding` now contains direct map from keys to commands instead of grouping them by hashid\n- New Features\n  - Improved autoindent for html and php modes (Adam Jimenez)\n  - Find All from searchbox (Colton Voege)\n- new language modes\n\n  - Elixir, Elm\n    2014.09.21 Version 1.1.7\n\n- Bugfixes\n\n  - fix several bugs in autocompletion\n  - workaround for inaccurate getBoundingClientRect on chrome 37\n\n    2014.08.17 Version 1.1.6\n\n- Bugfixes\n  - fix regression in double tap to highlight\n  - Improved Latex Mode (Daniel Felder)\n- API Changes\n\n  - editor.destroy destroys editor.session too (call editor.setSession(null) to prevent that)\n\n- new language modes\n\n* Praat (José Joaquín Atria)\n* Eiffel (Victorien Elvinger)\n* G-code (Adam Joseph Cook)\n  2014.07.09 Version 1.1.5\n\n- Bugfixes\n\n  - fix regression in autocomplete popup\n\n- new language modes\n\n* gitignore (Devon Carew)\n  2014.07.01 Version 1.1.4\n\n- New Features\n\n  - Highlight matching tags (Adam Jimenez)\n  - Improved jump to matching command (Adam Jimenez)\n\n- new language modes\n\n* AppleScript (Yaogang Lian)\n* Vala\n\n  2014.03.08 Version 1.1.3\n\n- New Features\n\n  - Allow syntax checkers to be loaded from CDN (Derk-Jan Hartman)\n  - Add ColdFusion behavior (Abram Adams)\n  - add showLineNumbers option\n  - Add html syntax checker (danyaPostfactum)\n\n- new language modes\n\n  - Gherkin (Patrick Nevels)\n  - Smarty\n\n    2013.12.02 Version 1.1.2\n\n- New Features\n  - Accessibility Theme for Ace (Peter Xiao)\n  - use snipetManager for expanding emmet snippets\n  - update jshint to 2.1.4\n  - improve php syntax checker (jdalegonzalez)\n  - add option for autoresizing\n  - add option for autohiding vertical scrollbar\n  - improvements to highlighting of xml like languages (danyaPostfactum)\n  - add support for autocompletion and snippets (gjtorikyan danyaPostfactum and others)\n  - add option to merge similar changes in undo history\n  - add scrollPastEnd option\n  - use html5 dragndrop for text dragging (danyaPostfactum)\n- API Changes\n\n  - fixed typo in HashHandler commmandManager\n\n- new language modes\n\n  - Nix (Zef Hemel)\n  - Protobuf (Zef Hemel)\n  - Soy\n  - Handlebars\n\n    2013.06.04 Version 1.1.1\n\n  - Improved emacs keybindings (Robert Krahn)\n  - Added markClean, isClean methods to UndoManager (Joonsoo Jeon)\n  - Do not allow `Toggle comments` command to remove spaces from indentation\n  - Softer colors for indent guides in dark themes\n\n- new language modes\n\n  - Ada\n  - Assembly_x86\n  - Cobol\n  - D\n  - ejs\n  - MATLAB\n  - MySQL\n  - Twig\n  - Verilog\n\n    2013.05.01, Version 1.1.0\n\n- API Changes\n\n  - Default position of the editor container is changed to relative. Add `.ace_editor {position: absolute}` css rule to restore old behavior\n  - Changed default line-height to `normal` to not conflict with bootstrap. Use `line-height: inherit` for old behavior.\n  - Changed marker types accepted by session.addMarker. It now accepts \"text\"|\"line\"|\"fullLine\"|\"screenLine\"\n  - Internal classnames used by editor were made more consistent\n  - Introduced `editor.setOption/getOption/setOptions/getOptions` methods\n  - Introduced positionToIndex, indexToPosition methods\n\n- New Features\n\n  - Improved emacs mode (chetstone)\n    with Incremental search and Occur modes (Robert Krahn)\n\n  - Improved ime handling\n  - Searchbox (Vlad Zinculescu)\n\n  - Added elastic tabstops lite extension (Garen Torikian)\n  - Added extension for whitespace manipulation\n  - Added extension for enabling spellchecking from contextmenu\n  - Added extension for displaying available keyboard shortcuts (Matthew Christopher Kastor-Inare III)\n  - Added extension for displaying options panel (Matthew Christopher Kastor-Inare III)\n  - Added modelist extension (Matthew Christopher Kastor-Inare III)\n\n  - Improved toggleCommentLines and added ToggleCommentBlock command\n  - `:;` pairing in CSS mode (danyaPostfactum)\n\n  - Added suppoert for Delete and SelectAll from context menu (danyaPostfactum)\n\n  - Make wrapping behavior optional\n  - Selective bracket insertion/skipping\n  - Added commands for increase/decrease numbers, sort lines (Vlad Zinculescu)\n  - Folding for Markdown, Lua, LaTeX\n  - Selective bracket insertion/skipping for C-like languages\n\n- Many new languages\n\n  - Scheme (Mu Lei)\n  - Dot (edwardsp)\n  - FreeMarker (nguillaumin)\n  - Tiny Mushcode (h3rb)\n  - Velocity (Ryan Griffith)\n  - TOML (Garen Torikian)\n  - LSL (Nemurimasu Neiro, Builders Brewery)\n  - Curly (Libo Cannici)\n  - vbScript (Jan Jongboom)\n  - R (RStudio)\n  - ABAP\n  - Lucene (Graham Scott)\n  - Haml (Garen Torikian)\n  - Objective-C (Garen Torikian)\n  - Makefile (Garen Torikian)\n  - TypeScript (Garen Torikian)\n  - Lisp (Garen Torikian)\n  - Stylus (Garen Torikian)\n  - Dart (Garen Torikian)\n\n- Live syntax checks\n\n  - PHP (danyaPostfactum)\n  - Lua\n\n- New Themes\n\n  - Chaos\n  - Terminal\n    2012.09.17, Version 1.0.0\n\n- New Features\n\n  - Multiple cursors and selections (https://c9.io/site/blog/2012/08/be-an-armenian-warrior-with-block-selection-on-steroids/)\n  - Fold buttons displayed in the gutter\n  - Indent Guides\n  - Completely reworked vim mode (Sergi Mansilla)\n  - Improved emacs keybindings\n  - Autoclosing of html tags (danyaPostfactum)\n\n- 20 New language modes\n\n  - Coldfusion (Russ)\n  - Diff\n  - GLSL (Ed Mackey)\n  - Go (Davide Saurino)\n  - Haxe (Jason O'Neil)\n  - Jade (Garen Torikian)\n  - jsx (Syu Kato)\n  - LaTeX (James Allen)\n  - Less (John Roepke)\n  - Liquid (Bernie Telles)\n  - Lua (Lee Gao)\n  - LuaPage (Choonster)\n  - Markdown (Chris Spencer)\n  - PostgreSQL (John DeSoi)\n  - Powershell (John Kane)\n  - Sh (Richo Healey)\n  - SQL (Jonathan Camile)\n  - Tcl (Cristoph Hochreiner)\n  - XQuery (William Candillion)\n  - Yaml (Meg Sharkey)\n\n  * Live syntax checks\n\n  - for XQuery and JSON\n\n- New Themes\n\n  - Ambiance (Irakli Gozalishvili)\n  - Dreamweaver (Adam Jimenez)\n  - Github (bootstraponline)\n  - Tommorrow themes (https://github.com/chriskempson/tomorrow-theme)\n  - XCode\n\n- Many Small Enhancements and Bugfixes\n\n  2011.08.02, Version 0.2.0\n\n- Split view (Julian Viereck)\n\n  - split editor area horizontally or vertivally to show two files at the same\n    time\n\n- Code Folding (Julian Viereck)\n\n  - Unstructured code folding\n  - Will be the basis for language aware folding\n\n- Mode behaviours (Chris Spencer)\n\n  - Adds mode specific hooks which allow transformations of entered text\n  - Autoclosing of braces, paranthesis and quotation marks in C style modes\n  - Autoclosing of angular brackets in XML style modes\n\n- New language modes\n  - Clojure (Carin Meier)\n  - C# (Rob Conery)\n  - Groovy (Ben Tilford)\n  - Scala (Ben Tilford)\n  - JSON\n  - OCaml (Sergi Mansilla)\n  - Perl (Panagiotis Astithas)\n  - SCSS/SASS (Andreas Madsen)\n  - SVG\n  - Textile (Kelley van Evert)\n  - SCAD (Jacob Hansson)\n- Live syntax checks\n\n  - Lint for CSS using CSS Lint <http://csslint.net/>\n  - CoffeeScript\n\n- New Themes\n\n  - Crimson Editor (iebuggy)\n  - Merbivore (Michael Schwartz)\n  - Merbivore soft (Michael Schwartz)\n  - Solarized dark/light <http://ethanschoonover.com/solarized> (David Alan Hjelle)\n  - Vibrant Ink (Michael Schwartz)\n\n- Small Features/Enhancements\n\n  - Lots of render performance optimizations (Harutyun Amirjanyan)\n  - Improved Ruby highlighting (Chris Wanstrath, Trent Ogren)\n  - Improved PHP highlighting (Thomas Hruska)\n  - Improved CSS highlighting (Sean Kellogg)\n  - Clicks which cause the editor to be focused don't reset the selection\n  - Make padding text layer specific so that print margin and active line\n    highlight are not affected (Irakli Gozalishvili)\n  - Added setFontSize method\n  - Improved vi keybindings (Trent Ogren)\n  - When unfocused make cursor transparent instead of removing it (Harutyun Amirjanyan)\n  - Support for matching groups in tokenizer with arrays of tokens (Chris Spencer)\n\n- Bug fixes\n\n  - Add support for the new OSX scroll bars\n  - Properly highlight JavaScript regexp literals\n  - Proper handling of unicode characters in JavaScript identifiers\n  - Fix remove lines command on last line (Harutyun Amirjanyan)\n  - Fix scroll wheel sluggishness in Safari\n  - Make keyboard infrastructure route keys like []^$ the right way (Julian Viereck)\n\n    2011.02.14, Version 0.1.6\n\n- Floating Anchors\n  - An Anchor is a floating pointer in the document.\n  - Whenever text is inserted or deleted before the cursor, the position of\n    the cursor is updated\n  - Usesd for the cursor and selection\n  - Basis for bookmarks, multiple cursors and snippets in the future\n- Extensive support for Cocoa style keybindings on the Mac <https://github.com/ajaxorg/ace/issues/closed#issue/116/comment/767803>\n- New commands:\n  - center selection in viewport\n  - remove to end/start of line\n  - split line\n  - transpose letters\n- Refator markers\n  - Custom code can be used to render markers\n  - Markers can be in front or behind the text\n  - Markers are now stored in the session (was in the renderer)\n- Lots of IE8 fixes including copy, cut and selections\n- Unit tests can also be run in the browser\n  <https://github.com/ajaxorg/ace/blob/master/lib/ace/test/tests.html>\n- Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng)\n- Add minimal node server server.js to run the Ace demo in Chrome\n- The top level editor.html demo has been renamed to index.html\n- Bug fixes\n\n  - Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen)\n  - Fixed isues when the editor was scrolled in the web page (Eric Allam)\n  - Highlighting of Python string literals\n  - Syntax rule for PHP comments\n\n    2011.02.08, Version 0.1.5\n\n- Add Coffeescript Mode (Satoshi Murakami)\n- Fix word wrap bug (Julian Viereck)\n- Fix packaged version of the Eclipse mode\n- Loading of workers is more robust\n- Fix \"click selection\"\n- Allow tokizing empty lines (Daniel Krech)\n- Make PageUp/Down behavior more consistent with native OS (Joe Cheng)\n\n  2011.02.04, Version 0.1.4\n\n- Add C/C++ mode contributed by Gastón Kleiman\n- Fix exception in key input\n\n  2011.02.04, Version 0.1.3\n\n- Let the packaged version play nice with requireJS\n- Add Ruby mode contributed by Shlomo Zalman Heigh\n- Add Java mode contributed by Tom Tasche\n- Fix annotation bug\n- Changing a document added a new empty line at the end\n"
  },
  {
    "path": "CNAME",
    "content": "ace.c9.io"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "## Code of Conduct\nThis project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). \nFor more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact \nopensource-codeofconduct@amazon.com with any additional questions or comments.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n------------\n\nAce is a community project and wouldn't be what it is without contributions! We actively encourage and support contributions. The Ace source code is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings!\n\nFeel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. Do make sure that your changes are covered by test cases to pass the pull request checks which exists inorder to keep ace robust.\n\nHappy coding, Cloud9\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2010, Ajax.org B.V.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of Ajax.org B.V. nor the\n      names of its contributors may be used to endorse or promote products\n      derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY : doc build clean dist\n\npre_build:\n\tgit rev-parse HEAD > .git-ref\n\tmkdir -p build/src\n\tmkdir -p build/demo/kitchen-sink\n\tmkdir -p build/textarea/src\n\t\n\tcp -r demo/kitchen-sink/styles.css build/demo/kitchen-sink/styles.css\n\tcp demo/kitchen-sink/logo.png build/demo/kitchen-sink/logo.png\n\tcp -r doc/site/images build/textarea\n\nbuild: pre_build\n\t./Makefile.dryice.js normal\n\t./Makefile.dryice.js demo\n\n# Minimal build: call Makefile.dryice.js only if our sources changed\nbasic: build/src/ace.js\n\nbuild/src/ace.js : ${wildcard lib/*} \\\n                   ${wildcard lib/*/*} \\\n                   ${wildcard lib/*/*/*} \\\n                   ${wildcard lib/*/*/*/*} \\\n                   ${wildcard lib/*/*/*/*/*} \\\n                   ${wildcard lib/*/*/*/*/*/*}\n\t./Makefile.dryice.js\n\ndoc:\n\tcd doc;\\\n\t(test -d node_modules && npm update) || npm install;\\\n\tnode build.js\n\nclean:\n\trm -rf build\n\trm -rf ace-*\n\trm -f ace-*.tgz\n\nace.tgz: build\n\tmv build ace-`./version.js`/\n\tcp Readme.md ace-`./version.js`/\n\tcp LICENSE ace-`./version.js`/\n\ttar cvfz ace-`./version.js`.tgz ace-`./version.js`/\n\ndist: clean build ace.tgz\n"
  },
  {
    "path": "Makefile.dryice.js",
    "content": "#!/usr/bin/env node\n/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*global Buffer, setImmediate*/\n\nvar fs = require(\"fs\");\nvar path = require(\"path\");\nvar copy = require('architect-build/copy');\nvar build = require('architect-build/build');\nvar {\n    updateDeclarationModuleNames,\n    generateDeclaration,\n    SEPARATE_MODULES\n} = require('./tool/ace_declaration_generator');\n\nvar ACE_HOME = __dirname;\nvar BUILD_DIR = ACE_HOME + \"/build\";\nvar CACHE = {};\n\nfunction generateAmdModules() {\n    var root = ACE_HOME + \"/\";\n    function iterate(dir) {\n        var filenames = fs.readdirSync(root + dir);\n        filenames.forEach(function(name) {\n            var path = dir + name;\n            var stat = fs.statSync(root + path);\n            var newPath = path.replace(\"src\", \"lib/ace\");\n            if (stat.isDirectory()) {\n                try {\n                    fs.mkdirSync(root + newPath);\n                } catch(e) {}\n                iterate(path + \"/\");\n            } else if (/\\.js/.test(name) && !/worker_client\\.js$/.test(name)) {\n                transform(path, newPath);\n            }\n        });\n    }\n    function transform(path, newPath) {\n        var data = fs.readFileSync(root + path, \"utf-8\");\n        data = \"define(function(require, exports, module){\"\n            + compileTypescript(data)\n            +\"\\n});\";\n        fs.writeFileSync(root + newPath, data, \"utf-8\");\n    }\n    function compileTypescript(code) {\n        var ts = require(\"typescript\");\n        return ts.transpileModule(code, {\n            compilerOptions: {\n                newLine: \"lf\",\n                downlevelIteration: true,\n                suppressExcessPropertyErrors: true,\n                module: ts.ModuleKind.CommonJS,\n                removeComments: false,\n                sourceMap: false,\n                inlineSourceMap: false,\n                target: \"ES5\"\n            },\n            fileName: \"\"\n        }).outputText;\n    }\n\n    iterate(\"src/\");\n}\n\nfunction main(args) {\n    if (args.indexOf(\"updateModes\") !== -1) {\n        return updateModes();\n    }\n    \n    var type = \"minimal\";\n    args = args.map(function(x) {\n        if (x[0] == \"-\" && x[1] != \"-\")\n            return \"-\" + x;\n        return x;\n    }).filter(Boolean);\n\n    if (args[2] && (args[2][0] != \"-\" || args[2].indexOf(\"h\") != -1))\n        type = args[2];\n\n    var i = args.indexOf(\"--target\");\n    if (i != -1 && args[i+1])\n        BUILD_DIR = args[i+1];\n\n    if (args.indexOf(\"--h\") != -1 || args.indexOf(\"-h\") != -1 || args.indexOf(\"--help\") != -1) {\n        return showHelp();\n    }\n    \n    if (type == \"css\") {\n        return extractCss();\n    }\n    if (type == \"nls\") {\n        return extractNls();\n    }\n\n    if (args.indexOf(\"--reuse\") === -1) {\n        console.log(\"updating files in lib/ace\");\n        generateAmdModules();\n    }\n\n    if (type == \"minimal\") {\n        buildAce({\n            compress: args.indexOf(\"--m\") != -1,\n            noconflict: args.indexOf(\"--nc\") != -1,\n            shrinkwrap: args.indexOf(\"--s\") != -1\n        });\n    } else if (type == \"normal\") {\n        ace();\n    } else if (type == \"demo\") {\n        demo();\n    } else if (type == \"full\") {\n        ace();\n        demo();\n    } else if (type == \"highlighter\") {\n        // TODO\n    }\n}\n\nfunction showHelp(type) {\n    console.log(\"--- Ace Dryice Build Tool ---\");\n    console.log(\"\");\n    console.log(\"Options:\");\n    console.log(\"  minimal      Places necessary Ace files out in build dir; uses configuration flags below [default]\");\n    console.log(\"  normal       Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min\");\n    console.log(\"  demo         Runs demo build of Ace\");\n    console.log(\"  full         all of above\");\n    console.log(\"  highlighter  \");\n    console.log(\"  css          extract css files\");\n    console.log(\"  nls          extract nls messages\");\n    console.log(\"args:\");\n    console.log(\"  --target ./path   path to build folder\");\n    console.log(\"flags:\");\n    console.log(\"  --h                print this help\");\n    console.log(\"  --m                minify\");\n    console.log(\"  --nc               namespace require\");\n    console.log(\"  --s                shrinkwrap (combines all output files into one)\");\n    console.log(\"\");\n    if (type)\n        console.log(\"  output for \" + type + \" generated in \" + BUILD_DIR);\n}\n\nfunction ace() {\n    console.log('# ace License | Readme | Changelog ---------');\n\n    copy.file(ACE_HOME + \"/build_support/editor.html\",  BUILD_DIR + \"/editor.html\");\n    copy.file(ACE_HOME + \"/LICENSE\", BUILD_DIR + \"/LICENSE\");\n    copy.file(ACE_HOME + \"/CHANGELOG.md\", BUILD_DIR + \"/CHANGELOG.md\");\n    \n    console.log('# ace ---------');\n    for (var i = 0; i < 4; i++) {\n        buildAce({compress: i & 2, noconflict: i & 1, check: true});\n    }\n}\n\nfunction correctDeclarationsForBuild(path, additionalDeclarations) {\n    var definitions = fs.readFileSync(path, 'utf8');\n    var newDefinitions = updateDeclarationModuleNames(definitions);\n    if (additionalDeclarations) {\n        newDefinitions = newDefinitions + '\\n' + additionalDeclarations;\n    }\n    if (/ace\\.d\\.ts$/.test(path)) {\n        var aceRequire = \"$1\\n    export function require(name: string): any;\";\n        newDefinitions = newDefinitions.replace(/(declare\\smodule\\s\"ace\\-builds\"\\s{)/, aceRequire);\n    }\n    fs.writeFileSync(path, newDefinitions);\n}\n\nfunction buildTypes() {\n    // ace-builds package has different structure and can't use mode types defined for the ace-code.\n    var paths = fs.readdirSync(BUILD_DIR + '/src-noconflict');\n\n    var typeDir = BUILD_DIR + \"/types\";\n\n    if (!fs.existsSync(typeDir)) {\n        fs.mkdirSync(typeDir);\n    }\n\n    fs.readdirSync(BUILD_DIR + '/src-noconflict/snippets').forEach(function(path) {\n        paths.push(\"snippets/\" + path);\n    });\n\n    var moduleNameRegex = /^(keybinding)-/;\n\n    var pathModules = [\n        \"declare module 'ace-builds/webpack-resolver';\",\n        \"declare module 'ace-builds/esm-resolver';\",\n        \"declare module 'ace-builds/src-noconflict/ace';\"\n    ].concat(paths.map(function(path) {\n        if (moduleNameRegex.test(path)) {\n            var moduleName = path.split('.')[0];\n            return \"declare module 'ace-builds/src-noconflict/\" + moduleName + \"';\";\n        }\n    }).filter(Boolean)).join(\"\\n\") + \"\\n\";\n    \n    fs.copyFileSync(ACE_HOME + '/ace-internal.d.ts', BUILD_DIR + '/ace.d.ts');\n    generateDeclaration(BUILD_DIR + '/ace.d.ts');\n    fs.copyFileSync(ACE_HOME + '/ace-modes.d.ts', BUILD_DIR + '/ace-modes.d.ts');\n    correctDeclarationsForBuild(BUILD_DIR + '/ace.d.ts', pathModules);\n    correctDeclarationsForBuild(BUILD_DIR + '/ace-modes.d.ts');\n\n    let allModules = SEPARATE_MODULES;\n    allModules.push(\"modules\"); // core modules\n    allModules.forEach(function (key) {\n        let fileName = '/ace-' + key + '.d.ts';\n        fs.copyFileSync(ACE_HOME + '/types' + fileName, BUILD_DIR + '/types' + fileName);\n        correctDeclarationsForBuild(BUILD_DIR + '/types' + fileName);\n    });\n    \n    var esmUrls = [];\n\n    var loader = paths.map(function(path) {\n        if (/\\.js$/.test(path) && !/^ace\\.js$/.test(path)) {\n            var moduleName = path.split('.')[0].replace(/-/, \"/\");\n            if (/^worker/.test(moduleName))\n                moduleName = \"mode\" + moduleName.slice(6) + \"_worker\";\n            moduleName = moduleName.replace(/keybinding/, \"keyboard\");\n            esmUrls.push(\"ace.config.setModuleLoader('ace/\" + moduleName + \"', () => import('./src-noconflict/\" + path + \"'));\");\n            return \"ace.config.setModuleUrl('ace/\" + moduleName + \"', require('file-loader?esModule=false!./src-noconflict/\" + path + \"'));\";\n        }\n    }).join('\\n');\n    var esmLoader = esmUrls.join('\\n');\n\n    fs.writeFileSync(BUILD_DIR + '/webpack-resolver.js', loader, \"utf8\");\n    fs.writeFileSync(BUILD_DIR + '/esm-resolver.js', esmLoader, \"utf8\");\n}\n\nfunction demo() {\n    console.log('# kitchen sink ---------');\n\n    var version = \"\", ref = \"\";\n    try {\n        version = JSON.parse(fs.readFileSync(ACE_HOME + \"/package.json\")).version;\n        ref = fs.readFileSync(ACE_HOME + \"/.git-ref\").toString();\n    } catch(e) {}\n\n    function changeComments(data) {\n        return (data\n            .replace(\"doc/site/images/ace-logo.png\", \"demo/kitchen-sink/ace-logo.png\")\n            .replace(/<!\\-\\-DEVEL[\\d\\D]*?DEVEL\\-\\->/g, \"\")\n            .replace(/PACKAGE\\-\\->|<!\\-\\-PACKAGE/g, \"\")\n            .replace(/\\/\\*DEVEL[\\d\\D]*?DEVEL\\*\\//g, \"\")\n            .replace(/PACKAGE\\*\\/|\\/\\*PACKAGE/g, \"\")\n            .replace(\"%version%\", version)\n            .replace(\"%commit%\", ref)\n        );\n    }\n    \n    require(\"rimraf\").sync(BUILD_DIR + \"/demo/kitchen-sink/docs/\");\n    copy(ACE_HOME +\"/demo/kitchen-sink/docs/\", BUILD_DIR + \"/demo/kitchen-sink/docs/\");\n    \n    copy.file(ACE_HOME + \"/demo/kitchen-sink/logo.png\", BUILD_DIR + \"/demo/kitchen-sink/logo.png\");\n    copy.file(ACE_HOME + \"/demo/kitchen-sink/styles.css\", BUILD_DIR + \"/demo/kitchen-sink/styles.css\");\n    copy.file(ACE_HOME + \"/kitchen-sink.html\", BUILD_DIR + \"/kitchen-sink.html\", changeComments);\n\n    buildSubmodule({}, {\n        require: [\"kitchen-sink/demo\"],\n        projectType: \"demo\"\n    }, BUILD_DIR + \"/demo/kitchen-sink/demo\");\n\n    copy(ACE_HOME + \"/demo/\", BUILD_DIR + \"/demo/\", {\n        shallow: true,\n        exclude: /\\s|requirejs/,\n        include: /\\.(js|html)$/,\n        replace: function(source) {\n            if (!/^\\s*</.test(source))\n                return source;\n            var removeRequireJS;\n            source = source.replace(/<script src=\"kitchen-sink\\/require.js\"[\\s\\S]+?require\\(\\[([^\\]]+).*/, function(e, m) {\n                removeRequireJS = true;\n                var scripts = m.split(/,\\s*/);\n                var result = [];\n                function comment(str) {result.push(\"<!-- \" + str + \" -->\");}\n                function script(str) {result.push('<script src=\"../src/' + str + '.js\"></script>');}\n                scripts.forEach(function(s) {\n                    s = s.replace(/\"/g, \"\");\n                    if (s == \"ace/ace\") {\n                        comment(\"load ace\");\n                        script(\"ace\");\n                    } else {\n                        var extName = s.match(/[^/]*$/)[0];\n                        comment(\"load ace \" + extName + \" extension\");\n                        script(\"ext-\" + extName);\n                    }\n                });\n                result.push(\"<script>\");\n                return result.join(\"\\n\");\n            });\n            if (removeRequireJS) {\n                source = source.replace(/\\s*\\}\\);?\\s*(<\\/script>)/, \"\\n$1\");\n                source = source.replace(/( |^)require\\(/gm, \"$1ace.require(\");\n            }\n            source = source.replace(/\"\\.\\.\\/build\\//g, function(e) {\n                return '\"../';\n            });\n            return source;\n        }\n    });\n}\n\nfunction jsFileList(path, filter) {\n    path = ACE_HOME + \"/\" + path;\n    if (!filter)\n        filter = /_test/;\n\n    return fs.readdirSync(path).map(function(x) {\n        if (x.slice(-3) == \".js\" && !filter.test(x) && !/\\s|BASE|(\\b|_)dummy(\\b|_)|[\\-\\.]css\\.js$/.test(x))\n            return x.slice(0, -3);\n    }).filter(Boolean);\n}\n\nfunction searchFiles(dir, fn) {\n    var files = fs.readdirSync(dir);\n    files.forEach(function(name) {\n        var path = dir + \"/\" + name;\n        try {\n            var stat = fs.statSync(path);\n        } catch (e) {\n            return;\n        }\n        if (stat.isFile() && /\\.js$/.test(path)) {\n            fn(path);\n        } else if (stat.isDirectory()) {\n            if (/node_modules|[#\\s]/.test(name)) return;\n            searchFiles(path, fn);\n        }\n    });\n}\n\nfunction workers(path) {\n    return jsFileList(path).map(function(x) {\n        if (x.slice(-7) == \"_worker\")\n            return x.slice(0, -7);\n    }).filter(function(x) { return !!x; });\n}\n\nfunction modeList(path) {\n    path = path || \"lib/ace/mode\";\n    return jsFileList(path, /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/);\n}\n\nfunction buildAceModule(opts, callback) {\n    // calling buildAceModuleInternal many times in parallel is slow, so we use queue\n    if (!buildAceModule.queue) {\n        buildAceModule.queue = [];\n        buildAceModule.dequeue = function() {\n            if (buildAceModule.running) return;\n            var call = buildAceModule.queue.shift();\n            buildAceModule.running = call;\n            if (call) {\n                setImmediate(function() {\n                    buildAceModuleInternal.apply(null, call);\n                });\n            }\n        };\n    }\n    \n    buildAceModule.queue.push([opts, function(err, result) {\n        callback && callback(err, result);\n        buildAceModule.running = null;\n        buildAceModule.dequeue();\n    }]);\n\n    if (!buildAceModule.running) {\n        buildAceModule.dequeue();\n    } else {\n        process.nextTick(buildAceModule.dequeue);\n    }\n}\n\nfunction buildAceModuleInternal(opts, callback) {\n    var cache = opts.cache == undefined ? CACHE : opts.cache;\n    var key = opts.require + \"|\" + opts.projectType;\n    if (cache && cache.configs && cache.configs[key])\n        return write(null, cache.configs[key]);\n        \n    var pathConfig = {\n        paths: {\n            ace: ACE_HOME + \"/lib/ace\",\n            \"kitchen-sink\": ACE_HOME + \"/demo/kitchen-sink\",\n            build_support:  ACE_HOME + \"/build_support\"\n        },\n        root: ACE_HOME\n    };\n        \n    function write(err, result) {\n        if (cache && key && !(cache.configs && cache.configs[key])) {\n            cache.configs = cache.configs || Object.create(null);\n            cache.configs[key] = result;\n            result.sources = result.sources.map(function(pkg) {\n                return {deps: pkg.deps};\n            });\n        } \n        \n        if (!opts.outputFile)\n            return callback(err, result);\n        \n        var code = result.code;\n        if (opts.compress) {\n            if (!result.codeMin)\n                result.codeMin = compress(result.code);\n            code = result.codeMin;\n        }\n            \n        var targetDir = getTargetDir(opts);\n        \n        var to = /^([\\\\/]|\\w:)/.test(opts.outputFile)\n            ? opts.outputFile\n            : path.join(opts.outputFolder || targetDir, opts.outputFile);\n    \n        var filters = [];\n\n        var ns = opts.ns || \"ace\";\n        if (opts.filters)\n            filters = filters.concat(opts.filters);\n    \n        if (opts.noconflict)\n            filters.push(namespace(ns));\n        var projectType = opts.projectType;\n        if (projectType !== \"worker\") {\n            filters.push(exportAce(ns, opts.require[0],\n                opts.noconflict ? ns : \"\", projectType !== \"main\"));\n        }\n        \n        filters.push(normalizeLineEndings);\n        \n        filters.forEach(function(f) { code = f(code); });\n        \n        build.writeToFile({code: code}, {\n            outputFolder: path.dirname(to),\n            outputFile: path.basename(to)\n        }, function() {});\n        \n        callback && callback(err, result);\n    }\n    \n    build(opts.require, {\n        cache: cache,\n        quiet: opts.quiet,\n        pathConfig: pathConfig,\n        additional: opts.additional,\n        enableBrowser: true,\n        keepDepArrays: opts.noconflict || opts.projectType == \"worker\" ? \"\" : \"all\",\n        noArchitect: true,\n        compress: false,\n        ignore: opts.ignore || [],\n        withRequire: false,\n        basepath: ACE_HOME,\n        transforms: [wrapCJS, normalizeLineEndings, includeLoader],\n        afterRead: [optimizeTextModules]\n    }, write);\n}\n\nfunction buildCore(options, extra, callback) {\n    options = extend(extra, options);\n    options.additional = [{\n        id: \"build_support/mini_require\", \n        order: -1000,\n        literal: true\n    }];\n    options.require =[\"ace/ace\", \"ace/loader_build\"];\n    options.projectType = \"main\";\n    options.ns = \"ace\";\n    buildAceModule(options, callback);\n}\n\nfunction buildSubmodule(options, extra, file, callback) {\n    options = extend(extra, options);\n    getLoadedFileList(options, function(coreFiles) {\n        options.outputFile = file + \".js\";\n        options.ignore = options.ignore || coreFiles;\n        options.quiet = true;\n        buildAceModule(options, callback);\n    });\n}\n\nfunction buildAce(options, callback) {\n    var snippetFiles = jsFileList(\"lib/ace/snippets\");\n    var modeNames = modeList();\n\n    buildCore(options, {outputFile: \"ace.js\"}, addCb());\n    // modes\n    modeNames.forEach(function(name) {\n        buildSubmodule(options, {\n            projectType: \"mode\",\n            require: [\"ace/mode/\" + name]\n        }, \"mode-\" + name, addCb());\n    });\n    // snippets\n    modeNames.forEach(function(name) {\n        buildSubmodule(options, {\n            require: [\"ace/snippets/\" + name]\n        }, \"snippets/\" + name, addCb());\n    });\n    // themes\n    jsFileList(\"lib/ace/theme\").forEach(function(name) {\n        buildSubmodule(options, {\n            projectType: \"theme\",\n            require: [\"ace/theme/\" + name]\n        }, \"theme-\" +  name, addCb());\n    });\n    // keybindings\n    [\"vim\", \"emacs\", \"sublime\", \"vscode\"].forEach(function(name) {\n        buildSubmodule(options, {\n            projectType: \"keybinding\",\n            require: [\"ace/keyboard/\" + name ]\n        }, \"keybinding-\" + name, addCb());\n    });\n    // extensions\n    jsFileList(\"lib/ace/ext\").forEach(function(name) {\n        buildSubmodule(options, {\n            projectType: \"ext\",\n            require: [\"ace/ext/\" + name]\n        }, \"ext-\" + name, addCb());\n    });\n    // workers\n    workers(\"lib/ace/mode\").forEach(function(name) {\n        buildSubmodule(options, {\n            projectType: \"worker\",\n            require: [\"ace/mode/\" + name + \"_worker\"],\n            ignore: [],\n            additional: [{\n                id: \"ace/worker/worker\",\n                transforms: [wrapCJS],\n                order: -1000\n            }]\n        }, \"worker-\" + name, addCb());\n    });\n    // worker base\n    buildSubmodule(options, {\n        projectType: \"worker\",\n        require: [\"ace/worker/mirror\"],\n        ignore: [],\n        additional: [{\n            id: \"ace/worker/worker\",\n            transforms: [wrapCJS],\n            order: -1000\n        }]\n    }, \"worker-base\", addCb());\n    // \n    function addCb() {\n        addCb.count = (addCb.count || 0) + 1; \n        return done;\n    }\n    function done() {\n        if (--addCb.count > 0)\n            return;\n        if (options.check)\n            sanityCheck(options, callback);\n        if (options.noconflict && !options.compress)\n            buildTypes();\n\n        // call extractCss only once during a build\n        if (cssUpdated) {\n            console.log(\"Finished building \" + getTargetDir(options));\n            return;\n        } else {\n            cssUpdated = true;\n            extractCss(function() {\n                if (callback) \n                    return callback();\n                console.log(\"Finished building \" + getTargetDir(options));                \n            });\n        }\n    }\n}\nvar cssUpdated = false;\n\nfunction extractCss(callback) {\n    var images = {};\n    var cssImports = {};\n    var fileName = \"\";\n\n    var extensions = jsFileList(\"src/ext\");\n    var keybinding = jsFileList(\"src/keyboard\");\n    var themes =  jsFileList(\"src/theme\");\n    var dom = require(\"./src/lib/dom\");\n    var index = 0;\n    dom.importCssString = function(value, id) {\n        if (!id) id = fileName + (index++);\n        cssImports[id] = value;\n    };\n    var loadFile = function(path) {\n        fileName = path;\n        require(path);\n    };\n    themes.forEach(function(name) {\n        cssImports = {};\n        loadFile(\"./src/theme/\" + name);\n        delete require.cache[require.resolve(\"./src/theme/\" + name)];\n\n        var themeCss = \"\";\n        for (var i in cssImports) {\n            themeCss += cssImports[i];\n        }\n        themeCss = extractImages(themeCss, name, \"..\");\n        build.writeToFile({code: themeCss}, {\n            outputFolder: BUILD_DIR + \"/css/theme\",\n            outputFile: name + \".css\"\n        }, function() {});\n    });\n\n    cssImports = {};\n    loadFile(\"./src/ace\");\n    extensions.forEach(function(name) {\n        loadFile(\"./src/ext/\" + name);\n    });\n    keybinding.forEach(function(name) {\n        loadFile(\"./src/keyboard/\" + name);\n    });\n\n    var css = \"\";\n    for (var i in cssImports) {\n        css += \"\\n/*\" + i + \"*/\";\n        css += \"\\n\" + cssImports[i];\n    }\n    \n    css = extractImages(css, \"main\", \".\").replace(/^\\s*/gm, \"\");\n    build.writeToFile({code: css}, {\n        outputFolder: BUILD_DIR + \"/css\",\n        outputFile: \"ace.css\"\n    }, function() {\n        saveImages();\n        callback && callback();\n    });\n    \n    function extractImages(css, name, directory) {\n        var imageCounter = 0;\n        return css.replace(\n            /url\\(\\s*\"data:([^\"\\\\]|\\\\.)+\"\\s*\\)|url\\(\\s*'data:([^'\\\\]|\\\\.)+'\\s*\\)|url\\(data:[^)]+\\)/g,\n            function(url) {\n                var data = url.slice(4, -1).trim();\n                if (/[\"']/.test(data[0])) {\n                    data = data.slice(1, -1).replace(/\\\\(.)/g, \"$1\");\n                }\n                data = data.slice(5);\n                var i = data.indexOf(\",\");\n                if (i == -1) {\n                    console.error(url);\n                    return url;\n                }\n                var buffer = Buffer.from(data.slice(i + 1), \"base64\");\n                imageCounter++;\n                var imageName;\n                if (/^image\\/svg\\+xml/.test(data))\n                    imageName = name + \"-\" + imageCounter + \".svg\";\n                else   \n                    imageName = name + \"-\" + imageCounter + \".png\";\n                images[imageName] = buffer;\n                return \"url(\\\"\" + directory + \"/\" + imageName + \"\\\")\";\n            }\n        );\n    }\n    function saveImages() {\n        for (var imageName in images) {\n            fs.writeFileSync(BUILD_DIR + \"/css/\" + imageName, images[imageName]);\n        }\n    }\n}\n\nfunction extractNls() {\n    var defaultData = require(__dirname + \"/src/lib/default_english_messages\").defaultEnglishMessages;\n\n    searchFiles(__dirname + \"/src\", function(path) {\n        if (/_test/.test(path)) return;\n        var text = fs.readFileSync(path, \"utf8\");\n        var matches = text.match(/nls\\s*\\(\\s*(\"([^\"\\\\]|\\\\.)+\"|'([^'\\\\]|\\\\.)+'),\\s*(\"([^\"\\\\]|\\\\.)+\"|'([^'\\\\]|\\\\.)+')/g);\n        matches && matches.forEach(function(m) {\n            var match = m.match(/(\"([^\"\\\\]|\\\\.)+\"|'([^'\\\\]|\\\\.)+)/g);      \n            var key = match[0].replace(/[\"']|[\"']$/g, \"\");\n            var defaultString = match[1].replace(/[\"']|[\"']$/g, \"\");\n\n            // If the key not yet in the default file, add it:\n            if (defaultData[key] !== undefined) return;\n            defaultData[key] = defaultString;\n        });\n    });\n    fs.writeFileSync(__dirname + \"/src/lib/default_english_messages.js\", \"var defaultEnglishMessages = \" + JSON.stringify(defaultData, null, 4) + \"\\n\\nexports.defaultEnglishMessages = defaultEnglishMessages;\", \"utf8\");\n    \n    fs.readdirSync(__dirname + \"/translations\").forEach(function(x) {\n        if (!/\\.json$/.test(x)) return;\n        var path = __dirname + \"/translations/\" + x;\n        var existingStr = fs.readFileSync(path, \"utf8\");\n        var existing = JSON.parse(existingStr);\n        \n        for (var i in defaultData) {\n            existing[i] = existing[i] || \"\";\n        }\n        fs.writeFileSync(path, JSON.stringify(existing, null, 4), \"utf8\");\n        console.log(\"Saved \" + x);\n    });\n}\n\nfunction getLoadedFileList(options, callback, result) {\n    if (!result) {\n        return buildCore({}, {}, function(e, result) {\n            getLoadedFileList(options, callback, result);\n        });\n    }\n    var deps = Object.create(null);\n    result.sources.forEach(function(pkg) {\n        pkg.deps && pkg.deps.forEach(function(p) {\n            if (!deps[p]) deps[p] = 1;\n        });\n    });\n    if (options.projectType == \"theme\")\n        delete deps[\"ace/theme/textmate\"];\n    deps[\"ace/ace\"] = 1;\n    callback(Object.keys(deps));\n}\n\nfunction normalizeLineEndings(module) {\n    if (typeof module == \"string\") \n        module = {source: module};\n    return module.source = module.source.replace(/\\r\\n/g, \"\\n\");\n}\n\nfunction includeLoader(module) {\n    var pattern = '\"include loader_build\";';\n    if (module.source && module.source.indexOf(pattern) != -1) {\n        module.deps.push(\"ace/loader_build\");\n        module.source = module.source.replace(pattern, 'require(\"./loader_build\")(exports)');\n    }\n}\n\nfunction optimizeTextModules(sources) {\n    var textModules = {};\n    return sources.filter(function(pkg) {\n        if (!pkg.id) {\n            return true;\n        }\n        else if (pkg.id.indexOf(\"text!\") > -1) {\n            detectTextModules(pkg);\n            return false;\n        }\n        else {\n            pkg.source = rewriteTextImports(pkg.source, pkg.deps);\n            return true;\n        }\n    }).map(function(pkg) {\n        if (pkg && pkg.deps) {\n            pkg.deps = pkg.deps && pkg.deps.filter(function(p) {\n                return p.indexOf(\"text!\") == -1;\n            });\n        }\n        return pkg;\n    });\n    \n    function rewriteTextImports(text, deps) {\n        return text.replace(/ require\\(['\"](?:ace|[.\\/]+)\\/requirejs\\/text!(.*?)['\"]\\)/g, function(_, call) {\n            if (call) {\n                var dep;\n                deps.some(function(d) {\n                    if (d.split(\"/\").pop() == call.split(\"/\").pop()) {\n                        dep = d;\n                        return true;\n                    }\n                });\n    \n                call = textModules[dep];\n                if (call)\n                    return \" \" + call;\n            }\n        });\n    }\n    function detectTextModules(pkg) {\n        var input = pkg.source.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n        if (/\\.css$/.test(pkg.id)) {\n            // remove unnecessary whitespace from css\n            input = input.replace(/\\n\\s+/g, \"\\n\");\n            input = '\"' + input.replace(/\\n/g, '\\\\\\n') + '\"';\n        } else {\n            // but don't break other files!\n            input = '\"' + input.replace(/\\n/g, '\\\\n\\\\\\n') + '\"';\n        }\n        textModules[pkg.id] = input;\n    }\n}\n\nfunction namespace(ns) {\n    return function(text) {\n        text = text\n            .toString()\n            .replace(/ACE_NAMESPACE\\s*=\\s*\"\"/, 'ACE_NAMESPACE = \"' + ns +'\"')\n            .replace(/\\bdefine\\(/g, function(def, index, source) {\n                if (/(^|[;}),])\\s*$/.test(source.slice(0, index)))\n                    return ns + \".\" + def;\n                return def;\n            });\n\n        return text;\n    };\n}\n\nfunction exportAce(ns, modules, requireBase, extModules) {\n    requireBase = requireBase || \"window\";\n    return function(text) {\n        /*globals REQUIRE_NS, MODULES, self*/\n        var template = function() {\n            (function() {\n                REQUIRE_NS.require(MODULES, function(a) {\n                    if (a) {\n                        a.config.init(true);\n                        a.define = REQUIRE_NS.define;\n                    }\n                    var global = (function () {\n                        return this;\n                    })();\n                    if (!global && typeof window != \"undefined\") global = window; // can happen in strict mode\n                    if (!global && typeof self != \"undefined\") global = self; // can happen in webworker\n                    \n                    if (!global.NS)\n                        global.NS = a;\n                    for (var key in a) if (a.hasOwnProperty(key))\n                        global.NS[key] = a[key];\n                    global.NS[\"default\"] = global.NS;\n                    if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n                        module.exports = global.NS;\n                    }\n                });\n            })();\n        };\n        \n        if (extModules) {\n            template = function() {\n                (function() {\n                    REQUIRE_NS.require(MODULES, function(m) {\n                        if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n                            module.exports = m;\n                        }\n                    });\n                })();\n            };\n        }\n        \n        text = text.replace(/function init\\(packaged\\) {/, \"init(true);$&\\n\");\n        \n        if (typeof modules == \"string\")\n            modules = [modules];\n            \n        return (text.replace(/;\\s*$/, \"\") + \";\" + template\n            .toString()\n            .replace(/MODULES/g, JSON.stringify(modules))\n            .replace(/REQUIRE_NS/g, requireBase)\n            .replace(/NS/g, ns)\n            .slice(13, -1)\n        );\n    };\n}\n\nfunction updateModes() {\n    modeList().forEach(function(m) {\n        var filepath = __dirname + \"/lib/ace/mode/\" + m + \".js\";\n        var source = fs.readFileSync(filepath, \"utf8\");\n        if (!/this.\\$id\\s*=\\s*\"/.test(source))\n            source = source.replace(/\\n([ \\t]*)(\\}\\).call\\(\\w*Mode.prototype\\))/, '\\n$1    this.$id = \"\";\\n$1$2');\n        \n        source = source.replace(/(this.\\$id\\s*=\\s*)\"[^\"]*\"/,  '$1\"ace/mode/' + m + '\"');\n        fs.writeFileSync(filepath, source, \"utf8\");\n    });\n}\n\nfunction generateThemesModule(themes) {\n    var themelist = [\n        'define(function(require, exports, module) {',\n        '\\n\\nmodule.exports.themes = ' + JSON.stringify(themes, null, '    '),\n        ';\\n\\n});'\n    ].join('');\n    fs.writeFileSync(__dirname + '/lib/ace/ext/themelist_utils/themes.js', themelist, 'utf8');\n}\n\nfunction wrapCJS(module) {\n    if (module.loaderModule || module.noRequire || module.literal) return;\n    module.source = module.source.replace(/^#.*\\n/, \"\");\n\n    if (!isCJS(module.source)) return;\n\n    module.source = `define(function(require, exports, module) {${module.source}\\n});`;\n}\n\nfunction isCJS(source) {\n    var firstDefineCall = source.match(/define\\(\\s*[^)]*/);\n    if (firstDefineCall) {\n        // check if it is a normal define or some crazy umd trick\n        if (/define\\(\\s*(function\\s*\\(|{)/.test(firstDefineCall[0])) return;\n        if (/define\\(\\s*\\[[^\\]]*\\],\\s*\\(?function\\(/.test(firstDefineCall[0])) return;\n        if (/typeof define/.test(source)) return;\n    }\n    if (/\"no use strict\"/.test(source)) return;\n    return true;\n}\n\nfunction compress(text) {\n    var uglify = require(\"dryice\").copy.filter.uglifyjs;\n    uglify.options.mangle_toplevel = {except: [\"ACE_NAMESPACE\", \"requirejs\"]};\n    uglify.options.beautify = {ascii_only: true, inline_script: true};\n    return asciify(uglify(text));\n    // copy.filter.uglifyjs.options.ascii_only = true; doesn't work with some uglify.js versions\n    function asciify(text) {\n        return text.replace(/[\\x00-\\x08\\x0b\\x0c\\x0e\\x19\\x80-\\uffff]/g, function(c) {\n            c = c.charCodeAt(0).toString(16);\n            if (c.length == 1)\n                return \"\\\\x0\" + c;\n            if (c.length == 2)\n                return \"\\\\x\" + c;\n            if (c.length == 3)\n                return \"\\\\u0\" + c;\n            return \"\\\\u\" + c;\n        });\n    }\n}\n\nfunction extend(base, extra) {\n    Object.keys(extra).forEach(function(k) {\n        base[k] = extra[k];\n    });\n    return base;\n}\n\nfunction getTargetDir(opts) {\n    var targetDir = BUILD_DIR + \"/src\";\n    if (opts.compress)\n        targetDir += \"-min\";\n    if (opts.noconflict)\n        targetDir += \"-noconflict\";\n    return targetDir;\n}\n\nfunction sanityCheck(opts, callback) {\n    var targetDir = getTargetDir(opts);\n    require(\"child_process\").execFile(process.execPath, [\"-e\", \"(\" + function() {\n        window = global;\n        require(\"./ace\");\n        if (typeof ace.edit != \"function\")\n            process.exit(1);\n        require(\"fs\").readdirSync(\".\").forEach(function(p) {\n            if (!/ace\\.js$/.test(p) && /\\.js$/.test(p))\n                require(\"./\" + p);\n        });\n        process.exit(0);\n    } + \")()\"], {\n        cwd: targetDir\n    }, function(err, stdout) {\n        if (callback) return callback(err, stdout);\n        if (err)\n            throw err;\n    });\n}\n\nif (!module.parent) \n    main(process.argv); \nelse {\n    exports.buildAce = buildAce;\n    exports.jsFileList = jsFileList;\n    exports.modeList = modeList;\n}\n    \n"
  },
  {
    "path": "Readme.md",
    "content": "Ace (Ajax.org Cloud9 Editor)\n============================\n\n[![Build Status](https://github.com/ajaxorg/ace/workflows/CI/badge.svg)](https://github.com/ajaxorg/ace/actions) \n[![npm](https://img.shields.io/npm/v/ace-builds.svg)](https://www.npmjs.com/package/ace-builds)\n\n_Note_: The new site at http://ace.c9.io contains all the info below along with an embedding guide and all the other resources you need to get started with Ace.\n\nAce is a standalone code editor written in JavaScript. Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page or JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](https://c9.io/) and the successor of the Mozilla Skywriter (Bespin) Project.\n\nFeatures\n--------\n\n* Syntax highlighting for over 120 languages (TextMate/Sublime/_.tmlanguage_ files can be imported)\n* Over 20 themes (TextMate/Sublime/_.tmtheme_ files can be imported)\n* Automatic indent and outdent\n* An optional command line\n* Handles huge documents (at last check, 4,000,000 lines is the upper limit)\n* Fully customizable key bindings including vim and Emacs modes\n* Search and replace with regular expressions\n* Highlight matching parentheses\n* Toggle between soft tabs and real tabs\n* Displays hidden characters\n* Drag and drop text using the mouse\n* Line wrapping\n* Code folding\n* Multiple cursors and selections\n* Live syntax checker (currently JavaScript/CoffeeScript/CSS/XQuery)\n* Cut, copy, and paste functionality\n\nTake Ace for a spin!\n--------------------\n\nCheck out the Ace live [demo](http://ace.c9.io/build/kitchen-sink.html) or get a [Cloud9 IDE account](https://c9.io/) to experience Ace while editing one of your own GitHub projects.\n\nIf you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.io/ace/build/demo/bookmarklet/index.html).\n\nEmbedding Ace\n-------------\n\nAce can be easily embedded into any existing web page. You can either use one of pre-packaged versions of [ace](https://github.com/ajaxorg/ace-builds/) (just copy one of `src*` subdirectories somewhere into your project), or use requireJS to load contents of [lib/ace](https://github.com/ajaxorg/ace/tree/master/lib/ace) as `ace`\n\n\nThe easiest version is simply:\n\n```html\n<div id=\"editor\">some text</div>\n<script src=\"src/ace.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script>\n    var editor = ace.edit(\"editor\");\n</script>\n```\n*Exploring configuration options [Configuring-Ace](https://github.com/ajaxorg/ace/wiki/Configuring-Ace/)*\n\nWith \"editor\" being the id of the DOM element, which should be converted to an editor. Note that this element must be explicitly sized and positioned `absolute` or `relative` for Ace to work. e.g.\n\n```css\n#editor {\n    position: absolute;\n    width: 500px;\n    height: 400px;\n}\n```\n\nTo change the theme simply include the Theme's JavaScript file\n\n```html\n<script src=\"src/theme-twilight.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n```\n\nand configure the editor to use the theme:\n\n```javascript\neditor.setTheme(\"ace/theme/twilight\");\n```\n\nBy default the editor only supports plain text mode; many other languages are available as separate modules. After including the mode's JavaScript file:\n\n```html\n<script src=\"src/mode-javascript.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n```\n\nThe mode can then be used like this:\n\n```javascript\nvar JavaScriptMode = ace.require(\"ace/mode/javascript\").Mode;\neditor.session.setMode(new JavaScriptMode());\n```\n\nto destroy editor use\n\n```javascript\neditor.destroy();\neditor.container.remove();\n```\n\n\nDocumentation\n-------------\n\nAdditional usage information, including events to listen to and extending syntax highlighters, can be found [on the main Ace website](http://ace.c9.io).\n\nYou can also find API documentation at [https://ajaxorg.github.io/ace-api-docs/](https://ajaxorg.github.io/ace-api-docs/).\n\nAlso check out the sample code for the kitchen sink [demo app](https://github.com/ajaxorg/ace/blob/master/demo/kitchen-sink/demo.js).\n\nIf you still need help, feel free to ask a question on our [discussions page](https://github.com/ajaxorg/ace/discussions).\n\nRunning Ace\n-----------\n\nAfter the checkout Ace works out of the box. No build step is required. To try it out, simply start the bundled mini HTTP server using Node.JS\n\n```bash\nnode ./static.js\n```\n\nThe editor can then be opened at http://localhost:8888/kitchen-sink.html. \n\nTo open the editor with a file:/// URL see [the wiki](https://github.com/ajaxorg/ace/wiki/Running-Ace-from-file).\n\nBuilding Ace\n-----------\n\nYou do not generally need to build ACE. The [ace-builds repository](https://github.com/ajaxorg/ace-builds/) endeavours to maintain the latest build, and you can just copy one of _src*_ subdirectories somewhere into your project.\n\nHowever, all you need is Node.js and npm installed to package ACE. Just run `npm install` in the ace folder to install dependencies:\n\n```bash\nnpm install\nnode ./Makefile.dryice.js\n```\n\nTo package Ace, we use the dryice build tool developed by the Mozilla Skywriter team. Call `node Makefile.dryice.js` on the command-line to start the packing. This build script accepts the following options\n\n```bash\n-m                 minify build files with uglify-js          \n-nc                namespace require and define calls with \"ace\"\n-bm                builds the bookmarklet version\n--target ./path    specify relative path for output folder (default value is \"./build\")\n```\n\nTo generate all the files in the ace-builds repository, run `node Makefile.dryice.js full --target ../ace-builds`\n\nRunning the Unit Tests\n----------------------\n\nThe Ace unit tests can run on node.js. Assuming you have already done `npm install`, just call:\n\n```bash\nnpm run test\n```\n\nYou can also run the tests in your browser by serving:\n\n    http://localhost:8888/src/test/tests.html\n\nThis makes debugging failing tests much easier.\n\nContributing\n-----------------------------\n\nAce is a community project and wouldn't be what it is without contributions! We actively encourage and support contributions. The Ace source code is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings!\n\nFeel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. For more information on our contributing guidelines, see [CONTRIBUTING.md](https://github.com/ajaxorg/ace/blob/master/CONTRIBUTING.md).\n\n"
  },
  {
    "path": "_config.yml",
    "content": "# Config file for Jekyll, which is used by GH pages to build the Ace website.\n# Some files in the docs folder can cause Jekyll to trip up so we ignore those.\n# https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll\nexclude:\n  - \"demo/kitchen-sink/docs\""
  },
  {
    "path": "ace-internal.d.ts",
    "content": "export namespace Ace {\n    type Anchor = import(\"./src/anchor\").Anchor;\n    type Editor = import(\"./src/editor\").Editor;\n    type EditSession = import(\"./src/edit_session\").EditSession;\n    type Document = import(\"./src/document\").Document;\n    type Fold = import(\"./src/edit_session/fold\").Fold;\n    type FoldLine = import(\"./src/edit_session/fold_line\").FoldLine;\n    type Range = import(\"./src/range\").Range;\n    type VirtualRenderer = import(\"./src/virtual_renderer\").VirtualRenderer;\n    type UndoManager = import(\"./src/undomanager\").UndoManager;\n    type Tokenizer = import(\"./src/tokenizer\").Tokenizer;\n    type TokenIterator = import(\"./src/token_iterator\").TokenIterator;\n    type Selection = import(\"./src/selection\").Selection;\n    type Autocomplete = import(\"./src/autocomplete\").Autocomplete;\n    type InlineAutocomplete = import(\"./src/ext/inline_autocomplete\").InlineAutocomplete;\n    type CompletionProvider = import(\"./src/autocomplete\").CompletionProvider;\n    type AcePopup = import(\"./src/autocomplete/popup\").AcePopup;\n    type AceInline = import(\"./src/autocomplete/inline\").AceInline;\n    type MouseEvent = import(\"./src/mouse/mouse_event\").MouseEvent;\n    type RangeList = import(\"./src/range_list\").RangeList;\n    type FilteredList = import(\"./src/autocomplete\").FilteredList;\n    type LineWidgets = import(\"./src/line_widgets\").LineWidgets;\n    type SearchBox = import(\"./src/ext/searchbox\").SearchBox;\n    type Occur = import(\"./src/occur\").Occur;\n    type DefaultHandlers = import(\"./src/mouse/default_handlers\").DefaultHandlers;\n    type GutterHandler = import(\"./src/mouse/default_gutter_handler\").GutterHandler;\n    type DragdropHandler = import(\"./src/mouse/dragdrop_handler\").DragdropHandler;\n    type AppConfig = import(\"./src/lib/app_config\").AppConfig;\n    type Config = typeof import(\"./src/config\");\n    type GutterTooltip = import( \"./src/mouse/default_gutter_handler\").GutterTooltip;\n    type GutterKeyboardEvent = import( \"./src/keyboard/gutter_handler\").GutterKeyboardEvent;\n    type HoverTooltip = import(\"./src/tooltip\").HoverTooltip;\n    type Tooltip = import(\"./src/tooltip\").Tooltip;\n    type TextInput = import(\"./src/keyboard/textinput\").TextInput;\n    type DiffChunk = import(\"./src/ext/diff/base_diff_view\").DiffChunk;\n\n    type AfterLoadCallback = (err: Error | null, module: unknown) => void;\n    type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;\n\n    export interface ConfigOptions {\n        packaged: boolean,\n        workerPath: string | null,\n        modePath: string | null,\n        themePath: string | null,\n        basePath: string,\n        suffix: string,\n        $moduleUrls: { [url: string]: string },\n        loadWorkerFromBlob: boolean,\n        sharedPopups: boolean,\n        useStrictCSP: boolean | null\n    }\n\n    interface Theme {\n        cssClass?: string;\n        cssText?: string;\n        $id?: string;\n        padding?: number | string;\n        isDark?: boolean;\n    }\n\n    interface ScrollBar {\n        setVisible(visible: boolean): void;\n\n        [key: string]: any;\n    }\n\n    interface HScrollbar extends ScrollBar {\n        setWidth(width: number): void;\n    }\n\n    interface VScrollbar extends ScrollBar {\n        setHeight(width: number): void;\n    }\n\n    interface LayerConfig {\n        width: number,\n        padding: number,\n        firstRow: number,\n        firstRowScreen: number,\n        lastRow: number,\n        lineHeight: number,\n        characterWidth: number,\n        minHeight: number,\n        maxHeight: number,\n        offset: number,\n        height: number,\n        gutterOffset: number\n    }\n\n    interface HardWrapOptions {\n        /** First row of the range to process */\n        startRow: number;\n        /** Last row of the range to process */\n        endRow: number;\n        /** Whether to merge short adjacent lines that fit within the limit */\n        allowMerge?: boolean;\n        /** Maximum column width for line wrapping (defaults to editor's print margin) */\n        column?: number;\n    }\n\n    interface CommandBarOptions {\n        maxElementsOnTooltip: number;\n        alwaysShow: boolean;\n        showDelay: number;\n        hideDelay: number;\n    }\n\n    interface ScreenCoordinates {\n        row: number,\n        column: number,\n        side?: 1 | -1,\n        offsetX?: number\n    }\n\n    interface Folding {\n        $foldData: FoldLine[];\n\n        /**\n         * Looks up a fold at a given row/column. Possible values for side:\n         *   -1: ignore a fold if fold.start = row/column\n         *   +1: ignore a fold if fold.end = row/column\n         **/\n        getFoldAt(row: number, column: number, side?: number): Ace.Fold;\n\n        /**\n         * Returns all folds in the given range. Note, that this will return folds\n         **/\n        getFoldsInRange(range: Ace.Range | Ace.Delta): Ace.Fold[];\n\n        getFoldsInRangeList(ranges: Ace.Range[] | Ace.Range): Ace.Fold[];\n\n        /**\n         * Returns all folds in the document\n         */\n        getAllFolds(): Ace.Fold[];\n\n        /**\n         * Returns the string between folds at the given position.\n         * E.g.\n         *  foo<fold>b|ar<fold>wolrd -> \"bar\"\n         *  foo<fold>bar<fold>wol|rd -> \"world\"\n         *  foo<fold>bar<fo|ld>wolrd -> <null>\n         *\n         * where | means the position of row/column\n         *\n         * The trim option determs if the return string should be trimed according\n         * to the \"side\" passed with the trim value:\n         *\n         * E.g.\n         *  foo<fold>b|ar<fold>wolrd -trim=-1> \"b\"\n         *  foo<fold>bar<fold>wol|rd -trim=+1> \"rld\"\n         *  fo|o<fold>bar<fold>wolrd -trim=00> \"foo\"\n         */\n        getFoldStringAt(row: number, column: number, trim?: number, foldLine?: Ace.FoldLine): string | null;\n\n        getFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine;\n\n        /**\n         * Returns the fold which starts after or contains docRow\n         */\n        getNextFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine;\n\n        getFoldedRowCount(first: number, last: number): number;\n\n        $addFoldLine(foldLine: FoldLine): Ace.FoldLine;\n\n        /**\n         * Adds a new fold.\n         * @returns {Ace.Fold}\n         *      The new created Fold object or an existing fold object in case the\n         *      passed in range fits an existing fold exactly.\n         */\n        addFold(placeholder: Ace.Fold | string, range?: Ace.Range): Ace.Fold;\n\n        $modified: boolean;\n\n        addFolds(folds: Ace.Fold[]): void;\n\n        removeFold(fold: Ace.Fold): void;\n\n        removeFolds(folds: Ace.Fold[]): void;\n\n        expandFold(fold: Ace.Fold): void;\n\n        expandFolds(folds: Ace.Fold[]): void;\n\n        unfold(location?: number | null | Ace.Point | Ace.Range | Ace.Range[], expandInner?: boolean): Ace.Fold[] | undefined;\n\n        /**\n         * Checks if a given documentRow is folded. This is true if there are some\n         * folded parts such that some parts of the line is still visible.\n         **/\n        isRowFolded(docRow: number, startFoldRow?: Ace.FoldLine): boolean;\n\n        getRowFoldEnd(docRow: number, startFoldRow?: Ace.FoldLine): number;\n\n        getRowFoldStart(docRow: number, startFoldRow?: Ace.FoldLine): number;\n\n        getFoldDisplayLine(foldLine: Ace.FoldLine, endRow?: number | null, endColumn?: number | null, startRow?: number | null, startColumn?: number | null): string;\n\n        getDisplayLine(row: number, endColumn: number | null, startRow: number | null, startColumn: number | null): string;\n\n        $cloneFoldData(): Ace.FoldLine[];\n\n        toggleFold(tryToUnfold?: boolean): void;\n\n        getCommentFoldRange(row: number, column: number, dir?: number): Ace.Range | undefined;\n\n        foldAll(startRow?: number | null, endRow?: number | null, depth?: number | null, test?: Function): void;\n\n        foldToLevel(level: number): void;\n\n        foldAllComments(): void;\n\n        $foldStyles: {\n            manual: number;\n            markbegin: number;\n            markbeginend: number;\n        };\n        $foldStyle: string;\n\n        setFoldStyle(style: string): void;\n\n        $setFolding(foldMode: Ace.FoldMode): void;\n\n        $foldMode: any;\n        foldWidgets: any[];\n        getFoldWidget: any;\n        getFoldWidgetRange: any;\n        $updateFoldWidgets: any;\n        $tokenizerUpdateFoldWidgets: any;\n\n        getParentFoldRangeData(row: number, ignoreCurrent?: boolean): {\n            range?: Ace.Range;\n            firstRange?: Ace.Range;\n        };\n\n        onFoldWidgetClick(row: number, e: any): void;\n\n        $toggleFoldWidget(row: number, options: any): Fold | any;\n\n        /**\n         *\n         * @param {boolean} [toggleParent]\n         */\n        toggleFoldWidget(toggleParent?: boolean): void;\n\n        updateFoldWidgets(delta: Ace.Delta): void;\n\n        tokenizerUpdateFoldWidgets(e: any): void;\n    }\n\n    interface BracketMatch {\n        findMatchingBracket: (position: Point, chr?: string) => Point;\n\n        getBracketRange: (pos: Point) => null | Range;\n        /**\n         * Returns:\n         * * null if there is no any bracket at `pos`;\n         * * two Ranges if there is opening and closing brackets;\n         * * one Range if there is only one bracket\n         */\n        getMatchingBracketRanges: (pos: Point, isBackwards?: boolean) => null | Range[];\n        $brackets: {\n            \")\": string;\n            \"(\": string;\n            \"]\": string;\n            \"[\": string;\n            \"{\": string;\n            \"}\": string;\n            \"<\": string;\n            \">\": string;\n        };\n        $findOpeningBracket: (bracket: string, position: Point, typeRe?: RegExp) => Point | null;\n        $findClosingBracket: (bracket: string, position: Point, typeRe?: RegExp) => Point | null;\n        /**\n         * Returns [[Range]]'s for matching tags and tag names, if there are any\n         */\n        getMatchingTags: (pos: Point) => {\n            closeTag: Range;\n            closeTagName: Range;\n            openTag: Range;\n            openTagName: Range;\n        };\n        $findTagName: (iterator: any) => any;\n        $findClosingTag: (iterator: any, token: any) => {\n            openTag: Range;\n            closeTag: Range;\n            openTagName: Range;\n            closeTagName: Range;\n        };\n        $findOpeningTag: (iterator: any, token: any) => {\n            openTag: Range;\n            closeTag: Range;\n            openTagName: Range;\n            closeTagName: Range;\n        };\n    }\n\n    interface IRange {\n        start: Point;\n        end: Point;\n    }\n\n    interface LineWidget {\n        editor?: Editor,\n        el?: HTMLElement;\n        rowCount?: number;\n        hidden?: boolean;\n        _inDocument?: boolean;\n        column?: number;\n        row: number;\n        $oldWidget?: LineWidget,\n        session?: EditSession,\n        html?: string,\n        text?: string,\n        className?: string,\n        coverGutter?: boolean,\n        pixelHeight?: number,\n        $fold?: Fold,\n        type?: any,\n        destroy?: () => void;\n        coverLine?: boolean,\n        fixedWidth?: boolean,\n        fullWidth?: boolean,\n        screenWidth?: number,\n        rowsAbove?: number,\n        lenses?: CodeLenseCommand[],\n    }\n\n    type NewLineMode = 'auto' | 'unix' | 'windows';\n\n    interface EditSessionOptions {\n        wrap: \"off\" | \"free\" | \"printmargin\" | boolean | number;\n        wrapMethod: 'code' | 'text' | 'auto';\n        indentedSoftWrap: boolean;\n        firstLineNumber: number;\n        useWorker: boolean;\n        useSoftTabs: boolean;\n        tabSize: number;\n        navigateWithinSoftTabs: boolean;\n        foldStyle: 'markbegin' | 'markbeginend' | 'manual';\n        overwrite: boolean;\n        newLineMode: NewLineMode;\n        mode: SyntaxMode | string;\n    }\n\n    interface VirtualRendererOptions {\n        animatedScroll: boolean;\n        showInvisibles: boolean;\n        showPrintMargin: boolean;\n        printMarginColumn: number;\n        printMargin: boolean | number;\n        showGutter: boolean;\n        fadeFoldWidgets: boolean;\n        showFoldWidgets: boolean;\n        showLineNumbers: boolean;\n        displayIndentGuides: boolean;\n        highlightIndentGuides: boolean;\n        highlightGutterLine: boolean;\n        hScrollBarAlwaysVisible: boolean;\n        vScrollBarAlwaysVisible: boolean;\n        fontSize: string | number;\n        fontFamily: string;\n        maxLines: number;\n        minLines: number;\n        scrollPastEnd: number;\n        fixedWidthGutter: boolean;\n        customScrollbar: boolean;\n        theme: string;\n        hasCssTransforms: boolean;\n        maxPixelHeight: number;\n        useSvgGutterIcons: boolean;\n        showFoldedAnnotations: boolean;\n        useResizeObserver: boolean;\n    }\n\n    interface MouseHandlerOptions {\n        scrollSpeed: number;\n        dragDelay: number;\n        dragEnabled: boolean;\n        focusTimeout: number;\n    }\n\n    interface EditorOptions extends EditSessionOptions,\n        MouseHandlerOptions,\n        VirtualRendererOptions {\n        selectionStyle: \"fullLine\" | \"screenLine\" | \"text\" | \"line\";\n        highlightActiveLine: boolean;\n        highlightSelectedWord: boolean;\n        readOnly: boolean;\n        copyWithEmptySelection: boolean;\n        cursorStyle: 'ace' | 'slim' | 'smooth' | 'wide';\n        mergeUndoDeltas: true | false | 'always';\n        behavioursEnabled: boolean;\n        wrapBehavioursEnabled: boolean;\n        enableAutoIndent: boolean;\n        enableBasicAutocompletion: boolean | Completer[];\n        enableLiveAutocompletion: boolean | Completer[];\n        liveAutocompletionDelay: number;\n        liveAutocompletionThreshold: number;\n        enableSnippets: boolean;\n        autoScrollEditorIntoView: boolean;\n        keyboardHandler: string | null;\n        placeholder: string;\n        value: string;\n        session: EditSession;\n        relativeLineNumbers: boolean;\n        enableMultiselect: boolean;\n        enableKeyboardAccessibility: boolean;\n        enableCodeLens: boolean;\n        textInputAriaLabel: string;\n        enableMobileMenu: boolean;\n    }\n\n    interface EventsBase {\n        [key: string]: any;\n    }\n\n    interface EditSessionEvents {\n        /**\n         * Emitted when the document changes.\n         * @param delta\n         */\n        \"change\": (delta: Delta, emitter: EditSession) => void;\n        /**\n         * Emitted when the tab size changes, via [[EditSession.setTabSize]].\n         */\n        \"changeTabSize\": (e: undefined, emitter: EditSession) => void;\n        /**\n         * Emitted when the ability to overwrite text changes, via [[EditSession.setOverwrite]].\n         * @param overwrite\n         */\n        \"changeOverwrite\": (overwrite: boolean, emitter: EditSession) => void;\n        /**\n         * Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.\n         * @param e\n         */\n        \"changeBreakpoint\": (e: { row?: number, breakpoint?: boolean }, emitter: EditSession) => void;\n        /**\n         * Emitted when a front marker changes.\n         */\n        \"changeFrontMarker\": (e: undefined, emitter: EditSession) => void;\n        /**\n         * Emitted when a back marker changes.\n         */\n        \"changeBackMarker\": (e: undefined, emitter: EditSession) => void;\n        /**\n         * Emitted when an annotation changes, like through [[EditSession.setAnnotations]].\n         */\n        \"changeAnnotation\": (e: {}, emitter: EditSession) => void;\n        /**\n         * Emitted when a background tokenizer asynchronously processes new rows.\n         */\n        \"tokenizerUpdate\": (e: { data: { first: number, last: number } }, emitter: EditSession) => void;\n        /**\n         * Emitted when the current mode changes.\n         * @param e\n         */\n        \"changeMode\": (e: any, emitter: EditSession) => void;\n        /**\n         * Emitted when the wrap mode changes.\n         * @param e\n         */\n        \"changeWrapMode\": (e: any, emitter: EditSession) => void;\n        /**\n         * Emitted when the wrapping limit changes.\n         * @param e\n         */\n        \"changeWrapLimit\": (e: any, emitter: EditSession) => void;\n        /**\n         * Emitted when a code fold is added or removed.\n         * @param e\n         */\n        \"changeFold\": (e: any, emitter: EditSession) => void;\n        /**\n         * Emitted when the scroll top changes.\n         * @param scrollTop The new scroll top value\n         **/\n        \"changeScrollTop\": (scrollTop: number, emitter: EditSession) => void;\n        /**\n         * Emitted when the scroll left changes.\n         * @param scrollLeft The new scroll left value\n         **/\n        \"changeScrollLeft\": (scrollLeft: number, emitter: EditSession) => void;\n        \"changeEditor\": (e: { editor?: Editor, oldEditor?: Editor }, emitter: EditSession) => void;\n        \"changeSelection\": (e: undefined, emitter: EditSession) => void;\n        \"startOperation\": (op: { command?: { name?: string }, args?: any }, emitter: EditSession) => void;\n        \"endOperation\": (op: any, emitter: EditSession) => void;\n        \"beforeEndOperation\": (e: undefined, emitter: EditSession) => void;\n    }\n\n    interface EditorEvents {\n        \"change\": (delta: Delta, emitter: Editor) => void;\n        \"changeSelection\": (e: undefined, emitter: Editor) => void;\n        \"input\": (e: undefined, emitter: Editor) => void;\n        /**\n         * Emitted whenever the [[EditSession]] changes.\n         * @param e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.\n         **/\n        \"changeSession\": (e: { oldSession: EditSession, session: EditSession }, emitter: Editor) => void;\n        \"blur\": (e: any, emitter: Editor) => void;\n        \"mousedown\": (e: MouseEvent, emitter: Editor) => void;\n        \"mousemove\": (e: MouseEvent & { scrollTop?: any }, emitter: Editor) => void;\n        \"changeStatus\": (e: any, emitter: Editor) => void;\n        \"keyboardActivity\": (e: any, emitter: Editor) => void;\n        \"mousewheel\": (e: MouseEvent, emitter: Editor) => void;\n        \"mouseup\": (e: MouseEvent, emitter: Editor) => void;\n        \"beforeEndOperation\": (e: any, emitter: Editor) => void;\n        \"nativecontextmenu\": (e: any, emitter: Editor) => void;\n        \"destroy\": (e: any, emitter: Editor) => void;\n        \"focus\": (e: any, emitter: Editor) => void;\n        /**\n         * Emitted when text is copied.\n         * @param text The copied text\n         **/\n        \"copy\": (e: { text: string }, emitter: Editor) => void;\n        /**\n         * Emitted when text is pasted.\n         **/\n        \"paste\": (e: { text: string, event?: ClipboardEvent }, emitter: Editor) => void;\n        /**\n         * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].\n         * @param data Contains one property, `data`, which indicates the new selection style\n         **/\n        \"changeSelectionStyle\": (data: \"fullLine\" | \"screenLine\" | \"text\" | \"line\", emitter: Editor) => void;\n        \"changeMode\": (e: { mode?: Ace.SyntaxMode, oldMode?: Ace.SyntaxMode }, emitter: Editor) => void;\n\n        //from searchbox extension\n        \"findSearchBox\": (e: { match: boolean }, emitter: Editor) => void;\n\n        //from code_lens extension\n        \"codeLensClick\": (e: any, emitter: Editor) => void;\n\n        \"select\": (e: undefined, emitter: Editor) => void;\n        \"gutterkeydown\": (e: GutterKeyboardEvent, emitter: Editor) => void;\n        \"gutterclick\": (e: MouseEvent, emitter: Editor) => void;\n        \"showGutterTooltip\": (e: GutterTooltip, emitter: Editor) => void;\n        \"hideGutterTooltip\": (e: GutterTooltip, emitter: Editor) => void;\n        \"compositionStart\": (e: undefined, emitter: Editor) => void;\n    }\n\n    interface AcePopupEvents {\n        \"click\": (e: MouseEvent, emitter: AcePopup) => void;\n        \"dblclick\": (e: MouseEvent, emitter: AcePopup) => void;\n        \"tripleclick\": (e: MouseEvent, emitter: AcePopup) => void;\n        \"quadclick\": (e: MouseEvent, emitter: AcePopup) => void;\n        \"show\": (e: undefined, emitter: AcePopup) => void;\n        \"hide\": (e: undefined, emitter: AcePopup) => void;\n        \"select\": (hide: boolean, emitter: AcePopup) => void;\n        \"changeHoverMarker\": (e: any, emitter: AcePopup) => void;\n    }\n\n    interface DocumentEvents {\n        /**\n         * Fires whenever the document changes.\n         * Several methods trigger different `\"change\"` events. Below is a list of each action type, followed by each property that's also available:\n         *  * `\"insert\"`\n         *    * `range`: the [[Range]] of the change within the document\n         *    * `lines`: the lines being added\n         *  * `\"remove\"`\n         *    * `range`: the [[Range]] of the change within the document\n         *    * `lines`: the lines being removed\n         *\n         **/\n        \"change\": (e: Delta, emitter: Document) => void;\n        \"changeNewLineMode\": (e: undefined, emitter: Document) => void;\n    }\n\n    interface AnchorEvents {\n        /**\n         * Fires whenever the anchor position changes.\n         * Both of these objects have a `row` and `column` property corresponding to the position.\n         * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]].\n         * @param {Object} e  An object containing information about the anchor position. It has two properties:\n         *  - `old`: An object describing the old Anchor position\n         *  - `value`: An object describing the new Anchor position\n         **/\n        \"change\": (e: { old: Point, value: Point }, emitter: Anchor) => void;\n    }\n\n    interface BackgroundTokenizerEvents {\n        /**\n         * Fires whenever the background tokeniziers between a range of rows are going to be updated.\n         * @param e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated.\n         **/\n        \"update\": (e: {\n            data: { first: number, last: number }\n        }, emitter: import(\"./src/background_tokenizer\").BackgroundTokenizer) => void;\n    }\n\n    interface SelectionEvents {\n        /**\n         * Emitted when the cursor position changes.\n         **/\n        \"changeCursor\": (e: undefined, emitter: Selection) => void;\n        /**\n         * Emitted when the cursor selection changes.\n         **/\n        \"changeSelection\": (e: undefined, emitter: Selection) => void;\n    }\n\n    interface MultiSelectionEvents extends SelectionEvents {\n        \"multiSelect\": (e: undefined, emitter: Selection) => void;\n        \"addRange\": (e: { range: Range }, emitter: Selection) => void;\n        \"removeRange\": (e: { ranges: Range[] }, emitter: Selection) => void;\n        \"singleSelect\": (e: undefined, emitter: Selection) => void;\n    }\n\n    interface PlaceHolderEvents {\n        \"cursorEnter\": (e: any, emitter: import(\"./src/placeholder\").PlaceHolder) => void;\n        \"cursorLeave\": (e: any, emitter: import(\"./src/placeholder\").PlaceHolder) => void;\n    }\n\n    interface GutterEvents {\n        \"changeGutterWidth\": (width: number, emitter: import(\"./src/layer/gutter\").Gutter) => void;\n        \"afterRender\": (e: undefined, emitter: import(\"./src/layer/gutter\").Gutter) => void;\n    }\n\n    interface TextEvents {\n        \"changeCharacterSize\": (e: any, emitter: import(\"./src/layer/text\").Text) => void;\n    }\n\n    interface VirtualRendererEvents {\n        \"afterRender\": (e: any, emitter: VirtualRenderer) => void;\n        \"beforeRender\": (e: any, emitter: VirtualRenderer) => void;\n        \"themeLoaded\": (e: { theme: string | Theme }, emitter: VirtualRenderer) => void;\n        \"themeChange\": (e: { theme: string | Theme }, emitter: VirtualRenderer) => void;\n        \"scrollbarVisibilityChanged\": (e: undefined, emitter: VirtualRenderer) => void;\n        \"changeCharacterSize\": (e: any, emitter: VirtualRenderer) => void;\n        \"resize\": (e: any, emitter: VirtualRenderer) => void;\n        \"autosize\": (e: undefined, emitter: VirtualRenderer) => void;\n    }\n\n    type EmitParameters<T extends (...args: any[]) => any> =\n        T extends (first: infer First, ...rest: any[]) => any\n            ? [First]\n            : [];\n\n    export class EventEmitter<T extends { [K in keyof T]: (...args: any[]) => any }> {\n        once<K extends keyof T>(name: K, callback: T[K]): void;\n\n        setDefaultHandler(name: string, callback: Function): void;\n\n        removeDefaultHandler(name: string, callback: Function): void;\n\n        on<K extends keyof T>(name: K, callback: T[K], capturing?: boolean): T[K];\n\n        addEventListener<K extends keyof T>(name: K, callback: T[K], capturing?: boolean): T[K];\n\n        off<K extends keyof T>(name: K, callback: T[K]): void;\n\n        removeListener<K extends keyof T>(name: K, callback: T[K]): void;\n\n        removeEventListener<K extends keyof T>(name: K, callback: T[K]): void;\n\n        removeAllListeners(name?: string): void;\n\n        _signal<K extends keyof T>(eventName: K, ...args: EmitParameters<T[K]>): void;\n\n        _emit<K extends keyof T>(eventName: K, ...args: EmitParameters<T[K]>): void;\n\n        _dispatchEvent<K extends keyof T>(eventName: K, ...args: EmitParameters<T[K]>): void;\n    }\n\n    interface SearchOptions {\n        /**The string or regular expression you're looking for*/\n        needle: string | RegExp;\n        preventScroll: boolean;\n        /**Whether to search backwards from where cursor currently is*/\n        backwards: boolean;\n        /**The starting [[Range]] or cursor position to begin the search*/\n        start: Range;\n        /**Whether or not to include the current line in the search*/\n        skipCurrent: boolean;\n        /**The [[Range]] to search within. Set this to `null` for the whole document*/\n        range: Range | null;\n        preserveCase: boolean;\n        /**Whether the search is a regular expression or not*/\n        regExp: boolean;\n        /**Whether the search matches only on whole words*/\n        wholeWord: boolean;\n        /**Whether the search ought to be case-sensitive*/\n        caseSensitive: boolean;\n        /**Whether to wrap the search back to the beginning when it hits the end*/\n        wrap: boolean;\n        re: any;\n        /**true, if needle has \\n or \\r\\n*/\n        $isMultiLine: boolean;\n        /**\n         * internal property, determine if browser supports unicode flag\n         * @private\n         * */\n        $supportsUnicodeFlag: boolean;\n    }\n\n    interface Point {\n        row: number;\n        column: number;\n    }\n\n    type Position = Point;\n\n    interface Delta {\n        action: 'insert' | 'remove';\n        start: Point;\n        end: Point;\n        lines: string[];\n        id?: number,\n        folds?: Fold[]\n    }\n\n    interface Annotation {\n        row: number;\n        column: number;\n        text: string;\n        type: string;\n    }\n\n    export interface MarkerGroupItem {\n        range: Range;\n        className: string;\n    }\n\n    type MarkerGroup = import(\"./src/marker_group\").MarkerGroup;\n\n\n    export interface Command {\n        name?: string;\n        bindKey?: string | { mac?: string, win?: string };\n        readOnly?: boolean;\n        exec?: (editor?: Editor | any, args?: any) => void;\n        isAvailable?: (editor: Editor) => boolean;\n        description?: string,\n        multiSelectAction?: \"forEach\" | \"forEachLine\" | Function,\n        scrollIntoView?: true | \"cursor\" | \"center\" | \"selectionPart\" | \"animate\" | \"selection\" | \"none\",\n        aceCommandGroup?: string,\n        passEvent?: boolean,\n        level?: number,\n        action?: string,\n    }\n\n    type CommandLike = Command | ((editor: Editor) => void) | ((sb: SearchBox) => void);\n\n    type KeyboardHandler = Partial<import(\"./src/keyboard/hash_handler\").HashHandler> & {\n        attach?: (editor: Editor) => void;\n        detach?: (editor: Editor) => void;\n        getStatusText?: (editor?: any, data?: any) => string;\n    }\n\n    export interface MarkerLike {\n        range?: Range;\n        type: string;\n        renderer?: MarkerRenderer;\n        clazz: string;\n        inFront?: boolean;\n        id?: number;\n        update?: (html: string[],\n                  // TODO maybe define Marker class\n                  marker: any,\n                  session: EditSession,\n                  config: any) => void;\n\n        [key: string]: any;\n    }\n\n    type MarkerRenderer = (html: string[],\n                           range: Range,\n                           left: number,\n                           top: number,\n                           config: any) => void;\n\n    interface Token {\n        type: string;\n        value: string;\n        index?: number;\n        start?: number;\n    }\n\n    type BaseCompletion = import(\"./src/autocomplete\").BaseCompletion;\n    type SnippetCompletion = import(\"./src/autocomplete\").SnippetCompletion;\n    type ValueCompletion = import(\"./src/autocomplete\").ValueCompletion;\n    type Completion = import(\"./src/autocomplete\").Completion;\n\n    type HighlightRule = ({ defaultToken: string } | { include: string } | { todo: string } | {\n        token: string | string[] | ((value: string) => string);\n        regex: string | RegExp;\n        next?: string | (() => void);\n        push?: string;\n        comment?: string;\n        caseInsensitive?: boolean;\n        nextState?: string;\n    }) & { [key: string]: any };\n\n    type HighlightRulesMap = Record<string, HighlightRule[]>;\n\n    type KeywordMapper = (keyword: string) => string;\n\n    interface HighlightRules {\n        $rules: HighlightRulesMap;\n        $embeds: string[];\n        $keywords: any[];\n        $keywordList: string[];\n\n        addRules(rules: HighlightRulesMap, prefix?: string): void;\n\n        getRules(): HighlightRulesMap;\n\n        embedRules(rules: (new () => HighlightRules) | HighlightRulesMap, prefix: string, escapeRules?: boolean, append?: boolean): void;\n\n        getEmbeds(): string[];\n\n        normalizeRules(): void;\n\n        createKeywordMapper(map: Record<string, string>, defaultToken?: string, ignoreCase?: boolean, splitChar?: string): KeywordMapper;\n    }\n\n    type FoldWidget = \"start\" | \"end\" | \"\"\n\n    interface FoldMode {\n        foldingStartMarker: RegExp;\n        foldingStopMarker?: RegExp;\n\n        getFoldWidget(session: EditSession, foldStyle: string, row: number): FoldWidget;\n\n        getFoldWidgetRange(session: EditSession, foldStyle: string, row: number): Range | undefined;\n\n        indentationBlock(session: EditSession, row: number, column?: number): Range | undefined;\n\n        openingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined;\n\n        closingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined;\n    }\n\n    type BehaviorAction = (state: string | string[], action: string, editor: Editor, session: EditSession, text: string | Range) => ({\n        text: string,\n        selection: number[]\n    } | Range) & { [key: string]: any } | undefined;\n    type BehaviorMap = Record<string, Record<string, BehaviorAction>>;\n\n    interface Behaviour {\n        $behaviours: { [behaviour: string]: any }\n\n        add(name: string, action: string, callback: BehaviorAction): void;\n\n        addBehaviours(behaviours: BehaviorMap): void;\n\n        remove(name: string): void;\n\n        inherit(mode: SyntaxMode | (new () => SyntaxMode), filter: string[]): void;\n\n        getBehaviours(filter?: string[]): BehaviorMap;\n    }\n\n    interface Outdent {\n        checkOutdent(line: string, input: string): boolean;\n\n        autoOutdent(doc: Document, row: number): number | undefined;\n    }\n\n    interface SyntaxMode {\n        /**\n         * quotes used by language mode\n         */\n        $quotes: { [quote: string]: string };\n        HighlightRules: {\n            new(config?: any): HighlightRules\n        }; //TODO: fix this\n        foldingRules?: FoldMode;\n        $behaviour?: Behaviour;\n        $defaultBehaviour?: Behaviour;\n        /**\n         * characters that indicate the start of a line comment\n         */\n        lineCommentStart?: string;\n        /**\n         * characters that indicate the start and end of a block comment\n         */\n        blockComment?: { start: string, end: string }\n        tokenRe?: RegExp;\n        nonTokenRe?: RegExp;\n        /**\n         * An object containing conditions to determine whether to apply matching quote or not.\n         */\n        $pairQuotesAfter: { [quote: string]: RegExp }\n        $tokenizer: Tokenizer;\n        $highlightRules: HighlightRules;\n        $embeds?: string[];\n        $modes?: SyntaxMode[];\n        $keywordList?: string[];\n        $highlightRuleConfig?: any;\n        completionKeywords: string[];\n        transformAction: BehaviorAction;\n        path?: string;\n\n        getTokenizer(): Tokenizer;\n\n        toggleCommentLines(state: string | string[],\n                           session: EditSession,\n                           startRow: number,\n                           endRow: number): void;\n\n        toggleBlockComment(state: string | string[],\n                           session: EditSession,\n                           range: Range,\n                           cursor: Point): void;\n\n        getNextLineIndent(state: string | string[], line: string, tab: string): string;\n\n        checkOutdent(state: string | string[], line: string, input: string): boolean;\n\n        autoOutdent(state: string | string[], doc: EditSession, row: number): void;\n\n        // TODO implement WorkerClient types\n        createWorker(session: EditSession): any;\n\n        createModeDelegates(mapping: { [key: string]: string }): void;\n\n        getKeywords(append?: boolean): Array<string | RegExp>;\n\n        getCompletions(state: string | string[],\n                       session: EditSession,\n                       pos: Point,\n                       prefix: string): Completion[];\n\n        $getIndent(line: string): string;\n\n        $createKeywordList(): string[];\n\n        $delegator(method: string, args: IArguments, defaultHandler: any): any;\n\n    }\n\n    interface OptionsBase {\n        [key: string]: any;\n    }\n\n    class OptionsProvider<T> {\n        setOptions(optList: Partial<T>): void;\n\n        getOptions(optionNames?: Array<keyof T> | Partial<T>): Partial<T>;\n\n        setOption<K extends keyof T>(name: K, value: T[K]): void;\n\n        getOption<K extends keyof T>(name: K): T[K];\n    }\n\n    type KeyBinding = import(\"./src/keyboard/keybinding\").KeyBinding;\n\n    interface CommandMap {\n        [name: string]: Command;\n    }\n\n    type execEventHandler = (obj: {\n        editor: Editor,\n        command: Command,\n        args: any[]\n    }, emitter: CommandManager) => void;\n\n    interface CommandManagerEvents {\n        \"exec\": execEventHandler\n        \"afterExec\": execEventHandler;\n        \"commandUnavailable\": execEventHandler;\n    }\n\n    type CommandManager = import(\"./src/commands/command_manager\").CommandManager;\n\n\n    interface SavedSelection {\n        start: Point;\n        end: Point;\n        isBackwards: boolean;\n    }\n\n    var Selection: {\n        new(session: EditSession): Selection;\n    }\n\n    type CompleterCallback = (error: any, completions: Completion[]) => void;\n\n    interface Completer {\n        /** Regular expressions defining valid identifier characters for completion triggers */\n        identifierRegexps?: Array<RegExp>,\n\n        /** Main completion method that provides suggestions for the given context */\n        getCompletions(editor: Editor,\n                       session: EditSession,\n                       position: Point,\n                       prefix: string,\n                       callback: CompleterCallback): void;\n\n        /** Returns documentation tooltip for a completion item */\n        getDocTooltip?(item: Completion): void | string | Completion;\n\n        /** Called when a completion item becomes visible */\n        onSeen?: (editor: Ace.Editor, completion: Completion) => void;\n        /** Called when a completion item is inserted */\n        onInsert?: (editor: Ace.Editor, completion: Completion) => void;\n\n        /** Cleanup method called when completion is cancelled */\n        cancel?(): void;\n\n        /** Unique identifier for this completer */\n        id?: string;\n        /** Characters that trigger autocompletion when typed */\n        triggerCharacters?: string[];\n        /** Whether to hide inline preview text */\n        hideInlinePreview?: boolean;\n        /** Custom insertion handler for completion items */\n        insertMatch?: (editor: Editor, data: Completion) => void;\n    }\n\n    interface CompletionOptions {\n        matches?: Completion[];\n    }\n\n    type CompletionProviderOptions = {\n        exactMatch?: boolean;\n        ignoreCaption?: boolean;\n    }\n\n    type GatherCompletionRecord = {\n        prefix: string;\n        matches: Completion[];\n        finished: boolean;\n    }\n\n    type CompletionCallbackFunction = (err: Error | undefined, data: GatherCompletionRecord) => void;\n    type CompletionProviderCallback = (this: import(\"./src/autocomplete\").Autocomplete, err: Error | undefined, completions: import(\"./src/autocomplete\").FilteredList, finished: boolean) => void;\n\n    type AcePopupNavigation = \"up\" | \"down\" | \"start\" | \"end\";\n\n    interface EditorMultiSelectProperties {\n        inMultiSelectMode?: boolean,\n        /**\n         * Updates the cursor and marker layers.\n         **/\n        updateSelectionMarkers: () => void,\n        /**\n         * Adds the selection and cursor.\n         * @param orientedRange A range containing a cursor\n         **/\n        addSelectionMarker: (orientedRange: Ace.Range & { marker?: any }) => Ace.Range & { marker?: any },\n        /**\n         * Removes the selection marker.\n         * @param range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].\n         **/\n        removeSelectionMarker: (range: Ace.Range & { marker?: any }) => void,\n        removeSelectionMarkers: (ranges: (Ace.Range & { marker?: any })[]) => void,\n        $onAddRange: (e: any) => void,\n        $onRemoveRange: (e: any) => void,\n        $onMultiSelect: (e: any) => void,\n        $onSingleSelect: (e: any) => void,\n        $onMultiSelectExec: (e: any) => void,\n        /**\n         * Executes a command for each selection range.\n         * @param cmd The command to execute\n         * @param [args] Any arguments for the command\n         **/\n        forEachSelection: (cmd: Object, args?: string, options?: Object) => void,\n        /**\n         * Removes all the selections except the last added one.\n         **/\n        exitMultiSelectMode: () => void,\n        getSelectedText: () => string,\n        $checkMultiselectChange: (e: any, anchor: Ace.Anchor) => void,\n        /**\n         * Finds and selects all the occurrences of `needle`.\n         * @param needle The text to find\n         * @param options The search options\n         * @param additive keeps\n         * @returns {Number} The cumulative count of all found matches\n         **/\n        findAll: (needle?: string, options?: Partial<Ace.SearchOptions>, additive?: boolean) => number,\n        /**\n         * Adds a cursor above or below the active cursor.\n         * @param dir The direction of lines to select: -1 for up, 1 for down\n         * @param [skip] If `true`, removes the active selection range\n         */\n        selectMoreLines: (dir: number, skip?: boolean) => void,\n        /**\n         * Transposes the selected ranges.\n         * @param {Number} dir The direction to rotate selections\n         **/\n        transposeSelections: (dir: number) => void,\n        /**\n         * Finds the next occurrence of text in an active selection and adds it to the selections.\n         * @param {Number} dir The direction of lines to select: -1 for up, 1 for down\n         * @param {Boolean} [skip] If `true`, removes the active selection range\n         * @param {Boolean} [stopAtFirst]\n         **/\n        selectMore: (dir: number, skip?: boolean, stopAtFirst?: boolean) => void,\n        /**\n         * Aligns the cursors or selected text.\n         **/\n        alignCursors: () => void,\n        $reAlignText: (lines: string[], forceLeft: boolean) => string[],\n        multiSelect?: any,\n        $multiselectOnSessionChange?: any,\n        $blockSelectEnabled?: boolean,\n    }\n\n    /**\n     * Provider interface for code lens functionality\n     */\n    interface CodeLenseProvider {\n        /**\n         * Compute code lenses for the given edit session\n         * @param session The edit session to provide code lenses for\n         * @param callback Callback function that receives errors and code lenses\n         */\n        provideCodeLenses: (session: EditSession, callback: (err: any, payload: CodeLense[]) => void) => void;\n    }\n\n    /**\n     * Represents a command associated with a code lens\n     */\n    interface CodeLenseCommand {\n        /**\n         * Command identifier that will be executed\n         */\n        id?: string,\n        /**\n         * Display title for the code lens\n         */\n        title: string,\n        /**\n         * Argument(s) to pass to the command when executed\n         */\n        arguments?: any,\n    }\n\n    /**\n     * Represents a code lens - an actionable UI element displayed above a code line\n     */\n    interface CodeLense {\n        /**\n         * Starting position where the code lens should be displayed\n         */\n        start: Point,\n        /**\n         * Command to execute when the code lens is activated\n         */\n        command?: CodeLenseCommand\n    }\n\n    interface CodeLenseEditorExtension {\n        codeLensProviders?: CodeLenseProvider[];\n        $codeLensClickHandler?: any;\n        $updateLenses?: () => void;\n        $updateLensesOnInput?: () => void;\n    }\n\n    interface ElasticTabstopsEditorExtension {\n        elasticTabstops?: import(\"./src/ext/elastic_tabstops_lite\").ElasticTabstopsLite;\n    }\n\n    interface TextareaEditorExtension {\n        setDisplaySettings?: (settings: any) => void;\n    }\n\n    interface PromptEditorExtension {\n        cmdLine?: Editor;\n    }\n\n    interface OptionsEditorExtension {\n        $options?: any;\n    }\n\n    interface MultiSelectProperties {\n        ranges: Ace.Range[] | null;\n        rangeList: Ace.RangeList | null;\n\n        /**\n         * Adds a range to a selection by entering multiselect mode, if necessary.\n         * @param {Ace.Range} range The new range to add\n         * @param {Boolean} [$blockChangeEvents] Whether or not to block changing events\n         **/\n        addRange(range: Ace.Range, $blockChangeEvents?: boolean): any;\n\n        inMultiSelectMode: boolean;\n\n        /**\n         * @param {Ace.Range} [range]\n         **/\n        toSingleRange(range?: Ace.Range): void;\n\n        /**\n         * Removes a Range containing pos (if it exists).\n         * @param {Ace.Point} pos The position to remove, as a `{row, column}` object\n         **/\n        substractPoint(pos: Ace.Point): any;\n\n        /**\n         * Merges overlapping ranges ensuring consistency after changes\n         **/\n        mergeOverlappingRanges(): void;\n\n        /**\n         * @param {Ace.Range} range\n         */\n        $onAddRange(range: Ace.Range): void;\n\n        rangeCount: number;\n\n        /**\n         *\n         * @param {Ace.Range[]} removed\n         */\n        $onRemoveRange(removed: Ace.Range[]): void;\n\n        /**\n         * adds multicursor support to selection\n         */\n        $initRangeList(): void;\n\n        /**\n         * Returns a concatenation of all the ranges.\n         * @returns {Ace.Range[]}\n         **/\n        getAllRanges(): Ace.Range[];\n\n        /**\n         * Splits all the ranges into lines.\n         **/\n        splitIntoLines(): void;\n\n        /**\n         */\n        joinSelections(): void;\n\n        /**\n         **/\n        toggleBlockSelection(): void;\n\n        /**\n         *\n         * Gets list of ranges composing rectangular block on the screen\n         *\n         * @param {Ace.ScreenCoordinates} screenCursor The cursor to use\n         * @param {Ace.ScreenCoordinates} screenAnchor The anchor to use\n         * @param {Boolean} [includeEmptyLines] If true, this includes ranges inside the block which are empty due to clipping\n         * @returns {Ace.Range[]}\n         **/\n        rectangularRangeBlock(screenCursor: Ace.ScreenCoordinates, screenAnchor: Ace.ScreenCoordinates, includeEmptyLines?: boolean): Ace.Range[];\n\n        _eventRegistry?: any;\n        index?: number;\n    }\n\n    type AcePopupEventsCombined = Ace.EditorEvents & Ace.AcePopupEvents;\n    type AcePopupWithEditor = Ace.EventEmitter<AcePopupEventsCombined> & Ace.Editor;\n    type InlineAutocompleteAction = \"prev\" | \"next\" | \"first\" | \"last\";\n\n    type TooltipCommandFunction<T> = (editor: Ace.Editor) => T;\n\n    export interface TooltipCommand extends Ace.Command {\n        enabled?: TooltipCommandFunction<boolean> | boolean,\n        getValue?: TooltipCommandFunction<any>,\n        type: \"button\" | \"text\" | \"checkbox\"\n        iconCssClass?: string,\n        cssClass?: string\n    }\n\n    export type CommandBarTooltip = import(\"./src/ext/command_bar\").CommandBarTooltip;\n\n    export type TokenizeResult = Array<Array<{\n        className?: string,\n        value: string,\n    }>>\n\n    export interface StaticHighlightOptions {\n        /** Syntax mode (e.g., 'ace/mode/javascript'). Auto-detected from CSS class if not provided */\n        mode?: string | SyntaxMode,\n        /** Color theme (e.g., 'ace/theme/textmate'). Defaults to 'ace/theme/textmate' */\n        theme?: string | Theme,\n        /** Whether to trim whitespace from code content */\n        trim?: boolean,\n        /** Starting line number for display */\n        firstLineNumber?: number,\n        /** Whether to show line numbers gutter */\n        showGutter?: boolean\n    }\n\n    export interface Operation {\n        command: {\n            name?: string;\n        };\n        args: any;\n        selectionBefore?: Range | Range[];\n        selectionAfter?: Range | Range[];\n        docChanged?: boolean;\n        selectionChanged?: boolean;\n    }\n\n    export interface CommandBarEvents {\n        \"hide\": (e: undefined, emitter: import(\"./src/ext/command_bar\").CommandBarTooltip) => void;\n        \"show\": (e: undefined, emitter: import(\"./src/ext/command_bar\").CommandBarTooltip) => void;\n        \"alwaysShow\": (e: boolean, emitter: import(\"./src/ext/command_bar\").CommandBarTooltip) => void;\n    }\n\n    export interface FontMetricsEvents {\n        \"changeCharacterSize\": (e: { data: { height: number, width: number } }, emitter: import(\"./src/layer/font_metrics\").FontMetrics) => void;\n    }\n\n    export interface OptionPanelEvents {\n        \"setOption\": (e: { name: string, value: any }, emitter: import(\"./src/ext/options\").OptionPanel) => void;\n    }\n\n    export interface ScrollbarEvents {\n        \"scroll\": (e: { data: number }, emitter: ScrollBar) => void;\n    }\n\n    export interface TextInputAriaOptions {\n        activeDescendant?: string;\n        role?: string;\n        setLabel?: boolean;\n        inline?: boolean;\n    }\n}\n\n\nexport const version: string;\nexport const config: Ace.Config;\n\nexport function require(name: string): any;\n\nexport function edit(el?: string | (Element & {\n    env?: any;\n    value?: any;\n}) | null, options?: Partial<Ace.EditorOptions>): Ace.Editor;\n\nexport function createEditSession(text: Ace.Document | string, mode?: Ace.SyntaxMode | string): Ace.EditSession;\n\nexport const VirtualRenderer: {\n    new(container: HTMLElement, theme?: string): Ace.VirtualRenderer;\n};\nexport const EditSession: {\n    new(text: string | Ace.Document, mode?: Ace.SyntaxMode): Ace.EditSession;\n};\nexport const UndoManager: {\n    new(): Ace.UndoManager;\n};\nexport const Editor: {\n    new(renderer: Ace.VirtualRenderer, session?: Ace.EditSession, options?: Partial<Ace.EditorOptions>): Ace.Editor;\n};\nexport const Range: {\n    new(startRow: number, startColumn: number, endRow: number, endColumn: number): Ace.Range;\n    fromPoints(start: Ace.Point, end: Ace.Point): Ace.Range;\n    comparePoints(p1: Ace.Point, p2: Ace.Point): number;\n};\n\nexport type InlineAutocomplete = Ace.InlineAutocomplete;\nexport type CommandBarTooltip = Ace.CommandBarTooltip;\n\ndeclare global {\n    interface Element {\n        setAttribute(name: string, value: boolean): void;\n\n        setAttribute(name: string, value: number): void;\n    }\n}\n\ndeclare module \"./src/anchor\" {\n    export interface Anchor extends Ace.EventEmitter<Ace.AnchorEvents> {\n        markerId?: number;\n        document: Ace.Document;\n    }\n\n\n}\n\ndeclare module \"./src/autocomplete\" {\n    export interface Autocomplete {\n        popup: Ace.AcePopup;\n        emptyMessage?: Function,\n    }\n\n    export interface CompletionProvider {\n        completions: Ace.FilteredList;\n    }\n}\n\ndeclare module \"./src/background_tokenizer\" {\n    export interface BackgroundTokenizer extends Ace.EventEmitter<Ace.BackgroundTokenizerEvents> {\n\n    }\n}\n\ndeclare module \"./src/document\" {\n    export interface Document extends Ace.EventEmitter<Ace.DocumentEvents> {\n    }\n\n}\n\ndeclare module \"./src/editor\" {\n    export interface Editor extends Ace.EditorMultiSelectProperties, Ace.OptionsProvider<Ace.EditorOptions>,\n        Ace.EventEmitter<Ace.EditorEvents>, Ace.CodeLenseEditorExtension, Ace.ElasticTabstopsEditorExtension,\n        Ace.TextareaEditorExtension, Ace.PromptEditorExtension, Ace.OptionsEditorExtension {\n        session: Ace.EditSession;\n        $mergeUndoDeltas?: any,\n        $highlightSelectedWord?: boolean,\n        $updatePlaceholder?: Function,\n        $cursorStyle?: string,\n        $readOnly?: any,\n        $highlightActiveLine?: any,\n        $enableAutoIndent?: any,\n        $copyWithEmptySelection?: any\n        $selectionStyle?: string,\n        env?: any;\n        widgetManager?: Ace.LineWidgets,\n        completer?: Ace.Autocomplete | Ace.InlineAutocomplete,\n        completers: Ace.Completer[],\n        $highlightTagPending?: boolean,\n        showKeyboardShortcuts?: () => void,\n        showSettingsMenu?: () => void,\n        searchBox?: Ace.SearchBox,\n        _eventRegistry?: any,\n        $textInputAriaLabel?: string\n    }\n}\n\ndeclare module \"./src/edit_session\" {\n    type TextMarker = import(\"./src/layer/text_markers\").TextMarker;\n    type TextMarkers = typeof import(\"./src/layer/text_markers\").editSessionTextMarkerMixin & {\n        $textMarkers: TextMarker[];\n        $textMarkerId: number;\n        $scheduleForRemove: Set<string>;\n    };\n\n    export interface EditSession extends Ace.EventEmitter<Ace.EditSessionEvents>,\n        Ace.OptionsProvider<Ace.EditSessionOptions>,\n        Ace.Folding, Ace.BracketMatch, TextMarkers  {\n        doc: Ace.Document,\n        $highlightLineMarker?: {\n            start: Ace.Point,\n            end: Ace.Point,\n            id?: number\n        }\n        $useSoftTabs?: boolean,\n        $tabSize?: number,\n        $useWorker?: boolean,\n        $wrapAsCode?: boolean,\n        $indentedSoftWrap?: boolean,\n        $bracketHighlight?: any,\n        $selectionMarker?: number,\n        lineWidgetsWidth?: number,\n        $getWidgetScreenLength?: () => number,\n        _changedWidgets?: any,\n        $options: any,\n        $wrapMethod?: any,\n        $enableVarChar?: any,\n        $wrap?: any,\n        $navigateWithinSoftTabs?: boolean,\n        $selectionMarkers?: any[],\n        gutterRenderer?: any,\n        $firstLineNumber?: number,\n        $emacsMark?: any,\n        selectionMarkerCount?: number,\n        multiSelect?: any,\n        $occurHighlight?: any,\n        $occur?: Ace.Occur,\n        $occurMatchingLines?: any,\n        $useEmacsStyleLineStart?: boolean,\n        $selectLongWords?: boolean,\n        curOp: Ace.Operation | null,\n\n        getSelectionMarkers(): any[],\n    }\n\n}\n\ndeclare module \"./src/edit_session/fold\" {\n    export interface Fold {\n        collapseChildren?: number;\n    }\n}\n\ndeclare module \"./src/placeholder\" {\n    export interface PlaceHolder extends Ace.EventEmitter<Ace.PlaceHolderEvents> {\n    }\n}\n\ndeclare module \"./src/scrollbar\" {\n    export interface VScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n\n    export interface HScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n}\n\ndeclare module \"./src/scrollbar_custom\" {\n    export interface VScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n\n    export interface HScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n}\n\ndeclare module \"./src/line_widgets\" {\n    export interface LineWidgets {\n        lineWidgets: Ace.LineWidget[];\n        editor: Ace.Editor;\n    }\n}\n\ndeclare module \"./src/selection\" {\n    export interface Selection extends Ace.EventEmitter<Ace.MultiSelectionEvents>, Ace.MultiSelectProperties {\n    }\n}\n\ndeclare module \"./src/range\" {\n    export interface Range {\n        id?: number;\n        cursor?: Ace.Point;\n        isBackwards?: boolean;\n    }\n}\n\ndeclare module \"./src/virtual_renderer\" {\n    export interface VirtualRenderer extends Ace.EventEmitter<Ace.VirtualRendererEvents>, Ace.OptionsProvider<Ace.VirtualRendererOptions> {\n        $customScrollbar?: boolean,\n        $extraHeight?: number,\n        $showGutter?: boolean,\n        $showPrintMargin?: boolean,\n        $printMarginColumn?: number,\n        $animatedScroll?: boolean,\n        $isMousePressed?: boolean,\n        textarea: HTMLTextAreaElement,\n        $hScrollBarAlwaysVisible?: boolean,\n        $vScrollBarAlwaysVisible?: boolean\n        $maxLines?: number,\n        $scrollPastEnd?: number,\n        enableKeyboardAccessibility?: boolean,\n        $highlightGutterLine?: boolean,\n        $minLines?: number,\n        $maxPixelHeight?: number,\n        $gutterWidth?: number,\n        showInvisibles?: boolean,\n        $hasCssTransforms?: boolean,\n        $blockCursor?: boolean,\n        $useTextareaForIME?: boolean,\n        theme?: any,\n        $theme?: any,\n        destroyed?: boolean,\n        session: Ace.EditSession,\n        keyboardFocusClassName?: string,\n    }\n}\n\ndeclare module \"./src/snippets\" {\n    interface SnippetManager extends Ace.EventEmitter<any> {\n    }\n}\n\ndeclare module \"./src/ext/command_bar\" {\n    export interface CommandBarTooltip extends Ace.EventEmitter<Ace.CommandBarEvents> {\n        $shouldHideMoreOptions?: boolean,\n    }\n}\n\ndeclare module \"./src/commands/command_manager\" {\n    export interface CommandManager extends Ace.EventEmitter<Ace.CommandManagerEvents> {\n        $checkCommandState?: boolean\n    }\n}\n\ndeclare module \"./src/autocomplete/popup\" {\n\n    export interface AcePopup extends Ace.AcePopupWithEditor {\n        setSelectOnHover: (val: boolean) => void,\n        setRow: (line: number) => void,\n        getRow: () => number,\n        getHoveredRow: () => number,\n        filterText: string,\n        isOpen: boolean,\n        isTopdown: boolean,\n        autoSelect: boolean,\n        data: Ace.Completion[],\n        setData: (data: Ace.Completion[], filterText?: string) => void,\n        getData: (row: number) => Ace.Completion,\n        hide: () => void,\n        anchor: \"top\" | \"bottom\",\n        anchorPosition: Ace.Point,\n        tryShow: (pos: any, lineHeight: number, anchor: \"top\" | \"bottom\", forceShow?: boolean) => boolean,\n        $borderSize: number,\n        show: (pos: any, lineHeight: number, topdownOnly?: boolean) => void,\n        goTo: (where: Ace.AcePopupNavigation) => void,\n        getTextLeftOffset: () => number,\n        $imageSize: number,\n        anchorPos: any,\n        isMouseOver?: boolean,\n        selectedNode?: HTMLElement,\n    }\n}\n\ndeclare module \"./src/layer/cursor\" {\n    export interface Cursor {\n        timeoutId?: number;\n    }\n}\n\ndeclare module \"./src/layer/gutter\" {\n    export interface Gutter extends Ace.EventEmitter<Ace.GutterEvents> {\n        $useSvgGutterIcons?: boolean,\n        $showFoldedAnnotations?: boolean,\n    }\n}\n\ndeclare module \"./src/layer/text\" {\n    type TextMarkersMixin = typeof import(\"./src/layer/text_markers\").textMarkerMixin;\n    export interface Text extends Ace.EventEmitter<Ace.TextEvents>, TextMarkersMixin {\n        config: Ace.LayerConfig\n    }\n}\n\ndeclare module \"./src/lib/app_config\" {\n    export interface AppConfig extends Ace.EventEmitter<any> {\n    }\n}\n\ndeclare module \"./src/mouse/mouse_event\" {\n    export interface MouseEvent {\n        time?: number;\n    }\n}\n\ndeclare module \"./src/mouse/mouse_handler\" {\n\n    export interface MouseHandler {\n        cancelDrag?: boolean\n        //from DefaultHandlers\n        $clickSelection?: Ace.Range,\n        mousedownEvent?: Ace.MouseEvent,\n        startSelect?: (pos?: Ace.Point, waitForClickSelection?: boolean) => void,\n        select?: () => void\n        $lastScroll?: { t: number, vx: number, vy: number, allowed: number }\n        selectEnd?: () => void\n        $tooltip?: Ace.GutterTooltip\n    }\n}\n\ndeclare module \"./src/ext/options\" {\n    export interface OptionPanel extends Ace.EventEmitter<Ace.OptionPanelEvents> {\n    }\n}\n\ndeclare module \"./src/layer/font_metrics\" {\n    export interface FontMetrics extends Ace.EventEmitter<Ace.FontMetricsEvents> {\n    }\n}\n\ndeclare module \"./src/tooltip\" {\n    export interface HoverTooltip {\n        row: number;\n    }\n}\n\ndeclare module \"./src/mouse/default_gutter_handler\" {\n    export interface GutterHandler {\n    }\n}\n\ndeclare module \"./src/ext/diff/base_diff_view\" {\n    export interface BaseDiffView extends Ace.OptionsProvider<import(\"ace-code/src/ext/diff\").DiffViewOptions> {\n    }\n}\n\n"
  },
  {
    "path": "ace-modes.d.ts",
    "content": "declare module \"ace-code/src/mode/abap_highlight_rules\" {\n    export const AbapHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/abap\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/abc_highlight_rules\" {\n    export const ABCHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/abc\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/actionscript_highlight_rules\" {\n    export const ActionScriptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/actionscript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ada_highlight_rules\" {\n    export const AdaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ada\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/alda_highlight_rules\" {\n    export const AldaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/alda\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/apache_conf_highlight_rules\" {\n    export const ApacheConfHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/apache_conf\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/apex_highlight_rules\" {\n    export const ApexHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/apex\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/applescript_highlight_rules\" {\n    export const AppleScriptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/applescript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/aql_highlight_rules\" {\n    export const AqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/aql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/asciidoc_highlight_rules\" {\n    export const AsciidocHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/asciidoc\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/asl_highlight_rules\" {\n    export const ASLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/asl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/assembly_arm32_highlight_rules\" {\n    export const AssemblyARM32HighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/assembly_arm32\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/assembly_x86_highlight_rules\" {\n    export const AssemblyX86HighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/assembly_x86\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/astro_highlight_rules\" {\n    export const AstroHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/astro\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/autohotkey_highlight_rules\" {\n    export const AutoHotKeyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/autohotkey\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/basic_highlight_rules\" {\n    export const BasicHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/basic\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/batchfile_highlight_rules\" {\n    export const BatchFileHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/batchfile\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/behaviour\" {\n    export const Behaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/css\" {\n    export const CssBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/cstyle\" {\n    export const CstyleBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/html\" {\n    export const HtmlBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/javascript\" {\n    export const JavaScriptBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/liquid\" {\n    export const LiquidBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/xml\" {\n    export const XmlBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/behaviour/xquery\" {\n    export const XQueryBehaviour: new () => import(\"ace-code\").Ace.Behaviour;\n}\n\ndeclare module \"ace-code/src/mode/bibtex_highlight_rules\" {\n    export const BibTeXHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/bibtex\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/c_cpp_highlight_rules\" {\n    export const cFunctions: string;\n    export const c_cppHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/c_cpp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/c9search_highlight_rules\" {\n    export const C9SearchHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/c9search\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/cirru_highlight_rules\" {\n    export const CirruHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/cirru\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/clojure_highlight_rules\" {\n    export const ClojureHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/clojure\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/clue_highlight_rules\" {\n    export const ClueHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/clue\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/cobol_highlight_rules\" {\n    export const CobolHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/cobol\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/coffee_highlight_rules\" {\n    export const CoffeeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/coffee\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/coldfusion_highlight_rules\" {\n    export const ColdfusionHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/coldfusion\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/crystal_highlight_rules\" {\n    export const CrystalHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/crystal\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csharp_highlight_rules\" {\n    export const CSharpHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csharp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csound_document_highlight_rules\" {\n    export const CsoundDocumentHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csound_document\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csound_orchestra_highlight_rules\" {\n    export const CsoundOrchestraHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csound_orchestra\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csound_preprocessor_highlight_rules\" {\n    export const CsoundPreprocessorHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csound_score_highlight_rules\" {\n    export const CsoundScoreHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csound_score\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csp_highlight_rules\" {\n    export const CspHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/css_completions\" {\n    export const CssCompletions: new () => import(\"ace-code\").Ace.Completion;\n}\n\ndeclare module \"ace-code/src/mode/css_highlight_rules\" {\n    export const supportType: string;\n    export const supportFunction: string;\n    export const supportConstant: string;\n    export const supportConstantColor: string;\n    export const supportConstantFonts: string;\n    export const numRe: string;\n    export const pseudoElements: string;\n    export const pseudoClasses: string;\n    export const CssHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/css\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/csv_highlight_rules\" {\n    export const CsvHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/csv\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/curly_highlight_rules\" {\n    export const CurlyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/curly\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/cuttlefish_highlight_rules\" {\n    export const CuttlefishHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/cuttlefish\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/d_highlight_rules\" {\n    export const DHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/d\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/dart_highlight_rules\" {\n    export const DartHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/dart\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/diff_highlight_rules\" {\n    export const DiffHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/diff\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/django\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/doc_comment_highlight_rules\" {\n    export const DocCommentHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/dockerfile_highlight_rules\" {\n    export const DockerfileHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/dockerfile\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/dot_highlight_rules\" {\n    export const DotHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/dot\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/drools_highlight_rules\" {\n    export const DroolsHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/drools\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/edifact_highlight_rules\" {\n    export const EdifactHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/edifact\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/eiffel_highlight_rules\" {\n    export const EiffelHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/eiffel\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ejs\" {\n    export const EjsHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/elixir_highlight_rules\" {\n    export const ElixirHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/elixir\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/elm_highlight_rules\" {\n    export const ElmHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/elm\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/erlang_highlight_rules\" {\n    export const ErlangHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/erlang\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/flix_highlight_rules\" {\n    export const FlixHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/flix\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/folding/asciidoc\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/basic\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/c9search\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/coffee\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/csharp\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/cstyle\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/diff\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/drools\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/fold_mode\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/haskell_cabal\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/html\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/ini\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/java\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/javascript\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/latex\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/lua\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/markdown\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/mixed\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/nunjucks\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/php\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/pythonic\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/ruby\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/sql\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/sqlserver\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/vbscript\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/velocity\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/xml\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/folding/yaml\" {\n    export const FoldMode: new () => import(\"ace-code\").Ace.Folding;\n}\n\ndeclare module \"ace-code/src/mode/forth_highlight_rules\" {\n    export const ForthHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/forth\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/fortran_highlight_rules\" {\n    export const FortranHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/fortran\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/fsharp_highlight_rules\" {\n    export const FSharpHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/fsharp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/fsl_highlight_rules\" {\n    export const FSLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/fsl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ftl_highlight_rules\" {\n    export const FtlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ftl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/gcode_highlight_rules\" {\n    export const GcodeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/gcode\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/gherkin_highlight_rules\" {\n    export const GherkinHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/gherkin\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/gitignore_highlight_rules\" {\n    export const GitignoreHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/gitignore\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/glsl_highlight_rules\" {\n    export const glslHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/glsl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/gobstones_highlight_rules\" {\n    export const GobstonesHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/gobstones\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/golang_highlight_rules\" {\n    export const GolangHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/golang\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/graphqlschema_highlight_rules\" {\n    export const GraphQLSchemaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/graphqlschema\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/groovy_highlight_rules\" {\n    export const GroovyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/groovy\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/haml_highlight_rules\" {\n    export const HamlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/haml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/handlebars_highlight_rules\" {\n    export const HandlebarsHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/handlebars\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/haskell_cabal_highlight_rules\" {\n    export const CabalHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/haskell_cabal\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/haskell_highlight_rules\" {\n    export const HaskellHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/haskell\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/haxe_highlight_rules\" {\n    export const HaxeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/haxe\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/hjson_highlight_rules\" {\n    export const HjsonHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/hjson\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/html_completions\" {\n    export const HtmlCompletions: new () => import(\"ace-code\").Ace.Completion;\n}\n\ndeclare module \"ace-code/src/mode/html_elixir_highlight_rules\" {\n    export const HtmlElixirHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/html_elixir\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/html_highlight_rules\" {\n    export const HtmlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/html_ruby_highlight_rules\" {\n    export const HtmlRubyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/html_ruby\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/html\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ini_highlight_rules\" {\n    export const IniHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ini\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/io_highlight_rules\" {\n    export const IoHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/io\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ion_highlight_rules\" {\n    export const IonHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ion\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jack_highlight_rules\" {\n    export const JackHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jack\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jade_highlight_rules\" {\n    export const JadeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jade\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/java_highlight_rules\" {\n    export const JavaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/java\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/javascript_highlight_rules\" {\n    export const JavaScriptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/javascript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jexl_highlight_rules\" {\n    export const JexlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jexl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/js_regex_highlight_rules\" {\n    export const JsRegexHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jsdoc_comment_highlight_rules\" {\n    export const JsDocCommentHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/json_highlight_rules\" {\n    export const JsonHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/json\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/json5_highlight_rules\" {\n    export const Json5HighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/json5\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jsp_highlight_rules\" {\n    export const JspHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jsp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jssm_highlight_rules\" {\n    export const JSSMHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jssm\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/jsx_highlight_rules\" {\n    export const JsxHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/jsx\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/julia_highlight_rules\" {\n    export const JuliaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/julia\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/kotlin_highlight_rules\" {\n    export const KotlinHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/kotlin\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/latex_highlight_rules\" {\n    export const LatexHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/latex\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/latte_highlight_rules\" {\n    export const LatteHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/latte\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/less_highlight_rules\" {\n    export const LessHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/less\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/liquid_highlight_rules\" {\n    export const LiquidHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/liquid\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/lisp_highlight_rules\" {\n    export const LispHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/lisp\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/livescript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/logiql_highlight_rules\" {\n    export const LogiQLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/logiql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/logtalk_highlight_rules\" {\n    export const LogtalkHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/logtalk\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/lsl_highlight_rules\" {\n    export const LSLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/lsl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/lua_highlight_rules\" {\n    export const LuaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/lua\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/luapage_highlight_rules\" {\n    export const LuaPageHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/luapage\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/lucene_highlight_rules\" {\n    export const LuceneHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/lucene\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/makefile_highlight_rules\" {\n    export const MakefileHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/makefile\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/markdown_highlight_rules\" {\n    export const MarkdownHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/markdown\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mask_highlight_rules\" {\n    export const MaskHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mask\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/matching_brace_outdent\" {\n    export const MatchingBraceOutdent: new () => import(\"ace-code\").Ace.Outdent;\n}\n\ndeclare module \"ace-code/src/mode/matching_parens_outdent\" {\n    export const MatchingParensOutdent: new () => import(\"ace-code\").Ace.Outdent;\n}\n\ndeclare module \"ace-code/src/mode/matlab_highlight_rules\" {\n    export const MatlabHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/matlab\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/maze_highlight_rules\" {\n    export const MazeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/maze\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mediawiki_highlight_rules\" {\n    export const MediaWikiHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mediawiki\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mel_highlight_rules\" {\n    export const MELHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mel\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mips_highlight_rules\" {\n    export const MIPSHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mips\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mixal_highlight_rules\" {\n    export const MixalHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mixal\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mushcode_highlight_rules\" {\n    export const MushCodeRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mushcode\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/mysql_highlight_rules\" {\n    export const MysqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/mysql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nasal_highlight_rules\" {\n    export const NasalHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nasal\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nginx_highlight_rules\" {\n    export const NginxHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nginx\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nim_highlight_rules\" {\n    export const NimHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nim\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nix_highlight_rules\" {\n    export const NixHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nix\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nsis_highlight_rules\" {\n    export const NSISHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nsis\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/nunjucks_highlight_rules\" {\n    export const NunjucksHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/nunjucks\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/objectivec_highlight_rules\" {\n    export const ObjectiveCHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/objectivec\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ocaml_highlight_rules\" {\n    export const OcamlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ocaml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/odin_highlight_rules\" {\n    export const OdinHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/odin\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/partiql_highlight_rules\" {\n    export const PartiqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/partiql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/pascal_highlight_rules\" {\n    export const PascalHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/pascal\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/perl_highlight_rules\" {\n    export const PerlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/perl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/pgsql_highlight_rules\" {\n    export const PgsqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/pgsql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/php_completions\" {\n    export const PhpCompletions: new () => import(\"ace-code\").Ace.Completion;\n}\n\ndeclare module \"ace-code/src/mode/php_highlight_rules\" {\n    export const PhpHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const PhpLangHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/php_laravel_blade_highlight_rules\" {\n    export const PHPLaravelBladeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/php_laravel_blade\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/php\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/pig_highlight_rules\" {\n    export const PigHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/pig\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/plain_text\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/plsql_highlight_rules\" {\n    export const plsqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/plsql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/powershell_highlight_rules\" {\n    export const PowershellHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/powershell\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/praat_highlight_rules\" {\n    export const PraatHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/praat\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/prisma_highlight_rules\" {\n    export const PrismaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/prisma\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/prolog_highlight_rules\" {\n    export const PrologHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/prolog\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/properties_highlight_rules\" {\n    export const PropertiesHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/properties\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/protobuf_highlight_rules\" {\n    export const ProtobufHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/protobuf\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/prql_highlight_rules\" {\n    export const PrqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/prql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/puppet_highlight_rules\" {\n    export const PuppetHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/puppet\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/python_highlight_rules\" {\n    export const PythonHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/python\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/qml_highlight_rules\" {\n    export const QmlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/qml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/r_highlight_rules\" {\n    export const RHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/r\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/raku_highlight_rules\" {\n    export const RakuHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/raku\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/razor_completions\" {\n    export const RazorCompletions: new () => import(\"ace-code\").Ace.Completion;\n}\n\ndeclare module \"ace-code/src/mode/razor_highlight_rules\" {\n    export const RazorHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const RazorLangHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/razor\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/rdoc_highlight_rules\" {\n    export const RDocHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/rdoc\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/red_highlight_rules\" {\n    export const RedHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/red\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/redshift_highlight_rules\" {\n    export const RedshiftHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/redshift\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/rhtml_highlight_rules\" {\n    export const RHtmlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/rhtml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/robot_highlight_rules\" {\n    export const RobotHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/robot\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/rst_highlight_rules\" {\n    export const RSTHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/rst\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/ruby_highlight_rules\" {\n    export const constantOtherSymbol: { token: string; regex: string; };\n    export const qString: { token: string; regex: string; };\n    export const qqString: { token: string; regex: string; };\n    export const tString: { token: string; regex: string; };\n    export const constantNumericHex: { token: string; regex: string; };\n    export const constantNumericBinary: { token: string; regex: RegExp; };\n    export const constantNumericDecimal: { token: string; regex: RegExp; };\n    export const constantNumericOctal: { token: string; regex: RegExp; };\n    export const constantNumericRational: { token: string; regex: RegExp; };\n    export const constantNumericComplex: { token: string; regex: RegExp; };\n    export const constantNumericFloat: { token: string; regex: string; };\n    export const instanceVariable: { token: string; regex: string; };\n    export const RubyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/ruby\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/rust_highlight_rules\" {\n    export const RustHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/rust\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sac_highlight_rules\" {\n    export const sacHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sac\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sass_highlight_rules\" {\n    export const SassHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sass\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/scad_highlight_rules\" {\n    export const scadHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/scad\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/scala_highlight_rules\" {\n    export const ScalaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/scala\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/scheme_highlight_rules\" {\n    export const SchemeHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/scheme\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/scrypt_highlight_rules\" {\n    export const scryptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/scrypt\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/scss_highlight_rules\" {\n    export const ScssHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/scss\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sh_highlight_rules\" {\n    export const reservedKeywords: string;\n    export const languageConstructs: string;\n    export const ShHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sh\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sjs_highlight_rules\" {\n    export const SJSHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sjs\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/slim_highlight_rules\" {\n    export const SlimHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/slim\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/smarty_highlight_rules\" {\n    export const SmartyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/smarty\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/smithy_highlight_rules\" {\n    export const SmithyHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/smithy\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/snippets\" {\n    export const SnippetHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const SnippetGroupHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/soy_template_highlight_rules\" {\n    export const SoyTemplateHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/soy_template\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/space_highlight_rules\" {\n    export const SpaceHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/space\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sparql_highlight_rules\" {\n    export const SPARQLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sparql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sql_highlight_rules\" {\n    export const SqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sql\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/sqlserver_highlight_rules\" {\n    export const SqlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/sqlserver\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/stylus_highlight_rules\" {\n    export const StylusHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/stylus\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/svg_highlight_rules\" {\n    export const SvgHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/svg\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/swift_highlight_rules\" {\n    export const HighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n    export const SwiftHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/swift\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/tcl_highlight_rules\" {\n    export const TclHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/tcl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/terraform_highlight_rules\" {\n    export const TerraformHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/terraform\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/tex_highlight_rules\" {\n    export const TexHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/tex\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/text_highlight_rules\" {\n    export const TextHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/text\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/textile_highlight_rules\" {\n    export const TextileHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/textile\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/toml_highlight_rules\" {\n    export const TomlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/toml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/tsv_highlight_rules\" {\n    export const TsvHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/tsv\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/tsx_highlight_rules\" {\n    export const TsxHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/tsx\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/turtle_highlight_rules\" {\n    export const TurtleHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/turtle\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/twig_highlight_rules\" {\n    export const TwigHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/twig\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/typescript_highlight_rules\" {\n    export const TypeScriptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/typescript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/vala_highlight_rules\" {\n    export const ValaHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/vala\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/vbscript_highlight_rules\" {\n    export const VBScriptHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/vbscript\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/velocity_highlight_rules\" {\n    export const VelocityHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/velocity\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/verilog_highlight_rules\" {\n    export const VerilogHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/verilog\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/vhdl_highlight_rules\" {\n    export const VHDLHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/vhdl\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/visualforce_highlight_rules\" {\n    export const VisualforceHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/visualforce\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/vue_highlight_rules\" {\n    export const VueHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/vue\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/wollok_highlight_rules\" {\n    export const WollokHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/wollok\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/xml_highlight_rules\" {\n    export const XmlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/xml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/yaml_highlight_rules\" {\n    export const YamlHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/yaml\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/zeek_highlight_rules\" {\n    export const ZeekHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/zeek\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}\n\ndeclare module \"ace-code/src/mode/zig_highlight_rules\" {\n    export const ZigHighlightRules: new () => import(\"ace-code\").Ace.HighlightRules;\n}\n\ndeclare module \"ace-code/src/mode/zig\" {\n    export const Mode: new () => import(\"ace-code\").Ace.SyntaxMode;\n}"
  },
  {
    "path": "ace.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\n/// <reference path=\"./types/ace-lib.d.ts\" />\n/// <reference path=\"./types/ace-modules.d.ts\" />\n/// <reference path=\"./types/ace-theme.d.ts\" />\n/// <reference path=\"./types/ace-ext.d.ts\" />\n/// <reference path=\"./types/ace-snippets.d.ts\" />\n/// <reference path=\"./ace-modes.d.ts\" />\ndeclare module \"ace-code\" {\n    export namespace Ace {\n        type Anchor = import(\"ace-code/src/anchor\").Anchor;\n        type Editor = import(\"ace-code/src/editor\").Editor;\n        type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n        type Document = import(\"ace-code/src/document\").Document;\n        type Fold = import(\"ace-code/src/edit_session/fold\").Fold;\n        type FoldLine = import(\"ace-code/src/edit_session/fold_line\").FoldLine;\n        type Range = import(\"ace-code/src/range\").Range;\n        type VirtualRenderer = import(\"ace-code/src/virtual_renderer\").VirtualRenderer;\n        type UndoManager = import(\"ace-code/src/undomanager\").UndoManager;\n        type Tokenizer = import(\"ace-code/src/tokenizer\").Tokenizer;\n        type TokenIterator = import(\"ace-code/src/token_iterator\").TokenIterator;\n        type Selection = import(\"ace-code/src/selection\").Selection;\n        type Autocomplete = import(\"ace-code/src/autocomplete\").Autocomplete;\n        type InlineAutocomplete = import(\"ace-code/src/ext/inline_autocomplete\").InlineAutocomplete;\n        type CompletionProvider = import(\"ace-code/src/autocomplete\").CompletionProvider;\n        type AcePopup = import(\"ace-code/src/autocomplete/popup\").AcePopup;\n        type AceInline = import(\"ace-code/src/autocomplete/inline\").AceInline;\n        type MouseEvent = import(\"ace-code/src/mouse/mouse_event\").MouseEvent;\n        type RangeList = import(\"ace-code/src/range_list\").RangeList;\n        type FilteredList = import(\"ace-code/src/autocomplete\").FilteredList;\n        type LineWidgets = import(\"ace-code/src/line_widgets\").LineWidgets;\n        type SearchBox = import(\"ace-code/src/ext/searchbox\").SearchBox;\n        type Occur = import(\"ace-code/src/occur\").Occur;\n        type DefaultHandlers = import(\"ace-code/src/mouse/default_handlers\").DefaultHandlers;\n        type GutterHandler = import(\"ace-code/src/mouse/default_gutter_handler\").GutterHandler;\n        type DragdropHandler = import(\"ace-code/src/mouse/dragdrop_handler\").DragdropHandler;\n        type AppConfig = import(\"ace-code/src/lib/app_config\").AppConfig;\n        type Config = typeof import(\"ace-code/src/config\");\n        type GutterTooltip = import(\"ace-code/src/mouse/default_gutter_handler\").GutterTooltip;\n        type GutterKeyboardEvent = import(\"ace-code/src/keyboard/gutter_handler\").GutterKeyboardEvent;\n        type HoverTooltip = import(\"ace-code/src/tooltip\").HoverTooltip;\n        type Tooltip = import(\"ace-code/src/tooltip\").Tooltip;\n        type TextInput = import(\"ace-code/src/keyboard/textinput\").TextInput;\n        type DiffChunk = import(\"ace-code/src/ext/diff/base_diff_view\").DiffChunk;\n        type AfterLoadCallback = (err: Error | null, module: unknown) => void;\n        type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;\n        export interface ConfigOptions {\n            packaged: boolean;\n            workerPath: string | null;\n            modePath: string | null;\n            themePath: string | null;\n            basePath: string;\n            suffix: string;\n            loadWorkerFromBlob: boolean;\n            sharedPopups: boolean;\n            useStrictCSP: boolean | null;\n        }\n        interface Theme {\n            cssClass?: string;\n            cssText?: string;\n            padding?: number | string;\n            isDark?: boolean;\n        }\n        interface ScrollBar {\n            setVisible(visible: boolean): void;\n            [key: string]: any;\n        }\n        interface HScrollbar extends ScrollBar {\n            setWidth(width: number): void;\n        }\n        interface VScrollbar extends ScrollBar {\n            setHeight(width: number): void;\n        }\n        interface LayerConfig {\n            width: number;\n            padding: number;\n            firstRow: number;\n            firstRowScreen: number;\n            lastRow: number;\n            lineHeight: number;\n            characterWidth: number;\n            minHeight: number;\n            maxHeight: number;\n            offset: number;\n            height: number;\n            gutterOffset: number;\n        }\n        interface HardWrapOptions {\n            /** First row of the range to process */\n            startRow: number;\n            /** Last row of the range to process */\n            endRow: number;\n            /** Whether to merge short adjacent lines that fit within the limit */\n            allowMerge?: boolean;\n            /** Maximum column width for line wrapping (defaults to editor's print margin) */\n            column?: number;\n        }\n        interface CommandBarOptions {\n            maxElementsOnTooltip: number;\n            alwaysShow: boolean;\n            showDelay: number;\n            hideDelay: number;\n        }\n        interface ScreenCoordinates {\n            row: number;\n            column: number;\n            side?: 1 | -1;\n            offsetX?: number;\n        }\n        interface Folding {\n            /**\n             * Looks up a fold at a given row/column. Possible values for side:\n             *   -1: ignore a fold if fold.start = row/column\n             *   +1: ignore a fold if fold.end = row/column\n             **/\n            getFoldAt(row: number, column: number, side?: number): Ace.Fold;\n            /**\n             * Returns all folds in the given range. Note, that this will return folds\n             **/\n            getFoldsInRange(range: Ace.Range | Ace.Delta): Ace.Fold[];\n            getFoldsInRangeList(ranges: Ace.Range[] | Ace.Range): Ace.Fold[];\n            /**\n             * Returns all folds in the document\n             */\n            getAllFolds(): Ace.Fold[];\n            /**\n             * Returns the string between folds at the given position.\n             * E.g.\n             *  foo<fold>b|ar<fold>wolrd -> \"bar\"\n             *  foo<fold>bar<fold>wol|rd -> \"world\"\n             *  foo<fold>bar<fo|ld>wolrd -> <null>\n             *\n             * where | means the position of row/column\n             *\n             * The trim option determs if the return string should be trimed according\n             * to the \"side\" passed with the trim value:\n             *\n             * E.g.\n             *  foo<fold>b|ar<fold>wolrd -trim=-1> \"b\"\n             *  foo<fold>bar<fold>wol|rd -trim=+1> \"rld\"\n             *  fo|o<fold>bar<fold>wolrd -trim=00> \"foo\"\n             */\n            getFoldStringAt(row: number, column: number, trim?: number, foldLine?: Ace.FoldLine): string | null;\n            getFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine;\n            /**\n             * Returns the fold which starts after or contains docRow\n             */\n            getNextFoldLine(docRow: number, startFoldLine?: Ace.FoldLine): null | Ace.FoldLine;\n            getFoldedRowCount(first: number, last: number): number;\n            /**\n             * Adds a new fold.\n             *      The new created Fold object or an existing fold object in case the\n             *      passed in range fits an existing fold exactly.\n             */\n            addFold(placeholder: Ace.Fold | string, range?: Ace.Range): Ace.Fold;\n            addFolds(folds: Ace.Fold[]): void;\n            removeFold(fold: Ace.Fold): void;\n            removeFolds(folds: Ace.Fold[]): void;\n            expandFold(fold: Ace.Fold): void;\n            expandFolds(folds: Ace.Fold[]): void;\n            unfold(location?: number | null | Ace.Point | Ace.Range | Ace.Range[], expandInner?: boolean): Ace.Fold[] | undefined;\n            /**\n             * Checks if a given documentRow is folded. This is true if there are some\n             * folded parts such that some parts of the line is still visible.\n             **/\n            isRowFolded(docRow: number, startFoldRow?: Ace.FoldLine): boolean;\n            getRowFoldEnd(docRow: number, startFoldRow?: Ace.FoldLine): number;\n            getRowFoldStart(docRow: number, startFoldRow?: Ace.FoldLine): number;\n            getFoldDisplayLine(foldLine: Ace.FoldLine, endRow?: number | null, endColumn?: number | null, startRow?: number | null, startColumn?: number | null): string;\n            getDisplayLine(row: number, endColumn: number | null, startRow: number | null, startColumn: number | null): string;\n            toggleFold(tryToUnfold?: boolean): void;\n            getCommentFoldRange(row: number, column: number, dir?: number): Ace.Range | undefined;\n            foldAll(startRow?: number | null, endRow?: number | null, depth?: number | null, test?: Function): void;\n            foldToLevel(level: number): void;\n            foldAllComments(): void;\n            setFoldStyle(style: string): void;\n            foldWidgets: any[];\n            getFoldWidget: any;\n            getFoldWidgetRange: any;\n            getParentFoldRangeData(row: number, ignoreCurrent?: boolean): {\n                range?: Ace.Range;\n                firstRange?: Ace.Range;\n            };\n            onFoldWidgetClick(row: number, e: any): void;\n            toggleFoldWidget(toggleParent?: boolean): void;\n            updateFoldWidgets(delta: Ace.Delta): void;\n            tokenizerUpdateFoldWidgets(e: any): void;\n        }\n        interface BracketMatch {\n            findMatchingBracket: (position: Point, chr?: string) => Point;\n            getBracketRange: (pos: Point) => null | Range;\n            /**\n             * Returns:\n             * * null if there is no any bracket at `pos`;\n             * * two Ranges if there is opening and closing brackets;\n             * * one Range if there is only one bracket\n             */\n            getMatchingBracketRanges: (pos: Point, isBackwards?: boolean) => null | Range[];\n            /**\n             * Returns [[Range]]'s for matching tags and tag names, if there are any\n             */\n            getMatchingTags: (pos: Point) => {\n                closeTag: Range;\n                closeTagName: Range;\n                openTag: Range;\n                openTagName: Range;\n            };\n        }\n        interface IRange {\n            start: Point;\n            end: Point;\n        }\n        interface LineWidget {\n            editor?: Editor;\n            el?: HTMLElement;\n            rowCount?: number;\n            hidden?: boolean;\n            column?: number;\n            row: number;\n            session?: EditSession;\n            html?: string;\n            text?: string;\n            className?: string;\n            coverGutter?: boolean;\n            pixelHeight?: number;\n            type?: any;\n            destroy?: () => void;\n            coverLine?: boolean;\n            fixedWidth?: boolean;\n            fullWidth?: boolean;\n            screenWidth?: number;\n            rowsAbove?: number;\n            lenses?: CodeLenseCommand[];\n        }\n        type NewLineMode = \"auto\" | \"unix\" | \"windows\";\n        interface EditSessionOptions {\n            wrap: \"off\" | \"free\" | \"printmargin\" | boolean | number;\n            wrapMethod: \"code\" | \"text\" | \"auto\";\n            indentedSoftWrap: boolean;\n            firstLineNumber: number;\n            useWorker: boolean;\n            useSoftTabs: boolean;\n            tabSize: number;\n            navigateWithinSoftTabs: boolean;\n            foldStyle: \"markbegin\" | \"markbeginend\" | \"manual\";\n            overwrite: boolean;\n            newLineMode: NewLineMode;\n            mode: SyntaxMode | string;\n        }\n        interface VirtualRendererOptions {\n            animatedScroll: boolean;\n            showInvisibles: boolean;\n            showPrintMargin: boolean;\n            printMarginColumn: number;\n            printMargin: boolean | number;\n            showGutter: boolean;\n            fadeFoldWidgets: boolean;\n            showFoldWidgets: boolean;\n            showLineNumbers: boolean;\n            displayIndentGuides: boolean;\n            highlightIndentGuides: boolean;\n            highlightGutterLine: boolean;\n            hScrollBarAlwaysVisible: boolean;\n            vScrollBarAlwaysVisible: boolean;\n            fontSize: string | number;\n            fontFamily: string;\n            maxLines: number;\n            minLines: number;\n            scrollPastEnd: number;\n            fixedWidthGutter: boolean;\n            customScrollbar: boolean;\n            theme: string;\n            hasCssTransforms: boolean;\n            maxPixelHeight: number;\n            useSvgGutterIcons: boolean;\n            showFoldedAnnotations: boolean;\n            useResizeObserver: boolean;\n        }\n        interface MouseHandlerOptions {\n            scrollSpeed: number;\n            dragDelay: number;\n            dragEnabled: boolean;\n            focusTimeout: number;\n        }\n        interface EditorOptions extends EditSessionOptions, MouseHandlerOptions, VirtualRendererOptions {\n            selectionStyle: \"fullLine\" | \"screenLine\" | \"text\" | \"line\";\n            highlightActiveLine: boolean;\n            highlightSelectedWord: boolean;\n            readOnly: boolean;\n            copyWithEmptySelection: boolean;\n            cursorStyle: \"ace\" | \"slim\" | \"smooth\" | \"wide\";\n            mergeUndoDeltas: true | false | \"always\";\n            behavioursEnabled: boolean;\n            wrapBehavioursEnabled: boolean;\n            enableAutoIndent: boolean;\n            enableBasicAutocompletion: boolean | Completer[];\n            enableLiveAutocompletion: boolean | Completer[];\n            liveAutocompletionDelay: number;\n            liveAutocompletionThreshold: number;\n            enableSnippets: boolean;\n            autoScrollEditorIntoView: boolean;\n            keyboardHandler: string | null;\n            placeholder: string;\n            value: string;\n            session: EditSession;\n            relativeLineNumbers: boolean;\n            enableMultiselect: boolean;\n            enableKeyboardAccessibility: boolean;\n            enableCodeLens: boolean;\n            textInputAriaLabel: string;\n            enableMobileMenu: boolean;\n        }\n        interface EventsBase {\n            [key: string]: any;\n        }\n        interface EditSessionEvents {\n            /**\n             * Emitted when the document changes.\n             */\n            \"change\": (delta: Delta, emitter: EditSession) => void;\n            /**\n             * Emitted when the tab size changes, via [[EditSession.setTabSize]].\n             */\n            \"changeTabSize\": (e: undefined, emitter: EditSession) => void;\n            /**\n             * Emitted when the ability to overwrite text changes, via [[EditSession.setOverwrite]].\n             */\n            \"changeOverwrite\": (overwrite: boolean, emitter: EditSession) => void;\n            /**\n             * Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.\n             */\n            \"changeBreakpoint\": (e: {\n                row?: number;\n                breakpoint?: boolean;\n            }, emitter: EditSession) => void;\n            /**\n             * Emitted when a front marker changes.\n             */\n            \"changeFrontMarker\": (e: undefined, emitter: EditSession) => void;\n            /**\n             * Emitted when a back marker changes.\n             */\n            \"changeBackMarker\": (e: undefined, emitter: EditSession) => void;\n            /**\n             * Emitted when an annotation changes, like through [[EditSession.setAnnotations]].\n             */\n            \"changeAnnotation\": (e: {}, emitter: EditSession) => void;\n            /**\n             * Emitted when a background tokenizer asynchronously processes new rows.\n             */\n            \"tokenizerUpdate\": (e: {\n                data: {\n                    first: number;\n                    last: number;\n                };\n            }, emitter: EditSession) => void;\n            /**\n             * Emitted when the current mode changes.\n             */\n            \"changeMode\": (e: any, emitter: EditSession) => void;\n            /**\n             * Emitted when the wrap mode changes.\n             */\n            \"changeWrapMode\": (e: any, emitter: EditSession) => void;\n            /**\n             * Emitted when the wrapping limit changes.\n             */\n            \"changeWrapLimit\": (e: any, emitter: EditSession) => void;\n            /**\n             * Emitted when a code fold is added or removed.\n             */\n            \"changeFold\": (e: any, emitter: EditSession) => void;\n            /**\n             * Emitted when the scroll top changes.\n             * @param scrollTop The new scroll top value\n             **/\n            \"changeScrollTop\": (scrollTop: number, emitter: EditSession) => void;\n            /**\n             * Emitted when the scroll left changes.\n             * @param scrollLeft The new scroll left value\n             **/\n            \"changeScrollLeft\": (scrollLeft: number, emitter: EditSession) => void;\n            \"changeEditor\": (e: {\n                editor?: Editor;\n                oldEditor?: Editor;\n            }, emitter: EditSession) => void;\n            \"changeSelection\": (e: undefined, emitter: EditSession) => void;\n            \"startOperation\": (op: {\n                command?: {\n                    name?: string;\n                };\n                args?: any;\n            }, emitter: EditSession) => void;\n            \"endOperation\": (op: any, emitter: EditSession) => void;\n            \"beforeEndOperation\": (e: undefined, emitter: EditSession) => void;\n        }\n        interface EditorEvents {\n            \"change\": (delta: Delta, emitter: Editor) => void;\n            \"changeSelection\": (e: undefined, emitter: Editor) => void;\n            \"input\": (e: undefined, emitter: Editor) => void;\n            /**\n             * Emitted whenever the [[EditSession]] changes.\n             * @param e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.\n             **/\n            \"changeSession\": (e: {\n                oldSession: EditSession;\n                session: EditSession;\n            }, emitter: Editor) => void;\n            \"blur\": (e: any, emitter: Editor) => void;\n            \"mousedown\": (e: MouseEvent, emitter: Editor) => void;\n            \"mousemove\": (e: MouseEvent & {\n                scrollTop?: any;\n            }, emitter: Editor) => void;\n            \"changeStatus\": (e: any, emitter: Editor) => void;\n            \"keyboardActivity\": (e: any, emitter: Editor) => void;\n            \"mousewheel\": (e: MouseEvent, emitter: Editor) => void;\n            \"mouseup\": (e: MouseEvent, emitter: Editor) => void;\n            \"beforeEndOperation\": (e: any, emitter: Editor) => void;\n            \"nativecontextmenu\": (e: any, emitter: Editor) => void;\n            \"destroy\": (e: any, emitter: Editor) => void;\n            \"focus\": (e: any, emitter: Editor) => void;\n            /**\n             * Emitted when text is copied.\n             * @param text The copied text\n             **/\n            \"copy\": (e: {\n                text: string;\n            }, emitter: Editor) => void;\n            /**\n             * Emitted when text is pasted.\n             **/\n            \"paste\": (e: {\n                text: string;\n                event?: ClipboardEvent;\n            }, emitter: Editor) => void;\n            /**\n             * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].\n             * @param data Contains one property, `data`, which indicates the new selection style\n             **/\n            \"changeSelectionStyle\": (data: \"fullLine\" | \"screenLine\" | \"text\" | \"line\", emitter: Editor) => void;\n            \"changeMode\": (e: {\n                mode?: Ace.SyntaxMode;\n                oldMode?: Ace.SyntaxMode;\n            }, emitter: Editor) => void;\n            //from searchbox extension\n            \"findSearchBox\": (e: {\n                match: boolean;\n            }, emitter: Editor) => void;\n            //from code_lens extension\n            \"codeLensClick\": (e: any, emitter: Editor) => void;\n            \"select\": (e: undefined, emitter: Editor) => void;\n            \"gutterkeydown\": (e: GutterKeyboardEvent, emitter: Editor) => void;\n            \"gutterclick\": (e: MouseEvent, emitter: Editor) => void;\n            \"showGutterTooltip\": (e: GutterTooltip, emitter: Editor) => void;\n            \"hideGutterTooltip\": (e: GutterTooltip, emitter: Editor) => void;\n            \"compositionStart\": (e: undefined, emitter: Editor) => void;\n        }\n        interface AcePopupEvents {\n            \"click\": (e: MouseEvent, emitter: AcePopup) => void;\n            \"dblclick\": (e: MouseEvent, emitter: AcePopup) => void;\n            \"tripleclick\": (e: MouseEvent, emitter: AcePopup) => void;\n            \"quadclick\": (e: MouseEvent, emitter: AcePopup) => void;\n            \"show\": (e: undefined, emitter: AcePopup) => void;\n            \"hide\": (e: undefined, emitter: AcePopup) => void;\n            \"select\": (hide: boolean, emitter: AcePopup) => void;\n            \"changeHoverMarker\": (e: any, emitter: AcePopup) => void;\n        }\n        interface DocumentEvents {\n            /**\n             * Fires whenever the document changes.\n             * Several methods trigger different `\"change\"` events. Below is a list of each action type, followed by each property that's also available:\n             *  * `\"insert\"`\n             *    * `range`: the [[Range]] of the change within the document\n             *    * `lines`: the lines being added\n             *  * `\"remove\"`\n             *    * `range`: the [[Range]] of the change within the document\n             *    * `lines`: the lines being removed\n             *\n             **/\n            \"change\": (e: Delta, emitter: Document) => void;\n            \"changeNewLineMode\": (e: undefined, emitter: Document) => void;\n        }\n        interface AnchorEvents {\n            /**\n             * Fires whenever the anchor position changes.\n             * Both of these objects have a `row` and `column` property corresponding to the position.\n             * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]].\n             * @param {Object} e  An object containing information about the anchor position. It has two properties:\n             *  - `old`: An object describing the old Anchor position\n             *  - `value`: An object describing the new Anchor position\n             **/\n            \"change\": (e: {\n                old: Point;\n                value: Point;\n            }, emitter: Anchor) => void;\n        }\n        interface BackgroundTokenizerEvents {\n            /**\n             * Fires whenever the background tokeniziers between a range of rows are going to be updated.\n             * @param e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated.\n             **/\n            \"update\": (e: {\n                data: {\n                    first: number;\n                    last: number;\n                };\n            }, emitter: import(\"ace-code/src/background_tokenizer\").BackgroundTokenizer) => void;\n        }\n        interface SelectionEvents {\n            /**\n             * Emitted when the cursor position changes.\n             **/\n            \"changeCursor\": (e: undefined, emitter: Selection) => void;\n            /**\n             * Emitted when the cursor selection changes.\n             **/\n            \"changeSelection\": (e: undefined, emitter: Selection) => void;\n        }\n        interface MultiSelectionEvents extends SelectionEvents {\n            \"multiSelect\": (e: undefined, emitter: Selection) => void;\n            \"addRange\": (e: {\n                range: Range;\n            }, emitter: Selection) => void;\n            \"removeRange\": (e: {\n                ranges: Range[];\n            }, emitter: Selection) => void;\n            \"singleSelect\": (e: undefined, emitter: Selection) => void;\n        }\n        interface PlaceHolderEvents {\n            \"cursorEnter\": (e: any, emitter: import(\"ace-code/src/placeholder\").PlaceHolder) => void;\n            \"cursorLeave\": (e: any, emitter: import(\"ace-code/src/placeholder\").PlaceHolder) => void;\n        }\n        interface GutterEvents {\n            \"changeGutterWidth\": (width: number, emitter: import(\"ace-code/src/layer/gutter\").Gutter) => void;\n            \"afterRender\": (e: undefined, emitter: import(\"ace-code/src/layer/gutter\").Gutter) => void;\n        }\n        interface TextEvents {\n            \"changeCharacterSize\": (e: any, emitter: import(\"ace-code/src/layer/text\").Text) => void;\n        }\n        interface VirtualRendererEvents {\n            \"afterRender\": (e: any, emitter: VirtualRenderer) => void;\n            \"beforeRender\": (e: any, emitter: VirtualRenderer) => void;\n            \"themeLoaded\": (e: {\n                theme: string | Theme;\n            }, emitter: VirtualRenderer) => void;\n            \"themeChange\": (e: {\n                theme: string | Theme;\n            }, emitter: VirtualRenderer) => void;\n            \"scrollbarVisibilityChanged\": (e: undefined, emitter: VirtualRenderer) => void;\n            \"changeCharacterSize\": (e: any, emitter: VirtualRenderer) => void;\n            \"resize\": (e: any, emitter: VirtualRenderer) => void;\n            \"autosize\": (e: undefined, emitter: VirtualRenderer) => void;\n        }\n        type EmitParameters<T extends (...args: any[]) => any> = T extends (first: infer First, ...rest: any[]) => any ? [\n            First\n        ] : [\n            ];\n        export class EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> {\n            once<K extends keyof T>(name: K, callback: T[K]): void;\n            setDefaultHandler(name: string, callback: Function): void;\n            removeDefaultHandler(name: string, callback: Function): void;\n            on<K extends keyof T>(name: K, callback: T[K], capturing?: boolean): T[K];\n            addEventListener<K extends keyof T>(name: K, callback: T[K], capturing?: boolean): T[K];\n            off<K extends keyof T>(name: K, callback: T[K]): void;\n            removeListener<K extends keyof T>(name: K, callback: T[K]): void;\n            removeEventListener<K extends keyof T>(name: K, callback: T[K]): void;\n            removeAllListeners(name?: string): void;\n        }\n        interface SearchOptions {\n            /**The string or regular expression you're looking for*/\n            needle: string | RegExp;\n            preventScroll: boolean;\n            /**Whether to search backwards from where cursor currently is*/\n            backwards: boolean;\n            /**The starting [[Range]] or cursor position to begin the search*/\n            start: Range;\n            /**Whether or not to include the current line in the search*/\n            skipCurrent: boolean;\n            /**The [[Range]] to search within. Set this to `null` for the whole document*/\n            range: Range | null;\n            preserveCase: boolean;\n            /**Whether the search is a regular expression or not*/\n            regExp: boolean;\n            /**Whether the search matches only on whole words*/\n            wholeWord: boolean;\n            /**Whether the search ought to be case-sensitive*/\n            caseSensitive: boolean;\n            /**Whether to wrap the search back to the beginning when it hits the end*/\n            wrap: boolean;\n            re: any;\n        }\n        interface Point {\n            row: number;\n            column: number;\n        }\n        type Position = Point;\n        interface Delta {\n            action: \"insert\" | \"remove\";\n            start: Point;\n            end: Point;\n            lines: string[];\n            id?: number;\n            folds?: Fold[];\n        }\n        interface Annotation {\n            row: number;\n            column: number;\n            text: string;\n            type: string;\n        }\n        export interface MarkerGroupItem {\n            range: Range;\n            className: string;\n        }\n        type MarkerGroup = import(\"ace-code/src/marker_group\").MarkerGroup;\n        export interface Command {\n            name?: string;\n            bindKey?: string | {\n                mac?: string;\n                win?: string;\n            };\n            readOnly?: boolean;\n            exec?: (editor?: Editor | any, args?: any) => void;\n            isAvailable?: (editor: Editor) => boolean;\n            description?: string;\n            multiSelectAction?: \"forEach\" | \"forEachLine\" | Function;\n            scrollIntoView?: true | \"cursor\" | \"center\" | \"selectionPart\" | \"animate\" | \"selection\" | \"none\";\n            aceCommandGroup?: string;\n            passEvent?: boolean;\n            level?: number;\n            action?: string;\n        }\n        type CommandLike = Command | ((editor: Editor) => void) | ((sb: SearchBox) => void);\n        type KeyboardHandler = Partial<import(\"ace-code/src/keyboard/hash_handler\").HashHandler> & {\n            attach?: (editor: Editor) => void;\n            detach?: (editor: Editor) => void;\n            getStatusText?: (editor?: any, data?: any) => string;\n        };\n        export interface MarkerLike {\n            range?: Range;\n            type: string;\n            renderer?: MarkerRenderer;\n            clazz: string;\n            inFront?: boolean;\n            id?: number;\n            update?: (html: string[],\n                // TODO maybe define Marker class\n                marker: any, session: EditSession, config: any) => void;\n            [key: string]: any;\n        }\n        type MarkerRenderer = (html: string[], range: Range, left: number, top: number, config: any) => void;\n        interface Token {\n            type: string;\n            value: string;\n            index?: number;\n            start?: number;\n        }\n        type BaseCompletion = import(\"ace-code/src/autocomplete\").BaseCompletion;\n        type SnippetCompletion = import(\"ace-code/src/autocomplete\").SnippetCompletion;\n        type ValueCompletion = import(\"ace-code/src/autocomplete\").ValueCompletion;\n        type Completion = import(\"ace-code/src/autocomplete\").Completion;\n        type HighlightRule = ({\n            defaultToken: string;\n        } | {\n            include: string;\n        } | {\n            todo: string;\n        } | {\n            token: string | string[] | ((value: string) => string);\n            regex: string | RegExp;\n            next?: string | (() => void);\n            push?: string;\n            comment?: string;\n            caseInsensitive?: boolean;\n            nextState?: string;\n        }) & {\n            [key: string]: any;\n        };\n        type HighlightRulesMap = Record<string, HighlightRule[]>;\n        type KeywordMapper = (keyword: string) => string;\n        interface HighlightRules {\n            addRules(rules: HighlightRulesMap, prefix?: string): void;\n            getRules(): HighlightRulesMap;\n            embedRules(rules: (new () => HighlightRules) | HighlightRulesMap, prefix: string, escapeRules?: boolean, append?: boolean): void;\n            getEmbeds(): string[];\n            normalizeRules(): void;\n            createKeywordMapper(map: Record<string, string>, defaultToken?: string, ignoreCase?: boolean, splitChar?: string): KeywordMapper;\n        }\n        type FoldWidget = \"start\" | \"end\" | \"\";\n        interface FoldMode {\n            foldingStartMarker: RegExp;\n            foldingStopMarker?: RegExp;\n            getFoldWidget(session: EditSession, foldStyle: string, row: number): FoldWidget;\n            getFoldWidgetRange(session: EditSession, foldStyle: string, row: number): Range | undefined;\n            indentationBlock(session: EditSession, row: number, column?: number): Range | undefined;\n            openingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined;\n            closingBracketBlock(session: EditSession, bracket: string, row: number, column: number, typeRe?: RegExp): Range | undefined;\n        }\n        type BehaviorAction = (state: string | string[], action: string, editor: Editor, session: EditSession, text: string | Range) => ({\n            text: string;\n            selection: number[];\n        } | Range) & {\n            [key: string]: any;\n        } | undefined;\n        type BehaviorMap = Record<string, Record<string, BehaviorAction>>;\n        interface Behaviour {\n            add(name: string, action: string, callback: BehaviorAction): void;\n            addBehaviours(behaviours: BehaviorMap): void;\n            remove(name: string): void;\n            inherit(mode: SyntaxMode | (new () => SyntaxMode), filter: string[]): void;\n            getBehaviours(filter?: string[]): BehaviorMap;\n        }\n        interface Outdent {\n            checkOutdent(line: string, input: string): boolean;\n            autoOutdent(doc: Document, row: number): number | undefined;\n        }\n        interface SyntaxMode {\n            HighlightRules: {\n                new(config?: any): HighlightRules;\n            }; //TODO: fix this\n            foldingRules?: FoldMode;\n            /**\n             * characters that indicate the start of a line comment\n             */\n            lineCommentStart?: string;\n            /**\n             * characters that indicate the start and end of a block comment\n             */\n            blockComment?: {\n                start: string;\n                end: string;\n            };\n            tokenRe?: RegExp;\n            nonTokenRe?: RegExp;\n            completionKeywords: string[];\n            transformAction: BehaviorAction;\n            path?: string;\n            getTokenizer(): Tokenizer;\n            toggleCommentLines(state: string | string[], session: EditSession, startRow: number, endRow: number): void;\n            toggleBlockComment(state: string | string[], session: EditSession, range: Range, cursor: Point): void;\n            getNextLineIndent(state: string | string[], line: string, tab: string): string;\n            checkOutdent(state: string | string[], line: string, input: string): boolean;\n            autoOutdent(state: string | string[], doc: EditSession, row: number): void;\n            // TODO implement WorkerClient types\n            createWorker(session: EditSession): any;\n            createModeDelegates(mapping: {\n                [key: string]: string;\n            }): void;\n            getKeywords(append?: boolean): Array<string | RegExp>;\n            getCompletions(state: string | string[], session: EditSession, pos: Point, prefix: string): Completion[];\n        }\n        interface OptionsBase {\n            [key: string]: any;\n        }\n        class OptionsProvider<T> {\n            setOptions(optList: Partial<T>): void;\n            getOptions(optionNames?: Array<keyof T> | Partial<T>): Partial<T>;\n            setOption<K extends keyof T>(name: K, value: T[K]): void;\n            getOption<K extends keyof T>(name: K): T[K];\n        }\n        type KeyBinding = import(\"ace-code/src/keyboard/keybinding\").KeyBinding;\n        interface CommandMap {\n            [name: string]: Command;\n        }\n        type execEventHandler = (obj: {\n            editor: Editor;\n            command: Command;\n            args: any[];\n        }, emitter: CommandManager) => void;\n        interface CommandManagerEvents {\n            \"exec\": execEventHandler;\n            \"afterExec\": execEventHandler;\n            \"commandUnavailable\": execEventHandler;\n        }\n        type CommandManager = import(\"ace-code/src/commands/command_manager\").CommandManager;\n        interface SavedSelection {\n            start: Point;\n            end: Point;\n            isBackwards: boolean;\n        }\n        var Selection: {\n            new(session: EditSession): Selection;\n        };\n        type CompleterCallback = (error: any, completions: Completion[]) => void;\n        interface Completer {\n            /** Regular expressions defining valid identifier characters for completion triggers */\n            identifierRegexps?: Array<RegExp>;\n            /** Main completion method that provides suggestions for the given context */\n            getCompletions(editor: Editor, session: EditSession, position: Point, prefix: string, callback: CompleterCallback): void;\n            /** Returns documentation tooltip for a completion item */\n            getDocTooltip?(item: Completion): void | string | Completion;\n            /** Called when a completion item becomes visible */\n            onSeen?: (editor: Ace.Editor, completion: Completion) => void;\n            /** Called when a completion item is inserted */\n            onInsert?: (editor: Ace.Editor, completion: Completion) => void;\n            /** Cleanup method called when completion is cancelled */\n            cancel?(): void;\n            /** Unique identifier for this completer */\n            id?: string;\n            /** Characters that trigger autocompletion when typed */\n            triggerCharacters?: string[];\n            /** Whether to hide inline preview text */\n            hideInlinePreview?: boolean;\n            /** Custom insertion handler for completion items */\n            insertMatch?: (editor: Editor, data: Completion) => void;\n        }\n        interface CompletionOptions {\n            matches?: Completion[];\n        }\n        type CompletionProviderOptions = {\n            exactMatch?: boolean;\n            ignoreCaption?: boolean;\n        };\n        type GatherCompletionRecord = {\n            prefix: string;\n            matches: Completion[];\n            finished: boolean;\n        };\n        type CompletionCallbackFunction = (err: Error | undefined, data: GatherCompletionRecord) => void;\n        type CompletionProviderCallback = (this: import(\"ace-code/src/autocomplete\").Autocomplete, err: Error | undefined, completions: import(\"ace-code/src/autocomplete\").FilteredList, finished: boolean) => void;\n        type AcePopupNavigation = \"up\" | \"down\" | \"start\" | \"end\";\n        interface EditorMultiSelectProperties {\n            inMultiSelectMode?: boolean;\n            /**\n             * Updates the cursor and marker layers.\n             **/\n            updateSelectionMarkers: () => void;\n            /**\n             * Adds the selection and cursor.\n             * @param orientedRange A range containing a cursor\n             **/\n            addSelectionMarker: (orientedRange: Ace.Range & {\n                marker?: any;\n            }) => Ace.Range & {\n                marker?: any;\n            };\n            /**\n             * Removes the selection marker.\n             * @param range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].\n             **/\n            removeSelectionMarker: (range: Ace.Range & {\n                marker?: any;\n            }) => void;\n            removeSelectionMarkers: (ranges: (Ace.Range & {\n                marker?: any;\n            })[]) => void;\n            /**\n             * Executes a command for each selection range.\n             * @param cmd The command to execute\n             * @param [args] Any arguments for the command\n             **/\n            forEachSelection: (cmd: Object, args?: string, options?: Object) => void;\n            /**\n             * Removes all the selections except the last added one.\n             **/\n            exitMultiSelectMode: () => void;\n            getSelectedText: () => string;\n            /**\n             * Finds and selects all the occurrences of `needle`.\n             * @param needle The text to find\n             * @param options The search options\n             * @param additive keeps\n             * @returns {Number} The cumulative count of all found matches\n             **/\n            findAll: (needle?: string, options?: Partial<Ace.SearchOptions>, additive?: boolean) => number;\n            /**\n             * Adds a cursor above or below the active cursor.\n             * @param dir The direction of lines to select: -1 for up, 1 for down\n             * @param [skip] If `true`, removes the active selection range\n             */\n            selectMoreLines: (dir: number, skip?: boolean) => void;\n            /**\n             * Transposes the selected ranges.\n             * @param {Number} dir The direction to rotate selections\n             **/\n            transposeSelections: (dir: number) => void;\n            /**\n             * Finds the next occurrence of text in an active selection and adds it to the selections.\n             * @param {Number} dir The direction of lines to select: -1 for up, 1 for down\n             * @param {Boolean} [skip] If `true`, removes the active selection range\n             **/\n            selectMore: (dir: number, skip?: boolean, stopAtFirst?: boolean) => void;\n            /**\n             * Aligns the cursors or selected text.\n             **/\n            alignCursors: () => void;\n            multiSelect?: any;\n        }\n        /**\n         * Provider interface for code lens functionality\n         */\n        interface CodeLenseProvider {\n            /**\n             * Compute code lenses for the given edit session\n             * @param session The edit session to provide code lenses for\n             * @param callback Callback function that receives errors and code lenses\n             */\n            provideCodeLenses: (session: EditSession, callback: (err: any, payload: CodeLense[]) => void) => void;\n        }\n        /**\n         * Represents a command associated with a code lens\n         */\n        interface CodeLenseCommand {\n            /**\n             * Command identifier that will be executed\n             */\n            id?: string;\n            /**\n             * Display title for the code lens\n             */\n            title: string;\n            /**\n             * Argument(s) to pass to the command when executed\n             */\n            arguments?: any;\n        }\n        /**\n         * Represents a code lens - an actionable UI element displayed above a code line\n         */\n        interface CodeLense {\n            /**\n             * Starting position where the code lens should be displayed\n             */\n            start: Point;\n            /**\n             * Command to execute when the code lens is activated\n             */\n            command?: CodeLenseCommand;\n        }\n        interface CodeLenseEditorExtension {\n            codeLensProviders?: CodeLenseProvider[];\n        }\n        interface ElasticTabstopsEditorExtension {\n            elasticTabstops?: import(\"ace-code/src/ext/elastic_tabstops_lite\").ElasticTabstopsLite;\n        }\n        interface TextareaEditorExtension {\n            setDisplaySettings?: (settings: any) => void;\n        }\n        interface PromptEditorExtension {\n            cmdLine?: Editor;\n        }\n        interface OptionsEditorExtension {\n        }\n        interface MultiSelectProperties {\n            ranges: Ace.Range[] | null;\n            rangeList: Ace.RangeList | null;\n            /**\n             * Adds a range to a selection by entering multiselect mode, if necessary.\n             * @param {Ace.Range} range The new range to add\n             * @param {Boolean} [$blockChangeEvents] Whether or not to block changing events\n             **/\n            addRange(range: Ace.Range, $blockChangeEvents?: boolean): any;\n            inMultiSelectMode: boolean;\n            toSingleRange(range?: Ace.Range): void;\n            /**\n             * Removes a Range containing pos (if it exists).\n             * @param {Ace.Point} pos The position to remove, as a `{row, column}` object\n             **/\n            substractPoint(pos: Ace.Point): any;\n            /**\n             * Merges overlapping ranges ensuring consistency after changes\n             **/\n            mergeOverlappingRanges(): void;\n            rangeCount: number;\n            /**\n             * Returns a concatenation of all the ranges.\n             **/\n            getAllRanges(): Ace.Range[];\n            /**\n             * Splits all the ranges into lines.\n             **/\n            splitIntoLines(): void;\n            joinSelections(): void;\n            toggleBlockSelection(): void;\n            /**\n             *\n             * Gets list of ranges composing rectangular block on the screen\n             *\n             * @param {Ace.ScreenCoordinates} screenCursor The cursor to use\n             * @param {Ace.ScreenCoordinates} screenAnchor The anchor to use\n             * @param {Boolean} [includeEmptyLines] If true, this includes ranges inside the block which are empty due to clipping\n             **/\n            rectangularRangeBlock(screenCursor: Ace.ScreenCoordinates, screenAnchor: Ace.ScreenCoordinates, includeEmptyLines?: boolean): Ace.Range[];\n            index?: number;\n        }\n        type AcePopupEventsCombined = Ace.EditorEvents & Ace.AcePopupEvents;\n        type AcePopupWithEditor = Ace.EventEmitter<AcePopupEventsCombined> & Ace.Editor;\n        type InlineAutocompleteAction = \"prev\" | \"next\" | \"first\" | \"last\";\n        type TooltipCommandFunction<T> = (editor: Ace.Editor) => T;\n        export interface TooltipCommand extends Ace.Command {\n            enabled?: TooltipCommandFunction<boolean> | boolean;\n            getValue?: TooltipCommandFunction<any>;\n            type: \"button\" | \"text\" | \"checkbox\";\n            iconCssClass?: string;\n            cssClass?: string;\n        }\n        export type CommandBarTooltip = import(\"ace-code/src/ext/command_bar\").CommandBarTooltip;\n        export type TokenizeResult = Array<Array<{\n            className?: string;\n            value: string;\n        }>>;\n        export interface StaticHighlightOptions {\n            /** Syntax mode (e.g., 'ace/mode/javascript'). Auto-detected from CSS class if not provided */\n            mode?: string | SyntaxMode;\n            /** Color theme (e.g., 'ace/theme/textmate'). Defaults to 'ace/theme/textmate' */\n            theme?: string | Theme;\n            /** Whether to trim whitespace from code content */\n            trim?: boolean;\n            /** Starting line number for display */\n            firstLineNumber?: number;\n            /** Whether to show line numbers gutter */\n            showGutter?: boolean;\n        }\n        export interface Operation {\n            command: {\n                name?: string;\n            };\n            args: any;\n            selectionBefore?: Range | Range[];\n            selectionAfter?: Range | Range[];\n            docChanged?: boolean;\n            selectionChanged?: boolean;\n        }\n        export interface CommandBarEvents {\n            \"hide\": (e: undefined, emitter: import(\"ace-code/src/ext/command_bar\").CommandBarTooltip) => void;\n            \"show\": (e: undefined, emitter: import(\"ace-code/src/ext/command_bar\").CommandBarTooltip) => void;\n            \"alwaysShow\": (e: boolean, emitter: import(\"ace-code/src/ext/command_bar\").CommandBarTooltip) => void;\n        }\n        export interface FontMetricsEvents {\n            \"changeCharacterSize\": (e: {\n                data: {\n                    height: number;\n                    width: number;\n                };\n            }, emitter: import(\"ace-code/src/layer/font_metrics\").FontMetrics) => void;\n        }\n        export interface OptionPanelEvents {\n            \"setOption\": (e: {\n                name: string;\n                value: any;\n            }, emitter: import(\"ace-code/src/ext/options\").OptionPanel) => void;\n        }\n        export interface ScrollbarEvents {\n            \"scroll\": (e: {\n                data: number;\n            }, emitter: ScrollBar) => void;\n        }\n        export interface TextInputAriaOptions {\n            activeDescendant?: string;\n            role?: string;\n            setLabel?: boolean;\n            inline?: boolean;\n        }\n    }\n    export const config: typeof import(\"ace-code/src/config\");\n    export function edit(el?: string | (HTMLElement & {\n        env?: any;\n        value?: any;\n    }) | null, options?: Partial<import(\"ace-code\").Ace.EditorOptions>): Editor;\n    export function createEditSession(text: import(\"ace-code/src/document\").Document | string, mode?: import(\"ace-code\").Ace.SyntaxMode): EditSession;\n    import { Editor } from \"ace-code/src/editor\";\n    import { EditSession } from \"ace-code/src/edit_session\";\n    import { Range } from \"ace-code/src/range\";\n    import { UndoManager } from \"ace-code/src/undomanager\";\n    import { VirtualRenderer as Renderer } from \"ace-code/src/virtual_renderer\";\n    export var version: \"1.43.6\";\n    export { Range, Editor, EditSession, UndoManager, Renderer as VirtualRenderer };\n}\n"
  },
  {
    "path": "amplify.yml",
    "content": "version: 0.1\nfrontend:\n  phases:\n    preBuild:\n      commands:\n        - npm install\n    # IMPORTANT - Please verify your build commands\n    build:\n      commands: \n        - make build\n  artifacts:\n    # IMPORTANT - Please verify your build output directory\n    baseDirectory: /\n    files:\n      - '**/*'\n  cache:\n    paths:\n      - node_modules/**/*\n"
  },
  {
    "path": "build_support/editor.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n\n    #editor {\n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\">function foo(items) {\n    var i;\n    for (i = 0; i &lt; items.length; i++) {\n        alert(\"Ace Rocks \" + items[i]);\n    }\n}</pre>\n\n<script src=\"src-noconflict/ace.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script>\n    var editor = ace.edit(\"editor\");\n    editor.setTheme(\"ace/theme/twilight\");\n    editor.session.setMode(\"ace/mode/javascript\");\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "build_support/mini_require.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/**\n * Define a module along with a payload\n * @param module a name for the payload\n * @param payload a function to call with (require, exports, module) params\n */\n\n(function() {\n\nvar ACE_NAMESPACE = \"\";\n\nvar global = (function() { return this; })();\nif (!global && typeof window != \"undefined\") global = window; // strict mode\n\n\nif (!ACE_NAMESPACE && typeof requirejs !== \"undefined\")\n    return;\n\n\nvar define = function(module, deps, payload) {\n    if (typeof module !== \"string\") {\n        if (define.original)\n            define.original.apply(this, arguments);\n        else {\n            console.error(\"dropping module because define wasn\\'t a string.\");\n            console.trace();\n        }\n        return;\n    }\n    if (arguments.length == 2)\n        payload = deps;\n    if (!define.modules[module]) {\n        define.payloads[module] = payload;\n        define.modules[module] = null;\n    }\n};\n\ndefine.modules = {};\ndefine.payloads = {};\n\n/**\n * Get at functionality define()ed using the function above\n */\nvar _require = function(parentId, module, callback) {\n    if (typeof module === \"string\") {\n        var payload = lookup(parentId, module);\n        if (payload != undefined) {\n            callback && callback();\n            return payload;\n        }\n    } else if (Object.prototype.toString.call(module) === \"[object Array]\") {\n        var params = [];\n        for (var i = 0, l = module.length; i < l; ++i) {\n            var dep = lookup(parentId, module[i]);\n            if (dep == undefined && require.original)\n                return;\n            params.push(dep);\n        }\n        return callback && callback.apply(null, params) || true;\n    }\n};\n\nvar require = function(module, callback) {\n    var packagedModule = _require(\"\", module, callback);\n    if (packagedModule == undefined && require.original)\n        return require.original.apply(this, arguments);\n    return packagedModule;\n};\n\nvar normalizeModule = function(parentId, moduleName) {\n    // normalize plugin requires\n    if (moduleName.indexOf(\"!\") !== -1) {\n        var chunks = moduleName.split(\"!\");\n        return normalizeModule(parentId, chunks[0]) + \"!\" + normalizeModule(parentId, chunks[1]);\n    }\n    // normalize relative requires\n    if (moduleName.charAt(0) == \".\") {\n        var base = parentId.split(\"/\").slice(0, -1).join(\"/\");\n        moduleName = base + \"/\" + moduleName;\n\n        while(moduleName.indexOf(\".\") !== -1 && previous != moduleName) {\n            var previous = moduleName;\n            moduleName = moduleName.replace(/\\/\\.\\//, \"/\").replace(/[^\\/]+\\/\\.\\.\\//, \"\");\n        }\n    }\n    return moduleName;\n};\n\n/**\n * Internal function to lookup moduleNames and resolve them by calling the\n * definition function if needed.\n */\nvar lookup = function(parentId, moduleName) {\n    moduleName = normalizeModule(parentId, moduleName);\n\n    var module = define.modules[moduleName];\n    if (!module) {\n        module = define.payloads[moduleName];\n        if (typeof module === 'function') {\n            var exports = {};\n            var mod = {\n                id: moduleName,\n                uri: '',\n                exports: exports,\n                packaged: true\n            };\n\n            var req = function(module, callback) {\n                return _require(moduleName, module, callback);\n            };\n\n            var returnValue = module(req, exports, mod);\n            exports = returnValue || mod.exports;\n            define.modules[moduleName] = exports;\n            delete define.payloads[moduleName];\n        }\n        module = define.modules[moduleName] = exports || module;\n    }\n    return module;\n};\n\nfunction exportAce(ns) {\n    var root = global;\n    if (ns) {\n        if (!global[ns])\n            global[ns] = {};\n        root = global[ns];\n    }\n\n    if (!root.define || !root.define.packaged) {\n        define.original = root.define;\n        root.define = define;\n        root.define.packaged = true;\n    }\n\n    if (!root.require || !root.require.packaged) {\n        require.original = root.require;\n        root.require = require;\n        root.require.packaged = true;\n    }\n}\n\nexportAce(ACE_NAMESPACE);\n\n})();\n"
  },
  {
    "path": "demo/autocompletion.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>ACE Autocompletion demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n\n<!-- load ace -->\n<script src=\"../build/src-noconflict/ace.js\"></script>\n<!-- load ace language tools -->\n<script src=\"../build/src-noconflict/ext-language_tools.js\"></script>\n<script>\n    // trigger extension\n    ace.require(\"ace/ext/language_tools\");\n    var editor = ace.edit(\"editor\");\n    editor.session.setMode(\"ace/mode/html\");\n    editor.setTheme(\"ace/theme/tomorrow\");\n    // enable autocompletion and snippets\n    editor.setOptions({\n        enableBasicAutocompletion: true,\n        enableSnippets: true,\n        enableLiveAutocompletion: false\n    });\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/autoresize.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n\n\t.ace_editor {\n\t\tborder: 1px solid lightgray;\n\t\tmargin: auto;\n\t\twidth: 80%;\n\t}\n\t.scrollmargin {\n\t\theight: 80px;\n\t}\n\t.scrollmargin2 {\n\t\theight: 180px;\n\t}\n    </style>\n</head>\n<body>\n<pre id=\"editor1\">autoresizing editor</pre>\n<div class=\"scrollmargin\"></div>\n<pre id=\"editor2\">minHeight = 2 lines</pre>\n<div class=\"scrollmargin\"></div>\n<pre id=\"editor3\" style=\"width: 40%;\"></pre>\n<div class=\"scrollmargin\"></div>\n<pre id=\"editor\"></pre>\n<div class=\"scrollmargin2\"></div>\n<pre id=\"editor4\" style=\"width: 40%;transform:scale(1.5)\"></pre>\n<div class=\"scrollmargin2\"></div>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/language_tools\"], function(ace) {\n    var editor1 = ace.edit(\"editor1\", {\n        theme: \"ace/theme/tomorrow_night_eighties\",\n        mode: \"ace/mode/javascript\",\n        maxLines: 30,\n        wrap: true,\n        autoScrollEditorIntoView: true\n    });\n\n    var editor2 = ace.edit(\"editor2\", {\n        theme: \"ace/theme/tomorrow_night_blue\",\n        mode: \"ace/mode/css\",\n        autoScrollEditorIntoView: true,\n        maxLines: 30,\n        minLines: 2\n    });\n\n    var editor = ace.edit(\"editor3\");\n    editor.setOptions({\n        autoScrollEditorIntoView: true,\n        maxLines: 8\n    });\n    editor.renderer.setScrollMargin(10, 10, 10, 10);\n    \n    var editor = ace.edit(\"editor\");\n    editor.setTheme(\"ace/theme/tomorrow\");\n    editor.session.setMode(\"ace/mode/html\");\n    editor.setAutoScrollEditorIntoView(true);\n    editor.setOption(\"maxLines\", 100); \n    window.editor = editor;\n    \n    var editor4 = ace.edit(\"editor4\", {\n        theme: \"ace/theme/tomorrow_night_blue\",\n        mode: \"ace/mode/javascript\",\n        autoScrollEditorIntoView: true,\n        maxLines: 30,\n        minLines: 100,\n        hasCssTransforms: true,\n        value: \"transformed editor\" + \"\\n\".repeat(100)\n    });\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/code_lens.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>ACE Code Lens demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n\n    #editor {\n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/code_lens\"], function(ace, codeLens) {\n    var editor = ace.edit(\"editor\");\n    editor.session.setMode(\"ace/mode/html\");\n\n    var commandId = \"describeCodeLens\";\n    editor.commands.addCommand({\n        name: commandId,\n        exec: function(editor, args) {\n            // services available in `ctx`\n            alert('CodeLens command called with arguments ' + args);\n        }\n    });\n    editor.commands.addCommand({\n        name: \"clearCodeLenses\",\n        exec: function(editor, args) {\n            editor.setOption(\"enableCodeLens\", false);\n            codeLens.clear(editor.session);\n        }\n    });\n    editor.setOption(\"enableCodeLens\", true);\n\n    codeLens.registerCodeLensProvider(editor, {\n        provideCodeLenses: function(session, callback) {\n            var p = [{\n                start: {row: 0},\n                command: {\n                    id: \"clearCodeLenses\",\n                    title: \"Clear all code lenses\",\n                    arguments: []\n                }\n            }];\n            var l = session.getLength()\n\n            for (var row = 2; row < l; row ++) {\n                var line = session.getLine(row);\n                var endColumn = line.length;\n\n                var m = /[{>]\\s*$/.exec(line);\n                if (!m) continue;\n\n                p.push({\n                    start: {\n                        row: row,\n                        column: m.index,\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"Line \" + (row + 1),\n                        arguments: [\"line\", row]\n                    }\n                });\n\n                if (m.index < 10) continue;\n                p.push({\n                    start: {\n                        row: row,\n                        column: m.index,\n                    },\n                    end: {\n                        row: row,\n                        column: m.index + 1,\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"column \" + endColumn,\n                        arguments: [\"column\", endColumn]\n                    }\n                });\n\n                if (m.index < 30) continue;\n                p.push({\n                    start: {\n                        row: row,\n                        column: m.index,\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"Third Link\",\n                        arguments: [\"3\", row]\n                    }\n                });\n\n            }\n            callback(null, p);\n        }\n    });\n\n    window.editor = editor;\n    window.codeLens = codeLens;\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/csp.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <meta http-equiv=\"Content-Security-Policy\" content=\"\n    style-src 'self' ;\n    img-src  'self' ;\n    script-src 'self' 'nonce-bootstrap-script';\n    worker-src 'self' blob:\n  \">\n  <title>Editor</title>\n</head>\n<body>\n<pre id=\"editor\"></pre>\n\n<script src=\"../build/src-noconflict/ace.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<link rel=\"stylesheet\" href=\"../build/css/ace.css\">\n<link rel=\"stylesheet\" href=\"../build/css/theme/tomorrow_night_eighties.css\">\n\n<script nonce=\"bootstrap-script\">\n\nace.config.set(\"useStrictCSP\", true);\n\nvar editor = ace.edit(\"editor\", {\n    theme: \"ace/theme/tomorrow_night_eighties\",\n    mode: \"ace/mode/html\",\n    maxLines: 30,\n    wrap: true,\n    autoScrollEditorIntoView: true\n});\n\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/diff/examples/editor.16.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar useragent = require(\"./lib/useragent\");\nvar TextInput = require(\"./keyboard/textinput\").TextInput;\nvar MouseHandler = require(\"./mouse/mouse_handler\").MouseHandler;\nvar FoldHandler = require(\"./mouse/fold_handler\").FoldHandler;\nvar KeyBinding = require(\"./keyboard/keybinding\").KeyBinding;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Search = require(\"./search\").Search;\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar CommandManager = require(\"./commands/command_manager\").CommandManager;\nvar defaultCommands = require(\"./commands/default_commands\").commands;\nvar config = require(\"./config\");\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\nvar LineWidgets = require(\"./line_widgets\").LineWidgets;\n\nvar clipboard = require(\"./clipboard\");\n\n/**\n * The main entry point into the Ace functionality.\n *\n * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.\n *\n * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.\n * @class Editor\n **/\n\n/**\n * Creates a new `Editor` object.\n *\n * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything\n * @param {EditSession} session The `EditSession` to refer to\n *\n *\n * @constructor\n **/\nvar Editor = function(renderer, session, options) {\n    this.$toDestroy = [];\n    var container = renderer.getContainerElement();\n    this.container = container;\n    this.renderer = renderer;\n    this.id = \"editor\" + (++Editor.$uid);\n\n    this.commands = new CommandManager(useragent.isMac ? \"mac\" : \"win\", defaultCommands);\n    if (typeof document == \"object\") {\n        this.textInput = new TextInput(renderer.getTextAreaContainer(), this);\n        this.renderer.textarea = this.textInput.getElement();\n        // TODO detect touch event support\n        this.$mouseHandler = new MouseHandler(this);\n        new FoldHandler(this);\n    }\n\n    this.keyBinding = new KeyBinding(this);\n\n    this.$search = new Search().set({\n        wrap: true\n    });\n\n    this.$historyTracker = this.$historyTracker.bind(this);\n    this.commands.on(\"exec\", this.$historyTracker);\n\n    this.$initOperationListeners();\n    \n    this._$emitInputEvent = lang.delayedCall(function() {\n        this._signal(\"input\", {});\n        if (this.session && !this.session.destroyed)\n            this.session.bgTokenizer.scheduleStart();\n    }.bind(this));\n    \n    this.on(\"change\", function(_, _self) {\n        _self._$emitInputEvent.schedule(31);\n    });\n\n    this.setSession(session || options && options.session || new EditSession(\"\"));\n    config.resetOptions(this);\n    if (options)\n        this.setOptions(options);\n    config._signal(\"editor\", this);\n};\n\nEditor.$uid = 0;\n\n(function(){\n\n    oop.implement(this, EventEmitter);\n\n    this.$initOperationListeners = function() {\n        this.commands.on(\"exec\", this.startOperation.bind(this), true);\n        this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n\n        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true));\n        \n        // todo: add before change events?\n        this.on(\"change\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.docChanged = true;\n        }.bind(this), true);\n        \n        this.on(\"changeSelection\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.selectionChanged = true;\n        }.bind(this), true);\n    };\n\n    this.curOp = null;\n    this.prevOp = {};\n    this.startOperation = function(commandEvent) {\n        if (this.curOp) {\n            if (!commandEvent || this.curOp.command)\n                return;\n            this.prevOp = this.curOp;\n        }\n        if (!commandEvent) {\n            this.previousCommand = null;\n            commandEvent = {};\n        }\n\n        this.$opResetTimer.schedule();\n        this.curOp = this.session.curOp = {\n            command: commandEvent.command || {},\n            args: commandEvent.args,\n            scrollTop: this.renderer.scrollTop\n        };\n        this.curOp.selectionBefore = this.selection.toJSON();\n    };\n\n    this.endOperation = function(e) {\n        if (this.curOp && this.session) {\n            if (e && e.returnValue === false || !this.session)\n                return (this.curOp = null);\n            if (e == true && this.curOp.command && this.curOp.command.name == \"mouse\")\n                return;\n            this._signal(\"beforeEndOperation\");\n            if (!this.curOp) return;\n            var command = this.curOp.command;\n            var scrollIntoView = command && command.scrollIntoView;\n            if (scrollIntoView) {\n                switch (scrollIntoView) {\n                    case \"center-animate\":\n                        scrollIntoView = \"animate\";\n                        /* fall through */\n                    case \"center\":\n                        this.renderer.scrollCursorIntoView(null, 0.5);\n                        break;\n                    case \"animate\":\n                    case \"cursor\":\n                        this.renderer.scrollCursorIntoView();\n                        break;\n                    case \"selectionPart\":\n                        var range = this.selection.getRange();\n                        var config = this.renderer.layerConfig;\n                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {\n                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);\n                        }\n                        break;\n                    default:\n                        break;\n                }\n                if (scrollIntoView == \"animate\")\n                    this.renderer.animateScrolling(this.curOp.scrollTop);\n            }\n            var sel = this.selection.toJSON();\n            this.curOp.selectionAfter = sel;\n            this.$lastSel = this.selection.toJSON();\n            \n            // console.log(this.$lastSel+\"  endOP\")\n            this.session.getUndoManager().addSelection(sel);\n            this.prevOp = this.curOp;\n            this.curOp = null;\n        }\n    };\n\n    // TODO use property on commands instead of this\n    this.$mergeableCommands = [\"backspace\", \"del\", \"insertstring\"];\n    this.$historyTracker = function(e) {\n        if (!this.$mergeUndoDeltas)\n            return;\n\n        var prev = this.prevOp;\n        var mergeableCommands = this.$mergeableCommands;\n        // previous command was the same\n        var shouldMerge = prev.command && (e.command.name == prev.command.name);\n        if (e.command.name == \"insertstring\") {\n            var text = e.args;\n            if (this.mergeNextCommand === undefined)\n                this.mergeNextCommand = true;\n\n            shouldMerge = shouldMerge\n                && this.mergeNextCommand // previous command allows to coalesce with\n                && (!/\\s/.test(text) || /\\s/.test(prev.args)); // previous insertion was of same type\n\n            this.mergeNextCommand = true;\n        } else {\n            shouldMerge = shouldMerge\n                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n        }\n\n        if (\n            this.$mergeUndoDeltas != \"always\"\n            && Date.now() - this.sequenceStartTime > 2000\n        ) {\n            shouldMerge = false; // the sequence is too long\n        }\n\n        if (shouldMerge)\n            this.session.mergeUndoDeltas = true;\n        else if (mergeableCommands.indexOf(e.command.name) !== -1)\n            this.sequenceStartTime = Date.now();\n    };\n\n    /**\n     * Sets a new key handler, such as \"vim\" or \"windows\".\n     * @param {String} keyboardHandler The new key handler\n     *\n     **/\n    this.setKeyboardHandler = function(keyboardHandler, cb) {\n        if (keyboardHandler && typeof keyboardHandler === \"string\" && keyboardHandler != \"ace\") {\n            this.$keybindingId = keyboardHandler;\n            var _self = this;\n            config.loadModule([\"keybinding\", keyboardHandler], function(module) {\n                if (_self.$keybindingId == keyboardHandler)\n                    _self.keyBinding.setKeyboardHandler(module && module.handler);\n                cb && cb();\n            });\n        } else {\n            this.$keybindingId = null;\n            this.keyBinding.setKeyboardHandler(keyboardHandler);\n            cb && cb();\n        }\n    };\n\n    /**\n     * Returns the keyboard handler, such as \"vim\" or \"windows\".\n     *\n     * @returns {String}\n     *\n     **/\n    this.getKeyboardHandler = function() {\n        return this.keyBinding.getKeyboardHandler();\n    };\n\n\n    /**\n     * Emitted whenever the [[EditSession]] changes.\n     * @event changeSession\n     * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.\n     *\n     **/\n    /**\n     * Sets a new editsession to use. This method also emits the `'changeSession'` event.\n     * @param {EditSession} session The new session to use\n     *\n     **/\n    this.setSession = function(session) {\n        if (this.session == session)\n            return;\n        \n        // make sure operationEnd events are not emitted to wrong session\n        if (this.curOp) this.endOperation();\n        this.curOp = {};\n\n        var oldSession = this.session;\n        if (oldSession) {\n            this.session.off(\"change\", this.$onDocumentChange);\n            this.session.off(\"changeMode\", this.$onChangeMode);\n            this.session.off(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n            this.session.off(\"changeTabSize\", this.$onChangeTabSize);\n            this.session.off(\"changeWrapLimit\", this.$onChangeWrapLimit);\n            this.session.off(\"changeWrapMode\", this.$onChangeWrapMode);\n            this.session.off(\"changeFold\", this.$onChangeFold);\n            this.session.off(\"changeFrontMarker\", this.$onChangeFrontMarker);\n            this.session.off(\"changeBackMarker\", this.$onChangeBackMarker);\n            this.session.off(\"changeBreakpoint\", this.$onChangeBreakpoint);\n            this.session.off(\"changeAnnotation\", this.$onChangeAnnotation);\n            this.session.off(\"changeOverwrite\", this.$onCursorChange);\n            this.session.off(\"changeScrollTop\", this.$onScrollTopChange);\n            this.session.off(\"changeScrollLeft\", this.$onScrollLeftChange);\n\n            var selection = this.session.getSelection();\n            selection.off(\"changeCursor\", this.$onCursorChange);\n            selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n\n        this.session = session;\n        if (session) {\n            this.$onDocumentChange = this.onDocumentChange.bind(this);\n            session.on(\"change\", this.$onDocumentChange);\n            this.renderer.setSession(session);\n    \n            this.$onChangeMode = this.onChangeMode.bind(this);\n            session.on(\"changeMode\", this.$onChangeMode);\n    \n            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n            session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n    \n            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n            session.on(\"changeTabSize\", this.$onChangeTabSize);\n    \n            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n            session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n    \n            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n            session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n    \n            this.$onChangeFold = this.onChangeFold.bind(this);\n            session.on(\"changeFold\", this.$onChangeFold);\n    \n            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n            this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n    \n            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n            this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n    \n            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n            this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n    \n            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n            this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n    \n            this.$onCursorChange = this.onCursorChange.bind(this);\n            this.session.on(\"changeOverwrite\", this.$onCursorChange);\n    \n            this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n            this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n    \n            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n            this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n    \n            this.selection = session.getSelection();\n            this.selection.on(\"changeCursor\", this.$onCursorChange);\n    \n            this.$onSelectionChange = this.onSelectionChange.bind(this);\n            this.selection.on(\"changeSelection\", this.$onSelectionChange);\n    \n            this.onChangeMode();\n    \n            this.onCursorChange();\n    \n            this.onScrollTopChange();\n            this.onScrollLeftChange();\n            this.onSelectionChange();\n            this.onChangeFrontMarker();\n            this.onChangeBackMarker();\n            this.onChangeBreakpoint();\n            this.onChangeAnnotation();\n            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();\n            this.renderer.updateFull();\n        } else {\n            this.selection = null;\n            this.renderer.setSession(session);\n        }\n\n        this._signal(\"changeSession\", {\n            session: session,\n            oldSession: oldSession\n        });\n        \n        this.curOp = null;\n        \n        oldSession && oldSession._signal(\"changeEditor\", {oldEditor: this});\n        session && session._signal(\"changeEditor\", {editor: this});\n        \n        if (session && !session.destroyed)\n            session.bgTokenizer.scheduleStart();\n    };\n\n    /**\n     * Returns the current session being used.\n     * @returns {EditSession}\n     **/\n    this.getSession = function() {\n        return this.session;\n    };\n\n    /**\n     * Sets the current document to `val`.\n     * @param {String} val The new value to set for the document\n     * @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end\n     *\n     * @returns {String} The current document value\n     * @related Document.setValue\n     **/\n    this.setValue = function(val, cursorPos) {\n        this.session.doc.setValue(val);\n\n        if (!cursorPos)\n            this.selectAll();\n        else if (cursorPos == 1)\n            this.navigateFileEnd();\n        else if (cursorPos == -1)\n            this.navigateFileStart();\n\n        return val;\n    };\n\n    /**\n     * Returns the current session's content.\n     *\n     * @returns {String}\n     * @related EditSession.getValue\n     **/\n    this.getValue = function() {\n        return this.session.getValue();\n    };\n\n    /**\n     *\n     * Returns the currently highlighted selection.\n     * @returns {Selection} The selection object\n     **/\n    this.getSelection = function() {\n        return this.selection;\n    };\n\n    /**\n     * {:VirtualRenderer.onResize}\n     * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed\n     *\n     *\n     * @related VirtualRenderer.onResize\n     **/\n    this.resize = function(force) {\n        this.renderer.onResize(force);\n    };\n\n    /**\n     * {:VirtualRenderer.setTheme}\n     * @param {String} theme The path to a theme\n     * @param {Function} cb optional callback called when theme is loaded\n     **/\n    this.setTheme = function(theme, cb) {\n        this.renderer.setTheme(theme, cb);\n    };\n\n    /**\n     * {:VirtualRenderer.getTheme}\n     *\n     * @returns {String} The set theme\n     * @related VirtualRenderer.getTheme\n     **/\n    this.getTheme = function() {\n        return this.renderer.getTheme();\n    };\n\n    /**\n     * {:VirtualRenderer.setStyle}\n     * @param {String} style A class name\n     *\n     *\n     * @related VirtualRenderer.setStyle\n     **/\n    this.setStyle = function(style) {\n        this.renderer.setStyle(style);\n    };\n\n    /**\n     * {:VirtualRenderer.unsetStyle}\n     * @related VirtualRenderer.unsetStyle\n     **/\n    this.unsetStyle = function(style) {\n        this.renderer.unsetStyle(style);\n    };\n\n    /**\n     * Gets the current font size of the editor text.\n     */\n    this.getFontSize = function () {\n        return this.getOption(\"fontSize\") ||\n           dom.computedStyle(this.container).fontSize;\n    };\n\n    /**\n     * Set a new font size (in pixels) for the editor text.\n     * @param {String} size A font size ( _e.g._ \"12px\")\n     *\n     *\n     **/\n    this.setFontSize = function(size) {\n        this.setOption(\"fontSize\", size);\n    };\n\n    this.$highlightBrackets = function() {\n        if (this.$highlightPending) {\n            return;\n        }\n\n        // perform highlight async to not block the browser during navigation\n        var self = this;\n        this.$highlightPending = true;\n        setTimeout(function () {\n            self.$highlightPending = false;\n            var session = self.session;\n            if (!session || session.destroyed) return;\n            if (session.$bracketHighlight) {\n                session.$bracketHighlight.markerIds.forEach(function(id) {\n                    session.removeMarker(id);\n                });\n                session.$bracketHighlight = null;\n            }\n            var pos = self.getCursorPosition();\n            var handler = self.getKeyboardHandler();\n            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);\n            var ranges = session.getMatchingBracketRanges(pos, isBackwards);\n\n            if (!ranges) {\n                var iterator = new TokenIterator(session, pos.row, pos.column);\n                var token = iterator.getCurrentToken();\n\n                if (token && /\\b(?:tag-open|tag-name)/.test(token.type)) {\n                    var tagNamesRanges = session.getMatchingTags(pos);\n                    if (tagNamesRanges) ranges = [tagNamesRanges.openTagName, tagNamesRanges.closeTagName];\n                }\n            }\n            if (!ranges && session.$mode.getMatching)\n                ranges = session.$mode.getMatching(self.session);\n            if (!ranges) {\n                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n                return;\n            }\n\n            var markerType = \"ace_bracket\";\n            if (!Array.isArray(ranges)) {\n                ranges = [ranges];\n            } else if (ranges.length == 1) {\n                markerType = \"ace_error_bracket\";\n            }\n\n            // show adjacent ranges as one\n            if (ranges.length == 2) {\n                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)\n                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];\n                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)\n                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];\n            }\n\n            session.$bracketHighlight = {\n                ranges: ranges,\n                markerIds: ranges.map(function(range) {\n                    return session.addMarker(range, markerType, \"text\");\n                })\n            };\n            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n        }, 50);\n    };\n\n    /**\n     *\n     * Brings the current `textInput` into focus.\n     **/\n    this.focus = function() {\n        this.textInput.focus();\n    };\n\n    /**\n     * Returns `true` if the current `textInput` is in focus.\n     * @return {Boolean}\n     **/\n    this.isFocused = function() {\n        return this.textInput.isFocused();\n    };\n\n    /**\n     *\n     * Blurs the current `textInput`.\n     **/\n    this.blur = function() {\n        this.textInput.blur();\n    };\n\n    /**\n     * Emitted once the editor comes into focus.\n     * @event focus\n     *\n     *\n     **/\n    this.onFocus = function(e) {\n        if (this.$isFocused)\n            return;\n        this.$isFocused = true;\n        this.renderer.showCursor();\n        this.renderer.visualizeFocus();\n        this._emit(\"focus\", e);\n    };\n\n    /**\n     * Emitted once the editor has been blurred.\n     * @event blur\n     *\n     *\n     **/\n    this.onBlur = function(e) {\n        if (!this.$isFocused)\n            return;\n        this.$isFocused = false;\n        this.renderer.hideCursor();\n        this.renderer.visualizeBlur();\n        this._emit(\"blur\", e);\n    };\n\n    this.$cursorChange = function() {\n        this.renderer.updateCursor();\n        this.$highlightBrackets();\n        this.$updateHighlightActiveLine();\n    };\n\n    /**\n     * Emitted whenever the document is changed.\n     * @event change\n     * @param {Object} e Contains a single property, `data`, which has the delta of changes\n     *\n     *\n     *\n     **/\n    this.onDocumentChange = function(delta) {\n        // Rerender and emit \"change\" event.\n        var wrap = this.session.$useWrapMode;\n        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);\n        this.renderer.updateLines(delta.start.row, lastRow, wrap);\n\n        this._signal(\"change\", delta);\n        \n        // Update cursor because tab characters can influence the cursor position.\n        this.$cursorChange();\n    };\n\n    this.onTokenizerUpdate = function(e) {\n        var rows = e.data;\n        this.renderer.updateLines(rows.first, rows.last);\n    };\n\n\n    this.onScrollTopChange = function() {\n        this.renderer.scrollToY(this.session.getScrollTop());\n    };\n\n    this.onScrollLeftChange = function() {\n        this.renderer.scrollToX(this.session.getScrollLeft());\n    };\n\n    /**\n     * Emitted when the selection changes.\n     *\n     **/\n    this.onCursorChange = function() {\n        this.$cursorChange();\n        this._signal(\"changeSelection\");\n    };\n\n    this.$updateHighlightActiveLine = function() {\n        var session = this.getSession();\n\n        var highlight;\n        if (this.$highlightActiveLine) {\n            if (this.$selectionStyle != \"line\" || !this.selection.isMultiLine())\n                highlight = this.getCursorPosition();\n            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())\n                highlight = false;\n            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))\n                highlight = false;\n        }\n\n        if (session.$highlightLineMarker && !highlight) {\n            session.removeMarker(session.$highlightLineMarker.id);\n            session.$highlightLineMarker = null;\n        } else if (!session.$highlightLineMarker && highlight) {\n            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);\n            range.id = session.addMarker(range, \"ace_active-line\", \"screenLine\");\n            session.$highlightLineMarker = range;\n        } else if (highlight) {\n            session.$highlightLineMarker.start.row = highlight.row;\n            session.$highlightLineMarker.end.row = highlight.row;\n            session.$highlightLineMarker.start.column = highlight.column;\n            session._signal(\"changeBackMarker\");\n        }\n    };\n\n    this.onSelectionChange = function(e) {\n        var session = this.session;\n\n        if (session.$selectionMarker) {\n            session.removeMarker(session.$selectionMarker);\n        }\n        session.$selectionMarker = null;\n\n        if (!this.selection.isEmpty()) {\n            var range = this.selection.getRange();\n            var style = this.getSelectionStyle();\n            session.$selectionMarker = session.addMarker(range, \"ace_selection\", style);\n        } else {\n            this.$updateHighlightActiveLine();\n        }\n\n        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n        this.session.highlight(re);\n\n        this._signal(\"changeSelection\");\n    };\n\n    this.$getSelectionHighLightRegexp = function() {\n        var session = this.session;\n\n        var selection = this.getSelectionRange();\n        if (selection.isEmpty() || selection.isMultiLine())\n            return;\n\n        var startColumn = selection.start.column;\n        var endColumn = selection.end.column;\n        var line = session.getLine(selection.start.row);\n        \n        var needle = line.substring(startColumn, endColumn);\n        // maximum allowed size for regular expressions in 32000, \n        // but getting close to it has significant impact on the performance\n        if (needle.length > 5000 || !/[\\w\\d]/.test(needle))\n            return;\n\n        var re = this.$search.$assembleRegExp({\n            wholeWord: true,\n            caseSensitive: true,\n            needle: needle\n        });\n        \n        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);\n        if (!re.test(wordWithBoundary))\n            return;\n        \n        return re;\n    };\n\n\n    this.onChangeFrontMarker = function() {\n        this.renderer.updateFrontMarkers();\n    };\n\n    this.onChangeBackMarker = function() {\n        this.renderer.updateBackMarkers();\n    };\n\n\n    this.onChangeBreakpoint = function() {\n        this.renderer.updateBreakpoints();\n    };\n\n    this.onChangeAnnotation = function() {\n        this.renderer.setAnnotations(this.session.getAnnotations());\n    };\n\n\n    this.onChangeMode = function(e) {\n        this.renderer.updateText();\n        this._emit(\"changeMode\", e);\n    };\n\n\n    this.onChangeWrapLimit = function() {\n        this.renderer.updateFull();\n    };\n\n    this.onChangeWrapMode = function() {\n        this.renderer.onResize(true);\n    };\n\n\n    this.onChangeFold = function() {\n        // Update the active line marker as due to folding changes the current\n        // line range on the screen might have changed.\n        this.$updateHighlightActiveLine();\n        // TODO: This might be too much updating. Okay for now.\n        this.renderer.updateFull();\n    };\n\n    \n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    this.getSelectedText = function() {\n        return this.session.getTextRange(this.getSelectionRange());\n    };\n    \n    /**\n     * Emitted when text is copied.\n     * @event copy\n     * @param {String} text The copied text\n     *\n     **/\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    this.getCopyText = function() {\n        var text = this.getSelectedText();\n        var nl = this.session.doc.getNewLineCharacter();\n        var copyLine= false;\n        if (!text && this.$copyWithEmptySelection) {\n            copyLine = true;\n            var ranges = this.selection.getAllRanges();\n            for (var i = 0; i < ranges.length; i++) {\n                var range = ranges[i];\n                if (i && ranges[i - 1].start.row == range.start.row)\n                    continue;\n                text += this.session.getLine(range.start.row) + nl;\n            }\n        }\n        var e = {text: text};\n        this._signal(\"copy\", e);\n        clipboard.lineMode = copyLine ? e.text : false;\n        return e.text;\n    };\n\n    /**\n     * Called whenever a text \"copy\" happens.\n     **/\n    this.onCopy = function() {\n        this.commands.exec(\"copy\", this);\n    };\n\n    /**\n     * Called whenever a text \"cut\" happens.\n     **/\n    this.onCut = function() {\n        this.commands.exec(\"cut\", this);\n    };\n\n    /**\n     * Emitted when text is pasted.\n     * @event paste\n     * @param {Object} an object which contains one property, `text`, that represents the text to be pasted. Editing this property will alter the text that is pasted.\n     *\n     *\n     **/\n    /**\n     * Called whenever a text \"paste\" happens.\n     * @param {String} text The pasted text\n     *\n     *\n     **/\n    this.onPaste = function(text, event) {\n        var e = {text: text, event: event};\n        this.commands.exec(\"paste\", this, e);\n    };\n    \n    this.$handlePaste = function(e) {\n        if (typeof e == \"string\") \n            e = {text: e};\n        this._signal(\"paste\", e);\n        var text = e.text;\n\n        var lineMode = text === clipboard.lineMode;\n        var session = this.session;\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n            if (lineMode)\n                session.insert({ row: this.selection.lead.row, column: 0 }, text);\n            else\n                this.insert(text);\n        } else if (lineMode) {\n            this.selection.rangeList.ranges.forEach(function(range) {\n                session.insert({ row: range.start.row, column: 0 }, text);\n            });\n        } else {\n            var lines = text.split(/\\r\\n|\\r|\\n/);\n            var ranges = this.selection.rangeList.ranges;\n    \n            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);\n            if (lines.length != ranges.length || isFullLine)\n                return this.commands.exec(\"insertstring\", this, text);\n    \n            for (var i = ranges.length; i--;) {\n                var range = ranges[i];\n                if (!range.isEmpty())\n                    session.remove(range);\n    \n                session.insert(range.start, lines[i]);\n            }\n        }\n    };\n\n    this.execCommand = function(command, args) {\n        return this.commands.exec(command, this, args);\n    };\n\n    /**\n     * Inserts `text` into wherever the cursor is pointing.\n     * @param {String} text The new text to add\n     *\n     **/\n    this.insert = function(text, pasted) {\n        var session = this.session;\n        var mode = session.getMode();\n        var cursor = this.getCursorPosition();\n\n        if (this.getBehavioursEnabled() && !pasted) {\n            // Get a transform if the current mode wants one.\n            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);\n            if (transform) {\n                if (text !== transform.text) {\n                    // keep automatic insertion in a separate delta, unless it is in multiselect mode\n                    if (!this.inVirtualSelectionMode) {\n                        this.session.mergeUndoDeltas = false;\n                        this.mergeNextCommand = false;\n                    }\n                }\n                text = transform.text;\n\n            }\n        }\n        \n        if (text == \"\\t\")\n            text = this.session.getTabString();\n\n        // remove selected text\n        if (!this.selection.isEmpty()) {\n            var range = this.getSelectionRange();\n            cursor = this.session.remove(range);\n            this.clearSelection();\n        }\n        else if (this.session.getOverwrite() && text.indexOf(\"\\n\") == -1) {\n            var range = new Range.fromPoints(cursor, cursor);\n            range.end.column += text.length;\n            this.session.remove(range);\n        }\n\n        if (text == \"\\n\" || text == \"\\r\\n\") {\n            var line = session.getLine(cursor.row);\n            if (cursor.column > line.search(/\\S|$/)) {\n                var d = line.substr(cursor.column).search(/\\S|$/);\n                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);\n            }\n        }\n        this.clearSelection();\n\n        var start = cursor.column;\n        var lineState = session.getState(cursor.row);\n        var line = session.getLine(cursor.row);\n        var shouldOutdent = mode.checkOutdent(lineState, line, text);\n        session.insert(cursor, text);\n\n        if (transform && transform.selection) {\n            if (transform.selection.length == 2) { // Transform relative to the current column\n                this.selection.setSelectionRange(\n                    new Range(cursor.row, start + transform.selection[0],\n                              cursor.row, start + transform.selection[1]));\n            } else { // Transform relative to the current row.\n                this.selection.setSelectionRange(\n                    new Range(cursor.row + transform.selection[0],\n                              transform.selection[1],\n                              cursor.row + transform.selection[2],\n                              transform.selection[3]));\n            }\n        }\n        if (this.$enableAutoIndent) {\n            if (session.getDocument().isNewLine(text)) {\n                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n\n                session.insert({row: cursor.row+1, column: 0}, lineIndent);\n            }\n            if (shouldOutdent)\n                mode.autoOutdent(lineState, session, cursor.row);\n        }\n    };\n\n    this.autoIndent = function () {\n        var session = this.session;\n        var mode = session.getMode();\n\n        var startRow, endRow;\n        if (this.selection.isEmpty()) {\n            startRow = 0;\n            endRow = session.doc.getLength() - 1;\n        } else {\n            var selectedRange = this.getSelectionRange();\n\n            startRow = selectedRange.start.row;\n            endRow = selectedRange.end.row;\n        }\n\n        var prevLineState = \"\";\n        var prevLine = \"\";\n        var lineIndent = \"\";\n        var line, currIndent, range;\n        var tab = session.getTabString();\n\n        for (var row = startRow; row <= endRow; row++) {\n            if (row > 0) {\n                prevLineState = session.getState(row - 1);\n                prevLine = session.getLine(row - 1);\n                lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);\n            }\n\n            line = session.getLine(row);\n            currIndent = mode.$getIndent(line);\n            if (lineIndent !== currIndent) {\n                if (currIndent.length > 0) {\n                    range = new Range(row, 0, row, currIndent.length);\n                    session.remove(range);\n                }\n                if (lineIndent.length > 0) {\n                    session.insert({row: row, column: 0}, lineIndent);\n                }\n            }\n\n            mode.autoOutdent(prevLineState, session, row);\n        }\n    };\n\n\n    this.onTextInput = function(text, composition) {\n        if (!composition)\n            return this.keyBinding.onTextInput(text);\n        \n        this.startOperation({command: { name: \"insertstring\" }});\n        var applyComposition = this.applyComposition.bind(this, text, composition);\n        if (this.selection.rangeCount)\n            this.forEachSelection(applyComposition);\n        else\n            applyComposition();\n        this.endOperation();\n    };\n    \n    this.applyComposition = function(text, composition) {\n        if (composition.extendLeft || composition.extendRight) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.extendLeft;\n            r.end.column += composition.extendRight;\n            if (r.start.column < 0) {\n                r.start.row--;\n                r.start.column += this.session.getLine(r.start.row).length + 1;\n            }\n            this.selection.setRange(r);\n            if (!text && !r.isEmpty())\n                this.remove();\n        }\n        if (text || !this.selection.isEmpty())\n            this.insert(text, true);\n        if (composition.restoreStart || composition.restoreEnd) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.restoreStart;\n            r.end.column -= composition.restoreEnd;\n            this.selection.setRange(r);\n        }\n    };\n\n    this.onCommandKey = function(e, hashId, keyCode) {\n        return this.keyBinding.onCommandKey(e, hashId, keyCode);\n    };\n\n    /**\n     * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n     * @param {Boolean} overwrite Defines whether or not to set overwrites\n     *\n     *\n     * @related EditSession.setOverwrite\n     **/\n    this.setOverwrite = function(overwrite) {\n        this.session.setOverwrite(overwrite);\n    };\n\n    /**\n     * Returns `true` if overwrites are enabled; `false` otherwise.\n     * @returns {Boolean}\n     * @related EditSession.getOverwrite\n     **/\n    this.getOverwrite = function() {\n        return this.session.getOverwrite();\n    };\n\n    /**\n     * Sets the value of overwrite to the opposite of whatever it currently is.\n     * @related EditSession.toggleOverwrite\n     **/\n    this.toggleOverwrite = function() {\n        this.session.toggleOverwrite();\n    };\n\n    /**\n     * Sets how fast the mouse scrolling should do.\n     * @param {Number} speed A value indicating the new speed (in milliseconds)\n     **/\n    this.setScrollSpeed = function(speed) {\n        this.setOption(\"scrollSpeed\", speed);\n    };\n\n    /**\n     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).\n     * @returns {Number}\n     **/\n    this.getScrollSpeed = function() {\n        return this.getOption(\"scrollSpeed\");\n    };\n\n    /**\n     * Sets the delay (in milliseconds) of the mouse drag.\n     * @param {Number} dragDelay A value indicating the new delay\n     **/\n    this.setDragDelay = function(dragDelay) {\n        this.setOption(\"dragDelay\", dragDelay);\n    };\n\n    /**\n     * Returns the current mouse drag delay.\n     * @returns {Number}\n     **/\n    this.getDragDelay = function() {\n        return this.getOption(\"dragDelay\");\n    };\n\n    /**\n     * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].\n     * @event changeSelectionStyle\n     * @param {Object} data Contains one property, `data`, which indicates the new selection style\n     **/\n    /**\n     * Draw selection markers spanning whole line, or only over selected text. Default value is \"line\"\n     * @param {String} style The new selection style \"line\"|\"text\"\n     *\n     **/\n    this.setSelectionStyle = function(val) {\n        this.setOption(\"selectionStyle\", val);\n    };\n\n    /**\n     * Returns the current selection style.\n     * @returns {String}\n     **/\n    this.getSelectionStyle = function() {\n        return this.getOption(\"selectionStyle\");\n    };\n\n    /**\n     * Determines whether or not the current line should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line\n     **/\n    this.setHighlightActiveLine = function(shouldHighlight) {\n        this.setOption(\"highlightActiveLine\", shouldHighlight);\n    };\n    /**\n     * Returns `true` if current lines are always highlighted.\n     * @return {Boolean}\n     **/\n    this.getHighlightActiveLine = function() {\n        return this.getOption(\"highlightActiveLine\");\n    };\n    this.setHighlightGutterLine = function(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    };\n\n    this.getHighlightGutterLine = function() {\n        return this.getOption(\"highlightGutterLine\");\n    };\n\n    /**\n     * Determines if the currently selected word should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word\n     *\n     **/\n    this.setHighlightSelectedWord = function(shouldHighlight) {\n        this.setOption(\"highlightSelectedWord\", shouldHighlight);\n    };\n\n    /**\n     * Returns `true` if currently highlighted words are to be highlighted.\n     * @returns {Boolean}\n     **/\n    this.getHighlightSelectedWord = function() {\n        return this.$highlightSelectedWord;\n    };\n\n    this.setAnimatedScroll = function(shouldAnimate){\n        this.renderer.setAnimatedScroll(shouldAnimate);\n    };\n\n    this.getAnimatedScroll = function(){\n        return this.renderer.getAnimatedScroll();\n    };\n\n    /**\n     * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.\n     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters\n     *\n     **/\n    this.setShowInvisibles = function(showInvisibles) {\n        this.renderer.setShowInvisibles(showInvisibles);\n    };\n\n    /**\n     * Returns `true` if invisible characters are being shown.\n     * @returns {Boolean}\n     **/\n    this.getShowInvisibles = function() {\n        return this.renderer.getShowInvisibles();\n    };\n\n    this.setDisplayIndentGuides = function(display) {\n        this.renderer.setDisplayIndentGuides(display);\n    };\n\n    this.getDisplayIndentGuides = function() {\n        return this.renderer.getDisplayIndentGuides();\n    };\n\n    this.setHighlightIndentGuides = function(highlight) {\n        this.renderer.setHighlightIndentGuides(highlight);\n    };\n\n    this.getHighlightIndentGuides = function() {\n        return this.renderer.getHighlightIndentGuides();\n    };\n\n    /**\n     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.\n     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin\n     *\n     **/\n    this.setShowPrintMargin = function(showPrintMargin) {\n        this.renderer.setShowPrintMargin(showPrintMargin);\n    };\n\n    /**\n     * Returns `true` if the print margin is being shown.\n     * @returns {Boolean}\n     **/\n    this.getShowPrintMargin = function() {\n        return this.renderer.getShowPrintMargin();\n    };\n\n    /**\n     * Sets the column defining where the print margin should be.\n     * @param {Number} showPrintMargin Specifies the new print margin\n     *\n     **/\n    this.setPrintMarginColumn = function(showPrintMargin) {\n        this.renderer.setPrintMarginColumn(showPrintMargin);\n    };\n\n    /**\n     * Returns the column number of where the print margin is.\n     * @returns {Number}\n     **/\n    this.getPrintMarginColumn = function() {\n        return this.renderer.getPrintMarginColumn();\n    };\n\n    /**\n     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.\n     * @param {Boolean} readOnly Specifies whether the editor can be modified or not\n     *\n     **/\n    this.setReadOnly = function(readOnly) {\n        this.setOption(\"readOnly\", readOnly);\n    };\n\n    /**\n     * Returns `true` if the editor is set to read-only mode.\n     * @returns {Boolean}\n     **/\n    this.getReadOnly = function() {\n        return this.getOption(\"readOnly\");\n    };\n\n    /**\n     * Specifies whether to use behaviors or not. [\"Behaviors\" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}\n     * @param {Boolean} enabled Enables or disables behaviors\n     *\n     **/\n    this.setBehavioursEnabled = function (enabled) {\n        this.setOption(\"behavioursEnabled\", enabled);\n    };\n\n    /**\n     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}\n     *\n     * @returns {Boolean}\n     **/\n    this.getBehavioursEnabled = function () {\n        return this.getOption(\"behavioursEnabled\");\n    };\n\n    /**\n     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets\n     * when such a character is typed in.\n     * @param {Boolean} enabled Enables or disables wrapping behaviors\n     *\n     **/\n    this.setWrapBehavioursEnabled = function (enabled) {\n        this.setOption(\"wrapBehavioursEnabled\", enabled);\n    };\n\n    /**\n     * Returns `true` if the wrapping behaviors are currently enabled.\n     **/\n    this.getWrapBehavioursEnabled = function () {\n        return this.getOption(\"wrapBehavioursEnabled\");\n    };\n\n    /**\n     * Indicates whether the fold widgets should be shown or not.\n     * @param {Boolean} show Specifies whether the fold widgets are shown\n     **/\n    this.setShowFoldWidgets = function(show) {\n        this.setOption(\"showFoldWidgets\", show);\n\n    };\n    /**\n     * Returns `true` if the fold widgets are shown.\n     * @return {Boolean}\n     **/\n    this.getShowFoldWidgets = function() {\n        return this.getOption(\"showFoldWidgets\");\n    };\n\n    this.setFadeFoldWidgets = function(fade) {\n        this.setOption(\"fadeFoldWidgets\", fade);\n    };\n\n    this.getFadeFoldWidgets = function() {\n        return this.getOption(\"fadeFoldWidgets\");\n    };\n\n    /**\n     * Removes the current selection or one character.\n     * @param {String} dir The direction of the deletion to occur, either \"left\" or \"right\"\n     *\n     **/\n    this.remove = function(dir) {\n        if (this.selection.isEmpty()){\n            if (dir == \"left\")\n                this.selection.selectLeft();\n            else\n                this.selection.selectRight();\n        }\n\n        var range = this.getSelectionRange();\n        if (this.getBehavioursEnabled()) {\n            var session = this.session;\n            var state = session.getState(range.start.row);\n            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);\n\n            if (range.end.column === 0) {\n                var text = session.getTextRange(range);\n                if (text[text.length - 1] == \"\\n\") {\n                    var line = session.getLine(range.end.row);\n                    if (/^\\s+$/.test(line)) {\n                        range.end.column = line.length;\n                    }\n                }\n            }\n            if (new_range)\n                range = new_range;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    };\n\n    /**\n     * Removes the word directly to the right of the current selection.\n     **/\n    this.removeWordRight = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordRight();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n\n    /**\n     * Removes the word directly to the left of the current selection.\n     **/\n    this.removeWordLeft = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordLeft();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n\n    /**\n     * Removes all the words to the left of the current selection, until the start of the line.\n     **/\n    this.removeToLineStart = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineStart();\n        if (this.selection.isEmpty())\n            this.selection.selectLeft();\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n\n    /**\n     * Removes all the words to the right of the current selection, until the end of the line.\n     **/\n    this.removeToLineEnd = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineEnd();\n\n        var range = this.getSelectionRange();\n        if (range.start.column == range.end.column && range.start.row == range.end.row) {\n            range.end.column = 0;\n            range.end.row++;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    };\n\n    /**\n     * Splits the line at the current selection (by inserting an `'\\n'`).\n     **/\n    this.splitLine = function() {\n        if (!this.selection.isEmpty()) {\n            this.session.remove(this.getSelectionRange());\n            this.clearSelection();\n        }\n\n        var cursor = this.getCursorPosition();\n        this.insert(\"\\n\");\n        this.moveCursorToPosition(cursor);\n    };\n\n    /**\n     * Set the \"ghost\" text in provided position. \"Ghost\" text is a kind of\n     * preview text inside the editor which can be used to preview some code\n     * inline in the editor such as, for example, code completions.\n     * \n     * @param {String} text Text to be inserted as \"ghost\" text\n     * @param {object} position Position to insert text to\n     */\n    this.setGhostText = function(text, position) {\n        if (!this.session.widgetManager) {\n            this.session.widgetManager = new LineWidgets(this.session);\n            this.session.widgetManager.attach(this);\n        }\n        this.renderer.setGhostText(text, position);\n    };\n\n    /**\n     * Removes \"ghost\" text currently displayed in the editor.\n     */\n    this.removeGhostText = function() {\n        if (!this.session.widgetManager) return;\n\n        this.renderer.removeGhostText();\n    };\n\n    /**\n     * Transposes current line.\n     **/\n    this.transposeLetters = function() {\n        if (!this.selection.isEmpty()) {\n            return;\n        }\n\n        var cursor = this.getCursorPosition();\n        var column = cursor.column;\n        if (column === 0)\n            return;\n\n        var line = this.session.getLine(cursor.row);\n        var swap, range;\n        if (column < line.length) {\n            swap = line.charAt(column) + line.charAt(column-1);\n            range = new Range(cursor.row, column-1, cursor.row, column+1);\n        }\n        else {\n            swap = line.charAt(column-1) + line.charAt(column-2);\n            range = new Range(cursor.row, column-2, cursor.row, column);\n        }\n        this.session.replace(range, swap);\n        this.session.selection.moveToPosition(range.end);\n    };\n\n    /**\n     * Converts the current selection entirely into lowercase.\n     **/\n    this.toLowerCase = function() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toLowerCase());\n        this.selection.setSelectionRange(originalRange);\n    };\n\n    /**\n     * Converts the current selection entirely into uppercase.\n     **/\n    this.toUpperCase = function() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toUpperCase());\n        this.selection.setSelectionRange(originalRange);\n    };\n\n    /**\n     * Inserts an indentation into the current cursor position or indents the selected lines.\n     *\n     * @related EditSession.indentRows\n     **/\n    this.indent = function() {\n        var session = this.session;\n        var range = this.getSelectionRange();\n\n        if (range.start.row < range.end.row) {\n            var rows = this.$getSelectedRows();\n            session.indentRows(rows.first, rows.last, \"\\t\");\n            return;\n        } else if (range.start.column < range.end.column) {\n            var text = session.getTextRange(range);\n            if (!/^\\s+$/.test(text)) {\n                var rows = this.$getSelectedRows();\n                session.indentRows(rows.first, rows.last, \"\\t\");\n                return;\n            }\n        }\n        \n        var line = session.getLine(range.start.row);\n        var position = range.start;\n        var size = session.getTabSize();\n        var column = session.documentToScreenColumn(position.row, position.column);\n\n        if (this.session.getUseSoftTabs()) {\n            var count = (size - column % size);\n            var indentString = lang.stringRepeat(\" \", count);\n        } else {\n            var count = column % size;\n            while (line[range.start.column - 1] == \" \" && count) {\n                range.start.column--;\n                count--;\n            }\n            this.selection.setSelectionRange(range);\n            indentString = \"\\t\";\n        }\n        return this.insert(indentString);\n    };\n\n    /**\n     * Indents the current line.\n     * @related EditSession.indentRows\n     **/\n    this.blockIndent = function() {\n        var rows = this.$getSelectedRows();\n        this.session.indentRows(rows.first, rows.last, \"\\t\");\n    };\n\n    /**\n     * Outdents the current line.\n     * @related EditSession.outdentRows\n     **/\n    this.blockOutdent = function() {\n        var selection = this.session.getSelection();\n        this.session.outdentRows(selection.getRange());\n    };\n\n    // TODO: move out of core when we have good mechanism for managing extensions\n    this.sortLines = function() {\n        var rows = this.$getSelectedRows();\n        var session = this.session;\n\n        var lines = [];\n        for (var i = rows.first; i <= rows.last; i++)\n            lines.push(session.getLine(i));\n\n        lines.sort(function(a, b) {\n            if (a.toLowerCase() < b.toLowerCase()) return -1;\n            if (a.toLowerCase() > b.toLowerCase()) return 1;\n            return 0;\n        });\n\n        var deleteRange = new Range(0, 0, 0, 0);\n        for (var i = rows.first; i <= rows.last; i++) {\n            var line = session.getLine(i);\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            deleteRange.end.column = line.length;\n            session.replace(deleteRange, lines[i-rows.first]);\n        }\n    };\n\n    /**\n     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.\n     **/\n    this.toggleCommentLines = function() {\n        var state = this.session.getState(this.getCursorPosition().row);\n        var rows = this.$getSelectedRows();\n        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);\n    };\n\n    this.toggleBlockComment = function() {\n        var cursor = this.getCursorPosition();\n        var state = this.session.getState(cursor.row);\n        var range = this.getSelectionRange();\n        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);\n    };\n\n    /**\n     * Works like [[EditSession.getTokenAt]], except it returns a number.\n     * @returns {Number}\n     **/\n    this.getNumberAt = function(row, column) {\n        var _numberRx = /[\\-]?[0-9]+(?:\\.[0-9]+)?/g;\n        _numberRx.lastIndex = 0;\n\n        var s = this.session.getLine(row);\n        while (_numberRx.lastIndex < column) {\n            var m = _numberRx.exec(s);\n            if(m.index <= column && m.index+m[0].length >= column){\n                var number = {\n                    value: m[0],\n                    start: m.index,\n                    end: m.index+m[0].length\n                };\n                return number;\n            }\n        }\n        return null;\n    };\n\n    /**\n     * If the character before the cursor is a number, this functions changes its value by `amount`.\n     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)\n     *\n     **/\n    this.modifyNumber = function(amount) {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n\n        // get the char before the cursor\n        var charRange = new Range(row, column-1, row, column);\n\n        var c = this.session.getTextRange(charRange);\n        // if the char is a digit\n        if (!isNaN(parseFloat(c)) && isFinite(c)) {\n            // get the whole number the digit is part of\n            var nr = this.getNumberAt(row, column);\n            // if number found\n            if (nr) {\n                var fp = nr.value.indexOf(\".\") >= 0 ? nr.start + nr.value.indexOf(\".\") + 1 : nr.end;\n                var decimals = nr.start + nr.value.length - fp;\n\n                var t = parseFloat(nr.value);\n                t *= Math.pow(10, decimals);\n\n\n                if(fp !== nr.end && column < fp){\n                    amount *= Math.pow(10, nr.end - column - 1);\n                } else {\n                    amount *= Math.pow(10, nr.end - column);\n                }\n\n                t += amount;\n                t /= Math.pow(10, decimals);\n                var nnr = t.toFixed(decimals);\n\n                //update number\n                var replaceRange = new Range(row, nr.start, row, nr.end);\n                this.session.replace(replaceRange, nnr);\n\n                //reposition the cursor\n                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));\n\n            }\n        } else {\n            this.toggleWord();\n        }\n    };\n\n    this.$toggleWordPairs = [\n        [\"first\", \"last\"],\n        [\"true\", \"false\"],\n        [\"yes\", \"no\"],\n        [\"width\", \"height\"],\n        [\"top\", \"bottom\"],\n        [\"right\", \"left\"],\n        [\"on\", \"off\"],\n        [\"x\", \"y\"],\n        [\"get\", \"set\"],\n        [\"max\", \"min\"],\n        [\"horizontal\", \"vertical\"],\n        [\"show\", \"hide\"],\n        [\"add\", \"remove\"],\n        [\"up\", \"down\"],\n        [\"before\", \"after\"],\n        [\"even\", \"odd\"],\n        [\"in\", \"out\"],\n        [\"inside\", \"outside\"],\n        [\"next\", \"previous\"],\n        [\"increase\", \"decrease\"],\n        [\"attach\", \"detach\"],\n        [\"&&\", \"||\"],\n        [\"==\", \"!=\"]\n    ];\n\n    this.toggleWord = function () {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        this.selection.selectWord();\n        var currentState = this.getSelectedText();\n        var currWordStart = this.selection.getWordRange().start.column;\n        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\\s/);\n        var delta = column - currWordStart - 1;\n        if (delta < 0) delta = 0;\n        var curLength = 0, itLength = 0;\n        var that = this;\n        if (currentState.match(/[A-Za-z0-9_]+/)) {\n            wordParts.forEach(function (item, i) {\n                itLength = curLength + item.length;\n                if (delta >= curLength && delta <= itLength) {\n                    currentState = item;\n                    that.selection.clearSelection();\n                    that.moveCursorTo(row, curLength + currWordStart);\n                    that.selection.selectTo(row, itLength + currWordStart);\n                }\n                curLength = itLength;\n            });\n        }\n\n        var wordPairs = this.$toggleWordPairs;\n        var reg;\n        for (var i = 0; i < wordPairs.length; i++) {\n            var item = wordPairs[i];\n            for (var j = 0; j <= 1; j++) {\n                var negate = +!j;\n                var firstCondition = currentState.match(new RegExp('^\\\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\\\s?$', 'i'));\n                if (firstCondition) {\n                    var secondCondition = currentState.match(new RegExp('([_]|^|\\\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\\\s)', 'g'));\n                    if (secondCondition) {\n                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {\n                            var res = item[negate];\n                            if (result.toUpperCase() == result) {\n                                res = res.toUpperCase();\n                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {\n                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);\n                            }\n                            return res;\n                        });\n                        this.insert(reg);\n                        reg = \"\";\n                    }\n                }\n            }\n        }\n    };\n\n    /**\n     * Finds link at defined {row} and {column}\n     * @returns {String}\n     **/\n    this.findLinkAt = function (row, column) {\n        var line = this.session.getLine(row);\n        var wordParts = line.split(/((?:https?|ftp):\\/\\/[\\S]+)/);\n        var columnPosition = column;\n        if (columnPosition < 0) columnPosition = 0;\n        var previousPosition = 0, currentPosition = 0, match;\n        for (let item of wordParts) {\n            currentPosition = previousPosition + item.length;\n            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {\n                if (item.match(/((?:https?|ftp):\\/\\/[\\S]+)/)) {\n                    match = item.replace(/[\\s:.,'\";}\\]]+$/, \"\");\n                    break;\n                }\n            }\n            previousPosition = currentPosition;\n        }\n        return match;\n    };\n\n    /**\n     * Open valid url under cursor in another tab\n     * @returns {Boolean}\n     **/\n    this.openLink = function () {\n        var cursor =  this.selection.getCursor();\n        var url = this.findLinkAt(cursor.row, cursor.column);\n        if (url)\n            window.open(url, '_blank');\n        return url != null;\n    };\n\n    /**\n     * Removes all the lines in the current selection\n     * @related EditSession.remove\n     **/\n    this.removeLines = function() {\n        var rows = this.$getSelectedRows();\n        this.session.removeFullLines(rows.first, rows.last);\n        this.clearSelection();\n    };\n\n    this.duplicateSelection = function() {\n        var sel = this.selection;\n        var doc = this.session;\n        var range = sel.getRange();\n        var reverse = sel.isBackwards();\n        if (range.isEmpty()) {\n            var row = range.start.row;\n            doc.duplicateLines(row, row);\n        } else {\n            var point = reverse ? range.start : range.end;\n            var endPoint = doc.insert(point, doc.getTextRange(range), false);\n            range.start = point;\n            range.end = endPoint;\n\n            sel.setSelectionRange(range, reverse);\n        }\n    };\n\n    /**\n     * Shifts all the selected lines down one row.\n     *\n     * @returns {Number} On success, it returns -1.\n     * @related EditSession.moveLinesUp\n     **/\n    this.moveLinesDown = function() {\n        this.$moveLines(1, false);\n    };\n\n    /**\n     * Shifts all the selected lines up one row.\n     * @returns {Number} On success, it returns -1.\n     * @related EditSession.moveLinesDown\n     **/\n    this.moveLinesUp = function() {\n        this.$moveLines(-1, false);\n    };\n\n    /**\n     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n     * ```json\n     *    { row: newRowLocation, column: newColumnLocation }\n     * ```\n     * @param {Range} fromRange The range of text you want moved within the document\n     * @param {Object} toPosition The location (row and column) where you want to move the text to\n     *\n     * @returns {Range} The new range where the text was moved to.\n     * @related EditSession.moveText\n     **/\n    this.moveText = function(range, toPosition, copy) {\n        return this.session.moveText(range, toPosition, copy);\n    };\n\n    /**\n     * Copies all the selected lines up one row.\n     * @returns {Number} On success, returns 0.\n     *\n     **/\n    this.copyLinesUp = function() {\n        this.$moveLines(-1, true);\n    };\n\n    /**\n     * Copies all the selected lines down one row.\n     * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.\n     * @related EditSession.duplicateLines\n     *\n     **/\n    this.copyLinesDown = function() {\n        this.$moveLines(1, true);\n    };\n\n    /**\n     * for internal use\n     * @ignore\n     *\n     **/\n    this.$moveLines = function(dir, copy) {\n        var rows, moved;\n        var selection = this.selection;\n        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {\n            var range = selection.toOrientedRange();\n            rows = this.$getSelectedRows(range);\n            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);\n            if (copy && dir == -1) moved = 0;\n            range.moveBy(moved, 0);\n            selection.fromOrientedRange(range);\n        } else {\n            var ranges = selection.rangeList.ranges;\n            selection.rangeList.detach(this.session);\n            this.inVirtualSelectionMode = true;\n            \n            var diff = 0;\n            var totalDiff = 0;\n            var l = ranges.length;\n            for (var i = 0; i < l; i++) {\n                var rangeIndex = i;\n                ranges[i].moveBy(diff, 0);\n                rows = this.$getSelectedRows(ranges[i]);\n                var first = rows.first;\n                var last = rows.last;\n                while (++i < l) {\n                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);\n                    var subRows = this.$getSelectedRows(ranges[i]);\n                    if (copy && subRows.first != last)\n                        break;\n                    else if (!copy && subRows.first > last + 1)\n                        break;\n                    last = subRows.last;\n                }\n                i--;\n                diff = this.session.$moveLines(first, last, copy ? 0 : dir);\n                if (copy && dir == -1) rangeIndex = i + 1;\n                while (rangeIndex <= i) {\n                    ranges[rangeIndex].moveBy(diff, 0);\n                    rangeIndex++;\n                }\n                if (!copy) diff = 0;\n                totalDiff += diff;\n            }\n            \n            selection.fromOrientedRange(selection.ranges[0]);\n            selection.rangeList.attach(this.session);\n            this.inVirtualSelectionMode = false;\n        }\n    };\n\n    /**\n     * Returns an object indicating the currently selected rows. The object looks like this:\n     *\n     * ```json\n     * { first: range.start.row, last: range.end.row }\n     * ```\n     *\n     * @returns {Object}\n     **/\n    this.$getSelectedRows = function(range) {\n        range = (range || this.getSelectionRange()).collapseRows();\n\n        return {\n            first: this.session.getRowFoldStart(range.start.row),\n            last: this.session.getRowFoldEnd(range.end.row)\n        };\n    };\n\n    this.onCompositionStart = function(compositionState) {\n        this.renderer.showComposition(compositionState);\n    };\n\n    this.onCompositionUpdate = function(text) {\n        this.renderer.setCompositionText(text);\n    };\n\n    this.onCompositionEnd = function() {\n        this.renderer.hideComposition();\n    };\n\n    /**\n     * {:VirtualRenderer.getFirstVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getFirstVisibleRow\n     **/\n    this.getFirstVisibleRow = function() {\n        return this.renderer.getFirstVisibleRow();\n    };\n\n    /**\n     * {:VirtualRenderer.getLastVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getLastVisibleRow\n     **/\n    this.getLastVisibleRow = function() {\n        return this.renderer.getLastVisibleRow();\n    };\n\n    /**\n     * Indicates if the row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     * @returns {Boolean}\n     **/\n    this.isRowVisible = function(row) {\n        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());\n    };\n\n    /**\n     * Indicates if the entire row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     *\n     * @returns {Boolean}\n     **/\n    this.isRowFullyVisible = function(row) {\n        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());\n    };\n\n    /**\n     * Returns the number of currently visible rows.\n     * @returns {Number}\n     **/\n    this.$getVisibleRowCount = function() {\n        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;\n    };\n\n    this.$moveByPage = function(dir, select) {\n        var renderer = this.renderer;\n        var config = this.renderer.layerConfig;\n        var rows = dir * Math.floor(config.height / config.lineHeight);\n\n        if (select === true) {\n            this.selection.$moveSelection(function(){\n                this.moveCursorBy(rows, 0);\n            });\n        } else if (select === false) {\n            this.selection.moveCursorBy(rows, 0);\n            this.selection.clearSelection();\n        }\n\n        var scrollTop = renderer.scrollTop;\n\n        renderer.scrollBy(0, rows * config.lineHeight);\n        if (select != null)\n            renderer.scrollCursorIntoView(null, 0.5);\n\n        renderer.animateScrolling(scrollTop);\n    };\n\n    /**\n     * Selects the text from the current position of the document until where a \"page down\" finishes.\n     **/\n    this.selectPageDown = function() {\n        this.$moveByPage(1, true);\n    };\n\n    /**\n     * Selects the text from the current position of the document until where a \"page up\" finishes.\n     **/\n    this.selectPageUp = function() {\n        this.$moveByPage(-1, true);\n    };\n\n    /**\n     * Shifts the document to wherever \"page down\" is, as well as moving the cursor position.\n     **/\n    this.gotoPageDown = function() {\n       this.$moveByPage(1, false);\n    };\n\n    /**\n     * Shifts the document to wherever \"page up\" is, as well as moving the cursor position.\n     **/\n    this.gotoPageUp = function() {\n        this.$moveByPage(-1, false);\n    };\n\n    /**\n     * Scrolls the document to wherever \"page down\" is, without changing the cursor position.\n     **/\n    this.scrollPageDown = function() {\n        this.$moveByPage(1);\n    };\n\n    /**\n     * Scrolls the document to wherever \"page up\" is, without changing the cursor position.\n     **/\n    this.scrollPageUp = function() {\n        this.$moveByPage(-1);\n    };\n\n    /**\n     * Moves the editor to the specified row.\n     * @related VirtualRenderer.scrollToRow\n     **/\n    this.scrollToRow = function(row) {\n        this.renderer.scrollToRow(row);\n    };\n\n    /**\n     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).\n     * @param {Number} line The line to scroll to\n     * @param {Boolean} center If `true`\n     * @param {Boolean} animate If `true` animates scrolling\n     * @param {Function} callback Function to be called when the animation has finished\n     *\n     *\n     * @related VirtualRenderer.scrollToLine\n     **/\n    this.scrollToLine = function(line, center, animate, callback) {\n        this.renderer.scrollToLine(line, center, animate, callback);\n    };\n\n    /**\n     * Attempts to center the current selection on the screen.\n     **/\n    this.centerSelection = function() {\n        var range = this.getSelectionRange();\n        var pos = {\n            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),\n            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)\n        };\n        this.renderer.alignCursor(pos, 0.5);\n    };\n\n    /**\n     * Gets the current position of the cursor.\n     * @returns {Object} An object that looks something like this:\n     *\n     * ```json\n     * { row: currRow, column: currCol }\n     * ```\n     *\n     * @related Selection.getCursor\n     **/\n    this.getCursorPosition = function() {\n        return this.selection.getCursor();\n    };\n\n    /**\n     * Returns the screen position of the cursor.\n     * @returns {Number}\n     * @related EditSession.documentToScreenPosition\n     **/\n    this.getCursorPositionScreen = function() {\n        return this.session.documentToScreenPosition(this.getCursorPosition());\n    };\n\n    /**\n     * {:Selection.getRange}\n     * @returns {Range}\n     * @related Selection.getRange\n     **/\n    this.getSelectionRange = function() {\n        return this.selection.getRange();\n    };\n\n\n    /**\n     * Selects all the text in editor.\n     * @related Selection.selectAll\n     **/\n    this.selectAll = function() {\n        this.selection.selectAll();\n    };\n\n    /**\n     * {:Selection.clearSelection}\n     * @related Selection.clearSelection\n     **/\n    this.clearSelection = function() {\n        this.selection.clearSelection();\n    };\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     *\n     *\n     * @related Selection.moveCursorTo\n     **/\n    this.moveCursorTo = function(row, column) {\n        this.selection.moveCursorTo(row, column);\n    };\n\n    /**\n     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.\n     * @param {Object} pos An object with two properties, row and column\n     *\n     *\n     * @related Selection.moveCursorToPosition\n     **/\n    this.moveCursorToPosition = function(pos) {\n        this.selection.moveCursorToPosition(pos);\n    };\n\n    /**\n     * Moves the cursor's row and column to the next matching bracket or HTML tag.\n     *\n     **/\n    this.jumpToMatching = function (select, expand) {\n        var cursor = this.getCursorPosition();\n        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);\n        var prevToken = iterator.getCurrentToken();\n        var tokenCount = 0;\n        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {\n            prevToken = iterator.stepBackward();\n        }\n        var token = prevToken || iterator.stepForward();\n\n        if (!token) return;\n\n        //get next closing tag or bracket\n        var matchType;\n        var found = false;\n        var depth = {};\n        var i = cursor.column - token.start;\n        var bracketType;\n        var brackets = {\n            \")\": \"(\",\n            \"(\": \"(\",\n            \"]\": \"[\",\n            \"[\": \"[\",\n            \"{\": \"{\",\n            \"}\": \"{\"\n        };\n\n        do {\n            if (token.value.match(/[{}()\\[\\]]/g)) {\n                for (; i < token.value.length && !found; i++) {\n                    if (!brackets[token.value[i]]) {\n                        continue;\n                    }\n\n                    bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n\n                    if (isNaN(depth[bracketType])) {\n                        depth[bracketType] = 0;\n                    }\n\n                    switch (token.value[i]) {\n                        case '(':\n                        case '[':\n                        case '{':\n                            depth[bracketType]++;\n                            break;\n                        case ')':\n                        case ']':\n                        case '}':\n                            depth[bracketType]--;\n\n                            if (depth[bracketType] === -1) {\n                                matchType = 'bracket';\n                                found = true;\n                            }\n                            break;\n                    }\n                }\n            }\n            else if (token.type.indexOf('tag-name') !== -1) {\n                if (isNaN(depth[token.value])) {\n                    depth[token.value] = 0;\n                }\n\n                if (prevToken.value === '<' && tokenCount > 1) {\n                    depth[token.value]++;\n                }\n                else if (prevToken.value === '</') {\n                    depth[token.value]--;\n                }\n\n                if (depth[token.value] === -1) {\n                    matchType = 'tag';\n                    found = true;\n                }\n            }\n\n            if (!found) {\n                prevToken = token;\n                tokenCount++;\n                token = iterator.stepForward();\n                i = 0;\n            }\n        } while (token && !found);\n\n        //no match found\n        if (!matchType) return;\n\n        var range, pos;\n        if (matchType === 'bracket') {\n            range = this.session.getBracketRange(cursor);\n            if (!range) {\n                range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1,\n                    iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1\n                );\n                pos = range.start;\n                if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column)\n                    < 2) range = this.session.getBracketRange(pos);\n            }\n        }\n        else if (matchType === 'tag') {\n            if (!token || token.type.indexOf('tag-name') === -1) return;\n            range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2,\n                iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2\n            );\n\n            //find matching tag\n            if (range.compare(cursor.row, cursor.column) === 0) {\n                var tagsRanges = this.session.getMatchingTags(cursor);\n                if (tagsRanges) {\n                    if (tagsRanges.openTag.contains(cursor.row, cursor.column)) {\n                        range = tagsRanges.closeTag;\n                        pos = range.start;\n                    }\n                    else {\n                        range = tagsRanges.openTag;\n                        if (tagsRanges.closeTag.start.row === cursor.row && tagsRanges.closeTag.start.column\n                            === cursor.column) pos = range.end; else pos = range.start;\n                    }\n                }\n            }\n\n            //we found it\n            pos = pos || range.start;\n        }\n\n        pos = range && range.cursor || pos;\n        if (pos) {\n            if (select) {\n                if (range && expand) {\n                    this.selection.setRange(range);\n                }\n                else if (range && range.isEqual(this.getSelectionRange())) {\n                    this.clearSelection();\n                }\n                else {\n                    this.selection.selectTo(pos.row, pos.column);\n                }\n            }\n            else {\n                this.selection.moveTo(pos.row, pos.column);\n            }\n        }\n    };\n\n    /**\n     * Moves the cursor to the specified line number, and also into the indicated column.\n     * @param {Number} lineNumber The line number to go to\n     * @param {Number} column A column number to go to\n     * @param {Boolean} animate If `true` animates scolling\n     *\n     **/\n    this.gotoLine = function(lineNumber, column, animate) {\n        this.selection.clearSelection();\n        this.session.unfold({row: lineNumber - 1, column: column || 0});\n\n        // todo: find a way to automatically exit multiselect mode\n        this.exitMultiSelectMode && this.exitMultiSelectMode();\n        this.moveCursorTo(lineNumber - 1, column || 0);\n\n        if (!this.isRowFullyVisible(lineNumber - 1))\n            this.scrollToLine(lineNumber - 1, true, animate);\n    };\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     *\n     *\n     * @related Editor.moveCursorTo\n     **/\n    this.navigateTo = function(row, column) {\n        this.selection.moveTo(row, column);\n    };\n\n    /**\n     * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    this.navigateUp = function(times) {\n        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {\n            var selectionStart = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionStart);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(-times || -1, 0);\n    };\n\n    /**\n     * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    this.navigateDown = function(times) {\n        if (this.selection.isMultiLine() && this.selection.isBackwards()) {\n            var selectionEnd = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionEnd);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(times || 1, 0);\n    };\n\n    /**\n     * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    this.navigateLeft = function(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionStart = this.getSelectionRange().start;\n            this.moveCursorToPosition(selectionStart);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorLeft();\n            }\n        }\n        this.clearSelection();\n    };\n\n    /**\n     * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    this.navigateRight = function(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionEnd = this.getSelectionRange().end;\n            this.moveCursorToPosition(selectionEnd);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorRight();\n            }\n        }\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the start of the current line. Note that this does de-select the current selection.\n     **/\n    this.navigateLineStart = function() {\n        this.selection.moveCursorLineStart();\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the end of the current line. Note that this does de-select the current selection.\n     **/\n    this.navigateLineEnd = function() {\n        this.selection.moveCursorLineEnd();\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the end of the current file. Note that this does de-select the current selection.\n     **/\n    this.navigateFileEnd = function() {\n        this.selection.moveCursorFileEnd();\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the start of the current file. Note that this does de-select the current selection.\n     **/\n    this.navigateFileStart = function() {\n        this.selection.moveCursorFileStart();\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.\n     **/\n    this.navigateWordRight = function() {\n        this.selection.moveCursorWordRight();\n        this.clearSelection();\n    };\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.\n     **/\n    this.navigateWordLeft = function() {\n        this.selection.moveCursorWordLeft();\n        this.clearSelection();\n    };\n\n    /**\n     * Replaces the first occurrence of `options.needle` with the value in `replacement`.\n     * @param {String} replacement The text to replace with\n     * @param {Object} options The [[Search `Search`]] options to use\n     *\n     *\n     **/\n    this.replace = function(replacement, options) {\n        if (options)\n            this.$search.set(options);\n\n        var range = this.$search.find(this.session);\n        var replaced = 0;\n        if (!range)\n            return replaced;\n\n        if (this.$tryReplace(range, replacement)) {\n            replaced = 1;\n        }\n\n        this.selection.setSelectionRange(range);\n        this.renderer.scrollSelectionIntoView(range.start, range.end);\n\n        return replaced;\n    };\n\n    /**\n     * Replaces all occurrences of `options.needle` with the value in `replacement`.\n     * @param {String} replacement The text to replace with\n     * @param {Object} options The [[Search `Search`]] options to use\n     *\n     *\n     **/\n    this.replaceAll = function(replacement, options) {\n        if (options) {\n            this.$search.set(options);\n        }\n\n        var ranges = this.$search.findAll(this.session);\n        var replaced = 0;\n        if (!ranges.length)\n            return replaced;\n\n        var selection = this.getSelectionRange();\n        this.selection.moveTo(0, 0);\n\n        for (var i = ranges.length - 1; i >= 0; --i) {\n            if(this.$tryReplace(ranges[i], replacement)) {\n                replaced++;\n            }\n        }\n\n        this.selection.setSelectionRange(selection);\n\n        return replaced;\n    };\n\n    this.$tryReplace = function(range, replacement) {\n        var input = this.session.getTextRange(range);\n        replacement = this.$search.replace(input, replacement);\n        if (replacement !== null) {\n            range.end = this.session.replace(range, replacement);\n            return range;\n        } else {\n            return null;\n        }\n    };\n\n    /**\n     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].\n     * @related Search.getOptions\n     * @returns {Object}\n     **/\n    this.getLastSearchOptions = function() {\n        return this.$search.getOptions();\n    };\n\n    /**\n     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].\n     * @param {String} needle The text to search for (optional)\n     * @param {Object} options An object defining various search properties\n     * @param {Boolean} animate If `true` animate scrolling\n     *\n     *\n     * @related Search.find\n     **/\n    this.find = function(needle, options, animate) {\n        if (!options)\n            options = {};\n\n        if (typeof needle == \"string\" || needle instanceof RegExp)\n            options.needle = needle;\n        else if (typeof needle == \"object\")\n            oop.mixin(options, needle);\n\n        var range = this.selection.getRange();\n        if (options.needle == null) {\n            needle = this.session.getTextRange(range)\n                || this.$search.$options.needle;\n            if (!needle) {\n                range = this.session.getWordRange(range.start.row, range.start.column);\n                needle = this.session.getTextRange(range);\n            }\n            this.$search.set({needle: needle});\n        }\n\n        this.$search.set(options);\n        if (!options.start)\n            this.$search.set({start: range});\n\n        var newRange = this.$search.find(this.session);\n        if (options.preventScroll)\n            return newRange;\n        if (newRange) {\n            this.revealRange(newRange, animate);\n            return newRange;\n        }\n        // clear selection if nothing is found\n        if (options.backwards)\n            range.start = range.end;\n        else\n            range.end = range.start;\n        this.selection.setRange(range);\n    };\n\n    /**\n     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].\n     * @param {Object} options search options\n     * @param {Boolean} animate If `true` animate scrolling\n     *\n     *\n     * @related Editor.find\n     **/\n    this.findNext = function(options, animate) {\n        this.find({skipCurrent: true, backwards: false}, options, animate);\n    };\n\n    /**\n     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].\n     * @param {Object} options search options\n     * @param {Boolean} animate If `true` animate scrolling\n     *\n     *\n     * @related Editor.find\n     **/\n    this.findPrevious = function(options, animate) {\n        this.find(options, {skipCurrent: true, backwards: true}, animate);\n    };\n\n    this.revealRange = function(range, animate) {\n        this.session.unfold(range);\n        this.selection.setSelectionRange(range);\n\n        var scrollTop = this.renderer.scrollTop;\n        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n        if (animate !== false)\n            this.renderer.animateScrolling(scrollTop);\n    };\n\n    /**\n     * {:UndoManager.undo}\n     * @related UndoManager.undo\n     **/\n    this.undo = function() {\n        this.session.getUndoManager().undo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    };\n\n    /**\n     * {:UndoManager.redo}\n     * @related UndoManager.redo\n     **/\n    this.redo = function() {\n        this.session.getUndoManager().redo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    };\n\n    /**\n     *\n     * Cleans up the entire editor.\n     **/\n    this.destroy = function() {\n        if (this.$toDestroy) {\n            this.$toDestroy.forEach(function(el) {\n                el.destroy();\n            });\n            this.$toDestroy = null;\n        }\n        if (this.$mouseHandler)\n            this.$mouseHandler.destroy();\n        this.renderer.destroy();\n        this._signal(\"destroy\", this);\n        if (this.session)\n            this.session.destroy();\n        if (this._$emitInputEvent)\n            this._$emitInputEvent.cancel();\n        this.removeAllListeners();\n    };\n\n    /**\n     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element\n     * @param {Boolean} enable default true\n     **/\n    this.setAutoScrollEditorIntoView = function(enable) {\n        if (!enable)\n            return;\n        var rect;\n        var self = this;\n        var shouldScroll = false;\n        if (!this.$scrollAnchor)\n            this.$scrollAnchor = document.createElement(\"div\");\n        var scrollAnchor = this.$scrollAnchor;\n        scrollAnchor.style.cssText = \"position:absolute\";\n        this.container.insertBefore(scrollAnchor, this.container.firstChild);\n        var onChangeSelection = this.on(\"changeSelection\", function() {\n            shouldScroll = true;\n        });\n        // needed to not trigger sync reflow\n        var onBeforeRender = this.renderer.on(\"beforeRender\", function() {\n            if (shouldScroll)\n                rect = self.renderer.container.getBoundingClientRect();\n        });\n        var onAfterRender = this.renderer.on(\"afterRender\", function() {\n            if (shouldScroll && rect && (self.isFocused()\n                || self.searchBox && self.searchBox.isFocused())\n            ) {\n                var renderer = self.renderer;\n                var pos = renderer.$cursorLayer.$pixelPos;\n                var config = renderer.layerConfig;\n                var top = pos.top - config.offset;\n                if (pos.top >= 0 && top + rect.top < 0) {\n                    shouldScroll = true;\n                } else if (pos.top < config.height &&\n                    pos.top + rect.top + config.lineHeight > window.innerHeight) {\n                    shouldScroll = false;\n                } else {\n                    shouldScroll = null;\n                }\n                if (shouldScroll != null) {\n                    scrollAnchor.style.top = top + \"px\";\n                    scrollAnchor.style.left = pos.left + \"px\";\n                    scrollAnchor.style.height = config.lineHeight + \"px\";\n                    scrollAnchor.scrollIntoView(shouldScroll);\n                }\n                shouldScroll = rect = null;\n            }\n        });\n        this.setAutoScrollEditorIntoView = function(enable) {\n            if (enable)\n                return;\n            delete this.setAutoScrollEditorIntoView;\n            this.off(\"changeSelection\", onChangeSelection);\n            this.renderer.off(\"afterRender\", onAfterRender);\n            this.renderer.off(\"beforeRender\", onBeforeRender);\n        };\n    };\n\n\n    this.$resetCursorStyle = function() {\n        var style = this.$cursorStyle || \"ace\";\n        var cursorLayer = this.renderer.$cursorLayer;\n        if (!cursorLayer)\n            return;\n        cursorLayer.setSmoothBlinking(/smooth/.test(style));\n        cursorLayer.isBlinking = !this.$readOnly && style != \"wide\";\n        dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n    };\n\n    /**\n     * opens a prompt displaying message\n     **/\n    this.prompt = function(message, options, callback) {\n        var editor = this;\n        config.loadModule(\"ace/ext/prompt\", function (module) {\n            module.prompt(editor, message, options, callback);\n        });\n    };\n\n}).call(Editor.prototype);\n\n\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    selectionStyle: {\n        set: function(style) {\n            this.onSelectionChange();\n            this._signal(\"changeSelectionStyle\", {data: style});\n        },\n        initialValue: \"line\"\n    },\n    highlightActiveLine: {\n        set: function() {this.$updateHighlightActiveLine();},\n        initialValue: true\n    },\n    highlightSelectedWord: {\n        set: function(shouldHighlight) {this.$onSelectionChange();},\n        initialValue: true\n    },\n    readOnly: {\n        set: function(readOnly) {\n            this.textInput.setReadOnly(readOnly);\n            this.$resetCursorStyle(); \n        },\n        initialValue: false\n    },\n    copyWithEmptySelection: {\n        set: function(value) {\n            this.textInput.setCopyWithEmptySelection(value);\n        },\n        initialValue: false\n    },\n    cursorStyle: {\n        set: function(val) { this.$resetCursorStyle(); },\n        values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n        initialValue: \"ace\"\n    },\n    mergeUndoDeltas: {\n        values: [false, true, \"always\"],\n        initialValue: true\n    },\n    behavioursEnabled: {initialValue: true},\n    wrapBehavioursEnabled: {initialValue: true},\n    enableAutoIndent: {initialValue: true},\n    autoScrollEditorIntoView: {\n        set: function(val) {this.setAutoScrollEditorIntoView(val);}\n    },\n    keyboardHandler: {\n        set: function(val) { this.setKeyboardHandler(val); },\n        get: function() { return this.$keybindingId; },\n        handlesSet: true\n    },\n    value: {\n        set: function(val) { this.session.setValue(val); },\n        get: function() { return this.getValue(); },\n        handlesSet: true,\n        hidden: true\n    },\n    session: {\n        set: function(val) { this.setSession(val); },\n        get: function() { return this.session; },\n        handlesSet: true,\n        hidden: true\n    },\n    \n    showLineNumbers: {\n        set: function(show) {\n            this.renderer.$gutterLayer.setShowLineNumbers(show);\n            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);\n            if (show && this.$relativeLineNumbers)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        },\n        initialValue: true\n    },\n    relativeLineNumbers: {\n        set: function(value) {\n            if (this.$showLineNumbers && value)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        }\n    },\n    placeholder: {\n        set: function(message) {\n            if (!this.$updatePlaceholder) {\n                this.$updatePlaceholder = function() {\n                    var value = this.session && (this.renderer.$composition || this.getValue());\n                    if (value && this.renderer.placeholderNode) {\n                        this.renderer.off(\"afterRender\", this.$updatePlaceholder);\n                        dom.removeCssClass(this.container, \"ace_hasPlaceholder\");\n                        this.renderer.placeholderNode.remove();\n                        this.renderer.placeholderNode = null;\n                    } else if (!value && !this.renderer.placeholderNode) {\n                        this.renderer.on(\"afterRender\", this.$updatePlaceholder);\n                        dom.addCssClass(this.container, \"ace_hasPlaceholder\");\n                        var el = dom.createElement(\"div\");\n                        el.className = \"ace_placeholder\";\n                        el.textContent = this.$placeholder || \"\";\n                        this.renderer.placeholderNode = el;\n                        this.renderer.content.appendChild(this.renderer.placeholderNode);\n                    } else if (!value && this.renderer.placeholderNode) {\n                        this.renderer.placeholderNode.textContent = this.$placeholder || \"\";\n                    }\n                }.bind(this);\n                this.on(\"input\", this.$updatePlaceholder);\n            }\n            this.$updatePlaceholder();\n        }\n    },\n    customScrollbar: \"renderer\",\n    hScrollBarAlwaysVisible: \"renderer\",\n    vScrollBarAlwaysVisible: \"renderer\",\n    highlightGutterLine: \"renderer\",\n    animatedScroll: \"renderer\",\n    showInvisibles: \"renderer\",\n    showPrintMargin: \"renderer\",\n    printMarginColumn: \"renderer\",\n    printMargin: \"renderer\",\n    fadeFoldWidgets: \"renderer\",\n    showFoldWidgets: \"renderer\",\n    displayIndentGuides: \"renderer\",\n    highlightIndentGuides: \"renderer\",\n    showGutter: \"renderer\",\n    fontSize: \"renderer\",\n    fontFamily: \"renderer\",\n    maxLines: \"renderer\",\n    minLines: \"renderer\",\n    scrollPastEnd: \"renderer\",\n    fixedWidthGutter: \"renderer\",\n    theme: \"renderer\",\n    hasCssTransforms: \"renderer\",\n    maxPixelHeight: \"renderer\",\n    useTextareaForIME: \"renderer\",\n\n    scrollSpeed: \"$mouseHandler\",\n    dragDelay: \"$mouseHandler\",\n    dragEnabled: \"$mouseHandler\",\n    focusTimeout: \"$mouseHandler\",\n    tooltipFollowsMouse: \"$mouseHandler\",\n\n    firstLineNumber: \"session\",\n    overwrite: \"session\",\n    newLineMode: \"session\",\n    useWorker: \"session\",\n    useSoftTabs: \"session\",\n    navigateWithinSoftTabs: \"session\",\n    tabSize: \"session\",\n    wrap: \"session\",\n    indentedSoftWrap: \"session\",\n    foldStyle: \"session\",\n    mode: \"session\"\n});\n\n\nvar relativeNumberRenderer = {\n    getText: function(session, row) {\n        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? \"\\xb7\" : \"\"))) + \"\";\n    },\n    getWidth: function(session, lastLineNumber, config) {\n        return Math.max(\n            lastLineNumber.toString().length,\n            (config.lastRow + 1).toString().length,\n            2\n        ) * config.characterWidth;\n    },\n    update: function(e, editor) {\n        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);\n    },\n    attach: function(editor) {\n        editor.renderer.$gutterLayer.$renderer = this;\n        editor.on(\"changeSelection\", this.update);\n        this.update(null, editor);\n    },\n    detach: function(editor) {\n        if (editor.renderer.$gutterLayer.$renderer == this)\n            editor.renderer.$gutterLayer.$renderer = null;\n        editor.off(\"changeSelection\", this.update);\n        this.update(null, editor);\n    }\n};\n\nexports.Editor = Editor;\n"
  },
  {
    "path": "demo/diff/examples/editor.17.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar useragent = require(\"./lib/useragent\");\nvar TextInput = require(\"./keyboard/textinput\").TextInput;\nvar MouseHandler = require(\"./mouse/mouse_handler\").MouseHandler;\nvar FoldHandler = require(\"./mouse/fold_handler\").FoldHandler;\nvar KeyBinding = require(\"./keyboard/keybinding\").KeyBinding;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Search = require(\"./search\").Search;\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar CommandManager = require(\"./commands/command_manager\").CommandManager;\nvar defaultCommands = require(\"./commands/default_commands\").commands;\nvar config = require(\"./config\");\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\nvar LineWidgets = require(\"./line_widgets\").LineWidgets;\n\nvar clipboard = require(\"./clipboard\");\nvar keys = require('./lib/keys');\n\n/**\n * The main entry point into the Ace functionality.\n *\n * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.\n *\n * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.\n **/\nclass Editor {\n    /**\n     * Creates a new `Editor` object.\n     *\n     * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything\n     * @param {EditSession} session The `EditSession` to refer to\n     **/\n    constructor(renderer, session, options) {\n        this.$toDestroy = [];\n        var container = renderer.getContainerElement();\n        this.container = container;\n        this.renderer = renderer;\n        this.id = \"editor\" + (++Editor.$uid);\n\n        this.commands = new CommandManager(useragent.isMac ? \"mac\" : \"win\", defaultCommands);\n        if (typeof document == \"object\") {\n            this.textInput = new TextInput(renderer.getTextAreaContainer(), this);\n            this.renderer.textarea = this.textInput.getElement();\n            // TODO detect touch event support\n            this.$mouseHandler = new MouseHandler(this);\n            new FoldHandler(this);\n        }\n\n        this.keyBinding = new KeyBinding(this);\n\n        this.$search = new Search().set({\n            wrap: true\n        });\n\n        this.$historyTracker = this.$historyTracker.bind(this);\n        this.commands.on(\"exec\", this.$historyTracker);\n\n        this.$initOperationListeners();\n\n        this._$emitInputEvent = lang.delayedCall(function() {\n            this._signal(\"input\", {});\n            if (this.session && !this.session.destroyed)\n                this.session.bgTokenizer.scheduleStart();\n        }.bind(this));\n\n        this.on(\"change\", function(_, _self) {\n            _self._$emitInputEvent.schedule(31);\n        });\n\n        this.setSession(session || options && options.session || new EditSession(\"\"));\n        config.resetOptions(this);\n        if (options)\n            this.setOptions(options);\n        config._signal(\"editor\", this);\n    }\n\n    $initOperationListeners() {\n        this.commands.on(\"exec\", this.startOperation.bind(this), true);\n        this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n\n        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true));\n        \n        // todo: add before change events?\n        this.on(\"change\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.docChanged = true;\n        }.bind(this), true);\n        \n        this.on(\"changeSelection\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.selectionChanged = true;\n        }.bind(this), true);\n    }\n\n    startOperation(commandEvent) {\n        if (this.curOp) {\n            if (!commandEvent || this.curOp.command)\n                return;\n            this.prevOp = this.curOp;\n        }\n        if (!commandEvent) {\n            this.previousCommand = null;\n            commandEvent = {};\n        }\n\n        this.$opResetTimer.schedule();\n        this.curOp = this.session.curOp = {\n            command: commandEvent.command || {},\n            args: commandEvent.args,\n            scrollTop: this.renderer.scrollTop\n        };\n        this.curOp.selectionBefore = this.selection.toJSON();\n    }\n\n    endOperation(e) {\n        if (this.curOp && this.session) {\n            if (e && e.returnValue === false || !this.session)\n                return (this.curOp = null);\n            if (e == true && this.curOp.command && this.curOp.command.name == \"mouse\")\n                return;\n            this._signal(\"beforeEndOperation\");\n            if (!this.curOp) return;\n            var command = this.curOp.command;\n            var scrollIntoView = command && command.scrollIntoView;\n            if (scrollIntoView) {\n                switch (scrollIntoView) {\n                    case \"center-animate\":\n                        scrollIntoView = \"animate\";\n                        /* fall through */\n                    case \"center\":\n                        this.renderer.scrollCursorIntoView(null, 0.5);\n                        break;\n                    case \"animate\":\n                    case \"cursor\":\n                        this.renderer.scrollCursorIntoView();\n                        break;\n                    case \"selectionPart\":\n                        var range = this.selection.getRange();\n                        var config = this.renderer.layerConfig;\n                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {\n                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);\n                        }\n                        break;\n                    default:\n                        break;\n                }\n                if (scrollIntoView == \"animate\")\n                    this.renderer.animateScrolling(this.curOp.scrollTop);\n            }\n            var sel = this.selection.toJSON();\n            this.curOp.selectionAfter = sel;\n            this.$lastSel = this.selection.toJSON();\n            \n            // console.log(this.$lastSel+\"  endOP\")\n            this.session.getUndoManager().addSelection(sel);\n            this.prevOp = this.curOp;\n            this.curOp = null;\n        }\n    }\n    \n    $historyTracker(e) {\n        if (!this.$mergeUndoDeltas)\n            return;\n\n        var prev = this.prevOp;\n        var mergeableCommands = this.$mergeableCommands;\n        // previous command was the same\n        var shouldMerge = prev.command && (e.command.name == prev.command.name);\n        if (e.command.name == \"insertstring\") {\n            var text = e.args;\n            if (this.mergeNextCommand === undefined)\n                this.mergeNextCommand = true;\n\n            shouldMerge = shouldMerge\n                && this.mergeNextCommand // previous command allows to coalesce with\n                && (!/\\s/.test(text) || /\\s/.test(prev.args)); // previous insertion was of same type\n\n            this.mergeNextCommand = true;\n        } else {\n            shouldMerge = shouldMerge\n                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n        }\n\n        if (\n            this.$mergeUndoDeltas != \"always\"\n            && Date.now() - this.sequenceStartTime > 2000\n        ) {\n            shouldMerge = false; // the sequence is too long\n        }\n\n        if (shouldMerge)\n            this.session.mergeUndoDeltas = true;\n        else if (mergeableCommands.indexOf(e.command.name) !== -1)\n            this.sequenceStartTime = Date.now();\n    }\n\n    /**\n     * Sets a new key handler, such as \"vim\" or \"windows\".\n     * @param {String} keyboardHandler The new key handler\n     *\n     **/\n    setKeyboardHandler(keyboardHandler, cb) {\n        if (keyboardHandler && typeof keyboardHandler === \"string\" && keyboardHandler != \"ace\") {\n            this.$keybindingId = keyboardHandler;\n            var _self = this;\n            config.loadModule([\"keybinding\", keyboardHandler], function(module) {\n                if (_self.$keybindingId == keyboardHandler)\n                    _self.keyBinding.setKeyboardHandler(module && module.handler);\n                cb && cb();\n            });\n        } else {\n            this.$keybindingId = null;\n            this.keyBinding.setKeyboardHandler(keyboardHandler);\n            cb && cb();\n        }\n    }\n\n    /**\n     * Returns the keyboard handler, such as \"vim\" or \"windows\".\n     *\n     * @returns {String}\n     *\n     **/\n    getKeyboardHandler() {\n        return this.keyBinding.getKeyboardHandler();\n    }\n\n\n    /**\n     * Emitted whenever the [[EditSession]] changes.\n     * @event changeSession\n     * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s.\n     *\n     **/\n    /**\n     * Sets a new editsession to use. This method also emits the `'changeSession'` event.\n     * @param {EditSession} session The new session to use\n     *\n     **/\n    setSession(session) {\n        if (this.session == session)\n            return;\n        \n        // make sure operationEnd events are not emitted to wrong session\n        if (this.curOp) this.endOperation();\n        this.curOp = {};\n\n        var oldSession = this.session;\n        if (oldSession) {\n            this.session.off(\"change\", this.$onDocumentChange);\n            this.session.off(\"changeMode\", this.$onChangeMode);\n            this.session.off(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n            this.session.off(\"changeTabSize\", this.$onChangeTabSize);\n            this.session.off(\"changeWrapLimit\", this.$onChangeWrapLimit);\n            this.session.off(\"changeWrapMode\", this.$onChangeWrapMode);\n            this.session.off(\"changeFold\", this.$onChangeFold);\n            this.session.off(\"changeFrontMarker\", this.$onChangeFrontMarker);\n            this.session.off(\"changeBackMarker\", this.$onChangeBackMarker);\n            this.session.off(\"changeBreakpoint\", this.$onChangeBreakpoint);\n            this.session.off(\"changeAnnotation\", this.$onChangeAnnotation);\n            this.session.off(\"changeOverwrite\", this.$onCursorChange);\n            this.session.off(\"changeScrollTop\", this.$onScrollTopChange);\n            this.session.off(\"changeScrollLeft\", this.$onScrollLeftChange);\n\n            var selection = this.session.getSelection();\n            selection.off(\"changeCursor\", this.$onCursorChange);\n            selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n\n        this.session = session;\n        if (session) {\n            this.$onDocumentChange = this.onDocumentChange.bind(this);\n            session.on(\"change\", this.$onDocumentChange);\n            this.renderer.setSession(session);\n    \n            this.$onChangeMode = this.onChangeMode.bind(this);\n            session.on(\"changeMode\", this.$onChangeMode);\n    \n            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n            session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n    \n            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n            session.on(\"changeTabSize\", this.$onChangeTabSize);\n    \n            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n            session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n    \n            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n            session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n    \n            this.$onChangeFold = this.onChangeFold.bind(this);\n            session.on(\"changeFold\", this.$onChangeFold);\n    \n            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n            this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n    \n            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n            this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n    \n            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n            this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n    \n            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n            this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n    \n            this.$onCursorChange = this.onCursorChange.bind(this);\n            this.session.on(\"changeOverwrite\", this.$onCursorChange);\n    \n            this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n            this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n    \n            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n            this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n    \n            this.selection = session.getSelection();\n            this.selection.on(\"changeCursor\", this.$onCursorChange);\n    \n            this.$onSelectionChange = this.onSelectionChange.bind(this);\n            this.selection.on(\"changeSelection\", this.$onSelectionChange);\n    \n            this.onChangeMode();\n    \n            this.onCursorChange();\n    \n            this.onScrollTopChange();\n            this.onScrollLeftChange();\n            this.onSelectionChange();\n            this.onChangeFrontMarker();\n            this.onChangeBackMarker();\n            this.onChangeBreakpoint();\n            this.onChangeAnnotation();\n            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();\n            this.renderer.updateFull();\n        } else {\n            this.selection = null;\n            this.renderer.setSession(session);\n        }\n\n        this._signal(\"changeSession\", {\n            session: session,\n            oldSession: oldSession\n        });\n        \n        this.curOp = null;\n        \n        oldSession && oldSession._signal(\"changeEditor\", {oldEditor: this});\n        session && session._signal(\"changeEditor\", {editor: this});\n        \n        if (session && !session.destroyed)\n            session.bgTokenizer.scheduleStart();\n    }\n\n    /**\n     * Returns the current session being used.\n     * @returns {EditSession}\n     **/\n    getSession() {\n        return this.session;\n    }\n\n    /**\n     * Sets the current document to `val`.\n     * @param {String} val The new value to set for the document\n     * @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end\n     *\n     * @returns {String} The current document value\n     * @related Document.setValue\n     **/\n    setValue(val, cursorPos) {\n        this.session.doc.setValue(val);\n\n        if (!cursorPos)\n            this.selectAll();\n        else if (cursorPos == 1)\n            this.navigateFileEnd();\n        else if (cursorPos == -1)\n            this.navigateFileStart();\n\n        return val;\n    }\n\n    /**\n     * Returns the current session's content.\n     *\n     * @returns {String}\n     * @related EditSession.getValue\n     **/\n    getValue() {\n        return this.session.getValue();\n    }\n\n    /**\n     *\n     * Returns the currently highlighted selection.\n     * @returns {Selection} The selection object\n     **/\n    getSelection() {\n        return this.selection;\n    }\n\n    /**\n     * {:VirtualRenderer.onResize}\n     * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed\n     *\n     *\n     * @related VirtualRenderer.onResize\n     **/\n    resize(force) {\n        this.renderer.onResize(force);\n    }\n\n    /**\n     * {:VirtualRenderer.setTheme}\n     * @param {String} theme The path to a theme\n     * @param {Function} cb optional callback called when theme is loaded\n     **/\n    setTheme(theme, cb) {\n        this.renderer.setTheme(theme, cb);\n    }\n\n    /**\n     * {:VirtualRenderer.getTheme}\n     *\n     * @returns {String} The set theme\n     * @related VirtualRenderer.getTheme\n     **/\n    getTheme() {\n        return this.renderer.getTheme();\n    }\n\n    /**\n     * {:VirtualRenderer.setStyle}\n     * @param {String} style A class name\n     *\n     *\n     * @related VirtualRenderer.setStyle\n     **/\n    setStyle(style) {\n        this.renderer.setStyle(style);\n    }\n\n    /**\n     * {:VirtualRenderer.unsetStyle}\n     * @related VirtualRenderer.unsetStyle\n     **/\n    unsetStyle(style) {\n        this.renderer.unsetStyle(style);\n    }\n\n    /**\n     * Gets the current font size of the editor text.\n     */\n    getFontSize() {\n        return this.getOption(\"fontSize\") ||\n           dom.computedStyle(this.container).fontSize;\n    }\n\n    /**\n     * Set a new font size (in pixels) for the editor text.\n     * @param {String} size A font size ( _e.g._ \"12px\")\n     *\n     *\n     **/\n    setFontSize(size) {\n        this.setOption(\"fontSize\", size);\n    }\n\n    $highlightBrackets() {\n        if (this.$highlightPending) {\n            return;\n        }\n\n        // perform highlight async to not block the browser during navigation\n        var self = this;\n        this.$highlightPending = true;\n        setTimeout(function () {\n            self.$highlightPending = false;\n            var session = self.session;\n            if (!session || session.destroyed) return;\n            if (session.$bracketHighlight) {\n                session.$bracketHighlight.markerIds.forEach(function(id) {\n                    session.removeMarker(id);\n                });\n                session.$bracketHighlight = null;\n            }\n            var pos = self.getCursorPosition();\n            var handler = self.getKeyboardHandler();\n            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);\n            var ranges = session.getMatchingBracketRanges(pos, isBackwards);\n\n            if (!ranges) {\n                var iterator = new TokenIterator(session, pos.row, pos.column);\n                var token = iterator.getCurrentToken();\n\n                if (token && /\\b(?:tag-open|tag-name)/.test(token.type)) {\n                    var tagNamesRanges = session.getMatchingTags(pos);\n                    if (tagNamesRanges) ranges = [tagNamesRanges.openTagName, tagNamesRanges.closeTagName];\n                }\n            }\n            if (!ranges && session.$mode.getMatching)\n                ranges = session.$mode.getMatching(self.session);\n            if (!ranges) {\n                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n                return;\n            }\n\n            var markerType = \"ace_bracket\";\n            if (!Array.isArray(ranges)) {\n                ranges = [ranges];\n            } else if (ranges.length == 1) {\n                markerType = \"ace_error_bracket\";\n            }\n\n            // show adjacent ranges as one\n            if (ranges.length == 2) {\n                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)\n                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];\n                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)\n                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];\n            }\n\n            session.$bracketHighlight = {\n                ranges: ranges,\n                markerIds: ranges.map(function(range) {\n                    return session.addMarker(range, markerType, \"text\");\n                })\n            };\n            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n        }, 50);\n    }\n\n    /**\n     *\n     * Brings the current `textInput` into focus.\n     **/\n    focus() {\n        this.textInput.focus();\n    }\n\n    /**\n     * Returns `true` if the current `textInput` is in focus.\n     * @return {Boolean}\n     **/\n    isFocused() {\n        return this.textInput.isFocused();\n    }\n\n    /**\n     *\n     * Blurs the current `textInput`.\n     **/\n    blur() {\n        this.textInput.blur();\n    }\n\n    /**\n     * Emitted once the editor comes into focus.\n     * @event focus\n     *\n     *\n     **/\n    onFocus(e) {\n        if (this.$isFocused)\n            return;\n        this.$isFocused = true;\n        this.renderer.showCursor();\n        this.renderer.visualizeFocus();\n        this._emit(\"focus\", e);\n    }\n\n    /**\n     * Emitted once the editor has been blurred.\n     * @event blur\n     *\n     *\n     **/\n    onBlur(e) {\n        if (!this.$isFocused)\n            return;\n        this.$isFocused = false;\n        this.renderer.hideCursor();\n        this.renderer.visualizeBlur();\n        this._emit(\"blur\", e);\n    }\n\n    $cursorChange() {\n        this.renderer.updateCursor();\n        this.$highlightBrackets();\n        this.$updateHighlightActiveLine();\n    }\n\n    /**\n     * Emitted whenever the document is changed.\n     * @event change\n     * @param {Object} delta Contains a single property, `data`, which has the delta of changes\n     *\n     *\n     *\n     **/\n    onDocumentChange(delta) {\n        // Rerender and emit \"change\" event.\n        var wrap = this.session.$useWrapMode;\n        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);\n        this.renderer.updateLines(delta.start.row, lastRow, wrap);\n\n        this._signal(\"change\", delta);\n        \n        // Update cursor because tab characters can influence the cursor position.\n        this.$cursorChange();\n    }\n\n    onTokenizerUpdate(e) {\n        var rows = e.data;\n        this.renderer.updateLines(rows.first, rows.last);\n    }\n\n\n    onScrollTopChange() {\n        this.renderer.scrollToY(this.session.getScrollTop());\n    }\n\n    onScrollLeftChange() {\n        this.renderer.scrollToX(this.session.getScrollLeft());\n    }\n\n    /**\n     * Emitted when the selection changes.\n     *\n     **/\n    onCursorChange() {\n        this.$cursorChange();\n        this._signal(\"changeSelection\");\n    }\n\n    $updateHighlightActiveLine() {\n        var session = this.getSession();\n\n        var highlight;\n        if (this.$highlightActiveLine) {\n            if (this.$selectionStyle != \"line\" || !this.selection.isMultiLine())\n                highlight = this.getCursorPosition();\n            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())\n                highlight = false;\n            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))\n                highlight = false;\n        }\n\n        if (session.$highlightLineMarker && !highlight) {\n            session.removeMarker(session.$highlightLineMarker.id);\n            session.$highlightLineMarker = null;\n        } else if (!session.$highlightLineMarker && highlight) {\n            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);\n            range.id = session.addMarker(range, \"ace_active-line\", \"screenLine\");\n            session.$highlightLineMarker = range;\n        } else if (highlight) {\n            session.$highlightLineMarker.start.row = highlight.row;\n            session.$highlightLineMarker.end.row = highlight.row;\n            session.$highlightLineMarker.start.column = highlight.column;\n            session._signal(\"changeBackMarker\");\n        }\n    }\n\n    onSelectionChange(e) {\n        var session = this.session;\n\n        if (session.$selectionMarker) {\n            session.removeMarker(session.$selectionMarker);\n        }\n        session.$selectionMarker = null;\n\n        if (!this.selection.isEmpty()) {\n            var range = this.selection.getRange();\n            var style = this.getSelectionStyle();\n            session.$selectionMarker = session.addMarker(range, \"ace_selection\", style);\n        } else {\n            this.$updateHighlightActiveLine();\n        }\n\n        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n        this.session.highlight(re);\n\n        this._signal(\"changeSelection\");\n    }\n\n    $getSelectionHighLightRegexp() {\n        var session = this.session;\n\n        var selection = this.getSelectionRange();\n        if (selection.isEmpty() || selection.isMultiLine())\n            return;\n\n        var startColumn = selection.start.column;\n        var endColumn = selection.end.column;\n        var line = session.getLine(selection.start.row);\n        \n        var needle = line.substring(startColumn, endColumn);\n        // maximum allowed size for regular expressions in 32000, \n        // but getting close to it has significant impact on the performance\n        if (needle.length > 5000 || !/[\\w\\d]/.test(needle))\n            return;\n\n        var re = this.$search.$assembleRegExp({\n            wholeWord: true,\n            caseSensitive: true,\n            needle: needle\n        });\n        \n        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);\n        if (!re.test(wordWithBoundary))\n            return;\n        \n        return re;\n    }\n\n\n    onChangeFrontMarker() {\n        this.renderer.updateFrontMarkers();\n    }\n\n    onChangeBackMarker() {\n        this.renderer.updateBackMarkers();\n    }\n\n\n    onChangeBreakpoint() {\n        this.renderer.updateBreakpoints();\n    }\n\n    onChangeAnnotation() {\n        this.renderer.setAnnotations(this.session.getAnnotations());\n    }\n\n\n    onChangeMode (e) {\n        this.renderer.updateText();\n        this._emit(\"changeMode\", e);\n    }\n\n\n    onChangeWrapLimit() {\n        this.renderer.updateFull();\n    }\n\n    onChangeWrapMode() {\n        this.renderer.onResize(true);\n    }\n\n\n    onChangeFold() {\n        // Update the active line marker as due to folding changes the current\n        // line range on the screen might have changed.\n        this.$updateHighlightActiveLine();\n        // TODO: This might be too much updating. Okay for now.\n        this.renderer.updateFull();\n    }\n\n    \n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getSelectedText() {\n        return this.session.getTextRange(this.getSelectionRange());\n    }\n    \n    /**\n     * Emitted when text is copied.\n     * @event copy\n     * @param {String} text The copied text\n     *\n     **/\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getCopyText () {\n        var text = this.getSelectedText();\n        var nl = this.session.doc.getNewLineCharacter();\n        var copyLine= false;\n        if (!text && this.$copyWithEmptySelection) {\n            copyLine = true;\n            var ranges = this.selection.getAllRanges();\n            for (var i = 0; i < ranges.length; i++) {\n                var range = ranges[i];\n                if (i && ranges[i - 1].start.row == range.start.row)\n                    continue;\n                text += this.session.getLine(range.start.row) + nl;\n            }\n        }\n        var e = {text: text};\n        this._signal(\"copy\", e);\n        clipboard.lineMode = copyLine ? e.text : false;\n        return e.text;\n    }\n\n    /**\n     * Called whenever a text \"copy\" happens.\n     **/\n    onCopy() {\n        this.commands.exec(\"copy\", this);\n    }\n\n    /**\n     * Called whenever a text \"cut\" happens.\n     **/\n    onCut() {\n        this.commands.exec(\"cut\", this);\n    }\n\n    /**\n     * Emitted when text is pasted.\n     * @event paste\n     * @param {Object} an object which contains one property, `text`, that represents the text to be pasted. Editing this property will alter the text that is pasted.\n     *\n     *\n     **/\n    /**\n     * Called whenever a text \"paste\" happens.\n     * @param {String} text The pasted text\n     *\n     *\n     **/\n    onPaste(text, event) {\n        var e = {text: text, event: event};\n        this.commands.exec(\"paste\", this, e);\n    }\n    \n    $handlePaste(e) {\n        if (typeof e == \"string\") \n            e = {text: e};\n        this._signal(\"paste\", e);\n        var text = e.text;\n\n        var lineMode = text === clipboard.lineMode;\n        var session = this.session;\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n            if (lineMode)\n                session.insert({ row: this.selection.lead.row, column: 0 }, text);\n            else\n                this.insert(text);\n        } else if (lineMode) {\n            this.selection.rangeList.ranges.forEach(function(range) {\n                session.insert({ row: range.start.row, column: 0 }, text);\n            });\n        } else {\n            var lines = text.split(/\\r\\n|\\r|\\n/);\n            var ranges = this.selection.rangeList.ranges;\n    \n            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);\n            if (lines.length != ranges.length || isFullLine)\n                return this.commands.exec(\"insertstring\", this, text);\n    \n            for (var i = ranges.length; i--;) {\n                var range = ranges[i];\n                if (!range.isEmpty())\n                    session.remove(range);\n    \n                session.insert(range.start, lines[i]);\n            }\n        }\n    }\n\n    execCommand(command, args) {\n        return this.commands.exec(command, this, args);\n    }\n\n    /**\n     * Inserts `text` into wherever the cursor is pointing.\n     * @param {String} text The new text to add\n     *\n     **/\n    insert(text, pasted) {\n        var session = this.session;\n        var mode = session.getMode();\n        var cursor = this.getCursorPosition();\n\n        if (this.getBehavioursEnabled() && !pasted) {\n            // Get a transform if the current mode wants one.\n            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);\n            if (transform) {\n                if (text !== transform.text) {\n                    // keep automatic insertion in a separate delta, unless it is in multiselect mode\n                    if (!this.inVirtualSelectionMode) {\n                        this.session.mergeUndoDeltas = false;\n                        this.mergeNextCommand = false;\n                    }\n                }\n                text = transform.text;\n\n            }\n        }\n        \n        if (text == \"\\t\")\n            text = this.session.getTabString();\n\n        // remove selected text\n        if (!this.selection.isEmpty()) {\n            var range = this.getSelectionRange();\n            cursor = this.session.remove(range);\n            this.clearSelection();\n        }\n        else if (this.session.getOverwrite() && text.indexOf(\"\\n\") == -1) {\n            var range = new Range.fromPoints(cursor, cursor);\n            range.end.column += text.length;\n            this.session.remove(range);\n        }\n\n        if (text == \"\\n\" || text == \"\\r\\n\") {\n            var line = session.getLine(cursor.row);\n            if (cursor.column > line.search(/\\S|$/)) {\n                var d = line.substr(cursor.column).search(/\\S|$/);\n                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);\n            }\n        }\n        this.clearSelection();\n\n        var start = cursor.column;\n        var lineState = session.getState(cursor.row);\n        var line = session.getLine(cursor.row);\n        var shouldOutdent = mode.checkOutdent(lineState, line, text);\n        session.insert(cursor, text);\n\n        if (transform && transform.selection) {\n            if (transform.selection.length == 2) { // Transform relative to the current column\n                this.selection.setSelectionRange(\n                    new Range(cursor.row, start + transform.selection[0],\n                              cursor.row, start + transform.selection[1]));\n            } else { // Transform relative to the current row.\n                this.selection.setSelectionRange(\n                    new Range(cursor.row + transform.selection[0],\n                              transform.selection[1],\n                              cursor.row + transform.selection[2],\n                              transform.selection[3]));\n            }\n        }\n        if (this.$enableAutoIndent) {\n            if (session.getDocument().isNewLine(text)) {\n                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n\n                session.insert({row: cursor.row+1, column: 0}, lineIndent);\n            }\n            if (shouldOutdent)\n                mode.autoOutdent(lineState, session, cursor.row);\n        }\n    }\n\n    autoIndent() {\n        var session = this.session;\n        var mode = session.getMode();\n\n        var startRow, endRow;\n        if (this.selection.isEmpty()) {\n            startRow = 0;\n            endRow = session.doc.getLength() - 1;\n        } else {\n            var selectedRange = this.getSelectionRange();\n\n            startRow = selectedRange.start.row;\n            endRow = selectedRange.end.row;\n        }\n\n        var prevLineState = \"\";\n        var prevLine = \"\";\n        var lineIndent = \"\";\n        var line, currIndent, range;\n        var tab = session.getTabString();\n\n        for (var row = startRow; row <= endRow; row++) {\n            if (row > 0) {\n                prevLineState = session.getState(row - 1);\n                prevLine = session.getLine(row - 1);\n                lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);\n            }\n\n            line = session.getLine(row);\n            currIndent = mode.$getIndent(line);\n            if (lineIndent !== currIndent) {\n                if (currIndent.length > 0) {\n                    range = new Range(row, 0, row, currIndent.length);\n                    session.remove(range);\n                }\n                if (lineIndent.length > 0) {\n                    session.insert({row: row, column: 0}, lineIndent);\n                }\n            }\n\n            mode.autoOutdent(prevLineState, session, row);\n        }\n    }\n\n\n    onTextInput(text, composition) {\n        if (!composition)\n            return this.keyBinding.onTextInput(text);\n        \n        this.startOperation({command: { name: \"insertstring\" }});\n        var applyComposition = this.applyComposition.bind(this, text, composition);\n        if (this.selection.rangeCount)\n            this.forEachSelection(applyComposition);\n        else\n            applyComposition();\n        this.endOperation();\n    }\n    \n    applyComposition(text, composition) {\n        if (composition.extendLeft || composition.extendRight) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.extendLeft;\n            r.end.column += composition.extendRight;\n            if (r.start.column < 0) {\n                r.start.row--;\n                r.start.column += this.session.getLine(r.start.row).length + 1;\n            }\n            this.selection.setRange(r);\n            if (!text && !r.isEmpty())\n                this.remove();\n        }\n        if (text || !this.selection.isEmpty())\n            this.insert(text, true);\n        if (composition.restoreStart || composition.restoreEnd) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.restoreStart;\n            r.end.column -= composition.restoreEnd;\n            this.selection.setRange(r);\n        }\n    }\n\n    onCommandKey(e, hashId, keyCode) {\n        return this.keyBinding.onCommandKey(e, hashId, keyCode);\n    }\n\n    /**\n     * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n     * @param {Boolean} overwrite Defines whether or not to set overwrites\n     *\n     *\n     * @related EditSession.setOverwrite\n     **/\n    setOverwrite(overwrite) {\n        this.session.setOverwrite(overwrite);\n    }\n\n    /**\n     * Returns `true` if overwrites are enabled; `false` otherwise.\n     * @returns {Boolean}\n     * @related EditSession.getOverwrite\n     **/\n    getOverwrite() {\n        return this.session.getOverwrite();\n    }\n\n    /**\n     * Sets the value of overwrite to the opposite of whatever it currently is.\n     * @related EditSession.toggleOverwrite\n     **/\n    toggleOverwrite() {\n        this.session.toggleOverwrite();\n    }\n\n    /**\n     * Sets how fast the mouse scrolling should do.\n     * @param {Number} speed A value indicating the new speed (in milliseconds)\n     **/\n    setScrollSpeed(speed) {\n        this.setOption(\"scrollSpeed\", speed);\n    }\n\n    /**\n     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).\n     * @returns {Number}\n     **/\n    getScrollSpeed() {\n        return this.getOption(\"scrollSpeed\");\n    }\n\n    /**\n     * Sets the delay (in milliseconds) of the mouse drag.\n     * @param {Number} dragDelay A value indicating the new delay\n     **/\n    setDragDelay(dragDelay) {\n        this.setOption(\"dragDelay\", dragDelay);\n    }\n\n    /**\n     * Returns the current mouse drag delay.\n     * @returns {Number}\n     **/\n    getDragDelay() {\n        return this.getOption(\"dragDelay\");\n    }\n\n    /**\n     * Emitted when the selection style changes, via [[Editor.setSelectionStyle]].\n     * @event changeSelectionStyle\n     * @param {Object} data Contains one property, `data`, which indicates the new selection style\n     **/\n    /**\n     * Draw selection markers spanning whole line, or only over selected text. Default value is \"line\"\n     * @param {String} val The new selection style \"line\"|\"text\"\n     *\n     **/\n    setSelectionStyle(val) {\n        this.setOption(\"selectionStyle\", val);\n    }\n\n    /**\n     * Returns the current selection style.\n     * @returns {String}\n     **/\n    getSelectionStyle() {\n        return this.getOption(\"selectionStyle\");\n    }\n\n    /**\n     * Determines whether or not the current line should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line\n     **/\n    setHighlightActiveLine(shouldHighlight) {\n        this.setOption(\"highlightActiveLine\", shouldHighlight);\n    }\n    /**\n     * Returns `true` if current lines are always highlighted.\n     * @return {Boolean}\n     **/\n    getHighlightActiveLine() {\n        return this.getOption(\"highlightActiveLine\");\n    }\n    setHighlightGutterLine(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    }\n\n    getHighlightGutterLine() {\n        return this.getOption(\"highlightGutterLine\");\n    }\n\n    /**\n     * Determines if the currently selected word should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word\n     *\n     **/\n    setHighlightSelectedWord(shouldHighlight) {\n        this.setOption(\"highlightSelectedWord\", shouldHighlight);\n    }\n\n    /**\n     * Returns `true` if currently highlighted words are to be highlighted.\n     * @returns {Boolean}\n     **/\n    getHighlightSelectedWord() {\n        return this.$highlightSelectedWord;\n    }\n\n    setAnimatedScroll(shouldAnimate){\n        this.renderer.setAnimatedScroll(shouldAnimate);\n    }\n\n    getAnimatedScroll(){\n        return this.renderer.getAnimatedScroll();\n    }\n\n    /**\n     * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.\n     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters\n     *\n     **/\n    setShowInvisibles(showInvisibles) {\n        this.renderer.setShowInvisibles(showInvisibles);\n    }\n\n    /**\n     * Returns `true` if invisible characters are being shown.\n     * @returns {Boolean}\n     **/\n    getShowInvisibles() {\n        return this.renderer.getShowInvisibles();\n    }\n\n    setDisplayIndentGuides(display) {\n        this.renderer.setDisplayIndentGuides(display);\n    }\n\n    getDisplayIndentGuides() {\n        return this.renderer.getDisplayIndentGuides();\n    }\n\n    setHighlightIndentGuides(highlight) {\n        this.renderer.setHighlightIndentGuides(highlight);\n    }\n\n    getHighlightIndentGuides() {\n        return this.renderer.getHighlightIndentGuides();\n    }\n\n    /**\n     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.\n     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin\n     *\n     **/\n    setShowPrintMargin(showPrintMargin) {\n        this.renderer.setShowPrintMargin(showPrintMargin);\n    }\n\n    /**\n     * Returns `true` if the print margin is being shown.\n     * @returns {Boolean}\n     **/\n    getShowPrintMargin() {\n        return this.renderer.getShowPrintMargin();\n    }\n\n    /**\n     * Sets the column defining where the print margin should be.\n     * @param {Number} showPrintMargin Specifies the new print margin\n     *\n     **/\n    setPrintMarginColumn(showPrintMargin) {\n        this.renderer.setPrintMarginColumn(showPrintMargin);\n    }\n\n    /**\n     * Returns the column number of where the print margin is.\n     * @returns {Number}\n     **/\n    getPrintMarginColumn() {\n        return this.renderer.getPrintMarginColumn();\n    }\n\n    /**\n     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.\n     * @param {Boolean} readOnly Specifies whether the editor can be modified or not\n     *\n     **/\n    setReadOnly(readOnly) {\n        this.setOption(\"readOnly\", readOnly);\n    }\n\n    /**\n     * Returns `true` if the editor is set to read-only mode.\n     * @returns {Boolean}\n     **/\n    getReadOnly() {\n        return this.getOption(\"readOnly\");\n    }\n\n    /**\n     * Specifies whether to use behaviors or not. [\"Behaviors\" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}\n     * @param {Boolean} enabled Enables or disables behaviors\n     *\n     **/\n    setBehavioursEnabled(enabled) {\n        this.setOption(\"behavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}\n     *\n     * @returns {Boolean}\n     **/\n    getBehavioursEnabled() {\n        return this.getOption(\"behavioursEnabled\");\n    }\n\n    /**\n     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets\n     * when such a character is typed in.\n     * @param {Boolean} enabled Enables or disables wrapping behaviors\n     *\n     **/\n    setWrapBehavioursEnabled(enabled) {\n        this.setOption(\"wrapBehavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the wrapping behaviors are currently enabled.\n     **/\n    getWrapBehavioursEnabled() {\n        return this.getOption(\"wrapBehavioursEnabled\");\n    }\n\n    /**\n     * Indicates whether the fold widgets should be shown or not.\n     * @param {Boolean} show Specifies whether the fold widgets are shown\n     **/\n    setShowFoldWidgets(show) {\n        this.setOption(\"showFoldWidgets\", show);\n\n    }\n    /**\n     * Returns `true` if the fold widgets are shown.\n     * @return {Boolean}\n     **/\n    getShowFoldWidgets() {\n        return this.getOption(\"showFoldWidgets\");\n    }\n\n    setFadeFoldWidgets(fade) {\n        this.setOption(\"fadeFoldWidgets\", fade);\n    }\n\n    getFadeFoldWidgets() {\n        return this.getOption(\"fadeFoldWidgets\");\n    }\n\n    /**\n     * Removes the current selection or one character.\n     * @param {String} dir The direction of the deletion to occur, either \"left\" or \"right\"\n     *\n     **/\n    remove(dir) {\n        if (this.selection.isEmpty()){\n            if (dir == \"left\")\n                this.selection.selectLeft();\n            else\n                this.selection.selectRight();\n        }\n\n        var range = this.getSelectionRange();\n        if (this.getBehavioursEnabled()) {\n            var session = this.session;\n            var state = session.getState(range.start.row);\n            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);\n\n            if (range.end.column === 0) {\n                var text = session.getTextRange(range);\n                if (text[text.length - 1] == \"\\n\") {\n                    var line = session.getLine(range.end.row);\n                    if (/^\\s+$/.test(line)) {\n                        range.end.column = line.length;\n                    }\n                }\n            }\n            if (new_range)\n                range = new_range;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the right of the current selection.\n     **/\n    removeWordRight() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordRight();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the left of the current selection.\n     **/\n    removeWordLeft() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordLeft();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the left of the current selection, until the start of the line.\n     **/\n    removeToLineStart() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineStart();\n        if (this.selection.isEmpty())\n            this.selection.selectLeft();\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the right of the current selection, until the end of the line.\n     **/\n    removeToLineEnd() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineEnd();\n\n        var range = this.getSelectionRange();\n        if (range.start.column == range.end.column && range.start.row == range.end.row) {\n            range.end.column = 0;\n            range.end.row++;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Splits the line at the current selection (by inserting an `'\\n'`).\n     **/\n    splitLine() {\n        if (!this.selection.isEmpty()) {\n            this.session.remove(this.getSelectionRange());\n            this.clearSelection();\n        }\n\n        var cursor = this.getCursorPosition();\n        this.insert(\"\\n\");\n        this.moveCursorToPosition(cursor);\n    }\n\n    /**\n     * Set the \"ghost\" text in provided position. \"Ghost\" text is a kind of\n     * preview text inside the editor which can be used to preview some code\n     * inline in the editor such as, for example, code completions.\n     * \n     * @param {String} text Text to be inserted as \"ghost\" text\n     * @param {object} position Position to insert text to\n     */\n    setGhostText(text, position) {\n        if (!this.session.widgetManager) {\n            this.session.widgetManager = new LineWidgets(this.session);\n            this.session.widgetManager.attach(this);\n        }\n        this.renderer.setGhostText(text, position);\n    }\n\n    /**\n     * Removes \"ghost\" text currently displayed in the editor.\n     */\n    removeGhostText() {\n        if (!this.session.widgetManager) return;\n\n        this.renderer.removeGhostText();\n    }\n\n    /**\n     * Transposes current line.\n     **/\n    transposeLetters() {\n        if (!this.selection.isEmpty()) {\n            return;\n        }\n\n        var cursor = this.getCursorPosition();\n        var column = cursor.column;\n        if (column === 0)\n            return;\n\n        var line = this.session.getLine(cursor.row);\n        var swap, range;\n        if (column < line.length) {\n            swap = line.charAt(column) + line.charAt(column-1);\n            range = new Range(cursor.row, column-1, cursor.row, column+1);\n        }\n        else {\n            swap = line.charAt(column-1) + line.charAt(column-2);\n            range = new Range(cursor.row, column-2, cursor.row, column);\n        }\n        this.session.replace(range, swap);\n        this.session.selection.moveToPosition(range.end);\n    }\n\n    /**\n     * Converts the current selection entirely into lowercase.\n     **/\n    toLowerCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toLowerCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Converts the current selection entirely into uppercase.\n     **/\n    toUpperCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toUpperCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Inserts an indentation into the current cursor position or indents the selected lines.\n     *\n     * @related EditSession.indentRows\n     **/\n    indent() {\n        var session = this.session;\n        var range = this.getSelectionRange();\n\n        if (range.start.row < range.end.row) {\n            var rows = this.$getSelectedRows();\n            session.indentRows(rows.first, rows.last, \"\\t\");\n            return;\n        } else if (range.start.column < range.end.column) {\n            var text = session.getTextRange(range);\n            if (!/^\\s+$/.test(text)) {\n                var rows = this.$getSelectedRows();\n                session.indentRows(rows.first, rows.last, \"\\t\");\n                return;\n            }\n        }\n        \n        var line = session.getLine(range.start.row);\n        var position = range.start;\n        var size = session.getTabSize();\n        var column = session.documentToScreenColumn(position.row, position.column);\n\n        if (this.session.getUseSoftTabs()) {\n            var count = (size - column % size);\n            var indentString = lang.stringRepeat(\" \", count);\n        } else {\n            var count = column % size;\n            while (line[range.start.column - 1] == \" \" && count) {\n                range.start.column--;\n                count--;\n            }\n            this.selection.setSelectionRange(range);\n            indentString = \"\\t\";\n        }\n        return this.insert(indentString);\n    }\n\n    /**\n     * Indents the current line.\n     * @related EditSession.indentRows\n     **/\n    blockIndent() {\n        var rows = this.$getSelectedRows();\n        this.session.indentRows(rows.first, rows.last, \"\\t\");\n    }\n\n    /**\n     * Outdents the current line.\n     * @related EditSession.outdentRows\n     **/\n    blockOutdent() {\n        var selection = this.session.getSelection();\n        this.session.outdentRows(selection.getRange());\n    }\n\n    // TODO: move out of core when we have good mechanism for managing extensions\n    sortLines() {\n        var rows = this.$getSelectedRows();\n        var session = this.session;\n\n        var lines = [];\n        for (var i = rows.first; i <= rows.last; i++)\n            lines.push(session.getLine(i));\n\n        lines.sort(function(a, b) {\n            if (a.toLowerCase() < b.toLowerCase()) return -1;\n            if (a.toLowerCase() > b.toLowerCase()) return 1;\n            return 0;\n        });\n\n        var deleteRange = new Range(0, 0, 0, 0);\n        for (var i = rows.first; i <= rows.last; i++) {\n            var line = session.getLine(i);\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            deleteRange.end.column = line.length;\n            session.replace(deleteRange, lines[i-rows.first]);\n        }\n    }\n\n    /**\n     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.\n     **/\n    toggleCommentLines() {\n        var state = this.session.getState(this.getCursorPosition().row);\n        var rows = this.$getSelectedRows();\n        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);\n    }\n\n    toggleBlockComment() {\n        var cursor = this.getCursorPosition();\n        var state = this.session.getState(cursor.row);\n        var range = this.getSelectionRange();\n        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);\n    }\n\n    /**\n     * Works like [[EditSession.getTokenAt]], except it returns a number.\n     * @returns {Number}\n     **/\n    getNumberAt(row, column) {\n        var _numberRx = /[\\-]?[0-9]+(?:\\.[0-9]+)?/g;\n        _numberRx.lastIndex = 0;\n\n        var s = this.session.getLine(row);\n        while (_numberRx.lastIndex < column) {\n            var m = _numberRx.exec(s);\n            if(m.index <= column && m.index+m[0].length >= column){\n                var number = {\n                    value: m[0],\n                    start: m.index,\n                    end: m.index+m[0].length\n                };\n                return number;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * If the character before the cursor is a number, this functions changes its value by `amount`.\n     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)\n     *\n     **/\n    modifyNumber(amount) {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n\n        // get the char before the cursor\n        var charRange = new Range(row, column-1, row, column);\n\n        var c = this.session.getTextRange(charRange);\n        // if the char is a digit\n        if (!isNaN(parseFloat(c)) && isFinite(c)) {\n            // get the whole number the digit is part of\n            var nr = this.getNumberAt(row, column);\n            // if number found\n            if (nr) {\n                var fp = nr.value.indexOf(\".\") >= 0 ? nr.start + nr.value.indexOf(\".\") + 1 : nr.end;\n                var decimals = nr.start + nr.value.length - fp;\n\n                var t = parseFloat(nr.value);\n                t *= Math.pow(10, decimals);\n\n\n                if(fp !== nr.end && column < fp){\n                    amount *= Math.pow(10, nr.end - column - 1);\n                } else {\n                    amount *= Math.pow(10, nr.end - column);\n                }\n\n                t += amount;\n                t /= Math.pow(10, decimals);\n                var nnr = t.toFixed(decimals);\n\n                //update number\n                var replaceRange = new Range(row, nr.start, row, nr.end);\n                this.session.replace(replaceRange, nnr);\n\n                //reposition the cursor\n                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));\n\n            }\n        } else {\n            this.toggleWord();\n        }\n    }\n    \n    toggleWord() {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        this.selection.selectWord();\n        var currentState = this.getSelectedText();\n        var currWordStart = this.selection.getWordRange().start.column;\n        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\\s/);\n        var delta = column - currWordStart - 1;\n        if (delta < 0) delta = 0;\n        var curLength = 0, itLength = 0;\n        var that = this;\n        if (currentState.match(/[A-Za-z0-9_]+/)) {\n            wordParts.forEach(function (item, i) {\n                itLength = curLength + item.length;\n                if (delta >= curLength && delta <= itLength) {\n                    currentState = item;\n                    that.selection.clearSelection();\n                    that.moveCursorTo(row, curLength + currWordStart);\n                    that.selection.selectTo(row, itLength + currWordStart);\n                }\n                curLength = itLength;\n            });\n        }\n\n        var wordPairs = this.$toggleWordPairs;\n        var reg;\n        for (var i = 0; i < wordPairs.length; i++) {\n            var item = wordPairs[i];\n            for (var j = 0; j <= 1; j++) {\n                var negate = +!j;\n                var firstCondition = currentState.match(new RegExp('^\\\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\\\s?$', 'i'));\n                if (firstCondition) {\n                    var secondCondition = currentState.match(new RegExp('([_]|^|\\\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\\\s)', 'g'));\n                    if (secondCondition) {\n                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {\n                            var res = item[negate];\n                            if (result.toUpperCase() == result) {\n                                res = res.toUpperCase();\n                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {\n                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);\n                            }\n                            return res;\n                        });\n                        this.insert(reg);\n                        reg = \"\";\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Finds link at defined {row} and {column}\n     * @returns {String}\n     **/\n    findLinkAt(row, column) {\n        var line = this.session.getLine(row);\n        var wordParts = line.split(/((?:https?|ftp):\\/\\/[\\S]+)/);\n        var columnPosition = column;\n        if (columnPosition < 0) columnPosition = 0;\n        var previousPosition = 0, currentPosition = 0, match;\n        for (let item of wordParts) {\n            currentPosition = previousPosition + item.length;\n            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {\n                if (item.match(/((?:https?|ftp):\\/\\/[\\S]+)/)) {\n                    match = item.replace(/[\\s:.,'\";}\\]]+$/, \"\");\n                    break;\n                }\n            }\n            previousPosition = currentPosition;\n        }\n        return match;\n    }\n\n    /**\n     * Open valid url under cursor in another tab\n     * @returns {Boolean}\n     **/\n    openLink() {\n        var cursor =  this.selection.getCursor();\n        var url = this.findLinkAt(cursor.row, cursor.column);\n        if (url)\n            window.open(url, '_blank');\n        return url != null;\n    }\n\n    /**\n     * Removes all the lines in the current selection\n     * @related EditSession.remove\n     **/\n    removeLines() {\n        var rows = this.$getSelectedRows();\n        this.session.removeFullLines(rows.first, rows.last);\n        this.clearSelection();\n    }\n\n    duplicateSelection() {\n        var sel = this.selection;\n        var doc = this.session;\n        var range = sel.getRange();\n        var reverse = sel.isBackwards();\n        if (range.isEmpty()) {\n            var row = range.start.row;\n            doc.duplicateLines(row, row);\n        } else {\n            var point = reverse ? range.start : range.end;\n            var endPoint = doc.insert(point, doc.getTextRange(range), false);\n            range.start = point;\n            range.end = endPoint;\n\n            sel.setSelectionRange(range, reverse);\n        }\n    }\n\n    /**\n     * Shifts all the selected lines down one row.\n     *\n     * @returns {Number} On success, it returns -1.\n     * @related EditSession.moveLinesUp\n     **/\n    moveLinesDown() {\n        this.$moveLines(1, false);\n    }\n\n    /**\n     * Shifts all the selected lines up one row.\n     * @returns {Number} On success, it returns -1.\n     * @related EditSession.moveLinesDown\n     **/\n    moveLinesUp() {\n        this.$moveLines(-1, false);\n    }\n\n    /**\n     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n     * ```json\n     *    { row: newRowLocation, column: newColumnLocation }\n     * ```\n     * @param {Range} range The range of text you want moved within the document\n     * @param {Object} toPosition The location (row and column) where you want to move the text to\n     *\n     * @returns {Range} The new range where the text was moved to.\n     * @related EditSession.moveText\n     **/\n    moveText(range, toPosition, copy) {\n        return this.session.moveText(range, toPosition, copy);\n    }\n\n    /**\n     * Copies all the selected lines up one row.\n     * @returns {Number} On success, returns 0.\n     *\n     **/\n   copyLinesUp() {\n        this.$moveLines(-1, true);\n    }\n\n    /**\n     * Copies all the selected lines down one row.\n     * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.\n     * @related EditSession.duplicateLines\n     *\n     **/\n    copyLinesDown() {\n        this.$moveLines(1, true);\n    }\n\n    /**\n     * for internal use\n     * @ignore\n     *\n     **/\n    $moveLines(dir, copy) {\n        var rows, moved;\n        var selection = this.selection;\n        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {\n            var range = selection.toOrientedRange();\n            rows = this.$getSelectedRows(range);\n            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);\n            if (copy && dir == -1) moved = 0;\n            range.moveBy(moved, 0);\n            selection.fromOrientedRange(range);\n        } else {\n            var ranges = selection.rangeList.ranges;\n            selection.rangeList.detach(this.session);\n            this.inVirtualSelectionMode = true;\n            \n            var diff = 0;\n            var totalDiff = 0;\n            var l = ranges.length;\n            for (var i = 0; i < l; i++) {\n                var rangeIndex = i;\n                ranges[i].moveBy(diff, 0);\n                rows = this.$getSelectedRows(ranges[i]);\n                var first = rows.first;\n                var last = rows.last;\n                while (++i < l) {\n                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);\n                    var subRows = this.$getSelectedRows(ranges[i]);\n                    if (copy && subRows.first != last)\n                        break;\n                    else if (!copy && subRows.first > last + 1)\n                        break;\n                    last = subRows.last;\n                }\n                i--;\n                diff = this.session.$moveLines(first, last, copy ? 0 : dir);\n                if (copy && dir == -1) rangeIndex = i + 1;\n                while (rangeIndex <= i) {\n                    ranges[rangeIndex].moveBy(diff, 0);\n                    rangeIndex++;\n                }\n                if (!copy) diff = 0;\n                totalDiff += diff;\n            }\n            \n            selection.fromOrientedRange(selection.ranges[0]);\n            selection.rangeList.attach(this.session);\n            this.inVirtualSelectionMode = false;\n        }\n    }\n\n    /**\n     * Returns an object indicating the currently selected rows. The object looks like this:\n     *\n     * ```json\n     * { first: range.start.row, last: range.end.row }\n     * ```\n     *\n     * @returns {Object}\n     **/\n    $getSelectedRows(range) {\n        range = (range || this.getSelectionRange()).collapseRows();\n\n        return {\n            first: this.session.getRowFoldStart(range.start.row),\n            last: this.session.getRowFoldEnd(range.end.row)\n        };\n    }\n\n    onCompositionStart(compositionState) {\n        this.renderer.showComposition(compositionState);\n    }\n\n    onCompositionUpdate(text) {\n        this.renderer.setCompositionText(text);\n    }\n\n    onCompositionEnd() {\n        this.renderer.hideComposition();\n    }\n\n    /**\n     * {:VirtualRenderer.getFirstVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getFirstVisibleRow\n     **/\n    getFirstVisibleRow() {\n        return this.renderer.getFirstVisibleRow();\n    }\n\n    /**\n     * {:VirtualRenderer.getLastVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getLastVisibleRow\n     **/\n    getLastVisibleRow() {\n        return this.renderer.getLastVisibleRow();\n    }\n\n    /**\n     * Indicates if the row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     * @returns {Boolean}\n     **/\n    isRowVisible(row) {\n        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());\n    }\n\n    /**\n     * Indicates if the entire row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     *\n     * @returns {Boolean}\n     **/\n    isRowFullyVisible(row) {\n        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());\n    }\n\n    /**\n     * Returns the number of currently visible rows.\n     * @returns {Number}\n     **/\n    $getVisibleRowCount() {\n        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;\n    }\n\n    $moveByPage(dir, select) {\n        var renderer = this.renderer;\n        var config = this.renderer.layerConfig;\n        var rows = dir * Math.floor(config.height / config.lineHeight);\n\n        if (select === true) {\n            this.selection.$moveSelection(function(){\n                this.moveCursorBy(rows, 0);\n            });\n        } else if (select === false) {\n            this.selection.moveCursorBy(rows, 0);\n            this.selection.clearSelection();\n        }\n\n        var scrollTop = renderer.scrollTop;\n\n        renderer.scrollBy(0, rows * config.lineHeight);\n        if (select != null)\n            renderer.scrollCursorIntoView(null, 0.5);\n\n        renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page down\" finishes.\n     **/\n    selectPageDown() {\n        this.$moveByPage(1, true);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page up\" finishes.\n     **/\n    selectPageUp() {\n        this.$moveByPage(-1, true);\n    }\n\n    /**\n     * Shifts the document to wherever \"page down\" is, as well as moving the cursor position.\n     **/\n    gotoPageDown() {\n       this.$moveByPage(1, false);\n    }\n\n    /**\n     * Shifts the document to wherever \"page up\" is, as well as moving the cursor position.\n     **/\n    gotoPageUp() {\n        this.$moveByPage(-1, false);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page down\" is, without changing the cursor position.\n     **/\n    scrollPageDown() {\n        this.$moveByPage(1);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page up\" is, without changing the cursor position.\n     **/\n    scrollPageUp() {\n        this.$moveByPage(-1);\n    }\n\n    /**\n     * Moves the editor to the specified row.\n     * @related VirtualRenderer.scrollToRow\n     **/\n    scrollToRow(row) {\n        this.renderer.scrollToRow(row);\n    }\n\n    /**\n     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).\n     * @param {Number} line The line to scroll to\n     * @param {Boolean} center If `true`\n     * @param {Boolean} animate If `true` animates scrolling\n     * @param {Function} callback Function to be called when the animation has finished\n     *\n     *\n     * @related VirtualRenderer.scrollToLine\n     **/\n    scrollToLine(line, center, animate, callback) {\n        this.renderer.scrollToLine(line, center, animate, callback);\n    }\n\n    /**\n     * Attempts to center the current selection on the screen.\n     **/\n    centerSelection() {\n        var range = this.getSelectionRange();\n        var pos = {\n            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),\n            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)\n        };\n        this.renderer.alignCursor(pos, 0.5);\n    }\n\n    /**\n     * Gets the current position of the cursor.\n     * @returns {Object} An object that looks something like this:\n     *\n     * ```json\n     * { row: currRow, column: currCol }\n     * ```\n     *\n     * @related Selection.getCursor\n     **/\n    getCursorPosition() {\n        return this.selection.getCursor();\n    }\n\n    /**\n     * Returns the screen position of the cursor.\n     * @returns {Position}\n     * @related EditSession.documentToScreenPosition\n     **/\n    getCursorPositionScreen() {\n        return this.session.documentToScreenPosition(this.getCursorPosition());\n    }\n\n    /**\n     * {:Selection.getRange}\n     * @returns {Range}\n     * @related Selection.getRange\n     **/\n    getSelectionRange() {\n        return this.selection.getRange();\n    }\n    \n    /**\n     * Selects all the text in editor.\n     * @related Selection.selectAll\n     **/\n    selectAll() {\n        this.selection.selectAll();\n    }\n\n    /**\n     * {:Selection.clearSelection}\n     * @related Selection.clearSelection\n     **/\n    clearSelection() {\n        this.selection.clearSelection();\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     * @related Selection.moveCursorTo\n     **/\n    moveCursorTo(row, column) {\n        this.selection.moveCursorTo(row, column);\n    }\n\n    /**\n     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.\n     * @param {Position} pos An object with two properties, row and column\n     * @related Selection.moveCursorToPosition\n     **/\n    moveCursorToPosition(pos) {\n        this.selection.moveCursorToPosition(pos);\n    }\n\n    /**\n     * Moves the cursor's row and column to the next matching bracket or HTML tag.\n     *\n     **/\n    jumpToMatching(select, expand) {\n        var cursor = this.getCursorPosition();\n        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);\n        var prevToken = iterator.getCurrentToken();\n        var tokenCount = 0;\n        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {\n            prevToken = iterator.stepBackward();\n        }\n        var token = prevToken || iterator.stepForward();\n\n        if (!token) return;\n\n        //get next closing tag or bracket\n        var matchType;\n        var found = false;\n        var depth = {};\n        var i = cursor.column - token.start;\n        var bracketType;\n        var brackets = {\n            \")\": \"(\",\n            \"(\": \"(\",\n            \"]\": \"[\",\n            \"[\": \"[\",\n            \"{\": \"{\",\n            \"}\": \"{\"\n        };\n\n        do {\n            if (token.value.match(/[{}()\\[\\]]/g)) {\n                for (; i < token.value.length && !found; i++) {\n                    if (!brackets[token.value[i]]) {\n                        continue;\n                    }\n\n                    bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n\n                    if (isNaN(depth[bracketType])) {\n                        depth[bracketType] = 0;\n                    }\n\n                    switch (token.value[i]) {\n                        case '(':\n                        case '[':\n                        case '{':\n                            depth[bracketType]++;\n                            break;\n                        case ')':\n                        case ']':\n                        case '}':\n                            depth[bracketType]--;\n\n                            if (depth[bracketType] === -1) {\n                                matchType = 'bracket';\n                                found = true;\n                            }\n                            break;\n                    }\n                }\n            }\n            else if (token.type.indexOf('tag-name') !== -1) {\n                if (isNaN(depth[token.value])) {\n                    depth[token.value] = 0;\n                }\n\n                if (prevToken.value === '<' && tokenCount > 1) {\n                    depth[token.value]++;\n                }\n                else if (prevToken.value === '</') {\n                    depth[token.value]--;\n                }\n\n                if (depth[token.value] === -1) {\n                    matchType = 'tag';\n                    found = true;\n                }\n            }\n\n            if (!found) {\n                prevToken = token;\n                tokenCount++;\n                token = iterator.stepForward();\n                i = 0;\n            }\n        } while (token && !found);\n\n        //no match found\n        if (!matchType) return;\n\n        var range, pos;\n        if (matchType === 'bracket') {\n            range = this.session.getBracketRange(cursor);\n            if (!range) {\n                range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1,\n                    iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1\n                );\n                pos = range.start;\n                if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column)\n                    < 2) range = this.session.getBracketRange(pos);\n            }\n        }\n        else if (matchType === 'tag') {\n            if (!token || token.type.indexOf('tag-name') === -1) return;\n            range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2,\n                iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2\n            );\n\n            //find matching tag\n            if (range.compare(cursor.row, cursor.column) === 0) {\n                var tagsRanges = this.session.getMatchingTags(cursor);\n                if (tagsRanges) {\n                    if (tagsRanges.openTag.contains(cursor.row, cursor.column)) {\n                        range = tagsRanges.closeTag;\n                        pos = range.start;\n                    }\n                    else {\n                        range = tagsRanges.openTag;\n                        if (tagsRanges.closeTag.start.row === cursor.row && tagsRanges.closeTag.start.column\n                            === cursor.column) pos = range.end; else pos = range.start;\n                    }\n                }\n            }\n\n            //we found it\n            pos = pos || range.start;\n        }\n\n        pos = range && range.cursor || pos;\n        if (pos) {\n            if (select) {\n                if (range && expand) {\n                    this.selection.setRange(range);\n                }\n                else if (range && range.isEqual(this.getSelectionRange())) {\n                    this.clearSelection();\n                }\n                else {\n                    this.selection.selectTo(pos.row, pos.column);\n                }\n            }\n            else {\n                this.selection.moveTo(pos.row, pos.column);\n            }\n        }\n    }\n\n    /**\n     * Moves the cursor to the specified line number, and also into the indicated column.\n     * @param {Number} lineNumber The line number to go to\n     * @param {Number} column A column number to go to\n     * @param {Boolean} animate If `true` animates scolling\n     *\n     **/\n    gotoLine(lineNumber, column, animate) {\n        this.selection.clearSelection();\n        this.session.unfold({row: lineNumber - 1, column: column || 0});\n\n        // todo: find a way to automatically exit multiselect mode\n        this.exitMultiSelectMode && this.exitMultiSelectMode();\n        this.moveCursorTo(lineNumber - 1, column || 0);\n\n        if (!this.isRowFullyVisible(lineNumber - 1))\n            this.scrollToLine(lineNumber - 1, true, animate);\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     *\n     *\n     * @related Editor.moveCursorTo\n     **/\n    navigateTo(row, column) {\n        this.selection.moveTo(row, column);\n    }\n\n    /**\n     * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    navigateUp(times) {\n        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {\n            var selectionStart = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionStart);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(-times || -1, 0);\n    }\n\n    /**\n     * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    navigateDown(times) {\n        if (this.selection.isMultiLine() && this.selection.isBackwards()) {\n            var selectionEnd = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionEnd);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(times || 1, 0);\n    }\n\n    /**\n     * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    navigateLeft(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionStart = this.getSelectionRange().start;\n            this.moveCursorToPosition(selectionStart);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorLeft();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} times The number of times to change navigation\n     *\n     *\n     **/\n    navigateRight(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionEnd = this.getSelectionRange().end;\n            this.moveCursorToPosition(selectionEnd);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorRight();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineStart() {\n        this.selection.moveCursorLineStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineEnd() {\n        this.selection.moveCursorLineEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileEnd() {\n        this.selection.moveCursorFileEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileStart() {\n        this.selection.moveCursorFileStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordRight() {\n        this.selection.moveCursorWordRight();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordLeft() {\n        this.selection.moveCursorWordLeft();\n        this.clearSelection();\n    }\n\n    /**\n     * Replaces the first occurrence of `options.needle` with the value in `replacement`.\n     * @param {String} replacement The text to replace with\n     * @param {Object} options The [[Search `Search`]] options to use\n     *\n     *\n     **/\n    replace(replacement, options) {\n        if (options)\n            this.$search.set(options);\n\n        var range = this.$search.find(this.session);\n        var replaced = 0;\n        if (!range)\n            return replaced;\n\n        if (this.$tryReplace(range, replacement)) {\n            replaced = 1;\n        }\n\n        this.selection.setSelectionRange(range);\n        this.renderer.scrollSelectionIntoView(range.start, range.end);\n\n        return replaced;\n    }\n\n    /**\n     * Replaces all occurrences of `options.needle` with the value in `replacement`.\n     * @param {String} replacement The text to replace with\n     * @param {Object} options The [[Search `Search`]] options to use\n     *\n     *\n     **/\n    replaceAll(replacement, options) {\n        if (options) {\n            this.$search.set(options);\n        }\n\n        var ranges = this.$search.findAll(this.session);\n        var replaced = 0;\n        if (!ranges.length)\n            return replaced;\n\n        var selection = this.getSelectionRange();\n        this.selection.moveTo(0, 0);\n\n        for (var i = ranges.length - 1; i >= 0; --i) {\n            if(this.$tryReplace(ranges[i], replacement)) {\n                replaced++;\n            }\n        }\n\n        this.selection.setSelectionRange(selection);\n\n        return replaced;\n    }\n\n    $tryReplace(range, replacement) {\n        var input = this.session.getTextRange(range);\n        replacement = this.$search.replace(input, replacement);\n        if (replacement !== null) {\n            range.end = this.session.replace(range, replacement);\n            return range;\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].\n     * @related Search.getOptions\n     * @returns {Object}\n     **/\n    getLastSearchOptions() {\n        return this.$search.getOptions();\n    }\n\n    /**\n     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].\n     * @param {String|RegExp|Object} needle The text to search for (optional)\n     * @param {Object} options An object defining various search properties\n     * @param {Boolean} animate If `true` animate scrolling\n     * @related Search.find\n     **/\n    find(needle, options, animate) {\n        if (!options)\n            options = {};\n\n        if (typeof needle == \"string\" || needle instanceof RegExp)\n            options.needle = needle;\n        else if (typeof needle == \"object\")\n            oop.mixin(options, needle);\n\n        var range = this.selection.getRange();\n        if (options.needle == null) {\n            needle = this.session.getTextRange(range)\n                || this.$search.$options.needle;\n            if (!needle) {\n                range = this.session.getWordRange(range.start.row, range.start.column);\n                needle = this.session.getTextRange(range);\n            }\n            this.$search.set({needle: needle});\n        }\n\n        this.$search.set(options);\n        if (!options.start)\n            this.$search.set({start: range});\n\n        var newRange = this.$search.find(this.session);\n        if (options.preventScroll)\n            return newRange;\n        if (newRange) {\n            this.revealRange(newRange, animate);\n            return newRange;\n        }\n        // clear selection if nothing is found\n        if (options.backwards)\n            range.start = range.end;\n        else\n            range.end = range.start;\n        this.selection.setRange(range);\n    }\n\n    /**\n     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].\n     * @param {Object} options search options\n     * @param {Boolean} animate If `true` animate scrolling\n     *\n     *\n     * @related Editor.find\n     **/\n    findNext(options, animate) {\n        this.find({skipCurrent: true, backwards: false}, options, animate);\n    }\n\n    /**\n     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].\n     * @param {Object} options search options\n     * @param {Boolean} animate If `true` animate scrolling\n     *\n     *\n     * @related Editor.find\n     **/\n    findPrevious(options, animate) {\n        this.find(options, {skipCurrent: true, backwards: true}, animate);\n    }\n\n    revealRange(range, animate) {\n        this.session.unfold(range);\n        this.selection.setSelectionRange(range);\n\n        var scrollTop = this.renderer.scrollTop;\n        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n        if (animate !== false)\n            this.renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * {:UndoManager.undo}\n     * @related UndoManager.undo\n     **/\n    undo() {\n        this.session.getUndoManager().undo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     * {:UndoManager.redo}\n     * @related UndoManager.redo\n     **/\n    redo() {\n        this.session.getUndoManager().redo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     *\n     * Cleans up the entire editor.\n     **/\n    destroy() {\n        if (this.$toDestroy) {\n            this.$toDestroy.forEach(function(el) {\n                el.destroy();\n            });\n            this.$toDestroy = null;\n        }\n        if (this.$mouseHandler)\n            this.$mouseHandler.destroy();\n        this.renderer.destroy();\n        this._signal(\"destroy\", this);\n        if (this.session)\n            this.session.destroy();\n        if (this._$emitInputEvent)\n            this._$emitInputEvent.cancel();\n        this.removeAllListeners();\n    }\n\n    /**\n     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element\n     * @param {Boolean} enable default true\n     **/\n    setAutoScrollEditorIntoView(enable) {\n        if (!enable)\n            return;\n        var rect;\n        var self = this;\n        var shouldScroll = false;\n        if (!this.$scrollAnchor)\n            this.$scrollAnchor = document.createElement(\"div\");\n        var scrollAnchor = this.$scrollAnchor;\n        scrollAnchor.style.cssText = \"position:absolute\";\n        this.container.insertBefore(scrollAnchor, this.container.firstChild);\n        var onChangeSelection = this.on(\"changeSelection\", function() {\n            shouldScroll = true;\n        });\n        // needed to not trigger sync reflow\n        var onBeforeRender = this.renderer.on(\"beforeRender\", function() {\n            if (shouldScroll)\n                rect = self.renderer.container.getBoundingClientRect();\n        });\n        var onAfterRender = this.renderer.on(\"afterRender\", function() {\n            if (shouldScroll && rect && (self.isFocused()\n                || self.searchBox && self.searchBox.isFocused())\n            ) {\n                var renderer = self.renderer;\n                var pos = renderer.$cursorLayer.$pixelPos;\n                var config = renderer.layerConfig;\n                var top = pos.top - config.offset;\n                if (pos.top >= 0 && top + rect.top < 0) {\n                    shouldScroll = true;\n                } else if (pos.top < config.height &&\n                    pos.top + rect.top + config.lineHeight > window.innerHeight) {\n                    shouldScroll = false;\n                } else {\n                    shouldScroll = null;\n                }\n                if (shouldScroll != null) {\n                    scrollAnchor.style.top = top + \"px\";\n                    scrollAnchor.style.left = pos.left + \"px\";\n                    scrollAnchor.style.height = config.lineHeight + \"px\";\n                    scrollAnchor.scrollIntoView(shouldScroll);\n                }\n                shouldScroll = rect = null;\n            }\n        });\n        this.setAutoScrollEditorIntoView = function(enable) {\n            if (enable)\n                return;\n            delete this.setAutoScrollEditorIntoView;\n            this.off(\"changeSelection\", onChangeSelection);\n            this.renderer.off(\"afterRender\", onAfterRender);\n            this.renderer.off(\"beforeRender\", onBeforeRender);\n        };\n    }\n\n\n    $resetCursorStyle() {\n        var style = this.$cursorStyle || \"ace\";\n        var cursorLayer = this.renderer.$cursorLayer;\n        if (!cursorLayer)\n            return;\n        cursorLayer.setSmoothBlinking(/smooth/.test(style));\n        cursorLayer.isBlinking = !this.$readOnly && style != \"wide\";\n        dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n    }\n\n    /**\n     * opens a prompt displaying message\n     **/\n    prompt(message, options, callback) {\n        var editor = this;\n        config.loadModule(\"ace/ext/prompt\", function (module) {\n            module.prompt(editor, message, options, callback);\n        });\n    }\n\n}\n\nEditor.$uid = 0;\nEditor.prototype.curOp = null;\nEditor.prototype.prevOp = {};\n// TODO use property on commands instead of this\nEditor.prototype.$mergeableCommands = [\"backspace\", \"del\", \"insertstring\"];\nEditor.prototype.$toggleWordPairs = [\n    [\"first\", \"last\"],\n    [\"true\", \"false\"],\n    [\"yes\", \"no\"],\n    [\"width\", \"height\"],\n    [\"top\", \"bottom\"],\n    [\"right\", \"left\"],\n    [\"on\", \"off\"],\n    [\"x\", \"y\"],\n    [\"get\", \"set\"],\n    [\"max\", \"min\"],\n    [\"horizontal\", \"vertical\"],\n    [\"show\", \"hide\"],\n    [\"add\", \"remove\"],\n    [\"up\", \"down\"],\n    [\"before\", \"after\"],\n    [\"even\", \"odd\"],\n    [\"in\", \"out\"],\n    [\"inside\", \"outside\"],\n    [\"next\", \"previous\"],\n    [\"increase\", \"decrease\"],\n    [\"attach\", \"detach\"],\n    [\"&&\", \"||\"],\n    [\"==\", \"!=\"]\n];\n\noop.implement(Editor.prototype, EventEmitter);\n\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    selectionStyle: {\n        set: function(style) {\n            this.onSelectionChange();\n            this._signal(\"changeSelectionStyle\", {data: style});\n        },\n        initialValue: \"line\"\n    },\n    highlightActiveLine: {\n        set: function() {this.$updateHighlightActiveLine();},\n        initialValue: true\n    },\n    highlightSelectedWord: {\n        set: function(shouldHighlight) {this.$onSelectionChange();},\n        initialValue: true\n    },\n    readOnly: {\n        set: function(readOnly) {\n            this.textInput.setReadOnly(readOnly);\n            this.$resetCursorStyle(); \n        },\n        initialValue: false\n    },\n    copyWithEmptySelection: {\n        set: function(value) {\n            this.textInput.setCopyWithEmptySelection(value);\n        },\n        initialValue: false\n    },\n    cursorStyle: {\n        set: function(val) { this.$resetCursorStyle(); },\n        values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n        initialValue: \"ace\"\n    },\n    mergeUndoDeltas: {\n        values: [false, true, \"always\"],\n        initialValue: true\n    },\n    behavioursEnabled: {initialValue: true},\n    wrapBehavioursEnabled: {initialValue: true},\n    enableAutoIndent: {initialValue: true},\n    autoScrollEditorIntoView: {\n        set: function(val) {this.setAutoScrollEditorIntoView(val);}\n    },\n    keyboardHandler: {\n        set: function(val) { this.setKeyboardHandler(val); },\n        get: function() { return this.$keybindingId; },\n        handlesSet: true\n    },\n    value: {\n        set: function(val) { this.session.setValue(val); },\n        get: function() { return this.getValue(); },\n        handlesSet: true,\n        hidden: true\n    },\n    session: {\n        set: function(val) { this.setSession(val); },\n        get: function() { return this.session; },\n        handlesSet: true,\n        hidden: true\n    },\n    \n    showLineNumbers: {\n        set: function(show) {\n            this.renderer.$gutterLayer.setShowLineNumbers(show);\n            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);\n            if (show && this.$relativeLineNumbers)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        },\n        initialValue: true\n    },\n    relativeLineNumbers: {\n        set: function(value) {\n            if (this.$showLineNumbers && value)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        }\n    },\n    placeholder: {\n        set: function(message) {\n            if (!this.$updatePlaceholder) {\n                this.$updatePlaceholder = function() {\n                    var value = this.session && (this.renderer.$composition || this.getValue());\n                    if (value && this.renderer.placeholderNode) {\n                        this.renderer.off(\"afterRender\", this.$updatePlaceholder);\n                        dom.removeCssClass(this.container, \"ace_hasPlaceholder\");\n                        this.renderer.placeholderNode.remove();\n                        this.renderer.placeholderNode = null;\n                    } else if (!value && !this.renderer.placeholderNode) {\n                        this.renderer.on(\"afterRender\", this.$updatePlaceholder);\n                        dom.addCssClass(this.container, \"ace_hasPlaceholder\");\n                        var el = dom.createElement(\"div\");\n                        el.className = \"ace_placeholder\";\n                        el.textContent = this.$placeholder || \"\";\n                        this.renderer.placeholderNode = el;\n                        this.renderer.content.appendChild(this.renderer.placeholderNode);\n                    } else if (!value && this.renderer.placeholderNode) {\n                        this.renderer.placeholderNode.textContent = this.$placeholder || \"\";\n                    }\n                }.bind(this);\n                this.on(\"input\", this.$updatePlaceholder);\n            }\n            this.$updatePlaceholder();\n        }\n    },\n    enableKeyboardAccessibility: {\n        set: function(value) {\n            var blurCommand = {\n                name: \"blurTextInput\",\n                description: \"Set focus to the editor content div to allow tabbing through the page\",\n                bindKey: \"Esc\",\n                exec: function(editor) {\n                    editor.blur();\n                    editor.renderer.content.focus();\n                },\n                readOnly: true\n            };\n\n            var focusOnEnterKeyup = function (e) {\n                if (e.target == this.renderer.content && e.keyCode === keys['enter']){\n                    e.stopPropagation();\n                    e.preventDefault();\n                    this.focus();\n                }\n            };\n\n            var keyboardFocusClassName = \"ace_keyboard-focus\";\n\n            // Prevent focus to be captured when tabbing through the page. When focus is set to the content div, \n            // press Enter key to give focus to Ace and press Esc to again allow to tab through the page.\n            if (value){\n                this.textInput.getElement().setAttribute(\"tabindex\", -1);\n                this.renderer.content.setAttribute(\"tabindex\", 0);\n                this.renderer.content.classList.add(keyboardFocusClassName);\n                this.renderer.content.setAttribute(\"aria-label\",\n                    \"Editor, press Enter key to start editing, press Escape key to exit\"\n                );\n\n                this.renderer.content.addEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.addCommand(blurCommand);\n            } else {\n                this.textInput.getElement().setAttribute(\"tabindex\", 0);\n                this.renderer.content.setAttribute(\"tabindex\", -1);\n                this.renderer.content.classList.remove(keyboardFocusClassName);\n                this.renderer.content.setAttribute(\"aria-label\", \"\");\n            \n                this.renderer.content.removeEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.removeCommand(blurCommand);\n            }\n        },\n        initialValue: false\n    },\n    customScrollbar: \"renderer\",\n    hScrollBarAlwaysVisible: \"renderer\",\n    vScrollBarAlwaysVisible: \"renderer\",\n    highlightGutterLine: \"renderer\",\n    animatedScroll: \"renderer\",\n    showInvisibles: \"renderer\",\n    showPrintMargin: \"renderer\",\n    printMarginColumn: \"renderer\",\n    printMargin: \"renderer\",\n    fadeFoldWidgets: \"renderer\",\n    showFoldWidgets: \"renderer\",\n    displayIndentGuides: \"renderer\",\n    highlightIndentGuides: \"renderer\",\n    showGutter: \"renderer\",\n    fontSize: \"renderer\",\n    fontFamily: \"renderer\",\n    maxLines: \"renderer\",\n    minLines: \"renderer\",\n    scrollPastEnd: \"renderer\",\n    fixedWidthGutter: \"renderer\",\n    theme: \"renderer\",\n    hasCssTransforms: \"renderer\",\n    maxPixelHeight: \"renderer\",\n    useTextareaForIME: \"renderer\",\n    useResizeObserver: \"renderer\",\n    useSvgGutterIcons: \"renderer\",\n\n    scrollSpeed: \"$mouseHandler\",\n    dragDelay: \"$mouseHandler\",\n    dragEnabled: \"$mouseHandler\",\n    focusTimeout: \"$mouseHandler\",\n    tooltipFollowsMouse: \"$mouseHandler\",\n\n    firstLineNumber: \"session\",\n    overwrite: \"session\",\n    newLineMode: \"session\",\n    useWorker: \"session\",\n    useSoftTabs: \"session\",\n    navigateWithinSoftTabs: \"session\",\n    tabSize: \"session\",\n    wrap: \"session\",\n    indentedSoftWrap: \"session\",\n    foldStyle: \"session\",\n    mode: \"session\"\n});\n\n\nvar relativeNumberRenderer = {\n    getText: function(session, row) {\n        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? \"\\xb7\" : \"\"))) + \"\";\n    },\n    getWidth: function(session, lastLineNumber, config) {\n        return Math.max(\n            lastLineNumber.toString().length,\n            (config.lastRow + 1).toString().length,\n            2\n        ) * config.characterWidth;\n    },\n    update: function(e, editor) {\n        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);\n    },\n    attach: function(editor) {\n        editor.renderer.$gutterLayer.$renderer = this;\n        editor.on(\"changeSelection\", this.update);\n        this.update(null, editor);\n    },\n    detach: function(editor) {\n        if (editor.renderer.$gutterLayer.$renderer == this)\n            editor.renderer.$gutterLayer.$renderer = null;\n        editor.off(\"changeSelection\", this.update);\n        this.update(null, editor);\n    }\n};\n\nexports.Editor = Editor;\n"
  },
  {
    "path": "demo/diff/examples/editor.40.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"./virtual_renderer\").VirtualRenderer} VirtualRenderer\n * @typedef {import(\"./selection\").Selection} Selection\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.SearchOptions} SearchOptions\n */\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar useragent = require(\"./lib/useragent\");\nvar TextInput = require(\"./keyboard/textinput\").TextInput;\nvar MouseHandler = require(\"./mouse/mouse_handler\").MouseHandler;\nvar FoldHandler = require(\"./mouse/fold_handler\").FoldHandler;\nvar KeyBinding = require(\"./keyboard/keybinding\").KeyBinding;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Search = require(\"./search\").Search;\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar CommandManager = require(\"./commands/command_manager\").CommandManager;\nvar defaultCommands = require(\"./commands/default_commands\").commands;\nvar config = require(\"./config\");\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\nvar GutterKeyboardHandler = require(\"./keyboard/gutter_handler\").GutterKeyboardHandler;\nvar nls = require(\"./config\").nls;\n\nvar clipboard = require(\"./clipboard\");\nvar keys = require('./lib/keys');\n\nvar event = require(\"./lib/event\");\nvar HoverTooltip = require(\"./tooltip\").HoverTooltip;\n\n/**\n * The main entry point into the Ace functionality.\n *\n * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.\n *\n * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.\n **/\nclass Editor {\n    /**\n     * Creates a new `Editor` object.\n     *\n     * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything\n     * @param {EditSession} [session] The `EditSession` to refer to\n     * @param {Partial<import(\"../ace-internal\").Ace.EditorOptions>} [options] The default options\n     **/\n    constructor(renderer, session, options) {\n        /**@type{EditSession}*/this.session;\n        this.$toDestroy = [];\n\n        var container = renderer.getContainerElement();\n        /**@type {HTMLElement & {env?:any, value?:any}}*/\n        this.container = container;\n        /**@type {VirtualRenderer}*/\n        this.renderer = renderer;\n        /**@type {string}*/\n        this.id = \"editor\" + (++Editor.$uid);\n        this.commands = new CommandManager(useragent.isMac ? \"mac\" : \"win\", defaultCommands);\n        if (typeof document == \"object\") {\n            this.textInput = new TextInput(renderer.getTextAreaContainer(), this);\n            this.renderer.textarea = this.textInput.getElement();\n            // TODO detect touch event support\n            /**@type {MouseHandler}*/\n            this.$mouseHandler = new MouseHandler(this);\n            new FoldHandler(this);\n        }\n        /**@type {KeyBinding}*/\n        this.keyBinding = new KeyBinding(this);\n        /**@type {Search}*/\n        this.$search = new Search().set({\n            wrap: true\n        });\n\n        this.$historyTracker = this.$historyTracker.bind(this);\n        this.commands.on(\"exec\", this.$historyTracker);\n\n        this.$initOperationListeners();\n\n        this._$emitInputEvent = lang.delayedCall(function() {\n            this._signal(\"input\", {});\n            if (this.session && !this.session.destroyed)\n                this.session.bgTokenizer.scheduleStart();\n        }.bind(this));\n\n        this.on(\"change\", function(_, _self) {\n            _self._$emitInputEvent.schedule(31);\n        });\n\n        this.setSession(session || options && options.session || new EditSession(\"\"));\n        config.resetOptions(this);\n        if (options)\n            this.setOptions(options);\n        config._signal(\"editor\", this);\n    }\n\n    $initOperationListeners() {\n        this.commands.on(\"exec\", this.startOperation.bind(this), true);\n        this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n    }\n\n    startOperation(commandEvent) {\n        this.session.startOperation(commandEvent);\n    }\n\n    /**\n     * @arg e\n     */\n    endOperation(e) {\n        this.session.endOperation(e);\n    }\n\n    onStartOperation(commandEvent) {\n        this.curOp = this.session.curOp;\n        this.curOp.scrollTop = this.renderer.scrollTop;\n        this.prevOp = this.session.prevOp;\n\n        if (!commandEvent) {\n            this.previousCommand = null;\n        }\n    }\n\n    /**\n     * @arg e\n     */\n    onEndOperation(e) {\n        if (this.curOp && this.session) {\n            if (e && e.returnValue === false) {\n                this.curOp = null;\n                return;\n            }\n\n            this._signal(\"beforeEndOperation\");\n            if (!this.curOp) return;\n\n            var command = this.curOp.command;\n            var scrollIntoView = command && command.scrollIntoView;\n            if (scrollIntoView) {\n                switch (scrollIntoView) {\n                    case \"center-animate\":\n                        scrollIntoView = \"animate\";\n                        /* fall through */\n                    case \"center\":\n                        this.renderer.scrollCursorIntoView(null, 0.5);\n                        break;\n                    case \"animate\":\n                    case \"cursor\":\n                        this.renderer.scrollCursorIntoView();\n                        break;\n                    case \"selectionPart\":\n                        var range = this.selection.getRange();\n                        var config = this.renderer.layerConfig;\n                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {\n                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);\n                        }\n                        break;\n                    default:\n                        break;\n                }\n                if (scrollIntoView == \"animate\")\n                    this.renderer.animateScrolling(this.curOp.scrollTop);\n            }\n\n            this.$lastSel = this.session.selection.toJSON();\n            this.prevOp = this.curOp;\n            this.curOp = null;\n        }\n    }\n\n    /**\n     * @param e\n     */\n    $historyTracker(e) {\n        if (!this.$mergeUndoDeltas)\n            return;\n\n        var prev = this.prevOp;\n        var mergeableCommands = this.$mergeableCommands;\n        // previous command was the same\n        var shouldMerge = prev.command && (e.command.name == prev.command.name);\n        if (e.command.name == \"insertstring\") {\n            var text = e.args;\n            if (this.mergeNextCommand === undefined)\n                this.mergeNextCommand = true;\n\n            shouldMerge = shouldMerge\n                && this.mergeNextCommand // previous command allows to coalesce with\n                && (!/\\s/.test(text) || /\\s/.test(prev.args)); // previous insertion was of same type\n\n            this.mergeNextCommand = true;\n        } else {\n            shouldMerge = shouldMerge\n                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n        }\n\n        if (\n            this.$mergeUndoDeltas != \"always\"\n            && Date.now() - this.sequenceStartTime > 2000\n        ) {\n            shouldMerge = false; // the sequence is too long\n        }\n\n        if (shouldMerge)\n            this.session.mergeUndoDeltas = true;\n        else if (mergeableCommands.indexOf(e.command.name) !== -1)\n            this.sequenceStartTime = Date.now();\n    }\n\n    /**\n     * Sets a new key handler, such as \"vim\" or \"windows\".\n     * @param {String | import(\"../ace-internal\").Ace.KeyboardHandler | null} keyboardHandler The new key handler\n     * @param {() => void} [cb]\n     **/\n    setKeyboardHandler(keyboardHandler, cb) {\n        if (keyboardHandler && typeof keyboardHandler === \"string\" && keyboardHandler != \"ace\") {\n            this.$keybindingId = keyboardHandler;\n            var _self = this;\n            config.loadModule([\"keybinding\", keyboardHandler], function(module) {\n                if (_self.$keybindingId == keyboardHandler)\n                    _self.keyBinding.setKeyboardHandler(module && module.handler);\n                cb && cb();\n            });\n        } else {\n            this.$keybindingId = null;\n            // @ts-ignore\n            this.keyBinding.setKeyboardHandler(keyboardHandler);\n            cb && cb();\n        }\n    }\n\n    /**\n     * Returns the keyboard handler, such as \"vim\" or \"windows\".\n     * @returns {Object}\n     **/\n    getKeyboardHandler() {\n        return this.keyBinding.getKeyboardHandler();\n    }\n\n\n\n    /**\n     * Sets a new editsession to use. This method also emits the `'changeSession'` event.\n     * @param {EditSession} [session] The new session to use\n     **/\n    setSession(session) {\n        if (this.session == session)\n            return;\n\n        // make sure operationEnd events are not emitted to wrong session\n        if (this.curOp) this.endOperation();\n        this.curOp = {};\n\n        var oldSession = this.session;\n        if (oldSession) {\n            this.session.off(\"change\", this.$onDocumentChange);\n            this.session.off(\"changeMode\", this.$onChangeMode);\n            this.session.off(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n            this.session.off(\"changeTabSize\", this.$onChangeTabSize);\n            this.session.off(\"changeWrapLimit\", this.$onChangeWrapLimit);\n            this.session.off(\"changeWrapMode\", this.$onChangeWrapMode);\n            this.session.off(\"changeFold\", this.$onChangeFold);\n            this.session.off(\"changeFrontMarker\", this.$onChangeFrontMarker);\n            this.session.off(\"changeBackMarker\", this.$onChangeBackMarker);\n            this.session.off(\"changeBreakpoint\", this.$onChangeBreakpoint);\n            this.session.off(\"changeAnnotation\", this.$onChangeAnnotation);\n            this.session.off(\"changeOverwrite\", this.$onCursorChange);\n            this.session.off(\"changeScrollTop\", this.$onScrollTopChange);\n            this.session.off(\"changeScrollLeft\", this.$onScrollLeftChange);\n            this.session.off(\"startOperation\", this.$onStartOperation);\n            this.session.off(\"endOperation\", this.$onEndOperation);\n\n            var selection = this.session.getSelection();\n            selection.off(\"changeCursor\", this.$onCursorChange);\n            selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n\n        this.session = session;\n        if (session) {\n            this.$onDocumentChange = this.onDocumentChange.bind(this);\n            session.on(\"change\", this.$onDocumentChange);\n            this.renderer.setSession(session);\n\n            this.$onChangeMode = this.onChangeMode.bind(this);\n            session.on(\"changeMode\", this.$onChangeMode);\n\n            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n            session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n\n            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n            session.on(\"changeTabSize\", this.$onChangeTabSize);\n\n            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n            session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n\n            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n            session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n\n            this.$onChangeFold = this.onChangeFold.bind(this);\n            session.on(\"changeFold\", this.$onChangeFold);\n\n            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n            this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n\n            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n            this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n\n            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n            this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n\n            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n            this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n\n            this.$onCursorChange = this.onCursorChange.bind(this);\n            this.session.on(\"changeOverwrite\", this.$onCursorChange);\n\n            this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n            this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n\n            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n            this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n\n            this.selection = session.getSelection();\n            this.selection.on(\"changeCursor\", this.$onCursorChange);\n\n            this.$onSelectionChange = this.onSelectionChange.bind(this);\n            this.selection.on(\"changeSelection\", this.$onSelectionChange);\n\n            this.$onStartOperation = this.onStartOperation.bind(this);\n            this.session.on(\"startOperation\", this.$onStartOperation);\n            this.$onEndOperation = this.onEndOperation.bind(this);\n            this.session.on(\"endOperation\", this.$onEndOperation);\n\n            this.onChangeMode();\n\n            this.onCursorChange();\n\n            this.onScrollTopChange();\n            this.onScrollLeftChange();\n            this.onSelectionChange();\n            this.onChangeFrontMarker();\n            this.onChangeBackMarker();\n            this.onChangeBreakpoint();\n            this.onChangeAnnotation();\n            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();\n            this.renderer.updateFull();\n        } else {\n            this.selection = null;\n            this.renderer.setSession(session);\n        }\n\n        this._signal(\"changeSession\", {\n            session: session,\n            oldSession: oldSession\n        });\n\n        this.curOp = null;\n\n        oldSession && oldSession._signal(\"changeEditor\", {oldEditor: this});\n        if (oldSession) oldSession.$editor = null;\n        session && session._signal(\"changeEditor\", {editor: this});\n        if (session) session.$editor = this;\n\n        if (session && !session.destroyed)\n            session.bgTokenizer.scheduleStart();\n    }\n\n    /**\n     * Returns the current session being used.\n     * @returns {EditSession}\n     **/\n    getSession() {\n        return this.session;\n    }\n\n    /**\n     * Sets the current document to `val`.\n     * @param {String} val The new value to set for the document\n     * @param {Number} [cursorPos] Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end\n     *\n     * @returns {String} The current document value\n     * @related Document.setValue\n     **/\n    setValue(val, cursorPos) {\n        this.session.doc.setValue(val);\n\n        if (!cursorPos)\n            this.selectAll();\n        else if (cursorPos == 1)\n            this.navigateFileEnd();\n        else if (cursorPos == -1)\n            this.navigateFileStart();\n\n        return val;\n    }\n\n    /**\n     * Returns the current session's content.\n     *\n     * @returns {String}\n     * @related EditSession.getValue\n     **/\n    getValue() {\n        return this.session.getValue();\n    }\n\n    /**\n     *\n     * Returns the currently highlighted selection.\n     * @returns {Selection} The selection object\n     **/\n    getSelection() {\n        return this.selection;\n    }\n\n    /**\n     * {:VirtualRenderer.onResize}\n     * @param {Boolean} [force] If `true`, recomputes the size, even if the height and width haven't changed\n     * @related VirtualRenderer.onResize\n     **/\n    resize(force) {\n        this.renderer.onResize(force);\n    }\n\n    /**\n     * {:VirtualRenderer.setTheme}\n     * @param {string | import(\"../ace-internal\").Ace.Theme} theme The path to a theme\n     * @param {() => void} [cb] optional callback called when theme is loaded\n     **/\n    setTheme(theme, cb) {\n        this.renderer.setTheme(theme, cb);\n    }\n\n    /**\n     * {:VirtualRenderer.getTheme}\n     *\n     * @returns {String} The set theme\n     * @related VirtualRenderer.getTheme\n     **/\n    getTheme() {\n        return this.renderer.getTheme();\n    }\n\n    /**\n     * {:VirtualRenderer.setStyle}\n     * @param {String} style A class name\n     * @related VirtualRenderer.setStyle\n     **/\n    setStyle(style) {\n        this.renderer.setStyle(style);\n    }\n\n    /**\n     * {:VirtualRenderer.unsetStyle}\n     * @related VirtualRenderer.unsetStyle\n     * @param {string} style\n     */\n    unsetStyle(style) {\n        this.renderer.unsetStyle(style);\n    }\n\n    /**\n     * Gets the current font size of the editor text.\n     * @return {string | number}\n     */\n    getFontSize() {\n        return this.getOption(\"fontSize\") ||\n           dom.computedStyle(this.container).fontSize;\n    }\n\n    /**\n     * Set a new font size (in pixels) for the editor text.\n     * @param {String | number} size A font size ( _e.g._ \"12px\")\n     **/\n    setFontSize(size) {\n        this.setOption(\"fontSize\", size);\n    }\n\n    $highlightBrackets() {\n        if (this.$highlightPending) {\n            return;\n        }\n\n        // perform highlight async to not block the browser during navigation\n        var self = this;\n        this.$highlightPending = true;\n        setTimeout(function () {\n            self.$highlightPending = false;\n            var session = self.session;\n            if (!session || session.destroyed) return;\n            if (session.$bracketHighlight) {\n                session.$bracketHighlight.markerIds.forEach(function(id) {\n                    session.removeMarker(id);\n                });\n                session.$bracketHighlight = null;\n            }\n            var pos = self.getCursorPosition();\n            var handler = self.getKeyboardHandler();\n            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);\n            var ranges = session.getMatchingBracketRanges(pos, isBackwards);\n\n            if (!ranges) {\n                var iterator = new TokenIterator(session, pos.row, pos.column);\n                var token = iterator.getCurrentToken();\n\n                if (token && /\\b(?:tag-open|tag-name)/.test(token.type)) {\n                    var tagNamesRanges = session.getMatchingTags(pos);\n                    if (tagNamesRanges) {\n                        ranges = [\n                            tagNamesRanges.openTagName.isEmpty() ? tagNamesRanges.openTag : tagNamesRanges.openTagName,\n                            tagNamesRanges.closeTagName.isEmpty() ? tagNamesRanges.closeTag : tagNamesRanges.closeTagName\n                        ];\n                    }\n                }\n            }\n            if (!ranges && session.$mode.getMatching)\n                ranges = session.$mode.getMatching(self.session);\n            if (!ranges) {\n                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n                return;\n            }\n\n            var markerType = \"ace_bracket\";\n            if (!Array.isArray(ranges)) {\n                ranges = [ranges];\n            } else if (ranges.length == 1) {\n                markerType = \"ace_error_bracket\";\n            }\n\n            // show adjacent ranges as one\n            if (ranges.length == 2) {\n                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)\n                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];\n                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)\n                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];\n            }\n\n            session.$bracketHighlight = {\n                ranges: ranges,\n                markerIds: ranges.map(function(range) {\n                    return session.addMarker(range, markerType, \"text\");\n                })\n            };\n            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n        }, 50);\n    }\n\n    /**\n     *\n     * Brings the current `textInput` into focus.\n     **/\n    focus() {\n        this.textInput.focus();\n    }\n\n    /**\n     * Returns `true` if the current `textInput` is in focus.\n     * @return {Boolean}\n     **/\n    isFocused() {\n        return this.textInput.isFocused();\n    }\n\n    /**\n     *\n     * Blurs the current `textInput`.\n     **/\n    blur() {\n        this.textInput.blur();\n    }\n\n    /**\n     * Emitted once the editor comes into focus.\n     * @internal\n     **/\n    onFocus(e) {\n        if (this.$isFocused)\n            return;\n        this.$isFocused = true;\n        this.renderer.showCursor();\n        this.renderer.visualizeFocus();\n        this._emit(\"focus\", e);\n    }\n\n    /**\n     * Emitted once the editor has been blurred.\n     * @internal\n     **/\n    onBlur(e) {\n        if (!this.$isFocused)\n            return;\n        this.$isFocused = false;\n        this.renderer.hideCursor();\n        this.renderer.visualizeBlur();\n        this._emit(\"blur\", e);\n    }\n\n    /**\n     */\n    $cursorChange() {\n        this.renderer.updateCursor();\n        this.$highlightBrackets();\n        this.$updateHighlightActiveLine();\n    }\n\n    /**\n     * Emitted whenever the document is changed.\n     * @param {import(\"../ace-internal\").Ace.Delta} delta Contains a single property, `data`, which has the delta of changes\n     * @internal\n     **/\n    onDocumentChange(delta) {\n        // Rerender and emit \"change\" event.\n        var wrap = this.session.$useWrapMode;\n        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);\n        this.renderer.updateLines(delta.start.row, lastRow, wrap);\n\n        this._signal(\"change\", delta);\n\n        // Update cursor because tab characters can influence the cursor position.\n        this.$cursorChange();\n    }\n\n    /**\n     * @internal\n     */\n    onTokenizerUpdate(e) {\n        var rows = e.data;\n        this.renderer.updateLines(rows.first, rows.last);\n    }\n\n    /**\n     * @internal\n     */\n    onScrollTopChange() {\n        this.renderer.scrollToY(this.session.getScrollTop());\n    }\n\n    /**\n     * @internal\n     */\n    onScrollLeftChange() {\n        this.renderer.scrollToX(this.session.getScrollLeft());\n    }\n\n    /**\n     * Emitted when the selection changes.\n     * @internal\n     **/\n    onCursorChange() {\n        this.$cursorChange();\n        this._signal(\"changeSelection\");\n    }\n\n    /**\n     */\n    $updateHighlightActiveLine() {\n        var session = this.getSession();\n        /**@type {Point|false}*/\n        var highlight;\n        if (this.$highlightActiveLine) {\n            if (this.$selectionStyle != \"line\" || !this.selection.isMultiLine())\n                highlight = this.getCursorPosition();\n            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())\n                highlight = false;\n            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))\n                highlight = false;\n        }\n\n        if (session.$highlightLineMarker && !highlight) {\n            session.removeMarker(session.$highlightLineMarker.id);\n            session.$highlightLineMarker = null;\n        } else if (!session.$highlightLineMarker && highlight) {\n            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);\n            range.id = session.addMarker(range, \"ace_active-line\", \"screenLine\");\n            session.$highlightLineMarker = range;\n        } else if (highlight) {\n            session.$highlightLineMarker.start.row = highlight.row;\n            session.$highlightLineMarker.end.row = highlight.row;\n            session.$highlightLineMarker.start.column = highlight.column;\n            session._signal(\"changeBackMarker\");\n        }\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onSelectionChange(e) {\n        var session = this.session;\n\n        if (session.$selectionMarker) {\n            session.removeMarker(session.$selectionMarker);\n        }\n        session.$selectionMarker = null;\n\n        if (!this.selection.isEmpty()) {\n            var range = this.selection.getRange();\n            var style = this.getSelectionStyle();\n            session.$selectionMarker = session.addMarker(range, \"ace_selection\", style);\n        } else {\n            this.$updateHighlightActiveLine();\n        }\n\n        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n        this.session.highlight(re);\n\n        this._signal(\"changeSelection\");\n    }\n\n    $getSelectionHighLightRegexp() {\n        var session = this.session;\n\n        var selection = this.getSelectionRange();\n        if (selection.isEmpty() || selection.isMultiLine())\n            return;\n\n        var startColumn = selection.start.column;\n        var endColumn = selection.end.column;\n        var line = session.getLine(selection.start.row);\n\n        var needle = line.substring(startColumn, endColumn);\n        // maximum allowed size for regular expressions in 32000,\n        // but getting close to it has significant impact on the performance\n        if (needle.length > 5000 || !/[\\w\\d]/.test(needle))\n            return;\n\n        var re = this.$search.$assembleRegExp({\n            wholeWord: true,\n            caseSensitive: true,\n            needle: needle\n        });\n\n        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);\n        if (!re.test(wordWithBoundary))\n            return;\n\n        return re;\n    }\n\n    /**\n     * @internal\n     */\n    onChangeFrontMarker() {\n        this.renderer.updateFrontMarkers();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeBackMarker() {\n        this.renderer.updateBackMarkers();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeBreakpoint() {\n        this.renderer.updateBreakpoints();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeAnnotation() {\n        this.renderer.setAnnotations(this.session.getAnnotations());\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onChangeMode (e) {\n        this.renderer.updateText();\n        this._emit(\"changeMode\", e);\n    }\n\n    /**\n     * @internal\n     */\n    onChangeWrapLimit() {\n        this.renderer.updateFull();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeWrapMode() {\n        this.renderer.onResize(true);\n    }\n\n\n    /**\n     * @internal\n     */\n    onChangeFold() {\n        // Update the active line marker as due to folding changes the current\n        // line range on the screen might have changed.\n        this.$updateHighlightActiveLine();\n        // TODO: This might be too much updating. Okay for now.\n        this.renderer.updateFull();\n    }\n\n\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getSelectedText() {\n        return this.session.getTextRange(this.getSelectionRange());\n    }\n\n\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getCopyText () {\n        var text = this.getSelectedText();\n        var nl = this.session.doc.getNewLineCharacter();\n        var copyLine= false;\n        if (!text && this.$copyWithEmptySelection) {\n            copyLine = true;\n            var ranges = this.selection.getAllRanges();\n            for (var i = 0; i < ranges.length; i++) {\n                var range = ranges[i];\n                if (i && ranges[i - 1].start.row == range.start.row)\n                    continue;\n                text += this.session.getLine(range.start.row) + nl;\n            }\n        }\n        var e = {text: text};\n        this._signal(\"copy\", e);\n        clipboard.lineMode = copyLine ? e.text : false;\n        return e.text;\n    }\n\n    /**\n     * Called whenever a text \"copy\" happens.\n     * @internal\n     **/\n    onCopy() {\n        this.commands.exec(\"copy\", this);\n    }\n\n    /**\n     * Called whenever a text \"cut\" happens.\n     * @internal\n     **/\n    onCut() {\n        this.commands.exec(\"cut\", this);\n    }\n\n\n    /**\n     * Called whenever a text \"paste\" happens.\n     * @param {String} text The pasted text\n     * @param {ClipboardEvent} [event]\n     * @internal\n     **/\n    onPaste(text, event) {\n        var e = {text: text, event: event};\n        this.commands.exec(\"paste\", this, e);\n    }\n\n    /**\n     *\n     * @param {string | {text: string, event?: ClipboardEvent}} e\n     * @returns {boolean}\n     */\n    $handlePaste(e) {\n        if (typeof e == \"string\")\n            e = {text: e};\n        this._signal(\"paste\", e);\n        var text = e.text;\n\n        var lineMode = text === clipboard.lineMode;\n        var session = this.session;\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n            if (lineMode)\n                session.insert({ row: this.selection.lead.row, column: 0 }, text);\n            else\n                this.insert(text);\n        } else if (lineMode) {\n            this.selection.rangeList.ranges.forEach(function(range) {\n                session.insert({ row: range.start.row, column: 0 }, text);\n            });\n        } else {\n            var lines = text.split(/\\r\\n|\\r|\\n/);\n            var ranges = this.selection.rangeList.ranges;\n\n            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);\n            if (lines.length != ranges.length || isFullLine)\n                return this.commands.exec(\"insertstring\", this, text);\n\n            for (var i = ranges.length; i--;) {\n                var range = ranges[i];\n                if (!range.isEmpty())\n                    session.remove(range);\n\n                session.insert(range.start, lines[i]);\n            }\n        }\n    }\n\n    /**\n     *\n     * @param {string | string[]} command\n     * @param [args]\n     * @return {boolean}\n     */\n    execCommand(command, args) {\n        return this.commands.exec(command, this, args);\n    }\n\n    /**\n     * Inserts `text` into wherever the cursor is pointing.\n     * @param {String} text The new text to add\n     * @param {boolean} [pasted]\n     **/\n    insert(text, pasted) {\n        var session = this.session;\n        var mode = session.getMode();\n        var cursor = this.getCursorPosition();\n\n        if (this.getBehavioursEnabled() && !pasted) {\n            // Get a transform if the current mode wants one.\n            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);\n            if (transform) {\n                if (text !== transform.text) {\n                    // keep automatic insertion in a separate delta, unless it is in multiselect mode\n                    if (!this.inVirtualSelectionMode) {\n                        this.session.mergeUndoDeltas = false;\n                        this.mergeNextCommand = false;\n                    }\n                }\n                text = transform.text;\n\n            }\n        }\n\n        if (text == \"\\t\")\n            text = this.session.getTabString();\n\n        // remove selected text\n        if (!this.selection.isEmpty()) {\n            var range = this.getSelectionRange();\n            cursor = this.session.remove(range);\n            this.clearSelection();\n        }\n        else if (this.session.getOverwrite() && text.indexOf(\"\\n\") == -1) {\n            var range = Range.fromPoints(cursor, cursor);\n            range.end.column += text.length;\n            this.session.remove(range);\n        }\n\n        if (text == \"\\n\" || text == \"\\r\\n\") {\n            var line = session.getLine(cursor.row);\n            if (cursor.column > line.search(/\\S|$/)) {\n                var d = line.substr(cursor.column).search(/\\S|$/);\n                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);\n            }\n        }\n        this.clearSelection();\n\n        var start = cursor.column;\n        var lineState = session.getState(cursor.row);\n        var line = session.getLine(cursor.row);\n        var shouldOutdent = mode.checkOutdent(lineState, line, text);\n        session.insert(cursor, text);\n\n        if (transform && transform.selection) {\n            if (transform.selection.length == 2) { // Transform relative to the current column\n                this.selection.setSelectionRange(\n                    new Range(cursor.row, start + transform.selection[0],\n                              cursor.row, start + transform.selection[1]));\n            } else { // Transform relative to the current row.\n                this.selection.setSelectionRange(\n                    new Range(cursor.row + transform.selection[0],\n                              transform.selection[1],\n                              cursor.row + transform.selection[2],\n                              transform.selection[3]));\n            }\n        }\n        if (this.$enableAutoIndent) {\n            if (session.getDocument().isNewLine(text)) {\n                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n\n                session.insert({row: cursor.row+1, column: 0}, lineIndent);\n            }\n            if (shouldOutdent)\n                mode.autoOutdent(lineState, session, cursor.row);\n        }\n    }\n\n    autoIndent() {\n        var session = this.session;\n        var mode = session.getMode();\n\n        var ranges = this.selection.isEmpty()\n            ? [new Range(0, 0, session.doc.getLength() - 1, 0)]\n            : this.selection.getAllRanges();\n\n        /**@type{string|string[]}*/\n        var prevLineState = \"\";\n        var prevLine = \"\";\n        var lineIndent = \"\";\n        var tab = session.getTabString();\n        for (var i = 0; i < ranges.length; i++) {\n            var startRow = ranges[i].start.row;\n            var endRow = ranges[i].end.row;\n\n            for (var row = startRow; row <= endRow; row++) {\n                if (row > 0) {\n                    prevLineState = session.getState(row - 1);\n                    prevLine = session.getLine(row - 1);\n                    lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);\n                }\n\n                var line = session.getLine(row);\n                var currIndent = mode.$getIndent(line);\n                if (lineIndent !== currIndent) {\n                    if (currIndent.length > 0) {\n                        var range = new Range(row, 0, row, currIndent.length);\n                        session.remove(range);\n                    }\n                    if (lineIndent.length > 0) {\n                        session.insert({row: row, column: 0}, lineIndent);\n                    }\n                }\n\n                mode.autoOutdent(prevLineState, session, row);\n            }\n        }\n    }\n\n    /**\n     *\n     * @param text\n     * @param composition\n     * @returns {*}\n     * @internal\n     */\n    onTextInput(text, composition) {\n        if (!composition)\n            return this.keyBinding.onTextInput(text);\n\n        this.startOperation({command: { name: \"insertstring\" }});\n        var applyComposition = this.applyComposition.bind(this, text, composition);\n        if (this.selection.rangeCount)\n            this.forEachSelection(applyComposition);\n        else\n            applyComposition();\n        this.endOperation();\n    }\n\n    /**\n     * @param {string} [text]\n     * @param {any} [composition]\n     */\n    applyComposition(text, composition) {\n        if (composition.extendLeft || composition.extendRight) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.extendLeft;\n            r.end.column += composition.extendRight;\n            if (r.start.column < 0) {\n                r.start.row--;\n                r.start.column += this.session.getLine(r.start.row).length + 1;\n            }\n            this.selection.setRange(r);\n            if (!text && !r.isEmpty())\n                this.remove();\n        }\n        if (text || !this.selection.isEmpty())\n            this.insert(text, true);\n        if (composition.restoreStart || composition.restoreEnd) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.restoreStart;\n            r.end.column -= composition.restoreEnd;\n            this.selection.setRange(r);\n        }\n    }\n\n    /**\n     * @internal\n     */\n    onCommandKey(e, hashId, keyCode) {\n        return this.keyBinding.onCommandKey(e, hashId, keyCode);\n    }\n\n    /**\n     * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n     * @param {Boolean} overwrite Defines whether or not to set overwrites\n     * @related EditSession.setOverwrite\n     **/\n    setOverwrite(overwrite) {\n        this.session.setOverwrite(overwrite);\n    }\n\n    /**\n     * Returns `true` if overwrites are enabled; `false` otherwise.\n     * @returns {Boolean}\n     * @related EditSession.getOverwrite\n     **/\n    getOverwrite() {\n        return this.session.getOverwrite();\n    }\n\n    /**\n     * Sets the value of overwrite to the opposite of whatever it currently is.\n     * @related EditSession.toggleOverwrite\n     **/\n    toggleOverwrite() {\n        this.session.toggleOverwrite();\n    }\n\n    /**\n     * Sets how fast the mouse scrolling should do.\n     * @param {Number} speed A value indicating the new speed (in milliseconds)\n     **/\n    setScrollSpeed(speed) {\n        this.setOption(\"scrollSpeed\", speed);\n    }\n\n    /**\n     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).\n     * @returns {Number}\n     **/\n    getScrollSpeed() {\n        return this.getOption(\"scrollSpeed\");\n    }\n\n    /**\n     * Sets the delay (in milliseconds) of the mouse drag.\n     * @param {Number} dragDelay A value indicating the new delay\n     **/\n    setDragDelay(dragDelay) {\n        this.setOption(\"dragDelay\", dragDelay);\n    }\n\n    /**\n     * Returns the current mouse drag delay.\n     * @returns {Number}\n     **/\n    getDragDelay() {\n        return this.getOption(\"dragDelay\");\n    }\n\n\n    /**\n     * Draw selection markers spanning whole line, or only over selected text. Default value is \"line\"\n     * @param {\"fullLine\" | \"screenLine\" | \"text\" | \"line\"} val The new selection style \"line\"|\"text\"\n     **/\n    setSelectionStyle(val) {\n        this.setOption(\"selectionStyle\", val);\n    }\n\n    /**\n     * Returns the current selection style.\n     * @returns {import(\"../ace-internal\").Ace.EditorOptions[\"selectionStyle\"]}\n     **/\n    getSelectionStyle() {\n        return this.getOption(\"selectionStyle\");\n    }\n\n    /**\n     * Determines whether or not the current line should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line\n     **/\n    setHighlightActiveLine(shouldHighlight) {\n        this.setOption(\"highlightActiveLine\", shouldHighlight);\n    }\n    /**\n     * Returns `true` if current lines are always highlighted.\n     * @return {Boolean}\n     **/\n    getHighlightActiveLine() {\n        return this.getOption(\"highlightActiveLine\");\n    }\n\n    /**\n     * @param {boolean} shouldHighlight\n     */\n    setHighlightGutterLine(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    }\n\n    /**\n     * @returns {Boolean}\n     */\n    getHighlightGutterLine() {\n        return this.getOption(\"highlightGutterLine\");\n    }\n\n    /**\n     * Determines if the currently selected word should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word\n     **/\n    setHighlightSelectedWord(shouldHighlight) {\n        this.setOption(\"highlightSelectedWord\", shouldHighlight);\n    }\n\n    /**\n     * Returns `true` if currently highlighted words are to be highlighted.\n     * @returns {Boolean}\n     **/\n    getHighlightSelectedWord() {\n        return this.$highlightSelectedWord;\n    }\n\n    /**\n     * @param {boolean} shouldAnimate\n     */\n    setAnimatedScroll(shouldAnimate){\n        this.renderer.setAnimatedScroll(shouldAnimate);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getAnimatedScroll(){\n        return this.renderer.getAnimatedScroll();\n    }\n\n    /**\n     * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.\n     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters\n     **/\n    setShowInvisibles(showInvisibles) {\n        this.renderer.setShowInvisibles(showInvisibles);\n    }\n\n    /**\n     * Returns `true` if invisible characters are being shown.\n     * @returns {Boolean}\n     **/\n    getShowInvisibles() {\n        return this.renderer.getShowInvisibles();\n    }\n\n    /**\n     * @param {boolean} display\n     */\n    setDisplayIndentGuides(display) {\n        this.renderer.setDisplayIndentGuides(display);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getDisplayIndentGuides() {\n        return this.renderer.getDisplayIndentGuides();\n    }\n\n    /**\n     * @param {boolean} highlight\n     */\n    setHighlightIndentGuides(highlight) {\n        this.renderer.setHighlightIndentGuides(highlight);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getHighlightIndentGuides() {\n        return this.renderer.getHighlightIndentGuides();\n    }\n\n    /**\n     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.\n     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin\n     *\n     **/\n    setShowPrintMargin(showPrintMargin) {\n        this.renderer.setShowPrintMargin(showPrintMargin);\n    }\n\n    /**\n     * Returns `true` if the print margin is being shown.\n     * @returns {Boolean}\n     **/\n    getShowPrintMargin() {\n        return this.renderer.getShowPrintMargin();\n    }\n\n    /**\n     * Sets the column defining where the print margin should be.\n     * @param {Number} showPrintMargin Specifies the new print margin\n     *\n     **/\n    setPrintMarginColumn(showPrintMargin) {\n        this.renderer.setPrintMarginColumn(showPrintMargin);\n    }\n\n    /**\n     * Returns the column number of where the print margin is.\n     * @returns {Number}\n     **/\n    getPrintMarginColumn() {\n        return this.renderer.getPrintMarginColumn();\n    }\n\n    /**\n     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.\n     * @param {Boolean} readOnly Specifies whether the editor can be modified or not\n     **/\n    setReadOnly(readOnly) {\n        this.setOption(\"readOnly\", readOnly);\n    }\n\n    /**\n     * Returns `true` if the editor is set to read-only mode.\n     * @returns {Boolean}\n     **/\n    getReadOnly() {\n        return this.getOption(\"readOnly\");\n    }\n\n    /**\n     * Specifies whether to use behaviors or not. [\"Behaviors\" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}\n     * @param {Boolean} enabled Enables or disables behaviors\n     **/\n    setBehavioursEnabled(enabled) {\n        this.setOption(\"behavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}\n     * @returns {Boolean}\n     **/\n    getBehavioursEnabled() {\n        return this.getOption(\"behavioursEnabled\");\n    }\n\n    /**\n     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets\n     * when such a character is typed in.\n     * @param {Boolean} enabled Enables or disables wrapping behaviors\n     **/\n    setWrapBehavioursEnabled(enabled) {\n        this.setOption(\"wrapBehavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the wrapping behaviors are currently enabled.\n     * @returns {boolean}\n     **/\n    getWrapBehavioursEnabled() {\n        return this.getOption(\"wrapBehavioursEnabled\");\n    }\n\n    /**\n     * Indicates whether the fold widgets should be shown or not.\n     * @param {Boolean} show Specifies whether the fold widgets are shown\n     **/\n    setShowFoldWidgets(show) {\n        this.setOption(\"showFoldWidgets\", show);\n\n    }\n    /**\n     * Returns `true` if the fold widgets are shown.\n     * @return {Boolean}\n     **/\n    getShowFoldWidgets() {\n        return this.getOption(\"showFoldWidgets\");\n    }\n\n    /**\n     * @param {boolean} fade\n     */\n    setFadeFoldWidgets(fade) {\n        this.setOption(\"fadeFoldWidgets\", fade);\n    }\n\n    /**\n     * @returns {boolean}\n     */\n    getFadeFoldWidgets() {\n        return this.getOption(\"fadeFoldWidgets\");\n    }\n\n    /**\n     * Removes the current selection or one character.\n     * @param {'left' | 'right'} [dir] The direction of the deletion to occur, either \"left\" or \"right\"\n     **/\n    remove(dir) {\n        if (this.selection.isEmpty()){\n            if (dir == \"left\")\n                this.selection.selectLeft();\n            else\n                this.selection.selectRight();\n        }\n\n        var range = this.getSelectionRange();\n        if (this.getBehavioursEnabled()) {\n            var session = this.session;\n            var state = session.getState(range.start.row);\n            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);\n\n            if (range.end.column === 0) {\n                var text = session.getTextRange(range);\n                if (text[text.length - 1] == \"\\n\") {\n                    var line = session.getLine(range.end.row);\n                    if (/^\\s+$/.test(line)) {\n                        range.end.column = line.length;\n                    }\n                }\n            }\n            if (new_range)\n                // @ts-expect-error TODO: possible bug, new_range could be not a Range\n                range = new_range;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the right of the current selection.\n     **/\n    removeWordRight() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordRight();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the left of the current selection.\n     **/\n    removeWordLeft() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordLeft();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the left of the current selection, until the start of the line.\n     **/\n    removeToLineStart() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineStart();\n        if (this.selection.isEmpty())\n            this.selection.selectLeft();\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the right of the current selection, until the end of the line.\n     **/\n    removeToLineEnd() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineEnd();\n\n        var range = this.getSelectionRange();\n        if (range.start.column == range.end.column && range.start.row == range.end.row) {\n            range.end.column = 0;\n            range.end.row++;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Splits the line at the current selection (by inserting an `'\\n'`).\n     **/\n    splitLine() {\n        if (!this.selection.isEmpty()) {\n            this.session.remove(this.getSelectionRange());\n            this.clearSelection();\n        }\n\n        var cursor = this.getCursorPosition();\n        this.insert(\"\\n\");\n        this.moveCursorToPosition(cursor);\n    }\n\n    /**\n     * Set the \"ghost\" text in provided position. \"Ghost\" text is a kind of\n     * preview text inside the editor which can be used to preview some code\n     * inline in the editor such as, for example, code completions.\n     *\n     * @param {String} text Text to be inserted as \"ghost\" text\n     * @param {Point} [position] Position to insert text to\n     */\n    setGhostText(text, position) {\n        this.renderer.setGhostText(text, position);\n    }\n\n    /**\n     * Removes \"ghost\" text currently displayed in the editor.\n     */\n    removeGhostText() {\n        this.renderer.removeGhostText();\n    }\n\n    /**\n     * Transposes current line.\n     **/\n    transposeLetters() {\n        if (!this.selection.isEmpty()) {\n            return;\n        }\n\n        var cursor = this.getCursorPosition();\n        var column = cursor.column;\n        if (column === 0)\n            return;\n\n        var line = this.session.getLine(cursor.row);\n        var swap, range;\n        if (column < line.length) {\n            swap = line.charAt(column) + line.charAt(column-1);\n            range = new Range(cursor.row, column-1, cursor.row, column+1);\n        }\n        else {\n            swap = line.charAt(column-1) + line.charAt(column-2);\n            range = new Range(cursor.row, column-2, cursor.row, column);\n        }\n        this.session.replace(range, swap);\n        this.session.selection.moveToPosition(range.end);\n    }\n\n    /**\n     * Converts the current selection entirely into lowercase.\n     **/\n    toLowerCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toLowerCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Converts the current selection entirely into uppercase.\n     **/\n    toUpperCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toUpperCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Inserts an indentation into the current cursor position or indents the selected lines.\n     *\n     * @related EditSession.indentRows\n     **/\n    indent() {\n        var session = this.session;\n        var range = this.getSelectionRange();\n\n        if (range.start.row < range.end.row) {\n            var rows = this.$getSelectedRows();\n            session.indentRows(rows.first, rows.last, \"\\t\");\n            return;\n        } else if (range.start.column < range.end.column) {\n            var text = session.getTextRange(range);\n            if (!/^\\s+$/.test(text)) {\n                var rows = this.$getSelectedRows();\n                session.indentRows(rows.first, rows.last, \"\\t\");\n                return;\n            }\n        }\n\n        var line = session.getLine(range.start.row);\n        var position = range.start;\n        var size = session.getTabSize();\n        var column = session.documentToScreenColumn(position.row, position.column);\n\n        if (this.session.getUseSoftTabs()) {\n            var count = (size - column % size);\n            var indentString = lang.stringRepeat(\" \", count);\n        } else {\n            var count = column % size;\n            while (line[range.start.column - 1] == \" \" && count) {\n                range.start.column--;\n                count--;\n            }\n            this.selection.setSelectionRange(range);\n            indentString = \"\\t\";\n        }\n        return this.insert(indentString);\n    }\n\n    /**\n     * Indents the current line.\n     * @related EditSession.indentRows\n     **/\n    blockIndent() {\n        var rows = this.$getSelectedRows();\n        this.session.indentRows(rows.first, rows.last, \"\\t\");\n    }\n\n    /**\n     * Outdents the current line.\n     * @related EditSession.outdentRows\n     **/\n    blockOutdent() {\n        var selection = this.session.getSelection();\n        this.session.outdentRows(selection.getRange());\n    }\n\n    // TODO: move out of core when we have good mechanism for managing extensions\n    sortLines() {\n        var rows = this.$getSelectedRows();\n        var session = this.session;\n\n        var lines = [];\n        for (var i = rows.first; i <= rows.last; i++)\n            lines.push(session.getLine(i));\n\n        lines.sort(function(a, b) {\n            if (a.toLowerCase() < b.toLowerCase()) return -1;\n            if (a.toLowerCase() > b.toLowerCase()) return 1;\n            return 0;\n        });\n\n        var deleteRange = new Range(0, 0, 0, 0);\n        for (var i = rows.first; i <= rows.last; i++) {\n            var line = session.getLine(i);\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            deleteRange.end.column = line.length;\n            session.replace(deleteRange, lines[i-rows.first]);\n        }\n    }\n\n    /**\n     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.\n     **/\n    toggleCommentLines() {\n        var state = this.session.getState(this.getCursorPosition().row);\n        var rows = this.$getSelectedRows();\n        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);\n    }\n\n    toggleBlockComment() {\n        var cursor = this.getCursorPosition();\n        var state = this.session.getState(cursor.row);\n        var range = this.getSelectionRange();\n        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);\n    }\n\n    /**\n     * Works like [[EditSession.getTokenAt]], except it returns a number.\n     * @returns {any}\n     **/\n    getNumberAt(row, column) {\n        var _numberRx = /[\\-]?[0-9]+(?:\\.[0-9]+)?/g;\n        _numberRx.lastIndex = 0;\n\n        var s = this.session.getLine(row);\n        while (_numberRx.lastIndex < column) {\n            var m = _numberRx.exec(s);\n            if(m.index <= column && m.index+m[0].length >= column){\n                var number = {\n                    value: m[0],\n                    start: m.index,\n                    end: m.index+m[0].length\n                };\n                return number;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * If the character before the cursor is a number, this functions changes its value by `amount`.\n     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)\n     **/\n    modifyNumber(amount) {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n\n        // get the char before the cursor\n        var charRange = new Range(row, column-1, row, column);\n\n        var c = this.session.getTextRange(charRange);\n        // if the char is a digit\n        // @ts-ignore\n        if (!isNaN(parseFloat(c)) && isFinite(c)) {\n            // get the whole number the digit is part of\n            var nr = this.getNumberAt(row, column);\n            // if number found\n            if (nr) {\n                var fp = nr.value.indexOf(\".\") >= 0 ? nr.start + nr.value.indexOf(\".\") + 1 : nr.end;\n                var decimals = nr.start + nr.value.length - fp;\n\n                var t = parseFloat(nr.value);\n                t *= Math.pow(10, decimals);\n\n\n                if(fp !== nr.end && column < fp){\n                    amount *= Math.pow(10, nr.end - column - 1);\n                } else {\n                    amount *= Math.pow(10, nr.end - column);\n                }\n\n                t += amount;\n                t /= Math.pow(10, decimals);\n                var nnr = t.toFixed(decimals);\n\n                //update number\n                var replaceRange = new Range(row, nr.start, row, nr.end);\n                this.session.replace(replaceRange, nnr);\n\n                //reposition the cursor\n                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));\n\n            }\n        } else {\n            this.toggleWord();\n        }\n    }\n\n    /**\n     */\n    toggleWord() {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        this.selection.selectWord();\n        var currentState = this.getSelectedText();\n        var currWordStart = this.selection.getWordRange().start.column;\n        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\\s/);\n        var delta = column - currWordStart - 1;\n        if (delta < 0) delta = 0;\n        var curLength = 0, itLength = 0;\n        var that = this;\n        if (currentState.match(/[A-Za-z0-9_]+/)) {\n            wordParts.forEach(function (item, i) {\n                itLength = curLength + item.length;\n                if (delta >= curLength && delta <= itLength) {\n                    currentState = item;\n                    that.selection.clearSelection();\n                    that.moveCursorTo(row, curLength + currWordStart);\n                    that.selection.selectTo(row, itLength + currWordStart);\n                }\n                curLength = itLength;\n            });\n        }\n\n        var wordPairs = this.$toggleWordPairs;\n        var reg;\n        for (var i = 0; i < wordPairs.length; i++) {\n            var item = wordPairs[i];\n            for (var j = 0; j <= 1; j++) {\n                var negate = +!j;\n                var firstCondition = currentState.match(new RegExp('^\\\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\\\s?$', 'i'));\n                if (firstCondition) {\n                    var secondCondition = currentState.match(new RegExp('([_]|^|\\\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\\\s)', 'g'));\n                    if (secondCondition) {\n                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {\n                            var res = item[negate];\n                            if (result.toUpperCase() == result) {\n                                res = res.toUpperCase();\n                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {\n                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);\n                            }\n                            return res;\n                        });\n                        this.insert(reg);\n                        reg = \"\";\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Finds link at defined {row} and {column}\n     * @returns {String}\n     **/\n    findLinkAt(row, column) {\n        var line = this.session.getLine(row);\n        var wordParts = line.split(/((?:https?|ftp):\\/\\/[\\S]+)/);\n        var columnPosition = column;\n        if (columnPosition < 0) columnPosition = 0;\n        var previousPosition = 0, currentPosition = 0, match;\n        for (let item of wordParts) {\n            currentPosition = previousPosition + item.length;\n            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {\n                if (item.match(/((?:https?|ftp):\\/\\/[\\S]+)/)) {\n                    match = item.replace(/[\\s:.,'\";}\\]]+$/, \"\");\n                    break;\n                }\n            }\n            previousPosition = currentPosition;\n        }\n        return match;\n    }\n\n    /**\n     * Open valid url under cursor in another tab\n     * @returns {Boolean}\n     **/\n    openLink() {\n        var cursor =  this.selection.getCursor();\n        var url = this.findLinkAt(cursor.row, cursor.column);\n        if (url)\n            window.open(url, '_blank');\n        return url != null;\n    }\n\n    /**\n     * Removes all the lines in the current selection\n     * @related EditSession.remove\n     **/\n    removeLines() {\n        var rows = this.$getSelectedRows();\n        this.session.removeFullLines(rows.first, rows.last);\n        this.clearSelection();\n    }\n\n    duplicateSelection() {\n        var sel = this.selection;\n        var doc = this.session;\n        var range = sel.getRange();\n        var reverse = sel.isBackwards();\n        if (range.isEmpty()) {\n            var row = range.start.row;\n            doc.duplicateLines(row, row);\n        } else {\n            var point = reverse ? range.start : range.end;\n            var endPoint = doc.insert(point, doc.getTextRange(range));\n            range.start = point;\n            range.end = endPoint;\n\n            sel.setSelectionRange(range, reverse);\n        }\n    }\n\n    /**\n     * Shifts all the selected lines down one row.\n     *\n     * @related EditSession.moveLinesUp\n     **/\n    moveLinesDown() {\n        this.$moveLines(1, false);\n    }\n\n    /**\n     * Shifts all the selected lines up one row.\n     * @related EditSession.moveLinesDown\n     **/\n    moveLinesUp() {\n        this.$moveLines(-1, false);\n    }\n\n    /**\n     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n     * ```json\n     *    { row: newRowLocation, column: newColumnLocation }\n     * ```\n     * @param {Range} range The range of text you want moved within the document\n     * @param {Point} toPosition The location (row and column) where you want to move the text to\n     * @param {boolean} [copy]\n     *\n     * @returns {Range} The new range where the text was moved to.\n     * @related EditSession.moveText\n     **/\n    moveText(range, toPosition, copy) {\n        return this.session.moveText(range, toPosition, copy);\n    }\n\n    /**\n     * Copies all the selected lines up one row.\n     *\n     **/\n   copyLinesUp() {\n        this.$moveLines(-1, true);\n    }\n\n    /**\n     * Copies all the selected lines down one row.\n     * @related EditSession.duplicateLines\n     *\n     **/\n    copyLinesDown() {\n        this.$moveLines(1, true);\n    }\n\n    /**\n     * for internal use\n     * @ignore\n     *\n     **/\n    $moveLines(dir, copy) {\n        var rows, moved;\n        var selection = this.selection;\n        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {\n            var range = selection.toOrientedRange();\n            rows = this.$getSelectedRows(range);\n            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);\n            if (copy && dir == -1) moved = 0;\n            range.moveBy(moved, 0);\n            selection.fromOrientedRange(range);\n        } else {\n            var ranges = selection.rangeList.ranges;\n            // @ts-expect-error TODO: possible bug, no args in parameters\n            selection.rangeList.detach(this.session);\n            this.inVirtualSelectionMode = true;\n\n            var diff = 0;\n            var totalDiff = 0;\n            var l = ranges.length;\n            for (var i = 0; i < l; i++) {\n                var rangeIndex = i;\n                ranges[i].moveBy(diff, 0);\n                rows = this.$getSelectedRows(ranges[i]);\n                var first = rows.first;\n                var last = rows.last;\n                while (++i < l) {\n                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);\n                    var subRows = this.$getSelectedRows(ranges[i]);\n                    if (copy && subRows.first != last)\n                        break;\n                    else if (!copy && subRows.first > last + 1)\n                        break;\n                    last = subRows.last;\n                }\n                i--;\n                diff = this.session.$moveLines(first, last, copy ? 0 : dir);\n                if (copy && dir == -1) rangeIndex = i + 1;\n                while (rangeIndex <= i) {\n                    ranges[rangeIndex].moveBy(diff, 0);\n                    rangeIndex++;\n                }\n                if (!copy) diff = 0;\n                totalDiff += diff;\n            }\n\n            selection.fromOrientedRange(selection.ranges[0]);\n            selection.rangeList.attach(this.session);\n            this.inVirtualSelectionMode = false;\n        }\n    }\n\n    /**\n     * Returns an object indicating the currently selected rows. The object looks like this:\n     *\n     * ```json\n     * { first: range.start.row, last: range.end.row }\n     * ```\n     *\n     * @returns {Object}\n     **/\n    $getSelectedRows(range) {\n        range = (range || this.getSelectionRange()).collapseRows();\n\n        return {\n            first: this.session.getRowFoldStart(range.start.row),\n            last: this.session.getRowFoldEnd(range.end.row)\n        };\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionStart(compositionState) {\n        this.renderer.showComposition(compositionState);\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionUpdate(text) {\n        this.renderer.setCompositionText(text);\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionEnd() {\n        this.renderer.hideComposition();\n    }\n\n    /**\n     * {:VirtualRenderer.getFirstVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getFirstVisibleRow\n     **/\n    getFirstVisibleRow() {\n        return this.renderer.getFirstVisibleRow();\n    }\n\n    /**\n     * {:VirtualRenderer.getLastVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getLastVisibleRow\n     **/\n    getLastVisibleRow() {\n        return this.renderer.getLastVisibleRow();\n    }\n\n    /**\n     * Indicates if the row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     * @returns {Boolean}\n     **/\n    isRowVisible(row) {\n        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());\n    }\n\n    /**\n     * Indicates if the entire row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     *\n     * @returns {Boolean}\n     **/\n    isRowFullyVisible(row) {\n        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());\n    }\n\n    /**\n     * Returns the number of currently visible rows.\n     * @returns {Number}\n     **/\n    $getVisibleRowCount() {\n        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;\n    }\n\n    $moveByPage(dir, select) {\n        var renderer = this.renderer;\n        var config = this.renderer.layerConfig;\n        var rows = dir * Math.floor(config.height / config.lineHeight);\n\n        if (select === true) {\n            this.selection.$moveSelection(function(){\n                this.moveCursorBy(rows, 0);\n            });\n        } else if (select === false) {\n            this.selection.moveCursorBy(rows, 0);\n            this.selection.clearSelection();\n        }\n\n        var scrollTop = renderer.scrollTop;\n\n        renderer.scrollBy(0, rows * config.lineHeight);\n        if (select != null)\n            renderer.scrollCursorIntoView(null, 0.5);\n\n        renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page down\" finishes.\n     **/\n    selectPageDown() {\n        this.$moveByPage(1, true);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page up\" finishes.\n     **/\n    selectPageUp() {\n        this.$moveByPage(-1, true);\n    }\n\n    /**\n     * Shifts the document to wherever \"page down\" is, as well as moving the cursor position.\n     **/\n    gotoPageDown() {\n       this.$moveByPage(1, false);\n    }\n\n    /**\n     * Shifts the document to wherever \"page up\" is, as well as moving the cursor position.\n     **/\n    gotoPageUp() {\n        this.$moveByPage(-1, false);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page down\" is, without changing the cursor position.\n     **/\n    scrollPageDown() {\n        this.$moveByPage(1);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page up\" is, without changing the cursor position.\n     **/\n    scrollPageUp() {\n        this.$moveByPage(-1);\n    }\n\n    /**\n     * Moves the editor to the specified row.\n     * @related VirtualRenderer.scrollToRow\n     * @param {number} row\n     */\n    scrollToRow(row) {\n        this.renderer.scrollToRow(row);\n    }\n\n    /**\n     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).\n     * @param {Number} line The line to scroll to\n     * @param {Boolean} center If `true`\n     * @param {Boolean} animate If `true` animates scrolling\n     * @param {() => void} [callback] Function to be called when the animation has finished\n     *\n     * @related VirtualRenderer.scrollToLine\n     **/\n    scrollToLine(line, center, animate, callback) {\n        this.renderer.scrollToLine(line, center, animate, callback);\n    }\n\n    /**\n     * Attempts to center the current selection on the screen.\n     **/\n    centerSelection() {\n        var range = this.getSelectionRange();\n        var pos = {\n            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),\n            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)\n        };\n        this.renderer.alignCursor(pos, 0.5);\n    }\n\n    /**\n     * Gets the current position of the cursor.\n     * @returns {Point} An object that looks something like this:\n     *\n     * ```json\n     * { row: currRow, column: currCol }\n     * ```\n     *\n     * @related Selection.getCursor\n     **/\n    getCursorPosition() {\n        return this.selection.getCursor();\n    }\n\n    /**\n     * Returns the screen position of the cursor.\n     * @returns {Point}\n     * @related EditSession.documentToScreenPosition\n     **/\n    getCursorPositionScreen() {\n        return this.session.documentToScreenPosition(this.getCursorPosition());\n    }\n\n    /**\n     * {:Selection.getRange}\n     * @returns {Range}\n     * @related Selection.getRange\n     **/\n    getSelectionRange() {\n        return this.selection.getRange();\n    }\n\n    /**\n     * Selects all the text in editor.\n     * @related Selection.selectAll\n     **/\n    selectAll() {\n        this.selection.selectAll();\n    }\n\n    /**\n     * {:Selection.clearSelection}\n     * @related Selection.clearSelection\n     **/\n    clearSelection() {\n        this.selection.clearSelection();\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     * @related Selection.moveCursorTo\n     **/\n    moveCursorTo(row, column) {\n        this.selection.moveCursorTo(row, column);\n    }\n\n    /**\n     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.\n     * @param {Point} pos An object with two properties, row and column\n     * @related Selection.moveCursorToPosition\n     **/\n    moveCursorToPosition(pos) {\n        this.selection.moveCursorToPosition(pos);\n    }\n\n    /**\n     * Moves the cursor's row and column to the next matching bracket or HTML tag.\n     * @param {boolean} [select]\n     * @param {boolean} [expand]\n     */\n    jumpToMatching(select, expand) {\n        var cursor = this.getCursorPosition();\n        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);\n        var prevToken = iterator.getCurrentToken();\n        var tokenCount = 0;\n        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {\n            prevToken = iterator.stepBackward();\n        }\n        var token = prevToken || iterator.stepForward();\n\n        if (!token) return;\n\n        //get next closing tag or bracket\n        var matchType;\n        var found = false;\n        var depth = {};\n        var i = cursor.column - token.start;\n        var bracketType;\n        var brackets = {\n            \")\": \"(\",\n            \"(\": \"(\",\n            \"]\": \"[\",\n            \"[\": \"[\",\n            \"{\": \"{\",\n            \"}\": \"{\"\n        };\n\n        do {\n            if (token.value.match(/[{}()\\[\\]]/g)) {\n                for (; i < token.value.length && !found; i++) {\n                    if (!brackets[token.value[i]]) {\n                        continue;\n                    }\n\n                    bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n\n                    if (isNaN(depth[bracketType])) {\n                        depth[bracketType] = 0;\n                    }\n\n                    switch (token.value[i]) {\n                        case '(':\n                        case '[':\n                        case '{':\n                            depth[bracketType]++;\n                            break;\n                        case ')':\n                        case ']':\n                        case '}':\n                            depth[bracketType]--;\n\n                            if (depth[bracketType] === -1) {\n                                matchType = 'bracket';\n                                found = true;\n                            }\n                            break;\n                    }\n                }\n            }\n            else if (token.type.indexOf('tag-name') !== -1) {\n                if (isNaN(depth[token.value])) {\n                    depth[token.value] = 0;\n                }\n\n                if (prevToken.value === '<' && tokenCount > 1) {\n                    depth[token.value]++;\n                }\n                else if (prevToken.value === '</') {\n                    depth[token.value]--;\n                }\n\n                if (depth[token.value] === -1) {\n                    matchType = 'tag';\n                    found = true;\n                }\n            }\n\n            if (!found) {\n                prevToken = token;\n                tokenCount++;\n                token = iterator.stepForward();\n                i = 0;\n            }\n        } while (token && !found);\n\n        //no match found\n        if (!matchType) return;\n\n        var range, pos;\n        if (matchType === 'bracket') {\n            range = this.session.getBracketRange(cursor);\n            if (!range) {\n                range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1,\n                    iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1\n                );\n                pos = range.start;\n                if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column)\n                    < 2) range = this.session.getBracketRange(pos);\n            }\n        }\n        else if (matchType === 'tag') {\n            if (!token || token.type.indexOf('tag-name') === -1) return;\n            range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2,\n                iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2\n            );\n\n            //find matching tag\n            if (range.compare(cursor.row, cursor.column) === 0) {\n                var tagsRanges = this.session.getMatchingTags(cursor);\n                if (tagsRanges) {\n                    if (tagsRanges.openTag.contains(cursor.row, cursor.column)) {\n                        range = tagsRanges.closeTag;\n                        pos = range.start;\n                    }\n                    else {\n                        range = tagsRanges.openTag;\n                        if (tagsRanges.closeTag.start.row === cursor.row && tagsRanges.closeTag.start.column\n                            === cursor.column) pos = range.end; else pos = range.start;\n                    }\n                }\n            }\n\n            //we found it\n            pos = pos || range.start;\n        }\n\n        pos = range && range.cursor || pos;\n        if (pos) {\n            if (select) {\n                if (range && expand) {\n                    this.selection.setRange(range);\n                }\n                else if (range && range.isEqual(this.getSelectionRange())) {\n                    this.clearSelection();\n                }\n                else {\n                    this.selection.selectTo(pos.row, pos.column);\n                }\n            }\n            else {\n                this.selection.moveTo(pos.row, pos.column);\n            }\n        }\n    }\n\n    /**\n     * Moves the cursor to the specified line number, and also into the indicated column.\n     * @param {Number} lineNumber The line number to go to\n     * @param {Number} [column] A column number to go to\n     * @param {Boolean} [animate] If `true` animates scolling\n     **/\n    gotoLine(lineNumber, column, animate) {\n        this.selection.clearSelection();\n        this.session.unfold({row: lineNumber - 1, column: column || 0});\n\n        // todo: find a way to automatically exit multiselect mode\n        this.exitMultiSelectMode && this.exitMultiSelectMode();\n        this.moveCursorTo(lineNumber - 1, column || 0);\n\n        if (!this.isRowFullyVisible(lineNumber - 1))\n            this.scrollToLine(lineNumber - 1, true, animate);\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     *\n     * @related Editor.moveCursorTo\n     **/\n    navigateTo(row, column) {\n        this.selection.moveTo(row, column);\n    }\n\n    /**\n     * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateUp(times) {\n        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {\n            var selectionStart = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionStart);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(-times || -1, 0);\n    }\n\n    /**\n     * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateDown(times) {\n        if (this.selection.isMultiLine() && this.selection.isBackwards()) {\n            var selectionEnd = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionEnd);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(times || 1, 0);\n    }\n\n    /**\n     * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateLeft(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionStart = this.getSelectionRange().start;\n            this.moveCursorToPosition(selectionStart);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorLeft();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateRight(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionEnd = this.getSelectionRange().end;\n            this.moveCursorToPosition(selectionEnd);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorRight();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineStart() {\n        this.selection.moveCursorLineStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineEnd() {\n        this.selection.moveCursorLineEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileEnd() {\n        this.selection.moveCursorFileEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileStart() {\n        this.selection.moveCursorFileStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordRight() {\n        this.selection.moveCursorWordRight();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordLeft() {\n        this.selection.moveCursorWordLeft();\n        this.clearSelection();\n    }\n\n    /**\n     * Replaces the first occurrence of `options.needle` with the value in `replacement`.\n     * @param {String} [replacement] The text to replace with\n     * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n     * @return {number}\n     **/\n    replace(replacement, options) {\n        if (options)\n            this.$search.set(options);\n\n        var range = this.$search.find(this.session);\n        var replaced = 0;\n        if (!range)\n            return replaced;\n\n        if (this.$tryReplace(range, replacement)) {\n            replaced = 1;\n        }\n\n        this.selection.setSelectionRange(range);\n        this.renderer.scrollSelectionIntoView(range.start, range.end);\n\n        return replaced;\n    }\n\n    /**\n     * Replaces all occurrences of `options.needle` with the value in `replacement`.\n     * @param {String} [replacement] The text to replace with\n     * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n     * @return {number}\n     **/\n    replaceAll(replacement, options) {\n        if (options) {\n            this.$search.set(options);\n        }\n\n        var ranges = this.$search.findAll(this.session);\n        var replaced = 0;\n        if (!ranges.length)\n            return replaced;\n\n        var selection = this.getSelectionRange();\n        this.selection.moveTo(0, 0);\n\n        for (var i = ranges.length - 1; i >= 0; --i) {\n            if(this.$tryReplace(ranges[i], replacement)) {\n                replaced++;\n            }\n        }\n\n        this.selection.setSelectionRange(selection);\n\n        return replaced;\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.IRange} range\n     * @param {string} [replacement]\n     */\n    $tryReplace(range, replacement) {\n        var input = this.session.getTextRange(range);\n        replacement = this.$search.replace(input, replacement);\n        if (replacement !== null) {\n            range.end = this.session.replace(range, replacement);\n            return range;\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].\n     * @related Search.getOptions\n     * @returns {Partial<SearchOptions>}\n     **/\n    getLastSearchOptions() {\n        return this.$search.getOptions();\n    }\n\n    /**\n     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].\n     * @param {String|RegExp|Object} needle The text to search for (optional)\n     * @param {Partial<SearchOptions>} [options] An object defining various search properties\n     * @param {Boolean} [animate] If `true` animate scrolling\n     * @related Search.find\n     **/\n    find(needle, options, animate) {\n        if (!options)\n            options = {};\n\n        if (typeof needle == \"string\" || needle instanceof RegExp)\n            options.needle = needle;\n        else if (typeof needle == \"object\")\n            oop.mixin(options, needle);\n\n        var range = this.selection.getRange();\n        if (options.needle == null) {\n            needle = this.session.getTextRange(range)\n                || this.$search.$options.needle;\n            if (!needle) {\n                range = this.session.getWordRange(range.start.row, range.start.column);\n                needle = this.session.getTextRange(range);\n            }\n            this.$search.set({needle: needle});\n        }\n\n        this.$search.set(options);\n        if (!options.start)\n            this.$search.set({start: range});\n\n        var newRange = this.$search.find(this.session);\n        if (options.preventScroll)\n            return newRange;\n        if (newRange) {\n            this.revealRange(newRange, animate);\n            return newRange;\n        }\n        // clear selection if nothing is found\n        if (options.backwards)\n            range.start = range.end;\n        else\n            range.end = range.start;\n        this.selection.setRange(range);\n    }\n\n    /**\n     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].\n     * @param {Partial<SearchOptions>} [options] search options\n     * @param {Boolean} [animate] If `true` animate scrolling\n     *\n     * @related Editor.find\n     **/\n    findNext(options, animate) {\n        this.find({skipCurrent: true, backwards: false}, options, animate);\n    }\n\n    /**\n     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].\n     * @param {Partial<SearchOptions>} [options] search options\n     * @param {Boolean} [animate] If `true` animate scrolling\n     *\n     * @related Editor.find\n     **/\n    findPrevious(options, animate) {\n        this.find(options, {skipCurrent: true, backwards: true}, animate);\n    }\n\n    /**\n     *\n     * @param {Range} range\n     * @param {boolean} [animate]\n     */\n    revealRange(range, animate) {\n        this.session.unfold(range);\n        this.selection.setSelectionRange(range);\n\n        var scrollTop = this.renderer.scrollTop;\n        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n        if (animate !== false)\n            this.renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * {:UndoManager.undo}\n     * @related UndoManager.undo\n     **/\n    undo() {\n        this.session.getUndoManager().undo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     * {:UndoManager.redo}\n     * @related UndoManager.redo\n     **/\n    redo() {\n        this.session.getUndoManager().redo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     *\n     * Cleans up the entire editor.\n     **/\n    destroy() {\n        if (this.$toDestroy) {\n            this.$toDestroy.forEach(function(el) {\n                el.destroy();\n            });\n            this.$toDestroy = null;\n        }\n        if (this.$mouseHandler)\n            this.$mouseHandler.destroy();\n        this.renderer.destroy();\n        this._signal(\"destroy\", this);\n        if (this.session)\n            this.session.destroy();\n        if (this._$emitInputEvent)\n            this._$emitInputEvent.cancel();\n        this.removeAllListeners();\n\n    }\n\n    /**\n     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element\n     * @param {Boolean} enable default true\n     **/\n    setAutoScrollEditorIntoView(enable) {\n        if (!enable)\n            return;\n        var rect;\n        var self = this;\n        var shouldScroll = false;\n        if (!this.$scrollAnchor)\n            this.$scrollAnchor = document.createElement(\"div\");\n        var scrollAnchor = this.$scrollAnchor;\n        scrollAnchor.style.cssText = \"position:absolute\";\n        this.container.insertBefore(scrollAnchor, this.container.firstChild);\n        var onChangeSelection = this.on(\"changeSelection\", function() {\n            shouldScroll = true;\n        });\n        // needed to not trigger sync reflow\n        var onBeforeRender = this.renderer.on(\"beforeRender\", function() {\n            if (shouldScroll)\n                rect = self.renderer.container.getBoundingClientRect();\n        });\n        var onAfterRender = this.renderer.on(\"afterRender\", function() {\n            if (shouldScroll && rect && (self.isFocused()\n                || self.searchBox && self.searchBox.isFocused())\n            ) {\n                var renderer = self.renderer;\n                var pos = renderer.$cursorLayer.$pixelPos;\n                var config = renderer.layerConfig;\n                var top = pos.top - config.offset;\n                if (pos.top >= 0 && top + rect.top < 0) {\n                    shouldScroll = true;\n                } else if (pos.top < config.height &&\n                    pos.top + rect.top + config.lineHeight > window.innerHeight) {\n                    shouldScroll = false;\n                } else {\n                    shouldScroll = null;\n                }\n                if (shouldScroll != null) {\n                    scrollAnchor.style.top = top + \"px\";\n                    scrollAnchor.style.left = pos.left + \"px\";\n                    scrollAnchor.style.height = config.lineHeight + \"px\";\n                    scrollAnchor.scrollIntoView(shouldScroll);\n                }\n                shouldScroll = rect = null;\n            }\n        });\n        this.setAutoScrollEditorIntoView = function(enable) {\n            if (enable)\n                return;\n            delete this.setAutoScrollEditorIntoView;\n            this.off(\"changeSelection\", onChangeSelection);\n            this.renderer.off(\"afterRender\", onAfterRender);\n            this.renderer.off(\"beforeRender\", onBeforeRender);\n        };\n    }\n\n    $resetCursorStyle() {\n        var style = this.$cursorStyle || \"ace\";\n        var cursorLayer = this.renderer.$cursorLayer;\n        if (!cursorLayer)\n            return;\n        cursorLayer.setSmoothBlinking(/smooth/.test(style));\n        cursorLayer.isBlinking = !this.$readOnly && style != \"wide\";\n        dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n    }\n\n    /**\n     * opens a prompt displaying message\n     **/\n    prompt(message, options, callback) {\n        var editor = this;\n        config.loadModule(\"ace/ext/prompt\", function (module) {\n            module.prompt(editor, message, options, callback);\n        });\n    }\n\n}\n\nEditor.$uid = 0;\nEditor.prototype.curOp = null;\nEditor.prototype.prevOp = {};\n// TODO use property on commands instead of this\nEditor.prototype.$mergeableCommands = [\"backspace\", \"del\", \"insertstring\"];\nEditor.prototype.$toggleWordPairs = [\n    [\"first\", \"last\"],\n    [\"true\", \"false\"],\n    [\"yes\", \"no\"],\n    [\"width\", \"height\"],\n    [\"top\", \"bottom\"],\n    [\"right\", \"left\"],\n    [\"on\", \"off\"],\n    [\"x\", \"y\"],\n    [\"get\", \"set\"],\n    [\"max\", \"min\"],\n    [\"horizontal\", \"vertical\"],\n    [\"show\", \"hide\"],\n    [\"add\", \"remove\"],\n    [\"up\", \"down\"],\n    [\"before\", \"after\"],\n    [\"even\", \"odd\"],\n    [\"in\", \"out\"],\n    [\"inside\", \"outside\"],\n    [\"next\", \"previous\"],\n    [\"increase\", \"decrease\"],\n    [\"attach\", \"detach\"],\n    [\"&&\", \"||\"],\n    [\"==\", \"!=\"]\n];\n\noop.implement(Editor.prototype, EventEmitter);\n\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    selectionStyle: {\n        set: function(style) {\n            this.onSelectionChange();\n            this._signal(\"changeSelectionStyle\", {data: style});\n        },\n        initialValue: \"line\"\n    },\n    highlightActiveLine: {\n        set: function() {this.$updateHighlightActiveLine();},\n        initialValue: true\n    },\n    highlightSelectedWord: {\n        set: function(shouldHighlight) {this.$onSelectionChange();},\n        initialValue: true\n    },\n    readOnly: {\n        set: function(/**@type{boolean}*/readOnly) {\n            this.textInput.setReadOnly(readOnly);\n            this.$resetCursorStyle();\n            if (!this.$readOnlyCallback) {\n                this.$readOnlyCallback = (e) => {\n                    var shouldShow = false;\n                    if (e && e.type == \"keydown\") {\n                        shouldShow = e && e.key && e.key.length == 1 && !e.ctrlKey && !e.metaKey;\n                        if (!shouldShow) return;\n                    } else if (e && e.type !== \"exec\") {\n                        shouldShow = true;\n                    }\n                    if (shouldShow) {\n                        if (!this.hoverTooltip) {\n                            this.hoverTooltip = new HoverTooltip();\n                        }\n                        var domNode = dom.createElement(\"div\");\n                        domNode.textContent = nls(\"editor.tooltip.disable-editing\", \"Editing is disabled\");\n                        if (!this.hoverTooltip.isOpen) {\n                            this.hoverTooltip.showForRange(this, this.getSelectionRange(), domNode);\n                        }\n                    } else if (this.hoverTooltip && this.hoverTooltip.isOpen) {\n                        this.hoverTooltip.hide();\n                    }\n                };\n            }\n            var textArea = this.textInput.getElement();\n            if (readOnly) {\n                event.addListener(textArea, \"keydown\", this.$readOnlyCallback, this);\n                this.commands.on(\"exec\", this.$readOnlyCallback);\n                this.commands.on(\"commandUnavailable\", this.$readOnlyCallback);\n            } else {\n                event.removeListener(textArea, \"keydown\", this.$readOnlyCallback);\n                this.commands.off(\"exec\", this.$readOnlyCallback);\n                this.commands.off(\"commandUnavailable\", this.$readOnlyCallback);\n                if (this.hoverTooltip) {\n                    this.hoverTooltip.destroy();\n                    this.hoverTooltip = null;\n                }\n            }\n        },\n        initialValue: false\n    },\n    copyWithEmptySelection: {\n        set: function(value) {\n            this.textInput.setCopyWithEmptySelection(value);\n        },\n        initialValue: false\n    },\n    cursorStyle: {\n        set: function(val) { this.$resetCursorStyle(); },\n        values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n        initialValue: \"ace\"\n    },\n    mergeUndoDeltas: {\n        values: [false, true, \"always\"],\n        initialValue: true\n    },\n    behavioursEnabled: {initialValue: true},\n    wrapBehavioursEnabled: {initialValue: true},\n    enableAutoIndent: {initialValue: true},\n    autoScrollEditorIntoView: {\n        set: function(val) {this.setAutoScrollEditorIntoView(val);}\n    },\n    keyboardHandler: {\n        set: function(val) { this.setKeyboardHandler(val); },\n        get: function() { return this.$keybindingId; },\n        handlesSet: true\n    },\n    value: {\n        set: function(val) { this.session.setValue(val); },\n        get: function() { return this.getValue(); },\n        handlesSet: true,\n        hidden: true\n    },\n    session: {\n        set: function(val) { this.setSession(val); },\n        get: function() { return this.session; },\n        handlesSet: true,\n        hidden: true\n    },\n\n    showLineNumbers: {\n        set: function(show) {\n            this.renderer.$gutterLayer.setShowLineNumbers(show);\n            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);\n            if (show && this.$relativeLineNumbers)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        },\n        initialValue: true\n    },\n    relativeLineNumbers: {\n        set: function(value) {\n            if (this.$showLineNumbers && value)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        }\n    },\n    placeholder: {\n        /**\n         * @param message\n         */\n        set: function(message) {\n            if (!this.$updatePlaceholder) {\n                this.$updatePlaceholder = function() {\n                    var hasValue = this.session && (this.renderer.$composition ||\n                         this.session.getLength() > 1 || this.session.getLine(0).length > 0);\n                    if (hasValue && this.renderer.placeholderNode) {\n                        this.renderer.off(\"afterRender\", this.$updatePlaceholder);\n                        dom.removeCssClass(this.container, \"ace_hasPlaceholder\");\n                        this.renderer.placeholderNode.remove();\n                        this.renderer.placeholderNode = null;\n                    } else if (!hasValue && !this.renderer.placeholderNode) {\n                        this.renderer.on(\"afterRender\", this.$updatePlaceholder);\n                        dom.addCssClass(this.container, \"ace_hasPlaceholder\");\n                        var el = dom.createElement(\"div\");\n                        el.className = \"ace_placeholder\";\n                        el.textContent = this.$placeholder || \"\";\n                        this.renderer.placeholderNode = el;\n                        this.renderer.content.appendChild(this.renderer.placeholderNode);\n                    } else if (!hasValue && this.renderer.placeholderNode) {\n                        this.renderer.placeholderNode.textContent = this.$placeholder || \"\";\n                    }\n                }.bind(this);\n                // @ts-ignore\n                this.on(\"input\", this.$updatePlaceholder);\n            }\n            this.$updatePlaceholder();\n        }\n    },\n    enableKeyboardAccessibility: {\n        set: function(value) {\n            var blurCommand = {\n                name: \"blurTextInput\",\n                description: \"Set focus to the editor content div to allow tabbing through the page\",\n                bindKey: \"Esc\",\n                exec: function(editor) {\n                    editor.blur();\n                    editor.renderer.scroller.focus();\n                },\n                readOnly: true\n            };\n\n            var focusOnEnterKeyup = function (e) {\n                if (e.target == this.renderer.scroller && e.keyCode === keys['enter']){\n                    e.preventDefault();\n                    var row = this.getCursorPosition().row;\n\n                    if (!this.isRowVisible(row))\n                        this.scrollToLine(row, true, true);\n\n                    this.focus();\n                }\n            };\n            /**@type {GutterKeyboardHandler}*/\n            var gutterKeyboardHandler;\n\n            // If keyboard a11y mode is enabled we:\n            // - Enable keyboard operability gutter.\n            // - Prevent tab-trapping.\n            // - Hide irrelevant elements from assistive technology.\n            // - On Windows, set more lines to the textarea.\n            // - set aria-label to the text input.\n            if (value){\n                this.renderer.enableKeyboardAccessibility = true;\n                this.renderer.keyboardFocusClassName = \"ace_keyboard-focus\";\n\n                this.textInput.getElement().setAttribute(\"tabindex\", -1);\n                // VoiceOver on Mac OS works best with single line in the textarea, the screen readers on\n                // Windows work best with multiple lines in the textarea.\n                this.textInput.setNumberOfExtraLines(useragent.isWin ? 3 : 0);\n                this.renderer.scroller.setAttribute(\"tabindex\", 0);\n                this.renderer.scroller.setAttribute(\"role\", \"group\");\n                this.renderer.scroller.setAttribute(\"aria-roledescription\", nls(\"editor.scroller.aria-roledescription\", \"editor\"));\n                this.renderer.scroller.classList.add(this.renderer.keyboardFocusClassName);\n                this.renderer.scroller.setAttribute(\"aria-label\",\n                    nls(\"editor.scroller.aria-label\", \"Editor content, press Enter to start editing, press Escape to exit\")\n                );\n\n                this.renderer.scroller.addEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.addCommand(blurCommand);\n\n                this.renderer.$gutter.setAttribute(\"tabindex\", 0);\n                this.renderer.$gutter.setAttribute(\"aria-hidden\", false);\n                this.renderer.$gutter.setAttribute(\"role\", \"group\");\n                this.renderer.$gutter.setAttribute(\"aria-roledescription\", nls(\"editor.gutter.aria-roledescription\", \"editor gutter\"));\n                this.renderer.$gutter.setAttribute(\"aria-label\",\n                    nls(\"editor.gutter.aria-label\", \"Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit\")\n                );\n                this.renderer.$gutter.classList.add(this.renderer.keyboardFocusClassName);\n\n                this.renderer.content.setAttribute(\"aria-hidden\", true);\n\n                if (!gutterKeyboardHandler)\n                    gutterKeyboardHandler = new GutterKeyboardHandler(this);\n\n                gutterKeyboardHandler.addListener();\n\n                this.textInput.setAriaOptions({\n                    setLabel: true\n                });\n            } else {\n                this.renderer.enableKeyboardAccessibility = false;\n\n                this.textInput.getElement().setAttribute(\"tabindex\", 0);\n                this.textInput.setNumberOfExtraLines(0);\n                this.renderer.scroller.setAttribute(\"tabindex\", -1);\n                this.renderer.scroller.removeAttribute(\"role\");\n                this.renderer.scroller.removeAttribute(\"aria-roledescription\");\n                this.renderer.scroller.classList.remove(this.renderer.keyboardFocusClassName);\n                this.renderer.scroller.removeAttribute(\"aria-label\");\n\n                this.renderer.scroller.removeEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.removeCommand(blurCommand);\n\n                this.renderer.content.removeAttribute(\"aria-hidden\");\n\n                this.renderer.$gutter.setAttribute(\"tabindex\", -1);\n                this.renderer.$gutter.setAttribute(\"aria-hidden\", true);\n                this.renderer.$gutter.removeAttribute(\"role\");\n                this.renderer.$gutter.removeAttribute(\"aria-roledescription\");\n                this.renderer.$gutter.removeAttribute(\"aria-label\");\n                this.renderer.$gutter.classList.remove(this.renderer.keyboardFocusClassName);\n\n                if (gutterKeyboardHandler)\n                    gutterKeyboardHandler.removeListener();\n            }\n        },\n        initialValue: false\n    },\n    textInputAriaLabel: {\n        set: function(val) { this.$textInputAriaLabel = val; },\n        initialValue: \"\"\n    },\n    enableMobileMenu: {\n        /**\n         * @param {boolean} val\n         */\n        set: function(val) { this.$enableMobileMenu = val; },\n        initialValue: true\n    },\n    customScrollbar: \"renderer\",\n    hScrollBarAlwaysVisible: \"renderer\",\n    vScrollBarAlwaysVisible: \"renderer\",\n    highlightGutterLine: \"renderer\",\n    animatedScroll: \"renderer\",\n    showInvisibles: \"renderer\",\n    showPrintMargin: \"renderer\",\n    printMarginColumn: \"renderer\",\n    printMargin: \"renderer\",\n    fadeFoldWidgets: \"renderer\",\n    showFoldWidgets: \"renderer\",\n    displayIndentGuides: \"renderer\",\n    highlightIndentGuides: \"renderer\",\n    showGutter: \"renderer\",\n    fontSize: \"renderer\",\n    fontFamily: \"renderer\",\n    maxLines: \"renderer\",\n    minLines: \"renderer\",\n    scrollPastEnd: \"renderer\",\n    fixedWidthGutter: \"renderer\",\n    theme: \"renderer\",\n    hasCssTransforms: \"renderer\",\n    maxPixelHeight: \"renderer\",\n    useTextareaForIME: \"renderer\",\n    useResizeObserver: \"renderer\",\n    useSvgGutterIcons: \"renderer\",\n    showFoldedAnnotations: \"renderer\",\n\n    scrollSpeed: \"$mouseHandler\",\n    dragDelay: \"$mouseHandler\",\n    dragEnabled: \"$mouseHandler\",\n    focusTimeout: \"$mouseHandler\",\n    tooltipFollowsMouse: \"$mouseHandler\",\n\n    firstLineNumber: \"session\",\n    overwrite: \"session\",\n    newLineMode: \"session\",\n    useWorker: \"session\",\n    useSoftTabs: \"session\",\n    navigateWithinSoftTabs: \"session\",\n    tabSize: \"session\",\n    wrap: \"session\",\n    indentedSoftWrap: \"session\",\n    foldStyle: \"session\",\n    mode: \"session\"\n});\n\n\nvar relativeNumberRenderer = {\n    getText: function(/**@type{EditSession}*/session, /**@type{number}*/row) {\n        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? \"\\xb7\" : \"\"))) + \"\";\n    },\n    getWidth: function(session, /**@type{number}*/lastLineNumber, config) {\n        return Math.max(\n            lastLineNumber.toString().length,\n            (config.lastRow + 1).toString().length,\n            2\n        ) * config.characterWidth;\n    },\n    update: function(e, /**@type{Editor}*/editor) {\n        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);\n    },\n    attach: function(/**@type{Editor}*/editor) {\n        editor.renderer.$gutterLayer.$renderer = this;\n        editor.on(\"changeSelection\", this.update);\n        this.update(null, editor);\n    },\n    detach: function(/**@type{Editor}*/editor) {\n        if (editor.renderer.$gutterLayer.$renderer == this)\n            editor.renderer.$gutterLayer.$renderer = null;\n        editor.off(\"changeSelection\", this.update);\n        this.update(null, editor);\n    }\n};\nexports.Editor = Editor;\n"
  },
  {
    "path": "demo/diff/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <title>Ace-diff - Simple Demo #1</title>\n\n    <script src=\"../kitchen-sink/require.js\"></script>\n\n    <style type=\"text/css\">\n        body {\n            display: flex;\n            flex-direction: column;\n            height: 100vh;\n            margin: 0;\n        }\n\n        .ace_diff-container {\n            overflow: hidden;\n        }\n\n        .toolbar {\n            display: flex;\n            gap: 10px;\n            padding: 10px;\n            background: #f1f1f1;\n            border-bottom: 1px solid #ddd;\n        }\n\n        .toolbar button {\n            padding: 5px 10px;\n            border: 1px solid #ccc;\n            background: #fff;\n            cursor: pointer;\n        }\n\n        .toolbar button:hover {\n            background: #e6e6e6;\n        }\n        .toolbar > label {\n            display: inline-flex;\n            align-items: center;\n        }\n\n    </style>\n</head>\n<body>\n \n\n<div class=\"ace_diff-container\"></div>\n\n<script>\n    var debugInline = false\n\n    var diffView = null;\n    var editorA = null;\n    var editorB = null;\n\n    var paths = {\n        \"ace\": \"../../src\",\n        diff: \".\",\n        demo: \"..\",\n    };\n\n    require.config({\n        paths: paths\n    });\n\n    require([\n        \"ace/ext/diff/split_diff_view\",\n        \"ace/ext/diff/inline_diff_view\",\n        \"demo/kitchen-sink/util\",\n        \"demo/kitchen-sink/layout\", \n        \"ace/ext/diff/providers/default\",\n        \"ace/ext/options\",\n        \"ace/ext/menu_tools/overlay_page\",\n    ], function () {\n        var {InlineDiffView} = require(\"ace/ext/diff/inline_diff_view\");\n        var {SplitDiffView} = require(\"ace/ext/diff/split_diff_view\");\n        var {DiffProvider} = require(\"ace/ext/diff/providers/default\");\n        var {OptionPanel, optionGroups} = require(\"ace/ext/options\")\n        var {buildDom} = require(\"ace/lib/dom\");\n\n        var tollbarButtons = {};\n\n        var initialValueA = \"\";\n        var initialValueB = \"\";\n        var updateButtonsState = () => {\n            if (!diffView) return;\n            tollbarButtons.prev.disabled = diffView.firstDiffSelected();\n            tollbarButtons.next.disabled = diffView.lastDiffSelected();\n        };\n\n        var goToNext = () => {\n            diffView.gotoNext(1);\n            updateButtonsState();\n        };\n\n        var goToPrevious = () => {\n            diffView.gotoNext(-1);\n            updateButtonsState();\n        };\n\n        function reset() {\n            editorA.setValue(initialValueA, -1);\n            editorB.setValue(initialValueB, -1);\n            \n            localStorage.removeItem(\"valueA\");\n            localStorage.removeItem(\"valueB\");\n        }\n\n        var diffViewMode = \"off\";\n        var diffVewContainer = document.querySelector(\".ace_diff-container\");\n        var setMode = (mode) => {\n            if (diffViewMode == mode) return;\n\n            localStorage.diffViewMode = diffViewMode = mode;\n\n            if (diffView) {\n                diffView.detach();\n            }\n            switch (mode) {\n                case \"inlineA\":\n                    diffView = new InlineDiffView({\n                        editorA, editorB,\n                    });\n                    if (!debugInline) editorB.container.style.display = \"none\";\n                    editorA.container.style.display = \"\";\n                    break;\n                case \"inlineB\":\n                    diffView = new InlineDiffView({\n                        editorA, editorB,\n                        inline: \"b\"\n                    });\n                    editorB.container.style.display = \"\";\n                    if (!debugInline) editorA.container.style.display = \"none\";\n                    break;\n                case \"split\":\n                    diffView = new SplitDiffView({editorA, editorB});\n                    editorA.container.style.display = \"\";\n                    editorB.container.style.display = \"\";\n                    break;\n                case \"off\":\n                    diffView = undefined;\n                    editorA.container.style.display = \"\";\n                    editorB.container.style.display = \"\";\n                    break;\n            }\n            if (diffView) {\n                diffView.setOptions(optionValues);\n                diffView.setProvider(new DiffProvider());\n            }\n            diffView?.onInput();\n        }\n\n        var optionValues = {\n            diffViewMode: localStorage.diffViewMode || \"split\",\n            ignoreTrimWhitespace: localStorage.ignoreTrimWhitespace == \"true\",\n            wrap: localStorage.wrap== \"true\",\n            syncSelections: localStorage.syncSelections != \"false\",\n            showOtherLineNumbers: localStorage.showOtherLineNumbers != \"false\",\n            folding: localStorage.folding != \"false\",\n            theme: localStorage.theme || \"ace/theme/textmate\",\n        }\n        function drawToolbar() {\n\n            var toolbar = document.createElement(\"div\");\n            toolbar.className = \"toolbar ace_optionsMenuEntry\";\n            diffVewContainer.parentNode.insertBefore(toolbar, diffVewContainer);\n\n\n            optionBar = new OptionPanel({\n                getOption(path) {\n                    return optionValues[path];\n                },\n                setOption(path, value) {\n                    optionValues[path] = value;\n                    if (path == \"diffViewMode\") {\n                        setMode(value);\n                    } else if (diffView) {\n                        diffView.setOption(path, value);\n                    }\n                    localStorage.setItem(path, value);\n                }\n            });\n            var data = [\n                [\"button\", {ref: \"prev\", onclick: goToPrevious}, \"<\"],\n                [\"button\", {ref: \"next\", onclick: goToNext}, \">\"],\n\n                optionBar.renderOptionControl(\"\", {\n                    path: \"diffViewMode\",\n                    type: \"buttonBar\",\n                    values: [\"inlineA\", \"inlineB\", \"split\", \"off\"],\n                }),\n                [\"label\", {},\n                    optionBar.renderOptionControl(\"\", {\n                        path: \"ignoreTrimWhitespace\",\n                        type: \"checkbox\",\n                    }),\n                    \"Ignore Spaces\"\n                ],\n                [\"label\", {},\n                    optionBar.renderOptionControl(\"\", {\n                        path: \"syncSelections\",\n                        type: \"checkbox\",\n                    }),\n                    \"Sync Selections\"\n                ],\n                [\"label\", {},\n                    optionBar.renderOptionControl(\"\", {\n                        path: \"wrap\",\n                        type: \"checkbox\",\n                    }),\n                    \"Wrap\"\n                ],\n                [\"label\", {},\n                    optionBar.renderOptionControl(\"\", {\n                        path: \"folding\",\n                        type: \"checkbox\",\n                    }),\n                    \"Folding\"\n                ],\n                [\"button\", {onclick: function() {diffView.toggleFoldUnchanged()}}, \"Fold Unchanged\"],\n                [\"button\", {id: \"btn-reset\", onclick: reset}, \"Reset\"],\n                [\"label\", {},\n                    optionBar.renderOptionControl(\"\", optionGroups.Main.Theme),\n                    \"Theme\"\n                ],\n            ] \n            buildDom(data, toolbar, tollbarButtons);\n        }\n\n        var config = require(\"ace/config\");\n        config.setLoader(function (moduleName, cb) {\n            require([moduleName], function (module) {\n                cb(null, module);\n            });\n        });\n\n        var util = require(\"demo/kitchen-sink/util\");\n        splitEditor = util.createSplitEditor(diffVewContainer);\n\n        editorA = splitEditor.editor0;\n        editorB = splitEditor.editor1; \n\n        require(\"ace/lib/net\").get(\"./examples/editor.17.js\", function (v) {\n            initialValueA = v;\n            editorA.setValue(localStorage.valueA || v, -1);\n            editorA.session.setMode(\"ace/mode/javascript\");\n            diffView?.onInput();\n        });\n        require(\"ace/lib/net\").get(\"./examples/editor.40.js\", function (v) {\n            initialValueB = v;\n            editorB.setValue(localStorage.valueB || v, -1);\n            editorB.session.setMode(\"ace/mode/javascript\");\n            diffView?.onInput();\n        });\n\n        window.onbeforeunload = function () {\n            localStorage.valueA = editorA.getValue();\n            localStorage.valueB = editorB.getValue();\n        };\n\n        editorA.on(\"changeSelection\", updateButtonsState);\n        editorB.on(\"changeSelection\", updateButtonsState);\n\n        drawToolbar();\n        setMode(optionValues.diffViewMode);\n    });\n\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/emmet.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>ACE Emmet demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n\n<!-- load emmet code and snippets compiled for browser -->\n<!-- <script src=\"...\"></script> -->\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/emmet\"], function(ace) {\n    var editor = ace.edit(\"editor\");\n    editor.session.setMode(\"ace/mode/html\");\n    // enable emmet on the current editor\n    editor.setOption(\"enableEmmet\", true);\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/i18n.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ACE Editor StatusBar Demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 2em;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n    #statusBar {\n        margin: 0;\n        padding: 0;\n        position: absolute;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        height: 20px;\n        background-color: rgb(245, 245, 245);\n        color: gray;\n    }\n    .ace_status-indicator {\n        color: gray;\n        position: absolute;\n        right: 0;\n        border-left: 1px solid;\n    }\n  </style>\n</head>\n<body>\n<a href=\"?lang=Ru\">Russian</a> &nbsp;\n<a href=\"?lang=Am\">Armenian</a>&nbsp; \n<a href=\"?lang=En\">English</a>&nbsp;\n<a href=\"?lang=Es\">Spanish</a>&nbsp;\n<pre id=\"editor\"></pre>\n    \n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/searchbox\", \"ace/ext/language_tools\"], function(ace) {\n    var messagesRussian = {\n        \"$id\": \"ru\",\n        \n        \"Search for\": \"Найти\",\n        \"All\": \"Все\",\n        \"Replace with\": \"Заменить\",\n        \"Replace\": \"Заменить\",\n        \"Toggle Replace mode\": \"Перейти в режим поиска\",\n        \"RegExp Search\": \"Поиск по регулярному выражению\",\n        \"CaseSensitive Search\": \"\",\n        \"Whole Word Search\": \"\",\n        \"Search In Selection\": \"Искать в выделенном\",\n        \"$0 of $1\": \"$0 из $1\",\n        \n        \"Looks good!\": \"Нет ошибок\",\n        \n        \"Recently used\": \"Недавно использованные\",\n        \"Other commands\": \"Другие команды\",\n        \"No matching commands\": \"Нет подходящих команд\",\n        \n        \"Autocomplete suggestions\": \"Предложения автозаполнения\",\n                \n        \"Cursor at row $0\": \"\",\n        \"Toggle code folding, rows $0 through $1\": \"\",\n        \"Toggle code folding, row $0\": \"\",\n        \"Unfold code\": \"\",\n        \"Fold code\": \"\",\n        \"Read annotations row $0\": \"\",\n        \n        \"error\": \"ошибка\",\n        \"errors\": \"ошибки\",\n        \"warning\": \"предупреждение\",\n        \"warnings\": \"предупреждения\",\n        \"information message\": \"информационное сообщение\",\n        \"information messages\": \"информационные сообщения\"\n    };\n    \n    var messagesArmenian = {\n        \"$id\": \"am\",\n        \n        \"Search for\": \"Փնտրել\",\n        \"All\": \"Բոլորը\",\n        \"Replace with\": \"Փոխարինել\",\n        \"Replace\": \"Փոխարինել\",\n        \"Toggle Replace mode\": \"\",\n        \"RegExp Search\": \"Փնտրել ռեգեքսպով\",\n        \"CaseSensitive Search\": \"\",\n        \"Whole Word Search\": \"Ամբողջ բառեր\",\n        \"Search In Selection\": \"Փնտրել նշվածում\",\n        \"$0 of $1\": \"$1-ից $0\",\n        \n        \"Looks good!\": \"Սխալ չկա\",\n        \n        \"Recently used\": \"Վերջերս օգտագործված\",\n        \"Other commands\": \"Այլ հրամաններ\",\n        \"No matching commands\": \"Չկան համապատասխան հրամաններ\",\n        \n        \"Autocomplete suggestions\": \"Ավտոմատ լրացման առաջարկներ\",\n        \n        \"Cursor at row $0\": \"\",\n        \"Toggle code folding, rows $0 through $1\": \"\",\n        \"Toggle code folding, row $0\": \"\",\n        \"Unfold code\": \"\",\n        \"Fold code\": \"\",\n        \"Read annotations row $0\": \"\",\n        \n        \"error\": \"սխալ\",\n        \"errors\": \"սխալներ\",\n        \"warning\": \"նախազգուշացում\",\n        \"warnings\": \"նախազգուշացումներ\",\n        \"information message\": \"տեղեկատվություն\",\n        \"information messages\": \"տեղեկատվություններ\"\n    };\n\n    var messagesSpanish = {\n        \"$id\": \"es\",\n        \"Autocomplete suggestions\": \"Sugerencias de autocompletar\",\n        \"editor\": \"editor\",\n        \"Editor content, press Enter to start editing, press Escape to exit\": \"Contenido del editor, presiona Entrar para empezar a editar, presiona Escape para salir\",\n        \"Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit\": \"Canaleta de editor, presiona Entrar para por, presiona Escape para salir\",\n        \"Looks good!\": \"¡Parece bien!\",\n        \"Recently used\": \"Usado recientemente\",\n        \"Other commands\": \"Otros mandos\",\n        \"No matching commands\": \"No hay mandos que hacen juego\",\n        \"Search for\": \"Buscar\",\n        \"All\": \"Todo\",\n        \"Replace with\": \"Reemplazar con\",\n        \"Replace\": \"Reemplazar\",\n        \"Toggle Replace mode\": \"Pasar el modo de reemplazar\",\n        \"RegExp Search\": \"Búsqueda de RegExp\",\n        \"CaseSensitive Search\": \"Búsqueda sensible a mayúsculas y minúsculas\",\n        \"Whole Word Search\": \"Búsqueda de palabras enteras\",\n        \"Search In Selection\": \"Buscar en la selección\",\n        \"$0 of $1\": \"$0 de $1\",\n        \"Cursor at row $0\": \"Cursor en row $0\",\n        \"Unfold rows $0 to $1\": \"Desplegar las filas desde $0 hasta $1\",\n        \"Unfold code\": \"Desplegar el codigo\",\n        \"Fold at row $0\": \"Plegar en fila $0\",\n        \"Toggle code folding, rows $0 through $1\": \"\",\n        \"Toggle code folding, row $0\": \"\",\n        \"Fold code\": \"Plegar el codigo\",\n        \"Read annotations row $0\": \"Leer anotaciones fila $0\",\n        \"error\": \"error\",\n        \"errors\": \"errores\",\n        \"warning\": \"advertencia\",\n        \"warnings\": \"advertencias\",\n        \"information message\": \"mensaje de informacion\",\n        \"information messages\": \"mensajes de informacion\"\n    }\n\n\n\n    if (/lang=ru/i.test(location.href)) {\n        ace.config.setMessages(messagesRussian);\n    } else if (/lang=en/i.test(location.href)) {\n        ace.config.setMessages();\n    } else if (/lang=es/i.test(location.href)) {\n        ace.config.setMessages(messagesSpanish)\n    } else {\n        ace.config.setMessages(messagesArmenian);\n    }\n\n    var editor = ace.edit(\"editor\", {\n        mode: \"ace/mode/html\"\n    });\n    \n    editor.execCommand(\"find\");\n    setTimeout(function() {\n        editor.execCommand(\"goToNextError\");\n    }, 2000);\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/inline_autocompletion.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>ACE Inline Autocompletion demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n\n    #editor {\n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/mode/javascript\", \"ace/ext/language_tools\", \"ace/ext/inline_autocomplete\"], function(ace, codeLens) {\n    var editor = ace.edit(\"editor\");\n    editor.session.setMode(\"ace/mode/javascript\");\n    editor.setTheme(\"ace/theme/tomorrow\");\n    // enable inline autocompletion\n    editor.setOptions({\n        enableBasicAutocompletion: false,\n        enableInlineAutocompletion: true,\n        enableSnippets: true,\n        enableLiveAutocompletion: false\n    });\n\n    window.editor = editor;\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/keyboard_shortcuts.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n    \n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\nrequire([\"ace/ace\"], function(ace) {\n    var editor = ace.edit(\"editor\")\n    editor.setTheme(\"ace/theme/twilight\")\n    editor.session.setMode(\"ace/mode/html\")\n    \n    // add command to lazy-load keybinding_menu extension\n    editor.commands.addCommand({\n        name: \"showKeyboardShortcuts\",\n        bindKey: {win: \"Ctrl-Alt-h\", mac: \"Command-Alt-h\"},\n        exec: function(editor) {\n            ace.config.loadModule(\"ace/ext/keybinding_menu\", function(module) {\n                module.init(editor);\n                editor.showKeyboardShortcuts()\n            })\n        }\n    })\n    editor.execCommand(\"showKeyboardShortcuts\")\n})\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/demo.js",
    "content": "\"use strict\";\n\nrequire(\"ace/ext/rtl\");\n\nrequire(\"ace/multi_select\");\nrequire(\"./inline_editor\");\nvar devUtil = require(\"./dev_util\");\nrequire(\"./file_drop\");\n\nvar config = require(\"ace/config\");\nconfig.setLoader(function(moduleName, cb) {\n    require([moduleName], function(module) {\n        cb(null, module);\n    });\n});\n\nvar env = {};\n\nvar dom = require(\"ace/lib/dom\");\nvar net = require(\"ace/lib/net\");\nvar lang = require(\"ace/lib/lang\");\n\nvar event = require(\"ace/lib/event\");\nvar theme = require(\"ace/theme/textmate\");\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\n\nvar HashHandler = require(\"ace/keyboard/hash_handler\").HashHandler;\n\nvar Renderer = require(\"ace/virtual_renderer\").VirtualRenderer;\nvar Editor = require(\"ace/editor\").Editor;\nvar Range = require(\"ace/range\").Range;\n\nvar whitespace = require(\"ace/ext/whitespace\");\n\nvar createDiffView = require(\"ace/ext/diff\").createDiffView;\n\n\nvar doclist = require(\"./doclist\");\nvar layout = require(\"./layout\");\nvar util = require(\"./util\");\nvar saveOption = util.saveOption;\n\nrequire(\"ace/ext/elastic_tabstops_lite\");\nrequire(\"ace/incremental_search\");\n\nrequire(\"ace/ext/whitespaces_in_selection\");\n\nvar TokenTooltip = require(\"./token_tooltip\").TokenTooltip;\nrequire(\"ace/config\").defineOptions(Editor.prototype, \"editor\", {\n    showTokenInfo: {\n        set: function(val) {\n            if (val) {\n                this.tokenTooltip = this.tokenTooltip || new TokenTooltip(this);\n            }\n            else if (this.tokenTooltip) {\n                this.tokenTooltip.destroy();\n                delete this.tokenTooltip;\n            }\n        },\n        get: function() {\n            return !!this.tokenTooltip;\n        },\n        handlesSet: true\n    }\n});\n\nrequire(\"ace/config\").defineOptions(Editor.prototype, \"editor\", {\n    useAceLinters: {\n        set: function(val) {\n            var enabled = !!val;\n            if (enabled && !window.languageProvider) {\n                loadLanguageProvider(this);\n            }\n            else if (enabled) {\n                window.languageProvider.registerEditor(this);\n            } else {\n                if (window.languageProvider) {\n                    window.languageProvider.unregisterEditor(this, true);\n                    window.languageProvider = null;\n                }\n                if (this.getOption(\"useAceSpellCheck\")) {\n                    this.setOption(\"useAceSpellCheck\", false);\n                    saveOption(\"useAceSpellCheck\", false);\n                    if (env.optionsPanel) {\n                        env.optionsPanel.editor = this;\n                        env.optionsPanel.render();\n                    }\n                }\n            }\n        }\n    }\n});\n\nrequire(\"ace/config\").defineOptions(Editor.prototype, \"editor\", {\n    useAceSpellCheck: {\n        set: function(val) {\n            var nextValue = !!val;\n            if (window.useAceSpellCheck === nextValue) return;\n            window.useAceSpellCheck = nextValue;\n            if (nextValue && !this.getOption(\"useAceLinters\")) {\n                this.setOption(\"useAceLinters\", true);\n                saveOption(\"useAceLinters\", true);\n                if (env.optionsPanel) {\n                    env.optionsPanel.editor = this;\n                    env.optionsPanel.render();\n                }\n                return;\n            }\n            if (window.languageProvider && this.getOption(\"useAceLinters\")) {\n                window.languageProvider.unregisterEditor(this, true);\n                window.languageProvider = null;\n                loadLanguageProvider(this);\n            }\n        },\n        get: function() {\n            return window.useAceSpellCheck !== false;\n        },\n        handlesSet: true\n    }\n});\n\nvar {HoverTooltip} = require(\"ace/tooltip\");\nvar MarkerGroup = require(\"ace/marker_group\").MarkerGroup;\nvar docTooltip = new HoverTooltip();\nwindow.useAceSpellCheck = true;\n\nfunction loadLanguageProvider(editor) {\n    function loadScript(cb) {\n        if (define.amd) {\n            require([\n                \"https://mkslanc.github.io/ace-linters/build/ace-linters.js\"\n            ], function(m) {\n                cb(m.LanguageProvider);\n            });\n        } else {\n            net.loadScript([\n                \"https://mkslanc.github.io/ace-linters/build/ace-linters.js\"\n            ], function() {\n                cb(window.LanguageProvider);\n            });\n        }\n    }\n    loadScript(function(LanguageProvider) {\n        var services = [];\n        if (window.useAceSpellCheck !== false) {\n            services.push({\n                name: \"ace-spell-check\",\n                className: \"AceSpellCheck\",\n                modes: \"*\",\n                script: \"ace-spell-check.js\",\n                cdnUrl: \"https://unpkg.com/ace-spell-check@latest/build\"\n            });\n        }\n\n        var languageProvider = LanguageProvider.fromCdn({\n            services: services,\n            serviceManagerCdn:\"https://mkslanc.github.io/ace-linters/build\",\n            includeDefaultLinters: true\n        }, {\n            functionality: {\n                hover: true,\n                completion: {\n                    overwriteCompleters: true\n                },\n                completionResolve: true,\n                format: true,\n                documentHighlights: true,\n                signatureHelp: false\n            }\n        });\n        window.languageProvider = languageProvider;\n        languageProvider.registerEditor(editor);\n    });\n}\n\n\n\nvar workerModule = require(\"ace/worker/worker_client\");\nif (location.href.indexOf(\"noworker\") !== -1) {\n    workerModule.WorkerClient = workerModule.UIWorkerClient;\n}\n\n/*********** create editor ***************************/\nvar container = document.getElementById(\"editor-container\");\n\n// Splitting.\nvar Split = require(\"ace/split\").Split;\nvar split = new Split(container, theme, 1);\nenv.editor = split.getEditor(0);\nsplit.on(\"focus\", function(editor) {\n    env.editor = editor;\n    updateUIEditorOptions();\n});\nenv.split = split;\nwindow.env = env;\n\n\nvar consoleEl = dom.createElement(\"div\");\ncontainer.parentNode.appendChild(consoleEl);\nconsoleEl.style.cssText = \"position:fixed; bottom:1px; right:0;\\\nborder:1px solid #baf; z-index:100\";\n\nvar cmdLine = new layout.singleLineEditor(consoleEl);\ncmdLine.setOption(\"placeholder\", \"Enter a command...\");\ncmdLine.editor = env.editor;\nenv.editor.cmdLine = cmdLine;\n\nenv.editor.showCommandLine = function(val) {\n    this.cmdLine.focus();\n    if (typeof val == \"string\")\n        this.cmdLine.setValue(val, 1);\n};\n\n/**\n * This demonstrates how you can define commands and bind shortcuts to them.\n */\nenv.editor.commands.addCommands([{\n    name: \"snippet\",\n    bindKey: {win: \"Alt-C\", mac: \"Command-Alt-C\"},\n    exec: function(editor, needle) {\n        if (typeof needle == \"object\") {\n            editor.cmdLine.setValue(\"snippet \", 1);\n            editor.cmdLine.focus();\n            return;\n        }\n        var s = snippetManager.getSnippetByName(needle, editor);\n        if (s)\n            snippetManager.insertSnippet(editor, s.content);\n    },\n    readOnly: true\n}, {\n    name: \"focusCommandLine\",\n    bindKey: \"shift-esc|ctrl-`\",\n    exec: function(editor, needle) { editor.cmdLine.focus(); },\n    readOnly: true\n}, {\n    name: \"nextFile\",\n    bindKey: \"Ctrl-tab\",\n    exec: function(editor) { doclist.cycleOpen(editor, 1); },\n    readOnly: true\n}, {\n    name: \"previousFile\",\n    bindKey: \"Ctrl-shift-tab\",\n    exec: function(editor) { doclist.cycleOpen(editor, -1); },\n    readOnly: true\n}, {\n    name: \"execute\",\n    bindKey: \"ctrl+enter\",\n    exec: function(editor) {\n        try {\n            var r = window.eval(editor.getCopyText() || editor.getValue());\n        } catch(e) {\n            r = e;\n        }\n        editor.cmdLine.setValue(r + \"\");\n    },\n    readOnly: true\n}, {\n    name: \"showKeyboardShortcuts\",\n    bindKey: {win: \"Ctrl-Alt-h\", mac: \"Command-Alt-h\"},\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/keybinding_menu\", function(module) {\n            module.init(editor);\n            editor.showKeyboardShortcuts();\n        });\n    }\n}, {\n    name: \"increaseFontSize\",\n    bindKey: \"Ctrl-=|Ctrl-+\",\n    exec: function(editor) {\n        var size = parseInt(editor.getFontSize(), 10) || 12;\n        editor.setFontSize(size + 1);\n    }\n}, {\n    name: \"decreaseFontSize\",\n    bindKey: \"Ctrl+-|Ctrl-_\",\n    exec: function(editor) {\n        var size = parseInt(editor.getFontSize(), 10) || 12;\n        editor.setFontSize(Math.max(size - 1 || 1));\n    }\n}, {\n    name: \"resetFontSize\",\n    bindKey: \"Ctrl+0|Ctrl-Numpad0\",\n    exec: function(editor) {\n        editor.setFontSize(12);\n    }\n}]);\n\n\nenv.editor.commands.addCommands(whitespace.commands);\n\ncmdLine.commands.bindKeys({\n    \"Shift-Return|Ctrl-Return|Alt-Return\": function(cmdLine) { cmdLine.insert(\"\\n\"); },\n    \"Esc|Shift-Esc\": function(cmdLine){ cmdLine.editor.focus(); },\n    \"Return\": function(cmdLine){\n        var command = cmdLine.getValue().split(/\\s+/);\n        var editor = cmdLine.editor;\n        editor.commands.exec(command[0], editor, command[1]);\n        editor.focus();\n    }\n});\n\ncmdLine.commands.removeCommands([\"find\", \"gotoline\", \"findall\", \"replace\", \"replaceall\"]);\n\nvar commands = env.editor.commands;\ncommands.addCommand({\n    name: \"save\",\n    bindKey: {win: \"Ctrl-S\", mac: \"Command-S\"},\n    exec: function(arg) {\n        var session = env.editor.session;\n        var name = session.name.match(/[^\\/]+$/);\n        localStorage.setItem(\n            \"saved_file:\" + name,\n            session.getValue()\n        );\n        env.editor.cmdLine.setValue(\"saved \"+ name);\n    }\n});\n\ncommands.addCommand({\n    name: \"load\",\n    bindKey: {win: \"Ctrl-O\", mac: \"Command-O\"},\n    exec: function(arg) {\n        var session = env.editor.session;\n        var name = session.name.match(/[^\\/]+$/);\n        var value = localStorage.getItem(\"saved_file:\" + name);\n        if (typeof value == \"string\") {\n            session.setValue(value);\n            env.editor.cmdLine.setValue(\"loaded \"+ name);\n        } else {\n            env.editor.cmdLine.setValue(\"no previuos value saved for \"+ name);\n        }\n    }\n});\n\n\n/*********** manage layout ***************************/\nfunction handleToggleActivate(target) {\n    if (dom.hasCssClass(sidePanelContainer, \"closed\"))\n        onResize(null, false);\n    else if (dom.hasCssClass(target, \"toggleButton\"))\n        onResize(null, true);\n};\nvar sidePanelContainer = document.getElementById(\"sidePanel\");\nsidePanelContainer.onclick = function(e) {\n    handleToggleActivate(e.target);\n};\nvar optionToggle = document.getElementById(\"optionToggle\");\noptionToggle.onkeydown = function(e) {\n    if (e.code === \"Space\" || e.code === \"Enter\") {\n        handleToggleActivate(e.target);\n    }\n};\nvar consoleHeight = 20;\nfunction onResize(e, closeSidePanel) {\n    var left = 280;\n    var width = document.documentElement.clientWidth;\n    var height = document.documentElement.clientHeight;\n    if (closeSidePanel == null)\n        closeSidePanel = width < 2 * left;\n    if (closeSidePanel) {\n        left = 20;\n        document.getElementById(\"optionToggle\").setAttribute(\"aria-label\", \"Show Options\");\n    } else\n        document.getElementById(\"optionToggle\").setAttribute(\"aria-label\", \"Hide Options\");\n    width -= left;\n    container.style.width = width + \"px\";\n    container.style.height = height - consoleHeight + \"px\";\n    container.style.left = left + \"px\";\n    env.split.resize();\n\n    consoleEl.style.width = width + \"px\";\n    consoleEl.style.left = left + \"px\";\n    cmdLine.resize();\n    \n    sidePanel.style.width = left + \"px\";\n    sidePanel.style.height = height + \"px\";\n    dom.setCssClass(sidePanelContainer, \"closed\", closeSidePanel);\n}\n\nwindow.onresize = onResize;\nonResize();\n\n/*********** options panel ***************************/\nvar diffView;\ndoclist.history = doclist.docs.map(function(doc) {\n    return doc.name;\n});\ndoclist.history.index = 0;\ndoclist.cycleOpen = function(editor, dir) {\n    var h = this.history;\n    h.index += dir;\n    if (h.index >= h.length)\n        h.index = 0;\n    else if (h.index <= 0)\n        h.index = h.length - 1;\n    var s = h[h.index];\n    doclist.pickDocument(s);\n};\ndoclist.addToHistory = function(name) {\n    var h = this.history;\n    var i = h.indexOf(name);\n    if (i != h.index) {\n        if (i != -1)\n            h.splice(i, 1);\n        h.index = h.push(name);\n    }\n};\n\nvar initDoc = (session) => {\n    if (!session)\n        return;\n    doclist.addToHistory(session.name);\n    session = env.split.setSession(session);\n    whitespace.detectIndentation(session);\n    optionsPanel.render();\n    env.editor.focus();\n    if (diffView) {\n        diffView.detach()\n        diffView = createDiffView({\n            inline: \"b\",\n            editorB: editor,\n            valueA: editor.getValue()\n        });\n    }\n}\n\ndoclist.pickDocument = function(name) {\n    doclist.loadDoc(name, initDoc);\n};\n\n\n\nvar OptionPanel = require(\"ace/ext/options\").OptionPanel;\nvar optionsPanel = env.optionsPanel = new OptionPanel(env.editor);\n\nvar originalAutocompleteCommand = null;\n\n\noptionsPanel.add({\n    Main: {\n        Document: {\n            type: \"select\",\n            path: \"doc\",\n            items: doclist.all,\n            position: -101,\n            onchange: doclist.pickDocument,\n            getValue: function() {\n                return env.editor.session.name || \"javascript\";\n            }\n        },\n        Split: {\n            type: \"buttonBar\",\n            path: \"split\",\n            values: [\"None\", \"Below\", \"Beside\"],\n            position: -100,\n            onchange: function(value) {\n                var sp = env.split;\n                if (value == \"Below\" || value == \"Beside\") {\n                    var newEditor = (sp.getSplits() == 1);\n                    sp.setOrientation(value == \"Below\" ? sp.BELOW : sp.BESIDE);\n                    sp.setSplits(2);\n\n                    if (newEditor) {\n                        var session = sp.getEditor(0).session;\n                        var newSession = sp.setSession(session, 1);\n                        newSession.name = session.name;\n                    }\n                } else {\n                    sp.setSplits(1);\n                }\n            },\n            getValue: function() {\n                var sp = env.split;\n                return sp.getSplits() == 1\n                    ? \"None\"\n                    : sp.getOrientation() == sp.BELOW\n                    ? \"Below\"\n                    : \"Beside\";\n            }\n        },\n        \"Show diffs\": {\n            position: -102,\n            type: \"buttonBar\",\n            path: \"diffView\",\n            values: [\"None\", \"Inline\"],\n            onchange: function (value) {\n                    if (value === \"Inline\" && !diffView) {\n                        diffView = createDiffView({\n                            inline: \"b\",\n                            editorB: editor,\n                            valueA: editor.getValue()\n                        });\n                    }\n                    else if (value === \"None\") {\n                        if (diffView) {\n                            diffView.detach();\n                            diffView = null;\n                        }\n                    }\n            },\n            getValue: function() {\n                return !diffView ? \"None\"\n                    : \"Inline\";\n            }\n        }\n    },\n    More: {\n        \"RTL\": {\n            path: \"rtl\",\n            position: 900\n        },\n        \"Line based RTL switching\": {\n            path: \"rtlText\",\n            position: 900\n        },\n        \"Show token info\": {\n            path: \"showTokenInfo\",\n            position: 2000\n        },\n        \"Inline preview for autocomplete\": {\n            path: \"inlineEnabledForAutocomplete\",\n            position: 2000,\n            onchange: function(value) {\n                var Autocomplete = require(\"ace/autocomplete\").Autocomplete;\n                if (value && !originalAutocompleteCommand) {\n                    originalAutocompleteCommand = Autocomplete.startCommand.exec;\n                    Autocomplete.startCommand.exec = function(editor) {\n                        var autocomplete = Autocomplete.for(editor);\n                        autocomplete.inlineEnabled = true;\n                        originalAutocompleteCommand(...arguments);\n                    }\n                } else if (!value) {\n                    var autocomplete = Autocomplete.for(editor);\n                    autocomplete.destroy();\n                    if (originalAutocompleteCommand)\n                        Autocomplete.startCommand.exec = originalAutocompleteCommand;\n                    originalAutocompleteCommand = null;\n                }\n            },\n            getValue: function() {\n                return !!originalAutocompleteCommand;\n            }\n        },\n        \"Use Ace Linters\": {\n            position: 3000,\n            path: \"useAceLinters\"\n        },\n        \"Use Spell Checker\": {\n            position: 3001,\n            path: \"useAceSpellCheck\"\n        },\n        \"Show whitespaces in selection\": {\n            position: 3100,\n            path: \"showWhitespacesInSelection\"\n        },\n        \"Show Textarea Position\": devUtil.textPositionDebugger,\n        \"Text Input Debugger\": devUtil.textInputDebugger,\n    }\n});\n\nvar optionsPanelContainer = document.getElementById(\"optionsPanel\");\noptionsPanel.render();\noptionsPanelContainer.insertBefore(optionsPanel.container, optionsPanelContainer.firstChild);\noptionsPanel.on(\"setOption\", function(e) {\n    util.saveOption(e.name, e.value);\n});\n\nfunction updateUIEditorOptions() {\n    optionsPanel.editor = env.editor;\n    optionsPanel.render();\n}\n\nenv.editor.on(\"changeSession\", function() {\n    for (var i in env.editor.session.$options) {\n        if (i == \"mode\") continue;\n        var value = util.getOption(i);\n        if (value != undefined) {\n            env.editor.setOption(i, value);\n        }\n    }\n});\n\nif (localStorage.last_session) {\n    try {\n        var sessionObj = JSON.parse(localStorage.last_session);\n        var session = EditSession.fromJSON(localStorage.last_session);\n        session.name = sessionObj.name;\n        var cachedDoc = doclist.fileCache[session.name.toLowerCase()];\n        if (cachedDoc) {\n            cachedDoc.session = session;\n        }\n        initDoc(session);\n    } catch (e) {\n        console.error(e);\n        optionsPanel.setOption(\"doc\", util.getOption(\"doc\") || \"JavaScript\");\n    }\n}\nfor (var i in optionsPanel.options) {\n    if (i === \"doc\") continue;\n    var value = util.getOption(i);\n    if (value != undefined) {\n        if ((i == \"mode\" || i == \"theme\") && !/[/]/.test(value))\n            value = \"ace/\" + i + \"/\" + value;\n        optionsPanel.setOption(i, value);\n    }\n}\noptionsPanel.render();\n\n\nfunction synchroniseScrolling() {\n    var s1 = env.split.$editors[0].session;\n    var s2 = env.split.$editors[1].session;\n    s1.on('changeScrollTop', function(pos) {s2.setScrollTop(pos)});\n    s2.on('changeScrollTop', function(pos) {s1.setScrollTop(pos)});\n    s1.on('changeScrollLeft', function(pos) {s2.setScrollLeft(pos)});\n    s2.on('changeScrollLeft', function(pos) {s1.setScrollLeft(pos)});\n}\n\nvar StatusBar = require(\"ace/ext/statusbar\").StatusBar;\nnew StatusBar(env.editor, cmdLine.container);\n\nrequire(\"ace/placeholder\").PlaceHolder;\n\nvar snippetManager = require(\"ace/snippets\").snippetManager;\n\nenv.editSnippets = function() {\n    var sp = env.split;\n    if (sp.getSplits() == 2) {\n        sp.setSplits(1);\n        return;\n    }\n    sp.setSplits(1);\n    sp.setSplits(2);\n    sp.setOrientation(sp.BESIDE);\n    var editor = sp.$editors[1];\n    var id = sp.$editors[0].session.$mode.$id || \"\";\n    var m = snippetManager.files[id];\n    if (!doclist[\"snippets/\" + id]) {\n        var text = m.snippetText;\n        var s = doclist.initDoc(text, \"\", {});\n        s.setMode(\"ace/mode/snippets\");\n        doclist[\"snippets/\" + id] = s;\n    }\n    editor.on(\"blur\", function() {\n        m.snippetText = editor.getValue();\n        snippetManager.unregister(m.snippets);\n        m.snippets = snippetManager.parseSnippetFile(m.snippetText, m.scope);\n        snippetManager.register(m.snippets);\n    });\n    sp.$editors[0].once(\"changeMode\", function() {\n        sp.setSplits(1);\n    });\n    editor.setSession(doclist[\"snippets/\" + id], 1);\n    editor.focus();\n};\n\noptionsPanelContainer.insertBefore(\n    dom.buildDom([\"div\", {style: \"text-align:right;width: 80%\"},\n        [\"div\", {}, \n            [\"button\", {onclick: env.editSnippets}, \"Edit Snippets\"]],\n        [\"div\", {}, \n            [\"button\", {onclick: function() {\n                var info = navigator.platform + \"\\n\" + navigator.userAgent;\n                if (env.editor.getValue() == info)\n                    return env.editor.undo();\n                env.editor.setValue(info, -1);\n                env.editor.setOption(\"wrap\", 80);\n            }}, \"Show Browser Info\"]],\n        devUtil.getUI(),\n        [\"div\", {},\n            \"Open Dialog \",\n            [\"button\",  {onclick: openTestDialog.bind(null, false)}, \"Scale\"],\n            [\"button\",  {onclick: openTestDialog.bind(null, true)}, \"Height\"]\n        ]\n    ]),\n    optionsPanelContainer.children[1]\n);\n\n\nvar resetSession = () => {\n    if (localStorage) {\n        localStorage.last_session = undefined;\n    }\n    try {\n        var session = env.editor.session;\n        if (session.name)\n            var cachedDoc = doclist.fileCache[session.name.toLowerCase()];\n        if (cachedDoc) {\n            cachedDoc.session = undefined;\n        }\n        optionsPanel.setOption(\"doc\", util.getOption(\"doc\") || \"JavaScript\");\n    } catch (e) {\n        console.error(e);\n    }\n};\n\noptionsPanelContainer.insertBefore(\n    dom.buildDom([\"div\", {style: \"text-align:center;width: 100%\"},\n        [\"div\", {},\n            [\"button\", {onclick: resetSession}, \"Reset session\"]],\n    ]),\n    optionsPanelContainer.children[0]\n);\n\nfunction openTestDialog(animateHeight) {\n    if (window.dialogEditor) \n        window.dialogEditor.destroy();\n    var editor = ace.edit(null, {\n        value: \"test editor\", \n        mode: \"ace/mode/javascript\",\n        enableBasicAutocompletion: true\n    });\n    window.dialogEditor = editor;\n\n    editor.completer.parentNode = editor.container;\n    if (window.languageProvider)\n        window.languageProvider.registerEditor(editor);\n\n    var dialog = dom.buildDom([\"div\", {\n        style: \"transition: all 1s; position: fixed; z-index: 100000;\"\n          + \"background: darkblue; border: solid 1px black; display: flex; flex-direction: column\"\n        }, \n        [\"div\", {}, \"test dialog\"],\n        editor.container\n    ], document.body);\n    editor.container.style.flex = \"1\";\n    if (animateHeight) {\n        dialog.style.width = \"0vw\";\n        dialog.style.height = \"0vh\";\n        dialog.style.left = \"20vw\";\n        dialog.style.top = \"20vh\";\n        setTimeout(function() {            \n            dialog.style.width = \"80vw\";\n            dialog.style.height = \"80vh\";\n            dialog.style.left = \"10vw\";\n            dialog.style.top = \"10vh\";\n        }, 0);\n        \n    } else {\n        dialog.style.width = \"80vw\";\n        dialog.style.height = \"80vh\";\n        dialog.style.left = \"10vw\";\n        dialog.style.top = \"10vh\";\n        dialog.style.transform = \"scale(0)\";\n        setTimeout(function() {\n            dialog.style.transform = \"scale(1)\"\n        }, 0);\n    }\n    function close(e) {\n        if (!e || !dialog.contains(e.target)) {\n            if (animateHeight) {\n                dialog.style.width = \"0vw\";\n                dialog.style.height = \"0vh\";\n                dialog.style.left = \"80vw\";\n                dialog.style.top = \"80vh\";\n            } else {\n                dialog.style.transform = \"scale(0)\"\n            }\n            window.removeEventListener(\"mousedown\", close);\n            dialog.addEventListener(\"transitionend\", function() {\n                dialog.remove();\n                editor.destroy();\n            });\n        }\n    }\n    window.addEventListener(\"mousedown\", close);\n    editor.focus()\n    editor.commands.bindKey(\"Esc\", function() { close(); });\n}\n\n\nrequire(\"ace/ext/language_tools\");\nrequire(\"ace/ext/inline_autocomplete\");\nenv.editor.setOptions({\n    enableBasicAutocompletion: true,\n    enableInlineAutocompletion: true,\n    enableSnippets: true\n});\n\nvar beautify = require(\"ace/ext/beautify\");\nenv.editor.commands.addCommands(beautify.commands);\n\n\n// global keybindings\n\nvar KeyBinding = require(\"ace/keyboard/keybinding\").KeyBinding;\nvar CommandManager = require(\"ace/commands/command_manager\").CommandManager;\nvar commandManager = new CommandManager();\nvar kb = new KeyBinding({\n    commands: commandManager,\n    fake: true\n});\nevent.addCommandKeyListener(document.documentElement, kb.onCommandKey.bind(kb));\nevent.addListener(document.documentElement, \"keyup\", function(e) {\n    if (e.keyCode === 18) // do not trigger browser menu on windows\n        e.preventDefault();\n});\ncommandManager.addCommands([{\n    name: \"window-left\",\n    bindKey: {win: \"cmd-alt-left\", mac: \"ctrl-cmd-left\"},\n    exec: function() {\n        moveFocus();\n    }\n}, {\n    name: \"window-right\",\n    bindKey: {win: \"cmd-alt-right\", mac: \"ctrl-cmd-right\"},\n    exec: function() {\n        moveFocus();\n    }\n}, {\n    name: \"window-up\",\n    bindKey: {win: \"cmd-alt-up\", mac: \"ctrl-cmd-up\"},\n    exec: function() {\n        moveFocus();\n    }\n}, {\n    name: \"window-down\",\n    bindKey: {win: \"cmd-alt-down\", mac: \"ctrl-cmd-down\"},\n    exec: function() {\n        moveFocus();\n    }\n}]);\n\nfunction moveFocus() {\n    var el = document.activeElement;\n    if (el == env.editor.textInput.getElement())\n        env.editor.cmdLine.focus();    \n    else\n        env.editor.focus();\n}\n\nwindow.onbeforeunload = function () {\n    if (env.editor && localStorage) {\n        var sessionObj = env.editor.session.toJSON();\n        sessionObj.name = util.getOption(\"doc\") || \"JavaScript\";\n        localStorage.last_session = JSON.stringify(sessionObj);\n    }\n};\n"
  },
  {
    "path": "demo/kitchen-sink/dev_util.js",
    "content": "var ace = require(\"ace/ace\");\nvar dom = require(\"ace/lib/dom\");\nvar event = require(\"ace/lib/event\");\nvar Range = require(\"ace/range\").Range;\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\nfunction def(o, key, get) {\n    try {\n        Object.defineProperty(o, key, {\n            configurable: true, \n            get: get,\n            set: function(val) {\n                delete o[key];\n                o[key] = val;\n            }\n        });\n    } catch(e) {\n        console.error(e);\n    }\n}\ndef(window, \"ace\", function(){  return ace });\ndef(window, \"editor\", function(){  return window.env.editor == logEditor ? editor : window.env.editor });\ndef(window, \"session\", function(){ return window.editor.session });\ndef(window, \"split\", function(){  return window.env.split });\n\n\ndef(window, \"devUtil\", function(){ return exports });\n\nexports.addGlobals = function() {\n    window.oop = require(\"ace/lib/oop\");\n    window.dom = require(\"ace/lib/dom\");\n    window.user = require(\"ace/test/user\");\n    window.Range = require(\"ace/range\").Range;\n    window.Editor = require(\"ace/editor\").Editor;\n    window.assert = require(\"ace/test/asyncjs/assert\");\n    window.asyncjs = require(\"ace/test/asyncjs/async\");\n    window.UndoManager = require(\"ace/undomanager\").UndoManager;\n    window.EditSession = require(\"ace/edit_session\").EditSession;\n    window.MockRenderer = require(\"ace/test/mockrenderer\").MockRenderer;\n    window.EventEmitter = require(\"ace/lib/event_emitter\").EventEmitter;\n    \n    window.getSelection = getSelection;\n    window.setSelection = setSelection;\n    window.testSelection = testSelection;\n    window.setValue = setValue;\n    window.testValue = testValue;\n    window.logToAce = exports.log;\n};\n\nfunction getSelection(editor) {\n    var data = editor.multiSelect.toJSON();\n    if (!data.length) data = [data];\n    data = data.map(function(x) {\n        var a, c;\n        if (x.isBackwards) {\n            a = x.end;\n            c = x.start;\n        } else {\n            c = x.end;\n            a = x.start;\n        }\n        return Range.comparePoints(a, c) \n            ? [a.row, a.column, c.row, c.column]\n            : [a.row, a.column];\n    });\n    return data.length > 1 ? data : data[0];\n}\nfunction setSelection(editor, data) {\n    if (typeof data[0] == \"number\")\n        data = [data];\n    editor.selection.fromJSON(data.map(function(x) {\n        var start = {row: x[0], column: x[1]};\n        var end = x.length == 2 ? start : {row: x[2], column: x[3]};\n        var isBackwards = Range.comparePoints(start, end) > 0;\n        return isBackwards ? {\n            start: end,\n            end: start,\n            isBackwards: true\n        } : {\n            start: start,\n            end: end,\n            isBackwards: true\n        };\n    }));\n}\nfunction testSelection(editor, data) {\n    assert.equal(getSelection(editor) + \"\", data + \"\");\n}\nfunction setValue(editor, value) {\n    editor.setValue(value, 1);\n}\nfunction testValue(editor, value) {\n    assert.equal(editor.getValue(), value);\n}\n\n \nvar editor;\nvar logEditor;\nvar logSession\nexports.openLogView = function() {\n    exports.addGlobals();\n    var sp = window.env.split;\n    sp.setSplits(1);\n    sp.setSplits(2);\n    sp.setOrientation(sp.BESIDE);\n    editor = sp.$editors[0];\n    logEditor = sp.$editors[1];\n    \n    if (!logSession) {\n        logSession = new EditSession(localStorage.lastTestCase || \"\", \"ace/mode/javascript\");\n        logSession.setUndoManager(new UndoManager)\n    }\n    logEditor.setSession(logSession);\n    logEditor.session.foldAll();\n    logEditor.on(\"input\", save);\n}\nexports.record = function() {\n    exports.addGlobals();\n    exports.openLogView();\n    \n    logEditor.setValue(\"var Range = require(\\\"ace/range\\\").Range;\\n\"\n        + getSelection + \"\\n\"\n        + testSelection + \"\\n\"\n        + setSelection + \"\\n\"\n        + testValue + \"\\n\"\n        + setValue + \"\\n\"\n        + \"\\n//-------------------------------------\\n\", 1);\n    logEditor.session.foldAll();\n\n    addAction({\n        type: \"setValue\",\n        data: editor.getValue()\n    });\n    addAction({\n        type: \"setSelection\",\n        data: getSelection(editor)\n    });\n    editor.commands.on(\"afterExec\", onAfterExec);\n    editor.on(\"mouseup\", onMouseUp);\n    editor.selection.on(\"beforeEndOperation\", onBeforeEndOperation);\n    editor.session.on(\"change\", reportChange);\n    editor.selection.on(\"changeCursor\", reportCursorChange);\n    editor.selection.on(\"changeSelection\", reportSelectionChange);\n}\n\nexports.stop = function() {\n    save();\n    editor.commands.off(\"afterExec\", onAfterExec);\n    editor.off(\"mouseup\", onMouseUp);\n    editor.off(\"beforeEndOperation\", onBeforeEndOperation);\n    editor.session.off(\"change\", reportChange);\n    editor.selection.off(\"changeCursor\", reportCursorChange);\n    editor.selection.off(\"changeSelection\", reportSelectionChange);\n    logEditor.off(\"input\", save);\n}\nexports.closeLogView = function() {\n    exports.stop(); \n    var sp = window.env.split;\n    sp.setSplits(1);\n}\n\nexports.play = function() {\n    exports.openLogView();\n    exports.stop();\n    var code = logEditor ? logEditor.getValue() : localStorage.lastTestCase;\n    var fn = new Function(\"editor\", \"debugger;\\n\" + code);\n    fn(editor);\n}\nvar reportChange = reportEvent.bind(null, \"change\");\nvar reportCursorChange = reportEvent.bind(null, \"CursorChange\");\nvar reportSelectionChange = reportEvent.bind(null, \"SelectionChange\");\n\nfunction save() {\n    localStorage.lastTestCase = logEditor.getValue();\n}\n\nfunction reportEvent(name) {\n    addAction({\n        type: \"event\",\n        source: name\n    });\n} \nfunction onSelection() {\n    addAction({\n        type: \"event\",\n        data: \"change\",\n        source: \"operationEnd\"\n    });\n} \nfunction onBeforeEndOperation() {\n    addAction({\n        type: \"setSelection\",\n        data: getSelection(editor),\n        source: \"operationEnd\"\n    });\n} \nfunction onMouseUp() {\n    addAction({\n        type: \"setSelection\",\n        data: getSelection(editor),\n        source: \"mouseup\"\n    });\n}\nfunction onAfterExec(e) {\n    addAction({\n        type: \"exec\",\n        data: e\n    });\n    addAction({\n        type: \"value\",\n        data: editor.getValue()\n    });\n    addAction({\n        type: \"selection\",\n        data: getSelection(editor)\n    });\n}\n\nfunction addAction(a) {\n    var str = toString(a);\n    if (str) {\n        logEditor.insert(str + \"\\n\");\n        logEditor.renderer.scrollCursorIntoView();\n    }\n}\n\nvar lastValue = \"\";\nfunction toString(x) {\n    var str = \"\";\n    var data = x.data;\n    switch (x.type) {\n        case \"exec\": \n            str = 'editor.execCommand(\"' \n                + data.command.name\n                + (data.args ? '\", ' + JSON.stringify(data.args) : '\"')\n            + ')';\n            break;\n        case \"setSelection\":\n            str = 'setSelection(editor, ' + JSON.stringify(data)  + ')';\n            break;\n        case \"setValue\":\n            if (lastValue != data) {\n                lastValue = data;\n                str = 'editor.setValue(' + JSON.stringify(data) + ', -1)';\n            }\n            else {\n                return;\n            }\n            break;\n        case \"selection\":\n            str = 'testSelection(editor, ' + JSON.stringify(data) + ')';\n            break;\n        case \"value\":\n            if (lastValue != data) {\n                lastValue = data;\n                str = 'testValue(editor, ' + JSON.stringify(data) + ')';\n            }\n            else  {\n                return;\n            }\n            break;\n    }\n    return str + (x.source ? \" // \" + x.source : \"\");\n}\n\nexports.getUI = function(container) {\n    return [\"div\", {role: \"group\", \"aria-label\": \"Test\"},\n        \" Test \", \n        [\"button\", {\"aria-label\": \"Open Log View\", onclick: exports.openLogView}, \"O\"],\n        [\"button\", {onclick: exports.record}, \"Record\"],\n        [\"button\", {onclick: exports.stop}, \"Stop\"],\n        [\"button\", {onclick: exports.play}, \"Play\"],\n        [\"button\", {\"aria-label\": \"Close Log View\", onclick: exports.closeLogView}, \"X\"],\n    ];\n};\n\n\nvar ignoreEvents = false;\nexports.textInputDebugger = {\n    position: 2000,\n    path: \"textInputDebugger\",\n    onchange: function(value) {\n        var sp = env.split;\n        if (sp.getSplits() == 2) {\n            sp.setSplits(1);\n        }\n        if (env.textarea) {\n            if (env.textarea.detach)\n                env.textarea.detach();\n            env.textarea.oldParent.appendChild(env.textarea);\n            env.textarea.className = env.textarea.oldClassName;\n            env.textarea = null;\n        }\n        if (value) {\n            this.showConsole();\n        }\n    },\n    showConsole: function() {\n        var editor = env.split.$editors[0];\n        var text = editor.textInput.getElement();\n        text.oldParent = text.parentNode;\n        text.oldClassName = text.className;\n        text.className = \"text-input-debug\";\n        document.body.appendChild(text);\n        env.textarea = text;\n        \n        var addToLog = function(e) {\n            if (ignoreEvents) return;\n            var data = {\n                _: e.type, \n                data: e.data,\n                inputType: e.inputType,\n                range: [text.selectionStart, text.selectionEnd], \n                value: text.value, \n                key: e.key && {\n                    code: e.code,\n                    key: e.key, \n                    keyCode: e.keyCode\n                },\n                modifier: event.getModifierString(e) || undefined\n            };\n            var str = JSON.stringify(data).replace(/\"(\\w+)\":/g, \" $1: \");\n            exports.log(str);\n        };\n        var events = [\"select\", \"input\", \"keypress\", \"keydown\", \"keyup\", \n            \"compositionstart\", \"compositionupdate\", \"compositionend\", \"cut\", \"copy\", \"paste\"\n        ];\n        events.forEach(function(name) {\n            text.addEventListener(name, addToLog, true);\n        });\n        function onMousedown(ev) {\n            if (ev.domEvent.target == text)\n                ev.$pos = editor.getCursorPosition();\n        }\n        text.detach = function() {\n            delete text.value;\n            delete text.setSelectionRange;\n            \n            events.forEach(function(name) {\n                text.removeEventListener(name, addToLog, true);\n            });\n            editor.off(\"mousedown\", onMousedown);\n        };\n        editor.on(\"mousedown\", onMousedown);\n        \n        text.__defineSetter__(\"value\", function(v) {\n            this.__proto__.__lookupSetter__(\"value\").call(this, v); \n            console.log(v);\n        });\n        text.__defineGetter__(\"value\", function(v) {\n            var v = this.__proto__.__lookupGetter__(\"value\").call(this); \n            return v;\n        });\n        text.setSelectionRange = function(start, end) {\n            ignoreEvents = true;\n            this.__proto__.setSelectionRange.call(this, start, end)\n            ignoreEvents = false;\n        }\n        exports.openConsole();\n        editor.focus();\n    },\n    getValue: function() {\n        return !!env.textarea;\n    }\n};\n\nexports.textPositionDebugger = {\n    position: 2000,\n    path: \"textPositionDebugger\",\n    onchange: function(value) {\n        document.body.classList[value ? \"add\" : \"remove\"](\"show-text-input\")\n    },\n    getValue: function() {\n        return document.body.classList.contains(\"show-text-input\");\n    }\n};\n\nexports.openConsole = function() {\n    var sp = env.split;\n    var logEditor = sp.$editors[1];\n    if (!logEditor) {\n        sp.setSplits(2);\n        sp.setOrientation(sp.BELOW);\n        logEditor = sp.$editors[1];\n    }\n    if (!exports.session)\n        exports.session = new EditSession(\"\");\n    logEditor.setSession(exports.session);\n    return logEditor\n};\nexports.log = function(str) {   \n    var logEditor = exports.openConsole();\n    logEditor.navigateFileEnd();\n    logEditor.insert(str + \",\\n\");\n    logEditor.renderer.scrollCursorIntoView();\n};\n\nexports.addGlobals();\n"
  },
  {
    "path": "demo/kitchen-sink/doclist.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\nvar net = require(\"ace/lib/net\");\n\nvar modelist = require(\"ace/ext/modelist\");\n/*********** demo documents ***************************/\nvar fileCache = {};\n\nfunction initDoc(file, path, doc) {\n    if (doc.prepare)\n        file = doc.prepare(file);\n\n    var session = new EditSession(file);\n    session.setUndoManager(new UndoManager());\n    doc.session = session;\n    doc.path = path;\n    session.name = doc.name;\n    if (doc.wrapped) {\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(80, 80);\n    }\n    var mode = modelist.getModeForPath(path);\n    session.modeName = mode.name;\n    session.setMode(mode.mode);\n    return session;\n}\n\n\nfunction makeHuge(txt) {\n    for (var i = 0; i < 5; i++)\n        txt += txt;\n    return txt;\n}\n\nvar docs = {\n    \"docs/javascript.js\": {order: 1, name: \"JavaScript\"},\n\n    \"docs/latex.tex\": {name: \"LaTeX\", wrapped: true},\n    \"docs/markdown.md\": {name: \"Markdown\", wrapped: true},\n    \"docs/mushcode.mc\": {name: \"MUSHCode\", wrapped: true},\n    \"docs/pgsql.pgsql\": {name: \"pgSQL\", wrapped: true},\n    \"docs/plaintext.txt\": {name: \"Plain Text\", prepare: makeHuge, wrapped: true},\n    \"docs/sql.sql\": {name: \"SQL\", wrapped: true},\n\n    \"docs/textile.textile\": {name: \"Textile\", wrapped: true},\n\n    \"docs/c9search.c9search_results\": \"C9 Search Results\",\n    \"docs/mel.mel\": \"MEL\",\n};\n\nvar ownSource = {\n    /* filled from require*/\n};\n\nvar hugeDocs = require.toUrl ? {\n    \"build/src/ace.js\": \"\",\n    \"build/src-min/ace.js\": \"\"\n} : {\n    \"src/ace.js\": \"\",\n    \"src-min/ace.js\": \"\"\n};\n\nmodelist.modes.forEach(function(m) {\n    var ext = m.extensions.split(\"|\")[0];\n    if (ext[0] === \"^\") {\n        path = ext.substr(1);\n    } else {\n        var path = m.name + \".\" + ext;\n    }\n    path = \"docs/\" + path;\n    if (!docs[path]) {\n        docs[path] = {name: m.caption};\n    } else if (typeof docs[path] == \"object\" && !docs[path].name) {\n        docs[path].name = m.caption;\n    }\n});\n\n\n\nif (window.define && window.define.modules) try {\n    for (var path in window.define.modules) {\n        if (path.indexOf(\"!\") != -1)\n            path = path.split(\"!\").pop();\n        else\n            path = path + \".js\";\n        ownSource[path] = \"\";\n    }\n} catch(e) {}\n\nfunction sort(list) {\n    return list.sort(function(a, b) {\n        var cmp = (b.order || 0) - (a.order || 0);\n        return cmp || a.name && a.name.localeCompare(b.name);\n    });\n}\n\nfunction prepareDocList(docs) {\n    var list = [];\n    for (var path in docs) {\n        var doc = docs[path];\n        if (typeof doc != \"object\")\n            doc = {name: doc || path};\n\n        doc.path = path;\n        doc.desc = doc.name.replace(/^(ace|docs|demo|build)\\//, \"\");\n        if (doc.desc.length > 18)\n            doc.desc = doc.desc.slice(0, 7) + \"..\" + doc.desc.slice(-9);\n\n        fileCache[doc.name.toLowerCase()] = doc;\n        list.push(doc);\n    }\n\n    return list;\n}\n\nfunction loadDoc(name, callback) {\n    var doc = fileCache[name.toLowerCase()];\n    if (!doc)\n        return callback(null);\n\n    if (doc.session)\n        return callback(doc.session);\n\n    // TODO: show load screen while waiting\n    var path = doc.path;\n    var parts = path.split(\"/\");\n    if (parts[0] == \"docs\")\n        path = \"demo/kitchen-sink/\" + path;\n    else if (parts[0] == \"ace\")\n        path = \"src/\" + parts.slice(1).join(\"/\");\n\n    net.get(path, function(x) {\n        initDoc(x, path, doc);\n        callback(doc.session);\n    });\n}\n\nfunction saveDoc(name, callback) {\n    var doc = name;\n    if (typeof(name) === 'string') {\n        doc = fileCache[name.toLowerCase()];\n    }\n    if (!doc || !doc.session)\n        return callback(\"Unknown document: \" + name);\n\n    var path = doc.path;\n    var parts = path.split(\"/\");\n    if (parts[0] == \"docs\")\n        path = \"demo/kitchen-sink/\" + path;\n    else if (parts[0] == \"ace\")\n        path = \"src/\" + parts.slice(1).join(\"/\");\n\n    upload(path, doc.session.getValue(), callback);\n}\n\nfunction upload(url, data, callback) {\n    var absUrl = net.qualifyURL(url);\n    if (/^file:/.test(absUrl))\n        absUrl = \"http://localhost:8888/\" + url;\n    url = absUrl;\n    if (!/^https?:/.test(url))\n        return callback(new Error(\"Unsupported url scheme\"));\n    var xhr = new XMLHttpRequest();\n    xhr.open(\"PUT\", url, true);\n    xhr.onreadystatechange = function () {\n        if (xhr.readyState === 4) {\n            callback(!/^2../.test(xhr.status));\n        }\n    };\n    xhr.send(data);\n}\n\nmodule.exports = {\n    fileCache: fileCache,\n    docs: sort(prepareDocList(docs)),\n    ownSource: prepareDocList(ownSource),\n    hugeDocs: prepareDocList(hugeDocs),\n    initDoc: initDoc,\n    loadDoc: loadDoc,\n    saveDoc: saveDoc\n};\nmodule.exports.all = {\n    \"Mode Examples\": module.exports.docs,\n    \"Huge documents\": module.exports.hugeDocs,\n    \"own source\": module.exports.ownSource\n};\n"
  },
  {
    "path": "demo/kitchen-sink/docs/Dockerfile",
    "content": "#\n# example Dockerfile for http://docs.docker.io/en/latest/examples/postgresql_service/\n#\n\nFROM ubuntu\nMAINTAINER SvenDowideit@docker.com\n\n# Add the PostgreSQL PGP key to verify their Debian packages.\n# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc \nRUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8\n\n# Add PostgreSQL's repository. It contains the most recent stable release\n#     of PostgreSQL, ``9.3``.\nRUN echo \"deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main\" > /etc/apt/sources.list.d/pgdg.list\n\n# Update the Ubuntu and PostgreSQL repository indexes\nRUN apt-get update\n\n# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3\n#  There are some warnings (in red) that show up during the build. You can hide\n#  them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive\nRUN apt-get -y -q install python-software-properties software-properties-common\nRUN apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3\n\n# Note: The official Debian and Ubuntu images automatically ``apt-get clean``\n# after each ``apt-get`` \n\n# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``\nUSER postgres\n\n# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and\n# then create a database `docker` owned by the ``docker`` role.\n# Note: here we use ``&&\\`` to run commands one after the other - the ``\\``\n#       allows the RUN command to span multiple lines.\nRUN    /etc/init.d/postgresql start &&\\\n    psql --command \"CREATE USER docker WITH SUPERUSER PASSWORD 'docker';\" &&\\\n    createdb -O docker docker\n\n# Adjust PostgreSQL configuration so that remote connections to the\n# database are possible. \nRUN echo \"host all  all    0.0.0.0/0  md5\" >> /etc/postgresql/9.3/main/pg_hba.conf\n\n# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``\nRUN echo \"listen_addresses='*'\" >> /etc/postgresql/9.3/main/postgresql.conf\n\n# Expose the PostgreSQL port\nEXPOSE 5432\n\n# Add VOLUMEs to allow backup of config, logs and databases\nVOLUME\t[\"/etc/postgresql\", \"/var/log/postgresql\", \"/var/lib/postgresql\"]\n\n# Set the default command to run when starting the container\nCMD [\"/usr/lib/postgresql/9.3/bin/postgres\", \"-D\", \"/var/lib/postgresql/9.3/main\", \"-c\", \"config_file=/etc/postgresql/9.3/main/postgresql.conf\"]"
  },
  {
    "path": "demo/kitchen-sink/docs/Makefile",
    "content": ".PHONY:    apf ext worker mode theme package test\n\ndefault: apf worker\n\nupdate: worker\n\n# packages apf\n\n# This is the first line of a comment \\\nand this is still part of the comment \\\nas is this, since I keep ending each line \\\nwith a backslash character\n\napf:\n    cd node_modules/packager; node package.js projects/apf_cloud9.apr\n\tcd node_modules/packager; cat build/apf_release.js | sed 's/\\(\\/\\*FILEHEAD(\\).*//g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_release.js\n\n# package debug version of apf\napfdebug:\n\tcd node_modules/packager/projects; cat apf_cloud9.apr | sed 's/<p:define name=\\\"__DEBUG\\\" value=\\\"0\\\" \\/>/<p:define name=\\\"__DEBUG\\\" value=\\\"1\\\" \\/>/g' > apf_cloud9_debug2.apr\n\tcd node_modules/packager/projects; cat apf_cloud9_debug2.apr | sed 's/apf_release/apf_debug/g' > apf_cloud9_debug.apr; rm apf_cloud9_debug2.apr\n\tcd node_modules/packager; node package.js projects/apf_cloud9_debug.apr\n\tcd node_modules/packager; cat build/apf_debug.js | sed 's/\\(\\/\\*FILEHEAD(\\).*\\/apf\\/\\(.*\\)/\\1\\2/g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_debug.js\n\n# package_apf--temporary fix for non-workering infra\npack_apf:\n\tmkdir -p build/src\n\tmv plugins-client/lib.apf/www/apf-packaged/apf_release.js build/src/apf_release.js\n\tnode build/r.js -o name=./build/src/apf_release.js out=./plugins-client/lib.apf/www/apf-packaged/apf_release.js baseUrl=.\n\n# makes ace; at the moment, requires dryice@0.4.2\nace:\n\tcd node_modules/ace; make clean pre_build; ./Makefile.dryice.js minimal\n\n\n# packages core\ncore: ace\n\tmkdir -p build/src\n\tnode build/r.js -o build/core.build.js\n\n# generates packed template\nhelper: \n\tnode build/packed_helper.js\n\nhelper_clean:\n\tmkdir -p build/src\n\tnode build/packed_helper.js 1\n\n# packages ext\next: \n\tnode build/r.js -o build/app.build.js\n\n# calls dryice on worker & packages it\nworker: plugins-client/lib.ace/www/worker/worker-language.js\n\nplugins-client/lib.ace/www/worker/worker-language.js plugins-client/lib.ace/www/worker/worker-javascript.js : \\\n        $(wildcard node_modules/ace/*) $(wildcard node_modules/ace/*/*) $(wildcard node_modules/ace/*/*/mode/*) \\\n        $(wildcard plugins-client/ext.language/*) \\\n        $(wildcard plugins-client/ext.language/*/*) \\\n        $(wildcard plugins-client/ext.linereport/*) \\\n        $(wildcard plugins-client/ext.codecomplete/*) \\\n        $(wildcard plugins-client/ext.codecomplete/*/*) \\\n        $(wildcard plugins-client/ext.jslanguage/*) \\\n        $(wildcard plugins-client/ext.jslanguage/*/*) \\\n        $(wildcard plugins-client/ext.csslanguage/*) \\\n        $(wildcard plugins-client/ext.csslanguage/*/*) \\\n        $(wildcard plugins-client/ext.htmllanguage/*) \\\n        $(wildcard plugins-client/ext.htmllanguage/*/*) \\\n        $(wildcard plugins-client/ext.jsinfer/*) \\\n        $(wildcard plugins-client/ext.jsinfer/*/*) \\\n        $(wildcard node_modules/treehugger/lib/*) \\\n        $(wildcard node_modules/treehugger/lib/*/*) \\\n        $(wildcard node_modules/ace/lib/*) \\\n        $(wildcard node_modules/ace/*/*) \\\n        Makefile.dryice.js\n\tmkdir -p plugins-client/lib.ace/www/worker\n\trm -rf /tmp/c9_worker_build\n\tmkdir -p /tmp/c9_worker_build/ext\n\tln -s `pwd`/plugins-client/ext.language /tmp/c9_worker_build/ext/language\n\tln -s `pwd`/plugins-client/ext.codecomplete /tmp/c9_worker_build/ext/codecomplete\n\tln -s `pwd`/plugins-client/ext.jslanguage /tmp/c9_worker_build/ext/jslanguage\n\tln -s `pwd`/plugins-client/ext.csslanguage /tmp/c9_worker_build/ext/csslanguage\n\tln -s `pwd`/plugins-client/ext.htmllanguage /tmp/c9_worker_build/ext/htmllanguage\n\tln -s `pwd`/plugins-client/ext.linereport /tmp/c9_worker_build/ext/linereport\n\tln -s `pwd`/plugins-client/ext.linereport_php /tmp/c9_worker_build/ext/linereport_php\n\tnode Makefile.dryice.js worker\n\tcp node_modules/ace/build/src/worker* plugins-client/lib.ace/www/worker\n\ndefine \n\nifeq\n\noverride\n\n# copies built ace modes\nmode:\n\tmkdir -p plugins-client/lib.ace/www/mode\n\tcp `find node_modules/ace/build/src | grep -E \"mode-[a-zA-Z_0-9]+.js\"`  plugins-client/lib.ace/www/mode\n\n# copies built ace themes\ntheme:\n\tmkdir -p plugins-client/lib.ace/www/theme\n\tcp `find node_modules/ace/build/src | grep -E \"theme-[a-zA-Z_0-9]+.js\"` plugins-client/lib.ace/www/theme\n\ngzip_safe:\n\tfor i in `ls ./plugins-client/lib.packed/www/*.js`; do \\\n\t\tgzip -9 -v -c -q -f $$i > $$i.gz ; \\\n\tdone\n\ngzip:\n\tfor i in `ls ./plugins-client/lib.packed/www/*.js`; do \\\n\t\tgzip -9 -v -q -f $$i ; \\\n\tdone\n\nc9core: apf ace core worker mode theme\n    \npackage_clean: helper_clean c9core ext\n\npackage: helper c9core ext\n\ntest check:\n\ttest/run-tests.sh\t"
  },
  {
    "path": "demo/kitchen-sink/docs/abap.abap",
    "content": "***************************************\n** Program: EXAMPLE                  **\n** Author: Joe Byte, 07-Jul-2007     **\n***************************************\n \nREPORT BOOKINGS.\n \n* Read flight bookings from the database\nSELECT * FROM FLIGHTINFO\n  WHERE CLASS = 'Y'       \"Y = economy\n  OR    CLASS = 'C'.      \"C = business\n(...)\n\nREPORT TEST.\nWRITE 'Hello World'.\n\nUSERPROMPT = 'Please double-click on a line in the output list ' &\n             'to see the complete details of the transaction.'.\n\n\nDATA LAST_EOM    TYPE D.  \"last end-of-month date\n \n* Start from today's date\n  LAST_EOM = SY-DATUM.\n* Set characters 6 and 7 (0-relative) of the YYYYMMDD string to \"01\",\n* giving the first day of the current month\n  LAST_EOM+6(2) = '01'.\n* Subtract one day\n  LAST_EOM = LAST_EOM - 1.\n \n  WRITE: 'Last day of previous month was', LAST_EOM.\n  \nDATA : BEGIN OF I_VBRK OCCURS 0,\n         VBELN LIKE VBRK-VBELN,\n         ZUONR LIKE VBRK-ZUONR,\n       END OF I_VBRK.\n\nSORT i_vbrk BY vbeln ASCENDING.\nSORT i_vbrk BY vbeln DESCENDING.\n\nRETURN."
  },
  {
    "path": "demo/kitchen-sink/docs/abc.abc",
    "content": "%abc-2.1\nH:This file contains some example English tunes\n% note that the comments (like this one) are to highlight usages\n%  and would not normally be included in such detail\nO:England             % the origin of all tunes is England\n\nX:1                   % tune no 1\nT:Dusty Miller, The   % title\nT:Binny's Jig         % an alternative title\nC:Trad.               % traditional\nR:DH                  % double hornpipe\nM:3/4                 % meter\nK:G                   % key\nB>cd BAG|FA Ac BA|B>cd BAG|DG GB AG:|\nBdd gfg|aA Ac BA|Bdd gfa|gG GB AG:|\nBG G/2G/2G BG|FA Ac BA|BG G/2G/2G BG|DG GB AG:|\nW:Hey, the dusty miller, and his dusty coat;\nW:He will win a shilling, or he spend a groat.\nW:Dusty was the coat, dusty was the colour;\nW:Dusty was the kiss, that I got frae the miller.\n\nX:2\nT:Old Sir Simon the King\nC:Trad.\nS:Offord MSS          % from Offord manuscript\nN:see also Playford   % reference note\nM:9/8\nR:SJ                  % slip jig\nN:originally in C     % transcription note\nK:G\nD|GFG GAG G2D|GFG GAG F2D|EFE EFE EFG|A2G F2E D2:|\nD|GAG GAB d2D|GAG GAB c2D|[1 EFE EFE EFG|[A2G] F2E D2:|\\ % no line-break in score\nM:12/8                % change of meter\n[2 E2E EFE E2E EFG|\\  % no line-break in score\nM:9/8                 % change of meter\nA2G F2E D2|]\n\nX:3\nT:William and Nancy\nT:New Mown Hay\nT:Legacy, The\nC:Trad.\nO:England; Gloucs; Bledington % place of origin\nB:Sussex Tune Book            % can be found in these books\nB:Mally's Cotswold Morris vol.1 2\nD:Morris On                   % can be heard on this record\nP:(AB)2(AC)2A                 % play the parts in this order\nM:6/8\nK:G                        \n[P:A] D|\"G\"G2G GBd|\"C\"e2e \"G\"dBG|\"D7\"A2d \"G\"BAG|\"C\"E2\"D7\"F \"G\"G2:|\n[P:B] d|\"G\"e2d B2d|\"C\"gfe \"G\"d2d| \"G\"e2d    B2d|\"C\"gfe    \"D7\"d2c|\n        \"G\"B2B Bcd|\"C\"e2e \"G\"dBG|\"D7\"A2d \"G\"BAG|\"C\"E2\"D7\"F \"G\"G2:|\n% changes of meter, using inline fields\n[T:Slows][M:4/4][L:1/4][P:C]\"G\"d2|\"C\"e2 \"G\"d2|B2 d2|\"Em\"gf \"A7\"e2|\"D7\"d2 \"G\"d2|\\\n       \"C\"e2 \"G\"d2|[M:3/8][L:1/8] \"G\"B2 d |[M:6/8] \"C\"gfe \"D7\"d2c|\n        \"G\"B2B Bcd|\"C\"e2e \"G\"dBG|\"D7\"A2d \"G\"BAG|\"C\"E2\"D7\"F \"G\"G2:|\n\nX:4\nT:South Downs Jig\nR:jig\nS:Robert Harbron\nM:6/8\nL:1/8\nK:G\n|: d | dcA G3 | EFG AFE | DEF GAB | cde d2d |\ndcA G3 | EFG AFE | DEF GAB | cAF G2 :|\nB | Bcd e2c | d2B c2A | Bcd e2c | [M:9/8]d2B c2B A3 |\n[M:6/8]DGF E3 | cBA FED | DEF GAB |1 cAF G2 :|2 cAF G3 |]\n\nX:5\nT:Atholl Brose\n% in this example, which reproduces Highland Bagpipe gracing,\n%  the large number of grace notes mean that it is more convenient to be specific about\n%  score line-breaks (using the $ symbol), rather than using code line breaks to indicate them\nI:linebreak $\nK:D\n{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|\n{gcd}c<{e}A {gAGAG}A>e {ag}a>f {gef}e>d|\n{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|\n{g}c/d/e {g}G>{d}B {gf}gG {dc}d>B:|$\n{g}c<e {gf}g>e {ag}a>e {gf}g>e|\n{g}c<e {gf}g>e {ag}a2 {GdG}a>d|\n{g}c<e {gf}g>e {ag}a>e {gf}g>f|\n{gef}e>d {gf}g>d {gBd}B<{e}G {dc}d>B|\n{g}c<e {gf}g>e {ag}a>e {gf}g>e|\n{g}c<e {gf}g>e {ag}a2 {GdG}ad|\n{g}c<{GdG}e {gf}ga {f}g>e {g}f>d|\n{g}e/f/g {Gdc}d>c {gBd}B<{e}G {dc}d2|]\n\nX:6\nT:Untitled Reel\nC:Trad.\nK:D\neg|a2ab ageg|agbg agef|g2g2 fgag|f2d2 d2:|\\\ned|cecA B2ed|cAcA E2ed|cecA B2ed|c2A2 A2:|\nK:G\nAB|cdec BcdB|ABAF GFE2|cdec BcdB|c2A2 A2:|\n\nX:7\nT:Kitchen Girl\nC:Trad.\nK:D\n[c4a4] [B4g4]|efed c2cd|e2f2 gaba|g2e2 e2fg|\na4 g4|efed cdef|g2d2 efed|c2A2 A4:|\nK:G\nABcA BAGB|ABAG EDEG|A2AB c2d2|e3f edcB|ABcA BAGB|\nABAG EGAB|cBAc BAG2|A4 A4:|\n\n%abc-2.1\n%%pagewidth      21cm\n%%pageheight     29.7cm\n%%topspace       0.5cm\n%%topmargin      1cm\n%%botmargin      0cm\n%%leftmargin     1cm\n%%rightmargin    1cm\n%%titlespace     0cm\n%%titlefont      Times-Bold 32\n%%subtitlefont   Times-Bold 24\n%%composerfont   Times 16\n%%vocalfont      Times-Roman 14\n%%staffsep       60pt\n%%sysstaffsep    20pt\n%%musicspace     1cm\n%%vocalspace     5pt\n%%measurenb      0\n%%barsperstaff   5\n%%scale          0.7\nX: 1\nT: Canzonetta a tre voci\nC: Claudio Monteverdi (1567-1643)\nM: C\nL: 1/4\nQ: \"Andante mosso\" 1/4 = 110\n%%score [1 2 3]\nV: 1 clef=treble name=\"Soprano\"sname=\"A\"\nV: 2 clef=treble name=\"Alto\"   sname=\"T\"\nV: 3 clef=bass middle=d name=\"Tenor\"  sname=\"B\"\n%%MIDI program 1 75 % recorder\n%%MIDI program 2 75\n%%MIDI program 3 75\nK: Eb\n% 1 - 4\n[V: 1] |:z4  |z4  |f2ec         |_ddcc        |\nw: Son que-sti~i cre-spi cri-ni~e\nw: Que-sti son gli~oc-chi che mi-\n[V: 2] |:c2BG|AAGc|(F/G/A/B/)c=A|B2AA         |\nw: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e\nw: Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-\n[V: 3] |:z4  |f2ec|_ddcf        |(B/c/_d/e/)ff|\nw: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il\nw: Que-sti son~gli oc-chi che mi-ran - - - - do\n% 5 - 9\n[V: 1] cAB2     |cAAA |c3B|G2!fermata!Gz ::e4|\nw: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,\nw: ran-do fi-so, tut-to re-stai con-qui-so.\n[V: 2] AAG2     |AFFF |A3F|=E2!fermata!Ez::c4|\nw: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,\nw: ran-do fi-so tut-to re-stai con-qui-so.\n[V: 3] (ag/f/e2)|A_ddd|A3B|c2!fermata!cz ::A4|\nw: vi - - - so ond' io ti-man-go~uc-ci-so. Deh,\nw: fi - - - so tut-to re-stai con-qui-so.\n% 10 - 15\n[V: 1] f_dec |B2c2|zAGF  |\\\nw: dim-me-lo ben mi-o, che que-sto\\\n=EFG2          |1F2z2:|2F8|] % more notes\nw: sol de-si-o_. % more lyrics\n[V: 2] ABGA  |G2AA|GF=EF |(GF3/2=E//D//E)|1F2z2:|2F8|]\nw: dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_.\n[V: 3] _dBc>d|e2AF|=EFc_d|c4             |1F2z2:|2F8|]\nw: dim-me-lo ben mi-o, che que-sto sol de-si-o_."
  },
  {
    "path": "demo/kitchen-sink/docs/actionscript.as",
    "content": "package code\n{\n    /*****************************************\n\t * based on textmate actionscript bundle\n\t ****************************************/\n\t \n\timport fl.events.SliderEvent;\n\t\n\tpublic class Foo extends MovieClip\n\t{\n\t\t//*************************\n\t\t// Properties:\n\t\t\n\t\tpublic var activeSwatch:MovieClip;\n\t\t\n\t\t// Color offsets\n\t\tpublic var c1:Number = 0;\t// R\n\t\t\n\t\t//*************************\n\t\t// Constructor:\n\t\t\n\t\tpublic function Foo()\n\t\t{\n\t\t\t// Respond to mouse events\n\t\t\tswatch1_btn.addEventListener(MouseEvent.CLICK,swatchHandler,false,0,false);\n\t\t\tpreviewBox_btn.addEventListener(MouseEvent.MOUSE_DOWN,dragPressHandler);\n\t\t\t\n\t\t\t// Respond to drag events\n\t\t\tred_slider.addEventListener(SliderEvent.THUMB_DRAG,sliderHandler);\n\t\t\t\n\t\t\t// Draw a frame later\n\t\t\taddEventListener(Event.ENTER_FRAME,draw);\n\t\t}\n        \n\t\tprotected function clickHandler(event:MouseEvent):void\n\t\t{\n\t\t\tcar.transform.colorTransform = new ColorTransform(0,0,0,1,c1,c2,c3);\n\t\t}\n\t\t\n\t\tprotected function changeRGBHandler(event:Event):void\n\t\t{\n\t\t\tc1 = Number(c1_txt.text);\n            \n\t\t\tif(!(c1>=0)){\n\t\t\t\tc1 = 0;\n\t\t\t}\t\t\t\n\t\t\t\n\t\t\tupdateSliders();\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/ada.ada",
    "content": "with Ada.Text_IO; use Ada.Text_IO;\nprocedure Hello is\nbegin\n  Put_Line(\"Hello, world!\");\nend Hello;"
  },
  {
    "path": "demo/kitchen-sink/docs/alda.alda",
    "content": "# Example taken from https://github.com/alda-lang/alda-core/blob/master/examples/across_the_sea.alda\n(tempo! 90)\n(quant! 95)\n\npiano:\n  o5 g- > g- g-/f > e- d-4. < b-8 d-2 | c-4 e- d- d- <b-1/>g-\n\nflute:\n  r2 g-4 a- b-2. > d-32~ e-16.~8 < b-2 a- g-1"
  },
  {
    "path": "demo/kitchen-sink/docs/apex.apex",
    "content": "public class testBlockDuplicatesLeadTrigger {\n\t\n\tstatic testMethod void testDuplicateTrigger(){  \n\t\n\t\tLead[] l1 =new Lead[]{\n\t\t\tnew Lead(  Email='homer@fox.tv', LastName='Simpson', Company='fox' )\n\t\t};\n\t\tinsert l1;\t\t// add a known lead\n\t\t\n\t\tLead[] l2 =new Lead[]{\n\t\t\tnew Lead(  Email='homer@fox.tv', LastName='Simpson', Company='fox' )\n\t\t};\n\t\t// try to add a matching lead\n\t\ttry {\tinsert l2;\t} catch ( System.DmlException e) { \n\t\t\tsystem.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),\n\t\t\t e.getMessage());\n\t\t}\n\t\t\n\t\t// test duplicates in the same batch\n\t\tLead[] l3 =new Lead[]{\n\t\t\tnew Lead(  Email='marge@fox.tv', LastName='Simpson', Company='fox' ),\n\t\t\tnew Lead(  Email='marge@fox.tv', LastName='Simpson', Company='fox' )\n\t\t};\t\t\n\t\ttry { insert l3;\t} catch ( System.DmlException e) { \n\t\t\tsystem.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Another new lead has the same email'),\n\t\t\t\te.getMessage());\n\t\t\t\n\t\t}\n\t\t\n\t\t// test update also\n\t\tLead[] lup = new Lead[]{\n\t\t\tnew Lead(  Email='marge@fox.tv',  LastName='Simpson', Company='fox' )\n\t\t};\n\t\tinsert lup;\n\t\tLead marge = [ select id,Email from lead where Email = 'marge@fox.tv' limit 1];\n\t\tsystem.assert(marge!=null);\n\t\tmarge.Email = 'homer@fox.tv'; \n\t\t\n\t\ttry { update marge; } catch ( System.DmlException e) { \n\t\t\tsystem.assert(e.getMessage().contains('irst error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),\n\t\t\t\te.getMessage());\t\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/aql.aql",
    "content": "FOR user IN users\n  FILTER user.username == \"olivier\"\n  RETURN user"
  },
  {
    "path": "demo/kitchen-sink/docs/asciidoc.asciidoc",
    "content": "AsciiDoc User Guide\n===================\nStuart Rackham <srackham@gmail.com>\n:Author Initials: SJR\n:toc:\n:icons:\n:numbered:\n:website: http://www.methods.co.nz/asciidoc/\n\nAsciiDoc is a text document format for writing notes, documentation,\narticles, books, ebooks, slideshows, web pages, blogs and UNIX man\npages.  AsciiDoc files can be translated to many formats including\nHTML, PDF, EPUB, man page.  AsciiDoc is highly configurable: both the\nAsciiDoc source file syntax and the backend output markups (which can\nbe almost any type of SGML/XML markup) can be customized and extended\nby the user.\n\n.This document\n**********************************************************************\nThis is an overly large document, it probably needs to be refactored\ninto a Tutorial, Quick Reference and Formal Reference.\n\nIf you're new to AsciiDoc read this section and the <<X6,Getting\nStarted>> section and take a look at the example AsciiDoc (`*.txt`)\nsource files in the distribution `doc` directory.\n**********************************************************************\n\n\nIntroduction\n------------\nAsciiDoc is a plain text human readable/writable document format that\ncan be translated to DocBook or HTML using the asciidoc(1) command.\nYou can then either use asciidoc(1) generated HTML directly or run\nasciidoc(1) DocBook output through your favorite DocBook toolchain or\nuse the AsciiDoc a2x(1) toolchain wrapper to produce PDF, EPUB, DVI,\nLaTeX, PostScript, man page, HTML and text formats.\n\nThe AsciiDoc format is a useful presentation format in its own right:\nAsciiDoc markup is simple, intuitive and as such is easily proofed and\nedited.\n\nAsciiDoc is light weight: it consists of a single Python script and a\nbunch of configuration files. Apart from asciidoc(1) and a Python\ninterpreter, no other programs are required to convert AsciiDoc text\nfiles to DocBook or HTML. See <<X11,Example AsciiDoc Documents>>\nbelow.\n\nText markup conventions tend to be a matter of (often strong) personal\npreference: if the default syntax is not to your liking you can define\nyour own by editing the text based asciidoc(1) configuration files.\nYou can also create configuration files to translate AsciiDoc\ndocuments to almost any SGML/XML markup.\n\nasciidoc(1) comes with a set of configuration files to translate\nAsciiDoc articles, books and man pages to HTML or DocBook backend\nformats.\n\n.My AsciiDoc Itch\n**********************************************************************\nDocBook has emerged as the de facto standard Open Source documentation\nformat. But DocBook is a complex language, the markup is difficult to\nread and even more difficult to write directly -- I found I was\nspending more time typing markup tags, consulting reference manuals\nand fixing syntax errors, than I was writing the documentation.\n**********************************************************************\n\n\n[[X6]]\nGetting Started\n---------------\nInstalling AsciiDoc\n~~~~~~~~~~~~~~~~~~~\nSee the `README` and `INSTALL` files for install prerequisites and\nprocedures. Packagers take a look at <<X38,Packager Notes>>.\n\n[[X11]]\nExample AsciiDoc Documents\n~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe best way to quickly get a feel for AsciiDoc is to view the\nAsciiDoc web site and/or distributed examples:\n\n- Take a look at the linked examples on the AsciiDoc web site home\n  page {website}.  Press the 'Page Source' sidebar menu item to view\n  corresponding AsciiDoc source.\n- Read the `*.txt` source files in the distribution `./doc` directory\n  along with the corresponding HTML and DocBook XML files.\n\n\nAsciiDoc Document Types\n-----------------------\nThere are three types of AsciiDoc documents: article, book and\nmanpage. All document types share the same AsciiDoc format with some\nminor variations. If you are familiar with DocBook you will have\nnoticed that AsciiDoc document types correspond to the same-named\nDocBook document types.\n\nUse the asciidoc(1) `-d` (`--doctype`) option to specify the AsciiDoc\ndocument type -- the default document type is 'article'.\n\nBy convention the `.txt` file extension is used for AsciiDoc document\nsource files.\n\narticle\n~~~~~~~\nUsed for short documents, articles and general documentation.  See the\nAsciiDoc distribution `./doc/article.txt` example.\n\nAsciiDoc defines standard DocBook article frontmatter and backmatter\n<<X93,section markup templates>> (appendix, abstract, bibliography,\nglossary, index).\n\nbook\n~~~~\nBooks share the same format as articles, with the following\ndifferences:\n\n- The part titles in multi-part books are <<X17,top level titles>>\n  (same level as book title).\n- Some sections are book specific e.g. preface and colophon.\n\nBook documents will normally be used to produce DocBook output since\nDocBook processors can automatically generate footnotes, table of\ncontents, list of tables, list of figures, list of examples and\nindexes.\n\nAsciiDoc defines standard DocBook book frontmatter and backmatter\n<<X93,section markup templates>> (appendix, dedication, preface,\nbibliography, glossary, index, colophon).\n\n.Example book documents\nBook::\n  The `./doc/book.txt` file in the AsciiDoc distribution.\n\nMulti-part book::\n  The `./doc/book-multi.txt` file in the AsciiDoc distribution.\n\nmanpage\n~~~~~~~\nUsed to generate roff format UNIX manual pages.  AsciiDoc manpage\ndocuments observe special header title and section naming conventions\n-- see the <<X1,Manpage Documents>> section for details.\n\nAsciiDoc defines the 'synopsis' <<X93,section markup template>> to\ngenerate the DocBook `refsynopsisdiv` section.\n\nSee also the asciidoc(1) man page source (`./doc/asciidoc.1.txt`) from\nthe AsciiDoc distribution.\n\n\n[[X5]]\nAsciiDoc Backends\n-----------------\nThe asciidoc(1) command translates an AsciiDoc formatted file to the\nbackend format specified by the `-b` (`--backend`) command-line\noption. asciidoc(1) itself has little intrinsic knowledge of backend\nformats, all translation rules are contained in customizable cascading\nconfiguration files. Backend specific attributes are listed in the\n<<X88,Backend Attributes>> section.\n\ndocbook45::\n  Outputs DocBook XML 4.5 markup.\n\nhtml4::\n  This backend generates plain HTML 4.01 Transitional markup.\n\nxhtml11::\n  This backend generates XHTML 1.1 markup styled with CSS2. Output\n  files have an `.html` extension.\n\nhtml5::\n  This backend generates HTML 5 markup, apart from the inclusion of\n  <<X98,audio and video block macros>> it is functionally identical to\n  the 'xhtml11' backend.\n\nslidy::\n  Use this backend to generate self-contained\n  http://www.w3.org/Talks/Tools/Slidy2/[Slidy] HTML slideshows for\n  your web browser from AsciiDoc documents. The Slidy backend is\n  documented in the distribution `doc/slidy.txt` file and\n  {website}slidy.html[online].\n\nwordpress::\n  A minor variant of the 'html4' backend to support\n  http://srackham.wordpress.com/blogpost1/[blogpost].\n\nlatex::\n  Experimental LaTeX backend.\n\nBackend Aliases\n~~~~~~~~~~~~~~~\nBackend aliases are alternative names for AsciiDoc backends.  AsciiDoc\ncomes with two backend aliases: 'html' (aliased to 'xhtml11') and\n'docbook' (aliased to 'docbook45').\n\nYou can assign (or reassign) backend aliases by setting an AsciiDoc\nattribute named like `backend-alias-<alias>` to an AsciiDoc backend\nname. For example, the following backend alias attribute definitions\nappear in the `[attributes]` section of the global `asciidoc.conf`\nconfiguration file:\n\n  backend-alias-html=xhtml11\n  backend-alias-docbook=docbook45\n\n[[X100]]\nBackend Plugins\n~~~~~~~~~~~~~~~\nThe asciidoc(1) `--backend` option is also used to install and manage\nbackend <<X101,plugins>>.\n\n- A backend plugin is used just like the built-in backends.\n- Backend plugins <<X27,take precedence>> over built-in backends with\n  the same name.\n- You can use the `{asciidoc-confdir}` <<X60, intrinsic attribute>> to\n  refer to the built-in backend configuration file location from\n  backend plugin configuration files.\n- You can use the `{backend-confdir}` <<X60, intrinsic attribute>> to\n  refer to the backend plugin configuration file location.\n- By default backends plugins are installed in\n  `$HOME/.asciidoc/backends/<backend>` where `<backend>` is the\n  backend name.\n\n\nDocBook\n-------\nAsciiDoc generates 'article', 'book' and 'refentry'\nhttp://www.docbook.org/[DocBook] documents (corresponding to the\nAsciiDoc 'article', 'book' and 'manpage' document types).\n\nMost Linux distributions come with conversion tools (collectively\ncalled a toolchain) for <<X12,converting DocBook files>> to\npresentation formats such as Postscript, HTML, PDF, EPUB, DVI,\nPostScript, LaTeX, roff (the native man page format), HTMLHelp,\nJavaHelp and text.  There are also programs that allow you to view\nDocBook files directly, for example http://live.gnome.org/Yelp[Yelp]\n(the GNOME help viewer).\n\n[[X12]]\nConverting DocBook to other file formats\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nDocBook files are validated, parsed and translated various\npresentation file formats using a combination of applications\ncollectively called a DocBook 'tool chain'. The function of a tool\nchain is to read the DocBook markup (produced by AsciiDoc) and\ntransform it to a presentation format (for example HTML, PDF, HTML\nHelp, EPUB, DVI, PostScript, LaTeX).\n\nA wide range of user output format requirements coupled with a choice\nof available tools and stylesheets results in many valid tool chain\ncombinations.\n\n[[X43]]\na2x Toolchain Wrapper\n~~~~~~~~~~~~~~~~~~~~~\nOne of the biggest hurdles for new users is installing, configuring\nand using a DocBook XML toolchain. `a2x(1)` can help -- it's a\ntoolchain wrapper command that will generate XHTML (chunked and\nunchunked), PDF, EPUB, DVI, PS, LaTeX, man page, HTML Help and text\nfile outputs from an AsciiDoc text file.  `a2x(1)` does all the grunt\nwork associated with generating and sequencing the toolchain commands\nand managing intermediate and output files.  `a2x(1)` also optionally\ndeploys admonition and navigation icons and a CSS stylesheet. See the\n`a2x(1)` man page for more details. In addition to `asciidoc(1)` you\nalso need <<X40,xsltproc(1)>>, <<X13,DocBook XSL Stylesheets>> and\noptionally: <<X31,dblatex>> or <<X14,FOP>> (to generate PDF);\n`w3m(1)` or `lynx(1)` (to generate text).\n\nThe following examples generate `doc/source-highlight-filter.pdf` from\nthe AsciiDoc `doc/source-highlight-filter.txt` source file. The first\nexample uses `dblatex(1)` (the default PDF generator) the second\nexample forces FOP to be used:\n\n  $ a2x -f pdf doc/source-highlight-filter.txt\n  $ a2x -f pdf --fop doc/source-highlight-filter.txt\n\nSee the `a2x(1)` man page for details.\n\nTIP: Use the `--verbose` command-line option to view executed\ntoolchain commands.\n\nHTML generation\n~~~~~~~~~~~~~~~\nAsciiDoc produces nicely styled HTML directly without requiring a\nDocBook toolchain but there are also advantages in going the DocBook\nroute:\n\n- HTML from DocBook can optionally include automatically generated\n  indexes, tables of contents, footnotes, lists of figures and tables.\n- DocBook toolchains can also (optionally) generate separate (chunked)\n  linked HTML pages for each document section.\n- Toolchain processing performs link and document validity checks.\n- If the DocBook 'lang' attribute is set then things like table of\n  contents, figure and table captions and admonition captions will be\n  output in the specified language (setting the AsciiDoc 'lang'\n  attribute sets the DocBook 'lang' attribute).\n\nOn the other hand, HTML output directly from AsciiDoc is much faster,\nis easily customized and can be used in situations where there is no\nsuitable DocBook toolchain (for example, see the {website}[AsciiDoc\nwebsite]).\n\nPDF generation\n~~~~~~~~~~~~~~\nThere are two commonly used tools to generate PDFs from DocBook,\n<<X31,dblatex>> and <<X14,FOP>>.\n\n.dblatex or FOP?\n- 'dblatex' is easier to install, there's zero configuration\n  required and no Java VM to install -- it just works out of the box.\n- 'dblatex' source code highlighting and numbering is superb.\n- 'dblatex' is easier to use as it converts DocBook directly to PDF\n  whereas before using 'FOP' you have to convert DocBook to XML-FO\n  using <<X13,DocBook XSL Stylesheets>>.\n- 'FOP' is more feature complete (for example, callouts are processed\n  inside literal layouts) and arguably produces nicer looking output.\n\nHTML Help generation\n~~~~~~~~~~~~~~~~~~~~\n. Convert DocBook XML documents to HTML Help compiler source files\n  using <<X13,DocBook XSL Stylesheets>> and <<X40,xsltproc(1)>>.\n. Convert the HTML Help source (`.hhp` and `.html`) files to HTML Help\n  (`.chm`) files using the <<X67,Microsoft HTML Help Compiler>>.\n\nToolchain components summary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAsciiDoc::\n    Converts AsciiDoc (`.txt`) files to DocBook XML (`.xml`) files.\n\n[[X13]]http://docbook.sourceforge.net/projects/xsl/[DocBook XSL Stylesheets]::\n  These are a set of XSL stylesheets containing rules for converting\n  DocBook XML documents to HTML, XSL-FO, manpage and HTML Help files.\n  The stylesheets are used in conjunction with an XML parser such as\n  <<X40,xsltproc(1)>>.\n\n[[X40]]http://www.xmlsoft.org[xsltproc]::\n  An XML parser for applying XSLT stylesheets (in our case the\n  <<X13,DocBook XSL Stylesheets>>) to XML documents.\n\n[[X31]]http://dblatex.sourceforge.net/[dblatex]::\n  Generates PDF, DVI, PostScript and LaTeX formats directly from\n  DocBook source via the intermediate LaTeX typesetting language --\n  uses <<X13,DocBook XSL Stylesheets>>, <<X40,xsltproc(1)>> and\n  `latex(1)`.\n\n[[X14]]http://xml.apache.org/fop/[FOP]::\n  The Apache Formatting Objects Processor converts XSL-FO (`.fo`)\n  files to PDF files.  The XSL-FO files are generated from DocBook\n  source files using <<X13,DocBook XSL Stylesheets>> and\n  <<X40,xsltproc(1)>>.\n\n[[X67]]Microsoft Help Compiler::\n  The Microsoft HTML Help Compiler (`hhc.exe`) is a command-line tool\n  that converts HTML Help source files to a single HTML Help (`.chm`)\n  file. It runs on MS Windows platforms and can be downloaded from\n  http://www.microsoft.com.\n\nAsciiDoc dblatex configuration files\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe AsciiDoc distribution `./dblatex` directory contains\n`asciidoc-dblatex.xsl` (customized XSL parameter settings) and\n`asciidoc-dblatex.sty` (customized LaTeX settings). These are examples\nof optional <<X31,dblatex>> output customization and are used by\n<<X43,a2x(1)>>.\n\nAsciiDoc DocBook XSL Stylesheets drivers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou will have noticed that the distributed HTML and HTML Help\ndocumentation files (for example `./doc/asciidoc.html`) are not the\nplain outputs produced using the default 'DocBook XSL Stylesheets'\nconfiguration.  This is because they have been processed using\ncustomized DocBook XSL Stylesheets along with (in the case of HTML\noutputs) the custom `./stylesheets/docbook-xsl.css` CSS stylesheet.\n\nYou'll find the customized DocBook XSL drivers along with additional\ndocumentation in the distribution `./docbook-xsl` directory. The\nexamples that follow are executed from the distribution documentation\n(`./doc`) directory. These drivers are also used by <<X43,a2x(1)>>.\n\n`common.xsl`::\n    Shared driver parameters.  This file is not used directly but is\n    included in all the following drivers.\n\n`chunked.xsl`::\n    Generate chunked XHTML (separate HTML pages for each document\n    section) in the `./doc/chunked` directory. For example:\n\n    $ python ../asciidoc.py -b docbook asciidoc.txt\n    $ xsltproc --nonet ../docbook-xsl/chunked.xsl asciidoc.xml\n\n`epub.xsl`::\n    Used by <<X43,a2x(1)>> to generate EPUB formatted documents.\n\n`fo.xsl`::\n    Generate XSL Formatting Object (`.fo`) files for subsequent PDF\n    file generation using FOP. For example:\n\n    $ python ../asciidoc.py -b docbook article.txt\n    $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo\n    $ fop article.fo article.pdf\n\n`htmlhelp.xsl`::\n    Generate Microsoft HTML Help source files for the MS HTML Help\n    Compiler in the `./doc/htmlhelp` directory. This example is run on\n    MS Windows from a Cygwin shell prompt:\n\n    $ python ../asciidoc.py -b docbook asciidoc.txt\n    $ xsltproc --nonet ../docbook-xsl/htmlhelp.xsl asciidoc.xml\n    $ c:/Program\\ Files/HTML\\ Help\\ Workshop/hhc.exe htmlhelp.hhp\n\n`manpage.xsl`::\n    Generate a `roff(1)` format UNIX man page from a DocBook XML\n    'refentry' document. This example generates an `asciidoc.1` man\n    page file:\n\n    $ python ../asciidoc.py -d manpage -b docbook asciidoc.1.txt\n    $ xsltproc --nonet ../docbook-xsl/manpage.xsl asciidoc.1.xml\n\n`xhtml.xsl`::\n    Convert a DocBook XML file to a single XHTML file. For example:\n\n    $ python ../asciidoc.py -b docbook asciidoc.txt\n    $ xsltproc --nonet ../docbook-xsl/xhtml.xsl asciidoc.xml > asciidoc.html\n\nIf you want to see how the complete documentation set is processed\ntake a look at the A-A-P script `./doc/main.aap`.\n\n\nGenerating Plain Text Files\n---------------------------\nAsciiDoc does not have a text backend (for most purposes AsciiDoc\nsource text is fine), however you can convert AsciiDoc text files to\nformatted text using the AsciiDoc <<X43,a2x(1)>> toolchain wrapper\nutility.\n\n\n[[X35]]\nHTML5 and XHTML 1.1\n-------------------\nThe 'xhtml11' and 'html5' backends embed or link CSS and JavaScript\nfiles in their outputs, there is also a <<X99,themes>> plugin\nframework.\n\n- If the AsciiDoc 'linkcss' attribute is defined then CSS and\n  JavaScript files are linked to the output document, otherwise they\n  are embedded (the default behavior).\n- The default locations for CSS and JavaScript files can be changed by\n  setting the AsciiDoc 'stylesdir' and 'scriptsdir' attributes\n  respectively.\n- The default locations for embedded and linked files differ and are\n  calculated at different times -- embedded files are loaded when\n  asciidoc(1) generates the output document, linked files are loaded\n  by the browser when the user views the output document.\n- Embedded files are automatically inserted in the output files but\n  you need to manually copy linked CSS and Javascript files from\n  AsciiDoc <<X27,configuration directories>> to the correct location\n  relative to the output document.\n\n.Stylesheet file locations\n[cols=\"3*\",frame=\"topbot\",options=\"header\"]\n|====================================================================\n|'stylesdir' attribute\n|Linked location ('linkcss' attribute defined)\n|Embedded location ('linkcss' attribute undefined)\n\n|Undefined (default).\n|Same directory as the output document.\n|`stylesheets` subdirectory in the AsciiDoc configuration directory\n(the directory containing the backend conf file).\n\n|Absolute or relative directory name.\n|Absolute or relative to the output document.\n|Absolute or relative to the AsciiDoc configuration directory (the\ndirectory containing the backend conf file).\n\n|====================================================================\n\n.JavaScript file locations\n[cols=\"3*\",frame=\"topbot\",options=\"header\"]\n|====================================================================\n|'scriptsdir' attribute\n|Linked location ('linkcss' attribute defined)\n|Embedded location ('linkcss' attribute undefined)\n\n|Undefined (default).\n|Same directory as the output document.\n|`javascripts` subdirectory in the AsciiDoc configuration directory\n(the directory containing the backend conf file).\n\n|Absolute or relative directory name.\n|Absolute or relative to the output document.\n|Absolute or relative to the AsciiDoc configuration directory (the\ndirectory containing the backend conf file).\n\n|====================================================================\n\n[[X99]]\nThemes\n~~~~~~\nThe AsciiDoc 'theme' attribute is used to select an alternative CSS\nstylesheet and to optionally include additional JavaScript code.\n\n- Theme files reside in an AsciiDoc <<X27,configuration directory>>\n  named `themes/<theme>/` (where `<theme>` is the the theme name set\n  by the 'theme' attribute). asciidoc(1) sets the 'themedir' attribute\n  to the theme directory path name.\n- The 'theme' attribute can also be set using the asciidoc(1)\n  `--theme` option, the `--theme` option can also be used to manage\n  theme <<X101,plugins>>.\n- AsciiDoc ships with two themes: 'flask' and 'volnitsky'.\n- The `<theme>.css` file replaces the default `asciidoc.css` CSS file.\n- The `<theme>.js` file is included in addition to the default\n  `asciidoc.js` JavaScript file.\n- If the <<X66,data-uri>> attribute is defined then icons are loaded\n  from the theme `icons` sub-directory if it exists (i.e.  the\n  'iconsdir' attribute is set to theme `icons` sub-directory path).\n- Embedded theme files are automatically inserted in the output files\n  but you need to manually copy linked CSS and Javascript files to the\n  location of the output documents.\n- Linked CSS and JavaScript theme files are linked to the same linked\n  locations as <<X35,other CSS and JavaScript files>>.\n\nFor example, the command-line option `--theme foo` (or `--attribute\ntheme=foo`) will cause asciidoc(1) to search <<\"X27\",\"configuration\nfile locations 1, 2 and 3\">> for a sub-directory called `themes/foo`\ncontaining the stylesheet `foo.css` and optionally a JavaScript file\nname `foo.js`.\n\n\nDocument Structure\n------------------\nAn AsciiDoc document consists of a series of <<X8,block elements>>\nstarting with an optional document Header, followed by an optional\nPreamble, followed by zero or more document Sections.\n\nAlmost any combination of zero or more elements constitutes a valid\nAsciiDoc document: documents can range from a single sentence to a\nmulti-part book.\n\nBlock Elements\n~~~~~~~~~~~~~~\nBlock elements consist of one or more lines of text and may contain\nother block elements.\n\nThe AsciiDoc block structure can be informally summarized as follows\nfootnote:[This is a rough structural guide, not a rigorous syntax\ndefinition]:\n\n  Document      ::= (Header?,Preamble?,Section*)\n  Header        ::= (Title,(AuthorInfo,RevisionInfo?)?)\n  AuthorInfo    ::= (FirstName,(MiddleName?,LastName)?,EmailAddress?)\n  RevisionInfo  ::= (RevisionNumber?,RevisionDate,RevisionRemark?)\n  Preamble      ::= (SectionBody)\n  Section       ::= (Title,SectionBody?,(Section)*)\n  SectionBody   ::= ((BlockTitle?,Block)|BlockMacro)+\n  Block         ::= (Paragraph|DelimitedBlock|List|Table)\n  List          ::= (BulletedList|NumberedList|LabeledList|CalloutList)\n  BulletedList  ::= (ListItem)+\n  NumberedList  ::= (ListItem)+\n  CalloutList   ::= (ListItem)+\n  LabeledList   ::= (ListEntry)+\n  ListEntry     ::= (ListLabel,ListItem)\n  ListLabel     ::= (ListTerm+)\n  ListItem      ::= (ItemText,(List|ListParagraph|ListContinuation)*)\n\nWhere:\n\n- '?' implies zero or one occurrence, '+' implies one or more\n  occurrences, '*' implies zero or more occurrences.\n- All block elements are separated by line boundaries.\n- `BlockId`, `AttributeEntry` and `AttributeList` block elements (not\n  shown) can occur almost anywhere.\n- There are a number of document type and backend specific\n  restrictions imposed on the block syntax.\n- The following elements cannot contain blank lines: Header, Title,\n  Paragraph, ItemText.\n- A ListParagraph is a Paragraph with its 'listelement' option set.\n- A ListContinuation is a <<X15,list continuation element>>.\n\n[[X95]]\nHeader\n~~~~~~\nThe Header contains document meta-data, typically title plus optional\nauthorship and revision information:\n\n- The Header is optional, but if it is used it must start with a\n  document <<X17,title>>.\n- Optional Author and Revision information immediately follows the\n  header title.\n- The document header must be separated from the remainder of the\n  document by one or more blank lines and cannot contain blank lines.\n- The header can include comments.\n- The header can include <<X18,attribute entries>>, typically\n  'doctype', 'lang', 'encoding', 'icons', 'data-uri', 'toc',\n  'numbered'.\n- Header attributes are overridden by command-line attributes.\n- If the header contains non-UTF-8 characters then the 'encoding' must\n  precede the header (either in the document or on the command-line).\n\nHere's an example AsciiDoc document header:\n\n  Writing Documentation using AsciiDoc\n  ====================================\n  Joe Bloggs <jbloggs@mymail.com>\n  v2.0, February 2003:\n  Rewritten for version 2 release.\n\nThe author information line contains the author's name optionally\nfollowed by the author's email address. The author's name is formatted\nlike:\n\n  firstname[ [middlename ]lastname][ <email>]]\n\ni.e. a first name followed by optional middle and last names followed\nby an email address in that order.  Multi-word first, middle and last\nnames can be entered using the underscore as a word separator.  The\nemail address comes last and must be enclosed in angle <> brackets.\nHere a some examples of author information lines:\n\n  Joe Bloggs <jbloggs@mymail.com>\n  Joe Bloggs\n  Vincent Willem van_Gogh\n\nIf the author line does not match the above specification then the\nentire author line is treated as the first name.\n\nThe optional revision information line follows the author information\nline. The revision information can be one of two formats:\n\n. An optional document revision number followed by an optional\n  revision date followed by an optional revision remark:\n+\n--\n  * If the revision number is specified it must be followed by a\n    comma.\n  * The revision number must contain at least one numeric character.\n  * Any non-numeric characters preceding the first numeric character\n    will be dropped.\n  * If a revision remark is specified it must be preceded by a colon.\n    The revision remark extends from the colon up to the next blank\n    line, attribute entry or comment and is subject to normal text\n    substitutions.\n  * If a revision number or remark has been set but the revision date\n    has not been set then the revision date is set to the value of the\n    'docdate' attribute.\n\nExamples:\n\n  v2.0, February 2003\n  February 2003\n  v2.0,\n  v2.0, February 2003: Rewritten for version 2 release.\n  February 2003: Rewritten for version 2 release.\n  v2.0,: Rewritten for version 2 release.\n  :Rewritten for version 2 release.\n--\n\n. The revision information line can also be an RCS/CVS/SVN $Id$\n  marker:\n+\n--\n  * AsciiDoc extracts the 'revnumber', 'revdate', and 'author'\n    attributes from the $Id$ revision marker and displays them in the\n    document header.\n  * If an $Id$ revision marker is used the header author line can be\n    omitted.\n\nExample:\n\n  $Id: mydoc.txt,v 1.5 2009/05/17 17:58:44 jbloggs Exp $\n--\n\nYou can override or set header parameters by passing 'revnumber',\n'revremark', 'revdate', 'email', 'author', 'authorinitials',\n'firstname' and 'lastname' attributes using the asciidoc(1) `-a`\n(`--attribute`) command-line option. For example:\n\n  $ asciidoc -a revdate=2004/07/27 article.txt\n\nAttribute entries can also be added to the header for substitution in\nthe header template with <<X18,Attribute Entry>> elements.\n\nThe 'title' element in HTML outputs is set to the AsciiDoc document\ntitle, you can set it to a different value by including a 'title'\nattribute entry in the document header.\n\n[[X87]]\nAdditional document header information\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAsciiDoc has two mechanisms for optionally including additional\nmeta-data in the header of the output document:\n\n'docinfo' configuration file sections::\nIf a <<X7,configuration file>> section named 'docinfo' has been loaded\nthen it will be included in the document header. Typically the\n'docinfo' section name will be prefixed with a '+' character so that it\nis appended to (rather than replace) other 'docinfo' sections.\n\n'docinfo' files::\nTwo docinfo files are recognized: one named `docinfo` and a second\nnamed like the AsciiDoc source file with a `-docinfo` suffix.  For\nexample, if the source document is called `mydoc.txt` then the\ndocument information files would be `docinfo.xml` and\n`mydoc-docinfo.xml` (for DocBook outputs) and `docinfo.html` and\n`mydoc-docinfo.html` (for HTML outputs).  The <<X97,docinfo, docinfo1\nand docinfo2>> attributes control which docinfo files are included in\nthe output files.\n\nThe contents docinfo templates and files is dependent on the type of\noutput:\n\nHTML::\n  Valid 'head' child elements. Typically 'style' and 'script' elements\n  for CSS and JavaScript inclusion.\n\nDocBook::\n  Valid 'articleinfo' or 'bookinfo' child elements.  DocBook defines\n  numerous elements for document meta-data, for example: copyrights,\n  document history and authorship information.  See the DocBook\n  `./doc/article-docinfo.xml` example that comes with the AsciiDoc\n  distribution.  The rendering of meta-data elements (or not) is\n  DocBook processor dependent.\n\n\n[[X86]]\nPreamble\n~~~~~~~~\nThe Preamble is an optional untitled section body between the document\nHeader and the first Section title.\n\nSections\n~~~~~~~~\nIn addition to the document title (level 0), AsciiDoc supports four\nsection levels: 1 (top) to 4 (bottom).  Section levels are delimited\nby section <<X17,titles>>.  Sections are translated using\nconfiguration file <<X93,section markup templates>>. AsciiDoc\ngenerates the following <<X60,intrinsic attributes>> specifically for\nuse in section markup templates:\n\nlevel::\nThe `level` attribute is the section level number, it is normally just\nthe <<X17,title>> level number (1..4). However, if the `leveloffset`\nattribute is defined it will be added to the `level` attribute. The\n`leveloffset` attribute is useful for <<X90,combining documents>>.\n\nsectnum::\nThe `-n` (`--section-numbers`) command-line option generates the\n`sectnum` (section number) attribute.  The `sectnum` attribute is used\nfor section numbers in HTML outputs (DocBook section numbering are\nhandled automatically by the DocBook toolchain commands).\n\n[[X93]]\nSection markup templates\n^^^^^^^^^^^^^^^^^^^^^^^^\nSection markup templates specify output markup and are defined in\nAsciiDoc configuration files.  Section markup template names are\nderived as follows (in order of precedence):\n\n1. From the title's first positional attribute or 'template'\n   attribute. For example, the following three section titles are\n   functionally equivalent:\n+\n.....................................................................\n[[terms]]\n[glossary]\nList of Terms\n-------------\n\n[\"glossary\",id=\"terms\"]\nList of Terms\n-------------\n\n[template=\"glossary\",id=\"terms\"]\nList of Terms\n-------------\n.....................................................................\n\n2. When the title text matches a configuration file\n   <<X16,`[specialsections]`>> entry.\n3. If neither of the above the default `sect<level>` template is used\n   (where `<level>` is a number from 1 to 4).\n\nIn addition to the normal section template names ('sect1', 'sect2',\n'sect3', 'sect4') AsciiDoc has the following templates for\nfrontmatter, backmatter and other special sections: 'abstract',\n'preface', 'colophon', 'dedication', 'glossary', 'bibliography',\n'synopsis', 'appendix', 'index'.  These special section templates\ngenerate the corresponding Docbook elements; for HTML outputs they\ndefault to the 'sect1' section template.\n\nSection IDs\n^^^^^^^^^^^\nIf no explicit section ID is specified an ID will be synthesised from\nthe section title.  The primary purpose of this feature is to ensure\npersistence of table of contents links (permalinks): the missing\nsection IDs are generated dynamically by the JavaScript TOC generator\n*after* the page is loaded. If you link to a dynamically generated TOC\naddress the page will load but the browser will ignore the (as yet\nungenerated) section ID.\n\nThe IDs are generated by the following algorithm:\n\n- Replace all non-alphanumeric title characters with underscores.\n- Strip leading or trailing underscores.\n- Convert to lowercase.\n- Prepend the `idprefix` attribute (so there's no possibility of name\n  clashes with existing document IDs). Prepend an underscore if the\n  `idprefix` attribute is not defined.\n- A numbered suffix (`_2`, `_3` ...) is added if a same named\n  auto-generated section ID exists.\n- If the `ascii-ids` attribute is defined then non-ASCII characters\n  are replaced with ASCII equivalents. This attribute may be\n  deprecated in future releases and *should be avoided*, it's sole\n  purpose is to accommodate deficient downstream applications that\n  cannot process non-ASCII ID attributes.\n\nExample: the title 'Jim's House' would generate the ID `_jim_s_house`.\n\nSection ID synthesis can be disabled by undefining the `sectids`\nattribute.\n\n[[X16]]\nSpecial Section Titles\n^^^^^^^^^^^^^^^^^^^^^^\nAsciiDoc has a mechanism for mapping predefined section titles\nauto-magically to specific markup templates. For example a title\n'Appendix A: Code Reference' will automatically use the 'appendix'\n<<X93,section markup template>>. The mappings from title to template\nname are specified in `[specialsections]` sections in the Asciidoc\nlanguage configuration files (`lang-*.conf`).  Section entries are\nformatted like:\n\n  <title>=<template>\n\n`<title>` is a Python regular expression and `<template>` is the name\nof a configuration file markup template section. If the `<title>`\nmatches an AsciiDoc document section title then the backend output is\nmarked up using the `<template>` markup template (instead of the\ndefault `sect<level>` section template). The `{title}` attribute value\nis set to the value of the matched regular expression group named\n'title', if there is no 'title' group `{title}` defaults to the whole\nof the AsciiDoc section title. If `<template>` is blank then any\nexisting entry with the same `<title>` will be deleted.\n\n.Special section titles vs. explicit template names\n*********************************************************************\nAsciiDoc has two mechanisms for specifying non-default section markup\ntemplates: you can specify the template name explicitly (using the\n'template' attribute) or indirectly (using 'special section titles').\nSpecifying a <<X93,section template>> attribute explicitly is\npreferred.  Auto-magical 'special section titles' have the following\ndrawbacks:\n\n- They are non-obvious, you have to know the exact matching\n  title for each special section on a language by language basis.\n- Section titles are predefined and can only be customised with a\n  configuration change.\n- The implementation is complicated by multiple languages: every\n  special section title has to be defined for each language (in each\n  of the `lang-*.conf` files).\n\nSpecifying special section template names explicitly does add more\nnoise to the source document (the 'template' attribute declaration),\nbut the intention is obvious and the syntax is consistent with other\nAsciiDoc elements c.f.  bibliographic, Q&A and glossary lists.\n\nSpecial section titles have been deprecated but are retained for\nbackward compatibility.\n\n*********************************************************************\n\nInline Elements\n~~~~~~~~~~~~~~~\n<<X34,Inline document elements>> are used to format text and to\nperform various types of text substitution. Inline elements and inline\nelement syntax is defined in the asciidoc(1) configuration files.\n\nHere is a list of AsciiDoc inline elements in the (default) order in\nwhich they are processed:\n\nSpecial characters::\n        These character sequences escape special characters used by\n        the backend markup (typically `<`, `>`, and `&` characters).\n        See `[specialcharacters]` configuration file sections.\n\nQuotes::\n        Elements that markup words and phrases; usually for character\n        formatting. See `[quotes]` configuration file sections.\n\nSpecial Words::\n        Word or word phrase patterns singled out for markup without\n        the need for further annotation.  See `[specialwords]`\n        configuration file sections.\n\nReplacements::\n        Each replacement defines a word or word phrase pattern to\n        search for along with corresponding replacement text. See\n        `[replacements]` configuration file sections.\n\nAttribute references::\n        Document attribute names enclosed in braces are replaced by\n        the corresponding attribute value.\n\nInline Macros::\n        Inline macros are replaced by the contents of parametrized\n        configuration file sections.\n\n\nDocument Processing\n-------------------\nThe AsciiDoc source document is read and processed as follows:\n\n1. The document 'Header' is parsed, header parameter values are\n   substituted into the configuration file `[header]` template section\n   which is then written to the output file.\n2. Each document 'Section' is processed and its constituent elements\n   translated to the output file.\n3. The configuration file `[footer]` template section is substituted\n   and written to the output file.\n\nWhen a block element is encountered asciidoc(1) determines the type of\nblock by checking in the following order (first to last): (section)\nTitles, BlockMacros, Lists, DelimitedBlocks, Tables, AttributeEntrys,\nAttributeLists, BlockTitles, Paragraphs.\n\nThe default paragraph definition `[paradef-default]` is last element\nto be checked.\n\nKnowing the parsing order will help you devise unambiguous macro, list\nand block syntax rules.\n\nInline substitutions within block elements are performed in the\nfollowing default order:\n\n1. Special characters\n2. Quotes\n3. Special words\n4. Replacements\n5. Attributes\n6. Inline Macros\n7. Replacements2\n\nThe substitutions and substitution order performed on\nTitle, Paragraph and DelimitedBlock elements is determined by\nconfiguration file parameters.\n\n\nText Formatting\n---------------\n[[X51]]\nQuoted Text\n~~~~~~~~~~~\nWords and phrases can be formatted by enclosing inline text with\nquote characters:\n\n_Emphasized text_::\n        Word phrases \\'enclosed in single quote characters' (acute\n        accents) or \\_underline characters_ are emphasized.\n\n*Strong text*::\n        Word phrases \\*enclosed in asterisk characters* are rendered\n        in a strong font (usually bold).\n\n[[X81]]+Monospaced text+::\n        Word phrases \\+enclosed in plus characters+ are rendered in a\n        monospaced font. Word phrases \\`enclosed in backtick\n        characters` (grave accents) are also rendered in a monospaced\n        font but in this case the enclosed text is rendered literally\n        and is not subject to further expansion (see <<X80,inline\n        literal passthrough>>).\n\n`Single quoted text'::\n        Phrases enclosed with a \\`single grave accent to the left and\n        a single acute accent to the right' are rendered in single\n        quotation marks.\n\n``Double quoted text''::\n        Phrases enclosed with \\\\``two grave accents to the left and\n        two acute accents to the right'' are rendered in quotation\n        marks.\n\n#Unquoted text#::\n        Placing \\#hashes around text# does nothing, it is a mechanism\n        to allow inline attributes to be applied to otherwise\n        unformatted text.\n\nNew quote types can be defined by editing asciidoc(1) configuration\nfiles. See the <<X7,Configuration Files>> section for details.\n\n.Quoted text behavior\n- Quoting cannot be overlapped.\n- Different quoting types can be nested.\n- To suppress quoted text formatting place a backslash character\n  immediately in front of the leading quote character(s). In the case\n  of ambiguity between escaped and non-escaped text you will need to\n  escape both leading and trailing quotes, in the case of\n  multi-character quotes you may even need to escape individual\n  characters.\n\n[[X96]]\nQuoted text attributes\n^^^^^^^^^^^^^^^^^^^^^^\nQuoted text can be prefixed with an <<X21,attribute list>>.  The first\npositional attribute ('role' attribute) is translated by AsciiDoc to\nan HTML 'span' element 'class' attribute or a DocBook 'phrase' element\n'role' attribute.\n\nDocBook XSL Stylesheets translate DocBook 'phrase' elements with\n'role' attributes to corresponding HTML 'span' elements with the same\n'class' attributes; CSS can then be used\nhttp://www.sagehill.net/docbookxsl/UsingCSS.html[to style the\ngenerated HTML].  Thus CSS styling can be applied to both DocBook and\nAsciiDoc generated HTML outputs.  You can also specify multiple class\nnames separated by spaces.\n\nCSS rules for text color, text background color, text size and text\ndecorators are included in the distributed AsciiDoc CSS files and are\nused in conjunction with AsciiDoc 'xhtml11', 'html5' and 'docbook'\noutputs. The CSS class names are:\n\n- '<color>' (text foreground color).\n- '<color>-background' (text background color).\n- 'big' and 'small' (text size).\n- 'underline', 'overline' and 'line-through' (strike through) text\n  decorators.\n\nWhere '<color>' can be any of the\nhttp://en.wikipedia.org/wiki/Web_colors#HTML_color_names[sixteen HTML\ncolor names].  Examples:\n\n  [red]#Obvious# and [big red yellow-background]*very obvious*.\n\n  [underline]#Underline text#, [overline]#overline text# and\n  [blue line-through]*bold blue and line-through*.\n\nis rendered as:\n\n[red]#Obvious# and [big red yellow-background]*very obvious*.\n\n[underline]#Underline text#, [overline]#overline text# and\n[bold blue line-through]*bold blue and line-through*.\n\nNOTE: Color and text decorator attributes are rendered for XHTML and\nHTML 5 outputs using CSS stylesheets.  The mechanism to implement\ncolor and text decorator attributes is provided for DocBook toolchains\nvia the DocBook 'phrase' element 'role' attribute, but the actual\nrendering is toolchain specific and is not part of the AsciiDoc\ndistribution.\n\n[[X52]]\nConstrained and Unconstrained Quotes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThere are actually two types of quotes:\n\nConstrained quotes\n++++++++++++++++++\nQuoted must be bounded by white space or commonly adjoining\npunctuation characters. These are the most commonly used type of\nquote.\n\nUnconstrained quotes\n++++++++++++++++++++\nUnconstrained quotes have no boundary constraints and can be placed\nanywhere within inline text. For consistency and to make them easier\nto remember unconstrained quotes are double-ups of the `_`, `*`, `+`\nand `#` constrained quotes:\n\n  __unconstrained emphasized text__\n  **unconstrained strong text**\n  ++unconstrained monospaced text++\n  ##unconstrained unquoted text##\n\nThe following example emboldens the letter F:\n\n  **F**ile Open...\n\nSuperscripts and Subscripts\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nPut \\^carets on either^ side of the text to be superscripted, put\n\\~tildes on either side~ of text to be subscripted.  For example, the\nfollowing line:\n\n  e^&#960;i^+1 = 0. H~2~O and x^10^. Some ^super text^\n  and ~some sub text~\n\nIs rendered like:\n\ne^&#960;i^+1 = 0. H~2~O and x^10^. Some ^super text^\nand ~some sub text~\n\nSuperscripts and subscripts are implemented as <<X52,unconstrained\nquotes>> and they can be escaped with a leading backslash and prefixed\nwith with an attribute list.\n\nLine Breaks\n~~~~~~~~~~~\nA plus character preceded by at least one space character at the end\nof a non-blank line forces a line break. It generates a line break\n(`br`) tag for HTML outputs and a custom XML `asciidoc-br` processing\ninstruction for DocBook outputs. The `asciidoc-br` processing\ninstruction is handled by <<X43,a2x(1)>>.\n\nPage Breaks\n~~~~~~~~~~~\nA line of three or more less-than (`<<<`) characters will generate a\nhard page break in DocBook and printed HTML outputs.  It uses the CSS\n`page-break-after` property for HTML outputs and a custom XML\n`asciidoc-pagebreak` processing instruction for DocBook outputs. The\n`asciidoc-pagebreak` processing instruction is handled by\n<<X43,a2x(1)>>. Hard page breaks are sometimes handy but as a general\nrule you should let your page processor generate page breaks for you.\n\nRulers\n~~~~~~\nA line of three or more apostrophe characters will generate a ruler\nline.  It generates a ruler (`hr`) tag for HTML outputs and a custom\nXML `asciidoc-hr` processing instruction for DocBook outputs. The\n`asciidoc-hr` processing instruction is handled by <<X43,a2x(1)>>.\n\nTabs\n~~~~\nBy default tab characters input files will translated to 8 spaces. Tab\nexpansion is set with the 'tabsize' entry in the configuration file\n`[miscellaneous]` section and can be overridden in included files by\nsetting a 'tabsize' attribute in the `include` macro's attribute list.\nFor example:\n\n  include::addendum.txt[tabsize=2]\n\nThe tab size can also be set using the attribute command-line option,\nfor example `--attribute tabsize=4`\n\nReplacements\n~~~~~~~~~~~~\nThe following replacements are defined in the default AsciiDoc\nconfiguration:\n\n  (C) copyright, (TM) trademark, (R) registered trademark,\n  -- em dash, ... ellipsis, -> right arrow, <- left arrow, => right\n  double arrow, <= left double arrow.\n\nWhich are rendered as:\n\n(C) copyright, (TM) trademark, (R) registered trademark,\n-- em dash, ... ellipsis, -> right arrow, <- left arrow, => right\ndouble arrow, <= left double arrow.\n\nYou can also include arbitrary entity references in the AsciiDoc\nsource. Examples:\n\n  &#x278a; &#182;\n\nrenders:\n\n&#x278a; &#182;\n\nTo render a replacement literally escape it with a leading back-slash.\n\nThe <<X7,Configuration Files>> section explains how to configure your\nown replacements.\n\nSpecial Words\n~~~~~~~~~~~~~\nWords defined in `[specialwords]` configuration file sections are\nautomatically marked up without having to be explicitly notated.\n\nThe <<X7,Configuration Files>> section explains how to add and replace\nspecial words.\n\n\n[[X17]]\nTitles\n------\nDocument and section titles can be in either of two formats:\n\nTwo line titles\n~~~~~~~~~~~~~~~\nA two line title consists of a title line, starting hard against the\nleft margin, and an underline. Section underlines consist a repeated\ncharacter pairs spanning the width of the preceding title (give or\ntake up to two characters):\n\nThe default title underlines for each of the document levels are:\n\n\n  Level 0 (top level):     ======================\n  Level 1:                 ----------------------\n  Level 2:                 ~~~~~~~~~~~~~~~~~~~~~~\n  Level 3:                 ^^^^^^^^^^^^^^^^^^^^^^\n  Level 4 (bottom level):  ++++++++++++++++++++++\n\nExamples:\n\n  Level One Section Title\n  -----------------------\n\n  Level 2 Subsection Title\n  ~~~~~~~~~~~~~~~~~~~~~~~~\n\n[[X46]]\nOne line titles\n~~~~~~~~~~~~~~~\nOne line titles consist of a single line delimited on either side by\none or more equals characters (the number of equals characters\ncorresponds to the section level minus one).  Here are some examples:\n\n  = Document Title (level 0) =\n  == Section title (level 1) ==\n  === Section title (level 2) ===\n  ==== Section title (level 3) ====\n  ===== Section title (level 4) =====\n\n[NOTE]\n=====================================================================\n- One or more spaces must fall between the title and the delimiters.\n- The trailing title delimiter is optional.\n- The one-line title syntax can be changed by editing the\n  configuration file `[titles]` section `sect0`...`sect4` entries.\n=====================================================================\n\nFloating titles\n~~~~~~~~~~~~~~~\nSetting the title's first positional attribute or 'style' attribute to\n'float' generates a free-floating title. A free-floating title is\nrendered just like a normal section title but is not formally\nassociated with a text body and is not part of the regular section\nhierarchy so the normal ordering rules do not apply. Floating titles\ncan also be used in contexts where section titles are illegal: for\nexample sidebar and admonition blocks.  Example:\n\n  [float]\n  The second day\n  ~~~~~~~~~~~~~~\n\nFloating titles do not appear in a document's table of contents.\n\n\n[[X42]]\nBlock Titles\n------------\nA 'BlockTitle' element is a single line beginning with a period\nfollowed by the title text. A BlockTitle is applied to the immediately\nfollowing Paragraph, DelimitedBlock, List, Table or BlockMacro. For\nexample:\n\n........................\n.Notes\n- Note 1.\n- Note 2.\n........................\n\nis rendered as:\n\n.Notes\n- Note 1.\n- Note 2.\n\n\n[[X41]]\nBlockId Element\n---------------\nA 'BlockId' is a single line block element containing a unique\nidentifier enclosed in double square brackets. It is used to assign an\nidentifier to the ensuing block element. For example:\n\n  [[chapter-titles]]\n  Chapter titles can be ...\n\nThe preceding example identifies the ensuing paragraph so it can be\nreferenced from other locations, for example with\n`<<chapter-titles,chapter titles>>`.\n\n'BlockId' elements can be applied to Title, Paragraph, List,\nDelimitedBlock, Table and BlockMacro elements.  The BlockId element\nsets the `{id}` attribute for substitution in the subsequent block's\nmarkup template. If a second positional argument is supplied it sets\nthe `{reftext}` attribute which is used to set the DocBook `xreflabel`\nattribute.\n\nThe 'BlockId' element has the same syntax and serves the same function\nto the <<X30,anchor inline macro>>.\n\n[[X79]]\nAttributeList Element\n---------------------\nAn 'AttributeList' block element is an <<X21,attribute list>> on a\nline by itself:\n\n- 'AttributeList' attributes are only applied to the immediately\n  following block element -- the attributes are made available to the\n  block's markup template.\n- Multiple contiguous 'AttributeList' elements are additively combined\n  in the order they appear..\n- The first positional attribute in the list is often used to specify\n  the ensuing element's <<X23,style>>.\n\nAttribute value substitution\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBy default, only substitutions that take place inside attribute list\nvalues are attribute references, this is because not all attributes\nare destined to be marked up and rendered as text (for example the\ntable 'cols' attribute). To perform normal inline text substitutions\n(special characters, quotes, macros, replacements) on an attribute\nvalue you need to enclose it in single quotes. In the following quote\nblock the second attribute value in the AttributeList is quoted to\nensure the 'http' macro is expanded to a hyperlink.\n\n---------------------------------------------------------------------\n[quote,'http://en.wikipedia.org/wiki/Samuel_Johnson[Samuel Johnson]']\n_____________________________________________________________________\nSir, a woman's preaching is like a dog's walking on his hind legs. It\nis not done well; but you are surprised to find it done at all.\n_____________________________________________________________________\n---------------------------------------------------------------------\n\nCommon attributes\n~~~~~~~~~~~~~~~~~\nMost block elements support the following attributes:\n\n[cols=\"1e,1,5a\",frame=\"topbot\",options=\"header\"]\n|====================================================================\n|Name |Backends |Description\n\n|id |html4, html5, xhtml11, docbook |\nUnique identifier typically serve as link targets.\nCan also be set by the 'BlockId' element.\n\n|role |html4, html5, xhtml11, docbook |\nRole contains a string used to classify or subclassify an element and\ncan be applied to AsciiDoc block elements.  The AsciiDoc 'role'\nattribute is translated to the 'role' attribute in DocBook outputs and\nis included in the 'class' attribute in HTML outputs, in this respect\nit behaves like the <<X96,quoted text role attribute>>.\n\nDocBook XSL Stylesheets translate DocBook 'role' attributes to HTML\n'class' attributes; CSS can then be used\nhttp://www.sagehill.net/docbookxsl/UsingCSS.html[to style the\ngenerated HTML].\n\n|reftext |docbook |\n'reftext' is used to set the DocBook 'xreflabel' attribute.\nThe 'reftext' attribute can an also be set by the 'BlockId' element.\n\n|====================================================================\n\n\nParagraphs\n----------\nParagraphs are blocks of text terminated by a blank line, the end of\nfile, or the start of a delimited block or a list.  There are three\nparagraph syntaxes: normal, indented (literal) and admonition which\nare rendered, by default, with the corresponding paragraph style.\n\nEach syntax has a default style, but you can explicitly apply any\nparagraph style to any paragraph syntax. You can also apply\n<<X104,delimited block>> styles to single paragraphs.\n\nThe built-in paragraph styles are: 'normal', 'literal', 'verse',\n'quote', 'listing', 'TIP', 'NOTE', 'IMPORTANT', 'WARNING', 'CAUTION',\n'abstract', 'partintro', 'comment', 'example', 'sidebar', 'source',\n'music', 'latex', 'graphviz'.\n\nnormal paragraph syntax\n~~~~~~~~~~~~~~~~~~~~~~~\nNormal paragraph syntax consists of one or more non-blank lines of\ntext. The first line must start hard against the left margin (no\nintervening white space). The default processing expectation is that\nof a normal paragraph of text.\n\n[[X85]]\nliteral paragraph syntax\n~~~~~~~~~~~~~~~~~~~~~~~~\nLiteral paragraphs are rendered verbatim in a monospaced font without\nany distinguishing background or border.  By default there is no text\nformatting or substitutions within Literal paragraphs apart from\nSpecial Characters and Callouts.\n\nThe 'literal' style is applied implicitly to indented paragraphs i.e.\nwhere the first line of the paragraph is indented by one or more space\nor tab characters.  For example:\n\n---------------------------------------------------------------------\n  Consul *necessitatibus* per id,\n  consetetur, eu pro everti postulant\n  homero verear ea mea, qui.\n---------------------------------------------------------------------\n\nRenders:\n\n  Consul *necessitatibus* per id,\n  consetetur, eu pro everti postulant\n  homero verear ea mea, qui.\n\nNOTE: Because <<X64,lists>> can be indented it's possible for your\nindented paragraph to be misinterpreted as a list -- in situations\nlike this apply the 'literal' style to a normal paragraph.\n\nInstead of using a paragraph indent you could apply the 'literal'\nstyle explicitly, for example:\n\n---------------------------------------------------------------------\n[literal]\nConsul *necessitatibus* per id,\nconsetetur, eu pro everti postulant\nhomero verear ea mea, qui.\n---------------------------------------------------------------------\n\nRenders:\n\n[literal]\nConsul *necessitatibus* per id,\nconsetetur, eu pro everti postulant\nhomero verear ea mea, qui.\n\n[[X94]]\nquote and verse paragraph styles\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe optional 'attribution' and 'citetitle' attributes (positional\nattributes 2 and 3) specify the author and source respectively.\n\nThe 'verse' style retains the line breaks, for example:\n\n---------------------------------------------------------------------\n[verse, William Blake, from Auguries of Innocence]\nTo see a world in a grain of sand,\nAnd a heaven in a wild flower,\nHold infinity in the palm of your hand,\nAnd eternity in an hour.\n---------------------------------------------------------------------\n\nWhich is rendered as:\n\n[verse, William Blake, from Auguries of Innocence]\nTo see a world in a grain of sand,\nAnd a heaven in a wild flower,\nHold infinity in the palm of your hand,\nAnd eternity in an hour.\n\nThe 'quote' style flows the text at left and right margins, for\nexample:\n\n---------------------------------------------------------------------\n[quote, Bertrand Russell, The World of Mathematics (1956)]\nA good notation has subtlety and suggestiveness which at times makes\nit almost seem like a live teacher.\n---------------------------------------------------------------------\n\nWhich is rendered as:\n\n[quote, Bertrand Russell, The World of Mathematics (1956)]\nA good notation has subtlety and suggestiveness which at times makes\nit almost seem like a live teacher.\n\n[[X28]]\nAdmonition Paragraphs\n~~~~~~~~~~~~~~~~~~~~~\n'TIP', 'NOTE', 'IMPORTANT', 'WARNING' and 'CAUTION' admonishment\nparagraph styles are generated by placing `NOTE:`, `TIP:`,\n`IMPORTANT:`, `WARNING:` or `CAUTION:` as the first word of the\nparagraph. For example:\n\n  NOTE: This is an example note.\n\nAlternatively, you can specify the paragraph admonition style\nexplicitly using an <<X79,AttributeList element>>. For example:\n\n  [NOTE]\n  This is an example note.\n\nRenders:\n\nNOTE: This is an example note.\n\nTIP: If your admonition requires more than a single paragraph use an\n<<X22,admonition block>> instead.\n\n[[X47]]\nAdmonition Icons and Captions\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nNOTE: Admonition customization with `icons`, `iconsdir`, `icon` and\n`caption` attributes does not apply when generating DocBook output. If\nyou are going the DocBook route then the <<X43,a2x(1)>> `--no-icons`\nand `--icons-dir` options can be used to set the appropriate XSL\nStylesheets parameters.\n\nBy default the asciidoc(1) HTML backends generate text captions\ninstead of admonition icon image links. To generate links to icon\nimages define the <<X45,`icons`>> attribute, for example using the `-a\nicons` command-line option.\n\nThe <<X44,`iconsdir`>> attribute sets the location of linked icon\nimages.\n\nYou can override the default icon image using the `icon` attribute to\nspecify the path of the linked image. For example:\n\n  [icon=\"./images/icons/wink.png\"]\n  NOTE: What lovely war.\n\nUse the `caption` attribute to customize the admonition captions (not\napplicable to `docbook` backend). The following example suppresses the\nicon image and customizes the caption of a 'NOTE' admonition\n(undefining the `icons` attribute with `icons=None` is only necessary\nif <<X45,admonition icons>> have been enabled):\n\n  [icons=None, caption=\"My Special Note\"]\n  NOTE: This is my special note.\n\nThis subsection also applies to <<X22,Admonition Blocks>>.\n\n\n[[X104]]\nDelimited Blocks\n----------------\nDelimited blocks are blocks of text enveloped by leading and trailing\ndelimiter lines (normally a series of four or more repeated\ncharacters). The behavior of Delimited Blocks is specified by entries\nin configuration file `[blockdef-*]` sections.\n\nPredefined Delimited Blocks\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAsciiDoc ships with a number of predefined DelimitedBlocks (see the\n`asciidoc.conf` configuration file in the asciidoc(1) program\ndirectory):\n\nPredefined delimited block underlines:\n\n  CommentBlock:     //////////////////////////\n  PassthroughBlock: ++++++++++++++++++++++++++\n  ListingBlock:     --------------------------\n  LiteralBlock:     ..........................\n  SidebarBlock:     **************************\n  QuoteBlock:       __________________________\n  ExampleBlock:     ==========================\n  OpenBlock:        --\n\n.Default DelimitedBlock substitutions\n[cols=\"2e,7*^\",frame=\"topbot\",options=\"header,autowidth\"]\n|=====================================================\n| |Attributes |Callouts |Macros | Quotes |Replacements\n|Special chars |Special words\n\n|PassthroughBlock |Yes |No  |Yes |No  |No  |No  |No\n|ListingBlock     |No  |Yes |No  |No  |No  |Yes |No\n|LiteralBlock     |No  |Yes |No  |No  |No  |Yes |No\n|SidebarBlock     |Yes |No  |Yes |Yes |Yes |Yes |Yes\n|QuoteBlock       |Yes |No  |Yes |Yes |Yes |Yes |Yes\n|ExampleBlock     |Yes |No  |Yes |Yes |Yes |Yes |Yes\n|OpenBlock        |Yes |No  |Yes |Yes |Yes |Yes |Yes\n|=====================================================\n\nListing Blocks\n~~~~~~~~~~~~~~\n'ListingBlocks' are rendered verbatim in a monospaced font, they\nretain line and whitespace formatting and are often distinguished by a\nbackground or border. There is no text formatting or substitutions\nwithin Listing blocks apart from Special Characters and Callouts.\nListing blocks are often used for computer output and file listings.\n\nHere's an example:\n\n[listing]\n......................................\n--------------------------------------\n#include <stdio.h>\n\nint main() {\n   printf(\"Hello World!\\n\");\n   exit(0);\n}\n--------------------------------------\n......................................\n\nWhich will be rendered like:\n\n--------------------------------------\n#include <stdio.h>\n\nint main() {\n    printf(\"Hello World!\\n\");\n    exit(0);\n}\n--------------------------------------\n\nBy convention <<X59,filter blocks>> use the listing block syntax and\nare implemented as distinct listing block styles.\n\n[[X65]]\nLiteral Blocks\n~~~~~~~~~~~~~~\n'LiteralBlocks' are rendered just like <<X85,literal paragraphs>>.\nExample:\n\n---------------------------------------------------------------------\n...................................\nConsul *necessitatibus* per id,\nconsetetur, eu pro everti postulant\nhomero verear ea mea, qui.\n...................................\n---------------------------------------------------------------------\n\nRenders:\n...................................\nConsul *necessitatibus* per id,\nconsetetur, eu pro everti postulant\nhomero verear ea mea, qui.\n...................................\n\nIf the 'listing' style is applied to a LiteralBlock it will be\nrendered as a ListingBlock (this is handy if you have a listing\ncontaining a ListingBlock).\n\nSidebar Blocks\n~~~~~~~~~~~~~~\nA sidebar is a short piece of text presented outside the narrative\nflow of the main text. The sidebar is normally presented inside a\nbordered box to set it apart from the main text.\n\nThe sidebar body is treated like a normal section body.\n\nHere's an example:\n\n---------------------------------------------------------------------\n.An Example Sidebar\n************************************************\nAny AsciiDoc SectionBody element (apart from\nSidebarBlocks) can be placed inside a sidebar.\n************************************************\n---------------------------------------------------------------------\n\nWhich will be rendered like:\n\n.An Example Sidebar\n************************************************\nAny AsciiDoc SectionBody element (apart from\nSidebarBlocks) can be placed inside a sidebar.\n************************************************\n\n[[X26]]\nComment Blocks\n~~~~~~~~~~~~~~\nThe contents of 'CommentBlocks' are not processed; they are useful for\nannotations and for excluding new or outdated content that you don't\nwant displayed. CommentBlocks are never written to output files.\nExample:\n\n---------------------------------------------------------------------\n//////////////////////////////////////////\nCommentBlock contents are not processed by\nasciidoc(1).\n//////////////////////////////////////////\n---------------------------------------------------------------------\n\nSee also <<X25,Comment Lines>>.\n\nNOTE: System macros are executed inside comment blocks.\n\n[[X76]]\nPassthrough Blocks\n~~~~~~~~~~~~~~~~~~\nBy default the block contents is subject only to 'attributes' and\n'macros' substitutions (use an explicit 'subs' attribute to apply\ndifferent substitutions).  PassthroughBlock content will often be\nbackend specific. Here's an example:\n\n---------------------------------------------------------------------\n[subs=\"quotes\"]\n++++++++++++++++++++++++++++++++++++++\n<table border=\"1\"><tr>\n  <td>*Cell 1*</td>\n  <td>*Cell 2*</td>\n</tr></table>\n++++++++++++++++++++++++++++++++++++++\n---------------------------------------------------------------------\n\nThe following styles can be applied to passthrough blocks:\n\npass::\n  No substitutions are performed. This is equivalent to `subs=\"none\"`.\n\nasciimath, latexmath::\n  By default no substitutions are performed, the contents are rendered\n  as <<X78,mathematical formulas>>.\n\nQuote Blocks\n~~~~~~~~~~~~\n'QuoteBlocks' are used for quoted passages of text. There are two\nstyles: 'quote' and 'verse'. The style behavior is identical to\n<<X94,quote and verse paragraphs>> except that blocks can contain\nmultiple paragraphs and, in the case of the 'quote' style, other\nsection elements.  The first positional attribute sets the style, if\nno attributes are specified the 'quote' style is used.  The optional\n'attribution' and 'citetitle' attributes (positional attributes 2 and\n3) specify the quote's author and source. For example:\n\n---------------------------------------------------------------------\n[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]\n____________________________________________________________________\nAs he spoke there was the sharp sound of horses' hoofs and\ngrating wheels against the curb, followed by a sharp pull at the\nbell. Holmes whistled.\n\n\"A pair, by the sound,\" said he. \"Yes,\" he continued, glancing\nout of the window. \"A nice little brougham and a pair of\nbeauties. A hundred and fifty guineas apiece. There's money in\nthis case, Watson, if there is nothing else.\"\n____________________________________________________________________\n---------------------------------------------------------------------\n\nWhich is rendered as:\n\n[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]\n____________________________________________________________________\nAs he spoke there was the sharp sound of horses' hoofs and\ngrating wheels against the curb, followed by a sharp pull at the\nbell. Holmes whistled.\n\n\"A pair, by the sound,\" said he. \"Yes,\" he continued, glancing\nout of the window. \"A nice little brougham and a pair of\nbeauties. A hundred and fifty guineas apiece. There's money in\nthis case, Watson, if there is nothing else.\"\n____________________________________________________________________\n\n[[X48]]\nExample Blocks\n~~~~~~~~~~~~~~\n'ExampleBlocks' encapsulate the DocBook Example element and are used\nfor, well, examples.  Example blocks can be titled by preceding them\nwith a 'BlockTitle'.  DocBook toolchains will normally automatically\nnumber examples and generate a 'List of Examples' backmatter section.\n\nExample blocks are delimited by lines of equals characters and can\ncontain any block elements apart from Titles, BlockTitles and\nSidebars) inside an example block. For example:\n\n---------------------------------------------------------------------\n.An example\n=====================================================================\nQui in magna commodo, est labitur dolorum an. Est ne magna primis\nadolescens.\n=====================================================================\n---------------------------------------------------------------------\n\nRenders:\n\n.An example\n=====================================================================\nQui in magna commodo, est labitur dolorum an. Est ne magna primis\nadolescens.\n=====================================================================\n\nA title prefix that can be inserted with the `caption` attribute\n(HTML backends). For example:\n\n---------------------------------------------------------------------\n[caption=\"Example 1: \"]\n.An example with a custom caption\n=====================================================================\nQui in magna commodo, est labitur dolorum an. Est ne magna primis\nadolescens.\n=====================================================================\n---------------------------------------------------------------------\n\n[[X22]]\nAdmonition Blocks\n~~~~~~~~~~~~~~~~~\nThe 'ExampleBlock' definition includes a set of admonition\n<<X23,styles>> ('NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION') for\ngenerating admonition blocks (admonitions containing more than a\n<<X28,single paragraph>>).  Just precede the 'ExampleBlock' with an\nattribute list specifying the admonition style name. For example:\n\n---------------------------------------------------------------------\n[NOTE]\n.A NOTE admonition block\n=====================================================================\nQui in magna commodo, est labitur dolorum an. Est ne magna primis\nadolescens.\n\n. Fusce euismod commodo velit.\n. Vivamus fringilla mi eu lacus.\n  .. Fusce euismod commodo velit.\n  .. Vivamus fringilla mi eu lacus.\n. Donec eget arcu bibendum\n  nunc consequat lobortis.\n=====================================================================\n---------------------------------------------------------------------\n\nRenders:\n\n[NOTE]\n.A NOTE admonition block\n=====================================================================\nQui in magna commodo, est labitur dolorum an. Est ne magna primis\nadolescens.\n\n. Fusce euismod commodo velit.\n. Vivamus fringilla mi eu lacus.\n  .. Fusce euismod commodo velit.\n  .. Vivamus fringilla mi eu lacus.\n. Donec eget arcu bibendum\n  nunc consequat lobortis.\n=====================================================================\n\nSee also <<X47,Admonition Icons and Captions>>.\n\n[[X29]]\nOpen Blocks\n~~~~~~~~~~~\nOpen blocks are special:\n\n- The open block delimiter is line containing two hyphen characters\n  (instead of four or more repeated characters).\n\n- They can be used to group block elements for <<X15,List item\n  continuation>>.\n\n- Open blocks can be styled to behave like any other type of delimited\n  block.  The  following built-in styles can be applied to open\n  blocks: 'literal', 'verse', 'quote', 'listing', 'TIP', 'NOTE',\n  'IMPORTANT', 'WARNING', 'CAUTION', 'abstract', 'partintro',\n  'comment', 'example', 'sidebar', 'source', 'music', 'latex',\n  'graphviz'. For example, the following open block and listing block\n  are functionally identical:\n\n  [listing]\n  --\n  Lorum ipsum ...\n  --\n\n  ---------------\n  Lorum ipsum ...\n  ---------------\n\n- An unstyled open block groups section elements but otherwise does\n  nothing.\n\nOpen blocks are used to generate document abstracts and book part\nintroductions:\n\n- Apply the 'abstract' style to generate an abstract, for example:\n\n  [abstract]\n  --\n  In this paper we will ...\n  --\n\n. Apply the 'partintro' style to generate a book part introduction for\n  a multi-part book, for example:\n\n  [partintro]\n  .Optional part introduction title\n  --\n  Optional part introduction goes here.\n  --\n\n\n[[X64]]\nLists\n-----\n.List types\n- Bulleted lists. Also known as itemized or unordered lists.\n- Numbered lists. Also called ordered lists.\n- Labeled lists. Sometimes called variable or definition lists.\n- Callout lists (a list of callout annotations).\n\n.List behavior\n- List item indentation is optional and does not determine nesting,\n  indentation does however make the source more readable.\n- Another list or a literal paragraph immediately following a list\n  item will be implicitly included in the list item; use <<X15, list\n  item continuation>> to explicitly append other block elements to a\n  list item.\n- A comment block or a comment line block macro element will terminate\n  a list -- use inline comment lines to put comments inside lists.\n- The `listindex` <<X60,intrinsic attribute>> is the current list item\n  index (1..). If this attribute is used outside a list then it's value\n  is the number of items in the most recently closed list. Useful for\n  displaying the number of items in a list.\n\nBulleted Lists\n~~~~~~~~~~~~~~\nBulleted list items start with a single dash or one to five asterisks\nfollowed by some white space then some text. Bulleted list syntaxes\nare:\n\n...................\n- List item.\n* List item.\n** List item.\n*** List item.\n**** List item.\n***** List item.\n...................\n\nNumbered Lists\n~~~~~~~~~~~~~~\nList item numbers are explicit or implicit.\n\n.Explicit numbering\nList items begin with a number followed by some white space then the\nitem text. The numbers can be decimal (arabic), roman (upper or lower\ncase) or alpha (upper or lower case). Decimal and alpha numbers are\nterminated with a period, roman numbers are terminated with a closing\nparenthesis. The different terminators are necessary to ensure 'i',\n'v' and 'x' roman numbers are are distinguishable from 'x', 'v' and\n'x' alpha numbers. Examples:\n\n.....................................................................\n1.   Arabic (decimal) numbered list item.\na.   Lower case alpha (letter) numbered list item.\nF.   Upper case alpha (letter) numbered list item.\niii) Lower case roman numbered list item.\nIX)  Upper case roman numbered list item.\n.....................................................................\n\n.Implicit numbering\nList items begin one to five period characters, followed by some white\nspace then the item text. Examples:\n\n.....................................................................\n. Arabic (decimal) numbered list item.\n.. Lower case alpha (letter) numbered list item.\n... Lower case roman numbered list item.\n.... Upper case alpha (letter) numbered list item.\n..... Upper case roman numbered list item.\n.....................................................................\n\nYou can use the 'style' attribute (also the first positional\nattribute) to specify an alternative numbering style.  The numbered\nlist style can be one of the following values: 'arabic', 'loweralpha',\n'upperalpha', 'lowerroman', 'upperroman'.\n\nHere are some examples of bulleted and numbered lists:\n\n---------------------------------------------------------------------\n- Praesent eget purus quis magna eleifend eleifend.\n  1. Fusce euismod commodo velit.\n    a. Fusce euismod commodo velit.\n    b. Vivamus fringilla mi eu lacus.\n    c. Donec eget arcu bibendum nunc consequat lobortis.\n  2. Vivamus fringilla mi eu lacus.\n    i)  Fusce euismod commodo velit.\n    ii) Vivamus fringilla mi eu lacus.\n  3. Donec eget arcu bibendum nunc consequat lobortis.\n  4. Nam fermentum mattis ante.\n- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n  * Fusce euismod commodo velit.\n  ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis\n     adolescens. Sit munere ponderum dignissim et. Minim luptatum et\n     vel.\n  ** Vivamus fringilla mi eu lacus.\n  * Donec eget arcu bibendum nunc consequat lobortis.\n- Nulla porttitor vulputate libero.\n  . Fusce euismod commodo velit.\n  . Vivamus fringilla mi eu lacus.\n[upperroman]\n    .. Fusce euismod commodo velit.\n    .. Vivamus fringilla mi eu lacus.\n  . Donec eget arcu bibendum nunc consequat lobortis.\n---------------------------------------------------------------------\n\nWhich render as:\n\n- Praesent eget purus quis magna eleifend eleifend.\n  1. Fusce euismod commodo velit.\n    a. Fusce euismod commodo velit.\n    b. Vivamus fringilla mi eu lacus.\n    c. Donec eget arcu bibendum nunc consequat lobortis.\n  2. Vivamus fringilla mi eu lacus.\n    i)  Fusce euismod commodo velit.\n    ii) Vivamus fringilla mi eu lacus.\n  3. Donec eget arcu bibendum nunc consequat lobortis.\n  4. Nam fermentum mattis ante.\n- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n  * Fusce euismod commodo velit.\n  ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis\n     adolescens. Sit munere ponderum dignissim et. Minim luptatum et\n     vel.\n  ** Vivamus fringilla mi eu lacus.\n  * Donec eget arcu bibendum nunc consequat lobortis.\n- Nulla porttitor vulputate libero.\n  . Fusce euismod commodo velit.\n  . Vivamus fringilla mi eu lacus.\n[upperroman]\n    .. Fusce euismod commodo velit.\n    .. Vivamus fringilla mi eu lacus.\n  . Donec eget arcu bibendum nunc consequat lobortis.\n\nA predefined 'compact' option is available to bulleted and numbered\nlists -- this translates to the DocBook 'spacing=\"compact\"' lists\nattribute which may or may not be processed by the DocBook toolchain.\nExample:\n\n  [options=\"compact\"]\n  - Compact list item.\n  - Another compact list item.\n\nTIP: To apply the 'compact' option globally define a document-wide\n'compact-option' attribute, e.g. using the `-a compact-option`\ncommand-line option.\n\nYou can set the list start number using the 'start' attribute (works\nfor HTML outputs and DocBook outputs processed by DocBook XSL\nStylesheets). Example:\n\n  [start=7]\n  . List item 7.\n  . List item 8.\n\nLabeled Lists\n~~~~~~~~~~~~~\nLabeled list items consist of one or more text labels followed by the\ntext of the list item.\n\nAn item label begins a line with an alphanumeric character hard\nagainst the left margin and ends with two, three or four colons or two\nsemi-colons. A list item can have multiple labels, one per line.\n\nThe list item text consists of one or more lines of text starting\nafter the last label (either on the same line or a new line) and can\nbe followed by nested List or ListParagraph elements. Item text can be\noptionally indented.\n\nHere are some examples:\n\n---------------------------------------------------------------------\nIn::\nLorem::\n  Fusce euismod commodo velit.\n\n  Fusce euismod commodo velit.\n\nIpsum:: Vivamus fringilla mi eu lacus.\n  * Vivamus fringilla mi eu lacus.\n  * Donec eget arcu bibendum nunc consequat lobortis.\nDolor::\n  Donec eget arcu bibendum nunc consequat lobortis.\n  Suspendisse;;\n    A massa id sem aliquam auctor.\n  Morbi;;\n    Pretium nulla vel lorem.\n  In;;\n    Dictum mauris in urna.\n    Vivamus::: Fringilla mi eu lacus.\n    Donec:::   Eget arcu bibendum nunc consequat lobortis.\n---------------------------------------------------------------------\n\nWhich render as:\n\nIn::\nLorem::\n  Fusce euismod commodo velit.\n\n  Fusce euismod commodo velit.\n\nIpsum:: Vivamus fringilla mi eu lacus.\n  * Vivamus fringilla mi eu lacus.\n  * Donec eget arcu bibendum nunc consequat lobortis.\nDolor::\n  Donec eget arcu bibendum nunc consequat lobortis.\n  Suspendisse;;\n    A massa id sem aliquam auctor.\n  Morbi;;\n    Pretium nulla vel lorem.\n  In;;\n    Dictum mauris in urna.\n    Vivamus::: Fringilla mi eu lacus.\n    Donec:::   Eget arcu bibendum nunc consequat lobortis.\n\nHorizontal labeled list style\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThe 'horizontal' labeled list style (also the first positional\nattribute) places the list text side-by-side with the label instead of\nunder the label. Here is an example:\n\n---------------------------------------------------------------------\n[horizontal]\n*Lorem*:: Fusce euismod commodo velit.  Qui in magna commodo, est\nlabitur dolorum an. Est ne magna primis adolescens.\n\n  Fusce euismod commodo velit.\n\n*Ipsum*:: Vivamus fringilla mi eu lacus.\n- Vivamus fringilla mi eu lacus.\n- Donec eget arcu bibendum nunc consequat lobortis.\n\n*Dolor*::\n  - Vivamus fringilla mi eu lacus.\n  - Donec eget arcu bibendum nunc consequat lobortis.\n\n---------------------------------------------------------------------\n\nWhich render as:\n\n[horizontal]\n*Lorem*:: Fusce euismod commodo velit.  Qui in magna commodo, est\nlabitur dolorum an. Est ne magna primis adolescens.\n\n  Fusce euismod commodo velit.\n\n*Ipsum*:: Vivamus fringilla mi eu lacus.\n- Vivamus fringilla mi eu lacus.\n- Donec eget arcu bibendum nunc consequat lobortis.\n\n*Dolor*::\n  - Vivamus fringilla mi eu lacus.\n  - Donec eget arcu bibendum nunc consequat lobortis.\n\n[NOTE]\n=====================================================================\n- Current PDF toolchains do not make a good job of determining\n  the relative column widths for horizontal labeled lists.\n- Nested horizontal labeled lists will generate DocBook validation\n  errors because the 'DocBook XML V4.2' DTD does not permit nested\n  informal tables (although <<X13,DocBook XSL Stylesheets>> and\n  <<X31,dblatex>> process them correctly).\n- The label width can be set as a percentage of the total width by\n  setting the 'width' attribute e.g. `width=\"10%\"`\n=====================================================================\n\nQuestion and Answer Lists\n~~~~~~~~~~~~~~~~~~~~~~~~~\nAsciiDoc comes pre-configured with a 'qanda' style labeled list for generating\nDocBook question and answer (Q&A) lists. Example:\n\n---------------------------------------------------------------------\n[qanda]\nQuestion one::\n        Answer one.\nQuestion two::\n        Answer two.\n---------------------------------------------------------------------\n\nRenders:\n\n[qanda]\nQuestion one::\n        Answer one.\nQuestion two::\n        Answer two.\n\nGlossary Lists\n~~~~~~~~~~~~~~\nAsciiDoc comes pre-configured with a 'glossary' style labeled list for\ngenerating DocBook glossary lists. Example:\n\n---------------------------------------------------------------------\n[glossary]\nA glossary term::\n    The corresponding definition.\nA second glossary term::\n    The corresponding definition.\n---------------------------------------------------------------------\n\nFor working examples see the `article.txt` and `book.txt` documents in\nthe AsciiDoc `./doc` distribution directory.\n\nNOTE: To generate valid DocBook output glossary lists must be located\nin a section that uses the 'glossary' <<X93,section markup template>>.\n\nBibliography Lists\n~~~~~~~~~~~~~~~~~~\nAsciiDoc comes with a predefined 'bibliography' bulleted list style\ngenerating DocBook bibliography entries. Example:\n\n---------------------------------------------------------------------\n[bibliography]\n.Optional list title\n- [[[taoup]]] Eric Steven Raymond. 'The Art of UNIX\n  Programming'. Addison-Wesley. ISBN 0-13-142901-9.\n- [[[walsh-muellner]]] Norman Walsh & Leonard Muellner.\n  'DocBook - The Definitive Guide'. O'Reilly & Associates.\n  1999. ISBN 1-56592-580-7.\n---------------------------------------------------------------------\n\nThe `[[[<reference>]]]` syntax is a bibliography entry anchor, it\ngenerates an anchor named `<reference>` and additionally displays\n`[<reference>]` at the anchor position. For example `[[[taoup]]]`\ngenerates an anchor named `taoup` that displays `[taoup]` at the\nanchor position. Cite the reference from elsewhere your document using\n`<<taoup>>`, this displays a hyperlink (`[taoup]`) to the\ncorresponding bibliography entry anchor.\n\nFor working examples see the `article.txt` and `book.txt` documents in\nthe AsciiDoc `./doc` distribution directory.\n\nNOTE: To generate valid DocBook output bibliography lists must be\nlocated in a <<X93,bibliography section>>.\n\n[[X15]]\nList Item Continuation\n~~~~~~~~~~~~~~~~~~~~~~\nAnother list or a literal paragraph immediately following a list item\nis implicitly appended to the list item; to append other block\nelements to a list item you need to explicitly join them to the list\nitem with a 'list continuation' (a separator line containing a single\nplus character). Multiple block elements can be appended to a list\nitem using list continuations (provided they are legal list item\nchildren in the backend markup).\n\nHere are some examples of list item continuations: list item one\ncontains multiple continuations; list item two is continued with an\n<<X29,OpenBlock>> containing multiple elements:\n\n---------------------------------------------------------------------\n1. List item one.\n+\nList item one continued with a second paragraph followed by an\nIndented block.\n+\n.................\n$ ls *.sh\n$ mv *.sh ~/tmp\n.................\n+\nList item continued with a third paragraph.\n\n2. List item two continued with an open block.\n+\n--\nThis paragraph is part of the preceding list item.\n\na. This list is nested and does not require explicit item continuation.\n+\nThis paragraph is part of the preceding list item.\n\nb. List item b.\n\nThis paragraph belongs to item two of the outer list.\n--\n---------------------------------------------------------------------\n\nRenders:\n\n1. List item one.\n+\nList item one continued with a second paragraph followed by an\nIndented block.\n+\n.................\n$ ls *.sh\n$ mv *.sh ~/tmp\n.................\n+\nList item continued with a third paragraph.\n\n2. List item two continued with an open block.\n+\n--\nThis paragraph is part of the preceding list item.\n\na. This list is nested and does not require explicit item continuation.\n+\nThis paragraph is part of the preceding list item.\n\nb. List item b.\n\nThis paragraph belongs to item two of the outer list.\n--\n\n\n[[X92]]\nFootnotes\n---------\nThe shipped AsciiDoc configuration includes three footnote inline\nmacros:\n\n`footnote:[<text>]`::\n  Generates a footnote with text `<text>`.\n\n`footnoteref:[<id>,<text>]`::\n  Generates a footnote with a reference ID `<id>` and text `<text>`.\n\n`footnoteref:[<id>]`::\n  Generates a reference to the footnote with ID `<id>`.\n\nThe footnote text can span multiple lines.\n\nThe 'xhtml11' and 'html5' backends render footnotes dynamically using\nJavaScript; 'html4' outputs do not use JavaScript and leave the\nfootnotes inline; 'docbook' footnotes are processed by the downstream\nDocBook toolchain.\n\nExample footnotes:\n\n  A footnote footnote:[An example footnote.];\n  a second footnote with a reference ID footnoteref:[note2,Second footnote.];\n  finally a reference to the second footnote footnoteref:[note2].\n\nRenders:\n\nA footnote footnote:[An example footnote.];\na second footnote with a reference ID footnoteref:[note2,Second footnote.];\nfinally a reference to the second footnote footnoteref:[note2].\n\n\nIndexes\n-------\nThe shipped AsciiDoc configuration includes the inline macros for\ngenerating DocBook index entries.\n\n`indexterm:[<primary>,<secondary>,<tertiary>]`::\n`(((<primary>,<secondary>,<tertiary>)))`::\n    This inline macro generates an index term (the `<secondary>` and\n    `<tertiary>` positional attributes are optional). Example:\n    `indexterm:[Tigers,Big cats]` (or, using the alternative syntax\n    `(((Tigers,Big cats)))`.  Index terms that have secondary and\n    tertiary entries also generate separate index terms for the\n    secondary and tertiary entries. The index terms appear in the\n    index, not the primary text flow.\n\n`indexterm2:[<primary>]`::\n`((<primary>))`::\n    This inline macro generates an index term that appears in both the\n    index and the primary text flow.  The `<primary>` should not be\n    padded to the left or right with white space characters.\n\nFor working examples see the `article.txt` and `book.txt` documents in\nthe AsciiDoc `./doc` distribution directory.\n\nNOTE: Index entries only really make sense if you are generating\nDocBook markup -- DocBook conversion programs automatically generate\nan index at the point an 'Index' section appears in source document.\n\n\n[[X105]]\nCallouts\n--------\nCallouts are a mechanism for annotating verbatim text (for example:\nsource code, computer output and user input). Callout markers are\nplaced inside the annotated text while the actual annotations are\npresented in a callout list after the annotated text. Here's an\nexample:\n\n---------------------------------------------------------------------\n .MS-DOS directory listing\n -----------------------------------------------------\n 10/17/97   9:04         <DIR>    bin\n 10/16/97  14:11         <DIR>    DOS            \\<1>\n 10/16/97  14:40         <DIR>    Program Files\n 10/16/97  14:46         <DIR>    TEMP\n 10/17/97   9:04         <DIR>    tmp\n 10/16/97  14:37         <DIR>    WINNT\n 10/16/97  14:25             119  AUTOEXEC.BAT   \\<2>\n  2/13/94   6:21          54,619  COMMAND.COM    \\<2>\n 10/16/97  14:25             115  CONFIG.SYS     \\<2>\n 11/16/97  17:17      61,865,984  pagefile.sys\n  2/13/94   6:21           9,349  WINA20.386     \\<3>\n -----------------------------------------------------\n\n \\<1> This directory holds MS-DOS.\n \\<2> System startup code for DOS.\n \\<3> Some sort of Windows 3.1 hack.\n---------------------------------------------------------------------\n\nWhich renders:\n\n.MS-DOS directory listing\n-----------------------------------------------------\n10/17/97   9:04         <DIR>    bin\n10/16/97  14:11         <DIR>    DOS            <1>\n10/16/97  14:40         <DIR>    Program Files\n10/16/97  14:46         <DIR>    TEMP\n10/17/97   9:04         <DIR>    tmp\n10/16/97  14:37         <DIR>    WINNT\n10/16/97  14:25             119  AUTOEXEC.BAT   <2>\n 2/13/94   6:21          54,619  COMMAND.COM    <2>\n10/16/97  14:25             115  CONFIG.SYS     <2>\n11/16/97  17:17      61,865,984  pagefile.sys\n 2/13/94   6:21           9,349  WINA20.386     <3>\n-----------------------------------------------------\n\n<1> This directory holds MS-DOS.\n<2> System startup code for DOS.\n<3> Some sort of Windows 3.1 hack.\n\n.Explanation\n- The callout marks are whole numbers enclosed in angle brackets --\n  they refer to the correspondingly numbered item in the following\n  callout list.\n- By default callout marks are confined to 'LiteralParagraphs',\n  'LiteralBlocks' and 'ListingBlocks' (although this is a\n  configuration file option and can be changed).\n- Callout list item numbering is fairly relaxed -- list items can\n  start with `<n>`, `n>` or `>` where `n` is the optional list item\n  number (in the latter case list items starting with a single `>`\n  character are implicitly numbered starting at one).\n- Callout lists should not be nested.\n- Callout lists start list items hard against the left margin.\n- If you want to present a number inside angle brackets you'll need to\n  escape it with a backslash to prevent it being interpreted as a\n  callout mark.\n\nNOTE: Define the AsciiDoc 'icons' attribute (for example using the `-a\nicons` command-line option) to display callout icons.\n\nImplementation Notes\n~~~~~~~~~~~~~~~~~~~~\nCallout marks are generated by the 'callout' inline macro while\ncallout lists are generated using the 'callout' list definition. The\n'callout' macro and 'callout' list are special in that they work\ntogether. The 'callout' inline macro is not enabled by the normal\n'macros' substitutions option, instead it has its own 'callouts'\nsubstitution option.\n\nThe following attributes are available during inline callout macro\nsubstitution:\n\n`{index}`::\n    The callout list item index inside the angle brackets.\n`{coid}`::\n    An identifier formatted like `CO<listnumber>-<index>` that\n    uniquely identifies the callout mark. For example `CO2-4`\n    identifies the fourth callout mark in the second set of callout\n    marks.\n\nThe `{coids}` attribute can be used during callout list item\nsubstitution -- it is a space delimited list of callout IDs that refer\nto the explanatory list item.\n\nIncluding callouts in included code\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou can annotate working code examples with callouts -- just remember\nto put the callouts inside source code comments. This example displays\nthe `test.py` source file (containing a single callout) using the\n'source' (code highlighter) filter:\n\n.AsciiDoc source\n---------------------------------------------------------------------\n [source,python]\n -------------------------------------------\n \\include::test.py[]\n -------------------------------------------\n\n \\<1> Print statement.\n---------------------------------------------------------------------\n\n.Included `test.py` source\n---------------------------------------------------------------------\nprint 'Hello World!'   # \\<1>\n---------------------------------------------------------------------\n\n\nMacros\n------\nMacros are a mechanism for substituting parametrized text into output\ndocuments.\n\nMacros have a 'name', a single 'target' argument and an 'attribute\nlist'.  The usual syntax is `<name>:<target>[<attrlist>]` (for\ninline macros) and `<name>::<target>[<attrlist>]` (for block\nmacros).  Here are some examples:\n\n  http://www.docbook.org/[DocBook.org]\n  include::chapt1.txt[tabsize=2]\n  mailto:srackham@gmail.com[]\n\n.Macro behavior\n- `<name>` is the macro name. It can only contain letters, digits or\n  dash characters and cannot start with a dash.\n- The optional `<target>` cannot contain white space characters.\n- `<attrlist>` is a <<X21,list of attributes>> enclosed in square\n  brackets.\n- `]` characters inside attribute lists must be escaped with a\n  backslash.\n- Expansion of macro references can normally be escaped by prefixing a\n  backslash character (see the AsciiDoc 'FAQ' for examples of\n  exceptions to this rule).\n- Attribute references in block macros are expanded.\n- The substitutions performed prior to Inline macro macro expansion\n  are determined by the inline context.\n- Macros are processed in the order they appear in the configuration\n  file(s).\n- Calls to inline macros can be nested inside different inline macros\n  (an inline macro call cannot contain a nested call to itself).\n- In addition to `<name>`, `<target>` and `<attrlist>` the\n  `<passtext>` and `<subslist>` named groups are available to\n  <<X77,passthrough macros>>. A macro is a passthrough macro if the\n  definition includes a `<passtext>` named group.\n\nInline Macros\n~~~~~~~~~~~~~\nInline Macros occur in an inline element context. Predefined Inline\nmacros include 'URLs', 'image' and 'link' macros.\n\nURLs\n^^^^\n'http', 'https', 'ftp', 'file', 'mailto' and 'callto' URLs are\nrendered using predefined inline macros.\n\n- If you don't need a custom link caption you can enter the 'http',\n  'https', 'ftp', 'file' URLs and email addresses without any special\n  macro syntax.\n- If the `<attrlist>` is empty the URL is displayed.\n\nHere are some examples:\n\n  http://www.docbook.org/[DocBook.org]\n  http://www.docbook.org/\n  mailto:joe.bloggs@foobar.com[email Joe Bloggs]\n  joe.bloggs@foobar.com\n\nWhich are rendered:\n\nhttp://www.docbook.org/[DocBook.org]\n\nhttp://www.docbook.org/\n\nmailto:joe.bloggs@foobar.com[email Joe Bloggs]\n\njoe.bloggs@foobar.com\n\nIf the `<target>` necessitates space characters use `%20`, for example\n`large%20image.png`.\n\nInternal Cross References\n^^^^^^^^^^^^^^^^^^^^^^^^^\nTwo AsciiDoc inline macros are provided for creating hypertext links\nwithin an AsciiDoc document. You can use either the standard macro\nsyntax or the (preferred) alternative.\n\n[[X30]]\nanchor\n++++++\nUsed to specify hypertext link targets:\n\n  [[<id>,<xreflabel>]]\n  anchor:<id>[<xreflabel>]\n\nThe `<id>` is a unique string that conforms to the output markup's\nanchor syntax. The optional `<xreflabel>` is the text to be displayed\nby captionless 'xref' macros that refer to this anchor. The optional\n`<xreflabel>` is only really useful when generating DocBook output.\nExample anchor:\n\n  [[X1]]\n\nYou may have noticed that the syntax of this inline element is the\nsame as that of the <<X41,BlockId block element>>, this is no\ncoincidence since they are functionally equivalent.\n\nxref\n++++\nCreates a hypertext link to a document anchor.\n\n  <<<id>,<caption>>>\n  xref:<id>[<caption>]\n\nThe `<id>` refers to an anchor ID. The optional `<caption>` is the\nlink's displayed text. Example:\n\n  <<X21,attribute lists>>\n\nIf `<caption>` is not specified then the displayed text is\nauto-generated:\n\n- The AsciiDoc 'xhtml11' and 'html5' backends display the `<id>`\n  enclosed in square brackets.\n- If DocBook is produced the DocBook toolchain is responsible for the\n  displayed text which will normally be the referenced figure, table\n  or section title number followed by the element's title text.\n\nHere is an example:\n\n---------------------------------------------------------------------\n[[tiger_image]]\n.Tyger tyger\nimage::tiger.png[]\n\nThis can be seen in <<tiger_image>>.\n---------------------------------------------------------------------\n\nLinking to Local Documents\n^^^^^^^^^^^^^^^^^^^^^^^^^^\nHypertext links to files on the local file system are specified using\nthe 'link' inline macro.\n\n  link:<target>[<caption>]\n\nThe 'link' macro generates relative URLs. The link macro `<target>` is\nthe target file name (relative to the file system location of the\nreferring document). The optional `<caption>` is the link's displayed\ntext. If `<caption>` is not specified then `<target>` is displayed.\nExample:\n\n  link:downloads/foo.zip[download foo.zip]\n\nYou can use the `<filename>#<id>` syntax to refer to an anchor within\na target document but this usually only makes sense when targeting\nHTML documents.\n\n[[X9]]\nImages\n^^^^^^\nInline images are inserted into the output document using the 'image'\nmacro. The inline syntax is:\n\n  image:<target>[<attributes>]\n\nThe contents of the image file `<target>` is displayed. To display the\nimage its file format must be supported by the target backend\napplication. HTML and DocBook applications normally support PNG or JPG\nfiles.\n\n`<target>` file name paths are relative to the location of the\nreferring document.\n\n[[X55]]\n.Image macro attributes\n- The optional 'alt' attribute is also the first positional attribute,\n  it specifies alternative text which is displayed if the output\n  application is unable to display the image file (see also\n  http://htmlhelp.com/feature/art3.htm[Use of ALT texts in IMGs]). For\n  example:\n\n  image:images/logo.png[Company Logo]\n\n- The optional 'title' attribute provides a title for the image. The\n  <<X49,block image macro>> renders the title alongside the image.\n  The inline image macro displays the title as a popup ``tooltip'' in\n  visual browsers (AsciiDoc HTML outputs only).\n\n- The optional `width` and `height` attributes scale the image size\n  and can be used in any combination. The units are pixels.  The\n  following example scales the previous example to a height of 32\n  pixels:\n\n  image:images/logo.png[\"Company Logo\",height=32]\n\n- The optional `link` attribute is used to link the image to an\n  external document. The following example links a screenshot\n  thumbnail to a full size version:\n\n  image:screen-thumbnail.png[height=32,link=\"screen.png\"]\n\n- The optional `scaledwidth` attribute is only used in DocBook block\n  images (specifically for PDF documents). The following example\n  scales the images to 75% of the available print width:\n\n  image::images/logo.png[scaledwidth=\"75%\",alt=\"Company Logo\"]\n\n- The image `scale` attribute sets the DocBook `imagedata` element\n  `scale` attribute.\n\n- The optional `align` attribute is used for horizontal image\n  alignment.  Allowed values are `center`, `left` and `right`. For\n  example:\n\n  image::images/tiger.png[\"Tiger image\",align=\"left\"]\n\n- The optional `float` attribute floats the image `left` or `right` on\n  the page (works with HTML outputs only, has no effect on DocBook\n  outputs). `float` and `align` attributes are mutually exclusive.\n  Use the `unfloat::[]` block macro to stop floating.\n\nComment Lines\n^^^^^^^^^^^^^\nSee <<X25,comment block macro>>.\n\nBlock Macros\n~~~~~~~~~~~~\nA Block macro reference must be contained in a single line separated\neither side by a blank line or a block delimiter.\n\nBlock macros behave just like Inline macros, with the following\ndifferences:\n\n- They occur in a block context.\n- The default syntax is `<name>::<target>[<attrlist>]` (two\n  colons, not one).\n- Markup template section names end in `-blockmacro` instead of\n  `-inlinemacro`.\n\nBlock Identifier\n^^^^^^^^^^^^^^^^\nThe Block Identifier macro sets the `id` attribute and has the same\nsyntax as the <<X30,anchor inline macro>> since it performs\nessentially the same function -- block templates use the `id`\nattribute as a block element ID. For example:\n\n  [[X30]]\n\nThis is equivalent to the `[id=\"X30\"]` <<X79,AttributeList element>>).\n\n[[X49]]\nImages\n^^^^^^\nThe 'image' block macro is used to display images in a block context.\nThe syntax is:\n\n  image::<target>[<attributes>]\n\nThe block `image` macro has the same <<X55,macro attributes>> as it's\n<<X9,inline image macro>> counterpart.\n\nBlock images can be titled by preceding the 'image' macro with a\n'BlockTitle'.  DocBook toolchains normally number titled block images\nand optionally list them in an automatically generated 'List of\nFigures' backmatter section.\n\nThis example:\n\n  .Main circuit board\n  image::images/layout.png[J14P main circuit board]\n\nis equivalent to:\n\n  image::images/layout.png[\"J14P main circuit board\",\n                            title=\"Main circuit board\"]\n\nA title prefix that can be inserted with the `caption` attribute\n(HTML backends). For example:\n\n  .Main circuit board\n  [caption=\"Figure 2: \"]\n  image::images/layout.png[J14P main circuit board]\n\n[[X66]]\n.Embedding images in XHTML documents\n*********************************************************************\nIf you define the `data-uri` attribute then images will be embedded in\nXHTML outputs using the\nhttp://en.wikipedia.org/wiki/Data:_URI_scheme[data URI scheme].  You\ncan use the 'data-uri' attribute with the 'xhtml11' and 'html5'\nbackends to produce single-file XHTML documents with embedded images\nand CSS, for example:\n\n  $ asciidoc -a data-uri mydocument.txt\n\n[NOTE]\n======\n- All current popular browsers support data URIs, although versions\n  of Internet Explorer prior to version 8 do not.\n- Some browsers limit the size of data URIs.\n======\n*********************************************************************\n\n[[X25]]\nComment Lines\n^^^^^^^^^^^^^\nSingle lines starting with two forward slashes hard up against the\nleft margin are treated as comments. Comment lines do not appear in\nthe output unless the 'showcomments' attribute is defined.  Comment\nlines have been implemented as both block and inline macros so a\ncomment line can appear as a stand-alone block or within block elements\nthat support inline macro expansion. Example comment line:\n\n  // This is a comment.\n\nIf the 'showcomments' attribute is defined comment lines are written\nto the output:\n\n- In DocBook the comment lines are enclosed by the 'remark' element\n  (which may or may not be rendered by your toolchain).\n- The 'showcomments' attribute does not expose <<X26,Comment Blocks>>.\n  Comment Blocks are never passed to the output.\n\nSystem Macros\n~~~~~~~~~~~~~\nSystem macros are block macros that perform a predefined task and are\nhardwired into the asciidoc(1) program.\n\n- You can escape system macros with a leading backslash character\n  (as you can with other macros).\n- The syntax and tasks performed by system macros is built into\n  asciidoc(1) so they don't appear in configuration files.  You can\n  however customize the syntax by adding entries to a configuration\n  file `[macros]` section.\n\n[[X63]]\nInclude Macros\n^^^^^^^^^^^^^^\nThe `include` and `include1`  system macros to include the contents of\na named file into the source document.\n\nThe `include` macro includes a file as if it were part of the parent\ndocument -- tabs are expanded and system macros processed. The\ncontents of `include1` files are not subject to tab expansion or\nsystem macro processing nor are attribute or lower priority\nsubstitutions performed. The `include1` macro's intended use is to\ninclude verbatim embedded CSS or scripts into configuration file\nheaders.  Example:\n\n------------------------------------\n\\include::chapter1.txt[tabsize=4]\n------------------------------------\n\n.Include macro behavior\n- If the included file name is specified with a relative path then the\n  path is relative to the location of the referring document.\n- Include macros can appear inside configuration files.\n- Files included from within 'DelimitedBlocks' are read to completion\n  to avoid false end-of-block underline termination.\n- Attribute references are expanded inside the include 'target'; if an\n  attribute is undefined then the included file is silently skipped.\n- The 'tabsize' macro attribute sets the number of space characters to\n  be used for tab expansion in the included file (not applicable to\n  `include1` macro).\n- The 'depth' macro attribute sets the maximum permitted number of\n  subsequent nested includes (not applicable to `include1` macro which\n  does not process nested includes). Setting 'depth' to '1' disables\n  nesting inside the included file. By default, nesting is limited to\n  a depth of ten.\n- If the he 'warnings' attribute is set to 'False' (or any other\n  Python literal that evaluates to boolean false) then no warning\n  message is printed if the included file does not exist. By default\n  'warnings' are enabled.\n- Internally the `include1` macro is translated to the `include1`\n  system attribute which means it must be evaluated in a region where\n  attribute substitution is enabled. To inhibit nested substitution in\n  included files it is preferable to use the `include` macro and set\n  the attribute `depth=1`.\n\nConditional Inclusion Macros\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLines of text in the source document can be selectively included or\nexcluded from processing based on the existence (or not) of a document\nattribute.\n\nDocument text between the `ifdef` and `endif` macros is included if a\ndocument attribute is defined:\n\n  ifdef::<attribute>[]\n  :\n  endif::<attribute>[]\n\nDocument text between the `ifndef` and `endif` macros is not included\nif a document attribute is defined:\n\n  ifndef::<attribute>[]\n  :\n  endif::<attribute>[]\n\n`<attribute>` is an attribute name which is optional in the trailing\n`endif` macro.\n\nIf you only want to process a single line of text then the text can be\nput inside the square brackets and the `endif` macro omitted, for\nexample:\n\n  ifdef::revnumber[Version number 42]\n\nIs equivalent to:\n\n  ifdef::revnumber[]\n  Version number 42\n  endif::revnumber[]\n\n'ifdef' and 'ifndef' macros also accept multiple attribute names:\n\n- Multiple ',' separated attribute names evaluate to defined if one\n  or more of the attributes is defined, otherwise it's value is\n  undefined.\n- Multiple '+' separated attribute names evaluate to defined if all\n  of the attributes is defined, otherwise it's value is undefined.\n\nDocument text between the `ifeval` and `endif` macros is included if\nthe Python expression inside the square brackets is true. Example:\n\n  ifeval::[{rs458}==2]\n  :\n  endif::[]\n\n- Document attribute references are expanded before the expression is\n  evaluated.\n- If an attribute reference is undefined then the expression is\n  considered false.\n\nTake a look at the `*.conf` configuration files in the AsciiDoc\ndistribution for examples of conditional inclusion macro usage.\n\nExecutable system macros\n^^^^^^^^^^^^^^^^^^^^^^^^\nThe 'eval', 'sys' and 'sys2' block macros exhibit the same behavior as\ntheir same named <<X24, system attribute references>>. The difference\nis that system macros occur in a block macro context whereas system\nattributes are confined to inline contexts where attribute\nsubstitution is enabled.\n\nThe following example displays a long directory listing inside a\nliteral block:\n\n  ------------------\n  sys::[ls -l *.txt]\n  ------------------\n\nNOTE: There are no block macro versions of the 'eval3' and 'sys3'\nsystem attributes.\n\nTemplate System Macro\n^^^^^^^^^^^^^^^^^^^^^\nThe `template` block macro allows the inclusion of one configuration\nfile template section within another.  The following example includes\nthe `[admonitionblock]` section in the `[admonitionparagraph]`\nsection:\n\n  [admonitionparagraph]\n  template::[admonitionblock]\n\n.Template macro behavior\n- The `template::[]` macro is useful for factoring configuration file\n  markup.\n- `template::[]` macros cannot be nested.\n- `template::[]` macro expansion is applied after all configuration\n  files have been read.\n\n\n[[X77]]\nPassthrough macros\n~~~~~~~~~~~~~~~~~~\nPassthrough macros are analogous to <<X76,passthrough blocks>> and are\nused to pass text directly to the output. The substitution performed\non the text is determined by the macro definition but can be overridden\nby the `<subslist>`.  The usual syntax is\n`<name>:<subslist>[<passtext>]` (for inline macros) and\n`<name>::<subslist>[<passtext>]` (for block macros). Passthroughs, by\ndefinition, take precedence over all other text substitutions.\n\npass::\n  Inline and block. Passes text unmodified (apart from explicitly\n  specified substitutions). Examples:\n\n  pass:[<q>To be or not to be</q>]\n  pass:attributes,quotes[<u>the '{author}'</u>]\n\nasciimath, latexmath::\n  Inline and block. Passes text unmodified.  Used for\n  <<X78,mathematical formulas>>.\n\n\\+++::\n  Inline and block. The triple-plus passthrough is functionally\n  identical to the 'pass' macro but you don't have to escape `]`\n  characters and you can prefix with quoted attributes in the inline\n  version. Example:\n\n  Red [red]+++`sum_(i=1)\\^n i=(n(n+1))/2`$+++ AsciiMathML formula\n\n$$::\n  Inline and block. The double-dollar passthrough is functionally\n  identical to the triple-plus passthrough with one exception: special\n  characters are escaped. Example:\n\n  $$`[[a,b],[c,d]]((n),(k))`$$\n\n[[X80]]`::\n  Text quoted with single backtick characters constitutes an 'inline\n  literal' passthrough. The enclosed text is rendered in a monospaced\n  font and is only subject to special character substitution.  This\n  makes sense since monospace text is usually intended to be rendered\n  literally and often contains characters that would otherwise have to\n  be escaped. If you need monospaced text containing inline\n  substitutions use a <<X81,plus character instead of a backtick>>.\n\nMacro Definitions\n~~~~~~~~~~~~~~~~~\nEach entry in the configuration `[macros]` section is a macro\ndefinition which can take one of the following forms:\n\n`<pattern>=<name>[<subslist]`:: Inline macro definition.\n`<pattern>=#<name>[<subslist]`:: Block macro definition.\n`<pattern>=+<name>[<subslist]`:: System macro definition.\n`<pattern>`:: Delete the existing macro with this `<pattern>`.\n\n`<pattern>` is a Python regular expression and `<name>` is the name of\na markup template. If `<name>` is omitted then it is the value of the\nregular expression match group named 'name'.  The optional\n`[<subslist]` is a comma-separated list of substitution names enclosed\nin `[]` brackets, it sets the default substitutions for passthrough\ntext, if omitted then no passthrough substitutions are performed.\n\n.Pattern named groups\nThe following named groups can be used in macro `<pattern>` regular\nexpressions and are available as markup template attributes:\n\nname::\n  The macro name.\n\ntarget::\n  The macro target.\n\nattrlist::\n  The macro attribute list.\n\npasstext::\n  Contents of this group are passed unmodified to the output subject\n  only to 'subslist' substitutions.\n\nsubslist::\n  Processed as a comma-separated list of substitution names for\n  'passtext' substitution, overrides the the macro definition\n  'subslist'.\n\n.Here's what happens during macro substitution\n- Each contextually relevant macro 'pattern' from the `[macros]`\n  section is matched against the input source line.\n- If a match is found the text to be substituted is loaded from a\n  configuration markup template section named like\n  `<name>-inlinemacro` or `<name>-blockmacro` (depending on the macro\n  type).\n- Global and macro attribute list attributes are substituted in the\n  macro's markup template.\n- The substituted template replaces the macro reference in the output\n  document.\n\n\n[[X98]]\nHTML 5 audio and video block macros\n-----------------------------------\nThe 'html5' backend 'audio' and 'video' block macros generate the HTML\n5 'audio' and 'video' elements respectively.  They follow the usual\nAsciiDoc block macro syntax `<name>::<target>[<attrlist>]` where:\n\n[horizontal]\n`<name>`:: 'audio' or 'video'.\n`<target>`:: The URL or file name of the video or audio file.\n`<attrlist>`:: A list of named attributes (see below).\n\n.Audio macro attributes\n[options=\"header\",cols=\"1,5\",frame=\"topbot\"]\n|====================================================================\n|Name | Value\n|options\n|A comma separated list of one or more of the following items:\n'autoplay', 'loop' which correspond to the same-named HTML 5 'audio'\nelement boolean attributes.  By default the player 'controls' are\nenabled, include the 'nocontrols' option value to hide them.\n|====================================================================\n\n.Video macro attributes\n[options=\"header\",cols=\"1,5\",frame=\"topbot\"]\n|====================================================================\n|Name   | Value\n|height | The height of the player in pixels.\n|width  | The width of the player in pixels.\n|poster | The URL or file name of an image representing the video.\n|options\n|A comma separated list of one or more of the following items:\n'autoplay', 'loop' and 'nocontrols'. The 'autoplay' and 'loop' options\ncorrespond to the same-named HTML 5 'video' element boolean\nattributes.  By default the player 'controls' are enabled, include the\n'nocontrols' option value to hide them.\n|====================================================================\n\nExamples:\n\n---------------------------------------------------------------------\naudio::images/example.ogg[]\n\nvideo::gizmo.ogv[width=200,options=\"nocontrols,autoplay\"]\n\n.Example video\nvideo::gizmo.ogv[]\n\nvideo::http://www.808.dk/pics/video/gizmo.ogv[]\n---------------------------------------------------------------------\n\nIf your needs are more complex put raw HTML 5 in a markup block, for\nexample (from http://www.808.dk/?code-html-5-video):\n\n---------------------------------------------------------------------\n++++\n<video poster=\"pics/video/gizmo.jpg\" id=\"video\" style=\"cursor: pointer;\" >\n  <source src=\"pics/video/gizmo.mp4\" />\n  <source src=\"pics/video/gizmo.webm\" type=\"video/webm\" />\n  <source src=\"pics/video/gizmo.ogv\" type=\"video/ogg\" />\n  Video not playing? <a href=\"pics/video/gizmo.mp4\">Download file</a> instead.\n</video>\n\n<script type=\"text/javascript\">\n  var video = document.getElementById('video');\n  video.addEventListener('click',function(){\n    video.play();\n  },false);\n</script>\n++++\n---------------------------------------------------------------------\n\n\nTables\n------\nThe AsciiDoc table syntax looks and behaves like other delimited block\ntypes and supports standard <<X73,block configuration entries>>.\nFormatting is easy to read and, just as importantly, easy to enter.\n\n- Cells and columns can be formatted using built-in customizable styles.\n- Horizontal and vertical cell alignment can be set on columns and\n  cell.\n- Horizontal and vertical cell spanning is supported.\n\n.Use tables sparingly\n*********************************************************************\nWhen technical users first start creating documents, tables (complete\nwith column spanning and table nesting) are often considered very\nimportant. The reality is that tables are seldom used, even in\ntechnical documentation.\n\nTry this exercise: thumb through your library of technical books,\nyou'll be surprised just how seldom tables are actually used, even\nless seldom are tables containing block elements (such as paragraphs\nor lists) or spanned cells. This is no accident, like figures, tables\nare outside the normal document flow -- tables are for consulting not\nfor reading.\n\nTables are designed for, and should normally only be used for,\ndisplaying column oriented tabular data.\n*********************************************************************\n\nExample tables\n~~~~~~~~~~~~~~\n\n.Simple table\n[width=\"15%\"]\n|=======\n|1 |2 |A\n|3 |4 |B\n|5 |6 |C\n|=======\n\n.AsciiDoc source\n---------------------------------------------------------------------\n[width=\"15%\"]\n|=======\n|1 |2 |A\n|3 |4 |B\n|5 |6 |C\n|=======\n---------------------------------------------------------------------\n\n.Columns formatted with strong, monospaced and emphasis styles\n[width=\"50%\",cols=\">s,^m,e\",frame=\"topbot\",options=\"header,footer\"]\n|==========================\n|      2+|Columns 2 and 3\n|1       |Item 1  |Item 1\n|2       |Item 2  |Item 2\n|3       |Item 3  |Item 3\n|4       |Item 4  |Item 4\n|footer 1|footer 2|footer 3\n|==========================\n\n.AsciiDoc source\n---------------------------------------------------------------------\n.An example table\n[width=\"50%\",cols=\">s,^m,e\",frame=\"topbot\",options=\"header,footer\"]\n|==========================\n|      2+|Columns 2 and 3\n|1       |Item 1  |Item 1\n|2       |Item 2  |Item 2\n|3       |Item 3  |Item 3\n|4       |Item 4  |Item 4\n|footer 1|footer 2|footer 3\n|==========================\n---------------------------------------------------------------------\n\n.Horizontal and vertical source data\n[width=\"80%\",cols=\"3,^2,^2,10\",options=\"header\"]\n|=========================================================\n|Date |Duration |Avg HR |Notes\n\n|22-Aug-08 |10:24 | 157 |\nWorked out MSHR (max sustainable heart rate) by going hard\nfor this interval.\n\n|22-Aug-08 |23:03 | 152 |\nBack-to-back with previous interval.\n\n|24-Aug-08 |40:00 | 145 |\nModerately hard interspersed with 3x 3min intervals (2min\nhard + 1min really hard taking the HR up to 160).\n\n|=========================================================\n\nShort cells can be entered horizontally, longer cells vertically.  The\ndefault behavior is to strip leading and trailing blank lines within a\ncell. These characteristics aid readability and data entry.\n\n.AsciiDoc source\n---------------------------------------------------------------------\n.Windtrainer workouts\n[width=\"80%\",cols=\"3,^2,^2,10\",options=\"header\"]\n|=========================================================\n|Date |Duration |Avg HR |Notes\n\n|22-Aug-08 |10:24 | 157 |\nWorked out MSHR (max sustainable heart rate) by going hard\nfor this interval.\n\n|22-Aug-08 |23:03 | 152 |\nBack-to-back with previous interval.\n\n|24-Aug-08 |40:00 | 145 |\nModerately hard interspersed with 3x 3min intervals (2min\nhard + 1min really hard taking the HR up to 160).\n\n|=========================================================\n---------------------------------------------------------------------\n\n.A table with externally sourced CSV data\n[format=\"csv\",cols=\"^1,4*2\",options=\"header\"]\n|===================================================\nID,Customer Name,Contact Name,Customer Address,Phone\ninclude::customers.csv[]\n|===================================================\n\n.AsciiDoc source\n---------------------------------------------------------------------\n[format=\"csv\",cols=\"^1,4*2\",options=\"header\"]\n|===================================================\nID,Customer Name,Contact Name,Customer Address,Phone\n\\include::customers.csv[]\n|===================================================\n---------------------------------------------------------------------\n\n\n.Cell spans, alignments and styles\n[cols=\"e,m,^,>s\",width=\"25%\"]\n|============================\n|1 >s|2 |3 |4\n^|5 2.2+^.^|6 .3+<.>m|7\n^|8\n|9 2+>|10\n|============================\n\n.AsciiDoc source\n---------------------------------------------------------------------\n[cols=\"e,m,^,>s\",width=\"25%\"]\n|============================\n|1 >s|2 |3 |4\n^|5 2.2+^.^|6 .3+<.>m|7\n^|8\n|9 2+>|10\n|============================\n---------------------------------------------------------------------\n\n[[X68]]\nTable input data formats\n~~~~~~~~~~~~~~~~~~~~~~~~\nAsciiDoc table data can be 'psv', 'dsv' or 'csv' formatted.  The\ndefault table format is 'psv'.\n\nAsciiDoc 'psv' ('Prefix Separated Values') and 'dsv' ('Delimiter\nSeparated Values') formats are cell oriented -- the table is treated\nas a sequence of cells -- there are no explicit row separators.\n\n- 'psv' prefixes each cell with a separator whereas 'dsv' delimits\n  cells with a separator.\n- 'psv' and 'dsv' separators are Python regular expressions.\n- The default 'psv' separator contains <<X84, cell specifier>> related\n  named regular expression groups.\n- The default 'dsv' separator is `:|\\n` (a colon or a new line\n  character).\n- 'psv' and 'dsv' cell separators can be escaped by preceding them\n  with a backslash character.\n\nHere are four 'psv' cells (the second item spans two columns; the\nlast contains an escaped separator):\n\n  |One 2+|Two and three |A \\| separator character\n\n'csv'  is the quasi-standard row oriented 'Comma Separated Values\n(CSV)' format commonly used to import and export spreadsheet and\ndatabase data.\n\n[[X69]]\nTable attributes\n~~~~~~~~~~~~~~~~\nTables can be customized by the following attributes:\n\nformat::\n'psv' (default), 'dsv' or 'csv' (See <<X68, Table Data Formats>>).\n\nseparator::\nThe cell separator. A Python regular expression ('psv' and 'dsv'\nformats) or a single character ('csv' format).\n\nframe::\nDefines the table border and can take the following values: 'topbot'\n(top and bottom), 'all' (all sides), 'none' and 'sides' (left and\nright sides). The default value is 'all'.\n\ngrid::\nDefines which ruler lines are drawn between table rows and columns.\nThe 'grid' attribute value can be any of the following values: 'none',\n'cols', 'rows' and 'all'. The default value is 'all'.\n\nalign::\nUse the 'align' attribute to horizontally align the table on the\npage (works with HTML outputs only, has no effect on DocBook outputs).\nThe following values are valid: 'left', 'right', and 'center'.\n\nfloat::\nUse the 'float' attribute to float the table 'left' or 'right' on the\npage (works with HTML outputs only, has no effect on DocBook outputs).\nFloating only makes sense in conjunction with a table 'width'\nattribute value of less than 100% (otherwise the table will take up\nall the available space).  'float' and 'align' attributes are mutually\nexclusive.  Use the `unfloat::[]` block macro to stop floating.\n\nhalign::\nUse the 'halign' attribute to horizontally align all cells in a table.\nThe following values are valid: 'left', 'right', and 'center'\n(defaults to 'left'). Overridden by <<X70,Column specifiers>>  and\n<<X84,Cell specifiers>>.\n\nvalign::\nUse the 'valign' attribute to vertically align all cells in a table.\nThe following values are valid: 'top', 'bottom', and 'middle'\n(defaults to 'top'). Overridden by <<X70,Column specifiers>>  and\n<<X84,Cell specifiers>>.\n\noptions::\nThe 'options' attribute can contain comma separated values, for\nexample: 'header', 'footer'. By default header and footer rows are\nomitted.  See <<X74,attribute options>> for a complete list of\navailable table options.\n\ncols::\nThe 'cols' attribute is a comma separated list of <<X70,column\nspecifiers>>. For example `cols=\"2<p,2*,4p,>\"`.\n\n- If 'cols' is present it must specify all columns.\n- If the 'cols' attribute is not specified the number of columns is\n  calculated as the number of data items in the *first line* of the\n  table.\n- The degenerate form for the 'cols' attribute is an integer\n  specifying the number of columns e.g. `cols=4`.\n\nwidth::\nThe 'width' attribute is expressed as a percentage value\n('\"1%\"'...'\"99%\"'). The width specifies the table width relative to\nthe available width. HTML backends use this value to set the table\nwidth attribute. It's a bit more complicated with DocBook, see the\n<<X89,DocBook table widths>> sidebar.\n\nfilter::\nThe 'filter' attribute defines an external shell command that is\ninvoked for each cell. The built-in 'asciidoc' table style is\nimplemented using a filter.\n\n[[X89]]\n.DocBook table widths\n**********************************************************************\nThe AsciiDoc docbook backend generates CALS tables. CALS tables do not\nsupport a table width attribute -- table width can only be controlled\nby specifying absolute column widths.\n\nSpecifying absolute column widths is not media independent because\ndifferent presentation media have different physical dimensions. To\nget round this limitation both\nhttp://www.sagehill.net/docbookxsl/Tables.html#TableWidth[DocBook XSL\nStylesheets] and\nhttp://dblatex.sourceforge.net/doc/manual/ch03s05.html#sec-table-width[dblatex]\nhave implemented table width processing instructions for setting the\ntable width as a percentage of the available width. AsciiDoc emits\nthese processing instructions if the 'width' attribute is set along\nwith proportional column widths (the AsciiDoc docbook backend\n'pageunits' attribute defaults to '*').\n\nTo generate DocBook tables with absolute column widths set the\n'pageunits' attribute to a CALS absolute unit such as 'pt' and set the\n'pagewidth' attribute to match the width of the presentation media.\n**********************************************************************\n\n[[X70]]\nColumn Specifiers\n~~~~~~~~~~~~~~~~~\nColumn specifiers define how columns are rendered and appear in the\ntable <<X69,cols attribute>>.  A column specifier consists of an\noptional column multiplier followed by optional alignment, width and\nstyle values and is formatted like:\n\n  [<multiplier>*][<align>][<width>][<style>]\n\n- All components are optional. The multiplier must be first and the\n  style last. The order of `<align>` or `<width>` is not important.\n- Column `<width>` can be either an integer proportional value (1...)\n  or a percentage (1%...100%). The default value is 1. To ensure\n  portability across different backends, there is no provision for\n  absolute column widths (not to be confused with output column width\n  <<X72,markup attributes>> which are available in both percentage and\n  absolute units).\n- The '<align>' column alignment specifier is formatted like:\n\n  [<horizontal>][.<vertical>]\n+\nWhere `<horizontal>` and `<vertical>` are one of the following\ncharacters: `<`, `^` or `>` which represent 'left', 'center' and\n'right' horizontal alignment or 'top', 'middle' and 'bottom' vertical\nalignment respectively.\n\n- A `<multiplier>` can be used to specify repeated columns e.g.\n  `cols=\"4*<\"` specifies four left-justified columns. The default\n  multiplier value is 1.\n- The `<style>` name specifies a <<X71,table style>> to used to markup\n  column cells (you can use the full style names if you wish but the\n  first letter is normally sufficient).\n- Column specific styles are not applied to header rows.\n\n[[X84]]\nCell Specifiers\n~~~~~~~~~~~~~~~\nCell specifiers allow individual cells in 'psv' formatted tables to be\nspanned, multiplied, aligned and styled.  Cell specifiers prefix 'psv'\n`|` delimiters and are formatted like:\n\n  [<span>*|+][<align>][<style>]\n\n- '<span>' specifies horizontal and vertical cell spans ('+' operator) or\n  the number of times the cell is replicated ('*' operator). '<span>'\n  is formatted like:\n\n  [<colspan>][.<rowspan>]\n+\nWhere `<colspan>` and `<rowspan>` are integers specifying the number of\ncolumns and rows to span.\n\n- `<align>` specifies horizontal and vertical cell alignment an is the\n  same as in <<X70,column specifiers>>.\n- A `<style>` value is the first letter of <<X71,table style>> name.\n\nFor example, the following 'psv' formatted cell will span two columns\nand the text will be centered and emphasized:\n\n  `2+^e| Cell text`\n\n[[X71]]\nTable styles\n~~~~~~~~~~~~\nTable styles can be applied to the entire table (by setting the\n'style' attribute in the table's attribute list) or on a per column\nbasis (by specifying the style in the table's <<X69,cols attribute>>).\nTable data can be formatted using the following predefined styles:\n\ndefault::\nThe default style: AsciiDoc inline text formatting; blank lines are\ntreated as paragraph breaks.\n\nemphasis::\nLike default but all text is emphasised.\n\nmonospaced::\nLike default but all text is in a monospaced font.\n\nstrong::\nLike default but all text is bold.\n\nheader::\nApply the same style as the table header. Normally used to create a\nvertical header in the first column.\n\nasciidoc::\nWith this style table cells can contain any of the AsciiDoc elements\nthat are allowed inside document sections. This style runs asciidoc(1)\nas a filter to process cell contents. See also <<X83,Docbook table\nlimitations>>.\n\nliteral::\nNo text formatting; monospaced font; all line breaks are retained\n(the same as the AsciiDoc <<X65,LiteralBlock>> element).\n\nverse::\nAll line breaks are retained (just like the AsciiDoc <<X94,verse\nparagraph style>>).\n\n[[X72]]\nMarkup attributes\n~~~~~~~~~~~~~~~~~\nAsciiDoc makes a number of attributes available to table markup\ntemplates and tags. Column specific attributes are available when\nsubstituting the 'colspec' cell data tags.\n\npageunits::\nDocBook backend only. Specifies table column absolute width units.\nDefaults to '*'.\n\npagewidth::\nDocBook backend only. The nominal output page width in 'pageunit'\nunits. Used to calculate CALS tables absolute column and table\nwidths. Defaults to '425'.\n\ntableabswidth::\nInteger value calculated from 'width' and 'pagewidth' attributes.\nIn 'pageunit' units.\n\ntablepcwidth::\nTable width expressed as a percentage of the available width. Integer\nvalue (0..100).\n\ncolabswidth::\nInteger value calculated from 'cols' column width, 'width' and\n'pagewidth' attributes.  In 'pageunit' units.\n\ncolpcwidth::\nColumn width expressed as a percentage of the table width. Integer\nvalue (0..100).\n\ncolcount::\nTotal number of table columns.\n\nrowcount::\nTotal number of table rows.\n\nhalign::\nHorizontal cell content alignment: 'left', 'right' or 'center'.\n\nvalign::\nVertical cell content alignment: 'top', 'bottom' or 'middle'.\n\ncolnumber, colstart::\nThe number of the leftmost column occupied by the cell (1...).\n\ncolend::\nThe number of the rightmost column occupied by the cell (1...).\n\ncolspan::\nNumber of columns the cell should span.\n\nrowspan::\nNumber of rows the cell should span (1...).\n\nmorerows::\nNumber of additional rows the cell should span (0...).\n\nNested tables\n~~~~~~~~~~~~~\nAn alternative 'psv' separator character '!' can be used (instead of\n'|') in nested tables. This allows a single level of table nesting.\nColumns containing nested tables must use the 'asciidoc' style. An\nexample can be found in `./examples/website/newtables.txt`.\n\n[[X83]]\nDocBook table limitations\n~~~~~~~~~~~~~~~~~~~~~~~~~\nFully implementing tables is not trivial, some DocBook toolchains do\nbetter than others.  AsciiDoc HTML table outputs are rendered\ncorrectly in all the popular browsers -- if your DocBook generated\ntables don't look right compare them with the output generated by the\nAsciiDoc 'xhtml11' backend or try a different DocBook toolchain.  Here\nis a list of things to be aware of:\n\n- Although nested tables are not legal in DocBook 4 the FOP and\n  dblatex toolchains will process them correctly.  If you use `a2x(1)`\n  you will need to include the `--no-xmllint` option to suppress\n  DocBook validation errors.\n+\nNOTE: In theory you can nest DocBook 4 tables one level using the\n'entrytbl' element, but not all toolchains process 'entrytbl'.\n\n- DocBook only allows a subset of block elements inside table cells so\n  not all AsciiDoc elements produce valid DocBook inside table cells.\n  If you get validation errors running `a2x(1)` try the `--no-xmllint`\n  option, toolchains will often process nested block elements such as\n  sidebar blocks and floating titles correctly even though, strictly\n  speaking, they are not legal.\n\n- Text formatting in cells using the 'monospaced' table style will\n  raise validation errors because the DocBook 'literal' element was\n  not designed to support formatted text (using the 'literal' element\n  is a kludge on the part of AsciiDoc as there is no easy way to set\n  the font style in DocBook.\n\n- Cell alignments are ignored for 'verse', 'literal' or 'asciidoc'\n  table styles.\n\n\n[[X1]]\nManpage Documents\n-----------------\nSooner or later, if you program in a UNIX environment, you're going\nto have to write a man page.\n\nBy observing a couple of additional conventions (detailed below) you\ncan write AsciiDoc files that will generate HTML and PDF man pages\nplus the native manpage roff format.  The easiest way to generate roff\nmanpages from AsciiDoc source is to use the a2x(1) command. The\nfollowing example generates a roff formatted manpage file called\n`asciidoc.1` (a2x(1) uses asciidoc(1) to convert `asciidoc.1.txt` to\nDocBook which it then converts to roff using DocBook XSL Stylesheets):\n\n  a2x --doctype manpage --format manpage asciidoc.1.txt\n\n.Viewing and printing manpage files\n**********************************************************************\nUse the `man(1)` command to view the manpage file:\n\n  $ man -l asciidoc.1\n\nTo print a high quality man page to a postscript printer:\n\n  $ man -l -Tps asciidoc.1 | lpr\n\nYou could also create a PDF version of the man page by converting\nPostScript to PDF using `ps2pdf(1)`:\n\n  $ man -l -Tps asciidoc.1 | ps2pdf - asciidoc.1.pdf\n\nThe `ps2pdf(1)` command is included in the Ghostscript distribution.\n**********************************************************************\n\nTo find out more about man pages view the `man(7)` manpage\n(`man 7 man` and `man man-pages` commands).\n\n\nDocument Header\n~~~~~~~~~~~~~~~\nA manpage document Header is mandatory. The title line contains the\nman page name followed immediately by the manual section number in\nbrackets, for example 'ASCIIDOC(1)'. The title name should not contain\nwhite space and the manual section number is a single digit optionally\nfollowed by a single character.\n\nThe NAME Section\n~~~~~~~~~~~~~~~~\nThe first manpage section is mandatory, must be titled 'NAME' and must\ncontain a single paragraph (usually a single line) consisting of a\nlist of one or more comma separated command name(s) separated from the\ncommand purpose by a dash character. The dash must have at least one\nwhite space character on either side. For example:\n\n  printf, fprintf, sprintf - print formatted output\n\nThe SYNOPSIS Section\n~~~~~~~~~~~~~~~~~~~~\nThe second manpage section is mandatory and must be titled 'SYNOPSIS'.\n\nrefmiscinfo attributes\n~~~~~~~~~~~~~~~~~~~~~~\nIn addition to the automatically created man page <<X60,intrinsic\nattributes>> you can assign DocBook\nhttp://www.docbook.org/tdg5/en/html/refmiscinfo.html[refmiscinfo]\nelement 'source', 'version' and 'manual' values using AsciiDoc\n`{mansource}`, `{manversion}` and `{manmanual}` attributes\nrespectively. This example is from the AsciiDoc header of a man page\nsource file:\n\n  :man source:   AsciiDoc\n  :man version:  {revnumber}\n  :man manual:   AsciiDoc Manual\n\n\n[[X78]]\nMathematical Formulas\n---------------------\nThe 'asciimath' and 'latexmath' <<X77,passthrough macros>> along with\n'asciimath' and 'latexmath'  <<X76,passthrough blocks>> provide a\n(backend dependent) mechanism for rendering mathematical formulas. You\ncan use the following math markups:\n\nNOTE: The 'latexmath' macro used to include 'LaTeX Math' in DocBook\noutputs is not the same as the 'latexmath' macro used to include\n'LaTeX MathML' in XHTML outputs.  'LaTeX Math' applies to DocBook\noutputs that are processed by <<X31,dblatex>> and is normally used to\ngenerate PDF files.  'LaTeXMathML' is very much a subset of 'LaTeX\nMath' and applies to XHTML documents.\n\nLaTeX Math\n~~~~~~~~~~\nftp://ftp.ams.org/pub/tex/doc/amsmath/short-math-guide.pdf[LaTeX\nmath] can be included in documents that are processed by\n<<X31,dblatex(1)>>.  Example inline formula:\n\n  latexmath:[$C = \\alpha + \\beta Y^{\\gamma} + \\epsilon$]\n\nFor more examples see the {website}[AsciiDoc website] or the\ndistributed `doc/latexmath.txt` file.\n\nASCIIMathML\n~~~~~~~~~~~\n/////////////////////////////////////////////////////////////////////\nThe older ASCIIMathML 1.47 version is used instead of version 2\nbecause:\n\n1. Version 2 doesn't work when embedded.\n2. Version 2 is much larger.\n/////////////////////////////////////////////////////////////////////\n\nhttp://www1.chapman.edu/~jipsen/mathml/asciimath.html[ASCIIMathML]\nformulas can be included in XHTML documents generated using the\n'xhtml11' and 'html5' backends. To enable ASCIIMathML support you must\ndefine the 'asciimath' attribute, for example using the `-a asciimath`\ncommand-line option.  Example inline formula:\n\n  asciimath:[`x/x={(1,if x!=0),(text{undefined},if x=0):}`]\n\nFor more examples see the {website}[AsciiDoc website] or the\ndistributed `doc/asciimathml.txt` file.\n\nLaTeXMathML\n~~~~~~~~~~~\n/////////////////////////////////////////////////////////////////////\nThere is an http://math.etsu.edu/LaTeXMathML/[extended LaTeXMathML\nversion] by Jeff Knisley, in addition to a JavaScript file it requires\nthe inclusion of a CSS file.\n/////////////////////////////////////////////////////////////////////\n\n'LaTeXMathML' allows LaTeX Math style formulas to be included in XHTML\ndocuments generated using the AsciiDoc 'xhtml11' and 'html5' backends.\nAsciiDoc uses the\nhttp://www.maths.nottingham.ac.uk/personal/drw/lm.html[original\nLaTeXMathML] by Douglas Woodall.  'LaTeXMathML' is derived from\nASCIIMathML and is for users who are more familiar with or prefer\nusing LaTeX math formulas (it recognizes a subset of LaTeX Math, the\ndifferences are documented on the 'LaTeXMathML' web page).  To enable\nLaTeXMathML support you must define the 'latexmath' attribute, for\nexample using the `-a latexmath` command-line option.  Example inline\nformula:\n\n  latexmath:[$\\sum_{n=1}^\\infty \\frac{1}{2^n}$]\n\nFor more examples see the {website}[AsciiDoc website] or the\ndistributed `doc/latexmathml.txt` file.\n\nMathML\n~~~~~~\nhttp://www.w3.org/Math/[MathML] is a low level XML markup for\nmathematics. AsciiDoc has no macros for MathML but users familiar with\nthis markup could use passthrough macros and passthrough blocks to\ninclude MathML in output documents.\n\n\n[[X7]]\nConfiguration Files\n-------------------\nAsciiDoc source file syntax and output file markup is largely\ncontrolled by a set of cascading, text based, configuration files.  At\nruntime The AsciiDoc default configuration files are combined with\noptional user and document specific configuration files.\n\nConfiguration File Format\n~~~~~~~~~~~~~~~~~~~~~~~~~\nConfiguration files contain named sections. Each section begins with a\nsection name in square brackets []. The section body consists of the\nlines of text between adjacent section headings.\n\n- Section names consist of one or more alphanumeric, underscore or\n  dash characters and cannot begin or end with a dash.\n- Lines starting with a '#' character are treated as comments and\n  ignored.\n- If the section name is prefixed with a '+' character then the\n  section contents is appended to the contents of an already existing\n  same-named section.\n- Otherwise same-named sections and section entries override\n  previously loaded sections and section entries (this is sometimes\n  referred to as 'cascading').  Consequently, downstream configuration\n  files need only contain those sections and section entries that need\n  to be overridden.\n\nTIP: When creating custom configuration files you only need to include\nthe sections and entries that differ from the default configuration.\n\nTIP: The best way to learn about configuration files is to read the\ndefault configuration files in the AsciiDoc distribution in\nconjunction with asciidoc(1) output files. You can view configuration\nfile load sequence by turning on the asciidoc(1) `-v` (`--verbose`)\ncommand-line option.\n\nAsciiDoc reserves the following section names for specific purposes:\n\nmiscellaneous::\n        Configuration options that don't belong anywhere else.\nattributes::\n        Attribute name/value entries.\nspecialcharacters::\n        Special characters reserved by the backend markup.\ntags::\n        Backend markup tags.\nquotes::\n        Definitions for quoted inline character formatting.\nspecialwords::\n        Lists of words and phrases singled out for special markup.\nreplacements, replacements2, replacements3::\n        Find and replace substitution definitions.\nspecialsections::\n        Used to single out special section names for specific markup.\nmacros::\n        Macro syntax definitions.\ntitles::\n        Heading, section and block title definitions.\nparadef-*::\n        Paragraph element definitions.\nblockdef-*::\n        DelimitedBlock element definitions.\nlistdef-*::\n        List element definitions.\nlisttags-*::\n        List element tag definitions.\ntabledef-*::\n        Table element definitions.\ntabletags-*::\n        Table element tag definitions.\n\nEach line of text in these sections is a 'section entry'. Section\nentries share the following syntax:\n\nname=value::\n        The entry value is set to value.\nname=::\n        The entry value is set to a zero length string.\nname!::\n        The entry is undefined (deleted from the configuration). This\n        syntax only applies to 'attributes' and 'miscellaneous'\n        sections.\n\n.Section entry behavior\n- All equals characters inside the `name` must be escaped with a\n  backslash character.\n- `name` and `value` are stripped of leading and trailing white space.\n- Attribute names, tag entry names and markup template section names\n  consist of one or more alphanumeric, underscore or dash characters.\n  Names should not begin or end with a dash.\n- A blank configuration file section (one without any entries) deletes\n  any preceding section with the same name (applies to non-markup\n  template sections).\n\n\nMiscellaneous section\n~~~~~~~~~~~~~~~~~~~~~\nThe optional `[miscellaneous]` section specifies the following\n`name=value` options:\n\nnewline::\n        Output file line termination characters. Can include any\n        valid Python string escape sequences. The default value is\n        `\\r\\n` (carriage return, line feed). Should not be quoted or\n        contain explicit spaces (use `\\x20` instead). For example:\n\n        $ asciidoc -a 'newline=\\n' -b docbook mydoc.txt\n\noutfilesuffix::\n        The default extension for the output file, for example\n        `outfilesuffix=.html`. Defaults to backend name.\ntabsize::\n        The number of spaces to expand tab characters, for example\n        `tabsize=4`. Defaults to 8. A 'tabsize' of zero suppresses tab\n        expansion (useful when piping included files through block\n        filters). Included files can override this option using the\n        'tabsize' attribute.\npagewidth, pageunits::\n        These global table related options are documented in the\n        <<X4,Table Configuration File Definitions>> sub-section.\n\nNOTE: `[miscellaneous]` configuration file entries can be set using\nthe asciidoc(1) `-a` (`--attribute`) command-line option.\n\nTitles section\n~~~~~~~~~~~~~~\nsectiontitle::\n        Two line section title pattern. The entry value is a Python\n        regular expression containing the named group 'title'.\n\nunderlines::\n        A comma separated list of document and section title underline\n        character pairs starting with the section level 0 and ending\n        with section level 4 underline. The default setting is:\n\n        underlines=\"==\",\"--\",\"~~\",\"^^\",\"++\"\n\nsect0...sect4::\n        One line section title patterns. The entry value is a Python\n        regular expression containing the named group 'title'.\n\nblocktitle::\n        <<X42,BlockTitle element>> pattern.  The entry value is a\n        Python regular expression containing the named group 'title'.\n\nsubs::\n        A comma separated list of substitutions that are performed on\n        the document header and section titles. Defaults to 'normal'\n        substitution.\n\nTags section\n~~~~~~~~~~~~\nThe `[tags]` section contains backend tag definitions (one per\nline). Tags are used to translate AsciiDoc elements to backend\nmarkup.\n\nAn AsciiDoc tag definition is formatted like\n`<tagname>=<starttag>|<endtag>`. For example:\n\n  emphasis=<em>|</em>\n\nIn this example asciidoc(1) replaces the | character with the\nemphasized text from the AsciiDoc input file and writes the result to\nthe output file.\n\nUse the `{brvbar}` attribute reference if you need to include a | pipe\ncharacter inside tag text.\n\nAttributes section\n~~~~~~~~~~~~~~~~~~\nThe optional `[attributes]` section contains predefined attributes.\n\nIf the attribute value requires leading or trailing spaces then the\ntext text should be enclosed in quotation mark (\") characters.\n\nTo delete a attribute insert a `name!` entry in a downstream\nconfiguration file or use the asciidoc(1) `--attribute name!`\ncommand-line option (an attribute name suffixed with a `!` character\ndeletes the attribute)\n\nSpecial Characters section\n~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe `[specialcharacters]` section specifies how to escape characters\nreserved by the backend markup. Each translation is specified on a\nsingle line formatted like:\n\n  <special_character>=<translated_characters>\n\nSpecial characters are normally confined to those that resolve\nmarkup ambiguity (in the case of HTML and XML markups the ampersand,\nless than and greater than characters).  The following example causes\nall occurrences of the `<` character to be replaced by `&lt;`.\n\n  <=&lt;\n\nQuoted Text section\n~~~~~~~~~~~~~~~~~~~\nQuoting is used primarily for text formatting.  The `[quotes]` section\ndefines AsciiDoc quoting characters and their corresponding backend\nmarkup tags.  Each section entry value is the name of a of a `[tags]`\nsection entry. The entry name is the character (or characters) that\nquote the text.  The following examples are taken from AsciiDoc\nconfiguration files:\n\n  [quotes]\n  _=emphasis\n\n  [tags]\n  emphasis=<em>|</em>\n\nYou can specify the left and right quote strings separately by\nseparating them with a | character, for example:\n\n  ``|''=quoted\n\nOmitting the tag will disable quoting, for example, if you don't want\nsuperscripts or subscripts put the following in a custom configuration\nfile or edit the global `asciidoc.conf` configuration file:\n\n  [quotes]\n  ^=\n  ~=\n\n<<X52,Unconstrained quotes>> are differentiated from constrained\nquotes by prefixing the tag name with a hash character, for example:\n\n  __=#emphasis\n\n.Quoted text behavior\n- Quote characters must be non-alphanumeric.\n- To minimize quoting ambiguity try not to use the same quote\n  characters in different quote types.\n\nSpecial Words section\n~~~~~~~~~~~~~~~~~~~~~\nThe `[specialwords]` section is used to single out words and phrases\nthat you want to consistently format in some way throughout your\ndocument without having to repeatedly specify the markup. The name of\neach entry corresponds to a markup template section and the entry\nvalue consists of a list of words and phrases to be marked up. For\nexample:\n\n  [specialwords]\n  strongwords=NOTE IMPORTANT\n\n  [strongwords]\n  <strong>{words}</strong>\n\nThe examples specifies that any occurrence of `NOTE` or `IMPORTANT`\nshould appear in a bold font.\n\nWords and word phrases are treated as Python regular expressions: for\nexample, the word `^NOTE` would only match `NOTE` if appeared at\nthe start of a line.\n\nAsciiDoc comes with three built-in Special Word types:\n'emphasizedwords', 'monospacedwords' and 'strongwords', each has a\ncorresponding (backend specific) markup template section. Edit the\nconfiguration files to customize existing Special Words and to add new\nones.\n\n.Special word behavior\n- Word list entries must be separated by space characters.\n- Word list entries with embedded spaces should be enclosed in quotation (\")\n  characters.\n- A `[specialwords]` section entry of the form\n  +name=word1{nbsp}[word2...]+ adds words to existing `name` entries.\n- A `[specialwords]` section entry of the form `name` undefines\n  (deletes) all existing `name` words.\n- Since word list entries are processed as Python regular expressions\n  you need to be careful to escape regular expression special\n  characters.\n- By default Special Words are substituted before Inline Macros, this\n  may lead to undesirable consequences. For example the special word\n  `foobar` would be expanded inside the macro call\n  `http://www.foobar.com[]`.  A possible solution is to emphasize\n  whole words only by defining the word using regular expression\n  characters, for example `\\bfoobar\\b`.\n- If the first matched character of a special word is a backslash then\n  the remaining characters are output without markup i.e. the\n  backslash can be used to escape special word markup.  For example\n  the special word `\\\\?\\b[Tt]en\\b` will mark up the words `Ten` and\n  `ten` only if they are not preceded by a backslash.\n\n[[X10]]\nReplacements section\n~~~~~~~~~~~~~~~~~~~~\n`[replacements]`, `[replacements2]` and `[replacements3]`\nconfiguration file entries specify find and replace text and are\nformatted like:\n\n  <find_pattern>=<replacement_text>\n\nThe find text can be a Python regular expression; the replace text can\ncontain Python regular expression group references.\n\nUse Replacement shortcuts for often used macro references, for\nexample (the second replacement allows us to backslash escape the\nmacro name):\n\n  NEW!=image:./images/smallnew.png[New!]\n  \\\\NEW!=NEW!\n\nThe only difference between the three replacement types is how they\nare applied. By default 'replacements' and 'replacement2' are applied\nin <<X102,normal>> substitution contexts whereas 'replacements3' needs\nto be configured explicitly and should only be used in backend\nconfiguration files.\n\n.Replacement behavior\n- The built-in replacements can be escaped with a backslash.\n- If the find or replace text has leading or trailing spaces then the\n  text should be enclosed in quotation (\") characters.\n- Since the find text is processed as a regular expression you need to\n  be careful to escape regular expression special characters.\n- Replacements are performed in the same order they appear in the\n  configuration file replacements section.\n\nMarkup Template Sections\n~~~~~~~~~~~~~~~~~~~~~~~~\nMarkup template sections supply backend markup for translating\nAsciiDoc elements.  Since the text is normally backend dependent\nyou'll find these sections in the backend specific configuration\nfiles. Template sections differ from other sections in that they\ncontain a single block of text instead of per line 'name=value'\nentries. A markup template section body can contain:\n\n- Attribute references\n- System macro calls.\n- A document content placeholder\n\nThe document content placeholder is a single | character and is\nreplaced by text from the source element.  Use the `{brvbar}`\nattribute reference if you need a literal | character in the template.\n\n[[X27]]\nConfiguration file names, precedence and locations\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nConfiguration files have a `.conf` file name extension; they are\nloaded from the following locations:\n\n1. The directory containing the asciidoc executable.\n2. If there is no `asciidoc.conf` file in the directory containing the\n   asciidoc executable then load from the global configuration\n   directory (normally `/etc/asciidoc` or `/usr/local/etc/asciidoc`)\n   i.e. the global configuration files directory is skipped if\n   AsciiDoc configuration files are installed in the same directory as\n   the asciidoc executable. This allows both a system wide copy and\n   multiple local copies of AsciiDoc to coexist on the same host PC.\n3. The user's `$HOME/.asciidoc` directory (if it exists).\n4. The directory containing the AsciiDoc source file.\n5. Explicit configuration files specified using:\n   - The `conf-files` attribute (one or more file names separated by a\n     `|` character). These files are loaded in the order they are\n     specified and prior to files specified using the `--conf-file`\n     command-line option.\n   - The asciidoc(1) `--conf-file`) command-line option.  The\n     `--conf-file` option can be specified multiple times, in which\n     case configuration files will be processed in the same order they\n     appear on the command-line.\n6. <<X100,Backend plugin>> configuration files are loaded from\n   subdirectories named like `backends/<backend>` in locations 1, 2\n   and 3.\n7. <<X59,Filter>> configuration files are loaded from subdirectories\n   named like `filters/<filter>` in locations 1, 2 and 3.\n\nConfiguration files from the above locations are loaded in the\nfollowing order:\n\n- The `[attributes]` section only from:\n  * `asciidoc.conf` in location 3\n  * Files from location 5.\n+\nThis first pass makes locally set attributes available in the global\n`asciidoc.conf` file.\n\n- `asciidoc.conf` from locations 1, 2, 3.\n- 'attributes', 'titles' and 'specialcharacters' sections from the\n  `asciidoc.conf` in location 4.\n- The document header is parsed at this point and we can assume the\n  'backend' and 'doctype' have now been defined.\n- Backend plugin `<backend>.conf` and `<backend>-<doctype>.conf` files\n  from locations 6.  If a backend plugin is not found then try\n  locations 1, 2 and 3 for `<backend>.conf` and\n  `<backend>-<doctype>.conf` backend configuration files.\n- Filter conf files from locations 7.\n- `lang-<lang>.conf` from locations 1, 2, 3.\n- `asciidoc.conf` from location 4.\n- `<backend>.conf` and `<backend>-<doctype>.conf` from location 4.\n- Filter conf files from location 4.\n- `<docfile>.conf` and `<docfile>-<backend>.conf` from location 4.\n- Configuration files from location 5.\n\nWhere:\n\n- `<backend>` and `<doctype>` are values specified by the asciidoc(1)\n  `-b` (`--backend`) and `-d` (`--doctype`) command-line options.\n- `<infile>` is the path name of the AsciiDoc input file without the\n  file name extension.\n- `<lang>` is a two letter country code set by the the AsciiDoc 'lang'\n  attribute.\n\n[NOTE]\n=====================================================================\nThe backend and language global configuration files are loaded *after*\nthe header has been parsed.  This means that you can set most\nattributes in the document header. Here's an example header:\n\n  Life's Mysteries\n  ================\n  :author: Hu Nose\n  :doctype: book\n  :toc:\n  :icons:\n  :data-uri:\n  :lang: en\n  :encoding: iso-8859-1\n\nAttributes set in the document header take precedence over\nconfiguration file attributes.\n\n=====================================================================\n\nTIP: Use the asciidoc(1) `-v` (`--verbose`) command-line option to see\nwhich configuration files are loaded and the order in which they are\nloaded.\n\n\nDocument Attributes\n-------------------\nA document attribute is comprised of a 'name' and a textual 'value'\nand is used for textual substitution in AsciiDoc documents and\nconfiguration files. An attribute reference (an attribute name\nenclosed in braces) is replaced by the corresponding attribute\nvalue. Attribute names are case insensitive and can only contain\nalphanumeric, dash and underscore characters.\n\nThere are four sources of document attributes (from highest to lowest\nprecedence):\n\n- Command-line attributes.\n- AttributeEntry, AttributeList, Macro and BlockId elements.\n- Configuration file `[attributes]` sections.\n- Intrinsic attributes.\n\nWithin each of these divisions the last processed entry takes\nprecedence.\n\nNOTE: If an attribute is not defined then the line containing the\nattribute reference is dropped. This property is used extensively in\nAsciiDoc configuration files to facilitate conditional markup\ngeneration.\n\n\n[[X18]]\nAttribute Entries\n-----------------\nThe `AttributeEntry` block element allows document attributes to be\nassigned within an AsciiDoc document. Attribute entries are added to\nthe global document attributes dictionary. The attribute name/value\nsyntax is a single line like:\n\n  :<name>: <value>\n\nFor example:\n\n  :Author Initials: JB\n\nThis will set an attribute reference `{authorinitials}` to the value\n'JB' in the current document.\n\nTo delete (undefine) an attribute use the following syntax:\n\n  :<name>!:\n\n.AttributeEntry behavior\n- The attribute entry line begins with colon -- no white space allowed\n  in left margin.\n- AsciiDoc converts the `<name>` to a legal attribute name (lower\n  case, alphanumeric, dash and underscore characters only -- all other\n  characters deleted). This allows more human friendly text to be\n  used.\n- Leading and trailing white space is stripped from the `<value>`.\n- Lines ending in a space followed by a plus character are continued\n  to the next line, for example:\n\n  :description: AsciiDoc is a text document format for writing notes, +\n                documentation, articles, books, slideshows, web pages +\n                and man pages.\n\n- If the `<value>` is blank then the corresponding attribute value is\n  set to an empty string.\n- Attribute references contained in the entry `<value>` will be\n  expanded.\n- By default AttributeEntry values are substituted for\n  `specialcharacters` and `attributes` (see above), if you want to\n  change or disable AttributeEntry substitution use the <<X77,pass:[]\n  inline macro>> syntax.\n- Attribute entries in the document Header are available for header\n  markup template substitution.\n- Attribute elements override configuration file and intrinsic\n  attributes but do not override command-line attributes.\n\nHere are some more attribute entry examples:\n\n---------------------------------------------------------------------\nAsciiDoc User Manual\n====================\n:author:    Stuart Rackham\n:email:     srackham@gmail.com\n:revdate:   April 23, 2004\n:revnumber: 5.1.1\n---------------------------------------------------------------------\n\nWhich creates these attributes:\n\n  {author}, {firstname}, {lastname}, {authorinitials}, {email},\n  {revdate}, {revnumber}\n\nThe previous example is equivalent to this <<X95,document header>>:\n\n---------------------------------------------------------------------\nAsciiDoc User Manual\n====================\nStuart Rackham <srackham@gmail.com>\n5.1.1, April 23, 2004\n---------------------------------------------------------------------\n\nSetting configuration entries\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nA variant of the Attribute Entry syntax allows configuration file\nsection entries and markup template sections to be set from within an\nAsciiDoc document:\n\n  :<section_name>.[<entry_name>]: <entry_value>\n\nWhere `<section_name>` is the configuration section name,\n`<entry_name>` is the name of the entry and `<entry_value>` is the\noptional entry value. This example sets the default labeled list\nstyle to 'horizontal':\n\n  :listdef-labeled.style: horizontal\n\nIt is exactly equivalent to a configuration file containing:\n\n  [listdef-labeled]\n  style=horizontal\n\n- If the `<entry_name>` is omitted then the entire section is\n  substituted with the `<entry_value>`. This feature should only be\n  used to set markup template sections. The following example sets the\n  'xref2' inline macro markup template:\n\n  :xref2-inlinemacro.: <a href=\"#{1}\">{2?{2}}</a>\n\n- No substitution is performed on configuration file attribute entries\n  and they cannot be undefined.\n- This feature can only be used in attribute entries -- configuration\n  attributes cannot be set using the asciidoc(1) command `--attribute`\n  option.\n\n[[X62]]\n.Attribute entries promote clarity and eliminate repetition\n*********************************************************************\nURLs and file names in AsciiDoc macros are often quite long -- they\nbreak paragraph flow and readability suffers.  The problem is\ncompounded by redundancy if the same name is used repeatedly.\nAttribute entries can be used to make your documents easier to read\nand write, here are some examples:\n\n  :1:         http://freshmeat.net/projects/asciidoc/\n  :homepage:  http://methods.co.nz/asciidoc/[AsciiDoc home page]\n  :new:       image:./images/smallnew.png[]\n  :footnote1: footnote:[A meaningless latin term]\n\n  Using previously defined attributes: See the {1}[Freshmeat summary]\n  or the {homepage} for something new {new}. Lorem ispum {footnote1}.\n\n.Note\n- The attribute entry definition must precede it's usage.\n- You are not limited to URLs or file names, entire macro calls or\n  arbitrary lines of text can be abbreviated.\n- Shared attributes entries could be grouped into a separate file and\n  <<X63,included>> in multiple documents.\n*********************************************************************\n\n\n[[X21]]\nAttribute Lists\n---------------\n- An attribute list is a comma separated list of attribute values.\n- The entire list is enclosed in square brackets.\n- Attribute lists are used to pass parameters to macros, blocks (using\n  the <<X79,AttributeList element>>) and inline quotes.\n\nThe list consists of zero or more positional attribute values followed\nby zero or more named attribute values.  Here are three examples: a\nsingle unquoted positional attribute; three unquoted positional\nattribute values; one positional attribute followed by two named\nattributes; the unquoted attribute value in the final example contains\ncomma (`&#44;`) and double-quote (`&#34;`) character entities:\n\n  [Hello]\n  [quote, Bertrand Russell, The World of Mathematics (1956)]\n  [\"22 times\", backcolor=\"#0e0e0e\", options=\"noborders,wide\"]\n  [A footnote&#44; &#34;with an image&#34; image:smallnew.png[]]\n\n.Attribute list behavior\n- If one or more attribute values contains a comma the all string\n  values must be quoted (enclosed in double quotation mark\n  characters).\n- If the list contains any named or quoted attributes then all string\n  attribute values must be quoted.\n- To include a double quotation mark (\") character in a quoted\n  attribute value the the quotation mark must be escaped with a\n  backslash.\n- List attributes take precedence over existing attributes.\n- List attributes can only be referenced in configuration file markup\n  templates and tags, they are not available elsewhere in the\n  document.\n- Setting a named attribute to `None` undefines the attribute.\n- Positional attributes are referred to as `{1}`,`{2}`,`{3}`,...\n- Attribute `{0}` refers to the entire list (excluding the enclosing\n  square brackets).\n- Named attribute names cannot contain dash characters.\n\n[[X75]]\nOptions attribute\n~~~~~~~~~~~~~~~~~\nIf the attribute list contains an attribute named `options` it is\nprocessed as a comma separated list of option names:\n\n- Each name generates an attribute named like `<option>-option` (where\n  `<option>` is the option name) with an empty string value.  For\n  example `[options=\"opt1,opt2,opt3\"]` is equivalent to setting the\n  following three attributes\n  `[opt1-option=\"\",opt2-option=\"\",opt2-option=\"\"]`.\n- If you define a an option attribute globally (for example with an\n  <<X18,attribute entry>>) then it will apply to all elements in the\n  document.\n- AsciiDoc implements a number of predefined options which are listed\n  in the <<X74,Attribute Options appendix>>.\n\nMacro Attribute lists\n~~~~~~~~~~~~~~~~~~~~~\nMacros calls are suffixed with an attribute list. The list may be\nempty but it cannot be omitted. List entries are used to pass\nattribute values to macro markup templates.\n\n\nAttribute References\n--------------------\nAn attribute reference is an attribute name (possibly followed by an\nadditional parameters) enclosed in curly braces.  When an attribute\nreference is encountered it is evaluated and replaced by its\ncorresponding text value.  If the attribute is undefined the line\ncontaining the attribute is dropped.\n\nThere are three types of attribute reference: 'Simple', 'Conditional'\nand 'System'.\n\n.Attribute reference evaluation\n- You can suppress attribute reference expansion by placing a\n  backslash character immediately in front of the opening brace\n  character.\n- By default attribute references are not expanded in\n  'LiteralParagraphs', 'ListingBlocks' or 'LiteralBlocks'.\n- Attribute substitution proceeds line by line in reverse line order.\n- Attribute reference evaluation is performed in the following order:\n  'Simple' then 'Conditional' and finally 'System'.\n\nSimple Attributes References\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSimple attribute references take the form `{<name>}`. If the\nattribute name is defined its text value is substituted otherwise the\nline containing the reference is dropped from the output.\n\nConditional Attribute References\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAdditional parameters are used in conjunction with attribute names to\ncalculate a substitution value. Conditional attribute references take\nthe following forms:\n\n`{<names>=<value>}`::\n        `<value>` is substituted if the attribute `<names>` is\n        undefined otherwise its value is substituted. `<value>` can\n        contain simple attribute references.\n\n`{<names>?<value>}`::\n        `<value>` is substituted if the attribute `<names>` is defined\n        otherwise an empty string is substituted.  `<value>` can\n        contain simple attribute references.\n\n`{<names>!<value>}`::\n        `<value>` is substituted if the attribute `<names>` is\n        undefined otherwise an empty string is substituted.  `<value>`\n        can contain simple attribute references.\n\n`{<names>#<value>}`::\n        `<value>` is substituted if the attribute `<names>` is defined\n        otherwise the undefined attribute entry causes the containing\n        line to be dropped.  `<value>` can contain simple attribute\n        references.\n\n`{<names>%<value>}`::\n        `<value>` is substituted if the attribute `<names>` is not\n        defined otherwise the containing line is dropped.  `<value>`\n        can contain simple attribute references.\n\n`{<names>@<regexp>:<value1>[:<value2>]}`::\n        `<value1>` is substituted if the value of attribute `<names>`\n        matches the regular expression `<regexp>` otherwise `<value2>`\n        is substituted. If attribute `<names>` is not defined the\n        containing line is dropped. If `<value2>` is omitted an empty\n        string is assumed. The values and the regular expression can\n        contain simple attribute references.  To embed colons in the\n        values or the regular expression escape them with backslashes.\n\n`{<names>$<regexp>:<value1>[:<value2>]}`::\n        Same behavior as the previous ternary attribute except for\n        the following cases:\n\n        `{<names>$<regexp>:<value>}`;;\n                Substitutes `<value>` if `<names>` matches `<regexp>`\n                otherwise the result is undefined and the containing\n                line is dropped.\n\n        `{<names>$<regexp>::<value>}`;;\n                Substitutes `<value>` if `<names>` does not match\n                `<regexp>` otherwise the result is undefined and the\n                containing line is dropped.\n\nThe attribute `<names>` parameter normally consists of a single\nattribute name but it can be any one of the following:\n\n- A single attribute name which evaluates to the attributes value.\n- Multiple ',' separated attribute names which evaluates to an empty\n  string if one or more of the attributes is defined, otherwise it's\n  value is undefined.\n- Multiple '+' separated attribute names which evaluates to an empty\n  string if all of the attributes are defined, otherwise it's value is\n  undefined.\n\nConditional attributes with single attribute names are evaluated first\nso they can be used inside the multi-attribute conditional `<value>`.\n\nConditional attribute examples\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nConditional attributes are mainly used in AsciiDoc configuration\nfiles -- see the distribution `.conf` files for examples.\n\nAttribute equality test::\n  If `{backend}` is 'docbook45' or 'xhtml11' the example evaluates to\n  ``DocBook 4.5 or XHTML 1.1 backend'' otherwise it evaluates to\n  ``some other backend'':\n\n  {backend@docbook45|xhtml11:DocBook 4.5 or XHTML 1.1 backend:some other backend}\n\nAttribute value map::\n  This example maps the `frame` attribute values [`topbot`, `all`,\n  `none`, `sides`] to [`hsides`, `border`, `void`, `vsides`]:\n\n  {frame@topbot:hsides}{frame@all:border}{frame@none:void}{frame@sides:vsides}\n\n\n[[X24]]\nSystem Attribute References\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSystem attribute references generate the attribute text value by\nexecuting a predefined action that is parametrized by one or more\narguments. The syntax is `{<action>:<arguments>}`.\n\n`{counter:<attrname>[:<seed>]}`::\n        Increments the document attribute (if the attribute is\n        undefined it is set to `1`). Returns the new attribute value.\n\n        - Counters generate global (document wide) attributes.\n        - The optional `<seed>` specifies the counter's initial value;\n          it can be a number or a single letter; defaults to '1'.\n        - `<seed>` can contain simple and conditional attribute\n          references.\n        - The 'counter' system attribute will not be executed if the\n          containing line is dropped by the prior evaluation of an\n          undefined attribute.\n\n`{counter2:<attrname>[:<seed>]}`::\n        Same as `counter` except the it always returns a blank string.\n\n`{eval:<expression>}`::\n        Substitutes the result of the Python `<expression>`.\n\n        - If `<expression>` evaluates to `None` or `False` the\n          reference is deemed undefined and the line containing the\n          reference is dropped from the output.\n        - If the expression evaluates to `True` the attribute\n          evaluates to an empty string.\n        - `<expression>` can contain simple and conditional attribute\n          references.\n        - The 'eval' system attribute can be nested inside other\n          system attributes.\n\n`{eval3:<command>}`::\n        Passthrough version of `{eval:<expression>}` -- the generated\n        output is written directly to the output without any further\n        substitutions.\n\n`{include:<filename>}`::\n        Substitutes contents of the file named `<filename>`.\n\n        - The included file is read at the time of attribute\n          substitution.\n        - If the file does not exist a warning is emitted and the line\n          containing the reference is dropped from the output file.\n        - Tabs are expanded based on the current 'tabsize' attribute\n          value.\n\n`{set:<attrname>[!][:<value>]}`::\n        Sets or unsets document attribute. Normally only used in\n        configuration file markup templates (use\n        <<X18,AttributeEntries>> in AsciiDoc documents).\n\n        - If the attribute name is followed by an exclamation mark\n          the attribute becomes undefined.\n        - If `<value>` is omitted the attribute is set to a blank\n          string.\n        - `<value>` can contain simple and conditional attribute\n          references.\n        - Returns a blank string unless the attribute is undefined in\n          which case the return value is undefined and the enclosing\n          line will be dropped.\n\n`{set2:<attrname>[!][:<value>]}`::\n        Same as `set` except that the attribute scope is local to the\n        template.\n\n`{sys:<command>}`::\n        Substitutes the stdout generated by the execution of the shell\n        `<command>`.\n\n`{sys2:<command>}`::\n        Substitutes the stdout and stderr generated by the execution\n        of the shell `<command>`.\n\n`{sys3:<command>}`::\n        Passthrough version of `{sys:<command>}` -- the generated\n        output is written directly to the output without any further\n        substitutions.\n\n`{template:<template>}`::\n        Substitutes the contents of the configuration file section\n        named `<template>`. Attribute references contained in the\n        template are substituted.\n\n.System reference behavior\n- System attribute arguments can contain non-system attribute\n  references.\n- Closing brace characters inside system attribute arguments must be\n  escaped with a backslash.\n\n[[X60]]\nIntrinsic Attributes\n--------------------\nIntrinsic attributes are simple attributes that are created\nautomatically from: AsciiDoc document header parameters; asciidoc(1)\ncommand-line arguments; attributes defined in the default\nconfiguration files; the execution context.  Here's the list of\npredefined intrinsic attributes:\n\n  {amp}                 ampersand (&) character entity\n  {asciidoc-args}       used to pass inherited arguments to asciidoc filters\n  {asciidoc-confdir}    the asciidoc(1) global configuration directory\n  {asciidoc-dir}        the asciidoc(1) application directory\n  {asciidoc-file}       the full path name of the asciidoc(1) script\n  {asciidoc-version}    the version of asciidoc(1)\n  {author}              author's full name\n  {authored}            empty string '' if {author} or {email} defined,\n  {authorinitials}      author initials (from document header)\n  {backend-<backend>}   empty string ''\n  {<backend>-<doctype>} empty string ''\n  {backend}             document backend specified by `-b` option\n  {backend-confdir}     the directory containing the <backend>.conf file\n  {backslash}           backslash character\n  {basebackend-<base>}  empty string ''\n  {basebackend}         html or docbook\n  {blockname}           current block name (note 8).\n  {brvbar}              broken vertical bar (|) character\n  {docdate}             document last modified date\n  {docdir}              document input directory name  (note 5)\n  {docfile}             document file name  (note 5)\n  {docname}             document file name without extension (note 6)\n  {doctime}             document last modified time\n  {doctitle}            document title (from document header)\n  {doctype-<doctype>}   empty string ''\n  {doctype}             document type specified by `-d` option\n  {email}               author's email address (from document header)\n  {empty}               empty string ''\n  {encoding}            specifies input and output encoding\n  {filetype-<fileext>}  empty string ''\n  {filetype}            output file name file extension\n  {firstname}           author first name (from document header)\n  {gt}                  greater than (>) character entity\n  {id}                  running block id generated by BlockId elements\n  {indir}               input file directory name (note 2,5)\n  {infile}              input file name (note 2,5)\n  {lastname}            author last name (from document header)\n  {ldquo}               Left double quote character (note 7)\n  {level}               title level 1..4 (in section titles)\n  {listindex}           the list index (1..) of the most recent list item\n  {localdate}           the current date\n  {localtime}           the current time\n  {lsquo}               Left single quote character (note 7)\n  {lt}                  less than (<) character entity\n  {manname}             manpage name (defined in NAME section)\n  {manpurpose}          manpage (defined in NAME section)\n  {mantitle}            document title minus the manpage volume number\n  {manvolnum}           manpage volume number (1..8) (from document header)\n  {middlename}          author middle name (from document header)\n  {nbsp}                non-breaking space character entity\n  {notitle}             do not display the document title\n  {outdir}              document output directory name (note 2)\n  {outfile}             output file name (note 2)\n  {python}              the full path name of the Python interpreter executable\n  {rdquo}               Right double quote character (note 7)\n  {reftext}             running block xreflabel generated by BlockId elements\n  {revdate}             document revision date (from document header)\n  {revnumber}           document revision number (from document header)\n  {rsquo}               Right single quote character (note 7)\n  {sectnum}             formatted section number (in section titles)\n  {sp}                  space character\n  {showcomments}        send comment lines to the output\n  {title}               section title (in titled elements)\n  {two-colons}          Two colon characters\n  {two-semicolons}      Two semicolon characters\n  {user-dir}            the ~/.asciidoc directory (if it exists)\n  {verbose}             defined as '' if --verbose command option specified\n  {wj}                  Word-joiner\n  {zwsp}                Zero-width space character entity\n\n[NOTE]\n======\n1. Intrinsic attributes are global so avoid defining custom attributes\n   with the same names.\n2. `{outfile}`, `{outdir}`, `{infile}`, `{indir}` attributes are\n   effectively read-only (you can set them but it won't affect the\n   input or output file paths).\n3.  See also the <<X88,Backend Attributes>> section for attributes\n    that relate to AsciiDoc XHTML file generation.\n4. The entries that translate to blank strings are designed to be used\n   for conditional text inclusion. You can also use the `ifdef`,\n   `ifndef` and `endif` System macros for conditional inclusion.\n   footnote:[Conditional inclusion using `ifdef` and `ifndef` macros\n   differs from attribute conditional inclusion in that the former\n   occurs when the file is read while the latter occurs when the\n   contents are written.]\n5. `{docfile}` and `{docdir}` refer to root document specified on the\n   asciidoc(1) command-line; `{infile}` and `{indir}` refer to the\n   current input file which may be the root document or an included\n   file. When the input is being read from the standard input\n   (`stdin`) these attributes are undefined.\n6. If the input file is the standard input and the output file is not\n   the standard output then `{docname}` is the output file name sans\n   file extension.\n7. See\n   http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks[non-English\n   usage of quotation marks].\n8. The `{blockname}` attribute identifies the style of the current\n   block. It applies to delimited blocks, lists and tables. Here is a\n   list of `{blockname}` values (does not include filters or custom\n   block and style names):\n\n   delimited blocks:: comment, sidebar, open, pass, literal, verse,\n   listing, quote, example, note, tip, important, caution, warning,\n   abstract, partintro\n\n   lists:: arabic, loweralpha, upperalpha, lowerroman, upperroman,\n   labeled, labeled3, labeled4, qanda, horizontal, bibliography,\n   glossary\n\n   tables:: table\n\n======\n\n\n[[X73]]\nBlock Element Definitions\n-------------------------\nThe syntax and behavior of Paragraph, DelimitedBlock, List and Table\nblock elements is determined by block definitions contained in\n<<X7,AsciiDoc configuration file>> sections.\n\nEach definition consists of a section title followed by one or more\nsection entries. Each entry defines a block parameter controlling some\naspect of the block's behavior. Here's an example:\n\n---------------------------------------------------------------------\n[blockdef-listing]\ndelimiter=^-{4,}$\ntemplate=listingblock\npresubs=specialcharacters,callouts\n---------------------------------------------------------------------\n\nConfiguration file block definition sections are processed\nincrementally after each configuration file is loaded. Block\ndefinition section entries are merged into the block definition, this\nallows block parameters to be overridden and extended by later\n<<X27,loading configuration files>>.\n\nAsciiDoc Paragraph, DelimitedBlock, List and Table block elements\nshare a common subset of configuration file parameters:\n\ndelimiter::\n  A Python regular expression that matches the first line of a block\n  element -- in the case of DelimitedBlocks and Tables it also matches\n  the last line.\n\ntemplate::\n  The name of the configuration file markup template section that will\n  envelope the block contents. The pipe ('|') character is substituted\n  for the block contents. List elements use a set of (list specific)\n  tag parameters instead of a single template. The template name can\n  contain attribute references allowing dynamic template selection a\n  the time of template substitution.\n\noptions::\n  A comma delimited list of element specific option names. In addition\n  to being used internally, options are available during markup tag\n  and template substitution as attributes with an empty string value\n  named like `<option>-option` (where `<option>` is the option name).\n  See <<X74,attribute options>> for a complete list of available\n  options.\n\nsubs, presubs, postsubs::\n  * 'presubs' and 'postsubs' are lists of comma separated substitutions that are\n    performed on the block contents. 'presubs' is applied first,\n    'postsubs' (if specified) second.\n\n  * 'subs' is an alias for 'presubs'.\n\n  * If a 'filter' is allowed (Paragraphs, DelimitedBlocks and Tables)\n    and has been specified then 'presubs' and 'postsubs' substitutions\n    are performed before and after the filter is run respectively.\n\n  * Allowed values: 'specialcharacters', 'quotes', 'specialwords',\n    'replacements', 'macros', 'attributes', 'callouts'.\n\n  * [[X102]]The following composite values are also allowed:\n\n    'none';;\n        No substitutions.\n    'normal';;\n        The following substitutions in the following order:\n        'specialcharacters', 'quotes', 'attributes', 'specialwords',\n        'replacements', 'macros', 'replacements2'.\n    'verbatim';;\n        The following substitutions in the following order:\n        'specialcharacters' and 'callouts'.\n\n  * 'normal' and 'verbatim' substitutions can be redefined by with\n    `subsnormal` and `subsverbatim` entries in a configuration file\n    `[miscellaneous]` section.\n\n  * The substitutions are processed in the order in which they are\n    listed and can appear more than once.\n\nfilter::\n  This optional entry specifies an executable shell command for\n  processing block content (Paragraphs, DelimitedBlocks and Tables).\n  The filter command can contain attribute references.\n\nposattrs::\n  Optional comma separated list of positional attribute names. This\n  list maps positional attributes (in the block's <<X21,attribute\n  list>>) to named block attributes. The following example, from the\n  QuoteBlock definition, maps the first and section positional\n  attributes:\n\n  posattrs=attribution,citetitle\n\nstyle::\n  This optional parameter specifies the default style name.\n\n\n<stylename>-style::\n  Optional style definition (see <<X23,Styles>> below).\n\nThe following block parameters behave like document attributes and can\nbe set in block attribute lists and style definitions: 'template',\n'options', 'subs', 'presubs', 'postsubs', 'filter'.\n\n[[X23]]\nStyles\n~~~~~~\nA style is a set of block parameter bundled as a single named\nparameter. The following example defines a style named 'verbatim':\n\n  verbatim-style=template=\"literalblock\",subs=\"verbatim\"\n\nIf a block's <<X21,attribute list>> contains a 'style' attribute then\nthe corresponding style parameters are be merged into the default\nblock definition parameters.\n\n- All style parameter names must be suffixed with `-style` and the\n  style parameter value is in the form of a list of <<X21,named\n  attributes>>.\n- The 'template' style parameter is mandatory, other parameters can be\n  omitted in which case they inherit their values from the default\n  block definition parameters.\n- Multi-item style parameters ('subs','presubs','postsubs','posattrs')\n  must be specified using Python tuple syntax (rather than a simple\n  list of values as they in separate entries) e.g.\n  `postsubs=(\"callouts\",)` not `postsubs=\"callouts\"`.\n\nParagraphs\n~~~~~~~~~~\nParagraph translation is controlled by `[paradef-*]` configuration\nfile section entries. Users can define new types of paragraphs and\nmodify the behavior of existing types by editing AsciiDoc\nconfiguration files.\n\nHere is the shipped Default paragraph definition:\n\n--------------------------------------------------------------------\n[paradef-default]\ndelimiter=(?P<text>\\S.*)\ntemplate=paragraph\n--------------------------------------------------------------------\n\nThe normal paragraph definition has a couple of special properties:\n\n1. It must exist and be defined in a configuration file section named\n   `[paradef-default]`.\n2. Irrespective of its position in the configuration files default\n   paragraph document matches are attempted only after trying all\n   other paragraph types.\n\nParagraph specific block parameter notes:\n\ndelimiter::\n  This regular expression must contain the named group 'text' which\n  matches the text on the first line.  Paragraphs are terminated by a\n  blank line, the end of file, or the start of a DelimitedBlock.\n\noptions::\n  The 'listelement' option specifies that paragraphs of this type will\n  automatically be considered part of immediately preceding list\n  items.  The 'skip' option causes the paragraph to be treated as a\n  comment (see <<X26,CommentBlocks>>).\n\n.Paragraph processing proceeds as follows:\n1. The paragraph text is aligned to the left margin.\n2. Optional 'presubs' inline substitutions are performed on the\n   paragraph text.\n3. If a filter command is specified it is executed and the paragraph\n   text piped to its standard input; the filter output replaces the\n   paragraph text.\n4. Optional 'postsubs' inline substitutions are performed on the\n   paragraph text.\n5. The paragraph text is enveloped by the paragraph's markup template\n   and written to the output file.\n\nDelimited Blocks\n~~~~~~~~~~~~~~~~\nDelimitedBlock 'options' values are:\n\nsectionbody::\n    The block contents are processed as a SectionBody.\n\nskip::\n    The block is treated as a comment (see <<X26,CommentBlocks>>).\n    Preceding <<X21,attribute lists>> and <<X42,block titles>> are not\n    consumed.\n\n'presubs', 'postsubs' and 'filter' entries are ignored when\n'sectionbody' or 'skip' options are set.\n\nDelimitedBlock processing proceeds as follows:\n\n1. Optional 'presubs' substitutions are performed on the block\n   contents.\n2. If a filter is specified it is executed and the block's contents\n   piped to its standard input. The filter output replaces the block\n   contents.\n3. Optional 'postsubs' substitutions are performed on the block\n   contents.\n4. The block contents is enveloped by the block's markup template and\n   written to the output file.\n\nTIP: Attribute expansion is performed on the block filter command\nbefore it is executed, this is useful for passing arguments to the\nfilter.\n\nLists\n~~~~~\nList behavior and syntax is determined by `[listdef-*]` configuration\nfile sections. The user can change existing list behavior and add new\nlist types by editing configuration files.\n\nList specific block definition notes:\n\ntype::\n  This is either 'bulleted','numbered','labeled' or 'callout'.\n\ndelimiter::\n  A Python regular expression that matches the first line of a\n  list element entry. This expression can contain the named groups\n  'text' (bulleted groups), 'index' and 'text' (numbered lists),\n  'label' and 'text' (labeled lists).\n\ntags::\n  The `<name>` of the `[listtags-<name>]` configuration file section\n  containing list markup tag definitions.  The tag entries ('list',\n  'entry', 'label', 'term', 'text') map the AsciiDoc list structure to\n  backend markup; see the 'listtags' sections in the AsciiDoc\n  distributed backend `.conf` configuration files for examples.\n\nTables\n~~~~~~\nTable behavior and syntax is determined by `[tabledef-*]` and\n`[tabletags-*]` configuration file sections. The user can change\nexisting table behavior and add new table types by editing\nconfiguration files.  The following `[tabledef-*]` section entries\ngenerate table output markup elements:\n\ncolspec::\n  The table 'colspec' tag definition.\n\nheadrow, footrow, bodyrow::\n  Table header, footer and body row tag definitions. 'headrow' and\n  'footrow' table definition entries default to 'bodyrow' if\n  they are undefined.\n\nheaddata, footdata, bodydata::\n  Table header, footer and body data tag definitions. 'headdata' and\n  'footdata' table definition entries default to 'bodydata' if they\n  are undefined.\n\nparagraph::\n  If the 'paragraph' tag is specified then blank lines in the cell\n  data are treated as paragraph delimiters and marked up using this\n  tag.\n\n[[X4]]\nTable behavior is also influenced by the following `[miscellaneous]`\nconfiguration file entries:\n\npagewidth::\n  This integer value is the printable width of the output media. See\n  <<X69,table attributes>>.\n\npageunits::\n  The units of width in output markup width attribute values.\n\n.Table definition behavior\n- The output markup generation is specifically designed to work with\n  the HTML and CALS (DocBook) table models, but should be adaptable to\n  most XML table schema.\n- Table definitions can be ``mixed in'' from multiple cascading\n  configuration files.\n- New table definitions inherit the default table and table tags\n  definitions (`[tabledef-default]` and `[tabletags-default]`) so you\n  only need to override those conf file entries that require\n  modification.\n\n\n[[X59]]\nFilters\n-------\nAsciiDoc filters allow external commands to process AsciiDoc\n'Paragraphs', 'DelimitedBlocks' and 'Table' content. Filters are\nprimarily an extension mechanism for generating specialized outputs.\nFilters are implemented using external commands which are specified in\nconfiguration file definitions.\n\nThere's nothing special about the filters, they're just standard UNIX\nfilters: they read text from the standard input, process it, and write\nto the standard output.\n\nThe asciidoc(1) command `--filter` option can be used to install and\nremove filters. The same option is used to unconditionally load a\nfilter.\n\nAttribute substitution is performed on the filter command prior to\nexecution -- attributes can be used to pass parameters from the\nAsciiDoc source document to the filter.\n\nWARNING: Filters sometimes included executable code. Before installing\na filter you should verify that it is from a trusted source.\n\nFilter Search Paths\n~~~~~~~~~~~~~~~~~~~\nIf the filter command does not specify a directory path then\nasciidoc(1) recursively searches for the executable filter command:\n\n- First it looks in the user's `$HOME/.asciidoc/filters` directory.\n- Next the global filters directory (usually `/etc/asciidoc/filters`\n  or `/usr/local/etc/asciidoc`) directory is searched.\n- Then it looks in the asciidoc(1) `./filters` directory.\n- Finally it relies on the executing shell to search the environment\n  search path (`$PATH`).\n\nStandard practice is to install each filter in it's own sub-directory\nwith the same name as the filter's style definition. For example the\nmusic filter's style name is 'music' so it's configuration and filter\nfiles are stored in the `filters/music` directory.\n\nFilter Configuration Files\n~~~~~~~~~~~~~~~~~~~~~~~~~~\nFilters are normally accompanied by a configuration file containing a\nParagraph or DelimitedBlock definition along with corresponding markup\ntemplates.\n\nWhile it is possible to create new 'Paragraph' or 'DelimitedBlock'\ndefinitions the preferred way to implement a filter is to add a\n<<X23,style>> to the existing Paragraph and ListingBlock definitions\n(all filters shipped with AsciiDoc use this technique). The filter is\napplied to the paragraph or delimited block by preceding it with an\nattribute list: the first positional attribute is the style name,\nremaining attributes are normally filter specific parameters.\n\nasciidoc(1) auto-loads all `.conf` files found in the filter search\npaths unless the container directory also contains a file named\n`__noautoload__` (see previous section). The `__noautoload__` feature\nis used for filters that will be loaded manually using the `--filter`\noption.\n\n[[X56]]\nExample Filter\n~~~~~~~~~~~~~~\nAsciiDoc comes with a toy filter for highlighting source code keywords\nand comments.  See also the `./filters/code/code-filter-readme.txt`\nfile.\n\nNOTE: The purpose of this toy filter is to demonstrate how to write a\nfilter -- it's much to simplistic to be passed off as a code syntax\nhighlighter.  If you want a full featured multi-language highlighter\nuse the {website}source-highlight-filter.html[source code highlighter\nfilter].\n\nBuilt-in filters\n~~~~~~~~~~~~~~~~\nThe AsciiDoc distribution includes 'source', 'music', 'latex' and\n'graphviz' filters, details are on the\n{website}index.html#_filters[AsciiDoc website].\n\n[cols=\"1e,5\",frame=\"topbot\",options=\"header\"]\n.Built-in filters list\n|====================================================================\n|Filter name |Description\n\n|music\n|A {website}music-filter.html[music filter] is included in the\ndistribution `./filters/` directory. It translates music in\nhttp://lilypond.org/[LilyPond] or http://abcnotation.org.uk/[ABC]\nnotation to standard classical notation.\n\n|source\n|A {website}source-highlight-filter.html[source code highlight filter]\nis included in the distribution `./filters/` directory.\n\n|latex\n|The {website}latex-filter.html[AsciiDoc LaTeX filter] translates\nLaTeX source to a PNG image that is automatically inserted into the\nAsciiDoc output documents.\n\n|graphviz\n|Gouichi Iisaka has written a http://www.graphviz.org/[Graphviz]\nfilter for AsciiDoc.  Graphviz generates diagrams from a textual\nspecification. Gouichi Iisaka's Graphviz filter is included in the\nAsciiDoc distribution. Here are some\n{website}asciidoc-graphviz-sample.html[AsciiDoc Graphviz examples].\n\n|====================================================================\n\n[[X58]]\nFilter plugins\n~~~~~~~~~~~~~~\nFilter <<X101,plugins>> are a mechanism for distributing AsciiDoc\nfilters.  A filter plugin is a Zip file containing the files that\nconstitute a filter.  The asciidoc(1) `--filter` option is used to\nload and manage filer <<X101,plugins>>.\n\n- Filter plugins <<X27,take precedence>> over built-in filters with\n  the same name.\n- By default filter plugins are installed in\n  `$HOME/.asciidoc/filters/<filter>` where `<filter>` is the filter\n  name.\n\n\n[[X101]]\nPlugins\n-------\nThe AsciiDoc plugin architecture is an extension mechanism that allows\nadditional <<X100,backends>>, <<X58,filters>> and <<X99,themes>> to be\nadded to AsciiDoc.\n\n- A plugin is a Zip file containing an AsciiDoc backend, filter or\n  theme (configuration files, stylesheets, scripts, images).\n- The asciidoc(1) `--backend`, `--filter` and `--theme` command-line\n  options are used to load and manage plugins. Each of these options\n  responds to the plugin management 'install', 'list', 'remove' and\n  'build' commands.\n- The plugin management command names are reserved and cannot be used\n  for filter, backend or theme names.\n- The plugin Zip file name always begins with the backend, filter or\n  theme name.\n\nPlugin commands and conventions are documented in the asciidoc(1) man\npage.  You can find lists of plugins on the\n{website}plugins.html[AsciiDoc website].\n\n\n[[X36]]\nHelp Commands\n-------------\nThe asciidoc(1) command has a `--help` option which prints help topics\nto stdout. The default topic summarizes asciidoc(1) usage:\n\n  $ asciidoc --help\n\nTo print a help topic specify the topic name as a command argument.\nHelp topic names can be shortened so long as they are not ambiguous.\nExamples:\n\n  $ asciidoc --help manpage\n  $ asciidoc -h m              # Short version of previous example.\n  $ asciidoc --help syntax\n  $ asciidoc -h s              # Short version of previous example.\n\nCustomizing Help\n~~~~~~~~~~~~~~~~\nTo change, delete or add your own help topics edit a help\nconfiguration file.  The help file name `help-<lang>.conf` is based on\nthe setting of the `lang` attribute, it defaults to `help.conf`\n(English).  The <<X27,help file location>> will depend on whether you\nwant the topics to apply to all users or just the current user.\n\nThe help topic files have the same named section format as other\n<<X7,configuration files>>. The `help.conf` files are stored in the\nsame locations and loaded in the same order as other configuration\nfiles.\n\nWhen the `--help` command-line option is specified AsciiDoc loads the\nappropriate help files and then prints the contents of the section\nwhose name matches the help topic name.  If a topic name is not\nspecified `default` is used. You don't need to specify the whole help\ntopic name on the command-line, just enough letters to ensure it's not\nambiguous. If a matching help file section is not found a list of\navailable topics is printed.\n\n\nTips and Tricks\n---------------\n\nKnow Your Editor\n~~~~~~~~~~~~~~~~\nWriting AsciiDoc documents will be a whole lot more pleasant if you\nknow your favorite text editor. Learn how to indent and reformat text\nblocks, paragraphs, lists and sentences. <<X20,Tips for 'vim' users>>\nfollow.\n\n[[X20]]\nVim Commands for Formatting AsciiDoc\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nText Wrap Paragraphs\n^^^^^^^^^^^^^^^^^^^^\nUse the vim `:gq` command to reformat paragraphs. Setting the\n'textwidth' sets the right text wrap margin; for example:\n\n  :set textwidth=70\n\nTo reformat a paragraph:\n\n1. Position the cursor at the start of the paragraph.\n2. Type `gq}`.\n\nExecute `:help gq` command to read about the vim gq command.\n\n[TIP]\n=====================================================================\n- Assign the `gq}` command to the Q key with the `nnoremap Q gq}`\n  command or put it in your `~/.vimrc` file to so it's always\n  available (see the <<X61, Example `~/.vimrc` file>>).\n- Put `set` commands in your `~/.vimrc` file so you don't have to\n  enter them manually.\n- The Vim website (http://www.vim.org) has a wealth of resources,\n  including scripts for automated spell checking and ASCII Art\n  drawing.\n=====================================================================\n\nFormat Lists\n^^^^^^^^^^^^\nThe `gq` command can also be used to format bulleted, numbered and\ncallout lists. First you need to set the `comments`, `formatoptions`\nand `formatlistpat` (see the <<X61, Example `~/.vimrc` file>>).\n\nNow you can format simple lists that use dash, asterisk, period and\nplus bullets along with numbered ordered lists:\n\n1. Position the cursor at the start of the list.\n2. Type `gq}`.\n\nIndent Paragraphs\n^^^^^^^^^^^^^^^^^\nIndent whole paragraphs by indenting the fist line with the desired\nindent and then executing the `gq}` command.\n\n[[X61]]\nExample `~/.vimrc` File\n^^^^^^^^^^^^^^^^^^^^^^^\n---------------------------------------------------------------------\n\" Use bold bright fonts.\nset background=dark\n\n\" Show tabs and trailing characters.\nset listchars=tab:,trail:\nset list\n\n\" Don't highlight searched text.\nhighlight clear Search\n\n\" Don't move to matched text while search pattern is being entered.\nset noincsearch\n\n\" Reformat paragraphs and list.\nnnoremap R gq}\n\n\" Delete trailing white space and Dos-returns and to expand tabs to spaces.\nnnoremap S :set et<CR>:retab!<CR>:%s/[\\r \\t]\\+$//<CR>\n\nautocmd BufRead,BufNewFile *.txt,README,TODO,CHANGELOG,NOTES\n        \\ setlocal autoindent expandtab tabstop=8 softtabstop=2 shiftwidth=2 filetype=asciidoc\n        \\ textwidth=70 wrap formatoptions=tcqn\n        \\ formatlistpat=^\\\\s*\\\\d\\\\+\\\\.\\\\s\\\\+\\\\\\\\|^\\\\s*<\\\\d\\\\+>\\\\s\\\\+\\\\\\\\|^\\\\s*[a-zA-Z.]\\\\.\\\\s\\\\+\\\\\\\\|^\\\\s*[ivxIVX]\\\\+\\\\.\\\\s\\\\+\n        \\ comments=s1:/*,ex:*/,://,b:#,:%,:XCOMM,fb:-,fb:*,fb:+,fb:.,fb:>\n---------------------------------------------------------------------\n\nTroubleshooting\n~~~~~~~~~~~~~~~\nAsciiDoc diagnostic features are detailed in the <<X82,Diagnostics\nappendix>>.\n\nGotchas\n~~~~~~~\nIncorrect character encoding::\n    If you get an error message like `'UTF-8' codec can't decode ...`\n    then you source file contains invalid UTF-8 characters -- set the\n    AsciiDoc <<X54,encoding attribute>> for the correct character set\n    (typically ISO-8859-1 (Latin-1) for European languages).\n\nInvalid output::\n    AsciiDoc attempts to validate the input AsciiDoc source but makes\n    no attempt to validate the output markup, it leaves that to\n    external tools such as `xmllint(1)` (integrated into `a2x(1)`).\n    Backend validation cannot be hardcoded into AsciiDoc because\n    backends are dynamically configured. The following example\n    generates valid HTML but invalid DocBook (the DocBook `literal`\n    element cannot contain an `emphasis` element):\n\n    +monospaced text with an _emphasized_ word+\n\nMisinterpreted text formatting::\n    You can suppress markup expansion by placing a backslash character\n    immediately in front of the element. The following example\n    suppresses inline monospaced formatting:\n\n    \\+1 for C++.\n\nOverlapping text formatting::\n    Overlapping text formatting will generate illegal overlapping\n    markup tags which will result in downstream XML parsing errors.\n    Here's an example:\n\n    Some *strong markup _that overlaps* emphasized markup_.\n\nAmbiguous underlines::\n    A DelimitedBlock can immediately follow a paragraph without an\n    intervening blank line, but be careful, a single line paragraph\n    underline may be misinterpreted as a section title underline\n    resulting in a ``closing block delimiter expected'' error.\n\nAmbiguous ordered list items::\n    Lines beginning with numbers at the end of sentences will be\n    interpreted as ordered list items.  The following example\n    (incorrectly) begins a new list with item number 1999:\n\n    He was last sighted in\n    1999. Since then things have moved on.\n+\nThe 'list item out of sequence' warning makes it unlikely that this\nproblem will go unnoticed.\n\nSpecial characters in attribute values::\n    Special character substitution precedes attribute substitution so\n    if attribute values contain special characters you may, depending\n    on the substitution context, need to escape the special characters\n    yourself. For example:\n\n    $ asciidoc -a 'orgname=Bill &amp; Ben Inc.' mydoc.txt\n\nAttribute lists::\n    If any named attribute entries are present then all string\n    attribute values must be quoted.  For example:\n\n    [\"Desktop screenshot\",width=32]\n\n[[X90]]\nCombining separate documents\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou have a number of stand-alone AsciiDoc documents that you want to\nprocess as a single document. Simply processing them with a series of\n`include` macros won't work because the documents contain (level 0)\ndocument titles.  The solution is to create a top level wrapper\ndocument and use the `leveloffset` attribute to push them all down one\nlevel. For example:\n\n[listing]\n.....................................................................\nCombined Document Title\n=======================\n\n// Push titles down one level.\n:leveloffset: 1\n\n\\include::document1.txt[]\n\n// Return to normal title levels.\n:leveloffset: 0\n\nA Top Level Section\n-------------------\nLorum ipsum.\n\n// Push titles down one level.\n:leveloffset: 1\n\n\\include::document2.txt[]\n\n\\include::document3.txt[]\n.....................................................................\n\nThe document titles in the included documents will now be processed as\nlevel 1 section titles, level 1 sections as level 2 sections and so\non.\n\n- Put a blank line between the `include` macro lines to ensure the\n  title of the included document is not seen as part of the last\n  paragraph of the previous document.\n- You won't want non-title document header lines (for example, Author\n  and Revision lines) in the included files -- conditionally exclude\n  them if they are necessary for stand-alone processing.\n\nProcessing document sections separately\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou have divided your AsciiDoc document into separate files (one per\ntop level section) which are combined and processed with the following\ntop level document:\n\n---------------------------------------------------------------------\nCombined Document Title\n=======================\nJoe Bloggs\nv1.0, 12-Aug-03\n\n\\include::section1.txt[]\n\n\\include::section2.txt[]\n\n\\include::section3.txt[]\n---------------------------------------------------------------------\n\nYou also want to process the section files as separate documents.\nThis is easy because asciidoc(1) will quite happily process\n`section1.txt`, `section2.txt` and `section3.txt` separately -- the\nresulting output documents contain the section but have no document\ntitle.\n\nProcessing document snippets\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nUse the `-s` (`--no-header-footer`) command-line option to suppress\nheader and footer output, this is useful if the processed output is to\nbe included in another file. For example:\n\n  $ asciidoc -sb docbook section1.txt\n\nasciidoc(1) can be used as a filter, so you can pipe chunks of text\nthrough it. For example:\n\n  $ echo 'Hello *World!*' | asciidoc -s -\n  <div class=\"paragraph\"><p>Hello <strong>World!</strong></p></div>\n\nBadges in HTML page footers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee the `[footer]` section in the AsciiDoc distribution `xhtml11.conf`\nconfiguration file.\n\nPretty printing AsciiDoc output\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nIf the indentation and layout of the asciidoc(1) output is not to your\nliking you can:\n\n1. Change the indentation and layout of configuration file markup\n   template sections. The `{empty}` attribute is useful for outputting\n   trailing blank lines in markup templates.\n\n2. Use Dave Raggett's http://tidy.sourceforge.net/[HTML Tidy] program\n   to tidy asciidoc(1) output. Example:\n\n   $ asciidoc -b docbook -o - mydoc.txt | tidy -indent -xml >mydoc.xml\n\n3. Use the `xmllint(1)` format option. Example:\n\n   $ xmllint --format mydoc.xml\n\nSupporting minor DocBook DTD variations\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe conditional inclusion of DocBook SGML markup at the end of the\ndistribution `docbook45.conf` file illustrates how to support minor\nDTD variations. The included sections override corresponding entries\nfrom preceding sections.\n\nCreating stand-alone HTML documents\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nIf you've ever tried to send someone an HTML document that includes\nstylesheets and images you'll know that it's not as straight-forward\nas exchanging a single file.  AsciiDoc has options to create\nstand-alone documents containing embedded images, stylesheets and\nscripts.  The following AsciiDoc command creates a single file\ncontaining <<X66,embedded images>>, CSS stylesheets, and JavaScript\n(for table of contents and footnotes):\n\n  $ asciidoc -a data-uri -a icons -a toc -a max-width=55em article.txt\n\nYou can view the HTML file here: {website}article-standalone.html[]\n\nShipping stand-alone AsciiDoc source\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nReproducing presentation documents from someone else's source has one\nmajor problem: unless your configuration files are the same as the\ncreator's you won't get the same output.\n\nThe solution is to create a single backend specific configuration file\nusing the asciidoc(1) `-c` (`--dump-conf`) command-line option. You\nthen ship this file along with the AsciiDoc source document plus the\n`asciidoc.py` script. The only end user requirement is that they have\nPython installed (and that they consider you a trusted source). This\nexample creates a composite HTML configuration file for `mydoc.txt`:\n\n  $ asciidoc -cb xhtml11 mydoc.txt > mydoc-xhtml11.conf\n\nShip `mydoc.txt`, `mydoc-html.conf`, and `asciidoc.py`. With\nthese three files (and a Python interpreter) the recipient can\nregenerate the HMTL output:\n\n  $ ./asciidoc.py -eb xhtml11 mydoc.txt\n\nThe `-e` (`--no-conf`) option excludes the use of implicit\nconfiguration files, ensuring that only entries from the\n`mydoc-html.conf` configuration are used.\n\nInserting blank space\n~~~~~~~~~~~~~~~~~~~~~\nAdjust your style sheets to add the correct separation between block\nelements. Inserting blank paragraphs containing a single non-breaking\nspace character `{nbsp}` works but is an ad hoc solution compared\nto using style sheets.\n\nClosing open sections\n~~~~~~~~~~~~~~~~~~~~~\nYou can close off section tags up to level `N` by calling the\n`eval::[Section.setlevel(N)]` system macro. This is useful if you\nwant to include a section composed of raw markup. The following\nexample includes a DocBook glossary division at the top section level\n(level 0):\n\n---------------------------------------------------------------------\n\\ifdef::basebackend-docbook[]\n\n\\eval::[Section.setlevel(0)]\n\n+++++++++++++++++++++++++++++++\n<glossary>\n  <title>Glossary</title>\n  <glossdiv>\n  ...\n  </glossdiv>\n</glossary>\n+++++++++++++++++++++++++++++++\n\\endif::basebackend-docbook[]\n---------------------------------------------------------------------\n\nValidating output files\n~~~~~~~~~~~~~~~~~~~~~~~\nUse `xmllint(1)` to check the AsciiDoc generated markup is both well\nformed and valid. Here are some examples:\n\n  $ xmllint --nonet --noout --valid docbook-file.xml\n  $ xmllint --nonet --noout --valid xhtml11-file.html\n  $ xmllint --nonet --noout --valid --html html4-file.html\n\nThe `--valid` option checks the file is valid against the document\ntype's DTD, if the DTD is not installed in your system's catalog then\nit will be fetched from its Internet location. If you omit the\n`--valid` option the document will only be checked that it is well\nformed.\n\nThe online http://validator.w3.org/#validate_by_uri+with_options[W3C\nMarkup Validation Service] is the defacto standard when it comes to\nvalidating HTML (it validates all HTML standards including HTML5).\n\n\n:numbered!:\n\n[glossary]\nGlossary\n--------\n[glossary]\n[[X8]] Block element::\n    An AsciiDoc block element is a document entity composed of one or\n    more whole lines of text.\n\n[[X34]] Inline element::\n    AsciiDoc inline elements occur within block element textual\n    content, they perform formatting and substitution tasks.\n\nFormal element::\n    An AsciiDoc block element that has a BlockTitle. Formal elements\n    are normally listed in front or back matter, for example lists of\n    tables, examples and figures.\n\nVerbatim element::\n    The word verbatim indicates that white space and line breaks in\n    the source document are to be preserved in the output document.\n\n\n[appendix]\nMigration Notes\n---------------\n[[X53]]\nVersion 7 to version 8\n~~~~~~~~~~~~~~~~~~~~~~\n- A new set of quotes has been introduced which may match inline text\n  in existing documents -- if they do you'll need to escape the\n  matched text with backslashes.\n- The index entry inline macro syntax has changed -- if your documents\n  include indexes you may need to edit them.\n- Replaced a2x(1) `--no-icons` and `--no-copy` options with their\n  negated equivalents: `--icons` and `--copy` respectively. The\n  default behavior has also changed -- the use of icons and copying of\n  icon and CSS files must be specified explicitly with the `--icons`\n  and `--copy` options.\n\nThe rationale for the changes can be found in the AsciiDoc\n`CHANGELOG`.\n\nNOTE: If you want to disable unconstrained quotes, the new alternative\nconstrained quotes syntax and the new index entry syntax then you can\ndefine the attribute `asciidoc7compatible` (for example by using the\n`-a asciidoc7compatible` command-line option).\n\n[[X38]]\n[appendix]\nPackager Notes\n--------------\nRead the `README` and `INSTALL` files (in the distribution root\ndirectory) for install prerequisites and procedures.  The distribution\n`Makefile.in` (used by `configure` to generate the `Makefile`) is the\ncanonical installation procedure.\n\n\n[[X39]]\n[appendix]\nAsciiDoc Safe Mode\n-------------------\nAsciiDoc 'safe mode' skips potentially dangerous scripted sections in\nAsciiDoc source files by inhibiting the execution of arbitrary code or\nthe inclusion of arbitrary files.\n\nThe safe mode is disabled by default, it can be enabled with the\nasciidoc(1) `--safe` command-line option.\n\n.Safe mode constraints\n- `eval`, `sys` and `sys2` executable attributes and block macros are\n  not executed.\n- `include::<filename>[]` and `include1::<filename>[]` block macro\n  files must reside inside the parent file's directory.\n- `{include:<filename>}` executable attribute files must reside\n  inside the source document directory.\n- Passthrough Blocks are dropped.\n\n[WARNING]\n=====================================================================\nThe safe mode is not designed to protect against unsafe AsciiDoc\nconfiguration files. Be especially careful when:\n\n1. Implementing filters.\n2. Implementing elements that don't escape special characters.\n3. Accepting configuration files from untrusted sources.\n=====================================================================\n\n\n[appendix]\nUsing AsciiDoc with non-English Languages\n-----------------------------------------\nAsciiDoc can process UTF-8 character sets but there are some things\nyou need to be aware of:\n\n- If you are generating output documents using a DocBook toolchain\n  then you should set the AsciiDoc `lang` attribute to the appropriate\n  language (it defaults to `en` (English)). This will ensure things\n  like table of contents, figure and table captions and admonition\n  captions are output in the specified language.  For example:\n\n  $ a2x -a lang=es doc/article.txt\n\n- If you are outputting HTML directly from asciidoc(1) you'll\n  need to set the various `*_caption` attributes to match your target\n  language (see the list of captions and titles in the `[attributes]`\n  section of the distribution `lang-*.conf` files). The easiest way is\n  to create a language `.conf` file (see the AsciiDoc's `lang-en.conf`\n  file).\n+\nNOTE: You still use the 'NOTE', 'CAUTION', 'TIP', 'WARNING',\n'IMPORTANT' captions in the AsciiDoc source, they get translated in\nthe HTML output file.\n\n- asciidoc(1) automatically loads configuration files named like\n  `lang-<lang>.conf` where `<lang>` is a two letter language code that\n  matches the current AsciiDoc `lang` attribute. See also\n  <<X27,Configuration File Names and Locations>>.\n\n\n[appendix]\nVim Syntax Highlighter\n----------------------\nSyntax highlighting is incredibly useful, in addition to making\nreading AsciiDoc documents much easier syntax highlighting also helps\nyou catch AsciiDoc syntax errors as you write your documents.\n\nThe AsciiDoc `./vim/` distribution directory contains Vim syntax\nhighlighter and filetype detection scripts for AsciiDoc.  Syntax\nhighlighting makes it much easier to spot AsciiDoc syntax errors.\n\nIf Vim is installed on your system the AsciiDoc installer\n(`install.sh`) will automatically install the vim scripts in the Vim\nglobal configuration directory (`/etc/vim`).\n\nYou can also turn on syntax highlighting by adding the following line\nto the end of you AsciiDoc source files:\n\n  // vim: set syntax=asciidoc:\n\nTIP: Bold fonts are often easier to read, use the Vim `:set\nbackground=dark` command to set bold bright fonts.\n\nNOTE: There are a number of alternative syntax highlighters for\nvarious editors listed on the {website}[AsciiDoc website].\n\nLimitations\n~~~~~~~~~~~\nThe current implementation does a reasonable job but on occasions gets\nthings wrong:\n\n- Nested quoted text formatting is highlighted according to the outer\n  format.\n- If a closing Example Block delimiter is sometimes mistaken for a\n  title underline. A workaround is to insert a blank line before the\n  closing delimiter.\n- Lines within a paragraph starting with equals characters may be\n  highlighted as single-line titles.\n- Lines within a paragraph beginning with a period may be highlighted\n  as block titles.\n\n\n[[X74]]\n[appendix]\nAttribute Options\n-----------------\nHere is the list of predefined <<X75,attribute list options>>:\n\n\n[cols=\"2e,2,2,5\",frame=\"topbot\",options=\"header\"]\n|====================================================================\n|Option|Backends|AsciiDoc Elements|Description\n\n|autowidth |xhtml11, html5, html4 |table|\nThe column widths are determined by the browser, not the AsciiDoc\n'cols' attribute. If there is no 'width' attribute the table width is\nalso left up to the browser.\n\n|unbreakable |xhtml11, html5 |block elements|\n'unbreakable' attempts to keep the block element together on a single\nprinted page c.f. the 'breakable' and 'unbreakable' docbook (XSL/FO)\noptions below.\n\n|breakable, unbreakable |docbook (XSL/FO) |table, example, block image|\nThe 'breakable' options allows block elements to break across page\nboundaries; 'unbreakable' attempts to keep the block element together\non a single page. If neither option is specified the default XSL\nstylesheet behavior prevails.\n\n|compact |docbook, xhtml11, html5 |bulleted list, numbered list|\nMinimizes vertical space in the list\n\n|footer |docbook, xhtml11, html5, html4 |table|\nThe last row of the table is rendered as a footer.\n\n|header |docbook, xhtml11, html5, html4 |table|\nThe first row of the table is rendered as a header.\n\n|pgwide |docbook (XSL/FO) |table, block image, horizontal labeled list|\nSpecifies that the element should be rendered across the full text\nwidth of the page irrespective of the current indentation.\n\n|strong |xhtml11, html5, html4 |labeled lists|\nEmboldens label text.\n|====================================================================\n\n\n[[X82]]\n[appendix]\nDiagnostics\n-----------\nThe `asciidoc(1)` `--verbose` command-line option prints additional\ninformation to stderr: files processed, filters processed, warnings,\nsystem attribute evaluation.\n\nA special attribute named 'trace' enables the output of\nelement-by-element diagnostic messages detailing output markup\ngeneration to stderr.  The 'trace' attribute can be set on the\ncommand-line or from within the document using <<X18,Attribute\nEntries>> (the latter allows tracing to be confined to specific\nportions of the document).\n\n- Trace messages print the source file name and line number and the\n  trace name followed by related markup.\n- 'trace names' are normally the names of AsciiDoc elements (see the\n  list below).\n- The trace message is only printed if the 'trace' attribute value\n  matches the start of a 'trace name'. The 'trace' attribute value can\n  be any Python regular expression.  If a trace value is not specified\n  all trace messages will be printed (this can result in large amounts\n  of output if applied to the whole document).\n\n- In the case of inline substitutions:\n  * The text before and after the substitution is printed; the before\n    text is preceded by a line containing `<<<` and the after text by\n    a line containing `>>>`.\n  * The 'subs' trace value is an alias for all inline substitutions.\n\n.Trace names\n.....................................................................\n<blockname> block close\n<blockname> block open\n<subs>\ndropped line (a line containing an undefined attribute reference).\nfloating title\nfooter\nheader\nlist close\nlist entry close\nlist entry open\nlist item close\nlist item open\nlist label close\nlist label open\nlist open\nmacro block (a block macro)\nname (man page NAME section)\nparagraph\npreamble close\npreamble open\npush blockname\npop blockname\nsection close\nsection open: level <level>\nsubs (all inline substitutions)\ntable\n.....................................................................\n\nWhere:\n\n- `<level>` is section level number '0...4'.\n- `<blockname>` is a delimited block name: 'comment', 'sidebar',\n  'open', 'pass', 'listing', 'literal', 'quote', 'example'.\n- `<subs>` is an inline substitution type:\n  'specialcharacters','quotes','specialwords', 'replacements',\n  'attributes','macros','callouts', 'replacements2', 'replacements3'.\n\nCommand-line examples:\n\n. Trace the entire document.\n\n  $ asciidoc -a trace mydoc.txt\n\n. Trace messages whose names start with `quotes` or `macros`:\n\n  $ asciidoc -a 'trace=quotes|macros'  mydoc.txt\n\n. Print the first line of each trace message:\n\n  $ asciidoc -a trace mydoc.txt 2>&1 | grep ^TRACE:\n\nAttribute Entry examples:\n\n. Begin printing all trace messages:\n\n  :trace:\n\n. Print only matched trace messages:\n\n  :trace: quotes|macros\n\n. Turn trace messages off:\n\n  :trace!:\n\n\n[[X88]]\n[appendix]\nBackend Attributes\n------------------\nThis table contains a list of optional attributes that influence the\ngenerated outputs.\n\n[cols=\"1e,1,5a\",frame=\"topbot\",options=\"header\"]\n|====================================================================\n|Name |Backends |Description\n\n|badges |xhtml11, html5 |\nLink badges ('XHTML 1.1' and 'CSS') in document footers. By default\nbadges are omitted ('badges' is undefined).\n\nNOTE: The path names of images, icons and scripts are relative path\nnames to the output document not the source document.\n\n|data-uri |xhtml11, html5 |\nEmbed images using the <<X66,data: uri scheme>>.\n\n|css-signature |html5, xhtml11 |\nSet a 'CSS signature' for the document (sets the 'id' attribute of the\nHTML 'body' element). CSS signatures provide a mechanism that allows\nusers to personalize the document appearance. The term 'CSS signature'\nwas http://archivist.incutio.com/viewlist/css-discuss/13291[coined by\nEric Meyer].\n\n\n|disable-javascript |xhtml11, html5 |\nIf the `disable-javascript` attribute is defined the `asciidoc.js`\nJavaScript is not embedded or linked to the output document.  By\ndefault AsciiDoc automatically embeds or links the `asciidoc.js`\nJavaScript to the output document. The script dynamically generates\n<<X91,table of contents>> and <<X92,footnotes>>.\n\n|[[X97]] docinfo, docinfo1, docinfo2 |All backends |\nThese three attributes control which <<X87,document information\nfiles>> will be included in the the header of the output file:\n\ndocinfo:: Include `<filename>-docinfo.<ext>`\ndocinfo1:: Include `docinfo.<ext>`\ndocinfo2:: Include `docinfo.<ext>` and `<filename>-docinfo.<ext>`\n\nWhere `<filename>` is the file name (sans extension) of the AsciiDoc\ninput file and `<ext>` is `.html` for HTML outputs or `.xml` for\nDocBook outputs. If the input file is the standard input then the\noutput file name is used. The following example will include the\n`mydoc-docinfo.xml` docinfo file in the DocBook `mydoc.xml` output\nfile:\n\n  $ asciidoc -a docinfo -b docbook mydoc.txt\n\nThis next example will include `docinfo.html` and `mydoc-docinfo.html`\ndocinfo files in the HTML output file:\n\n  $ asciidoc -a docinfo2 -b html4 mydoc.txt\n\n\n|[[X54]]encoding |html4, html5, xhtml11, docbook |\nSet the input and output document character set encoding. For example\nthe `--attribute encoding=ISO-8859-1` command-line option will set the\ncharacter set encoding to `ISO-8859-1`.\n\n- The default encoding is UTF-8.\n- This attribute specifies the character set in the output document.\n- The encoding name must correspond to a Python codec name or alias.\n- The 'encoding' attribute can be set using an AttributeEntry inside\n  the document header. For example:\n\n  :encoding: ISO-8859-1\n\n|[[X45]]icons |xhtml11, html5 |\nLink admonition paragraph and admonition block icon images and badge\nimages. By default 'icons' is undefined and text is used in place of\nicon images.\n\n|[[X44]]iconsdir |html4, html5, xhtml11, docbook |\nThe name of the directory containing linked admonition icons,\nnavigation icons and the `callouts` sub-directory (the `callouts`\nsub-directory contains <<X105,callout>> number images). 'iconsdir'\ndefaults to `./images/icons`.\n\n|imagesdir |html4, html5, xhtml11, docbook |\nIf this attribute is defined it is prepended to the target image file\nname paths in inline and block image macros.\n\n|keywords, description, title |html4, html5, xhtml11 |\nThe 'keywords' and 'description' attributes set the correspondingly\nnamed HTML meta tag contents; the 'title' attribute sets the HTML\ntitle tag contents.  Their principle use is for SEO (Search Engine\nOptimisation).  All three are optional, but if they are used they must\nappear in the document header (or on the command-line). If 'title' is\nnot specified the AsciiDoc document title is used.\n\n|linkcss |html5, xhtml11 |\nLink CSS stylesheets and JavaScripts. By default 'linkcss' is\nundefined in which case stylesheets and scripts are automatically\nembedded in the output document.\n\n|[[X103]]max-width |html5, xhtml11 |\nSet the document maximum display width (sets the 'body' element CSS\n'max-width' property).\n\n|numbered |html4, html5, xhtml11, docbook (XSL Stylesheets) |\nAdds section numbers to section titles. The 'docbook' backend ignores\n'numbered' attribute entries after the document header.\n\n|plaintext | All backends |\nIf this global attribute is defined all inline substitutions are\nsuppressed and block indents are retained.  This option is useful when\ndealing with large amounts of imported plain text.\n\n|quirks |xhtml11 |\nInclude the `xhtml11-quirks.conf` configuration file and\n`xhtml11-quirks.css` <<X35,stylesheet>> to work around IE6 browser\nincompatibilities. This feature is deprecated and its use is\ndiscouraged -- documents are still viewable in IE6 without it.\n\n|revremark |docbook |\nA short summary of changes in this document revision. Must be defined\nprior to the first document section. The document also needs to be\ndated to output this attribute.\n\n|scriptsdir |html5, xhtml11 |\nThe name of the directory containing linked JavaScripts.\nSee <<X35,HTML stylesheets and JavaScript locations>>.\n\n|sgml |docbook45 |\nThe `--backend=docbook45` command-line option produces DocBook 4.5\nXML.  You can produce the older DocBook SGML format using the\n`--attribute sgml` command-line option.\n\n|stylesdir |html5, xhtml11 |\nThe name of the directory containing linked or embedded\n<<X35,stylesheets>>.\nSee <<X35,HTML stylesheets and JavaScript locations>>.\n\n|stylesheet |html5, xhtml11 |\nThe file name of an optional additional CSS <<X35,stylesheet>>.\n\n|theme |html5, xhtml11 |\nUse alternative stylesheet (see <<X35,Stylesheets>>).\n\n|[[X91]]toc |html5, xhtml11, docbook (XSL Stylesheets) |\nAdds a table of contents to the start of an article or book document.\nThe `toc` attribute can be specified using the `--attribute toc`\ncommand-line option or a `:toc:` attribute entry in the document\nheader. The 'toc' attribute is defined by default when the 'docbook'\nbackend is used. To disable table of contents generation undefine the\n'toc' attribute by putting a `:toc!:` attribute entry in the document\nheader or from the command-line with an `--attribute toc!` option.\n\n*xhtml11 and html5 backends*\n\n- JavaScript needs to be enabled in your browser.\n- The following example generates a numbered table of contents using a\n  JavaScript embedded in the `mydoc.html` output document:\n\n  $ asciidoc -a toc -a numbered mydoc.txt\n\n|toc2 |html5, xhtml11 |\nAdds a scrollable table of contents in the left hand margin of an\narticle or book document. Use the 'max-width' attribute to change the\ncontent width. In all other respects behaves the same as the 'toc'\nattribute.\n\n|toc-placement |html5, xhtml11 |\nWhen set to 'auto' (the default value) asciidoc(1) will place the\ntable of contents in the document header. When 'toc-placement' is set\nto 'manual' the TOC can be positioned anywhere in the document by\nplacing the `toc::[]` block macro at the point you want the TOC to\nappear.\n\nNOTE: If you use 'toc-placement' then you also have to define the\n<<X91,toc>> attribute.\n\n|toc-title |html5, xhtml11 |\nSets the table of contents title (defaults to 'Table of Contents').\n\n|toclevels |html5, xhtml11 |\nSets the number of title levels (1..4) reported in the table of\ncontents (see the 'toc' attribute above). Defaults to 2 and must be\nused with the 'toc' attribute. Example usage:\n\n  $ asciidoc -a toc -a toclevels=3 doc/asciidoc.txt\n\n|====================================================================\n\n\n[appendix]\nLicense\n-------\nAsciiDoc is free software; you can redistribute it and/or modify it\nunder the terms of the 'GNU General Public License version 2' (GPLv2)\nas published by the Free Software Foundation.\n\nAsciiDoc is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\nGeneral Public License version 2 for more details.\n\nAsciiDoc Highlighter sponsored by O'Reilly Media\n\nCopyright (C) 2002-2011 Stuart Rackham.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/asl.dsl",
    "content": "/*\n * Intel ACPI Component Architecture\n * AML/ASL+ Disassembler version 20180105\n *\n * ASL example\n */\nDefinitionBlock (\"\", \"SSDT\", 1, \"PmRef\", \"Cpu0Ist\", 0x00003000)\n{\n    External (_PR_.CPU0, DeviceObj)\n    External (_SB_.CPUP, UnknownObj)\n\n    Scope (\\_PR.CPU0)\n    {\n        Method (_PCT, 0, NotSerialized)  // _PCT: Performance Control\n        {\n            If (((CFGD & One) && (PDC0 & One)))\n            {\n                Return (Package (0x02)\n                {\n                    ResourceTemplate ()\n                    {\n                        Register (FFixedHW, \n                            0x00,               // Bit Width\n                            0x00,               // Bit Offset\n                            0x0000000000000000, // Address\n                            ,)\n                    }, \n\n                    ResourceTemplate ()\n                    {\n                        Register (FFixedHW, \n                            0x00,               // Bit Width\n                            0x00,               // Bit Offset\n                            0x0000000000000000, // Address\n                            ,)\n                    }\n                })\n            }\n\n            Return (Package (0x02)\n            {\n                ResourceTemplate ()\n                {\n                    Register (SystemIO, \n                        0x10,               // Bit Width\n                        0x00,               // Bit Offset\n                        0x0000000000001000, // Address\n                        ,)\n                }, \n\n                ResourceTemplate ()\n                {\n                    Register (SystemIO, \n                        0x08,               // Bit Width\n                        0x00,               // Bit Offset\n                        0x00000000000000B3, // Address\n                        ,)\n                }\n            })\n        }\n\n        Name (PSDF, Zero)\n        Method (_PSD, 0, NotSerialized)  // _PSD: Power State Dependencies\n        {\n            If (!PSDF)\n            {\n                DerefOf (HPSD [Zero]) [0x04] = TCNT /* External reference */\n                DerefOf (SPSD [Zero]) [0x04] = TCNT /* External reference */\n                PSDF = Ones\n            }\n\n            If ((PDC0 & 0x0800))\n            {\n                Return (HPSD) /* \\_PR_.CPU0.HPSD */\n            }\n\n            Return (SPSD) /* \\_PR_.CPU0.SPSD */\n        }\n    }\n}\n\n"
  },
  {
    "path": "demo/kitchen-sink/docs/assembly_arm32.s",
    "content": ".section .text\n.global _start\n.global msg\n\n_start:\n    bl _asmtest\n    mov r1, r0 // move return value into r1 for syscall write\n\n/* syscall write(int fd, const void *buf, size_t count) */\n    mov r0, #1 \n    //ldr r1, =msg // done by above call to _asmtest\n    ldr r2, =len \n    mov r7, #4 \n    svc #0\n\n/* syscall exit(int status) */\n    mov r0, #0 \n    mov r7, #1 \n    svc #0\n\n_asmtest:                           // Start of the function\n    ldr r0, =msg                    ; loads pointer for msg into r0\n    bx lr                           // Returns from the function\n\n\nmsg:\n.ascii \"Hello, ARM32!\\n\"\nlen = . - msg\n\n// All of these should match as instructions\n\naddhs\nadceqs\nqaddne\nqdaddcs\nsubcc\nsbclo\nrsbmi\nrscpl\nqsubvs\nqdsubvc\nmulhi\nmlals\numullge\numlallt\numaalgt\nsmullle\nsmlalal\nsmulbb\nsmulwb\nsmlabt\nsmlawt\nsmlaltb\nsmuad\nsmladx\nsmlald\nsmusdx\nsmlsd\nsmlsldx\nsmmul\nsmmlar\nsmmls\nmia\nmiaph\nmiatt\nclz\nsadd16\nqsub16\nshadd8\nusub8\nuqaddsubx\nuhsubaddx\nusad8\nusada8\nmov\nmovt\nmovw\nmvn\nmrs\nmsr\nmra\nmar\ncpy\ntst\nteq\nand\neor\norr\nbic\ncmp\ncmn\nssat\nssat16\nusat\nusat16\npkhbt\npkhtb\nsxth\nsxtb16\nsxtb\nuxth\nuxtb16\nuxtb\nsxtah\nsxtab16\nsxtab\nuxtah\nuxtab16\nuxtab\nrev\nrev16\nrevsh\nsel\nb\nbl\nbx\nblx\nblx\nbxj\ncpsid\ncpsie\ncps\nsetend\nsrsia\nrfeib\nsrsda\nrfedb\nsrsfd\nrfeed\nsrsfa\nrfeea\nbkpt\nswi\nsvc\nnop\nldr\nldrt\nldrb\nldrbt\nldrsb\nldrh\nldrsh\nldrd\nldmia\nldmfa\npld\nldrex\nstr\nstrt\nstrb\nstrbt\nstrh\nstrd\nstmia\nstmfd\nstrex\nswp\nswpb\ncdp\ncdp2\nmrc\nmrc2\nmrrc\nmrrc2\nmcr\nmcr2\nmcrr\nmcrr2\nldc\nldc2\nstc\nstc2\n\n// End instruction matching test\n"
  },
  {
    "path": "demo/kitchen-sink/docs/assembly_x86.asm",
    "content": "section\t.text\n    global main         ;must be declared for using gcc\n\nmain:\t                ;tell linker entry point\n\n\tmov\tedx, len\t    ;message length\n\tmov\tecx, msg\t    ;message to write\n\tmov\tebx, 1\t        ;file descriptor (stdout)\n\tmov\teax, 4\t        ;system call number (sys_write)\n\tint\t0x80\t        ;call kernel\n\n\tmov\teax, 1\t        ;system call number (sys_exit)\n\tint\t0x80\t        ;call kernel\n\nsection\t.data\n\nmsg\tdb\t'Hello, world!',0xa\t;our dear string\nlen\tequ\t$ - msg\t\t\t;length of our dear string\n"
  },
  {
    "path": "demo/kitchen-sink/docs/astro.astro",
    "content": "---\nconst visible = true;\nconst name = \"Legend Sabbir\"\n---\n{visible && <p>Show me!</p>}\n\n{visible ? <p>Show me!</p> : <p>Else show me!</p>}\n\n<h1>{name}</h1>"
  },
  {
    "path": "demo/kitchen-sink/docs/autohotkey.ahk",
    "content": "#NoEnv\nSetBatchLines -1\n\nCoordMode Mouse, Screen\nOnExit GuiClose\n\nzoom := 9\n\ncomputeSize(){\n\tglobal as_x\n\tas_x := Round(ws_x/zoom/2 - 0.5)\n\tif (zoom>1) {\n\t\tpix := Round(zoom)\n\t} ele {\n\t\tpix := 1\n\t}\n    ToolTip Message %as_x% %zoom% %ws_x% %hws_x% \n}\n\nhdc_frame := DllCall(\"GetDC\", UInt, MagnifierID)\n\n; comment\nDrawCross(byRef x=\"\", rX,rY,z, dc){\n        ;specify the style, thickness and color of the cross lines\n    h_pen := DllCall( \"gdi32.dll\\CreatePen\", Int, 0, Int, 1, UInt, 0x0000FF)\n}\n\n;Ctrl ^; Shift +; Win #; Alt !\n^NumPadAdd::\n^WheelUp::   \n^;::   ;comment\n    If(zoom < ws_x and ( A_ThisHotKey = \"^WheelUp\" or A_ThisHotKey =\"^NumPadAdd\") )\n\t\tzoom *= 1.189207115         ; sqrt(sqrt(2))\n\tGosub,setZoom\nreturn\n"
  },
  {
    "path": "demo/kitchen-sink/docs/basic.bas",
    "content": "120 OPEN\"R\" #1 \"INVEN.DAT\",39\n125 FIELD#1,1 AS F$,30 AS D$, 2 AS Q$,2 AS R$,4 AS PH\n130 PRINT:PRINT \"FUNCTIONS:\":PRINT\n135 PRINT 1,\"INITIALIZE FILE\"\n140 PRINT 2 \"CREATE A NEW ENTRY\"\n150 PRINT 3,\"DISPLAY INVENTORY FOR ONE PART\"\n160 PRINT 4 \"ADD TO STOCK\"\n170 PRINT 5,\"SUBTRACT FROM STOCK\"\n180 PRINT 6,\"DISPLAY ALL ITEMS BELOW REORDER LEVEL\"\n220 PRINT:PRINT:INPUT\"FUNCTION\";FUNCTION\n225 IF (FUNCTION<1)OR(FUNCTION>6) THEN PRINT \"BAD FUNCTION NUMBER\":GOTO 130\n230 ON FUNCTION GOSUB 900,250,390,480,560,680\n240 GOTO 220\n560 REM REMOVE FROM STOCK\n570 GOSUB 840\n580 IF ASC(F$)=255 THEN PRINT \"NULL ENTRY\":RETURN\n590 PRINT DH\n600 INPUT \"QUANTITY TO SUBTRACT\";S%\n610 Q%=CVI(Q$)\n620 IF (Q%-S%)<0 THEN PRINT \"ONIY\";Q%; \"IN STOCK\":GOTO 600\n630 Q%=Q%-S%\n640 IF Q%=<CVT(R$) THEN PRINT \"QUANTITY NOW\";Q%;\n44 REORDER LEVEL\";CVI(RH)\nLSET Q$=MKU(Q%)\nPUT#1,PART%\nRETURN\nDISPLAY ITEMS BELOW REORDER LEVEL\nFOR 1=1 TO 100\nGET#1J\nIF OVI(tzH)OVI(RH) THEN PRINT Dtz;\" QUANTITY\";\nOVI(Qtz) TAB(50) \"REORDER LEVEL\";CVI(R$)\nNEXT I\nRETURN\nINPUT \"PART NUMBER\";PART%\nIF(PART%<1)OR(PART%>100) THEN PRINT \"BAD PART NUMBER\": GOTO 840 ELSE GET#1 J>ART%:RETURN\nEND\nREM INITIALIZE FILE\nINPUT \"ARE YOU SURE\";B$:IF B$<=\"Y\" THEN RETURN\nLSET F$=CHR$(255)\nFOR O=1 TO 100\nPUT#1J\nNEXT I\nRETURN\n"
  },
  {
    "path": "demo/kitchen-sink/docs/batchfile.bat",
    "content": ":: batch file highlighting in Ace!\n@echo off\n\nCALL set var1=%cd%\necho unhide everything in %var1%!\n\n:: FOR loop in bat is super strange!\nFOR /f \"tokens=*\" %%G IN ('dir /A:D /b') DO (\necho %var1%%%G\nattrib -r -a -h -s \"%var1%%%G\" /D /S\n)\n\npause\n\nREM that's all\n"
  },
  {
    "path": "demo/kitchen-sink/docs/bibtex.bib",
    "content": "@Comment{\n  @Book{tes03,\n    author =\t {John Smith},\n    title =\t {Cooking},\n    publisher =\t {Culinary Expert},\n    year =\t 1890\n  }\n}\n\n@String(mar = \"march\")\n\n@Book{sweig-42,\n  Author =\t { Stefan Sweig },\n  title =\t { The impossible book },\n  publisher =\t { Dead Poet Society},\n  year =\t 1942,\n  month =        mar\n}\n\n@String {firstname = \"John\"}\n@String {lastname  = \"Smith\"}\n@String {email      = firstname # \".\" # lastname # \"@imag.en\"}\n\n@Article{key01,\n  title = { The history of @ sign }\n}\n\nEverything \" \" outside {entries} is treated as comment in BibTeX.\n\n@Article{key03,\n  title = \"A {bunch {of} braces {in}} title\"\n}\n\n@preamble {\"This bibliography was generated on \\today\"}"
  },
  {
    "path": "demo/kitchen-sink/docs/c9search.c9search_results",
    "content": "Searching for \u0001var\u0001 in\u0001/.c9/metadata/workspace/plugins\u0001\u0001regexp, case sensitive, whole word\u0001\n\nconfigs/default.js:\n    1: var fs = require(\"fs\");\n\t2: var argv = require('optimist').argv;\n\t3: var path = require(\"path\");\n\t5: var clientExtensions = {};\n\t6: var clientDirs = fs.readdirSync(__dirname + \"/../plugins-client\");\n\t7: for (var i = 0; i < clientDirs.length; i++) {\n\t8:     var dir = clientDirs[i];\n\t12:     var name = dir.split(\".\")[1];\n\t16: var projectDir = (argv.w && path.resolve(process.cwd(), argv.w)) || process.cwd();\n\t17: var fsUrl = \"/workspace\";\n\t19: var port = argv.p || process.env.PORT || 3131;\n\t20: var host = argv.l || \"localhost\";\n\t22: var config = {\n\nconfigs/local.js:\n\t2: var config = require(\"./default\");\n\nconfigs/packed.js:\n\t1: var config = require(\"./default\");\n\n\nFound 15 matches in 3 files"
  },
  {
    "path": "demo/kitchen-sink/docs/c_cpp.cpp",
    "content": "// compound assignment operators\n\n#include <iostream>\n\n#include \\\n   <iostream>\n\n#include \\\n   \\\n   <iostream>\n\n#include \\\n   \\\n   \"iostream\"\n\n#include <boost/asio/io_service.hpp>\n#include \"boost/asio/io_service.hpp\"\n\n#include \\\n   \\\n   \"iostream\" \\\n   \"string\" \\\n   <vector>\n   \nusing namespace std;\n\n//\nint main ()\n{\n    int a, b=3; /* foobar */\n    a = b; // single line comment\\\n        continued\n    a+=2; // equivalent to a=a+2\n    cout << a;\n    #if VERBOSE >= 2\n        prints(\"trace message\\n\");\n    #endif\n    return 0;\n}\n\n/* Print an error message and get out */\n#define ABORT                             \\\n    do {                                  \\\n        print( \"Abort\\n\" );                \\\n        exit(8);                          \\\n} while (0)                      /* Note: No semicolon */"
  },
  {
    "path": "demo/kitchen-sink/docs/cirru.cirru",
    "content": "-- https://github.com/Cirru/cirru-gopher/blob/master/code/scope.cr,\n\nset a (int 2)\n\nprint (self)\n\nset c (child)\n\nunder c\n  under parent\n    print a\n\nprint $ get c a\n\nset c x (int 3)\nprint $ get c x\n\nset just-print $ code\n  print a\n\nprint just-print\n\neval (self) just-print\neval just-print\n\nprint (string \"string with space\")\nprint (string \"escapes \\n \\\"\\\\\")\n\nbrackets ((((()))))\n\n\"eval\" $ string \"eval\"\n\nprint (add $ (int 1) (int 2))\n\nprint $ unwrap $\n  map (a $ int 1) (b $ int 2)\n\nprint a\n  int 1\n  , b c\n  int 2\n  , d"
  },
  {
    "path": "demo/kitchen-sink/docs/clojure.clj",
    "content": "(defn parting\n  \"returns a String parting in a given language\"\n  ([] (parting \"World\"))\n  ([name] (parting name \"en\"))\n  ([name language]\n    ; condp is similar to a case statement in other languages.\n    ; It is described in more detail later.\n    ; It is used here to take different actions based on whether the\n    ; parameter \"language\" is set to \"en\", \"es\" or something else.\n    (condp = language\n      \"en\" (str \"Goodbye, \" name)\n      \"es\" (str \"Adios, \" name)\n      (throw (IllegalArgumentException.\n        (str \"unsupported language \" language))))))\n\n(println (parting)) ; -> Goodbye, World\n(println (parting \"Mark\")) ; -> Goodbye, Mark\n(println (parting \"Mark\" \"es\")) ; -> Adios, Mark\n(println (parting \"Mark\", \"xy\")) ; -> java.lang.IllegalArgumentException: unsupported language xy\n\n(print (re-matches #\"abc(.*)\n            (r)\" \"abcxyz\n            r\") )"
  },
  {
    "path": "demo/kitchen-sink/docs/clue.clue",
    "content": "@iflua jit {\n\tlocal fn pack(...) {\n\t\treturn love.data.pack(\"string\", ...)\n\t}\n\tlocal fn unpack(...) {\n\t\treturn love.data.unpack(...)\n\t}\n\tlocal fn mtype(x) {\n\t\tif type(x) != \"number\" {\n\t\t\treturn\n\t\t} elseif x == math.floor(x) {\n\t\t\treturn \"integer\"\n\t\t} else {\n\t\t\treturn \"float\"\n\t\t}\n\t}\n\tlocal utf8len = require(\"utf8\").len\n\tlocal tconcat, tunpack = table.concat, _G.unpack\n\tlocal ssub = string.sub\n\tlocal type, pcall, pairs, select = type, pcall, pairs, select\n} @else {\n\t@if all(not(lua(5.4)), not(lua(5.3))) {\n\t\t@print \"Warning: Lua version not specified, defaulting to Lua5.4\"\n\t}\n\tlocal {pack, unpack} = string\n\tlocal mtype, utf8len = math.type, utf8.len\n\tlocal tconcat, tunpack = table.concat, table.unpack\n\tlocal ssub = string.sub\n\tlocal type, pcall, pairs, select = type, pcall, pairs, select\n}\n\n//ENCODER\nlocal encode_value //forward declaration\n\nlocal fn is_an_array(value) {\n\tlocal expected = 1\n\tfor k of value {\n\t\tif k != expected {\n\t\t\treturn false\n\t\t}\n\t\texpected += 1\n\t}\n\treturn true\n}\n\nlocal encoder_functions = {\n\t[\"nil\"] = fn {\n\t\treturn pack(\"B\", 0xc0)\n\t},\n\t[\"boolean\"] = fn(value) {\n\t\tif value {\n\t\t\treturn pack(\"B\", 0xc3)\n\t\t} else {\n\t\t\treturn pack(\"B\", 0xc2)\n\t\t}\n\t},\n\t[\"number\"] = fn(value) {\n\t\tif mtype(value) == \"integer\" {\n\t\t\tif value >= 0 {\n\t\t\t\tif value < 128 {\n\t\t\t\t\treturn pack(\"B\", value)\n\t\t\t\t} elseif value <= 0xff {\n\t\t\t\t\treturn pack(\"BB\", 0xcc, value)\n\t\t\t\t} elseif value <= 0xffff {\n\t\t\t\t\treturn pack(\">BI2\", 0xcd, value)\n\t\t\t\t} elseif value <= 0xffffffff {\n\t\t\t\t\treturn pack(\">BI4\", 0xce, value)\n\t\t\t\t} else {\n\t\t\t\t\treturn pack(\">BI8\", 0xcf, value)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif value >= -32 {\n\t\t\t\t\treturn pack(\"B\", 0xe0 + (value + 32))\n\t\t\t\t} elseif value >= -128 {\n\t\t\t\t\treturn pack(\"Bb\", 0xd0, value)\n\t\t\t\t} elseif value >= -32768 {\n\t\t\t\t\treturn pack(\">Bi2\", 0xd1, value)\n\t\t\t\t} elseif value >= -2147483648 {\n\t\t\t\t\treturn pack(\">Bi4\", 0xd2, value)\n\t\t\t\t} else {\n\t\t\t\t\treturn pack(\">Bi8\", 0xd3, value)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlocal test = unpack(\"f\", pack(\"f\", value))\n\t\t\tif test == value { //check if we can use float\n\t\t\t\treturn pack(\">Bf\", 0xca, value)\n\t\t\t} else {\n\t\t\t\treturn pack(\">Bd\", 0xcb, value)\n\t\t\t}\n\t\t}\n\t},\n\t[\"string\"] = fn(value) {\n\t\tlocal len = #value\n\t\tif utf8len(value) { //check if it is a real utf8 string or just byte junk\n\t\t\tif len < 32 {\n\t\t\t\treturn pack(\"B\", 0xa0 + len) .. value\n\t\t\t} elseif len < 256 {\n\t\t\t\treturn pack(\">Bs1\", 0xd9, value)\n\t\t\t} elseif len < 65536 {\n\t\t\t\treturn pack(\">Bs2\", 0xda, value)\n\t\t\t} else {\n\t\t\t\treturn pack(\">Bs4\", 0xdb, value)\n\t\t\t}\n\t\t} else { //encode it as byte-junk :)\n\t\t\tif len < 256 {\n\t\t\t\treturn pack(\">Bs1\", 0xc4, value)\n\t\t\t} elseif len < 65536 {\n\t\t\t\treturn pack(\">Bs2\", 0xc5, value)\n\t\t\t} else {\n\t\t\t\treturn pack(\">Bs4\", 0xc6, value)\n\t\t\t}\n\t\t}\n\t},\n\t[\"table\"] = fn(value) {\n\t\tif is_an_array(value) { //it seems to be a proper Lua array\n\t\t\tlocal elements = {}\n\t\t\tfor i, v of value {\n\t\t\t\telements[i] = encode_value(v)\n\t\t\t}\n\n\t\t\tlocal length = #elements\n\t\t\tif length < 16 {\n\t\t\t\treturn pack(\">B\", 0x90 + length) .. tconcat(elements)\n\t\t\t} elseif length < 65536 {\n\t\t\t\treturn pack(\">BI2\", 0xdc, length) .. tconcat(elements)\n\t\t\t} else {\n\t\t\t\treturn pack(\">BI4\", 0xdd, length) .. tconcat(elements)\n\t\t\t}\n\t\t} else { //encode as a map\n\t\t\tlocal elements = {}\n\t\t\tfor k, v of value {\n\t\t\t\tif type(v) != \"function\" {\n\t\t\t\t\telements[#elements + 1] = encode_value(k)\n\t\t\t\t\telements[#elements + 1] = encode_value(v)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlocal length = #elements /_ 2\n\t\t\tif length < 16 {\n\t\t\t\treturn pack(\">B\", 0x80 + length) .. tconcat(elements)\n\t\t\t} elseif length < 65536 {\n\t\t\t\treturn pack(\">BI2\", 0xde, length) .. tconcat(elements)\n\t\t\t} else {\n\t\t\t\treturn pack(\">BI4\", 0xdf, length) .. tconcat(elements)\n\t\t\t}\n\t\t}\n\t},\n\t[\"function\"] = fn {\n\t\treturn pack(\"B\", 0xc0)\n\t}\n}\n\nencode_value = fn(value) {\n\treturn encoder_functions[type(value)](value)\n}\n\nlocal fn encode(...) {\n\tlocal data = {}\n\tfor i = 1, select(\"#\", ...) {\n\t\tdata[#data + 1] = encode_value(select(i, ...))\n\t}\n\treturn tconcat(data)\n}\n\n\n//DECODER\nlocal decode_value //forward declaration\n\nlocal fn decode_array(data, position, length) {\n\tlocal elements, value = {}\n\tfor i = 1, length {\n\t\tvalue, position = decode_value(data, position)\n\t\telements[i] = value\n\t}\n\treturn elements, position\n}\n\nlocal fn decode_map(data, position, length) {\n\tlocal elements, key, value = {}\n\tfor i = 1, length {\n\t\tkey, position = decode_value(data, position)\n\t\tvalue, position = decode_value(data, position)\n\t\telements[key] = value\n\t}\n\treturn elements, position\n}\n\nlocal decoder_functions = {\n\t[0xc0] = fn(data, position) {\n\t\treturn nil, position\n\t},\n\t[0xc2] = fn(data, position) {\n\t\treturn false, position\n\t},\n\t[0xc3] = fn(data, position) {\n\t\treturn true, position\n\t},\n\t[0xc4] = fn(data, position) {\n\t\treturn unpack(\">s1\", data, position)\n\t},\n\t[0xc5] = fn(data, position) {\n\t\treturn unpack(\">s2\", data, position)\n\t},\n\t[0xc6] = fn(data, position) {\n\t\treturn unpack(\">s4\", data, position)\n\t},\n\t[0xca] = fn(data, position) {\n\t\treturn unpack(\">f\", data, position)\n\t},\n\t[0xcb] = fn(data, position) {\n\t\treturn unpack(\">d\", data, position)\n\t},\n\t[0xcc] = fn(data, position) {\n\t\treturn unpack(\">B\", data, position)\n\t},\n\t[0xcd] = fn(data, position) {\n\t\treturn unpack(\">I2\", data, position)\n\t},\n\t[0xce] = fn(data, position) {\n\t\treturn unpack(\">I4\", data, position)\n\t},\n\t[0xcf] = fn(data, position) {\n\t\treturn unpack(\">I8\", data, position)\n\t},\n\t[0xd0] = fn(data, position) {\n\t\treturn unpack(\">b\", data, position)\n\t},\n\t[0xd1] = fn(data, position) {\n\t\treturn unpack(\">i2\", data, position)\n\t},\n\t[0xd2] = fn(data, position) {\n\t\treturn unpack(\">i4\", data, position)\n\t},\n\t[0xd3] = fn(data, position) {\n\t\treturn unpack(\">i8\", data, position)\n\t},\n\t[0xd9] = fn(data, position) {\n\t\treturn unpack(\">s1\", data, position)\n\t},\n\t[0xda] = fn(data, position) {\n\t\treturn unpack(\">s2\", data, position)\n\t},\n\t[0xdb] = fn(data, position) {\n\t\treturn unpack(\">s4\", data, position)\n\t},\n\t[0xdc] = fn(data, position) {\n\t\tlocal length\n\t\tlength, position = unpack(\">I2\", data, position)\n\t\treturn decode_array(data, position, length)\n\t},\n\t[0xdd] = fn(data, position) {\n\t\tlocal length\n\t\tlength, position = unpack(\">I4\", data, position)\n\t\treturn decode_array(data, position, length)\n\t},\n\t[0xde] = fn(data, position) {\n\t\tlocal length\n\t\tlength, position = unpack(\">I2\", data, position)\n\t\treturn decode_map(data, position, length)\n\t},\n\t[0xdf] = fn(data, position) {\n\t\tlocal length\n\t\tlength, position = unpack(\">I4\", data, position)\n\t\treturn decode_map(data, position, length)\n\t},\n}\n\n//add fix-array, fix-map, fix-string, fix-int stuff\nfor i = 0x00, 0x7f {\n\tdecoder_functions[i] = fn(data, position) {\n\t\treturn i, position\n\t}\n}\nfor i = 0x80, 0x8f {\n\tdecoder_functions[i] = fn(data, position) {\n\t\treturn decode_map(data, position, i - 0x80)\n\t}\n}\nfor i = 0x90, 0x9f {\n\tdecoder_functions[i] = fn(data, position) {\n\t\treturn decode_array(data, position, i - 0x90)\n\t}\n}\nfor i = 0xa0, 0xbf {\n\tdecoder_functions[i] = fn(data, position) {\n\t\tlocal length = i - 0xa0\n\t\treturn ssub(data, position, position + length - 1), position + length\n\t}\n}\nfor i = 0xe0, 0xff {\n\tdecoder_functions[i] = fn(data, position) {\n\t\treturn -32 + (i - 0xe0), position\n\t}\n}\n\ndecode_value = fn(data, position) {\n\tlocal byte, value\n\tbyte, position = unpack(\"B\", data, position)\n\tvalue, position = decoder_functions[byte](data, position)\n\treturn value, position\n}\n\n//INTERFACE\nreturn {\n\t_AUTHOR = \"Felice D'Angelo <https://github.com/Maiori44>\",\n\t_VERSION = \"0.2.1\",\n\n\t//primary encode function\n\tencode = fn(...) {\n\t\tlocal data, ok = {}\n\t\tfor i = 1, select(\"#\", ...) {\n\t\t\tok, data[i] = pcall(encode_value, select(i, ...))\n\t\t\tif !ok {\n\t\t\t\treturn nil, \"cannot encode MessagePack\"\n\t\t\t}\n\t\t}\n\t\treturn tconcat(data)\n\t},\n\n\t//encode just one value\n\tencode_one = fn(value) {\n\t\tlocal ok, data = pcall(encode_value, value)\n\t\tif ok {\n\t\t\treturn data\n\t\t} else {\n\t\t\treturn nil, \"cannot encode MessagePack\"\n\t\t}\n\t},\n\n\t//primary decode function\n\tdecode = fn(data, position) {\n\t\tlocal values, value, ok = {}\n\t\tposition ||= 1\n\t\twhile position <= #data {\n\t\t\tok, value, position = pcall(decode_value, data, position)\n\t\t\tif ok {\n\t\t\t\tvalues[#values + 1] = value\n\t\t\t} else {\n\t\t\t\treturn nil, \"cannot decode MessagePack\"\n\t\t\t}\n\t\t}\n\t\treturn tunpack(values)\n\t},\n\n\t//decode just one value\n\tdecode_one = fn(data, position) {\n\t\tlocal value, ok\n\t\tok, value, position = pcall(decode_value, data, position || 1)\n\t\tif ok {\n\t\t\treturn value, position\n\t\t} else {\n\t\t\treturn nil, \"cannot decode MessagePack\"\n\t\t}\n\t},\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/cobol.CBL",
    "content": "GNU    >>SOURCE FORMAT IS FIXED\nCobol *> ***************************************************************\n      *> Purpose:   Say hello to GNU Cobol\nHello *> Tectonics: cobc -x bigworld.cob\nmoney *> ***************************************************************\n       identification division.\n       program-id. bigworld.\n\nDATA   data division.\n       working-storage section.\n       01 hello                pic $$$$,$$$,$$$,$$$,$$$,$$$.99.\n       01 world                pic s9(18)v99 value zero.\n\n       01 people               pic ZZZ,ZZZ,ZZZ,ZZ9.\n       01 persons              pic 9(18) value 7182044470.\n\n       01 each                 pic 9(5)v99 value 26202.42.\n\n      *> ***************************************************************\nCODE   procedure division.\n\n       multiply persons by each giving world\n           on size error\n             display \"We did it.  We broke the world bank\" end-display\n       end-multiply\n\n       move world to hello\n       move persons to people\n\n       display \"Hello, world\" end-display\n       display \" \" end-display\n       display\n           \"On \" function locale-date(20130927)\n           \" at \" function locale-time(120000)\n           \", according to UN estimates:\" \n       end-display\n       display\n           \"You were home to some \" people  \" people,\"\n           \" with an estimated worth of \" hello\n       end-display\n\n       goback.\n       end program bigworld.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/coffee.coffee",
    "content": "#!/usr/bin/env coffee\n\ntry\n    throw URIError decodeURI(0xC0ffee * 123456.7e-8 / .9)\ncatch e\n    console.log 'qstring' + \"qqstring\" + '''\n        qdoc\n    ''' + \"\"\"\n        qqdoc\n    \"\"\"\n\ndo ->\n    ###\n    herecomment\n    ###\n    re = /regex/imgy.test ///\n        heregex  # comment\n    ///imgy\n    this isnt: `just JavaScript`\n    undefined\n    \nsentence = \"#{ 22 / 7 } is a decent approximation of π\""
  },
  {
    "path": "demo/kitchen-sink/docs/coldfusion.cfm",
    "content": "<!--- hello world --->\n\n<cfset welcome=\"Hello World!\">\n\n<cfoutput>#welcome#</cfoutput>"
  },
  {
    "path": "demo/kitchen-sink/docs/crystal.cr",
    "content": "# crystal comment\n\nrequire \"llvm\"\n\nNUM_CELLS          = 30000\nCELL_SIZE_IN_BYTES =     1\n\nabstract class Instruction\n  abstract def compile(program, bb)\nend\n\nclass Increment < Instruction\n  def initialize(@amount : Int32)\n  end\n\n  def compile(program, bb)\n    cell_val_is_zero = builder.icmp LLVM::IntPredicate::EQ, cell_val, zero\n    call_args = [@ctx.int32.const_int(NUM_CELLS), @ctx.int32.const_int(CELL_SIZE_IN_BYTES)]\n    builder.cond cell_val_is_zero, loop_after, loop_body_block\n\n    @body.each do |instruction|\n      loop_body_block = instruction.compile(program, loop_body_block)\n    end\n\n    builder.position_at_end loop_body_block\n\n    unless matching_close_index\n      error \"Unmatched '[' at position #{i}\"\n    end\n\n    bb\n  end\nend\n"
  },
  {
    "path": "demo/kitchen-sink/docs/csharp.cs",
    "content": "public void HelloWorld() {\n    //Say Hello!\n    Console.WriteLine(\"Hello World\");\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/csound_document.csd",
    "content": "text\n<CsoundSynthesizer>\n<CsInstruments>\n0dbfs = 1\nprints \"hello, world\\n\"\n</CsInstruments>\n<CsScore>\ni 1 0 0\n</CsScore>\n<html>\n<!DOCTYPE html>\n</html>\n</CsoundSynthesizer>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/csound_orchestra.orc",
    "content": "/*\n * comment\n */\n; comment\n// comment\n\ninstr/**/1,/**/N_a_M_e_,/**/+Name/**///\n  iDuration = p3\n  outc:a(aSignal)\nendin\n\nopcode/**/aUDO,/**/i[],/**/aik//\n  aUDO\nendop\n\n123 0123456789\n0xabcdef0123456789 0XABCDEF\n1e2 3e+4 5e-6 7E8 9E+0 1E-2 3. 4.56 .789\n\n\"characters$MACRO.\"\n\"\\\\\\a\\b\\n\\r\\t\\012\\345\\67\\\"\"\n\n{{\ncharacters$MACRO.\n}}\n{{\\\\\\a\\b\\n\\r\\t\\\"\\012\\345\\67}}\n\n+ - ~ ¬ ! * / ^ % << >> < > <= >= == != & # | && || ? : += -= *= /=\n\n0dbfs A4 kr ksmps nchnls nchnls_i sr\n\ndo else elseif endif enduntil fi if ithen kthen od then until while\nreturn rireturn\n\naLabel:\n label2:\n\ngoto aLabel\nreinit aLabel\ncggoto 1==0, aLabel\ntimout 0, 0, aLabel\nloop_ge 0, 0, 0, aLabel\n\nreadscore {{\ni 1 0 0\n}}\npyrun {{\n# Python\n}}\nlua_exec {{\n-- Lua\n}}\n\n#include/**/\"file.udo\"\n#include/**/|file.udo|\n\n#ifdef MACRO\n#else\n#ifndef MACRO\n#endif\n#undef MACRO\n\n#   define MACRO#macro_body#\n#define/**/\nMACRO/**/\n#\\#macro\nbody\\##\n\n#define MACRO(ARG1#ARG2) #macro_body#\n#define/**/\nMACRO(ARG1'ARG2'ARG3)/**/\n#\\#macro\nbody\\##\n\n$MACRO $MACRO.\n$MACRO(x)\n@0\n@@ 1\n$MACRO.(((x#y\\)))' \"(#'x)\\)x\\))\"# {{x\\))x)\\)(#'}});\n"
  },
  {
    "path": "demo/kitchen-sink/docs/csound_score.sco",
    "content": "/*\n * comment\n */\n; comment\n// comment\na B b C d e f i q s t v x y\nz\nnp0 nP1 Np2 NP3\nm/**/label;\nn label\n123 0123456789\n0xabcdef0123456789 0XABCDEF\n1e2 3e+4 5e-6 7E8 9E+0 1E-2 3. 4.56 .789\n\"characters$MACRO.\"\n{ 1 I\n  { 2 J\n    { 3 K\n      $I $J $K\n    }\n  }\n}\n#include \"score.sco\"\n"
  },
  {
    "path": "demo/kitchen-sink/docs/css.css",
    "content": ".text-layer {\n    font: 12px Monaco, \"Courier New\", monospace;\n    font-size: 3vmin;\n    cursor: text;\n}\n\n.blinker {\n    animation: blink 1s linear infinite alternate;\n}\n\n@keyframes blink {\n    0%, 40% {\n        opacity: 0; /*\n        */\n        opacity: 1\n    }\n\n    40.5%, 100% {\n        opacity: 1\n    }\n}\n\n@document url(http://c9.io/), url-prefix(http://ace.c9.io/build/),\n   domain(c9.io), regexp(\"https:.*\") /**/\n{\n    /**/\n    img[title]:before \n    {\n        content: attr(title) \"\\AImage \\\n            retrieved from\"\n            attr(src); /*\n            */\n        white-space: pre;\n        display: block;\n        background: url(asdasd); \"err\n    }\n}\n\n@viewport {\n    min-zoom: 1;\n    max-zoom: 200%;\n    user-zoom: fixed;\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/csv.csv",
    "content": "col1,col2 long,col3,col4,\n\"col1,with quotes\",col2,col3,col4,\ncol1,col2,col\"\"\"3,co\"\"l4,\ncol1,col2,col3\"broken\",col4,\ncol1\",-\"col2,col3,col4,col5\ncol1,\"col2\nmultiline\",\"col3\nmultiline\"\"string\n3\",\"col4\nmultiline string\n\n4\"\ncol1,col2,\"c,o,l\"\"3\",col4,col5,col6,col7,col8,col9,col10,col11,col12,col13\ncol1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12,col13\ncol1,col2,col3,col4,col5,col6,co\"l7,col8,col9,col10,11,col12,col13\n"
  },
  {
    "path": "demo/kitchen-sink/docs/curly.curly",
    "content": "<html>\n    <head>\n\n    <style type=\"text/css\">\n        .text-layer {\n            font-family: Monaco, \"Courier New\", monospace;\n            font-size: 12px;\n            cursor: text;\n        }\n    </style>\n\n    </head>\n    <body>\n        <h1 style=\"color:red\">{{author_name}}</h1>\n    </body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/cuttlefish.conf",
    "content": "include extras.conf     # overflow config file\n\nring_size = 32\n\n# experimental\nanti_entropy = debug\n\n# logging\nlog.error.file = /var/log/error.log\nlog.console.file = /var/log/console.log\nlog.syslog = on\n"
  },
  {
    "path": "demo/kitchen-sink/docs/d.d",
    "content": "#!/usr/bin/env rdmd\n// Computes average line length for standard input.\nimport std.stdio;\n\nvoid main() {\n    ulong lines = 0;\n    double sumLength = 0;\n    foreach (line; stdin.byLine()) {\n        ++lines;\n        sumLength += line.length;\n    }\n    writeln(\"Average line length: \",\n        lines ? sumLength / lines : 0);\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/dart.dart",
    "content": "// Go ahead and modify this example.\n\nimport \"dart:html\";\n\n// Computes the nth Fibonacci number.\nint fibonacci(int n) {\n  if (n < 2) return n;\n  return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\n// Displays a Fibonacci number.\nvoid main() {\n  int i = 20;\n  String message = \"fibonacci($i) = ${fibonacci(i)}\";\n\n  // This example uses HTML to display the result and it will appear\n  // in a nested HTML frame (an iframe).\n  document.body.append(new HeadingElement.h1()..appendText(message));\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/diff.diff",
    "content": "diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js\nindex 23fc3fc..ed3b273 100644\n--- a/lib/ace/edit_session.js\n+++ b/lib/ace/edit_session.js\n@@ -51,6 +51,7 @@ var TextMode = require(\"./mode/text\").Mode;\n var Range = require(\"./range\").Range;\n var Document = require(\"./document\").Document;\n var BackgroundTokenizer = require(\"./background_tokenizer\").BackgroundTokenizer;\n+var SearchHighlight = require(\"./search_highlight\").SearchHighlight;\n \n /**\n  * class EditSession\n@@ -307,6 +308,13 @@ var EditSession = function(text, mode) {\n         return token;\n     };\n \n+    this.highlight = function(re) {\n+        if (!this.$searchHighlight) {\n+            var highlight = new SearchHighlight(null, \"ace_selected-word\", \"text\");\n+            this.$searchHighlight = this.addDynamicMarker(highlight);\n+        }\n+        this.$searchHighlight.setRegexp(re);\n+    }\n     /**\n     * EditSession.setUndoManager(undoManager)\n     * - undoManager (UndoManager): The new undo manager\n@@ -556,7 +564,8 @@ var EditSession = function(text, mode) {\n             type : type || \"line\",\n             renderer: typeof type == \"function\" ? type : null,\n             clazz : clazz,\n-            inFront: !!inFront\n+            inFront: !!inFront,\n+            id: id\n         }\n \n         if (inFront) {\ndiff --git a/lib/ace/editor.js b/lib/ace/editor.js\nindex 834e603..b27ec73 100644\n--- a/lib/ace/editor.js\n+++ b/lib/ace/editor.js\n@@ -494,7 +494,7 @@ var Editor = function(renderer, session) {\n      * Emitted when a selection has changed.\n      **/\n     this.onSelectionChange = function(e) {\n-        var session = this.getSession();\n+        var session = this.session;\n \n         if (session.$selectionMarker) {\n             session.removeMarker(session.$selectionMarker);\n@@ -509,12 +509,40 @@ var Editor = function(renderer, session) {\n             this.$updateHighlightActiveLine();\n         }\n \n-        var self = this;\n-        if (this.$highlightSelectedWord && !this.$wordHighlightTimer)\n-            this.$wordHighlightTimer = setTimeout(function() {\n-                self.session.$mode.highlightSelection(self);\n-                self.$wordHighlightTimer = null;\n-            }, 30, this);\n+        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()\n     };\ndiff --git a/lib/ace/search_highlight.js b/lib/ace/search_highlight.js\nnew file mode 100644\nindex 0000000..b2df779\n--- /dev/null\n+++ b/lib/ace/search_highlight.js\n@@ -0,0 +1,3 @@\n+new\n+empty file"
  },
  {
    "path": "demo/kitchen-sink/docs/django.djt",
    "content": "{% extends \"base.html\" %}\n\n{% block title %}Ace Django Template{% endblock %}\n\n{% block content %}\n  <h1>Hello, {{ name|default:\"World\" }}!</h1>\n{% endblock %}\n\n<p id=\"formatted\" class=\"test-class-1 {{ variable_class }} test-class-2\" data-attribute=\"unformatted\"></p>\n\n{% comment %}\n    This content should be green.\n{% endcomment %}\n\n<p>{#line comment#}</p>"
  },
  {
    "path": "demo/kitchen-sink/docs/dot.dot",
    "content": "// Original source: http://www.graphviz.org/content/lion_share\n##\"A few people in the field of genetics are using dot to draw \"marriage node diagram\"  pedigree drawings.  Here is one I have done of a test pedigree from the FTREE pedigree drawing package (Lion Share was a racehorse).\" Contributed by David Duffy.\n\n##Command to get the layout: \"dot -Tpng thisfile > thisfile.png\"\n\ndigraph Ped_Lion_Share           {\n# page = \"8.2677165,11.692913\" ;\nratio = \"auto\" ;\nmincross = 2.0 ;\nlabel = \"Pedigree Lion_Share\" ;\n\n\"001\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"002\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"003\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"004\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"005\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"006\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"007\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"009\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"014\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"015\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"016\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"ZZ01\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"ZZ02\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"017\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"012\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"008\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"011\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"013\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"010\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"023\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"020\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"021\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"018\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"025\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"019\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"022\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"024\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"027\" [shape=circle  , regular=1,style=filled,fillcolor=white   ] ;\n\"026\" [shape=box     , regular=1,style=filled,fillcolor=white   ] ;\n\"028\" [shape=box     , regular=1,style=filled,fillcolor=grey    ] ;\n\"marr0001\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"001\" -> \"marr0001\" [dir=none,weight=1] ;\n\"007\" -> \"marr0001\" [dir=none,weight=1] ;\n\"marr0001\" -> \"017\" [dir=none, weight=2] ;\n\"marr0002\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"001\" -> \"marr0002\" [dir=none,weight=1] ;\n\"ZZ02\" -> \"marr0002\" [dir=none,weight=1] ;\n\"marr0002\" -> \"012\" [dir=none, weight=2] ;\n\"marr0003\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"002\" -> \"marr0003\" [dir=none,weight=1] ;\n\"003\" -> \"marr0003\" [dir=none,weight=1] ;\n\"marr0003\" -> \"008\" [dir=none, weight=2] ;\n\"marr0004\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"002\" -> \"marr0004\" [dir=none,weight=1] ;\n\"006\" -> \"marr0004\" [dir=none,weight=1] ;\n\"marr0004\" -> \"011\" [dir=none, weight=2] ;\n\"marr0005\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"002\" -> \"marr0005\" [dir=none,weight=1] ;\n\"ZZ01\" -> \"marr0005\" [dir=none,weight=1] ;\n\"marr0005\" -> \"013\" [dir=none, weight=2] ;\n\"marr0006\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"004\" -> \"marr0006\" [dir=none,weight=1] ;\n\"009\" -> \"marr0006\" [dir=none,weight=1] ;\n\"marr0006\" -> \"010\" [dir=none, weight=2] ;\n\"marr0007\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"005\" -> \"marr0007\" [dir=none,weight=1] ;\n\"015\" -> \"marr0007\" [dir=none,weight=1] ;\n\"marr0007\" -> \"023\" [dir=none, weight=2] ;\n\"marr0008\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"005\" -> \"marr0008\" [dir=none,weight=1] ;\n\"016\" -> \"marr0008\" [dir=none,weight=1] ;\n\"marr0008\" -> \"020\" [dir=none, weight=2] ;\n\"marr0009\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"005\" -> \"marr0009\" [dir=none,weight=1] ;\n\"012\" -> \"marr0009\" [dir=none,weight=1] ;\n\"marr0009\" -> \"021\" [dir=none, weight=2] ;\n\"marr0010\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"008\" -> \"marr0010\" [dir=none,weight=1] ;\n\"017\" -> \"marr0010\" [dir=none,weight=1] ;\n\"marr0010\" -> \"018\" [dir=none, weight=2] ;\n\"marr0011\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"011\" -> \"marr0011\" [dir=none,weight=1] ;\n\"023\" -> \"marr0011\" [dir=none,weight=1] ;\n\"marr0011\" -> \"025\" [dir=none, weight=2] ;\n\"marr0012\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"013\" -> \"marr0012\" [dir=none,weight=1] ;\n\"014\" -> \"marr0012\" [dir=none,weight=1] ;\n\"marr0012\" -> \"019\" [dir=none, weight=2] ;\n\"marr0013\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"010\" -> \"marr0013\" [dir=none,weight=1] ;\n\"021\" -> \"marr0013\" [dir=none,weight=1] ;\n\"marr0013\" -> \"022\" [dir=none, weight=2] ;\n\"marr0014\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"019\" -> \"marr0014\" [dir=none,weight=1] ;\n\"020\" -> \"marr0014\" [dir=none,weight=1] ;\n\"marr0014\" -> \"024\" [dir=none, weight=2] ;\n\"marr0015\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"022\" -> \"marr0015\" [dir=none,weight=1] ;\n\"025\" -> \"marr0015\" [dir=none,weight=1] ;\n\"marr0015\" -> \"027\" [dir=none, weight=2] ;\n\"marr0016\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"024\" -> \"marr0016\" [dir=none,weight=1] ;\n\"018\" -> \"marr0016\" [dir=none,weight=1] ;\n\"marr0016\" -> \"026\" [dir=none, weight=2] ;\n\"marr0017\" [shape=diamond,style=filled,label=\"\",height=.1,width=.1] ;\n\"026\" -> \"marr0017\" [dir=none,weight=1] ;\n\"027\" -> \"marr0017\" [dir=none,weight=1] ;\n\"marr0017\" -> \"028\" [dir=none, weight=2] ;\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/drools.drl",
    "content": "/*\n * Copyright 2010 JBoss Inc\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n Original source\n https://github.com/droolsjbpm/drools/blob/master/drools-examples/\n http://docs.jboss.org/drools/\n*/\npackage com.example.ace\n\nimport java.math.BigDecimal\nimport function my.package.Foo.hello\n\ndeclare FactType\n  @author( Bob )\n  id : String\n  name : String @maxLength(100) @notnull\n\n  value : BigDecimal\nend\n\ndeclare FactType2 extends AnotherType\nend\n\ndeclare trait TraitType extends com.package.AnotherType\nend\n\n\ndeclare trait GoldenCustomer\n    balance : long @Alias( \"org.acme.foo.accountBalance\" )\nend\n\nglobal org.slf4j.Logger logger\n\n/**\n * @param name who we'll salute?\n */\nfunction String hello(String name) {\n    return \"Hello \"+name+\"!\";\n}\n\nrule \"Trim all strings\"\n  dialect \"java\"\n  no-loop\nwhen // fdsfds\n  $s : String(a == null || == \"empty\", $g : size)\n  Cheese( name matches \"(Buffalo)?\\\\S*Mozarella\" )\n    CheeseCounter( cheeses contains $var ) // contains with a variable\n    CheeseCounter( cheese memberof $matureCheeses )\n    Cheese( name soundslike 'foobar' )\n    Message( routingValue str[startsWith] \"R1\" )\n    Cheese( name in ( \"stilton\", \"cheddar\", $cheese ) )\n    Person( eval( age == girlAge + 2 ), sex = 'M' )\nthen\n  /**\n   * TODO There mus be better way\n   */\n  retract($s);\n  String a = \"fd\";\n  a.toString();\n\n  insert($s.trim());\nend\n\nquery isContainedIn( String x, String y )\n  Location( x, y; )\n  or\n  ( Location( z, y; ) and isContainedIn( x, z; ) )\nend\n\nrule \"go\" salience 10\nwhen\n    $s : String(  )\nthen\n    System.out.println( $s );\nend\n\nrule \"When all English buses are not red\"\nwhen\n    not(forall( $bus : Bus( nationality == 'english')\n                Bus( this == $bus, color = 'red' ) ))\nthen\n    // What if all english buses are not red?\nend\n\nrule \"go1\"\nwhen\n    String( this == \"go1\" )\n    isContainedIn(\"Office\", \"House\"; )\nthen\n    System.out.println( \"office is in the house\" );\nend\n\nrule \"go2\"\nwhen\n    String( this == \"go2\" )\n    isContainedIn(\"Draw\", \"House\"; )\nthen\n    System.out.println( \"Draw in the House\" );\nend\n\n/**\n * Go Right\n */\nrule GoRight dialect \"mvel\"  salience (Math.abs( $df.colDiff ))  when\n    $df   : DirectionDiff(colDiff > 0 )\n    $target : Cell(  row == $df.row, col == ($df.col + 1) )\n    CellContents( cell == $target, cellType != CellType.WALL )\n    not Direction(character == $df.fromChar, horizontal == Direction.RIGHT )\nthen\n    System.out.println( \"monster right\" );\n    retract( $df );\n    insert( new Direction($df.fromChar, Direction.RIGHT, Direction.NONE ) );\nend\n"
  },
  {
    "path": "demo/kitchen-sink/docs/edifact.edi",
    "content": "UNB+UNOA:1+005435656:1+006415160:1+060515:1434+00000000000778'\nUNH+00000000000117+INVnrOIC:D:97B:UN'\nBGM+380+342459+9'\nDTM+3:20060515:102'\nRFF+ON:521052'\nNAD+BY+792820524::16++CUMMINS MID-RANGE ENGINE PLANT'\nNAD+SE+005435656::16++GENERAL WIDGET COMPANY'\nCUX+1:USD'\nLIN+1++157870:IN'\nIMD+F++:::WIDGET'\nQTY+47:1020:EA'\nALI+US'\nMOA+203:1202.58'\nPRI+INV:1.179'\nLIN+2++157871:IN'\nIMD+F++:::DIFFERENT WIDGET'\nQTY+47:20:EA'\nALI+JP'\nMOA+203:410'\nPRI+INV:20.5'\nUNS+S'\nMOA+39:2137.58'\nALC+C+ABG'\nMOA+8:525'\nUNT+23+00000000000117'\nUNZ+1+00000000000778'"
  },
  {
    "path": "demo/kitchen-sink/docs/eiffel.e",
    "content": "note\n\tdescription: \"Represents a person.\"\n\nclass\n\tPERSON\n\ncreate\n\tmake, make_unknown\n\nfeature {NONE} -- Creation\n\n\tmake (a_name: like name)\n\t\t\t-- Create a person with `a_name' as `name'.\n\t\tdo\n\t\t\tname := a_name\n\t\tensure\n\t\t\tname = a_name\n\t\tend\n\n\tmake_unknown\n\t\tdo ensure\n\t\t\tname = Void\n\t\tend\n\nfeature -- Access\n\n\tname: detachable STRING\n\t\t\t-- Full name or Void if unknown.\n\nend"
  },
  {
    "path": "demo/kitchen-sink/docs/ejs.ejs",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>Cloud9 Rocks!</title>\n    </head>\n    <body>\n\n    <table class=\"table\">\n        <tr>\n            <th>Name</th>\n            <th>Size</th>\n        </tr>\n        <% if (!isRoot) { %>\n            <tr>\n                <td><a href=\"..\">..</a></td>\n                <td></td></td>\n            </tr>\n        <% } %>\n        <% entries.forEach(function(entry) { %>\n            <tr>\n                <td>\n                    <span class=\"glyphicon <%= entry.mime == 'directory' ? 'folder': 'file'%>\"></span>\n                    <a href=\"<%= entry.name %>\"><%= entry.name %></a>\n                </td>\n                <td><%= entry.size %></td>\n            </tr>\n        <% }) %>\n    </table>\n    \n    </body>\n</html>"
  },
  {
    "path": "demo/kitchen-sink/docs/elixir.ex",
    "content": "defmodule HelloModule do\n  @moduledoc \"\"\"\n    This is supposed to be `markdown`.\n    __Yes__ this is [mark](http://down.format)\n\n    # Truly\n\n    ## marked\n\n    * with lists\n    * more\n    * and more\n\n        Even.with(code)\n        blocks |> with |> samples\n\n    _Docs are first class citizens in Elixir_ (Jose Valim)\n  \"\"\"\n  \n  # A \"Hello world\" function\n  def some_fun do\n    IO.puts \"Juhu Kinners!\"\n  end\n  # A private function\n  defp priv do\n    is_regex ~r\"\"\"\n       This is a regex\n       spanning several\n       lines.\n    \"\"\"\n    x = elem({ :a, :b, :c }, 0)  #=> :a\n  end\nend\n\ntest_fun = fn(x) ->\n  cond do\n    x > 10 ->\n      :greater_than_ten\n    true ->\n      :maybe_ten\n  end\nend"
  },
  {
    "path": "demo/kitchen-sink/docs/elm.elm",
    "content": "{- Ace {- 4 -} Elm -}\nmain = lift clock (every second)\n\nclock t = collage 400 400 [ filled    lightGrey   (ngon 12 110)\n                          , outlined (solid grey) (ngon 12 110)\n                          , hand orange   100  t\n                          , hand charcoal 100 (t/60)\n                          , hand charcoal 60  (t/720) ]\n\nhand clr len time =\n  let angle = degrees (90 - 6 * inSeconds time)\n  in  traced (solid clr) <| segment (0,0) (len * cos angle, len * sin angle)"
  },
  {
    "path": "demo/kitchen-sink/docs/erlang.erl",
    "content": "  %% A process whose only job is to keep a counter.\n  %% First version\n  -module(counter).\n  -export([start/0, codeswitch/1]).\n \n  start() -> loop(0).\n \n  loop(Sum) ->\n    receive\n       {increment, Count} ->\n          loop(Sum+Count);\n       {counter, Pid} ->\n          Pid ! {counter, Sum},\n          loop(Sum);\n       code_switch ->\n          ?MODULE:codeswitch(Sum)\n          % Force the use of 'codeswitch/1' from the latest MODULE version\n    end.\n \n  codeswitch(Sum) -> loop(Sum).\n  \n  % Print the data using the pretty print specifier\n  io:format(\"Here is the data: ~p~n\", [Data]).\n"
  },
  {
    "path": "demo/kitchen-sink/docs/flix.flix",
    "content": "/// Mooo's `n` times on channel `c`.\ndef mooo(tx: Sender[String, r], n: Int32): Unit \\ IO =\n    match n {\n        case 0 => ()\n        case x => Channel.send(\"Mooo!\", tx); mooo(tx, x - 1)\n    }\n\n/// Meow's `n` times on channel `c`.\ndef meow(tx: Sender[String, r], n: Int32): Unit \\ IO =\n    match n {\n        case 0 => ()\n        case x => Channel.send(\"Meow!\", tx); meow(tx, x - 1)\n    }\n\n/// Hiss'es `n` times on channel `c`.\ndef hiss(tx: Sender[String, r], n: Int32): Unit \\ IO =\n    match n {\n        case 0 => ()\n        case x => Channel.send(\"Hiss!\", tx); hiss(tx, x - 1)\n    }\n\n/// Start the animal farm...\ndef main(): Unit \\ IO = region rc {\n    let (tx1, rx1) = Channel.buffered(rc, 10);\n    let (tx2, rx2) = Channel.buffered(rc, 10);\n    let (tx3, rx3) = Channel.buffered(rc, 10);\n    spawn mooo(tx1, 0) @ rc;\n    spawn meow(tx2, 3) @ rc;\n    spawn hiss(tx3, 7) @ rc;\n    select {\n        case m <- recv(rx1) => m |> println\n        case m <- recv(rx2) => m |> println\n        case m <- recv(rx3) => m |> println\n    }\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/forth.frt",
    "content": ": HELLO  ( -- )  CR .\" Hello, world!\" ; \n\nHELLO <cr>\nHello, world!\n\n: [CHAR]   CHAR  POSTPONE LITERAL ; IMMEDIATE\n\n0 value ii        0 value jj\n0 value KeyAddr   0 value KeyLen\ncreate SArray   256 allot   \\ state array of 256 bytes\n: KeyArray      KeyLen mod   KeyAddr ;\n\n: get_byte      + c@ ;\n: set_byte      + c! ;\n: as_byte       255 and ;\n: reset_ij      0 TO ii   0 TO jj ;\n: i_update      1 +   as_byte TO ii ;\n: j_update      ii SArray get_byte +   as_byte TO jj ;\n: swap_s_ij\n    jj SArray get_byte\n       ii SArray get_byte  jj SArray set_byte\n    ii SArray set_byte\n;\n\n: rc4_init ( KeyAddr KeyLen -- )\n    256 min TO KeyLen   TO KeyAddr\n    256 0 DO   i i SArray set_byte   LOOP\n    reset_ij\n    BEGIN\n        ii KeyArray get_byte   jj +  j_update\n        swap_s_ij\n        ii 255 < WHILE\n        ii i_update\n    REPEAT\n    reset_ij\n;\n: rc4_byte\n    ii i_update   jj j_update\n    swap_s_ij\n    ii SArray get_byte   jj SArray get_byte +   as_byte SArray get_byte  xor\n;"
  },
  {
    "path": "demo/kitchen-sink/docs/fortran.f",
    "content": "#include \"globalDefines.h\"\n\n!=========================================================\nprogram main\n!========================================================= \n    use params_module, only : nx, ny, nz\n\n    implicit none\n\n    integer, parameter :: g = 9.81\n    real, allocatable, dimension(:,:,:) :: array\n    integer :: a, b, c\n    real*8 :: x, y, z\n      \n    b = 5\n    c = 7\n\n#ifdef ARRAY_COMP\n    allocate(array(10,10,10), status=a)\n\n    write(c,'(i5.5)') b\n#endif\n\n    if(x.lt.5.0) then\n        array(:,:,:) = g\n    else\n        array(:,:,:) = x - y\n    endif\n\n    return\n!========================================================    \nend program main\n!========================================================\n"
  },
  {
    "path": "demo/kitchen-sink/docs/fsharp.fsi",
    "content": "(* fsharp (* example *) *)\nmodule Test =\n    let (*) x y = (x + y)\n    let func1 x = \n        if x < 100 then\n            x*x\n        else\n            x*x + 1\n    let list = (-1, 42) :: [ for i in 0 .. 99 -> (i, func1(i)) ]\n    let verbatim = @\"c:\\Program \"\" Files\\\"\n    let trippleQuote = \"\"\" \"hello world\" \"\"\"\n    \n    // print\n    printfn \"The table of squares from 0 to 99 is:\\n%A\" list"
  },
  {
    "path": "demo/kitchen-sink/docs/fsl.fsl",
    "content": "machine_name      : \"BGP\";\nmachine_version   : 1.0.0;\n\nmachine_author    : \"John Haugeland <stonecypher@gmail.com>\";\nmachine_license   : MIT;\n\ngraph_layout      : dot;\n\n\n\nIdle 'Invite' => Invited;\n\nInvited 'Invite, 1xx' -> Invited;\nInvited '3xx'         -> Redirecting;\nInvited 'Cancel'      -> Cancelling;\nInvited '200'         => Accepted;\nInvited '407'         => AuthRequested;\nInvited '4xx-6xx'     -> Failed;\n\nAuthRequested 'Ack' => Invited;\n\nRedirecting 'Act' -> Redirected;\n\nCancelling '200 (Invite)' -> LateCancel;\nCancelling '200 (Cancel)' -> Cancelled;\n\nAccepted 'Cancel' -> LateCancel;\nAccepted 'Ack'    => Established;\n\nFailed 'Ack' -> Terminated;\n\nRedirected 'Invite'  -> Invited;\nRedirected 'Timeout' -> Terminated;\n\nLateCancel 'Ack' -> Established;\n\nCancelled '487' -> Failed;\n\nEstablished 'Invite' => SessionModifying;\nEstablished 'Bye'    -> Closing;\n\nSessionModifying '488' -> SessionModificationRefused;\nSessionModifying '200' => SessionModified;\n\nClosing 'Bye,Ack,200 (Invite)' -> Closing;\nClosing '200 (Bye)'            -> Terminated;\n\nSessionModificationRefused 'Ack' -> Established;\n\nSessionModified 'Ack' => Established;\nSessionModified 'Bye' -> Closing;\n"
  },
  {
    "path": "demo/kitchen-sink/docs/ftl.ftl",
    "content": "<#ftl encoding=\"utf-8\" />\n<#setting locale=\"en_US\" />\n<#import \"library\" as lib />\n<#--\n    FreeMarker comment\n    ${abc} <#assign a=12 />\n-->\n\n<!DOCTYPE html>\n<html lang=\"en-us\">\n    <head>\n        <meta charset=\"utf-8\" />\n        \n        <title>${title!\"FreeMarker\"}<title>\n    </head>\n    \n    <body>\n    \n        <h1>Hello ${name!\"\"}</h1>\n        \n        <p>Today is: ${.now?date}</p>\n        \n        <#assign x = 13>\n        <#if x &gt; 12 && x lt 14>x equals 13: ${x}</#if>\n        \n        <ul>\n            <#list items as item>\n                <li>${item_index}: ${item.name!?split(\"\\n\")[0]}</li>\n            </#list>\n        </ul>\n        \n        User directive: <@lib.function attr1=true attr2='value' attr3=-42.12>Test</@lib.function>\n        <@anotherOne />\n        \n        <#if variable?exists>\n            Deprecated\n        <#elseif variable??>\n            Better\n        <#else>\n            Default\n        </#if>\n        \n        <img src=\"images/${user.id}.png\" />\n        \n    </body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/gcode.gcode",
    "content": "O003 (DIAMOND SQUARE)\nN2 G54 G90 G49 G80\nN3 M6 T1 (1.ENDMILL)\nN4 M3 S1800\nN5 G0 X-.6 Y2.050\nN6 G43  H1  Z.1\nN7 G1 Z-.3 F50.\nN8 G41 D1 Y1.45\nN9 G1 X0 F20.\nN10 G2 J-1.45\n(CUTTER COMP CANCEL)\nN11 G1 Z-.2 F50.\nN12 Y-.990\nN13 G40\nN14 G0 X-.6 Y1.590\nN15 G0 Z.1\nN16 M5 G49 G28 G91 Z0\nN17 CALL O9456\nN18 #500=0.004\nN19 #503=[#500+#501]\nN20 VC45=0.0006\nVS4=0.0007\nN21 G90 G10 L20 P3 X5.Y4. Z6.567\nN22 G0 X5000\nN23 IF [#1 LT 0.370] GOTO 49\nN24 X-0.678 Y+.990\nN25 G84.3 X-0.1\nN26 #4=#5*COS[45]\nN27 #4=#5*SIN[45]\nN28 VZOFZ=652.9658\n%"
  },
  {
    "path": "demo/kitchen-sink/docs/gherkin.feature",
    "content": "@these @_are_ @tags\nFeature: Serve coffee\n  Coffee should not be served until paid for\n  Coffee should not be served until the button has been pressed\n  If there is no coffee left then money should be refunded\n  \n  Scenario Outline: Eating\n    Given there are <start> cucumbers\n    When I eat <eat> cucumbers\n    Then I should have <left> cucumbers\n\n    Examples:\n      | start | eat | left |\n      |  12   |  5  |  7   |\n      |  @20  |  5  |  15  |    \n\n  Scenario: Buy last coffee\n    Given there are 1 coffees left in the machine\n    And I have deposited 1$ \n    When I press the coffee button\n    Then I should be served a \"coffee\"\n    \n  # this a comment\n  \n  \"\"\"\n  this is a \n  pystring\n  \"\"\""
  },
  {
    "path": "demo/kitchen-sink/docs/glsl.glsl",
    "content": "uniform float amplitude;\nattribute float displacement;\nvarying vec3 vNormal;\n\nvoid main() {\n\n    vNormal = normal;\n  \n    // multiply our displacement by the\n    // amplitude. The amp will get animated\n    // so we'll have animated displacement\n    vec3 newPosition = position + \n                       normal * \n                       vec3(displacement *\n                            amplitude);\n\n    gl_Position = projectionMatrix *\n                  modelViewMatrix *\n                  vec4(newPosition,1.0);\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/gobstones.gbs",
    "content": "/*\n * A Gobstones implementation of Conwey's Game of Life\n * that tries to use most of Gobstones syntax.\n *\n * Check out more about Gobstones at http://gobstones.org\n */\n\n-----------------------------------------------------------\n--         HELPERS TO MOVE AROUND ALL THE BOARD          --\n-----------------------------------------------------------\n\n// This helpers allow the user to move around the board\n// one cell at a time\nprocedure GoToStartOfBoard(firstDir, secondDir) {\n    IrAlBorde(opuesto(firstDir))\n    IrAlBorde(opuesto(secondDir))\n}\n\nfunction isEndOfBoard(firstDir, secondDir) {\n    return (not puedeMover(firstDir) && not puedeMover(secondDir))\n}\n\nprocedure NextCellOfTheBoard(firstDir, secondDir) {\n    if (puedeMover(firstDir)) {\n        Mover(firstDir)\n    } else {\n        IrAlBorde(opuesto(firstDir))\n        Mover(secondDir)\n    }\n}\n\n-----------------------------------------------------------\n--                   TYPE DECLARATIONS                   --\n-----------------------------------------------------------\n// The cell type declarations\ntype CellStatus is variant {\n    case Alive {}\n    case Dead  {}\n}\n\ntype Cell is record {\n    field status  # CellStatus\n    field color   # Color\n}\n\n\n-----------------------------------------------------------\n--                  PROGRAM DEFINITION                   --\n-----------------------------------------------------------\ninteractive program {\n    # Map key press to actions\n    K_UP     -> { PrepareNextTick()  }\n    K_RIGHT  -> { CompleteNextTick() }\n    K_RETURN -> { SimulateNextTick() }\n}\n\n/*\nprogram {\n    return ( numberOfNeighbors())\n}\n*/\n-----------------------------------------------------------\n--                      FUNCTIONS                        --\n-----------------------------------------------------------\nfunction isCellAlive() {\n    return (hayBolitas(Verde))\n}\n\nfunction cellStatus() {\n    return (\n        choose\n            Alive when (isCellAlive())\n            Dead otherwise\n    )\n}\n\nfunction readCell() {\n    return (\n        Cell(color <- Verde, status <- cellStatus())\n    )\n}\n\nfunction numberOfNeighbors() {\n    amountOfNeighbors := 0\n    foreach dir in [minDir() .. maxDir()] {\n        amountOfNeighbors := amountOfNeighbors + aliveCellsAt(dir)\n    }\n    return (amountOfNeighbors)\n}\n\nfunction aliveCellsAt(dir) {\n    firstCompare := puedeMover(dir) && hasAliveCellAt(dir)\n    secondCompare := puedeMover(dir) && puedeMover(siguiente(dir)) && hasAliveCellAtD(dir)\n    value :=\n        matching (firstCompare) select\n            1 on True\n            0 otherwise\n        +\n        matching (secondCompare) select\n            1 on True\n            0 otherwise\n    return (value)\n}\n\nfunction hasAliveCellAt(dir) {\n    Mover(dir)\n    return (isCellAlive())\n}\n\nfunction hasAliveCellAtD(dir) {\n    Mover(dir)\n    Mover(siguiente(dir))\n    return (isCellAlive())\n}\n\n-----------------------------------------------------------\n--              ROCEDURES DECLARATIONS                   --\n-----------------------------------------------------------\nprocedure TagAsReanimated() {\n    Poner(Azul)\n}\n\nprocedure TagAsDead() {\n    Poner(Rojo)\n}\n\nprocedure ProcessAction() {\n    switch (hayBolitas(Rojo)) {\n        True -> { Sacar(Verde); Sacar(Rojo) }\n        _ -> {}\n    }\n    switch (hayBolitas(Azul)) {\n        True -> { Poner(Verde); Sacar(Azul) }\n        _ -> {}\n    }\n}\n\nprocedure TagCell(numNeighbors) {\n    if     (    isCellAlive() && numNeighbors < 2)  { TagAsDead() }\n    elseif (    isCellAlive() && numNeighbors > 3)  { TagAsDead() }\n    elseif ((not isCellAlive()) && numNeighbors == 3) { TagAsReanimated() }\n}\n\nprocedure SimulateTicks(amount) {\n    repeat(amount) {\n        SimulateNextTick()\n    }\n}\n\nprocedure SimulateNextTick() {\n    PrepareNextTick()\n    CompleteNextTick()\n}\n\nprocedure PrepareNextTick() {\n    GoToStartOfBoard(Norte, Este)\n    while (not isEndOfBoard(Norte, Este)) {\n        TagCell(numberOfNeighbors())\n        NextCellOfTheBoard(Norte, Este)\n    }\n    TagCell(numberOfNeighbors())\n}\n\nprocedure CompleteNextTick() {\n    GoToStartOfBoard(Norte, Este)\n    while (not isEndOfBoard(Norte, Este)) {\n        ProcessAction()\n        NextCellOfTheBoard(Norte, Este)\n    }\n    ProcessAction()\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/golang.go",
    "content": "// Concurrent computation of pi.\n// See http://goo.gl/ZuTZM.\n//\n// This demonstrates Go's ability to handle\n// large numbers of concurrent processes.\n// It is an unreasonable way to calculate pi.\npackage main\n\nimport (\n    \"fmt\"\n    \"math\"\n)\n\nfunc main() {\n    fmt.Println(pi(5000))\n}\n\n// pi launches n goroutines to compute an\n// approximation of pi.\nfunc pi(n int) float64 {\n    ch := make(chan float64)\n    for k := 0; k <= n; k++ {\n        go term(ch, float64(k))\n    }\n    f := 0.0\n    for k := 0; k <= n; k++ {\n        f += <-ch\n    }\n    return f\n}\n\nfunc term(ch chan float64, k float64) {\n    ch <- 4 * math.Pow(-1, k) / (2*k + 1)\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/graphqlschema.gql",
    "content": "# Main Schema\nschema {\n\tquery: Query;\n}\n\nscalar Date;\n\n# Simple type to contain all scalar types\ntype AllTypes {\n\t# Field Description for String\n\ttestString: String;\n\t# Field Description for Int\n\ttestInt: Int;\n\t# Field Description for ID\n\ttestID: ID;\n\t# Field Description for Boolean\n\ttestBoolean: Boolean;\n\t# Field Description for Float\n\ttestFloat: Float;\n}\n\ninterface ISearchable {\n    searchPreview: String!;\n}\n\nunion ProductTypes = Movie | Book;\n\n# Testing enum\nenum MovieGenere {\n    ACTION\n    COMEDY\n    THRILLER\n    DRAMA\n}\n\n# Testing Input\ninput SearchByGenere {\n\tbefore: Date;\n\tafter: Date;\n\tgenere: MovieGenere!;\n}\n\n# Testing Interface\ntype Movie implements ISearchable {\n\tid: ID!;\n\tsearchPreview: String!;\n\trentPrice: Float;\n\tpublishDate: Date;\n\tgenere: MovieGenere;\n\tcast: [String];\n}\n\n# Testing Interface\ntype Book implements ISearchable {\n    id: ID!;\n\tsearchPreview: String!;\n\tprice: Float;\n\tpublishDate: Date;\n\tauthors: [String];\n}\n\ntype Query {\n\ttestString: String;\n\ttestDate; Date;\n\tallTypes: AllTypes;\n\tallProducts: [ProductTypes];\n\n\t# searches only movies by genere with sophisticated argument\n\tsearchMovieByGenere(searchObject: SearchByGenere!): [Movie];\n\n\t# Searchs all products by text string\n\tsearchProduct(text: String!): [ISearchable];\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/groovy.groovy",
    "content": "//http://groovy.codehaus.org/Martin+Fowler%27s+closure+examples+in+Groovy\n\nclass Employee {\n    def name, salary\n    boolean manager\n    String toString() { return name }\n}\n\ndef emps = [new Employee(name:'Guillaume', manager:true, salary:200),\n    new Employee(name:'Graeme', manager:true, salary:200),\n    new Employee(name:'Dierk', manager:false, salary:151),\n    new Employee(name:'Bernd', manager:false, salary:50)]\n\ndef managers(emps) {\n    emps.findAll { e -> e.isManager() }\n}\n\nassert emps[0..1] == managers(emps) // [Guillaume, Graeme]\n\ndef highPaid(emps) {\n    threshold = 150\n    emps.findAll { e -> e.salary > threshold }\n}\n\nassert emps[0..2] == highPaid(emps) // [Guillaume, Graeme, Dierk]\n\ndef paidMore(amount) {\n    { e -> e.salary > amount}\n}\ndef highPaid = paidMore(150)\n\nassert highPaid(emps[0]) // true\nassert emps[0..2] == emps.findAll(highPaid)\n\ndef filename = 'test.txt'\nnew File(filename).withReader{ reader -> doSomethingWith(reader) }\n\ndef readersText\ndef doSomethingWith(reader) { readersText = reader.text }\n\nassert new File(filename).text == readersText"
  },
  {
    "path": "demo/kitchen-sink/docs/haml.haml",
    "content": "!!!5\n\n/[if IE]\n  %a{ :href => 'http://www.mozilla.com/en-US/firefox/' }\n    %h1 Get Firefox\n\n-# This is a HAML comment. It will not show in the output HTML\n\n-#\n  This is a HAML multiline comment\n  This won't be displayed\n    Nor will this\n                   Nor will this.\n\n/ This is a HTML comment. It will be rendered as HTML\n\n/\n  %p This doesn't render...\n  %div\n    %h1 Because it's commented out!\n\n.row\n  .col-md-6\n\n  .col-md-6\n\n\n#users.row.green\n  #articles{:style => \"border: 5px;\"}\n  #lists.list-inline\n\n%div#todos.bg-green{:id => \"#{@item.type}_#{@item.number}\", :class => '#{@item.type} #{@item.urgency}', :phoney => `asdasdasd`}\n\n/ file: app/views/movies/index.html.haml\n\n%ads:{:bleh => 33}\n%p\n  Date/Time:\n  - now = DateTime.now\n  %strong= now\n   = if now DateTime.parse(\"December 31, 2006\")\n    = \"Happy new \" + \"year!\"\n\n%sfd.dfdfg\n#content\n .title\n   %h1= @title\n   = link_to 'Home', home_url\n\n   #contents\n%div#content\n  %div.articles\n    %div.article.title Blah\n    %div.article.date 2006-11-05\n    %div.article.entry\n      Neil Patrick Harris\n\n%div[@user, :greeting]\n  %bar[290]\n\n/ This is a comment\n\n/ This is another comment with line break above\n\n.row\n  .col-md-6\n  .col-md-6\n\n  .col-md-6\n\n.row\n  .col-md-6\n\n\n  .col-md-6"
  },
  {
    "path": "demo/kitchen-sink/docs/handlebars.hbs",
    "content": "{{!-- Ace + :-}} --}}\n\n<div id=\"comments\">\n  {{#each comments}}\n  <h2><a href=\"/posts/{{../permalink}}#{{id}}\">{{title}}</a></h2>\n  <div>{{{body}}}</div>\n  {{/each}}\n</div>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/haskell.hs",
    "content": "-- Type annotation (optional)\nfib :: Int -> Integer\n \n-- With self-referencing data\nfib n = fibs !! n\n        where fibs = 0 : scanl (+) 1 fibs\n        -- 0,1,1,2,3,5,...\n \n-- Same, coded directly\nfib n = fibs !! n\n        where fibs = 0 : 1 : next fibs\n              next (a : t@(b:_)) = (a+b) : next t\n \n-- Similar idea, using zipWith\nfib n = fibs !! n\n        where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)\n \n-- Using a generator function\nfib n = fibs (0,1) !! n\n        where fibs (a,b) = a : fibs (b,a+b)"
  },
  {
    "path": "demo/kitchen-sink/docs/haskell_cabal.cabal",
    "content": "name:                reload\nversion:             0.1.0.0\nsynopsis:            Initial project template from stack\nDescription:\n    The \\'cabal\\' command-line program simplifies the process of managing\n    Haskell software by automating the fetching, configuration, compilation\n    and installation of Haskell libraries and programs.\nhomepage:            https://github.com/jpmoresmau/dbIDE/reload#readme\nlicense:             BSD3\nlicense-file:        LICENSE\nauthor:              JP Moresmau\nmaintainer:          jpmoresmau@gmail.com\ncopyright:           2016 JP Moresmau\ncategory:            Web\nbuild-type:          Simple\n-- extra-source-files:\ncabal-version:       >=1.10\n\nFlag network-uri\n  description:  Get Network.URI from the network-uri package\n  default:      True\n\nlibrary\n  hs-source-dirs:      src\n  exposed-modules:     Language.Haskell.Reload\n  build-depends:       base >= 4.7 && < 5\n                     , aeson\n                     , scotty\n                     , wai\n                     , text\n                     , directory\n                     , filepath\n                     , bytestring\n                     , containers\n                     , mime-types\n                     , transformers\n                     , wai-handler-launch\n                     , wai-middleware-static\n                     , wai-extra\n                     , http-types\n  default-language:    Haskell2010\n  other-modules:       Language.Haskell.Reload.FileBrowser\n  ghc-options:         -Wall -O2\n\nexecutable reload-exe\n  hs-source-dirs:      app\n  main-is:             Main.hs\n  ghc-options:         -threaded -O2 -rtsopts -with-rtsopts=-N\n  build-depends:       base\n                     , reload\n  default-language:    Haskell2010\n\ntest-suite reload-test\n  type:                exitcode-stdio-1.0\n  hs-source-dirs:      test\n  main-is:             Spec.hs\n  build-depends:       base\n                     , reload\n                     , hspec\n                     , hspec-wai\n                     , hspec-wai-json\n                     , aeson\n                     , directory\n                     , filepath\n                     , text\n                     , containers\n                     , unordered-containers\n                     , bytestring\n                     , wai-extra\n  ghc-options:         -threaded -O2 -rtsopts -with-rtsopts=-N\n  default-language:    Haskell2010\n  other-modules:       Language.Haskell.Reload.FileBrowserSpec\n                       Language.Haskell.ReloadSpec\n\nsource-repository head\n  type:     git\n  location: https://github.com/jpmoresmau/dbIDE/reload\n"
  },
  {
    "path": "demo/kitchen-sink/docs/haxe.hx",
    "content": "class Haxe \n{\n    public static function main() \n    {\n        // Say Hello!\n        var greeting:String = \"Hello World\";\n        trace(greeting);\n        \n        var targets:Array<String> = [\"Flash\",\"Javascript\",\"PHP\",\"Neko\",\"C++\",\"iOS\",\"Android\",\"webOS\"];\n        trace(\"Haxe is a great language that can target:\");\n        for (target in targets)\n        {\n            trace (\" - \" + target);\n        }\n        trace(\"And many more!\");\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/hjson.hjson",
    "content": "{\n  # specify rate in requests/second (because comments are helpful!)\n  rate: 1000\n\n  // prefer c-style comments?\n  /* feeling old fashioned? */\n\n  # did you notice that rate doesn't need quotes?\n  hey: look ma, no quotes for strings either!\n\n  # best of all\n  notice: []\n  anything: ?\n\n  # yes, commas are optional!\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/htaccess",
    "content": "Redirect /linux http://www.linux.org\nRedirect 301 /kernel http://www.linux.org\n\n# comment\nRewriteEngine on\n\nRewriteCond %{HTTP_USER_AGENT} ^Mozilla.*\nRewriteRule ^/$ /homepage.max.html [L]\n\nRewriteRule ^/$ /homepage.std.html [L]\n"
  },
  {
    "path": "demo/kitchen-sink/docs/html.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n\n    <style type=\"text/css\">\n        .text-layer {\n            font-family: Monaco, \"Courier New\", monospace;\n            font-size: 12px;\n            cursor: text;\n        }\n    </style>\n\n    </head>\n    <body>\n        <h1 style=\"color:red\">Juhu Kinners</h1>\n    </body>\n</html>"
  },
  {
    "path": "demo/kitchen-sink/docs/html_elixir.eex",
    "content": "<h1>Listing Books</h1>\n \n<table>\n  <tr>\n    <th>Title</th>\n    <th>Summary</th>\n    <th></th>\n    <th></th>\n    <th></th>\n  </tr>\n\n<%= for book <- @books do %>\n  <tr>\n    <%# comment %>\n    <td><%= book.title %></td>\n    <td><%= book.content %></td>\n    <td><%= link \"Show\", to: book_path(@conn, :show, book) %></td>\n    <td><%= link \"Edit\", to: book_path(@conn, :edit, book) %></td>\n    <td><%= link \"Delete\", to: book_path(@conn, :delete, book), method: :delete, data: [confirm: \"Are you sure?\"] %></td>\n  </tr>\n<% end %>\n</table>\n \n<br />\n \n<%= link \"New book\", to: book_path(@conn, :new) %>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/html_ruby.erb",
    "content": "<h1>Listing Books</h1>\n \n<table>\n  <tr>\n    <th>Title</th>\n    <th>Summary</th>\n    <th></th>\n    <th></th>\n    <th></th>\n  </tr>\n \n<% @books.each do |book| %>\n  <tr>\n    <%# comment %>\n    <td><%= book.title %></td>\n    <td><%= book.content %></td>\n    <td><%= link_to 'Show', book %></td>\n    <td><%= link_to 'Edit', edit_book_path(book) %></td>\n    <td><%= link_to 'Remove', book, :confirm => 'Are you sure?', :method => :delete %></td>\n  </tr>\n<% end %>\n</table>\n \n<br />\n \n<%= link_to 'New book', new_book_path %>"
  },
  {
    "path": "demo/kitchen-sink/docs/ini.ini",
    "content": "[.ShellClassInfo]\nIconResource=..\\logo.png\n[ViewState]\nFolderType=Generic\n"
  },
  {
    "path": "demo/kitchen-sink/docs/io.io",
    "content": "// computes factorial of a number\nfactorial := method(n,\n    if(n == 0, return 1)\n    res := 1\n    Range 1 to(n) foreach(i, res = res * i)\n)"
  },
  {
    "path": "demo/kitchen-sink/docs/ion.ion",
    "content": "// Comment\n/*\nMulti\nLine\nComment\n*/\n[1,2,3,45 /*TODO: should be 42, obviously*/, 2016-04-21T08:10:46Z, 2016-04-21T08:10:46-08:00, 2016-04-21, 2016, 0x5, 0b0110]\n(5 7 1 3 [\n    'a', 'b',\n    null, null.int, null.bool, null.list,\n    true, false,\n    nan, -inf, +inf,\n    \"str\",\n    \"str with embedded \\\" \",\n    '''str with embedded \\''' ''',\n    {{\"clob content\"}},\n    {{ AB/ }}\n    ])\n\n'''\n\nmulti\nline\nstring\n\n'''\n\nstates::{\n    // https://amzn.github.io/ion-docs/docs/spec.html\n    root: rules::[\n        include::'value'\n    ],\n\n    // https://amzn.github.io/ion-docs/docs/spec.html#string\n    string: rules::[\n        match :: {\n            regex: \"(\\\\\\\")((?:\\\\\\\\\\\"|[^\\\"])*)(\\\\\\\")\",\n            token: ['string.dblq.punc.start', 'string.dblq', 'string.dblq.punc.end']\n        },\n        push::{\n            regex: \"\\'{3}\",\n            token: 'string.trpq.punc.start',\n            states: rules::[\n                pop     ::     {\n                    regex: \"\\'{3}\",\n                    token: 'string.trpq.punc.end',\n                },\n                match::{\n                    regex: \"(?:\\\\\\\\'*|.|[^']*)\",\n                    token: 'string.trpq'\n                }\n            ]\n        },\n    ],\n\n    /*\n    ...\n    */\n}\n{\n\"json\": {\n      \"compatibility\": true,\n      \"open sourced\": \"2016-04-21T08:10:46Z\",\n      \"foo\": 9,\n      \"bar\": 1.1,\n      \"baz\": [{\"id\": 1}, {\"id\":2}]\n  }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/jack.jack",
    "content": "vars it, p\n\np = {label, value|\n  print(\"\\n\" + label)\n  print(inspect(value))\n}\n-- Create an array from 0 to 15\np(\"range\", i-collect(range(5)))\n\n-- Create an array from 0 to 15 and break up in chunks of 4\np(\"chunked range\", i-collect(i-chunk(4, range(16))))\n\n-- Check if all or none items in stream pass test.\np(\"all < 60 in range(60)\", i-all?({i|i<60}, range(60)))\np(\"any < 60 in range(60)\", i-any?({i|i>60}, range(60)))\np(\"all < 60 in range(70)\", i-all?({i|i<60}, range(70)))\np(\"any < 60 in range(70)\", i-any?({i|i>60}, range(70)))\n\n-- Zip three different collections together\np(\"zipped\", i-collect(i-zip(\n  range(10),\n  [1,2,3,4,5],\n  i-map({i|i*i}, range(10))\n)))\n\nvars names, person, i, doubles, lengths, cubeRange\nnames = [\"Thorin\", \"Dwalin\", \"Balin\", \"Bifur\", \"Bofur\", \"Bombur\", \"Oin\",\n         \"Gloin\", \"Ori\", \"Nori\", \"Dori\", \"Fili\", \"Kili\", \"Bilbo\", \"Gandalf\"]\n\nfor name in names {\n  if name != \"Bilbo\" && name != \"Gandalf\" {\n    print(name)\n  }\n}\n\nperson = {name: \"Tim\", age: 30}\nfor key, value in person {\n  print(key + \" = \" + value)\n}\n\ni = 0\nwhile i < 10 {\n  i = i + 1\n  print(i)\n}\n\nprint(\"range\")\nfor i in range(10) {\n  print(i + 1)\n}\nfor i in range(10) {\n  print(10 - i)\n}\n\n-- Dynamic object that gives the first 10 doubles\ndoubles = {\n  @len: {| 10 }\n  @get: {key|\n    if key is Integer { key * key }\n  }\n}\nprint(\"#doubles\", #doubles)\n\nprint(\"Doubles\")\nfor k, v in doubles {\n  print([k, v])\n}\n\n-- Dynamic object that has names list as keys and string lenth as values\nlengths = {\n  @keys: {| names }\n  @get: {key|\n    if key is String { #key }\n  }\n}\n\nprint (\"Lengths\")\nfor k, v in lengths {\n  print([k, v])\n}\n\n\ncubeRange = {n|\n  vars i, v\n  i = 0\n  {\n    @call: {|\n      v = i\n      i = i + 1\n      if v < n { v * v * v }\n    }\n  }\n}\n\nprint(\"Cubes\")\nfor k, v in cubeRange(5) {\n  print([k, v])\n}\nprint(\"String\")\nfor k, v in \"Hello World\" {\n  print([k, v])\n}\n\n\nprint([i for i in range(10)])\nprint([i for i in range(20) if i % 3])\n\n\n\n-- Example showing how to do parallel work using split..and\nbase = {bootstrap, target-dir|\n  split {\n    copy(\"res\", target-dir)\n  } and {\n    if newer(\"src/*.less\", target-dir + \"/style.css\") {\n      lessc(\"src/\" + bootstrap + \".less\", target-dir + \"/style.css\")\n    }\n  } and {\n    build(\"src/\" + bootstrap + \".js\", target-dir + \"/app.js\")\n  }\n}\n\n\nvars Dragon, pet\n\nDragon = {name|\n  vars asleep, stuff-in-belly, stuff-in-intestine,\n       feed, walk, put-to-bed, toss, rock,\n       hungry?, poopy?, passage-of-time\n\n  asleep = false\n  stuff-in-belly     = 10 -- He's full.\n  stuff-in-intestine =  0 -- He doesn't need to go.\n\n  print(name + ' is born.')\n\n  feed = {|\n    print('You feed ' + name + '.')\n    stuff-in-belly = 10\n    passage-of-time()\n  }\n\n  walk = {|\n    print('You walk ' + name + \".\")\n    stuff-in-intestine = 0\n    passage-of-time\n  }\n\n  put-to-bed = {|\n    print('You put ' + name + ' to bed.')\n    asleep = true\n    for i in range(3) {\n      if asleep {\n        passage-of-time()\n      }\n      if asleep {\n        print(name + ' snores, filling the room with smoke.')\n      }\n    }\n    if asleep {\n      asleep = false\n      print(name + ' wakes up slowly.')\n    }\n  }\n\n  toss = {|\n    print('You toss ' + name + ' up into the air.')\n    print('He giggles, which singes your eyebrows.')\n    passage-of-time()\n  }\n\n  rock = {|\n    print('You rock ' + name + ' gently.')\n    asleep = true\n    print('He briefly dozes off...')\n    passage-of-time()\n    if asleep {\n      asleep = false\n      print('...but wakes when you stop.')\n    }\n  }\n\n  hungry? = {|\n    stuff-in-belly <= 2\n  }\n\n  poopy? = {|\n    stuff-in-intestine >= 8\n  }\n\n  passage-of-time = {|\n    if stuff-in-belly > 0 {\n      -- Move food from belly to intestine\n      stuff-in-belly     = stuff-in-belly     - 1\n      stuff-in-intestine = stuff-in-intestine + 1\n    } else { -- Our dragon is starving!\n      if asleep {\n        asleep = false\n        print('He wakes up suddenly!')\n      }\n      print(name + ' is starving! In desperation, he ate YOU!')\n      abort \"died\"\n    }\n\n    if stuff-in-intestine >= 10 {\n      stuff-in-intestine = 0\n      print('Whoops! ' + name + ' had an accident...')\n    }\n\n    if hungry?() {\n      if asleep {\n        asleep = false\n        print('He wakes up suddenly!')\n      }\n      print(name + \"'s stomach grumbles...\")\n    }\n\n    if poopy?() {\n      if asleep {\n        asleep = false\n        print('He wakes up suddenly!')\n      }\n      print(name + ' does the potty dance...')\n    }\n  }\n\n  -- Export the public interface to this closure object.\n  {\n   feed: feed\n   walk: walk\n   put-to-bed: put-to-bed\n   toss: toss\n   rock: rock\n  }\n\n}\n\npet = Dragon('Norbert')\npet.feed()\npet.toss()\npet.walk()\npet.put-to-bed()\npet.rock()\npet.put-to-bed()\npet.put-to-bed()\npet.put-to-bed()\npet.put-to-bed()\n"
  },
  {
    "path": "demo/kitchen-sink/docs/jade.jade",
    "content": "!!!doctype\n!!!5\n!!!\n\ninclude something\n\n         include another_thing\n\n  // let's talk about it\n\n// \n  here it is. a block comment!\n and another row!\nbut not here.\n\n     // \n        a far spaced\n    should be lack of block\n\n   // also not a comment\n     div.attemptAtBlock\n  \n  span#myName\n\n  #{implicit}\n     !{more_explicit}\n\n  #idDiv\n\n    .idDiv\n\n    test(id=\"tag\")\n    header(id=\"tag\", blah=\"foo\", meh=\"aads\")\nmixin article(obj, parents)\n\n  mixin bleh()\n\n    mixin clever-name\n\n -var x = \"0\";\n - y each z\n\n - var items = [\"one\", \"two\", \"three\"]\n   each item in items\n    li= item"
  },
  {
    "path": "demo/kitchen-sink/docs/java.java",
    "content": "import java.util.ArrayList;\nimport java.util.Vector;\n\npublic class InfiniteLoop {\n\n    /*\n     * This will cause the program to hang...\n     *\n     * Taken from:\n     * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/\n     */\n    @Override\n    public static void main(String[] args) {\n        double d = Double.parseDouble(\"2.2250738585072012e-308\");\n\n        // unreachable code\n        System.out.println(\"Value: \" + d);\n    }\n}\n\nString name = \"Joan\"; String info = STR.\"My name is \\{name}\";\n\nSTR.\"Today's weather is \\{ getFeelsLike() }, with a temperature of \\{ getTemperature()++ } degrees \\{ getUnit() }\"\n\nString nestedMultilineTemplates() {\n    return STR.\"\"\"\n        {\n            \"outerKey1\": \"outerValue1\",\n            \"nestedTemplate\": \"\\{\n                STR.\"\"\"\n                {\n                    \"innerKey\": \"\\{innerValue.get()}\"\n                }\n                \"\"\"\n            }\",\n            \"outerKey2\": \"outerValue2\"\n        }\n        \"\"\";\n}\n\nvar to = \"working\";\n\nmodule com.example.myapp {\n    /**\n     * Test doc comment\n     * @property test\n     */\n    requires transitive java.base;\n    //comment\n    exports com.example.myapp.api;\n    /*\n        multiline comment\n    */\n    opens com.example.myapp.internal to other.module;\n    uses com.example.myapp.service.MyService;\n    provides com.example.myapp.service.MyService with com.example.myapp.impl.MyServiceImpl;\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/javascript.js",
    "content": "/**\n * \n * @param {string[]} items\n * @param nada\n */\nfunction foo(items, nada) {\n    for (var i=0; i<items.length; i++) {\n        alert(items[i] + \"juhu\\n\");\n    }\t// Real Tab.\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/jexl.jexl",
    "content": "#pragma execution.option 42\n\n##\n## This is a test script\n##\n\n/* This is\na multi-line\ncomment\n*/\nif (out != null and result == null) out.println(\"The result is \" + result);\nx = ~/\\w+\\/test/;\ny = 2;\nresult = x * y + 5;\nif (out != null) out.println(\"The result is \" + result);\n\n@lenient @silent x.someMethod();\n\n`multi-line string\nwith ${var interpolation = \"Hey!\"} and \\escap\\u00E9 chars`\n"
  },
  {
    "path": "demo/kitchen-sink/docs/json.json",
    "content": "{\n \"query\": {\n  \"count\": 10,\n  \"created\": \"2011-06-21T08:10:46Z\",\n  \"lang\": \"en-US\",\n  \"results\": {\n   \"photo\": [\n    {\n     \"farm\": \"6\",\n     \"id\": \"5855620975\",\n     \"isfamily\": \"0\",\n     \"isfriend\": \"0\",\n     \"ispublic\": \"1\",\n     \"owner\": \"32021554@N04\",\n     \"secret\": \"f1f5e8515d\",\n     \"server\": \"5110\",\n     \"title\": \"7087 bandit cat\"\n    },\n    {\n     \"farm\": \"4\",\n     \"id\": \"5856170534\",\n     \"isfamily\": \"0\",\n     \"isfriend\": \"0\",\n     \"ispublic\": \"1\",\n     \"owner\": \"32021554@N04\",\n     \"secret\": \"ff1efb2a6f\",\n     \"server\": \"3217\",\n     \"title\": \"6975 rusty cat\"\n    },\n    {\n     \"farm\": \"6\",\n     \"id\": \"5856172972\",\n     \"isfamily\": \"0\",\n     \"isfriend\": \"0\",\n     \"ispublic\": \"1\",\n     \"owner\": \"51249875@N03\",\n     \"secret\": \"6c6887347c\",\n     \"server\": \"5192\",\n     \"title\": \"watermarked-cats\"\n    },\n    {\n     \"farm\": \"6\",\n     \"id\": \"5856168328\",\n     \"isfamily\": \"0\",\n     \"isfriend\": \"0\",\n     \"ispublic\": \"1\",\n     \"owner\": \"32021554@N04\",\n     \"secret\": \"0c1cfdf64c\",\n     \"server\": \"5078\",\n     \"title\": \"7020 mandy cat\"\n    },\n    {\n     \"farm\": \"3\",\n     \"id\": \"5856171774\",\n     \"isfamily\": \"0\",\n     \"isfriend\": \"0\",\n     \"ispublic\": \"1\",\n     \"owner\": \"32021554@N04\",\n     \"secret\": \"7f5a3180ab\",\n     \"server\": \"2696\",\n     \"title\": \"7448 bobby cat\"\n    }\n   ]\n  }\n }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/json5.json5",
    "content": "{\n  foo: 'bar',\n  while: true,\n\n  this: 'is a \\\nmulti-line string',\n\n  // this is an inline comment\n  here: 'is another', // inline comment\n\n  /* this is a block comment\n     that continues on another line */\n\n  hex: 0xDEADbeef,\n  half: .5,\n  delta: +10,\n  to: Infinity,   // and beyond!\n\n  finally: 'a trailing comma',\n  oh: [\n    \"we shouldn't forget\",\n    'arrays can have',\n    'trailing commas too',\n  ],\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/jsoniq.jq",
    "content": "(: Single line comment :)\n\n(:\n : Multi-line comment block\n : JSONiq uses XQuery-style comments\n :)\n\nlet $string := \"Hello, JSONiq!\"\nlet $number := 42\nlet $decimal := 3.14159\nlet $scientific := 1.5e10\nlet $boolean_true := true\n\nlet $person := {\n    \"name\": \"John Doe\",\n    \"age\": 30,\n    \"email\": \"john@example.com\",\n    \"active\": true,\n    \"balance\": 1250.50,\n    \"metadata\": null\n}\n\nlet $result :=\n    for $i in 1 to 10\n    let $squared := $i * $i\n    where $i mod 2 eq 0\n    order by $squared descending\n    return { \"number\": $i, \"squared\": $squared }\n\nlet $admins :=\n    for $user in $data.users[]\n    where $user.roles[] = \"admin\"\n    order by $user.name ascending\n    return $user.name\n\n(: Conditional Expressions :)\nlet $status :=\n    if ($person.age >= 18)\n    then \"adult\"\n    else \"minor\"\n\nlet $tier :=\n    if ($person.balance >= 1000) then \"gold\"\n    else if ($person.balance >= 500) then \"silver\"\n    else \"bronze\"\n\n(: Quantified Expressions :)\nlet $has_admin :=\n    some $user in $data.users[]\n    satisfies $user.roles[] = \"admin\"\n\nlet $all_active :=\n    every $user in $data.users[]\n    satisfies exists($user.name)\n\n(: Type Expressions :)\nlet $typed_value := 42 cast as string\nlet $check := $person.name instance of string\nlet $treated := $number treat as integer\n\nlet $eq := 5 eq 5\nlet $ne := 5 ne 3\nlet $lt := 3 lt 5\nlet $le := 3 le 5\nlet $gt := 5 gt 3\nlet $ge := 5 ge 3\n\nlet $concat := \"Hello\" || \" \" || \"World\"\nlet $contains := contains(\"JSONiq\", \"JSON\")\nlet $substring := substring(\"Hello World\", 1, 5)\nlet $upper := upper-case(\"hello\")\nlet $lower := lower-case(\"HELLO\")\nlet $length := string-length(\"JSONiq\")\n\n(: User-Defined Function :)\ndeclare function local:greet($name as string) as string {\n    \"Hello, \" || $name || \"!\"\n};\n\ndeclare function local:factorial($n as integer) as integer {\n    if ($n le 1)\n    then 1\n    else $n * local:factorial($n - 1)\n};\n\ndeclare function local:filter-by-age($users, $min-age as integer) {\n    for $user in $users[]\n    where $user.age >= $min-age\n    return $user\n};\n\nreturn {\n    \"greeting\": local:greet(\"World\"),\n    \"factorial_5\": local:factorial(5),\n    \"admins\": $admins,\n    \"status\": $status,\n    \"tier\": $tier,\n    \"has_admin\": $has_admin,\n    \"grouped\": $grouped\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/jsp.jsp",
    "content": "<%-- initial comment --%>\n<%@ page import=\"java.util.Date\" %>\n<%--@ page isELIgnored=\"true\" //Now EL will be ignored   --%>\n<html>\n    <jsp:declaration>\n        int day = 3;\n    </jsp:declaration>\n    <%@ include file=\"relative url\" %>\n    <jsp:directive.include file=\"relative url\" />\n    <head>\n        <title>Day <%= day %></title>\n    </head> \n    <body>\n        <script>\n            var x = \"abc\";\n                function y {\n            }\n        </script>\n    <style>\n        .class {\n            background: #124356;\n        }\n    </style>\n\n    <p>\n        Today's date: <%= (new java.util.Date()).toLocaleString()%>\n    </p>\n    <%! int day = 3; %> \n    \n    <jsp:directive.page attribute=\"value\" />\n    \n    \n    <%-- This comment will not be visible in the page source --%>\n    <!-- html comment -->\n    <body>\n        <p>\n           Today's date: <%= (new java.util.Date()).toLocaleString()%>\n        </p>\n        \n<%! int i = 0; %>\n    <jsp:declaration>\n       int j = 10;\n    </jsp:declaration>\n\n    <%-- This is JSP comment --%>\n    <%@ directive attribute=\"value\" %>\n\n    <h2>Select Languages:</h2>\n\n    <form ACTION=\"jspCheckBox.jsp\">\n        <input type=\"checkbox\" name=\"id\" value=\"Java\"> Java<BR>\n        <input type=\"checkbox\" name=\"id\" value=\".NET\"> .NET<BR>\n        <input type=\"checkbox\" name=\"id\" value=\"PHP\"> PHP<BR>\n        <input type=\"checkbox\" name=\"id\" value=\"C/C++\"> C/C++<BR>\n        <input type=\"checkbox\" name=\"id\" value=\"PERL\"> PERL <BR>\n        <input type=\"submit\" value=\"Submit\">\n    </form>\n\n    <%\n    String select[] = request.getParameterValues(\"id\"); \n    if (select != null && select.length != 0) {\n        out.println(\"You have selected: \");\n        for (int i = 0; i < select.length; i++) {\n           out.println(select[i]); \n        }\n    }\n    %>\n\n\n        <% \n            switch(day) {\n            case 0:\n                   out.println(\"It\\'s Sunday.\");\n                   break;\n            case 1:\n                   out.println(\"It\\'s Monday.\");\n                   break;\n            case 2:\n                   out.println(\"It\\'s Tuesday.\");\n                   break;\n            case 3:\n                   out.println(\"It\\'s Wednesday.\");\n                   break;\n            case 4:\n                   out.println(\"It\\'s Thursday.\");\n                   break;\n            case 5:\n                   out.println(\"It\\'s Friday.\");\n                   break;\n            //hello\n            default:\n                   out.println(\"It's Saturday.\");\n            }\n        %>\n        <p>\n            <jsp:scriptlet>\n                out.println(\"Your IP address is \" + request.getRemoteAddr());\n            </jsp:scriptlet>\n        </p>\n    </body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/jssm.jssm",
    "content": "\nmachine_name    : \"Three-state traffic light, plus off and flash-red\";\nmachine_version : 1.2.1;\n\njssm_version    : >= 5.0.0;\ngraph_layout    : dot;\n\non_init         : ${setup};\non_halt         : ${finalize};\n\n\n\n/* turn on */\nOff 'Enable' { follow: ${turned_on}; } -> Red;\n\n// main sequence\nRed 'Proceed' => Green 'Proceed' => Yellow 'Proceed' => Red;\n\n// emergency flash red\n[Red Yellow Green] 'Flash' -> Flash;\nFlash 'Proceed' { label: 'no change'; } -> Flash 'Exit' -> Red;\n\n// turn off\n[Red Yellow Green Flash] 'Disable' { follow: ${turned_off}; } ~> Off;\n\n"
  },
  {
    "path": "demo/kitchen-sink/docs/jsx.jsx",
    "content": "import * as React from \"react\";\n\nexport default () => {\n  return (\n    <div variant=\"p\">\n      Keywords here are not highlighted, for example class or instance.\n    </div>\n  );\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/julia.jl",
    "content": "for op = (:+, :*, :&, :|, :$)\n  @eval ($op)(a,b,c) = ($op)(($op)(a,b),c)\nend\n\nv = α';\nfunction g(x,y)\n  return x * y\n  x + y\nend\n\ncd(\"data\") do\n    open(\"outfile\", \"w\") do f\n        write(f, data)\n    end\nend\n"
  },
  {
    "path": "demo/kitchen-sink/docs/kotlin.kt",
    "content": "#!/usr/bin/env kotlinc -script\n\n/*Taken from http://try.kotlinlang.org/#/Examples/Longer%20examples/Life/Life.kt*/\n/**\n * This is a straightforward implementation of The Game of Life\n * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life\n */\npackage life\n\n/*\n * A field where cells live. Effectively immutable\n */\nclass Field(\n        val width: Int,\n        val height: Int,\n        // This function tells the constructor which cells are alive\n        // if init(i, j) is true, the cell (i, j) is alive\n        init: (Int, Int) -> Boolean\n) {\n    private val live: Array<Array<Boolean>> = Array(height) { i -> Array(width) { j -> init(i, j) } }\n\n    private fun liveCount(i: Int, j: Int)\n            = if (i in 0..height - 1 &&\n            j in 0..width - 1 &&\n            live[i][j]) 1 else 0\n\n    // How many neighbors of (i, j) are alive?\n    fun liveNeighbors(i: Int, j: Int) =\n            liveCount(i - 1, j - 1) +\n                    liveCount(i - 1, j) +\n                    liveCount(i - 1, j + 1) +\n                    liveCount(i, j - 1) +\n                    liveCount(i, j + 1) +\n                    liveCount(i + 1, j - 1) +\n                    liveCount(i + 1, j) +\n                    liveCount(i + 1, j + 1)\n\n    // You can say field[i, j], and this function gets called\n    operator fun get(i: Int, j: Int) = live[i][j]\n}\n\nclass Test public constructor {\n}\nvar test = \"test\"\n\n/**\n * This function takes the present state of the field\n * and returns a new field representing the next moment of time\n */\nfun next(field: Field): Field {\n    return Field(field.width, field.height) { i, j ->\n        val n = field.liveNeighbors(i, j)\n        if (field[i, j])\n        // (i, j) is alive\n            n in 2..3 // It remains alive iff it has 2 or 3 neighbors\n        else\n        // (i, j) is dead\n            n == 3 // A new cell is born if there are 3 neighbors alive\n    }\n}\n\n/** A few colony examples here */\nfun main(args: Array<String>) {\n    // Simplistic demo\n    runGameOfLife(\"***\", 3)\n    // \"Star burst\"\n    runGameOfLife(\"\"\"\n        _______\n        ___*___\n        __***__\n        ___*___\n        _______\n    \"\"\", 10)\n    // Stable colony\n    runGameOfLife(\"\"\"\n        _____\n        __*__\n        _*_*_\n        __*__\n        _____\n    \"\"\", 3)\n    // Stable from the step 2\n    runGameOfLife(\"\"\"\n        __**__\n        __**__\n        __**__\n    \"\"\", 3)\n    // Oscillating colony\n    runGameOfLife(\"\"\"\n        __**____\n        __**____\n        ____**__\n        ____**__\n    \"\"\", 6)\n    // A fancier oscillating colony\n    runGameOfLife(\"\"\"\n        -------------------\n        -------***---***---\n        -------------------\n        -----*----*-*----*-\n        -----*----*-*----*-\n        -----*----*-*----*-\n        -------***---***---\n        -------------------\n        -------***---***---\n        -----*----*-*----*-\n        -----*----*-*----*-\n        -----*----*-*----*-\n        -------------------\n        -------***---***---\n        -------------------\n    \"\"\", 10)\n}\n\n// UTILITIES\n\nfun runGameOfLife(fieldText: String, steps: Int) {\n    var field = makeField(fieldText)\n    for (step in 1..steps) {\n        println(\"Step: $step\")\n        for (i in 0..field.height - 1) {\n            for (j in 0..field.width - 1) {\n                print(if (field[i, j]) \"*\" else \" \")\n            }\n            println(\"\")\n        }\n        field = next(field)\n    }\n}\n\nfun makeField(s: String): Field {\n    val lines = s.replace(\" \", \"\").split('\\n').filter({ it.isNotEmpty() })\n    val longestLine = lines.toList().maxBy { it.length } ?: \"\"\n\n    return Field(longestLine.length, lines.size) { i, j -> lines[i][j] == '*' }\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/latex.tex",
    "content": "\\usepackage{amsmath}\n\\title{\\LaTeX}\n\\date{}\n\\begin{document}\n  \\maketitle\n  \\LaTeX{} is a document preparation system for the \\TeX{}\n  typesetting program. It offers programmable desktop publishing\n  features and extensive facilities for automating most aspects of\n  typesetting and desktop publishing, including numbering and\n  cross-referencing, tables and figures, page layout, bibliographies,\n  and much more. \\LaTeX{} was originally written in 1984 by Leslie\n  Lamport and has become the dominant method for using \\TeX; few\n  people write in plain \\TeX{} anymore. The current version  is\n  \\LaTeXe.\n \n  % This is a comment; it will not be shown in the final output.\n  % The following shows a little of the typesetting power of LaTeX:\n  \\begin{align}\n    E &= mc^2                              \\\\\n    m &= \\frac{m_0}{\\sqrt{1-\\frac{v^2}{c^2}}}\n  \\end{align}\n\\end{document}"
  },
  {
    "path": "demo/kitchen-sink/docs/latte.latte",
    "content": "<!doctype html>\n<html>\n    <head>\n        <title>{$title}</title>\n        {* \n        \tcomment\n        *}\n    </head>\n    <body>\n    \t<h1 n:inner-if=1 title=1>My Webpage</h1>\n\n        <ul n:if=\"count($navigation) > 0\" id=\"navigation\">\n        {foreach [a, b, 'x', 10] as $item}\n            <li><a href=\"{$item}\">{test($item->caption)}</a></li>\n        {/foreach}\n        </ul>\n\n        {$variable}\n        {=$variable}\n        {XXXX::func($variable /* comment */)|filter}\n        {$variable?->obj|filter:10, abc, 'x$var', \"x$var\"|filter2}\n\n        {if} ... {/if true}\n\n        <script>\n\t        var a = {$a}, b = {'a': 1}, c = {'a': 1};\n\t        if (true) {\n\t        \talert();\n\t        }\n        </script>\n\n        <style>\n        \tbody { color: {$color} }\n        </style>\n    </body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/less.less",
    "content": "/* styles.less */\n\n@base: #f938ab;\n\n.box-shadow(@style, @c) when (iscolor(@c)) {\n    box-shadow:         @style @c;\n    -webkit-box-shadow: @style @c;\n    -moz-box-shadow:    @style @c;\n}\n.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {\n    .box-shadow(@style, rgba(0, 0, 0, @alpha));\n}\n\n// Box styles\n.box { \n    color: saturate(@base, 5%);\n    border-color: lighten(@base, 30%);\n    \n    div { .box-shadow(0 0 5px, 30%) }\n  \n    a {\n        color: @base;\n        \n        &:hover {\n            color: lighten(@base, 50%);\n        }\n    }\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/liquid.liquid",
    "content": "There are a couple of different Liquid variations in circulation. This grammars supports\nboth the Standard and Shopify Liquid variations. The following examples can be found in full at:\n\nStandard Variation: https://shopify.github.io/liquid\nShopify Variation: https://shopify.dev/docs/api/liquid\n\nLiquid is an extraction from the e-commerce system Shopify.\nShopify powers many thousands of e-commerce stores which all call for unique designs.\nFor this we developed Liquid which allows our customers complete design freedom while\nmaintaining the integrity of our servers.\n\nLiquid has been in production use since June 2006 and is now used by many other\nhosted web applications.\n\nIt was developed for usage in Ruby on Rails web applications and integrates seamlessly\nas a plugin but it also works excellently as a stand alone library.\n\nHere's what it looks like:\n\n  <ul id=\"products\">\n    {% for product in products %}\n      <li>\n        <h2>{{ product.title }}</h2>\n        Only {{ product.price | format_as_money }}\n\n        <p>{{ product.description | prettyprint | truncate: 200  }}</p>\n\n      </li>\n    {% endfor %}\n  </ul>\n\n\nSome more features include:\n\n<h2>Filters</h2>\n<p> The word \"tobi\" in uppercase: {{ 'tobi' | upcase }} </p>\n<p>The word \"tobi\" has {{ 'tobi' | size }} letters! </p>\n<p>Change \"Hello world\" to \"Hi world\": {{ 'Hello world' | replace: 'Hello', 'Hi' }} </p>\n<p>The date today is {{ 'now' | date: \"%Y %b %d\" }} </p>\n\n\n<h2>If</h2>\n<p>\n  {% if user.name == 'tobi' or user.name == 'marc' %}\n    hi marc or tobi\n  {% endif %}\n</p>\n\n<h2>Comments</h2>\n\n{% # Line Comment  %}\n\n{% comment %}\n  Block Comment\n{% endcomment %}\n\n<h2>Case</h2>\n<p>\n  {% case template %}\n    {% when 'index' %}\n       Welcome\n    {% when 'product' %}\n       {{ product.vendor | link_to_vendor }} / {{ product.title }}\n    {% else %}\n       {{ page_title }}\n  {% endcase %}\n</p>\n\n\n<h2>For Loops</h2>\n<p>\n  {% for item in array %}\n    {{ item }}\n  {% endfor %}\n</p>\n\n\n<h2>Tables</h2>\n<p>\n  {% tablerow item in items cols: 3 %}\n    {% if tablerowloop.col_first %}\n      First column: {{ item.variable }}\n    {% else %}\n      Different column: {{ item.variable }}\n    {% endif %}\n  {% endtablerow %}\n</p>\n\n<h2>Embedded Code Blocks</h2>\n\nThis support Shopify Liquid variation JSON schema code blocks\n\n{% schema %}\n  {\n    \"string\": \"bar\",\n    \"boolean\": true,\n    \"number\": 100,\n    \"object\": {\n      \"array\": [100, false, \"string\", {}, [] ]\n    }\n  }\n{% endschema %}\n\nThis support Shopify Liquid variation Stylesheet and Style code blocks\n\n{% style %}\n .class {\n   font-size: 10px; /* comment */\n }\n{% endstyle %}\n\n{% stylesheet %}\n .class {\n   font-size: 10px; /* comment */\n }\n{% endstylesheet %}\n\nThis support Shopify Liquid variation JavaScript code blocks\n\n{% javascript %}\n\n  function foo (param) {\n\n    return 'something' // comment\n  }\n\n{% endjavascript %}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/lisp.lisp",
    "content": "(defun prompt-for-cd ()\n   \"Prompts\n    for CD\"\n   (prompt-read \"Title\" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6))\n   (prompt-read \"Artist\" &rest)\n   (or (parse-integer (prompt-read \"Rating\") :junk-allowed t) 0)\n  (if x (format t \"yes\") (format t \"no\" nil) ;and here comment\n  ) 0xFFLL -23ull\n  ;; second line comment\n  '(+ 1 2)\n  (defvar *lines*)                ; list of all lines\n  (position-if-not #'sys::whitespacep line :start beg))\n  (quote (privet 1 2 3))\n  '(hello world)\n  (* 5 7)\n  (1 2 34 5)\n  (:use \"aaaa\")\n  (let ((x 10) (y 20))\n    (print (+ x y))\n  ) LAmbDa\n\n  \"asdad\\0eqweqe\""
  },
  {
    "path": "demo/kitchen-sink/docs/livescript.ls",
    "content": "# Defines an editing mode for [Ace](https://ace.c9.io).\n#\n# Open [test/ace.html](../test/ace.html) to test.\n\nrequire, exports, module <-! define \\ace/mode/ls\n\nidentifier = /(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*/$\n\nexports.Mode = class LiveScriptMode extends require(\\ace/mode/text)Mode\n  ->\n    @$tokenizer =\n      new (require \\ace/tokenizer)Tokenizer LiveScriptMode.Rules\n    if require \\ace/mode/matching_brace_outdent\n      @$outdent = new that.MatchingBraceOutdent\n\n  indenter = // (?\n    : [({[=:]\n    | [-~]>\n    | \\b (?: e(?:lse|xport) | d(?:o|efault) | t(?:ry|hen) | finally |\n             import (?:\\s* all)? | const | var |\n             let | new | catch (?:\\s* #identifier)? )\n  ) \\s* $ //\n\n  getNextLineIndent: (state, line, tab) ->\n    indent   = @$getIndent line\n    {tokens} = @$tokenizer.getLineTokens line, state\n    unless tokens.length and tokens[*-1]type is \\comment\n      indent += tab if state is \\start and indenter.test line\n    indent\n\n  toggleCommentLines: (state, doc, startRow, endRow) ->\n    comment = /^(\\s*)#/; range = new (require \\ace/range)Range 0 0 0 0\n    for i from startRow to endRow\n      if out = comment.test line = doc.getLine i\n      then line.=replace comment, \\$1\n      else line.=replace /^\\s*/   \\$&#\n      range.end.row = range.start.row = i\n      range.end.column = line.length + 1\n      doc.replace range, line\n    1 - out * 2\n\n  checkOutdent: (state, line, input) -> @$outdent?checkOutdent line, input\n\n  autoOutdent: (state, doc, row) -> @$outdent?autoOutdent doc, row\n\n### Highlight Rules\n\nkeywordend = /(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))/$\nstringfill = token: \\string, regex: '.+'\n\nLiveScriptMode.Rules =\n  start:\n    * token: \\keyword\n      regex: //(?\n        :t(?:h(?:is|row|en)|ry|ypeof!?)\n        |c(?:on(?:tinue|st)|a(?:se|tch)|lass)\n        |i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])\n        |d(?:e(?:fault|lete|bugger)|o)\n        |f(?:or(?:\\s+own)?|inally|unction)\n        |s(?:uper|witch)\n        |e(?:lse|x(?:tends|port)|val)\n        |a(?:nd|rguments)\n        |n(?:ew|ot)\n        |un(?:less|til)\n        |w(?:hile|ith)\n        |o[fr]|return|break|let|var|loop\n      )//$ + keywordend\n\n    * token: \\constant.language\n      regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend\n\n    * token: \\invalid.illegal\n      regex: '(?\n        :p(?:ackage|r(?:ivate|otected)|ublic)\n        |i(?:mplements|nterface)\n        |enum|static|yield\n      )' + keywordend\n\n    * token: \\language.support.class\n      regex: '(?\n        :R(?:e(?:gExp|ferenceError)|angeError)\n        |S(?:tring|yntaxError)\n        |E(?:rror|valError)\n        |Array|Boolean|Date|Function|Number|Object|TypeError|URIError\n      )' + keywordend\n\n    * token: \\language.support.function\n      regex: '(?\n        :is(?:NaN|Finite)\n        |parse(?:Int|Float)\n        |Math|JSON\n        |(?:en|de)codeURI(?:Component)?\n      )' + keywordend\n\n    * token: \\variable.language\n      regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend\n\n    * token: \\identifier\n      regex: identifier + /\\s*:(?![:=])/$\n\n    * token: \\variable\n      regex: identifier\n\n    * token: \\keyword.operator\n      regex: /(?:\\.{3}|\\s+\\?)/$\n\n    * token: \\keyword.variable\n      regex: /(?:@+|::|\\.\\.)/$\n      next : \\key\n\n    * token: \\keyword.operator\n      regex: /\\.\\s*/$\n      next : \\key\n\n    * token: \\string\n      regex: /\\\\\\S[^\\s,;)}\\]]*/$\n\n    * token: \\string.doc\n      regex: \\'''\n      next : \\qdoc\n\n    * token: \\string.doc\n      regex: \\\"\"\"\n      next : \\qqdoc\n\n    * token: \\string\n      regex: \\'\n      next : \\qstring\n\n    * token: \\string\n      regex: \\\"\n      next : \\qqstring\n\n    * token: \\string\n      regex: \\`\n      next : \\js\n\n    * token: \\string\n      regex: '<\\\\['\n      next : \\words\n\n    * token: \\string.regex\n      regex: \\//\n      next : \\heregex\n\n    * token: \\comment.doc\n      regex: '/\\\\*'\n      next : \\comment\n\n    * token: \\comment\n      regex: '#.*'\n\n    * token: \\string.regex\n      regex: //\n        /(?: [^ [ / \\n \\\\ ]*\n          (?: (?: \\\\.\n                | \\[ [^\\]\\n\\\\]* (?:\\\\.[^\\]\\n\\\\]*)* \\]\n              ) [^ [ / \\n \\\\ ]*\n          )*\n        )/ [gimy$]{0,4}\n      //$\n      next : \\key\n\n    * token: \\constant.numeric\n      regex: '(?:0x[\\\\da-fA-F][\\\\da-fA-F_]*\n                |(?:[2-9]|[12]\\\\d|3[0-6])r[\\\\da-zA-Z][\\\\da-zA-Z_]*\n                |(?:\\\\d[\\\\d_]*(?:\\\\.\\\\d[\\\\d_]*)?|\\\\.\\\\d[\\\\d_]*)\n                 (?:e[+-]?\\\\d[\\\\d_]*)?[\\\\w$]*)'\n\n    * token: \\lparen\n      regex: '[({[]'\n\n    * token: \\rparen\n      regex: '[)}\\\\]]'\n      next : \\key\n\n    * token: \\keyword.operator\n      regex: \\\\\\S+\n\n    * token: \\text\n      regex: \\\\\\s+\n\n  heregex:\n    * token: \\string.regex\n      regex: '.*?//[gimy$?]{0,4}'\n      next : \\start\n    * token: \\string.regex\n      regex: '\\\\s*#{'\n    * token: \\comment.regex\n      regex: '\\\\s+(?:#.*)?'\n    * token: \\string.regex\n      regex: '\\\\S+'\n\n  key:\n    * token: \\keyword.operator\n      regex: '[.?@!]+'\n    * token: \\identifier\n      regex: identifier\n      next : \\start\n    * token: \\text\n      regex: '.'\n      next : \\start\n\n  comment:\n    * token: \\comment.doc\n      regex: '.*?\\\\*/'\n      next : \\start\n    * token: \\comment.doc\n      regex: '.+'\n\n  qdoc:\n    token: \\string\n    regex: \".*?'''\"\n    next : \\key\n    stringfill\n\n  qqdoc:\n    token: \\string\n    regex: '.*?\"\"\"'\n    next : \\key\n    stringfill\n\n  qstring:\n    token: \\string\n    regex: /[^\\\\']*(?:\\\\.[^\\\\']*)*'/$\n    next : \\key\n    stringfill\n\n  qqstring:\n    token: \\string\n    regex: /[^\\\\\"]*(?:\\\\.[^\\\\\"]*)*\"/$\n    next : \\key\n    stringfill\n\n  js:\n    token: \\string\n    regex: /[^\\\\`]*(?:\\\\.[^\\\\`]*)*`/$\n    next : \\key\n    stringfill\n\n  words:\n    token: \\string\n    regex: '.*?\\\\]>'\n    next : \\key\n    stringfill\n"
  },
  {
    "path": "demo/kitchen-sink/docs/logiql.logic",
    "content": "// ancestors\nparentof(\"douglas\", \"john\").\nparentof(\"john\", \"bob\").\nparentof(\"bob\", \"ebbon\").\n\nparentof(\"douglas\", \"jane\").\nparentof(\"jane\", \"jan\").\n\nancestorof(A, B) <- parentof(A, B).\nancestorof(A, C) <- ancestorof(A, B), parentof(B,C).\n\ngrandparentof(A, B) <- parentof(A, C), parentof(C, B).\n\ncousins(A,B) <- grandparentof(C,A), grandparentof(C,B).\n\nparentof[`arg](A, B) -> int[32](A), !string(B)."
  },
  {
    "path": "demo/kitchen-sink/docs/logtalk.lgt",
    "content": ":- object(bottles).\n\n\t:- initialization(sing(99)).\n\n\tsing(0) :-\n\t\twrite('No more bottles of beer on the wall, no more bottles of beer.'), nl,\n\t\twrite('Go to the store and buy some more, 99 bottles of beer on the wall.'), nl, nl.\n\tsing(N) :-\n\t\tN > 0,\n\t\tN2 is N - 1,\n\t\tbeers(N), write(' of beer on the wall, '), beers(N), write(' of beer.'), nl,\n\t\twrite('Take one down and pass it around, '), beers(N2), write(' of beer on the wall.'), nl, nl,\n\t\tsing(N2).\n\n\tbeers(0) :-\n\t\twrite('no more bottles').\n\tbeers(1) :-\n\t\twrite('1 bottle').\n\tbeers(N) :-\n\t\tN > 1,\n\t\twrite(N), write(' bottles').\n\n:- end_object.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/lsl.lsl",
    "content": "/*\n    Testing syntax highlighting\n    of Ace Editor\n    for the Linden Scripting Language\n*/\n\ninteger someIntNormal       = 3672;\ninteger someIntHex          = 0x00000000;\ninteger someIntMath         = PI_BY_TWO;\n\ninteger event               = 5673;                                             // invalid.illegal\n\nkey someKeyTexture          = TEXTURE_DEFAULT;\nstring someStringSpecial    = EOF;\n\nsome_user_defined_function_without_return_type(string inputAsString)\n{\n    llSay(PUBLIC_CHANNEL, inputAsString);\n}\n\nstring user_defined_function_returning_a_string(key inputAsKey)\n{\n    return (string)inputAsKey;\n}\n\ndefault\n{\n    state_entry()\n    {\n        key someKey = NULL_KEY;\n        someKey = llGetOwner();\n\n        string someString = user_defined_function_returning_a_string(someKey);\n\n        some_user_defined_function_without_return_type(someString);\n    }\n\n    touch_start(integer num_detected)\n    {\n        list agentsInRegion = llGetAgentList(AGENT_LIST_REGION, []);\n        integer numOfAgents = llGetListLength(agentsInRegion);\n\n        integer index;                                                          // defaults to 0\n        for (; index <= numOfAgents - 1; index++)                               // for each agent in region\n        {\n            llRegionSayTo(llList2Key(agentsInRegion, index), PUBLIC_CHANNEL, \"Hello, Avatar!\");\n        }\n    }\n\n    touch_end(integer num_detected)\n    {\n        someIntNormal       = 3672;\n        someIntHex          = 0x00000000;\n        someIntMath         = PI_BY_TWO;\n\n        event               = 5673;                                             // invalid.illegal\n\n        someKeyTexture      = TEXTURE_DEFAULT;\n        someStringSpecial   = EOF;\n\n        llSetInventoryPermMask(\"some item\", MASK_NEXT, PERM_ALL);               // reserved.godmode\n\n        llWhisper(PUBLIC_CHANNEL, \"Leaving \\\"default\\\" now...\");\n        state other;\n    }\n}\n\nstate other\n{\n    state_entry()\n    {\n        llWhisper(PUBLIC_CHANNEL, \"Entered \\\"state other\\\", returning to \\\"default\\\" again...\");\n        state default;\n    }\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/lua.lua",
    "content": "--[[--\nnum_args takes in 5.1 byte code and extracts the number of arguments\nfrom its function header.\n--]]--\n\nfunction int(t)\n\treturn t:byte(1)+t:byte(2)*0x100+t:byte(3)*0x10000+t:byte(4)*0x1000000\nend\n\nfunction num_args(func)\n\tlocal dump = string.dump(func)\n\tlocal offset, cursor = int(dump:sub(13)), offset + 26\n\t--Get the params and var flag (whether there's a ... in the param)\n\treturn dump:sub(cursor):byte(), dump:sub(cursor+1):byte()\nend\n\n-- Usage:\nnum_args(function(a,b,c,d, ...) end) -- return 4, 7\n\n-- Python styled string format operator\nlocal gm = debug.getmetatable(\"\")\n\ngm.__mod=function(self, other)\n    if type(other) ~= \"table\" then other = {other} end\n    for i,v in ipairs(other) do other[i] = tostring(v) end\n    return self:format(unpack(other))\nend\n\nprint([===[\n    blah blah %s, (%d %d)\n]===]%{\"blah\", num_args(int)})\n\n--[=[--\ntable.maxn is deprecated, use # instead.\n--]=]--\nprint(table.maxn{1,2,[4]=4,[8]=8}) -- outputs 8 instead of 2\n\nprint(5 --[[ blah ]])\n"
  },
  {
    "path": "demo/kitchen-sink/docs/luapage.lp",
    "content": "﻿<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n   \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html>\n<% --[[--\n    index.lp from the Kepler Project's LuaDoc HTML doclet.\n    http://keplerproject.github.com/luadoc/\n--]] %>\n<head>\n    <title>Reference</title>\n    <link rel=\"stylesheet\" href=\"<%=luadoc.doclet.html.link(\"luadoc.css\")%>\" type=\"text/css\" />\n\t<!--meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/-->\n</head>\n\n<body>\n<div id=\"container\">\n\n<div id=\"product\">\n\t<div id=\"product_logo\"></div>\n\t<div id=\"product_name\"><big><b></b></big></div>\n\t<div id=\"product_description\"></div>\n</div> <!-- id=\"product\" -->\n\n<div id=\"main\">\n\n<div id=\"navigation\">\n<%=luadoc.doclet.html.include(\"menu.lp\", { doc=doc })%>\n\n</div> <!-- id=\"navigation\" -->\n\n<div id=\"content\">\n\n\n<%if not options.nomodules and #doc.modules > 0 then%>\n<h2>Modules</h2>\n<table class=\"module_list\">\n<!--<tr><td colspan=\"2\">Modules</td></tr>-->\n<%for _, modulename in ipairs(doc.modules) do%>\n\t<tr>\n\t\t<td class=\"name\"><a href=\"<%=luadoc.doclet.html.module_link(modulename, doc)%>\"><%=modulename%></a></td>\n\t\t<td class=\"summary\"><%=doc.modules[modulename].summary%></td>\n\t</tr>\n<%end%>\n</table>\n<%end%>\n\n\n\n<%if not options.nofiles and #doc.files > 0 then%>\n<h2>Files</h2>\n<table class=\"file_list\">\n<!--<tr><td colspan=\"2\">Files</td></tr>-->\n<%for _, filepath in ipairs(doc.files) do%>\n\t<tr>\n\t\t<td class=\"name\"><a href=\"<%=luadoc.doclet.html.file_link(filepath)%>\"><%=filepath%></a></td>\n\t\t<td class=\"summary\"></td>\n\t</tr>\n<%end%>\n</table>\n<%end%>\n\n</div> <!-- id=\"content\" -->\n\n</div> <!-- id=\"main\" -->\n\n<div id=\"about\">\n\t<p><a href=\"http://validator.w3.org/check?uri=referer\"><img src=\"http://www.w3.org/Icons/valid-xhtml10\" alt=\"Valid XHTML 1.0!\" height=\"31\" width=\"88\" /></a></p>\n</div> <!-- id=\"about\" -->\n\n</div> <!-- id=\"container\" -->\t\n</body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/lucene.lucene",
    "content": "(title:\"foo bar\" AND body:\"quick fox\") OR title:fox"
  },
  {
    "path": "demo/kitchen-sink/docs/markdown.md",
    "content": "Ace (Ajax.org Cloud9 Editor)\n============================\n\nAce is a standalone code editor written in JavaScript. Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page or JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](http://www.cloud9ide.com/) and the successor of the Mozilla Skywriter (Bespin) Project.\n\nFeatures\n--------\n\n* Syntax highlighting\n* Automatic indent and outdent\n* An optional command line\n* Handles huge documents (100,000 lines and more are no problem)\n* Fully customizable key bindings including VI and Emacs modes\n* Themes (TextMate themes can be imported)\n* Search and replace with regular expressions\n* Highlight matching parentheses\n* Toggle between soft tabs and real tabs\n* Displays hidden characters\n* Drag and drop text using the mouse\n* Line wrapping\n* Unstructured / user code folding\n* Live syntax checker (currently JavaScript/CoffeeScript)\n\nTake Ace for a spin!\n--------------------\n\nCheck out the Ace live [demo](http://ajaxorg.github.com/ace/) or get a [Cloud9 IDE account](http://run.cloud9ide.com) to experience Ace while editing one of your own GitHub projects.\n\nIf you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace/build/textarea/editor.html).\n\nHistory\n-------\n\nPreviously known as “Bespin” and “Skywriter” it’s now known as Ace (Ajax.org Cloud9 Editor)! Bespin and Ace started as two independent projects, both aiming to build a no-compromise code editor component for the web. Bespin started as part of Mozilla Labs and was based on the canvas tag, while Ace is the Editor component of the Cloud9 IDE and is using the DOM for rendering. After the release of Ace at JSConf.eu 2010 in Berlin the Skywriter team decided to merge Ace with a simplified version of Skywriter's plugin system and some of Skywriter's extensibility points. All these changes have been merged back to Ace. Both Ajax.org and Mozilla are actively developing and maintaining Ace.\n\nGetting the code\n----------------\n\nAce is a community project. We actively encourage and support contributions. The Ace source code is hosted on GitHub. It is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings!\n\n```bash\n    git clone git://github.com/ajaxorg/ace.git\n    cd ace\n    git submodule update --init --recursive\n```\n\nEmbedding Ace\n-------------\n\nAce can be easily embedded into any existing web page. The Ace git repository ships with a pre-packaged version of Ace inside of the `build` directory. The same packaged files are also available as a separate [download](https://github.com/ajaxorg/ace/downloads). Simply copy the contents of the `src` subdirectory somewhere into your project and take a look at the included demos of how to use Ace.\n\nThe easiest version is simply:\n\n```html\n    <div id=\"editor\">some text</div>\n    <script src=\"src/ace.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n    <script>\n    window.onload = function() {\n        var editor = ace.edit(\"editor\");\n    };\n    </script>\n```\n\nWith \"editor\" being the id of the DOM element, which should be converted to an editor. Note that this element must be explicitly sized and positioned `absolute` or `relative` for Ace to work. e.g.\n\n```css\n    #editor {\n        position: absolute;\n        width: 500px;\n        height: 400px;\n    }\n```\n\nTo change the theme simply include the Theme's JavaScript file\n\n```html\n    <script src=\"src/theme-twilight.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n```\n\nand configure the editor to use the theme:\n\n```javascript\n    editor.setTheme(\"ace/theme/twilight\");\n```\n\nBy default the editor only supports plain text mode; many other languages are available as separate modules. After including the mode's JavaScript file:\n\n```html\n    <script src=\"src/mode-javascript.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n```\n\nThen the mode can be used like this:\n\n```javascript\n    var JavaScriptMode = require(\"ace/mode/javascript\").Mode;\n    editor.getSession().setMode(new JavaScriptMode());\n```\n\nDocumentation\n-------------\n\nYou find a lot more sample code in the [demo app](https://github.com/ajaxorg/ace/blob/master/demo/demo.js).\n\nThere is also some documentation on the [wiki page](https://github.com/ajaxorg/ace/wiki).\n\nIf you still need help, feel free to drop a mail on the [ace mailing list](http://groups.google.com/group/ace-discuss).\n\nRunning Ace\n-----------\n\nAfter the checkout Ace works out of the box. No build step is required. Open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open Ace in Chrome simply start the bundled mini HTTP server:\n\n```bash\n    ./static.py\n```\n\nOr using Node.JS\n\n```bash\n    ./static.js\n```\n\nThe editor can then be opened at http://localhost:8888/index.html.\n\nPackage Ace\n-----------\n\nTo package Ace we use the dryice build tool developed by the Mozilla Skywriter team. Before you can build you need to make sure that the submodules are up to date.\n\n```bash\n    git submodule update --init --recursive\n```\n\nAfterwards Ace can be built by calling\n\n```bash\n    ./Makefile.dryice.js normal\n```\n\nThe packaged Ace will be put in the 'build' folder.\n\nTo build the bookmarklet version execute\n\n```bash\n    ./Makefile.dryice.js bm\n```\n\nRunning the Unit Tests\n----------------------\n\nThe Ace unit tests run on node.js. Before the first run a couple of node modules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call\n\n```bash\n    npm link .\n```\n\nTo run the tests call:\n\n```bash\n    node lib/ace/test/all.js\n```\n\nYou can also run the tests in your browser by serving:\n\n    http://localhost:8888/lib/ace/test/tests.html\n\nThis makes debugging failing tests way more easier.\n\nContributing\n------------\n\nAce wouldn't be what it is without contributions! Feel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. To protect the interests of the Ace contributors and users we require contributors to sign a Contributors License Agreement (CLA) before we pull the changes into the main repository. Our CLA is the simplest of agreements, requiring that the contributions you make to an ajax.org project are only those you're allowed to make. This helps us significantly reduce future legal risk for everyone involved. It is easy, helps everyone, takes ten minutes, and only needs to be completed once.  There are two versions of the agreement:\n\n1. [The Individual CLA](https://github.com/ajaxorg/ace/raw/master/doc/Contributor_License_Agreement-v2.pdf): use this version if you're working on an ajax.org in your spare time, or can clearly claim ownership of copyright in what you'll be submitting.\n2. [The Corporate CLA](https://github.com/ajaxorg/ace/raw/master/doc/Corporate_Contributor_License_Agreement-v2.pdf): have your corporate lawyer review and submit this if your company is going to be contributing to ajax.org  projects\n\nIf you want to contribute to an ajax.org project please print the CLA and fill it out and sign it. Then either send it by snail mail or fax to us or send it back scanned (or as a photo) by email.\n\nEmail: fabian.jakobs@web.de\n\nFax: +31 (0) 206388953\n\nAddress: Ajax.org B.V.\n  Keizersgracht 241\n  1016 EA, Amsterdam\n  the Netherlands"
  },
  {
    "path": "demo/kitchen-sink/docs/mask.mask",
    "content": "/* Mask Syntax Demo */\n\ndiv > ' Test ~[name]';\n\ndefine :userProfile {\n\theader {\n\t\th4 > @title;\n\t\tbutton.close;\n\t}\n}\n\n:userProfile {\n\t@title > ' Hello ~[: username.toUpperCase()]'\n}\n\nstyle {\n    html, body {\n        background: url('name.png') 0 0 no-repeat;\n    }\n}\n\nbutton {\n\tevent click (e) {\n\t    this.textContent = `name ${e.clientX} !`;\n\t}\n}\n\nmd > \"\"\"\n\n- div\n- span\n \nHello\n\n[one](http://google.com)\n\n\"\"\";\n\n\nheader .foo > 'Heading'\n\nbutton .baz x-signal='click: test' disabled > \"\n\tHello,\n\tworld \n\t\\\"Buddy\\\"\n\"\n\nvar a = {\n    name: `name ${window.innerWidth}`\n};\n\nspan .foo > \"~[bind: a.name]\""
  },
  {
    "path": "demo/kitchen-sink/docs/matlab.matlab",
    "content": "%{\n   %{\n      Ace Matlab demo\n   %}\n%}\n\nclassdef hello\n   methods\n      function greet(this)\n         disp('Hello!')  % say hi\n      end\n   end\nend\n\n% transpose \na = [ 'x''y', \"x\\n\\\n      y\", 1' ]' + 2'"
  },
  {
    "path": "demo/kitchen-sink/docs/maze.mz",
    "content": "## ## () ## ^^ ## ## ## ##\n## H1 C2 S1 <> S2 H2 DN ##\n## %U <> %D *2 %L IZ .. ##\n## ## ## .. ## DN *3 ## ##\n## ## ## %R C1 IZ () ## ##\n## ## ## ## >/ *1\n## () *3 *1 %L ()\n\n\n// Set divisor and dividend\nS1-> = 9\nS2-> = 24\n\n// Holding cells\nH1-> IF *1 THEN %R ELSE %N\nH2-> IF *2 THEN %R ELSE %N\n\n// Arithmetic\nDN-> -= 1\nIZ-> IF <= 0 THEN %D ELSE %U\n\nC1-> IF *3 THEN %D ELSE %R\nC2-> IF *3 THEN %U ELSE %D\n"
  },
  {
    "path": "demo/kitchen-sink/docs/mediawiki.wiki",
    "content": "{{Languages}}\n\n'''Ace''' is a standalone code editor written in [[wikipedia:JavaScript|JavaScript]]. Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be ''easily'' embedded in any web page or JavaScript application. Ace is developed as the primary editor for [http://www.cloud9ide.com/ Cloud9 IDE] and the successor of the Mozilla Skywriter (Bespin) Project.\n\n== Features ==\n* Syntax highlighting\n* Automatic indent and outdent\n* An optional command line\n* Handles huge documents (100,000 lines and more are no problem)\n* Fully customizable key bindings including VI and Emacs modes\n* Themes (TextMate themes can be imported)\n* Search and replace with regular expressions\n* Highlight matching parentheses\n* Toggle between soft tabs and real tabs\n* Displays hidden characters\n* Drag and drop text using the mouse\n* Line wrapping\n* Unstructured / user code folding\n* Live syntax checker (currently JavaScript/CoffeeScript)\n\n== Take Ace for a spin! ==\nCheck out the Ace live [http://ajaxorg.github.com/ace/ demo] or get a [http://run.cloud9ide.com Cloud9 IDE account] to experience Ace while editing one of your own GitHub projects.\n\nIf you want, you can use Ace as a textarea replacement thanks to the [http://ajaxorg.github.com/ace/build/textarea/editor.html Ace Bookmarklet].\n\n== Documentation ==\nYou find a lot more sample code in the [https://github.com/ajaxorg/ace/blob/master/demo/demo.js demo app].\n\nThere is also some documentation on the [https://github.com/ajaxorg/ace/wiki wiki page].\n\nIf you still need help, feel free to drop a mail on the [http://groups.google.com/group/ace-discuss ace mailing list].\n"
  },
  {
    "path": "demo/kitchen-sink/docs/mel.mel",
    "content": "// animated duplicates, instances script\nproc animatedDuplication (int $rangeStart, int $rangeEnd, int $numOfDuplicates, int $duplicateOrInstance)\n{\n    int $range_start = $rangeStart;\n    int $range_end = $rangeEnd;\n    int $num_of_duplicates = $numOfDuplicates;\n    int $step_size = ($range_end - $range_start) / $num_of_duplicates;\n    int $i = 0;\n    int $temp;\n\n    currentTime $range_start;     // set to range start\n\n    string $selectedObjects[];    // to store selected objects\n    $selectedObjects = `ls -sl`;  // store selected objects\n    select $selectedObjects;\n\n    while ($i <= $num_of_duplicates)\n    {\n        $temp = $range_start + ($step_size * $i);\n        currentTime ($temp);\n        // seleced the objects to duplicate or instance\n        select $selectedObjects;\n        if($duplicateOrInstance == 0)\n        {\n            duplicate;\n        }\n        else\n        {\n            instance;\n        }\n        $i++;\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/mips.s",
    "content": "# Original source from https://eng.libretexts.org\n# Kann, Charles W., \"Introduction To MIPS Assembly Language Programming\" (2015). Open Textbooks. 2.\n# https://cupola.gettysburg.edu/oer/2\n\n# Program File: Program2-1.asm\n# Author: Charles Kann\n# Purpose: First program, Hello World\n.text                   # Define the program instructions.\nmain:                   # Label to define the main program.\n    li $v0,4            # Load 4 into $v0 to indicate a print string.\n    la $a0, greeting    # Load the address of the greeting into $a0.\n    syscall             # Print greeting. The print is indicated by\n                        # $v0 having a value of 4, and the string to\n                        # print is stored at the address in $a0.\n    li $v0, 10          # Load a 10 (halt) into $v0.\n    syscall             # The program ends.\n.data                   # Define the program data.\ngreeting: .asciiz \"Hello World\" #The string to print.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/mixal.mixal",
    "content": "* PROGRAM START\nΔSTART     LDA  2000 LOAD A FROM CELL 2000\n           CMP7 =15=\n12345      HLT\n           END  START\nABC        ALF abc\n"
  },
  {
    "path": "demo/kitchen-sink/docs/mushcode.mc",
    "content": "@create phone\n&pickup phone=$pick up:@ifelse [u(is,u(mode),ICC)]={@pemit %#=You pick up the [fullname(me)].[set(me,PHONER:%#)][set(me,MODE:CIP)][set([u(INCOMING)],CONNECTED:[num(me)])][set(me,CONNECTED:[u(INCOMING)])]%r[showpicture(PICPICKUP)]%rUse '[color(green,black,psay <message>)]' (or '[color(green,black,p <message>)]') to talk into the phone.;@oemit %#=%N picks up the [fullname(me)].},{@pemit %#=You pick up the phone but no one is there. You hear a dialtone and then hang up. [play(u(DIALTONE))];@oemit %#=%N picks up the phone, but no one is on the other end.}\n&ringfun phone=[ifelse(eq(comp([u(%0/ringtone)],off),0),[color(black,cyan,INCOMING CALL FROM %1)],[play([switch([u(%0/ringtone)],1,[u(%0/ringtone1)],2,[u(%0/ringtone2)],3,[u(%0/ringtone3)],4,[u(%0/ringtone4)],5,[u(%0/ringtone5)],6,[u(%0/ringtone6)],7,[u(%0/ringtone7)],8,[u(%0/ringtone8)],9,[u(%0/ringtone9)],custom,[u(%0/customtone)],vibrate,[u(%0/vibrate)])])]\n&ringloop phone=@switch [u(ringstate)]=1,{@emit [setq(q,[u(connecting)])][set(%qq,rangs:0)][set(%qq,mode:WFC)][set(%qq,INCOMING:)];@ifelse [u(%qq/HASVMB)]={@tr me/ROUTEVMB=[u(connecting)];},{@pemit %#=[u(MSGCNC)];}},2,{@pemit %#=The call is connected.[setq(q,[u(CONNECTING)])][set(me,CONNECTED:%qq)][set(%qq,CONNECTED:[num(me)])][set(%qq,MODE:CIP)];@tr me/ciploop;@tr %qq/ciploop;},3,{@emit On [fullname(me)]'s earpiece you hear a ringing sound.[play(u(LINETONE))];@tr me/ringhere;@increment [u(connecting)]/RANGS;@wait 5={@tr me/ringloop};},4,{}\n&ringstate phone=[setq(q,u(connecting))][setq(1,[gt(u(%qq/rangs),sub(u(%qq/rings),1))])][setq(2,[and(u(is,u(%qq/MODE),CIP),u(is,u(%qq/INCOMING),[num(me)]))][setq(3,[u(is,u(%qq/MODE),ICC)])][ifelse(%q1,1,ifelse(%q2,2,ifelse(%q3,3,4)))]\n;comment\n@@(comment)\nsay [time()]\n"
  },
  {
    "path": "demo/kitchen-sink/docs/mysql.mysql",
    "content": "-- Single line comment\n\n/*\n * Multi-line comment block\n *\n */\n\n# Hash-style comment (MySQL specific)\n\n-- Database and Table Operations\nCREATE DATABASE IF NOT EXISTS demo_db\n    CHARACTER SET utf8mb4\n    COLLATE utf8mb4_unicode_ci;\n\nUSE demo_db;\n\nCREATE TABLE users (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    username VARCHAR(50) NOT NULL UNIQUE,\n    email VARCHAR(100) NOT NULL,\n    password_hash CHAR(64),\n    balance DECIMAL(10, 2) DEFAULT 0.00,\n    is_active BOOLEAN DEFAULT TRUE,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP,\n    profile_data JSON,\n    INDEX idx_email (email),\n    FULLTEXT INDEX idx_username (username)\n) ENGINE=InnoDB;\n\n-- Insert Statements\nINSERT INTO users (username, email, password_hash)\nVALUES\n    ('john_doe', 'john@example.com', SHA2('password123', 256)),\n    ('jane_smith', 'jane@example.com', SHA2('secure456', 256));\n\n-- Select with Various Clauses\nSELECT\n    u.id,\n    u.username,\n    CONCAT(UPPER(LEFT(u.username, 1)), LOWER(SUBSTRING(u.username, 2))) AS formatted_name,\n    COALESCE(u.balance, 0) AS balance,\n    DATE_FORMAT(u.created_at, '%Y-%m-%d') AS join_date\nFROM users u\nWHERE u.is_active = TRUE\n    AND u.created_at >= '2024-01-01'\n    AND u.email LIKE '%@example.com'\n    AND u.id BETWEEN 1 AND 1000\n    AND u.username IN ('john_doe', 'jane_smith')\n    AND u.profile_data IS NOT NULL\nGROUP BY u.id\nHAVING COUNT(*) > 0\nORDER BY u.created_at DESC\nLIMIT 10 OFFSET 0;\n\n-- Update Statement\nUPDATE users\nSET balance = balance + 100.50,\n    updated_at = NOW()\nWHERE username = 'john_doe';\n\n-- Delete Statement\nDELETE FROM users\nWHERE is_active = FALSE\n    AND created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);\n\n-- Join Example\nSELECT\n    u.username,\n    o.order_id,\n    o.total_amount\nFROM users u\nINNER JOIN orders o ON u.id = o.user_id\nLEFT JOIN order_items oi ON o.order_id = oi.order_id\nWHERE o.status != 'cancelled';\n\n-- Subquery and EXISTS\nSELECT * FROM users\nWHERE EXISTS (\n    SELECT 1 FROM orders\n    WHERE orders.user_id = users.id\n    AND orders.total_amount > 500\n);\n\n-- CASE Expression\nSELECT\n    username,\n    CASE\n        WHEN balance >= 1000 THEN 'Premium'\n        WHEN balance >= 100 THEN 'Standard'\n        ELSE 'Basic'\n    END AS tier\nFROM users;\n\n-- Window Functions\nSELECT\n    username,\n    balance,\n    ROW_NUMBER() OVER (ORDER BY balance DESC) AS rank,\n    SUM(balance) OVER (PARTITION BY is_active) AS total_by_status\nFROM users;\n\n-- Variables\nSET @user_count = (SELECT COUNT(*) FROM users);\nSET @tax_rate = 0.08;\n\nSELECT @user_count AS total_users;\n\n-- Stored Procedure\nDELIMITER //\nCREATE PROCEDURE GetUserByEmail(IN user_email VARCHAR(100))\nBEGIN\n    DECLARE user_exists INT DEFAULT 0;\n\n    SELECT COUNT(*) INTO user_exists\n    FROM users WHERE email = user_email;\n\n    IF user_exists > 0 THEN\n        SELECT * FROM users WHERE email = user_email;\n    ELSE\n        SELECT 'User not found' AS message;\n    END IF;\nEND //\nDELIMITER ;\n\n-- Function\nCREATE FUNCTION CalculateDiscount(price DECIMAL(10,2), discount_pct INT)\nRETURNS DECIMAL(10,2)\nDETERMINISTIC\nBEGIN\n    RETURN price * (1 - discount_pct / 100);\nEND;\n\n-- Trigger\nCREATE TRIGGER before_user_update\nBEFORE UPDATE ON users\nFOR EACH ROW\nBEGIN\n    SET NEW.updated_at = NOW();\nEND;\n\n-- Transaction\nSTART TRANSACTION;\n    UPDATE users SET balance = balance - 50 WHERE id = 1;\n    UPDATE users SET balance = balance + 50 WHERE id = 2;\nCOMMIT;\n\n-- Common Table Expression (CTE)\nWITH active_users AS (\n    SELECT * FROM users WHERE is_active = TRUE\n)\nSELECT * FROM active_users WHERE balance > 100;\n\n-- EXPLAIN for query analysis\nEXPLAIN SELECT * FROM users WHERE email = 'test@example.com';\n\n-- Numeric literals\nSELECT 42, 3.14159, 1e10, 0x1A2B, b'101010';\n\n-- String literals\nSELECT 'single quotes', \"double quotes\", `backtick identifiers`;"
  },
  {
    "path": "demo/kitchen-sink/docs/nasal.nas",
    "content": "var sayHello = func(names, favorite) {\n  foreach (var name; names) {\n    printf(\"Hello %s, %s is the best!\", name, favorite);\n  }\n}\n\nsayHello([\"World\", \"FlightGear\"], \"Nasal\");\n"
  },
  {
    "path": "demo/kitchen-sink/docs/nginx.nginx",
    "content": "user       www www;  ## Default: nobody\nworker_processes  5;  ## Default: 1\nerror_log  logs/error.log;\npid        logs/nginx.pid;\nworker_rlimit_nofile 8192;\n\nevents {\n  worker_connections  4096;  ## Default: 1024\n}\n\nhttp {\n  include    conf/mime.types;\n  include    /etc/nginx/proxy.conf;\n  include    /etc/nginx/fastcgi.conf;\n  index    index.html index.htm index.php;\n\n  default_type application/octet-stream;\n  log_format   main '$remote_addr - $remote_user [$time_local]  $status '\n    '\"$request\" $body_bytes_sent \"$http_referer\" '\n    '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n  access_log   logs/access.log  main;\n  sendfile     on;\n  tcp_nopush   on;\n  server_names_hash_bucket_size 128; # this seems to be required for some vhosts\n\n  server { # php/fastcgi\n    listen       80;\n    server_name  domain1.com www.domain1.com;\n    access_log   logs/domain1.access.log  main;\n    root         html;\n\n    location ~ \\.php$ {\n      fastcgi_pass   127.0.0.1:1025;\n    }\n  }\n\n  server { # simple reverse-proxy\n    listen       80;\n    server_name  domain2.com www.domain2.com;\n    access_log   logs/domain2.access.log  main;\n\n    # serve static files\n    location ~ ^/(images|javascript|js|css|flash|media|static)/  {\n      root    /var/www/virtual/big.server.com/htdocs;\n      expires 30d;\n    }\n\n    # pass requests for dynamic content to rails/turbogears/zope, et al\n    location / {\n      proxy_pass      http://127.0.0.1:8080;\n    }\n  }\n\n  upstream big_server_com {\n    server 127.0.0.3:8000 weight=5;\n    server 127.0.0.3:8001 weight=5;\n    server 192.168.0.1:8000;\n    server 192.168.0.1:8001;\n  }\n\n  server { # simple load balancing\n    listen          80;\n    server_name     big.server.com;\n    access_log      logs/big.server.access.log main;\n\n    location / {\n      proxy_pass      http://big_server_com;\n    }\n  }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/nim.nim",
    "content": "#[  #[ Multiline comment in already\n   commented out code. ]#\nproc p[T](x: T) = discard\n]#\necho \"This is code\"\nvar\n    p = 0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64\n\nproc getAlphabet(): string =\n  var accm = \"\"\n  for letter in 'a'..'z':  # see iterators\n    accm.add(letter)\n  return accm\n\nassert(\"a\" * 10 == \"aaaaaaaaaa\")\n"
  },
  {
    "path": "demo/kitchen-sink/docs/nix.nix",
    "content": "{\n  # Name of our deployment\n  network.description = \"HelloWorld\";\n  # Enable rolling back to previous versions of our infrastructure\n  network.enableRollback = true;\n\n  # It consists of a single server named 'helloserver'\n  helloserver =\n    # Every server gets passed a few arguments, including a reference\n    # to nixpkgs (pkgs)\n    { config, pkgs, ... }:\n    let\n      # We import our custom packages from ./default passing pkgs as argument\n      packages = import ./default.nix { pkgs = pkgs; };\n      # This is the nodejs version specified in default.nix\n      nodejs   = packages.nodejs;\n      # And this is the application we'd like to deploy\n      app      = packages.app;\n    in\n    {\n      # We'll be running our application on port 8080, because a regular\n      # user cannot bind to port 80\n      # Then, using some iptables magic we'll forward traffic designated to port 80 to 8080\n      networking.firewall.enable = true;\n      # We will open up port 22 (SSH) as well otherwise we're locking ourselves out\n      networking.firewall.allowedTCPPorts = [ 80 8080 22 ];\n      networking.firewall.allowPing = true;\n\n      # Port forwarding using iptables\n      networking.firewall.extraCommands = ''\n        iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080\n      '';\n\n      # To run our node.js program we're going to use a systemd service\n      # We can configure the service to automatically start on boot and to restart\n      # the process in case it crashes\n      systemd.services.helloserver = {\n        description = \"Hello world application\";\n        # Start the service after the network is available\n        after = [ \"network.target\" ];\n        # We're going to run it on port 8080 in production\n        environment = { PORT = \"8080\"; };\n        serviceConfig = {\n          # The actual command to run\n          ExecStart = \"${nodejs}/bin/node ${app}/server.js\";\n          # For security reasons we'll run this process as a special 'nodejs' user\n          User = \"nodejs\";\n          Restart = \"always\";\n        };\n      };\n\n      # And lastly we ensure the user we run our application as is created\n      users.extraUsers = {\n        nodejs = { };\n      };\n    };\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/nsis.nsi",
    "content": "/*\n  NSIS Mode\n  for Ace\n*/\n\n; Includes\n!include MUI2.nsh\n\n; Settings\nName \"installer_name\"\nOutFile \"installer_name.exe\"\nRequestExecutionLevel user\nCRCCheck on\n!ifdef x64\n  InstallDir \"$PROGRAMFILES64\\installer_name\"\n!else\n  InstallDir \"$PROGRAMFILES\\installer_name\"\n!endif\n\n; Pages\n!insertmacro MUI_PAGE_INSTFILES\n\n; Sections\nSection \"section_name\" section_index\n  # your code here\nSectionEnd\n\n; Functions\nFunction .onInit\n  MessageBox MB_OK \"Here comes a$\\n$\\rline-break!\"\nFunctionEnd"
  },
  {
    "path": "demo/kitchen-sink/docs/nunjucks.nunjucks",
    "content": "{{ foo.bar }}\n{{ foo[\"bar\"] }}\n{{ foo | title }}\n{{ foo | join(\",\") }}\n{{ foo | replace(\"foo\", \"bar\") | capitalize }}\n{% block header %}\nThis is the default content\n{% endblock %}\n\n<section class=\"left\">\n  {% block left %}{% endblock %}\n</section>\n\n<section class=\"right\">\n  {% block right %}\n  This is more content\n  {% endblock %}\n</section>\n{% extends \"parent.html\" %}\n\n{% block left %}\nThis is the left side!\n{% endblock %}\n\n{% block right %}\nThis is the right side!\n{% endblock %}\n\n{% block right %}\n{{ super() }}\nRight side!\n{% endblock %}\n\n{% if variable %}\n  It is true\n{% endif %}\n\n{% if hungry %}\n  I am hungry\n{% elif tired %}\n  I am tired\n{% else %}\n  I am good!\n{% endif %}\n\n<h1>Posts</h1>\n<ul>\n{% for item in items %}\n  <li>{{ item.title }}</li>\n{% else %}\n  <li>This would display if the 'item' collection were empty</li>\n{% endfor %}\n</ul>\n\n{% for ingredient, amount in food %}\n  Use {{ amount }} of {{ ingredient }}\n{% endfor %}\n\n{% for fruit, color in fruits %}\n  Did you know that {{ fruit }} is {{ color }}?\n{% endfor %}\n\n{% for x, y, z in points %}\n  Point: {{ x }}, {{ y }}, {{ z }}\n{% endfor %}\n\n<h1>Posts</h1>\n<ul>\n{% asyncEach item in items %}\n  {% include \"item-template.html\" %}\n{% endeach %}\n</ul>\n\n<h1>Posts</h1>\n<ul>\n{% asyncAll item in items %}\n  <li>{{ item.id | lookup }}</li>\n{% endall %}\n</ul>\n\n{% macro field(name, value='', type='text') %}\n<div class=\"field\">\n  <input type=\"{{ type }}\" name=\"{{ name }}\"\n         value=\"{{ value | escape }}\" />\n</div>\n{% endmacro %}\n\n{{ username }}\n{% set username = \"joe\" %}\n{{ username }}\n\n{% set standardModal %}\n    {% include 'standardModalData.html' %}\n{% endset %}\n\n<div class=\"js-modal\" data-modal=\"{{standardModal | e}}\">\n\n{% set standardModal %}\n    {% include 'standardModalData.html' %}\n{% endset %}\n\n<div class=\"js-modal\" data-modal=\"{{standardModal | e}}\">\n\n{% include \"missing.html\" ignore missing %}\n\n{% import \"forms.html\" as forms %}\n\n{{ forms.label('Username') }}\n{{ forms.field('user') }}\n{{ forms.label('Password') }}\n{{ forms.field('pass', type='password') }}\n\n{% from \"forms.html\" import field, label as description %}\n\n{{ description('Username') }}\n{{ field('user') }}\n{{ description('Password') }}\n{{ field('pass', type='password') }}\n\n{{ foo(1, 2, bar=3, baz=4) }}\n\n{# Loop through all the users #}\n{% for user in users %}...{% endfor %}\n\n\n{% set cls = cycler(\"odd\", \"even\") %}\n{% for row in rows %}\n  <div class=\"{{ cls.next() }}\">{{ row.name }}</div>\n{% endfor %}"
  },
  {
    "path": "demo/kitchen-sink/docs/objectivec.m",
    "content": "@protocol Printing: someParent\n-(void) print;\n@end\n\n@interface Fraction: NSObject <Printing, NSCopying> {\n    int numerator;\n    int denominator;\n}\n@end\n\n@\"blah\\8\" @\"a\\222sd\\d\" @\"\\faw\\\"\\? \\' \\4 n\\\\\" @\"\\56\"\n@\"\\xSF42\"\n\n-(NSDecimalNumber*)addCount:(id)addObject{\n\nreturn [count decimalNumberByAdding:addObject.count];\n\n}\n\n  NS_DURING  NS_HANDLER NS_ENDHANDLER\n\n@try {\n   if (argc > 1)    {\n    @throw [NSException exceptionWithName:@\"Throwing a test exception\" reason:@\"Testing the @throw directive.\" userInfo:nil];\n   }\n} \n@catch (id theException) {\n    NSLog(@\"%@\", theException);\n    result = 1  ;\n} \n@finally {\n    NSLog(@\"This always happens.\");\n    result += 2 ;\n}\n\n    @synchronized(lock) {\n        NSLog(@\"Hello World\");\n    }\n\nstruct { @defs( NSObject) }\n\nchar *enc1 = @encode(int);\n\n         IBOutlet|IBAction|BOOL|SEL|id|unichar|IMP|Class \n\n\n @class @protocol\n\n@public\n  // instance variables\n@package\n  // instance variables\n@protected\n  // instance variables\n@private\n  // instance variables\n\n  YES NO Nil nil\nNSApp()\nNSRectToCGRect (Protocol ProtocolFromString:\"NSTableViewDelegate\"))\n\n[SPPoint pointFromCGPoint:self.position]\n\nNSRoundDownToMultipleOfPageSize\n\n#import <stdio.h>\n\nint main( int argc, const char *argv[] ) {\n    printf( \"hello world\\n\" );\n    return 0;\n}\n\nNSChangeSpelling\n\n@\"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count\"\n\n@selector(lowercaseString) @selector(uppercaseString:)\n\nNSFetchRequest *localRequest = [[NSFetchRequest alloc] init];  \nlocalRequest.entity = [NSEntityDescription entityForName:@\"VNSource\" inManagedObjectContext:context];  \nlocalRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@\"resolution\" ascending:YES]];  \nNSPredicate *predicate = [NSPredicate predicateWithFormat:@\"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count\"];\n[NSPredicate predicateWithFormat:]\nNSString *predicateString = [NSString stringWithFormat:@\"SELF beginsWith[cd] %@\", searchString];\nNSPredicate *pred = [NSPredicate predicateWithFormat:predicateString];\nNSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; \n\nlocalRequest.predicate = [NSPredicate predicateWithFormat:@\"whichChart = %@\" argumentArray: listChartToDownload];\nlocalRequest.fetchBatchSize = 100;\narrayRequest    = [context  executeFetchRequest:localRequest error:&error1];\n\n[localRequest   release];\n\n#ifndef Nil\n#define Nil __DARWIN_NULL   /* id of Nil class */\n#endif\n\n@implementation MyObject\n- (unsigned int)areaOfWidth:(unsigned int)width\n                height:(unsigned int)height\n{\n  return width*height;\n}\n@end\n"
  },
  {
    "path": "demo/kitchen-sink/docs/ocaml.ml",
    "content": "(*\n * Example of early return implementation taken from\n * http://ocaml.janestreet.com/?q=node/91\n *)\n\nlet with_return (type t) (f : _ -> t) =\n  let module M =\n     struct exception Return of t end\n  in\n  let return = { return = (fun x -> raise (M.Return x)); } in\n  try f return with M.Return x -> x\n\n\n(* Function that uses the 'early return' functionality provided by `with_return` *)\nlet sum_until_first_negative list =\n  with_return (fun r ->\n    List.fold list ~init:0 ~f:(fun acc x ->\n      if x >= 0 then acc + x else r.return acc))"
  },
  {
    "path": "demo/kitchen-sink/docs/odin.odin",
    "content": "package main\n\nimport \"core:fmt\"\n\nmain :: proc() {\n\tprogram := \"+ + * 😃 - /\"\n\taccumulator := 0\n\n\tfor token in program {\n\t\tswitch token {\n\t\tcase '+': accumulator += 1\n\t\tcase '-': accumulator -= 1\n\t\tcase '*': accumulator *= 2\n\t\tcase '/': accumulator /= 2\n\t\tcase '😃': accumulator *= accumulator\n\t\tcase: // Ignore everything else\n\t\t}\n\t}\n\n\tfmt.printf(\"The program \\\"%s\\\" calculates the value %d\\n\", program, accumulator)\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/partiql.partiql",
    "content": "-- comment\n/* multi\n   line\n   comment */\n\nSELECT \"a\", b, c FROM stuff s INNER CROSS JOIN @s WHERE f(s)  -- comment\n-- comment\n\nSELECT VALUE {'sensor': s.sensor,\n              'readings': (SELECT VALUE l.co\n                           FROM logs as l\n                           WHERE l.sensor = s.sensor\n                          )\n             }\nFROM sensors AS s\n\nSELECT VALUE (PIVOT v AT g\n              FROM UNPIVOT r as v At g\n              WHERE g LIKE 'co%')\nFROM sensors AS r\n\n\nSELECT x.*\nFROM [{'a':1, 'b':1}, {'a':2}, 'foo'] AS x\n\n-- NOTE: the embedded ion values parse as ion (inside the backticks \"`\")\nSELECT x.*\nFROM `[{'a':1, 'b':1}, {'a':2}, \"foo\"]` AS x\n\nSELECT VALUE {v.a: v.b, v.c: v.d}\nFROM <<{'a':'same', 'b':1, 'c':'same', 'd':2}>> AS v\nWHERE v.b\n\nSELECT u.id, feedbackId, commentId, upvoteId\nFROM users as u, u.feedbacks as feedback at feedbackId\nLEFT CROSS JOIN feedback.comments as comment AT commentId\nLEFT CROSS JOIN UNPIVOT comment.upvotes as upvote at upvoteId\n\n\nSELECT (\n        SELECT numRec, tabulated\n        FROM committed.changes changes,\n          (SELECT u.id, feedbackId, commentId, upvoteId\n            FROM changes.tabulated as u,\n            u.feedbacks as feedback at feedbackId LEFT CROSS JOIN feedback.comments as comment AT commentId\n            LEFT CROSS JOIN UNPIVOT comment.upvotes as upvote at upvoteId\n          ) as tabulated,\n          changes.numRec as numRec\n        )\n    AS changes\n    FROM incoming_committed committed\n\nSELECT SUM(AVG(n)) FROM <<numbers, numbers>> AS n\n\n\nSELECT attributeId, COUNT(*) as the_count\nFROM repeating_things\nGROUP BY attributeId GROUP AS g\nHAVING 1 = 0"
  },
  {
    "path": "demo/kitchen-sink/docs/pascal.pas",
    "content": "(*****************************************************************************\n * A simple bubble sort program.  Reads integers, one per line, and prints   *\n * them out in sorted order.  Blows up if there are more than 49.            *\n *****************************************************************************)\nPROGRAM Sort(input, output);\n    CONST\n        (* Max array size. *)\n        MaxElts = 50;\n    TYPE \n        (* Type of the element array. *)\n        IntArrType = ARRAY [1..MaxElts] OF Integer;\n\n    VAR\n        (* Indexes, exchange temp, array size. *)\n        i, j, tmp, size: integer;\n\n        (* Array of ints *)\n        arr: IntArrType;\n\n    (* Read in the integers. *)\n    PROCEDURE ReadArr(VAR size: Integer; VAR a: IntArrType); \n        BEGIN\n            size := 1;\n            WHILE NOT eof DO BEGIN\n                readln(a[size]);\n                IF NOT eof THEN \n                    size := size + 1\n            END\n        END;\n\n    BEGIN\n        (* Read *)\n        ReadArr(size, arr);\n\n        (* Sort using bubble sort. *)\n        FOR i := size - 1 DOWNTO 1 DO\n            FOR j := 1 TO i DO \n                IF arr[j] > arr[j + 1] THEN BEGIN\n                    tmp := arr[j];\n                    arr[j] := arr[j + 1];\n                    arr[j + 1] := tmp;\n                END;\n\n        (* Print. *)\n        FOR i := 1 TO size DO\n            writeln(arr[i])\n    END.\n            "
  },
  {
    "path": "demo/kitchen-sink/docs/perl.pl",
    "content": "#!/usr/bin/perl\n=begin\n perl example code for Ace\n=cut\n\nuse v5.10;\nuse strict;\nuse warnings;\n\nuse List::Util qw(first);\nmy @primes;\n\n# Put 2 as the first prime so we won't have an empty array\npush @primes, 2;\n\nfor my $number_to_check (3 .. 200) {\n    # Check if the current number is divisible by any previous prime\n    # if it is, skip to the next number.  Use first to bail out as soon\n    # as we find a prime that divides it.\n    next if (first {$number_to_check % $_ == 0} @primes);\n\n    # If we reached this point it means $number_to_check is not\n    # divisable by any prime number that came before it.\n    push @primes, $number_to_check;\n}\n\n# List out all of the primes\nsay join(', ', @primes);\n"
  },
  {
    "path": "demo/kitchen-sink/docs/pgsql.pgsql",
    "content": "\nBEGIN;\n\n/**\n* Samples from PostgreSQL src/tutorial/basics.source\n*/\nCREATE TABLE weather (\n\tcity\t\tvarchar(80),\n\ttemp_lo\t\tint,\t\t-- low temperature\n\ttemp_hi\t\tint,\t\t-- high temperature\n\tprcp\t\treal,\t\t-- precipitation\n\t\"date\"\t\tdate\n);\n\nCREATE TABLE cities (\n\tname\t\tvarchar(80),\n\tlocation\tpoint\n);\n\n\nINSERT INTO weather\n    VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');\n\nINSERT INTO cities\n    VALUES ('San Francisco', '(-194.0, 53.0)');\n\nINSERT INTO weather (city, temp_lo, temp_hi, prcp, \"date\")\n    VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');\n\nINSERT INTO weather (date, city, temp_hi, temp_lo)\n    VALUES ('1994-11-29', 'Hayward', 54, 37);\n\n\nSELECT city, (temp_hi+temp_lo)/2 AS temp_avg, \"date\" FROM weather;\n\nSELECT city, temp_lo, temp_hi, prcp, \"date\", location\n    FROM weather, cities\n    WHERE city = name;\n\n\n\n/**\n* Dollar quotes starting at the end of the line are colored as SQL unless\n* a special language tag is used. Dollar quote syntax coloring is implemented\n* for Perl, Python, JavaScript, and Json.\n*/\ncreate or replace function blob_content_chunked(\n    in p_data bytea, \n    in p_chunk integer)\nreturns setof bytea as $$\n-- Still SQL comments\ndeclare\n\tv_size integer = octet_length(p_data);\nbegin\n\tfor i in 1..v_size by p_chunk loop\n\t\treturn next substring(p_data from i for p_chunk);\n\tend loop;\nend;\n$$ language plpgsql stable;\n\n\n-- pl/perl\nCREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $perl$\n    # perl comment...\n    my ($x,$y) = @_;\n    if (! defined $x) {\n        if (! defined $y) { return undef; }\n        return $y;\n    }\n    if (! defined $y) { return $x; }\n    if ($x > $y) { return $x; }\n    return $y;\n$perl$ LANGUAGE plperl;\n\n-- pl/python\nCREATE FUNCTION usesavedplan() RETURNS trigger AS $python$\n    # python comment...\n    if SD.has_key(\"plan\"):\n        plan = SD[\"plan\"]\n    else:\n        plan = plpy.prepare(\"SELECT 1\")\n        SD[\"plan\"] = plan\n$python$ LANGUAGE plpythonu;\n\n-- pl/v8 (javascript)\nCREATE FUNCTION plv8_test(keys text[], vals text[]) RETURNS text AS $javascript$\nvar o = {};\nfor(var i=0; i<keys.length; i++){\n o[keys[i]] = vals[i];\n}\nreturn JSON.stringify(o);\n$javascript$ LANGUAGE plv8 IMMUTABLE STRICT;\n\n-- json\nselect * from json_object_keys($json$\n{\n  \"f1\": 5,\n  \"f2\": \"test\",\n  \"f3\": {}\n}\n$json$);\n\n\n-- psql commands\n\\df cash*\n\n\n-- Some string samples.\nselect 'don''t do it now;' || 'maybe later';\nselect E'dont\\'t do it';\nselect length('some other''s stuff' || $$cat in hat's stuff $$);\n\nselect $$ strings\nover multiple \nlines - use dollar quotes\n$$;\n\nEND;\n\n-- Anonymous code block\nDO LANGUAGE plpgsql $$\nBEGIN\n    -- code block\nEND $$;\n\nDO $$\nBEGIN\n    -- code block\nEND; $$;\n"
  },
  {
    "path": "demo/kitchen-sink/docs/php.php",
    "content": "<?php\n\nfunction nfact($n) {\n    if ($n == 0) {\n        return 1;\n    }\n    else {\n        return $n * nfact($n - 1);\n    }\n}\n\necho \"\\n\\nPlease enter a whole number ... \";\n$num = trim(fgets(STDIN));\n\n// ===== PROCESS - Determing the factorial of the input number =====\n$output = \"\\n\\nFactorial \" . $num . \" = \" . nfact($num) . \"\\n\\n\";\necho $output;\n\n?>"
  },
  {
    "path": "demo/kitchen-sink/docs/php_laravel_blade.blade.php",
    "content": "<!-- Stored in resources/views/layouts/app.blade.php -->\n\n<html>\n    <head>\n        <title>App Name - @yield('title')</title>\n        <script>\n            var app = @json($array);\n        </script>\n    </head>\n    <body>\n        @extends('layouts.app')\n        @section('sidebar')\n            @parent\n\n            <p>This is appended to the master sidebar.</p>\n        @endsection\n \n        @if (count($records) === 1)\n            I have one record!\n        @elseif (count($records) > 1)\n            I have multiple records!\n        @else\n            I don't have any records!\n        @endif\n\n        @foreach ($users as $user)\n            @if ($user->type == 1)\n                @continue\n            @endif\n\n            <li>{{ $user->name }}</li>\n\n            @if ($user->number == 5)\n                @break\n            @endif\n        @endforeach\n\n        @foreach ($users as $user)\n            @continue($user->type == 1)\n\n            <li>{{ $user->name }}</li>\n\n            @break($user->number == 5)\n        @endforeach\n\n        <div>\n            @include('shared.errors')\n\n            <form>\n                <!-- Form Contents -->\n            </form>\n        </div>\n\n        @includeIf('view.name', ['some' => 'data'])\n\n        @env('local')\n            // The application is in the local environment...\n        @elseenv('testing')\n            // The application is in the testing environment...\n        @else\n            // The application is not in the local or testing environment...\n        @endenv\n\n        <div class=\"container\">\n            @yield('content')\n        </div>\n    </body>\n</html>\n\n\n{{-- comment --}}\n\n@if (\n    {{-- comment --}}\n    /*block comment*/\n    #another comment\n    $user->type == 1\n    // c comment\n    /* comment*/\n)\n    # not a comment <div id=\"#//x\"></div>\n@endif\n"
  },
  {
    "path": "demo/kitchen-sink/docs/pig.pig",
    "content": "A = load 'mobydick.txt';\nB = foreach A generate flatten(TOKENIZE((chararray)$0)) as word;\nC = filter B by word matches '\\\\w+';\nD = group C by word;\nE = foreach D generate COUNT(C) as count, group as word;\nF = order E by count desc;\n-- one comment\n/* another comment */\ndump F;\n"
  },
  {
    "path": "demo/kitchen-sink/docs/plaintext.txt",
    "content": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\n\nUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.\n\nAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur"
  },
  {
    "path": "demo/kitchen-sink/docs/plsql.plsql",
    "content": "create table t (\n    id integer, \n    month varchar(3), \n    value integer\n);\n\ninsert into t (month, value) values ('jan', 1);\ninsert into t (month, value) values ('jan', 1);\ninsert into t (month, value) values ('oct', 3);\ninsert into t (month, value) values ('dec', 96);\n\n\nselect * from (select month, value from t)\npivot\n(\n    sum(value)\n    for month in ('jan', 'oct', 'dec')\n);"
  },
  {
    "path": "demo/kitchen-sink/docs/powershell.ps1",
    "content": "# This is a simple comment\nfunction Hello($name) {\n  Write-host \"Hello $name\"\n}\n\nfunction add($left, $right=4) {\n    if ($right -ne 4) {\n        return $left\n    } elseif ($left -eq $null -and $right -eq 2) {\n        return 3\n    } else {\n        return 2\n    }\n}\n\n$number = 1 + 2;\n$number += 3\n\nWrite-Host Hello -name \"World\"\n\n$an_array = @(1, 2, 3)\n$a_hash = @{\"something\" = \"something else\"}\n\n& notepad .\\readme.md\n\n$h1 = @{ FirstName = \"James\"; LastName = \"Anderson\"; IDNum = 123 }\n$last = \"Anderson\"; $IDNum = 120\n$h2 = @{ FirstName = \"James\"; LastName = $last; IDNum = $IDNum + 3 }\n$h3 = @{ }\n$h4 = @{ 10 = \"James\"; 20.5 = \"Anderson\"; $true = 123 }\n\n${Maximum_Count_26}\n${Name with`twhite space and `{punctuation`}}\n${E:\\\\File.txt}\n\n\"C:\\Temp\\\" {mkdir \"C:\\Temp\\\"}\n\"C:\\Temp\\\"\n\n@\"\nThis is a here string\n$h1 = @{ FirstName = \"James\"; LastName = \"Anderson\"; IDNum = 123 }\n$last = \"Anderson\"; $IDNum = 120\n$h2 = @{ FirstName = \"James\"; LastName = $last; IDNum = $IDNum + 3 }\n$h3 = @{ }\n$h4 = @{ 10 = \"James\"; 20.5 = \"Anderson\"; $true = 123 }\n$j = 20\n\nstill string\n$($i = 10) # pipeline gets nothing\n$(($i = 10)) # pipeline gets int 10\n$($i = 10; $j) # pipeline gets int 20\n$(($i = 10); $j) # pipeline gets [object[]](10,20)\n$(($i = 10); ++$j) # pipeline gets int 10\n$(($i = 10); (++$j)) # pipeline gets [object[]](10,22)\n$($i = 10; ++$j) # pipeline gets nothing\n$(2,4,6) # pipeline gets [object[]](2,4,6)\n\"@\n\n@'\nExpressions inside should be recognised as string\n$h1 = @{ FirstName = \"James\"; LastName = \"Anderson\"; IDNum = 123 }\n$last = \"Anderson\"; $IDNum = 120\n$h2 = @{ FirstName = \"James\"; LastName = $last; IDNum = $IDNum + 3 }\n$h3 = @{ }\n$h4 = @{ 10 = \"James\"; 20.5 = \"Anderson\"; $true = 123 }\n'@\n"
  },
  {
    "path": "demo/kitchen-sink/docs/praat.praat",
    "content": "form Highlighter test\n  sentence My_sentence This should all be a string\n  text My_text This should also all be a string\n  word My_word Only the first word is a string, the rest is invalid\n  boolean Binary 1\n  boolean Text no\n  boolean Quoted \"yes\"\n  comment This should be a string\n  real left_Range -123.6\n  positive right_Range_max 3.3\n  integer Int 4\n  natural Nat 4\nendform\n\n# External scripts\ninclude /path/to/file\nrunScript: \"/path/to/file\"\nexecute /path/to/file\n\nstopwatch\n\n# old-style procedure call\ncall oldStyle \"quoted\" 2 unquoted string\nassert oldStyle.local = 1\n\n# New-style procedure call with parens\n@newStyle(\"quoted\", 2, \"quoted string\")\nif praatVersion >= 5364 \n  # New-style procedure call with colon\n  @newStyle: \"quoted\", 2, \"quoted string\"\nendif\n\n# if-block with built-in variables\nif windows\n  # We are on Windows\nelsif unix = 1 or !macintosh\n  exitScript: \"We are on Linux\"\nelse macintosh == 1\n  exit We are on Mac\nendif\n\n# inline if with inline comment\nvar = if macintosh = 1 then 0 else 1 fi ; This is an inline comment\n\n# for-loop with explicit from using local variable\n# and paren-style function calls and variable interpolation\nn = numberOfSelected(\"Sound\")\nfor i from newStyle.local to n\n  sound'i' = selected(\"Sound\", i)\n  sound[i] = sound'i'\nendfor\n\nfor i from 1 to n\n  # Different styles of object selection\n  select sound'i'\n  sound = selected()\n  sound$ = selected$(\"Sound\")\n  select Sound 'sound$'\n  selectObject(sound[i])\n  selectObject: sound\n  \n  # Pause commands\n  beginPause(\"Viewing \" + sound$)\n  if i > 1\n    button = endPause(\"Stop\", \"Previous\",\n      ...if i = total_sounds then \"Finish\" else \"Next\" fi,\n      ...3, 1)\n  else\n    button = endPause(\"Stop\",\n      ...if i = total_sounds then \"Finish\" else \"Next\" fi,\n      ...2, 1)  \n  endif\n  editor_name$ = if total_textgrids then \"TextGrid \" else \"Sound \" fi + name$\n  nocheck editor 'editor_name$'\n    nocheck Close\n  nocheck endeditor\n  \n  # New-style standalone command call\n  Rename: \"SomeName\"\n\n  # Command call with assignment\n  duration = Get total duration\n  \n  # Multi-line command with modifier\n  pitch = noprogress To Pitch (ac): 0, 75, 15, \"no\",\n    ...0.03, 0.45, 0.01, 0.35, 0.14, 600\n    \n  # do-style command with assignment\n  minimum = do(\"Get minimum...\", 0, 0, \"Hertz\", \"Parabolic\")\n\n  # New-style multi-line command call with broken strings\n  table = Create Table with column names: \"table\", 0,\n    ...\"file subject speaker\n    ...f0 f1 f2 f3 \" +\n    ...\"duration response\"\n  \n  removeObject: pitch, table\n    \n  # Picture window commands\n  selectObject: sound\n  # do-style command\n  do(\"Select inner viewport...\", 1, 6, 0.5, 1.5)\n  Black\n  Draw... 0 0 0 0 \"no\" Curve\n  Draw inner box\n  Text bottom: \"yes\", sound$\n  Erase all\n  \n  # Demo window commands\n  demo Erase all\n  demo Select inner viewport... 0 100 0 100\n  demo Axes... 0 100 0 100\n  demo Paint rectangle... white 0 100 0 100\n  demo Text... 50 centre 50 half Click to finish\n  demoWaitForInput ( )\n  demo Erase all\n  demo Text: 50, \"centre\", 50, \"half\", \"Finished\"\nendfor\n\n# An old-style sendpraat block\nsendpraat Praat\n  ...'newline$' Create Sound as pure tone... \"tone\" 1 0 0.4 44100 440 0.2 0.01 0.01\n  ...'newline$' Play\n  ...'newline$' Remove\n\n# A new-style sendpraat block\nbeginSendPraat: \"Praat\"\n  Create Sound as pure tone: \"tone\", 1, 0, 0.4, 44100, 440, 0.2, 0.01, 0.01\n  duration = Get total duration\n  Remove\nendSendPraat: \"duration\"\nappendInfoLine: \"The generated sound lasted for \", duration, \"seconds\"\n\ntime = stopwatch\nclearinfo\necho This script took \nprint 'time' seconds to \nprintline execute.\n\n# Old-style procedure declaration\nprocedure oldStyle .str1$ .num .str2$\n  .local = 1\nendproc\n\n# New-style procedure declaration with parentheses\nprocedure newStyle (.str1$, .num, .str2$)\n  # Command with \"local\" variable\n  .local = Get total duration\nendproc\n\n# New-style procedure declaration with colon\nprocedure newStyle: .str1$, .num, .str2$\n  # Command with \"local\" variable\n  newStyle.local = Get total duration\nendproc\n"
  },
  {
    "path": "demo/kitchen-sink/docs/prisma.prisma",
    "content": "generator photon {\n  provider = \"photonjs\"\n}\n\nmodel User {\n  id                 String           @default(cuid()) @id\n  createdAt          DateTime         @default(now())\n  updatedAt          DateTime         @updatedAt\n  firstName          String\n  lastName           String\n  email              String           @unique\n  password           String\n  phone              String\n  responseRate       Float?\n  responseTime       Int?\n  ReportsTo  User?  @relation(\"EmployeeToEmployee_ReportsTo\")\n  employees         User[] @relation(\"EmployeeToEmployee_ReportsTo\")\n  isSuperHost        Boolean\n  ownedPlaces        Place[]\n  location           Location?\n  bookings           Booking[]\n  paymentAccount     PaymentAccount[]\n  sentMessages       Message[]        @relation(\"SentMessages\")\n  receivedMessages   Message[]        @relation(\"ReceivedMessages\")\n  notifications      Notification[]\n  profilePicture     Picture?\n  hostingExperiences Experience[]\n}\n\nmodel Place {\n  id                String             @default(cuid()) @id\n  name              String\n  size              PLACE_SIZES?\n  shortDescription  String\n  description       String\n  slug              String\n  maxGuests         Int\n  numBedrooms       Int\n  numBeds           Int\n  numBaths          Int\n  reviews           Review[]\n  amenities         Amenities\n  host              User\n  pricing           Pricing\n  location          Location\n  views             Views\n  guestRequirements GuestRequirements?\n  policies          Policies?\n  houseRules        HouseRules?\n  bookings          Booking[]\n  pictures          Picture[]\n  popularity        Int\n}\n\nmodel Pricing {\n  id              String    @default(cuid()) @id\n  place           Place\n  monthlyDiscount Int?\n  weeklyDiscount  Int?\n  perNight        Int\n  smartPricing    Boolean\n  basePrice       Int\n  averageWeekly   Int\n  averageMonthly  Int\n  cleaningFee     Int?\n  securityDeposit Int?\n  extraGuests     Int?\n  weekendPricing  Int?\n  currency        CURRENCY?\n}\n\nmodel GuestRequirements {\n  id                            String  @default(cuid()) @id\n  govIssuedId                   Boolean\n  recommendationsFromOtherHosts Boolean\n  guestTripInformation          Boolean\n  place                         Place\n}\n\nmodel Policies {\n  id               String   @default(cuid()) @id\n  createdAt        DateTime @default(now())\n  updatedAt        DateTime @updatedAt\n  checkInStartTime Float\n  checkInEndTime   Float\n  checkoutTime     Float\n  place            Place\n}\n\nmodel HouseRules {\n  id                      String   @default(cuid()) @id\n  createdAt               DateTime @default(now())\n  updatedAt               DateTime @updatedAt\n  suitableForChildren     Boolean?\n  suitableForInfants      Boolean?\n  petsAllowed             Boolean?\n  smokingAllowed          Boolean?\n  partiesAndEventsAllowed Boolean?\n  additionalRules         String?\n}\n\nmodel Views {\n  id       String @default(cuid()) @id\n  lastWeek Int\n  place    Place\n}\n\nmodel Location {\n  id            String         @default(cuid()) @id\n  lat           Float\n  lng           Float\n  neighbourHood Neighbourhood?\n  user          User?\n  place         Place?\n  address       String\n  directions    String\n  experience    Experience?\n  restaurant    Restaurant?\n}\n\nmodel Neighbourhood {\n  id          String     @default(cuid()) @id\n  locations   Location[]\n  name        String\n  slug        String\n  homePreview Picture?\n  city        City\n  featured    Boolean\n  popularity  Int\n}\n\nmodel City {\n  id             String          @default(cuid()) @id\n  name           String\n  neighbourhoods Neighbourhood[]\n}\n\nmodel Picture {\n  id  String @default(cuid()) @id\n  url String\n}\n\nmodel Experience {\n  id             String              @default(cuid()) @id\n  category       ExperienceCategory?\n  title          String\n  host           User\n  location       Location\n  pricePerPerson Int\n  reviews        Review[]\n  preview        Picture\n  popularity     Int\n}\n\nmodel ExperienceCategory {\n  id         String      @default(cuid()) @id\n  mainColor  String\n  name       String\n  experience Experience?\n}\n\nmodel Amenities {\n  id                        String  @default(cuid()) @id\n  place                     Place\n  elevator                  Boolean\n  petsAllowed               Boolean\n  internet                  Boolean\n  kitchen                   Boolean\n  wirelessInternet          Boolean\n  familyKidFriendly         Boolean\n  freeParkingOnPremises     Boolean\n  hotTub                    Boolean\n  pool                      Boolean\n  smokingAllowed            Boolean\n  wheelchairAccessible      Boolean\n  breakfast                 Boolean\n  cableTv                   Boolean\n  suitableForEvents         Boolean\n  dryer                     Boolean\n  washer                    Boolean\n  indoorFireplace           Boolean\n  tv                        Boolean\n  heating                   Boolean\n  hangers                   Boolean\n  iron                      Boolean\n  hairDryer                 Boolean\n  doorman                   Boolean\n  paidParkingOffPremises    Boolean\n  freeParkingOnStreet       Boolean\n  gym                       Boolean\n  airConditioning           Boolean\n  shampoo                   Boolean\n  essentials                Boolean\n  laptopFriendlyWorkspace   Boolean\n  privateEntrance           Boolean\n  buzzerWirelessIntercom    Boolean\n  babyBath                  Boolean\n  babyMonitor               Boolean\n  babysitterRecommendations Boolean\n  bathtub                   Boolean\n  changingTable             Boolean\n  childrensBooksAndToys     Boolean\n  childrensDinnerware       Boolean\n  crib                      Boolean\n}\n\nmodel Review {\n  id            String      @default(cuid()) @id\n  createdAt     DateTime    @default(now())\n  text          String\n  stars         Int\n  accuracy      Int\n  location      Int\n  checkIn       Int\n  value         Int\n  cleanliness   Int\n  communication Int\n  place         Place\n  experience    Experience?\n}\n\nmodel Booking {\n  id        String   @default(cuid()) @id\n  createdAt DateTime @default(now())\n  bookee    User\n  place     Place\n  startDate DateTime\n  endDate   DateTime\n  payment   Payment?\n}\n\nmodel Payment {\n  id            String         @default(cuid()) @id\n  createdAt     DateTime       @default(now())\n  serviceFee    Float\n  placePrice    Float\n  totalPrice    Float\n  booking       Booking\n  paymentMethod PaymentAccount\n}\n\nmodel PaymentAccount {\n  id         String                 @default(cuid()) @id\n  createdAt  DateTime               @default(now())\n  type       PAYMENT_PROVIDER?\n  user       User\n  payments   Payment[]\n  paypal     PaypalInformation?\n  creditcard CreditCardInformation?\n}\n\nmodel PaypalInformation {\n  id             String         @default(cuid()) @id\n  createdAt      DateTime       @default(now())\n  email          String\n  paymentAccount PaymentAccount\n}\n\nmodel CreditCardInformation {\n  id             String          @default(cuid()) @id\n  createdAt      DateTime        @default(now())\n  cardNumber     String\n  expiresOnMonth Int\n  expiresOnYear  Int\n  securityCode   String\n  firstName      String\n  lastName       String\n  postalCode     String\n  country        String\n  paymentAccount PaymentAccount?\n}\n\nmodel Message {\n  id          String   @default(cuid()) @id\n  createdAt   DateTime @default(now())\n  from        User     @relation(\"SentMessages\")\n  to          User     @relation(\"ReceivedMessages\")\n  deliveredAt DateTime\n  readAt      DateTime\n}\n\nmodel Notification {\n  id        String             @default(cuid()) @id\n  createdAt DateTime           @default(now())\n  type      NOTIFICATION_TYPE?\n  user      User\n  link      String\n  readDate  DateTime\n}\n\nmodel Restaurant {\n  id                String    @default(cuid()) @id\n  createdAt         DateTime  @default(now())\n  title             String\n  avgPricePerPerson Int\n  pictures          Picture[]\n  location          Location\n  isCurated         Boolean\n  slug              String\n  popularity        Int\n}\n\nenum CURRENCY {\n  CAD\n  CHF\n  EUR\n  JPY\n  USD\n  ZAR\n}\n\nenum PLACE_SIZES {\n  ENTIRE_HOUSE\n  ENTIRE_APARTMENT\n  ENTIRE_EARTH_HOUSE\n  ENTIRE_CABIN\n  ENTIRE_VILLA\n  ENTIRE_PLACE\n  ENTIRE_BOAT\n  PRIVATE_ROOM\n}\n\nenum PAYMENT_PROVIDER {\n  PAYPAL\n  CREDIT_CARD\n}\n\nenum NOTIFICATION_TYPE {\n  OFFER\n  INSTANT_BOOK\n  RESPONSIVENESS\n  NEW_AMENITIES\n  HOUSE_RULES\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/prolog.plg",
    "content": "partition([], _, [], []).\npartition([X|Xs], Pivot, Smalls, Bigs) :-\n    (   X @< Pivot ->\n        Smalls = [X|Rest],\n        partition(Xs, Pivot, Rest, Bigs)\n    ;   Bigs = [X|Rest],\n        partition(Xs, Pivot, Smalls, Rest)\n    ).\n \nquicksort([])     --> [].\nquicksort([X|Xs]) -->\n    { partition(Xs, X, Smaller, Bigger) },\n    quicksort(Smaller), [X], quicksort(Bigger).\n\nperfect(N) :-\n    between(1, inf, N), U is N // 2,\n    findall(D, (between(1,U,D), N mod D =:= 0), Ds),\n    sumlist(Ds, N)."
  },
  {
    "path": "demo/kitchen-sink/docs/properties.properties",
    "content": "# You are reading the \".properties\" entry.\n! The exclamation mark can also mark text as comments.\n# The key and element characters #, !, =, and : are written with a preceding backslash to ensure that they are properly loaded.\nwebsite = http\\://en.wikipedia.org/\nlanguage = English\n# The backslash below tells the application to continue reading\n# the value onto the next line.\nmessage = Welcome to \\\n          Wikipedia!\n# Add spaces to the key\nkey\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n# Unicode\ntab : \\u0009\nempty-key=\nlast.line=value\n"
  },
  {
    "path": "demo/kitchen-sink/docs/protobuf.proto",
    "content": "message Point {\n  required int32 x = 1;\n  required int32 y = 2;\n  optional string label = 3;\n}\n\nmessage Line {\n  required Point start = 1;\n  required Point end = 2;\n  optional string label = 3;\n}\n\nmessage Polyline {\n  repeated Point point = 1;\n  optional string label = 2;\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/prql.prql",
    "content": "from invoices\nfilter invoice_date >= @1970-01-16\nderive {\n  transaction_fees = 0.8,\n  income = total - transaction_fees\n}\nfilter income > 1\ngroup customer_id (\n  aggregate {\n    average total,\n    sum_income = sum income,\n    ct = count total,\n  }\n)\nsort {-sum_income}\ntake 10\njoin c=customers (==customer_id)\nderive name = f\"{c.last_name}, {c.first_name}\"\nselect {\n  c.customer_id, name, sum_income\n}\nderive db_version = s\"version()\"\n"
  },
  {
    "path": "demo/kitchen-sink/docs/puppet.epp",
    "content": "define apache::vhost ($port, $docroot, $servername = $title, $vhost_name = '*') {\n  include apache\n  include apache::params\n  $vhost_dir = $apache::params::vhost_dir\n  file { \"${vhost_dir}/${servername}.conf\":\n      content => template('apache/vhost-default.conf.erb'),\n      owner   => 'www',\n      group   => 'www',\n      mode    => '644',\n      require => Package['httpd'],\n      notify  => Service['httpd'],\n  }\n}\n\ntype MyModule::Tree = Array[Variant[Data, Tree]]\n\nfunction apache::bool2http(Variant[String, Boolean] $arg) >> String {\n  case $arg {\n    false, undef, /(?i:false)/ : { 'Off' }\n    true, /(?i:true)/          : { 'On' }\n    default               : { \"$arg\" }\n  }\n}\n\n# A class with parameters\nclass apache (String $version = 'latest') {\n  package {'httpd':\n    ensure => $version, # Using the class parameter from above\n    before => File['/etc/httpd.conf'],\n  }\n  file {'/etc/httpd.conf':\n    ensure  => file,\n    owner   => 'httpd',\n    content => template('apache/httpd.conf.erb'), # Template from a module\n  }\n  service {'httpd':\n    ensure    => running,\n    enable    => true,\n    subscribe => File['/etc/httpd.conf'],\n  }\n}\n\n\nif $is_virtual {\n  warning( 'Tried to include class ntp on virtual machine; this node might be misclassified.' )\n}\nelsif $operatingsystem == 'Darwin' {\n  warning( 'This NTP module does not yet work on our Mac laptops.' )\nelse {\n  include ntp\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/python.py",
    "content": "#!/usr/local/bin/python\n\nimport string, sys\n\n# If no arguments were given, print a helpful message\nif len(sys.argv)==1:\n    print '''Usage:\ncelsius temp1 temp2 ...'''\n    sys.exit(0)\n\n# Loop over the arguments\nfor i in sys.argv[1:]:\n    try:\n        fahrenheit=float(string.atoi(i))\n    except string.atoi_error:\n        print repr(i), \"not a numeric value\"\n    else:\n        celsius=(fahrenheit-32)*5.0/9.0\n        print '%i\\260F = %i\\260C' % (int(fahrenheit), int(celsius+.5))"
  },
  {
    "path": "demo/kitchen-sink/docs/qml.qml",
    "content": "// A simple example\nimport QtQuick 2.7\nimport QtQuick.Controls 2.3\n\nRectangle {\n    color: \"red\"\n    anchors.fill: parent\n\n    Text {\n        text: \"WEEEEEEEEEE\"\n        font.pixelSize: 50\n        color: \"white\"\n        anchors.centerIn: parent\n        RotationAnimator on rotation {\n            running: true\n            loops: Animation.Infinite\n            from: 0\n            to: 360\n            duration: 1500\n        }\n    }\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/r.r",
    "content": "Call:\nlm(formula = y ~ x)\n \nResiduals:\n1       2       3       4       5       6\n3.3333 -0.6667 -2.6667 -2.6667 -0.6667  3.3333\n \nCoefficients:\n            Estimate Std. Error t value Pr(>|t|)\n(Intercept)  -9.3333     2.8441  -3.282 0.030453 *\nx             7.0000     0.7303   9.585 0.000662 ***\n---\nSignif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1\n \nResidual standard error: 3.055 on 4 degrees of freedom\nMultiple R-squared: 0.9583,     Adjusted R-squared: 0.9478\nF-statistic: 91.88 on 1 and 4 DF,  p-value: 0.000662\n \n> par(mfrow=c(2, 2))     # Request 2x2 plot layout\n> plot(lm_1)             # Diagnostic plot of regression model"
  },
  {
    "path": "demo/kitchen-sink/docs/raku.raku",
    "content": "=begin comment\nRaku example for ace\n=end comment\nclass Cook is Employee {\n    has @.utensils  is rw;\n    has @.cookbooks is rw;\n\n    method cook( $food ) {\n        say \"Cooking $food\";\n    }\n\n    method clean_utensils {\n        say \"Cleaning $_\" for @.utensils;\n    }\n}\n\nclass Baker is Cook {\n    method cook( $confection ) {\n        say \"Baking a tasty $confection\";\n    }\n}\n\nmy $cook = Cook.new(\n    utensils => <spoon ladle knife pan>,\n    cookbooks => 'The Joy of Cooking',\n    salary => 40000);\n\n$cook.cook( 'pizza' );       # OUTPUT: «Cooking pizza␤»\nsay $cook.utensils.perl;     # OUTPUT: «[\"spoon\", \"ladle\", \"knife\", \"pan\"]␤»\nsay $cook.cookbooks.perl;    # OUTPUT: «[\"The Joy of Cooking\"]␤»\nsay $cook.salary;            # OUTPUT: «40000␤»\n\nmy $baker = Baker.new(\n    utensils => 'self cleaning oven',\n    cookbooks => \"The Baker's Apprentice\",\n    salary => 50000);\n\n$baker.cook('brioche');      # OUTPUT: «Baking a tasty brioche␤»\nsay $baker.utensils.perl;    # OUTPUT: «[\"self cleaning oven\"]␤»\nsay $baker.cookbooks.perl;   # OUTPUT: «[\"The Baker's Apprentice\"]␤»\nsay $baker.salary;           # OUTPUT: «50000␤»\n"
  },
  {
    "path": "demo/kitchen-sink/docs/razor.cshtml",
    "content": "@* razor mode *@\n@{\n\tLayout = \"~/layout\"\n\t@: <a>\n\t@Layout\n\t@: </a>\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/rdoc.Rd",
    "content": "\\name{picker}\n\\alias{picker}\n\\title{Create a picker control}\n\\description{\n  Create a picker control to enable manipulation of plot variables based on a set of fixed choices.\n}\n\n\\usage{\npicker(..., initial = NULL, label = NULL)\n}\n\n\n\\arguments{\n  \\item{\\dots}{\n    Arguments containing objects to be presented as choices for the picker (or a list containing the choices). If an element is named then the name is used to display it within the picker. If an element is not named then it is displayed within the picker using \\code{\\link{as.character}}. \n}\n  \\item{initial}{\n    Initial value for picker. Value must be present in the list of choices specified. If not specified defaults to the first choice.\n}\n  \\item{label}{\n    Display label for picker. Defaults to the variable name if not specified.\n}\n}\n\n\\value{\n  An object of class \"manipulator.picker\" which can be passed to the \\code{\\link{manipulate}} function.\n}\n\n\\seealso{\n\\code{\\link{manipulate}}, \\code{\\link{slider}}, \\code{\\link{checkbox}}, \\code{\\link{button}}\n}\n\n\n\\examples{\n\\dontrun{\n\n## Filtering data with a picker\nmanipulate(\n  barplot(as.matrix(longley[,factor]), \n          beside = TRUE, main = factor),\n  factor = picker(\"GNP\", \"Unemployed\", \"Employed\"))\n\n## Create a picker with labels\nmanipulate(\n  plot(pressure, type = type), \n  type = picker(\"points\" = \"p\", \"line\" = \"l\", \"step\" = \"s\"))\n  \n## Picker with groups\nmanipulate(\n  barplot(as.matrix(mtcars[group,\"mpg\"]), beside=TRUE),\n  group = picker(\"Group 1\" = 1:11, \n                 \"Group 2\" = 12:22, \n                 \"Group 3\" = 23:32))\n\n## Histogram w/ picker to select type\nrequire(lattice)\nrequire(stats)\nmanipulate(\n  histogram(~ height | voice.part, \n            data = singer, type = type),\n  type = picker(\"percent\", \"count\", \"density\"))\n\n}\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/red.red",
    "content": "Red []\ninfo: func ['fn  /name /intro /args /refinements /locals /return /spec \n\t/arg-num /arg-names /arg-types /ref-names /ref-types /ref-num /type\n\t/local intr ars refs locs ret arg ref typ\n][\n\tintr: copy \"\" ars: make map! copy [] refs: make map! copy [] locs: copy [] ret: copy [] typ: ref-arg: ref-arg-type: none\n\tif lit-word? fn [fn: to-word fn]\n\tunless find [op! native! function! action!] type?/word get fn [\n\t\tcause-error 'user 'message [\"Only function types accepted!\"]\n\t]\n\tout: make map! copy []\n\tspecs: spec-of get fn \n\tparse specs [\n\t\topt [set intr string!]\n\t\tany [set arg [word! | lit-word!] opt [set typ block!] opt string! (put ars arg either typ [typ][[any-type!]])]\n\t\tany [set ref refinement! [\n\t\t\tif (ref <> /local) (put refs to-lit-word ref make map! copy []) \n\t\t\t\topt string! \n\t\t\t\tany [set ref-arg word! opt [set ref-arg-type block!] \n\t\t\t\t\t(put refs/(to-word ref) to-lit-word ref-arg either ref-arg-type [ref-arg-type][[any-type!]])\n\t\t\t\t]\n\t\t\t|\tany [set loc word! (append locs loc) opt string!] \n\t\t\t\topt [set-word! set ret block!]\n\t\t]]\n\t\t\n\t\t(\n\t\tout: case [\n\t\t\tname\t\t[to-word fn]\n\t\t\tintro \t\t[intr] \n\t\t\targs\t\t[ars]\n\t\t\targ-num\t\t[length? ars]\n\t\t\targ-names \t[copy keys-of ars] \n\t\t\targ-types\t[copy values-of ars]\n\t\t\trefinements [refs] \n\t\t\tref-names\t[copy keys-of refs]\n\t\t\tref-types\t[copy values-of refs]\n\t\t\tref-num\t\t[length? refs]\n\t\t\tlocals \t\t[locs] \n\t\t\treturn \t\t[ret]\n\t\t\tspec\t\t[specs]\n\t\t\ttrue \t\t[\n\t\t\t\tmake object!  [\n\t\t\t\t\tname: \t\tto-word fn \n\t\t\t\t\tintro: \t\tintr \n\t\t\t\t\targs: \t\tars \n\t\t\t\t\trefinements: refs \n\t\t\t\t\tlocals: \tlocs \n\t\t\t\t\treturn: \tret \n\t\t\t\t\tspec: \t\tspecs \n\t\t\t\t\ttype: \t\ttype? get fn\n\t\t\t\t\targ-num: \tlength? args\n\t\t\t\t\targ-names: \tcopy keys-of args\n\t\t\t\t\targ-types: \tcopy values-of args\n\t\t\t\t\tref-names: \tcopy keys-of refinements\n\t\t\t\t\tref-types: \tcopy values-of refinements\n\t\t\t\t\tref-num:\tlength? refinements\n\t\t\t\t]\n\t\t\t]\n\t\t])\n\t]\n\tout\n]\n"
  },
  {
    "path": "demo/kitchen-sink/docs/rhtml.Rhtml",
    "content": "<html>\n\n<head>\n<title>Title</title>\n</head>\n\n<body>\n\n<p>This is an R HTML document. When you click the <b>Knit HTML</b> button a web page will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:</p>\n\n<!--begin.rcode\nsummary(cars)\nend.rcode-->\n\n<p>You can also embed plots, for example:</p>\n\n<!--begin.rcode fig.width=7, fig.height=6\nplot(cars)\nend.rcode-->\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/robot.robot",
    "content": "*** Settings ***\nDocumentation     Robot Framework 4 syntax recipes cheat sheet robot.\n...               Demonstrates Robot Framework syntax in a concise format.\nLibrary           MyLibrary\nLibrary           MyLibrary    WITH NAME    HelloLibrary\nLibrary           MyLibrary    greeting=Howdy!    WITH NAME    HowdyLibrary\nResource          keywords.robot\nSuite Setup       Log    Suite Setup!\nSuite Teardown    Log    Suite Teardown!\nTest Setup        Log    Test Setup!\nTest Teardown     Log    Test Teardown!\nTest Timeout      2 minutes\nVariables         variables.py\n\n*** Variables ***\n${STRING}=        cat\n${NUMBER}=        ${1}\n@{LIST}=          one    two    three\n&{DICTIONARY}=    string=${STRING}    number=${NUMBER}    list=@{LIST}\n${ENVIRONMENT_VARIABLE}=    %{PATH=Default value}\n\n*** Keywords ***\nA keyword without arguments\n    Log    No arguments.\n\nA keyword with a required argument\n    [Arguments]    ${argument}\n    Log    Required argument: ${argument}\n\nA keyword with an optional argument\n    [Arguments]    ${argument}=Default value\n    Log    Optional argument: ${argument}\n    ...    Another arg\n\nA keyword with any number of arguments\n    [Arguments]    @{varargs}\n    Log    Any number of arguments: @{varargs}\n\nA keyword with one or more arguments\n    [Arguments]    ${argument}    @{varargs}\n    Log    One or more arguments: ${argument} @{varargs}\n\nA keyword that returns a value\n    [Return]    Return value\n\nA keyword with documentation\n    [Documentation]    This is keyword documentation.\n    No Operation\n\n*** Test Cases ***\nCall keywords with a varying number of arguments\n    [Tags]    Test    Another Tag\n    A keyword without arguments\n    A keyword with a required argument    Argument\n    A keyword with a required argument    argument=Argument\n    A keyword with an optional argument\n    A keyword with an optional argument    Argument\n    A keyword with an optional argument    argument=Argument\n    A keyword with any number of arguments\n    A keyword with any number of arguments    arg1    arg2    arg3    arg4    arg5\n    A keyword with one or more arguments    arg1\n    A keyword with one or more arguments    arg1    arg2    arg3\n\nCall a keyword that returns a value\n    ${value}=    A keyword that returns a value\n    Log    ${value}    # Return value\n\nDo conditional IF - ELSE IF - ELSE execution\n    IF    ${NUMBER} > 1\n        Log    Greater than one.\n    ELSE IF    \"${STRING}\" == \"dog\"\n        Log    It's a dog!\n    ELSE\n        Log    Probably a cat. 🤔\n    END\n\nLoop a list\n    Log    ${LIST}    # ['one', 'two', 'three']\n    FOR    ${item}    IN    @{LIST}\n        Log    ${item}    # one, two, three\n    END\n    FOR    ${item}    IN    one    two    three\n        Log    ${item}    # one, two, three\n    END\n\nLoop a dictionary\n    Log    ${DICTIONARY}\n    # {'string': 'cat', 'number': 1, 'list': ['one', 'two', 'three']}\n    FOR    ${key_value_tuple}    IN    &{DICTIONARY}\n        Log    ${key_value_tuple}\n        # ('string', 'cat'), ('number', 1), ('list', ['one', 'two', 'three'])\n    END\n    FOR    ${key}    IN    @{DICTIONARY}\n        Log    ${key}=${DICTIONARY}[${key}]\n        # string=cat, number=1, list=['one', 'two', 'three']\n    END\n\nLoop a range from 0 to end index\n    FOR    ${index}    IN RANGE    10\n        Log    ${index}    # 0-9\n    END\n\nLoop a range from start to end index\n    FOR    ${index}    IN RANGE    1    10\n        Log    ${index}    # 1-9\n    END\n\nLoop a range from start to end index with steps\n    FOR    ${index}    IN RANGE    0    10    2\n        Log    ${index}    # 0, 2, 4, 6, 8\n    END\n\nNest loops\n    @{alphabets}=    Create List    a    b    c\n    Log    ${alphabets}    # ['a', 'b', 'c']\n    @{numbers}=    Create List    ${1}    ${2}    ${3}\n    Log    ${numbers}    # [1, 2, 3]\n    FOR    ${alphabet}    IN    @{alphabets}\n        FOR    ${number}    IN    @{numbers}\n            Log    ${alphabet}${number}\n            # a1, a2, a3, b1, b2, b3, c1, c2, c3\n        END\n    END\n\nExit a loop on condition\n    FOR    ${i}    IN RANGE    5\n        Exit For Loop If    ${i} == 2\n        Log    ${i}    # 0, 1\n    END\n\nContinue a loop from the next iteration on condition\n    FOR    ${i}    IN RANGE    3\n        Continue For Loop If    ${i} == 1\n        Log    ${i}    # 0, 2\n    END\n\nCreate a scalar variable\n    ${animal}=    Set Variable    dog\n    Log    ${animal}    # dog\n    Log    ${animal}[0]    # d\n    Log    ${animal}[-1]    # g\n\nCreate a number variable\n    ${π}=    Set Variable    ${3.14}\n    Log    ${π}    # 3.14\n\nCreate a list variable\n    @{animals}=    Create List    dog    cat    bear\n    Log    ${animals}    # ['dog', 'cat', 'bear']\n    Log    ${animals}[0]    # dog\n    Log    ${animals}[-1]    # bear\n\nCreate a dictionary variable\n    &{dictionary}=    Create Dictionary    key1=value1    key2=value2\n    Log    ${dictionary}    # {'key1': 'value1', 'key2': 'value2'}\n    Log    ${dictionary}[key1]    # value1\n    Log    ${dictionary.key2}    # value2\n\nAccess the items in a sequence (list, string)\n    ${string}=    Set Variable    Hello world!\n    Log    ${string}[0]    # H\n    Log    ${string}[:5]    # Hello\n    Log    ${string}[6:]    # world!\n    Log    ${string}[-1]    # !\n    @{list}=    Create List    one    two    three    four    five\n    Log    ${list}    # ['one', 'two', 'three', 'four', 'five']\n    Log    ${list}[0:6:2]    # ['one', 'three', 'five']\n\nCall a custom Python library\n    ${greeting}=    MyLibrary.Get Greeting\n    Log    ${greeting}    # Hello!\n    ${greeting}=    HelloLibrary.Get Greeting\n    Log    ${greeting}    # Hello!\n    ${greeting}=    HowdyLibrary.Get Greeting\n    Log    ${greeting}    # Howdy!\n\nCall a keyword from a separate resource file\n    My keyword in a separate resource file\n\nAccess a variable in a separate variable file\n    Log    ${MY_VARIABLE_FROM_A_SEPARATE_VARIABLE_FILE}\n\nSplit arguments to multiple lines\n    A keyword with any number of arguments\n    ...    arg1\n    ...    arg2\n    ...    arg3\n\nLog available variables\n    Log Variables\n    # ${/} = /\n    # &{DICTIONARY} = { string=cat | number=1 | list=['one', 'two', 'three'] }\n    # ${OUTPUT_DIR} = /Users/<username>/...\n    # ...\n\nEvaluate Python expressions\n    ${path}=    Evaluate    os.environ.get(\"PATH\")\n    ${path}=    Set Variable    ${{os.environ.get(\"PATH\")}}\n\nUse special variables\n    Log    ${EMPTY}    # Like the ${SPACE}, but without the space.\n    Log    ${False}    # Boolean False.\n    Log    ${None}    # Python None\n    Log    ${null}    # Java null.\n    Log    ${SPACE}    # ASCII space (\\x20).\n    Log    ${SPACE * 4}    # Four spaces.\n    Log    \"${SPACE}\"    # Quoted space (\" \").\n    Log    ${True}    # Boolean True.\n    LOG    ${CURDIR}  # Current directory\n"
  },
  {
    "path": "demo/kitchen-sink/docs/rst.rst",
    "content": "==========================================\n*reStructuredText* Highlighter for **Ace**\n==========================================\n\n.. seealso::\n\n   http://docutils.sourceforge.net/docs/user/rst/quickstart.html\n\n\nReStructuredText Primer\n=======================\n\n:Author: Richard Jones\n:Version: $Revision: 5801 $\n:Copyright: This document has been placed in the public domain.\n\n.. contents::\n\n\nThe text below contains links that look like \"(quickref__)\".  These\nare relative links that point to the `Quick reStructuredText`_ user\nreference.  If these links don't work, please refer to the `master\nquick reference`_ document.\n\n__\n.. _Quick reStructuredText: quickref.html\n.. _master quick reference:\n   http://docutils.sourceforge.net/docs/user/rst/quickref.html\n\n.. Note:: This document is an informal introduction to\n   reStructuredText.  The `What Next?`_ section below has links to\n   further resources, including a formal reference.\n\n\nStructure\n---------\n\nFrom the outset, let me say that \"Structured Text\" is probably a bit\nof a misnomer.  It's more like \"Relaxed Text\" that uses certain\nconsistent patterns.  These patterns are interpreted by a HTML\nconverter to produce \"Very Structured Text\" that can be used by a web\nbrowser.\n\nThe most basic pattern recognised is a **paragraph** (quickref__).\nThat's a chunk of text that is separated by blank lines (one is\nenough).  Paragraphs must have the same indentation -- that is, line\nup at their left edge.  Paragraphs that start indented will result in\nindented quote paragraphs. For example::\n\n  This is a paragraph.  It's quite\n  short.\n\n     This paragraph will result in an indented block of\n     text, typically used for quoting other text.\n\n  This is another one.\n\nResults in:\n\n  This is a paragraph.  It's quite\n  short.\n\n     This paragraph will result in an indented block of\n     text, typically used for quoting other text.\n\n  This is another one.\n\n__ quickref.html#paragraphs\n\n\nText styles\n-----------\n\n(quickref__)\n\n__ quickref.html#inline-markup\n\nInside paragraphs and other bodies of text, you may additionally mark\ntext for *italics* with \"``*italics*``\" or **bold** with\n\"``**bold**``\".  This is called \"inline markup\".\n\nIf you want something to appear as a fixed-space literal, use\n\"````double back-quotes````\".  Note that no further fiddling is done\ninside the double back-quotes -- so asterisks \"``*``\" etc. are left\nalone.\n\nIf you find that you want to use one of the \"special\" characters in\ntext, it will generally be OK -- reStructuredText is pretty smart.\nFor example, this lone asterisk * is handled just fine, as is the\nasterisk in this equation: 5*6=30.  If you actually\nwant text \\*surrounded by asterisks* to **not** be italicised, then\nyou need to indicate that the asterisk is not special.  You do this by\nplacing a backslash just before it, like so \"``\\*``\" (quickref__), or\nby enclosing it in double back-quotes (inline literals), like this::\n\n    ``*``\n\n__ quickref.html#escaping\n\n.. Tip:: Think of inline markup as a form of (parentheses) and use it\n   the same way: immediately before and after the text being marked\n   up.  Inline markup by itself (surrounded by whitespace) or in the\n   middle of a word won't be recognized.  See the `markup spec`__ for\n   full details.\n\n__ ../../ref/rst/restructuredtext.html#inline-markup\n\n\nLists\n-----\n\nLists of items come in three main flavours: **enumerated**,\n**bulleted** and **definitions**.  In all list cases, you may have as\nmany paragraphs, sublists, etc. as you want, as long as the left-hand\nside of the paragraph or whatever aligns with the first line of text\nin the list item.\n\nLists must always start a new paragraph -- that is, they must appear\nafter a blank line.\n\n**enumerated** lists (numbers, letters or roman numerals; quickref__)\n__ quickref.html#enumerated-lists\n\nStart a line off with a number or letter followed by a period \".\",\nright bracket \")\" or surrounded by brackets \"( )\" -- whatever you're\ncomfortable with.  All of the following forms are recognised::\n\n  1. numbers\n\n  A. upper-case letters\n     and it goes over many lines\n\n     with two paragraphs and all!\n\n  a. lower-case letters\n\n     3. with a sub-list starting at a different number\n     4. make sure the numbers are in the correct sequence though!\n\n  I. upper-case roman numerals\n\n  i. lower-case roman numerals\n\n  (1) numbers again\n\n  1) and again\n\nResults in (note: the different enumerated list styles are not\nalways supported by every web browser, so you may not get the full\neffect here):\n\n1. numbers\n\nA. upper-case letters\n   and it goes over many lines\n\n   with two paragraphs and all!\n\na. lower-case letters\n\n   3. with a sub-list starting at a different number\n   4. make sure the numbers are in the correct sequence though!\n\nI. upper-case roman numerals\n\ni. lower-case roman numerals\n\n(1) numbers again\n\n1) and again\n\n**bulleted** lists (quickref__)\n__ quickref.html#bullet-lists\n\nJust like enumerated lists, start the line off with a bullet point\ncharacter - either \"-\", \"+\" or \"\\*\"::\n\n  * a bullet point using \"\\*\"\n\n    - a sub-list using \"-\"\n\n      + yet another sub-list\n\n    - another item\n\nResults in:\n\n* a bullet point using \"\\*\"\n\n  - a sub-list using \"-\"\n\n    + yet another sub-list\n\n  - another item\n\n**definition** lists (quickref__)\n__ quickref.html#definition-lists\n\nUnlike the other two, the definition lists consist of a term, and\nthe definition of that term.  The format of a definition list is::\n\n  what\n    Definition lists associate a term with a definition.\n\n  *how*\n    The term is a one-line phrase, and the definition is one or more\n    paragraphs or body elements, indented relative to the term.\n    Blank lines are not allowed between term and definition.\n\nResults in:\n\nwhat\n  Definition lists associate a term with a definition.\n\n*how*\n  The term is a one-line phrase, and the definition is one or more\n  paragraphs or body elements, indented relative to the term.\n  Blank lines are not allowed between term and definition.\n\n\nPreformatting (code samples)\n----------------------------\n(quickref__)\n\n__ quickref.html#literal-blocks\n\nTo just include a chunk of preformatted, never-to-be-fiddled-with\ntext, finish the prior paragraph with \"``::``\".  The preformatted\nblock is finished when the text falls back to the same indentation\nlevel as a paragraph prior to the preformatted block.  For example::\n\n  An example::\n\n      Whitespace, newlines, blank lines, and all kinds of markup\n        (like *this* or \\this) is preserved by literal blocks.\n    Lookie here, I've dropped an indentation level\n    (but not far enough)\n\n  no more example\n\nResults in:\n\nAn example::\n\n    Whitespace, newlines, blank lines, and all kinds of markup\n      (like *this* or \\this) is preserved by literal blocks.\n  Lookie here, I've dropped an indentation level\n  (but not far enough)\n\nno more example\n\nNote that if a paragraph consists only of \"``::``\", then it's removed\nfrom the output::\n\n  ::\n\n      This is preformatted text, and the\n      last \"::\" paragraph is removed\n\nResults in:\n\n::\n\n    This is preformatted text, and the\n    last \"::\" paragraph is removed\n\n\nSections\n--------\n\n(quickref__)\n\n__ quickref.html#section-structure\n\nTo break longer text up into sections, you use **section headers**.\nThese are a single line of text (one or more words) with adornment: an\nunderline alone, or an underline and an overline together, in dashes\n\"``-----``\", equals \"``======``\", tildes \"``~~~~~~``\" or any of the\nnon-alphanumeric characters ``= - ` : ' \" ~ ^ _ * + # < >`` that you\nfeel comfortable with.  An underline-only adornment is distinct from\nan overline-and-underline adornment using the same character.  The\nunderline/overline must be at least as long as the title text.  Be\nconsistent, since all sections marked with the same adornment style\nare deemed to be at the same level::\n\n  Chapter 1 Title\n  ===============\n\n  Section 1.1 Title\n  -----------------\n\n  Subsection 1.1.1 Title\n  ~~~~~~~~~~~~~~~~~~~~~~\n\n  Section 1.2 Title\n  -----------------\n\n  Chapter 2 Title\n  ===============\n\nThis results in the following structure, illustrated by simplified\npseudo-XML::\n\n    <section>\n        <title>\n            Chapter 1 Title\n        <section>\n            <title>\n                Section 1.1 Title\n            <section>\n                <title>\n                    Subsection 1.1.1 Title\n        <section>\n            <title>\n                Section 1.2 Title\n    <section>\n        <title>\n            Chapter 2 Title\n\n(Pseudo-XML uses indentation for nesting and has no end-tags.  It's\nnot possible to show actual processed output, as in the other\nexamples, because sections cannot exist inside block quotes.  For a\nconcrete example, compare the section structure of this document's\nsource text and processed output.)\n\nNote that section headers are available as link targets, just using\ntheir name.  To link to the Lists_ heading, I write \"``Lists_``\".  If\nthe heading has a space in it like `text styles`_, we need to quote\nthe heading \"```text styles`_``\".\n\n\nDocument Title / Subtitle\n`````````````````````````\n\nThe title of the whole document is distinct from section titles and\nmay be formatted somewhat differently (e.g. the HTML writer by default\nshows it as a centered heading).\n\nTo indicate the document title in reStructuredText, use a unique adornment\nstyle at the beginning of the document.  To indicate the document subtitle,\nuse another unique adornment style immediately after the document title.  For\nexample::\n\n    ================\n     Document Title\n    ================\n    ----------\n     Subtitle\n    ----------\n\n    Section Title\n    =============\n\n    ...\n\nNote that \"Document Title\" and \"Section Title\" above both use equals\nsigns, but are distict and unrelated styles.  The text of\noverline-and-underlined titles (but not underlined-only) may be inset\nfor aesthetics.\n\n\nImages\n------\n\n(quickref__)\n\n__ quickref.html#directives\n\nTo include an image in your document, you use the the ``image`` directive__.\nFor example::\n\n  .. image:: images/biohazard.png\n\nresults in:\n\n.. image:: images/biohazard.png\n\nThe ``images/biohazard.png`` part indicates the filename of the image\nyou wish to appear in the document. There's no restriction placed on\nthe image (format, size etc).  If the image is to appear in HTML and\nyou wish to supply additional information, you may::\n\n  .. image:: images/biohazard.png\n     :height: 100\n     :width: 200\n     :scale: 50\n     :alt: alternate text\n\nSee the full `image directive documentation`__ for more info.\n\n__ ../../ref/rst/directives.html\n__ ../../ref/rst/directives.html#images\n\n\nWhat Next?\n----------\n\nThis primer introduces the most common features of reStructuredText,\nbut there are a lot more to explore.  The `Quick reStructuredText`_\nuser reference is a good place to go next.  For complete details, the\n`reStructuredText Markup Specification`_ is the place to go [#]_.\n\nUsers who have questions or need assistance with Docutils or\nreStructuredText should post a message to the Docutils-users_ mailing\nlist.\n\n.. [#] If that relative link doesn't work, try the master document:\n   http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html.\n\n.. _reStructuredText Markup Specification:\n   ../../ref/rst/restructuredtext.html\n.. _Docutils-users: ../mailing-lists.html#docutils-users\n.. _Docutils project web site: http://docutils.sourceforge.net/\n"
  },
  {
    "path": "demo/kitchen-sink/docs/ruby.rb",
    "content": "#!/usr/bin/ruby\n\n# Program to find the factorial of a number\ndef fact(n)\n    if n == 0\n        1\n    else\n        n * fact(n-1)\n    end\nend\n\nputs fact(ARGV[0].to_i)\n\nclass Range\n  def to_json(*a)\n    {\n      'json_class'   => self.class.name, # = 'Range'\n      'data'         => [ first, last, exclude_end? ]\n    }.to_json(*a)\n  end\nend\n\n{:id => ?\", :key => \"value\"}\n\n\n    herDocs = [<<'FOO', <<BAR, <<-BAZ, <<-`EXEC`] #comment\n  FOO #{literal}\nFOO\n  BAR #{fact(10)}\nBAR\n  BAZ indented\n    BAZ\n        echo hi\n    EXEC\nputs herDocs"
  },
  {
    "path": "demo/kitchen-sink/docs/rust.rs",
    "content": "use core::rand::RngUtil;\n\nfn main() {\n    for [\"Alice\", \"Bob\", \"Carol\"].each |&name| {\n        do spawn {\n            let v = rand::Rng().shuffle([1, 2, 3]);\n            for v.each |&num| {\n                print(fmt!(\"%s says: '%d'\\n\", name, num + 1))\n            }\n        }\n    }\n}\n\nfn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {\n    let mut accumulator = ~[];\n    for vec::each(vector) |element| {\n        accumulator.push(function(element));\n    }\n    return accumulator;\n}\n\nstruct ConstGenericStruct<const N: usize>([(); N]);\n// T constrains by being an argument to GenericTrait.\nimpl<T> GenericTrait<T> for i32 { /* ... */ }\n\n// T constrains by being an arguement to GenericStruct\nimpl<T> Trait for GenericStruct<T> { /* ... */ }\n\n// Likewise, N constrains by being an argument to ConstGenericStruct\nimpl<const N: usize> Trait for ConstGenericStruct<N> { /* ... */ }\n\n// T constrains by being in an associated type in a bound for type `U` which is\n// itself a generic parameter constraining the trait.\nimpl<T, U> GenericTrait<U> for u32 where U: HasAssocType<Ty = T> { /* ... */ }\n\n// Like previous, except the type is `(U, isize)`. `U` appears inside the type\n// that includes `T`, and is not the type itself.\nimpl<T, U> GenericStruct<U> where (U, isize): HasAssocType<Ty = T> { /* ... */ }\n\n//!  - Inner line doc\n//!! - Still an inner line doc (but with a bang at the beginning)\n\n/*!  - Inner block doc */\n/*!! - Still an inner block doc (but with a bang at the beginning) */\n\n/**  - Outer block doc (exactly) 2 asterisks */\nlet multiline = r##\"\n    This is a raw string.\n    r#\"nested string\"#\n\"##;\nlet empty = br##\"\"##;\nlet _strings = [r\"hello\\\", br\"hello\\\", cr\"hello\\\" ];\n\nmacro_rules! mac_variant {\n    ($vis:vis $name:ident) => {\n        enum $name {\n            $vis Unit,\n\n            $vis Tuple(u8, u16),\n\n            $vis Struct { f: u8 },\n        }\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/sac.sac",
    "content": "/*****************************************************************************\n *\n *   SAC demo program\n *\n *   This SAC demo program implements 2-dimensional relaxation on double\n *   precision floating point numbers applying a 4-point stencil and fixed\n *   boundary conditions.\n *\n *   The vertical (SIZE1) and the horizontal (SIZE2) array size as well as\n *   the number of iterations to be performed (LOOP) may be set at compile\n *   time.\n *\n *****************************************************************************/\n\n#ifndef LOOP\n#define LOOP 100\n#endif\n\n#ifndef SIZE1\n#define SIZE1 1000\n#endif\n\n#ifndef SIZE2\n#define SIZE2 1000\n#endif\n\nuse Array: all;\nuse StdIO: all;\n\ninline\ndouble[+] onestep(double[+] B)\n{\n  A = with {\n        ( . < x < . ) : 0.25*(B[x+[1,0]]\n                              + B[x-[1,0]]\n                              + B[x+[0,1]]\n                              + B[x-[0,1]]);\n      } : modarray( B );\n\n  return(A);\n}\n\ninline\ndouble[+] relax(double[+] A, int steps)\n{\n  for (k=0; k<steps; k++) {\n    A = onestep(A);\n  }\n\n  return(A);\n}\n\nint main ()\n{\n  A = with {\n        ( . <= x <= . ) : 0.0d;\n      } : genarray( [SIZE1,SIZE2] );\n\n  A = modarray(A, [0,1], 500.0d);\n  A = relax( A, LOOP);\n\n  z = with {\n        ( 0*shape(A) <= x < shape(A) ) : A[x];\n      } : fold( +, 0d );\n\n#if 0\n  printf(\"%.10g\\n\", z);\n  return(0);\n#else\n  print( z);\n  return( 0);\n#endif\n}\n\n\n"
  },
  {
    "path": "demo/kitchen-sink/docs/sass.sass",
    "content": "// sass ace mode;\n\n@import url(http://fonts.googleapis.com/css?family=Ace:700)\n\nhtml, body\n  :background-color #ace\n  text-align: center\n  height: 100%\n  /*;*********;\n    ;comment  ;\n    ;*********;\n\n.toggle\n  $size: 14px\n\n  :background url(http://subtlepatterns.com/patterns/dark_stripes.png)\n  border-radius: 8px\n  height: $size\n\n  &:before\n    $radius: $size * 0.845\n    $glow: $size * 0.125\n\n    box-shadow: 0 0 $glow $glow / 2 #fff\n    border-radius: $radius\n    \n    &:active\n      ~ .button\n        box-shadow: 0 15px 25px -4px rgba(0,0,0,0.4)      \n      ~ .label\n        font-size: 40px\n        color: rgba(0,0,0,0.45)\n\n    &:checked      \n      ~ .button\n        box-shadow: 0 15px 25px -4px #ace\n      ~ .label\n        font-size: 40px\n        color: #c9c9c9\n"
  },
  {
    "path": "demo/kitchen-sink/docs/scad.scad",
    "content": "// ace can highlight scad!\nmodule Element(xpos, ypos, zpos){\n\ttranslate([xpos,ypos,zpos]){\n\t\tunion(){\n\t\t\tcube([10,10,4],true);\n\t\t\tcylinder(10,15,5);\n\t\t\ttranslate([0,0,10])sphere(5);\n\t\t}\n\t}\n}\n\nunion(){\n\tfor(i=[0:30]){\n\t\t# Element(0,0,0);\n\t\tElement(15*i,0,0);\n\t}\n}\n\nfor (i = [3, 5, 7, 11]){\n\trotate([i*10,0,0])scale([1,1,i])cube(10);\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/scala.scala",
    "content": "// http://www.scala-lang.org/node/54\n\npackage examples.actors\n\nimport scala.actors.Actor\nimport scala.actors.Actor._\n\nabstract class PingMessage\ncase object Start extends PingMessage\ncase object SendPing extends PingMessage\ncase object Pong extends PingMessage\n\nabstract class PongMessage\ncase object Ping extends PongMessage\ncase object Stop extends PongMessage\n\nobject pingpong extends Application {\n  val pong = new Pong\n  val ping = new Ping(100000, pong)\n  ping.start\n  pong.start\n  ping ! Start\n}\n\nclass Ping(count: Int, pong: Actor) extends Actor {\n  def act() {\n    println(\"Ping: Initializing with count \"+count+\": \"+pong)\n    var pingsLeft = count\n    loop {\n      react {\n        case Start =>\n          println(\"Ping: starting.\")\n          pong ! Ping\n          pingsLeft = pingsLeft - 1\n        case SendPing =>\n          pong ! Ping\n          pingsLeft = pingsLeft - 1\n        case Pong =>\n          if (pingsLeft % 1000 == 0)\n            println(\"Ping: pong from: \"+sender)\n          if (pingsLeft > 0)\n            self ! SendPing\n          else {\n            println(\"Ping: Stop.\")\n            pong ! Stop\n            exit('stop)\n          }\n      }\n    }\n  }\n}\n\nclass Pong extends Actor {\n  def act() {\n    var pongCount = 0\n    loop {\n      react {\n        case Ping =>\n          if (pongCount % 1000 == 0)\n            println(\"Pong: ping \"+pongCount+\" from \"+sender)\n          sender ! Pong\n          pongCount = pongCount + 1\n        case Stop =>\n          println(\"Pong: Stop.\")\n          exit('stop)\n      }\n    }\n  }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/scheme.scm",
    "content": "(define (prompt-for-cd)\n   \"Prompts\n    for CD\"\n   (prompt-read \"Title\" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6))\n   (prompt-read \"Artist\")\n   (or (parse-integer (prompt-read \"Rating\") #:junk-allowed #t) 0)\n  (if x (format #t \"yes\") (format #f \"no\") ;and here comment\n  ) \n  ;; second line comment\n  '(+ 1 2)\n  (position-if-not char-set:whitespace line #:start beg))\n  (quote (privet 1 2 3))\n  '(hello world)\n  (* 5 7)\n  (1 2 34 5)\n  (#:use \"aaaa\")\n  (let ((x 10) (y 20))\n    (display (+ x y))\n  ) \n\n  \"asdad\\0eqweqe\"\n"
  },
  {
    "path": "demo/kitchen-sink/docs/scrypt.scrypt",
    "content": "// https://github.com/sCrypt-Inc/boilerplate/blob/master/contracts/ackermann.scrypt\n\ncontract Ackermann {\n    int a; // a = 2\n    int b; // b = 1\n\n    static const int LOOPCOUNT = 14;\n\n    function ackermann(int m, int n) : int {\n        bytes stk = num2bin(m, 1);\n\n        // run this function off chain to get the loop count and set it here\n        // e.g., (2, 1) requires 14 loops, (3, 5) 42438\n        loop (LOOPCOUNT) {\n            if (len(stk) > 0) {\n                bytes top = stk[0 : 1];\n                m = unpack(top);\n\n                // pop\n                stk = stk[1 : len(stk)];\n\n                if (m == 0) {\n                    n = n + m + 1;\n                }\n                else if (n == 0) {\n                    n++;\n                    m--;\n                    // push\n                    stk = num2bin(m, 1) + stk;\n                }\n                else {\n                    stk = num2bin(m - 1, 1) + stk;\n                    stk = num2bin(m, 1) + stk;\n                    n--;\n                }\n            }\n        }\n\n        return n;\n    }\n\n    // y = 5\n    public function unlock(int y) {\n        require(y == this.ackermann(this.a, this.b));\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/scss.scss",
    "content": "/* style.scss */\n\n#navbar {\n    $navbar-width: 800px;\n    $items: 5;\n    $navbar-color: #ce4dd6;\n\n    width: $navbar-width;\n    border-bottom: 2px solid $navbar-color;\n\n    li {\n        float: left;\n        width: $navbar-width/$items - 10px;\n\n        background-color: lighten($navbar-color, 20%);\n        &:hover {\n            background-color: lighten($navbar-color, 10%);\n        }\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/sh.sh",
    "content": "#!/bin/sh\n\n# Script to open a browser to current branch\n# Repo formats:\n# ssh   git@github.com:richo/gh_pr.git\n# http  https://richoH@github.com/richo/gh_pr.git\n# git   git://github.com/richo/gh_pr.git\n\nusername=`git config --get github.user`\n\nget_repo() {\n    git remote -v | grep ${@:-$username} | while read remote; do\n      if repo=`echo $remote | grep -E -o \"git@github.com:[^ ]*\"`; then\n          echo $repo | sed -e \"s/^git@github\\.com://\" -e \"s/\\.git$//\"\n          exit 1\n      fi\n      if repo=`echo $remote | grep -E -o \"https?://([^@]*@)?github.com/[^ ]*\\.git\"`; then\n          echo $repo | sed -e \"s|^https?://||\" -e \"s/^.*github\\.com\\///\" -e \"s/\\.git$//\"\n          exit 1\n      fi\n      if repo=`echo $remote | grep -E -o \"git://github.com/[^ ]*\\.git\"`; then\n          echo $repo | sed -e \"s|^git://github.com/||\" -e \"s/\\.git$//\"\n          exit 1\n      fi\n    done\n\n    if [ $? -eq 0 ]; then\n        echo \"Couldn't find a valid remote\" >&2\n        exit 1\n    fi\n}\n\necho ${#x[@]}\n\nif repo=`get_repo $@`; then\n    branch=`git symbolic-ref HEAD 2>/dev/null`\n    echo \"http://github.com/$repo/pull/new/${branch##refs/heads/}\"\nelse\n    exit 1\nfi\n"
  },
  {
    "path": "demo/kitchen-sink/docs/sjs.sjs",
    "content": "var { each, map } = require('sjs:sequence');\nvar { get } = require('sjs:http');\n\nfunction foo(items, nada) {\n    var component = { name: \"Ace\", role: \"Editor\" };\n    console.log(\"\n        Welcome, #{component.name}\n    \".trim());\n\n    logging.debug(`Component added: $String(component) (${component})`);\n\n    console.log(`\n        Welcome, {${function() {\n            return { x: 1, y: \"why?}\"};\n        }()}\n    `.trim());\n\n    waitfor {\n        items .. each.par { |item|\n            get(item);\n        }\n    } and {\n        var lengths = items .. map(i -> i.length);\n    } or {\n        hold(1500);\n        throw new Error(\"timed out\");\n    }\n}\t// Real Tab.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/slim.slim",
    "content": "doctype html\nhtml\n  head\n    title Slim Examples\n    meta name=\"keywords\" content=\"template language\"\n    meta name=\"author\" content=author\n    link rel=\"icon\" type=\"image/png\" href=file_path(\"favicon.png\")\n    javascript:\n        alert('Slim supports embedded javascript!')\n\n  body\n    h1 Markup examples\n\n    #content\n      p This example shows you how a basic Slim file looks.\n\n    == yield\n\n    - if items.any?\n      table#items\n        - for item in items\n          tr\n            td.name = item.name\n            td.price = item.price\n    - else\n      p No items found. Please add some inventory.\n        Thank you!\n\n    div id=\"footer\"\n      == render 'footer'\n      | Copyright &copy; #{@year} #{@author}\n        indenting test\n\n    - @page_current = true"
  },
  {
    "path": "demo/kitchen-sink/docs/smarty.smarty",
    "content": "{foreach $foo as $bar}\n  <a href=\"{$bar.zig}\">{$bar.zag}</a>\n  <a href=\"{$bar.zig2}\">{$bar.zag2}</a>\n  <a href=\"{$bar.zig3}\">{$bar.zag3}</a>\n{foreachelse}\n  There were no rows found.\n{/foreach}"
  },
  {
    "path": "demo/kitchen-sink/docs/smithy.smithy",
    "content": "namespace example.weather\n\n/// Provides weather forecasts.\n@paginated(inputToken: \"nextToken\", outputToken: \"nextToken\",\n           pageSize: \"pageSize\")\nservice Weather {\n    version: \"2006-03-01\",\n    resources: [City],\n    operations: [GetCurrentTime]\n}\n\nresource City {\n    identifiers: { cityId: CityId },\n    read: GetCity,\n    list: ListCities,\n    resources: [Forecast],\n}\n\nresource Forecast {\n    identifiers: { cityId: CityId },\n    read: GetForecast,\n}\n\n// \"pattern\" is a trait.\n@pattern(\"^[A-Za-z0-9 ]+$\")\nstring CityId\n\n@readonly\noperation GetCity {\n    input: GetCityInput,\n    output: GetCityOutput,\n    errors: [NoSuchResource]\n}\n\nstructure GetCityInput {\n    // \"cityId\" provides the identifier for the resource and\n    // has to be marked as required.\n    @required\n    cityId: CityId\n}\n\nstructure GetCityOutput {\n    // \"required\" is used on output to indicate if the service\n    // will always provide a value for the member.\n    @required\n    name: String,\n\n    @required\n    coordinates: CityCoordinates,\n}\n\n// This structure is nested within GetCityOutput.\nstructure CityCoordinates {\n    @required\n    latitude: Float,\n\n    @required\n    longitude: Float,\n}\n\n// \"error\" is a trait that is used to specialize\n// a structure as an error.\n@error(\"client\")\nstructure NoSuchResource {\n    @required\n    resourceType: String\n}\n\n// The paginated trait indicates that the operation may\n// return truncated results.\n@readonly\n@paginated(items: \"items\")\noperation ListCities {\n    input: ListCitiesInput,\n    output: ListCitiesOutput\n}\n\nstructure ListCitiesInput {\n    nextToken: String,\n    pageSize: Integer\n}\n\nstructure ListCitiesOutput {\n    nextToken: String,\n\n    @required\n    items: CitySummaries,\n}\n\n// CitySummaries is a list of CitySummary structures.\nlist CitySummaries {\n    member: CitySummary\n}\n\n// CitySummary contains a reference to a City.\n@references([{resource: City}])\nstructure CitySummary {\n    @required\n    cityId: CityId,\n\n    @required\n    name: String,\n}\n\n@readonly\noperation GetCurrentTime {\n    output: GetCurrentTimeOutput\n}\n\nstructure GetCurrentTimeOutput {\n    @required\n    time: Timestamp\n}\n\n@readonly\noperation GetForecast {\n    input: GetForecastInput,\n    output: GetForecastOutput\n}\n\n// \"cityId\" provides the only identifier for the resource since\n// a Forecast doesn't have its own.\nstructure GetForecastInput {\n    @required\n    cityId: CityId,\n}\n\nstructure GetForecastOutput {\n    chanceOfRain: Float\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/snippets.snippets",
    "content": "# Function\nsnippet fun\n\tfunction ${1?:function_name}(${2:argument}) {\n\t\t${3:// body...}\n\t}\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nname f\n\tfunction${M1?: ${1:functionName}}($2) {\n\t\t${0:$TM_SELECTED_TEXT}\n\t}${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n\t(function(${1}) {\n\t\t${0:${TM_SELECTED_TEXT:/* code */}}\n\t}(${1}));\n# if\nsnippet if\n\tif (${1:true}) {\n\t\t${0}\n\t}\n\t\n\t\n\t"
  },
  {
    "path": "demo/kitchen-sink/docs/soy_template.soy",
    "content": "/**\n * Greets a person using \"Hello\" by default.\n * @param name The name of the person.\n * @param? greetingWord Optional greeting word to use instead of \"Hello\".\n */\n{template .helloName #eee}\n  {if not $greetingWord}\n    Hello {$name}!\n  {else}\n    {$greetingWord} {$name}!\n  {/if}\n{/template}\n\n/**\n * Greets a person and optionally a list of other people.\n * @param name The name of the person.\n * @param additionalNames The additional names to greet. May be an empty list.\n */\n{template .helloNames}\n  // Greet the person.\n  {call .helloName data=\"all\" /}<br>\n  // Greet the additional people.\n  {foreach $additionalName in $additionalNames}\n    {call .helloName}\n      {param name: $additionalName /}\n    {/call}\n    {if not isLast($additionalName)}\n      <br>  // break after every line except the last\n    {/if}\n  {ifempty}\n    No additional people to greet.\n  {/foreach}\n{/template}\n\n\n{/foreach}\n{if length($items) > 5}\n{msg desc=\"Says hello to the user.\"}\n\n\n{namespace ns autoescape=\"contextual\"}\n\n/** Example. */\n{template .example}\n  foo is {$ij.foo}\n{/template}"
  },
  {
    "path": "demo/kitchen-sink/docs/space.space",
    "content": "query\n count 10\n created 2011-06-21T08:10:46Z\n lang en-US\n results\n  photo\n   0\n    farm 6\n    id 5855620975\n    isfamily 0\n    isfriend 0\n    ispublic 1\n    owner 32021554@N04\n    secret f1f5e8515d\n    server 5110\n    title 7087 bandit cat\n   1\n    farm 4\n    id 5856170534\n    isfamily 0\n    isfriend 0\n    ispublic 1\n    owner 32021554@N04\n    secret ff1efb2a6f\n    server 3217\n    title 6975 rusty cat\n   2\n    farm 6\n    id 5856172972\n    isfamily 0\n    isfriend 0\n    ispublic 1\n    owner 51249875@N03\n    secret 6c6887347c\n    server 5192\n    title watermarked-cats\n   3\n    farm 6\n    id 5856168328\n    isfamily 0\n    isfriend 0\n    ispublic 1\n    owner 32021554@N04\n    secret 0c1cfdf64c\n    server 5078\n    title 7020 mandy cat\n   4\n    farm 3\n    id 5856171774\n    isfamily 0\n    isfriend 0\n    ispublic 1\n    owner 32021554@N04\n    secret 7f5a3180ab\n    server 2696\n    title 7448 bobby cat\n"
  },
  {
    "path": "demo/kitchen-sink/docs/sparql.rq",
    "content": "PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>\nPREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n\n# 1. Directors of movies starring Brad Pitt\n# Datasource: http://fragments.dbpedia.org/*/en\nSELECT ?movie ?title ?name\nWHERE {\n  ?movie dbpedia-owl:starring [ rdfs:label \"Brad Pitt\"@en ];\n         rdfs:label ?title;\n         dbpedia-owl:director [ rdfs:label ?name ].\n  FILTER LANGMATCHES(LANG(?title), \"EN\")\n  FILTER LANGMATCHES(LANG(?name),  \"EN\")\n}\n"
  },
  {
    "path": "demo/kitchen-sink/docs/sql.sql",
    "content": "SELECT city, COUNT(id) AS users_count\nFROM users\nWHERE group_name = 'salesman'\nAND created > '2011-05-21'\nGROUP BY 1\nORDER BY 2 DESC"
  },
  {
    "path": "demo/kitchen-sink/docs/sqlserver.sqlserver",
    "content": "-- =============================================\n-- Author:\t\tMorgan Yarbrough\n-- Create date: 4/27/2015\n-- Description:\tTest procedure that shows off language features.\n-- \t\t\t\tIncludes non-standard folding with region comments using either\n-- \t\t\t\tline comments or block comments (both are demonstrated below).\n--\t\t\t\tThis mode imitates SSMS and it designed to be used with SQL Server theme.\n-- =============================================\nCREATE PROCEDURE dbo.TestProcedure\n\t\n--#region parameters\n\t@vint INT = 1\n\t,@vdate DATE = NULL\n\t,@vdatetime DATETIME = DATEADD(dd, 1, GETDATE())\n\t,@vvarchar VARCHAR(MAX) = ''\n--#endregion\n\nAS\nBEGIN\n\n\t/*#region set statements */\n\tSET NOCOUNT ON;\n\tSET XACT_ABORT ON;\n\tSET QUOTED_IDENTIFIER ON;\n\t/*#endregion*/\n\t\n\t/**\n\t * These comments will produce a fold widget\n\t */\n\t\n\t-- folding demonstration\n\tSET @vint = CASE\n\t\t\t\t\tWHEN @vdate IS NULL\n\t\t\t\t\t\tTHEN 1\n\t\t\t\t\tELSE 2\n\t\t\t\tEND\n\t\n\t-- another folding demonstration\n\tIF @vint = 1 \n\tBEGIN\n\t\tSET @vvarchar = 'one'\n\t\tSET @vint = DATEDIFF(dd, @vdate, @vdatetime)\n\tEND\n\t\n\t-- this mode handles strings properly\n\tDECLARE @sql NVARCHAR(4000) = N'SELECT TOP(1) OrderID \n\t\t\t\t\t\t\t\t\tFROM Orders\n\t\t\t\t\t\t\t\t\tWHERE @OrderDate > GETDATE()'\n\t\t\t\t\t\t\t\t\n\t-- this mode is aware of built in stored procedures \n\tEXECUTE sp_executesql @sql\n\t\n\t-- demonstrating some syntax highlighting\n\tSELECT Orders.OrderID\n\t\t,Customers.CompanyName\n\t\t,DATEFROMPARTS(YEAR(GETDATE()), 1, 1) AS FirstDayOfYear\n\tFROM Orders\n\tINNER JOIN Customers\n\t\tON Orders.CustomerID = Customers.CustomerID\n\tWHERE CompanyName NOT LIKE '%something'\n\t\tOR CompanyName IS NULL\n\t\tOR CompanyName IN ('bla', 'nothing')\n\t\t\n\t-- this mode includes snippets\n\t-- place your cusor at the end of the line below and trigger auto complete (Ctrl+Space)\n\tcreatepr\n\t\n\t-- SQL Server allows using keywords as object names (not recommended) as long as they are wrapped in brackets\n\tDATABASE -- keyword\n\t[DATABASE] -- not a keyword\n\t\nEND\n"
  },
  {
    "path": "demo/kitchen-sink/docs/stylus.styl",
    "content": "// I'm a comment!\n\n/*\n * Adds the given numbers together.\n */\n\n\n/*!\n * Adds the given numbers together.\n */\n\n\nasdasdasdad(df, ad=23)\n\nadd(a, b = a)\n   a + b\ngreen(#0c0)\n add(10, 5)\n // => 15\n\n add(10)\n add(a, b)\n\n    &asdasd\n\n    (arguments)\n\n    @sdfsdf\n.signatures\n  background-color #e0e8e0\n  border 1px solid grayLighter\n  box-shadow 0 0 3px grayLightest\n  border-radius 3px\n  padding 3px 5px\n  \"adsads\"\n  margin-left 0\n  list-style none\n.signature\n  list-style none\n  display: inline\n  margin-left 0\n  > li\n    display inline\nis not\n.signature-values\n  list-style none\n  display inline\n  margin-left 0\n  &:before\n    content '→'\n    margin 0 5px\n  > li\n  !important\n\n  unless"
  },
  {
    "path": "demo/kitchen-sink/docs/swift.swift",
    "content": "import UIKit\n \nclass DetailsViewController: UIViewController {\n    var album: Album?\n    @IBOutlet weak var albumCover: UIImageView!\n     \n    required init(coder aDecoder: NSCoder) {\n        super.init(coder: aDecoder)\n    }\n     \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        mLabel.text = self.album?.title && \"Juhu \\( \"kinners\" )! \"\n        albumCover.image = UIImage(data: NSData(contentsOfURL: NSURL(string: self.album!.largeImageURL)!)!)\n    }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/tcl.tcl",
    "content": "\nproc dijkstra {graph origin} {\n    # Initialize\n    dict for {vertex distmap} $graph {\n\tdict set dist $vertex Inf\n\tdict set path $vertex {}\n    }\n    dict set dist $origin 0\n    dict set path $origin [list $origin]\n \n    while {[dict size $graph]} {\n\t# Find unhandled node with least weight\n\tset d Inf\n\tdict for {uu -} $graph {\n\t    if {$d > [set dd [dict get $dist $uu]]} {\n\t\tset u $uu\n\t\tset d $dd\n\t    }\n\t}\n \n\t# No such node; graph must be disconnected\n\tif {$d == Inf} break\n \n\t# Update the weights for nodes\\\n\t lead to by the node we've picked\n\tdict for {v dd} [dict get $graph $u] {\n\t    if {[dict exists $graph $v]} {\n\t\tset alt [expr {$d + $dd}]\n\t\tif {$alt < [dict get $dist $v]} {\n\t\t    dict set dist $v $alt\n\t\t    dict set path $v [list {*}[dict get $path $u] $v]\n\t\t}\n\t    }\n\t}\n \n\t# Remove chosen node from graph still to be handled\n\tdict unset graph $u\n    }\n    return [list $dist $path]\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/terraform.tf",
    "content": "export TF_LOG=TRACE\n\n# An AMI\nvariable \"ami\" {\n  description = \"the AMI to use\"\n}\n\n/* A multi\n   line comment. */\nresource \"aws_instance\" \"web\" {\n  ami               = \"${var.ami}\"\n  count             = 2\n  source_dest_check = false\n\n  connection {\n    user = \"root\"\n  }\n}\n\nresource \"aws_instance\" \"web\" {\n  subnet = \"${var.env == \"production\" ? var.prod_subnet : var.dev_subnet}\"\n}\n\nvariable \"count\" {\n  default = 2\n}\n\nvariable \"hostnames\" {\n  default = {\n    \"0\" = \"example1.org\"\n    \"1\" = \"example2.net\"\n  }\n}\n\ndata \"template_file\" \"web_init\" {\n  # Render the template once for each instance\n  count    = \"${length(var.hostnames)}\"\n  template = \"${file(\"templates/web_init.tpl\")}\"\n  vars {\n    # count.index tells us the index of the instance we are rendering\n    hostname = \"${var.hostnames[count.index]}\"\n  }\n}\n\nresource \"aws_instance\" \"web\" {\n  # Create one instance for each hostname\n  count     = \"${length(var.hostnames)}\"\n\n  # Pass each instance its corresponding template_file\n  user_data = \"${data.template_file.web_init.*.rendered[count.index]}\"\n}\n\nvariable \"count\" {\n  default = 2\n}\n\n# Define the common tags for all resources\nlocals {\n  common_tags = {\n    Component   = \"awesome-app\"\n    Environment = \"production\"\n  }\n}\n\n# Create a resource that blends the common tags with instance-specific tags.\nresource \"aws_instance\" \"server\" {\n  ami           = \"ami-123456\"\n  instance_type = \"t2.micro\"\n\n  tags = \"${merge(\n    local.common_tags,\n    map(\n      \"Name\", \"awesome-app-server\",\n      \"Role\", \"server\"\n    )\n  )}\"\n}\n\n$ terraform apply -var foo=bar -var foo=baz\n$ terraform apply -var 'foo={quux=\"bar\"}' -var 'foo={bar=\"baz\"}'\n\n$ terraform apply -var-file=foo.tfvars -var-file=bar.tfvars\n$ TF_VAR_somemap='{foo = \"bar\", baz = \"qux\"}' terraform plan\n\nresource \"aws_instance\" \"web\" {\n  # ...\n\n  count = \"${var.count}\"\n\n  # Tag the instance with a counter starting at 1, ie. web-001\n  tags {\n    Name = \"${format(\"web-%03d\", count.index + 1)}\"\n  }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/tex.tex",
    "content": "The quadratic formula is $$-b \\pm \\sqrt{b^2 - 4ac} \\over 2a$$\n\\bye\n\n\\makeatletter\n \\newcommand{\\be}{%\n \\begingroup\n % \\setlength{\\arraycolsep}{2pt}\n \\eqnarray%\n \\@ifstar{\\nonumber}{}%\n  }\n  \\newcommand{\\ee}{\\endeqnarray\\endgroup}\n  \\makeatother\n\n \\begin{equation}\n x=\\left\\{ \\begin{array}{cl}\n 0 & \\textrm{if }A=\\ldots\\\\\n 1 & \\textrm{if }B=\\ldots\\\\\n x & \\textrm{this runs with as much text as you like, but without an raggeright text\n.}\\end{array}\\right.\n \\end{equation}"
  },
  {
    "path": "demo/kitchen-sink/docs/text.txt",
    "content": "This is just some text!\n\n//   These\n  #    are\n    --   not\n      <!-- comments -->\n        (but indent actions work)\n\nThis is just some text!\n"
  },
  {
    "path": "demo/kitchen-sink/docs/textile.textile",
    "content": "h1. Textile document\n\nh2. Heading Two\n\nh3. A two-line\n    header\n\nh2. Another two-line\nheader\n\nParagraph:\none, two,\nthee lines!\n\np(classone two three). This is a paragraph with classes\n\np(#id). (one with an id)\n\np(one two three#my_id). ..classes + id\n\n* Unordered list\n** sublist\n* back again!\n** sublist again..\n\n# ordered\n\nbg. Blockquote!\n    This is a two-list blockquote..!"
  },
  {
    "path": "demo/kitchen-sink/docs/toml.toml",
    "content": "# This is a TOML document. Boom.\n\ntitle = \"TOML Example\"\n\n[owner]\nname = \"Tom Preston-Werner\"\norganization = \"GitHub\"\nbio = \"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"\ndob = 1979-05-27T07:32:00Z # First class dates? Why not?\n\n[database]\nserver = \"192.168.1.1\"\nports = [ 8001, 8001, 8002 ]\nconnection_max = 5000\nenabled = true\n\n[servers]\n\n  # You can indent as you please. Tabs or spaces. TOML don't care.\n  [servers.alpha]\n  ip = \"10.0.0.1\"\n  dc = \"eqdc10\"\n\n  [servers.beta]\n  ip = \"10.0.0.2\"\n  dc = \"eqdc10\"\n\n[clients]\ndata = [ [\"gamma\", \"delta\"], [1, 2] ] # just an update to make sure parsers support it"
  },
  {
    "path": "demo/kitchen-sink/docs/tsv.tsv",
    "content": "col1\tcol2 long\tcol3\tcol4\t\n\"col1\twith quotes\"\tcol2\tcol3\tcol4\t\ncol1\tcol2\tcol\"\"\"3\tco\"\"l4\t\ncol1\tcol2\tcol3\"broken\"\tcol4\t\ncol1\"\t-\"col2\tcol3\tcol4\tcol5\ncol1\t\"col2\nmultiline\"\t\"col3\nmultiline\"\"string\n3\"\t\"col4\nmultiline string\n\n4\"\ncol1\tcol2\t\"c\to\tl\"\"3\"\tcol4\tcol5\tcol6\tcol7\tcol8\tcol9\tcol10\tcol11\tcol12\tcol13\ncol1\tcol2\tcol3\tcol4\tcol5\tcol6\tcol7\tcol8\tcol9\tcol10\tcol11\tcol12\tcol13\ncol1\tcol2\tcol3\tcol4\tcol5\tcol6\tco\"l7\tcol8\tcol9\tcol10\t11\tcol12\tcol13\n"
  },
  {
    "path": "demo/kitchen-sink/docs/tsx.tsx",
    "content": "var mode = <div> \n    Typescript + <b> JSX </b> \n</div>;"
  },
  {
    "path": "demo/kitchen-sink/docs/turtle.ttl",
    "content": "@base <http://example.org/> .\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n@prefix rel: <http://www.perceive.net/schemas/relationship/> .\n\n<#green-goblin>\n    rel:enemyOf <#spiderman> ;\n    a foaf:Person ;    # in the context of the Marvel universe\n    foaf:name \"Green Goblin\" .\n\n<#spiderman>\n    rel:enemyOf <#green-goblin> ;\n    a foaf:Person ;\n    foaf:name \"Spiderman\", \"Человек-паук\"@ru ."
  },
  {
    "path": "demo/kitchen-sink/docs/twig.twig",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>My Webpage</title>\n    </head>\n    <body>\n        <ul id=\"navigation\">\n        {% for item in navigation %}\n            <li><a href=\"{{ item.href|escape }}\">{{ item.caption }}</a></li>\n        {% endfor %}\n        </ul>\n\n        {% if 1 not in [1, 2, 3] %}\n\n        {# is equivalent to #}\n        {% if not (1 in [1, 2, 3]) %}\n\n        {% autoescape true %}\n            {{ var }}\n            {{ var|raw }}     {# var won't be escaped #}\n            {{ var|escape }}  {# var won't be doubled-escaped #}\n        {% endautoescape %}\n\n        {{ include('twig.html', sandboxed = true) }}\n\n        {{\"string #{with} \\\" escapes\" 'another#one' }}\n        <h1>My Webpage</h1>\n        {{ a_variable }}\n    </body>\n</html>"
  },
  {
    "path": "demo/kitchen-sink/docs/typescript.ts",
    "content": "class Greeter {\n\tgreeting: string;\n\tconstructor (message: string) {\n\t\tthis.greeting = message;\n\t}\n\tgreet() {\n\t\treturn \"Hello, \" + this.greeting;\n\t}\n}   \n\nvar greeter = new Greeter(\"world\");\n\nvar button = document.createElement('button')\nbutton.innerText = <string>\"Say Hello\";\nbutton.onclick = function() {\n\talert(greeter.greet())\n}\n\ndocument.body.appendChild(button)\n\nclass Snake extends Animal {\n   move() {\n       alert(\"Slithering...\");\n       super(5);\n   }\n}\n\nclass Horse extends Animal {\n   move() {\n       alert(\"Galloping...\");\n       super.move(45);\n   }\n}\n\nmodule Sayings {\n    export class Greeter {\n        greeting: string;\n        constructor (message: string) {\n            this.greeting = message;\n        }\n        greet() {\n            return \"Hello, \" + this.greeting;\n        }\n    }\n}\nmodule Mankala {\n   export class Features {\n       public turnContinues = false;\n       public seedStoredCount = 0;\n       public capturedCount = 0;\n       public spaceCaptured = NoSpace;\n\n       public clear() {\n           this.turnContinues = false;\n           this.seedStoredCount = 0;\n           this.capturedCount = 0;\n           this.spaceCaptured = NoSpace;\n       }\n\n       public toString() {\n           var stringBuilder = \"\";\n           if (this.turnContinues) {\n               stringBuilder += \" turn continues,\";\n           }\n           stringBuilder += \" stores \" + this.seedStoredCount;\n           if (this.capturedCount > 0) {\n               stringBuilder += \" captures \" + this.capturedCount + \" from space \" + this.spaceCaptured;\n           }\n           return stringBuilder;\n       }\n   }\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/vala.vala",
    "content": "﻿using Gtk;\n \nint main (string[] args) {\n    Gtk.init (ref args);\n    var foo = new MyFoo<string[](), MyBar<string, int>>();\n\n    var window = new Window();\n    window.title = \"Hello, World!\";\n    window.border_width = 10;\n    window.window_position = WindowPosition.CENTER;\n    window.set_default_size(350, 70);\n    window.destroy.connect(Gtk.main_quit);\n \n    var label = new Label(\"Hello, World!\");\n \n    window.add(label);\n    window.show_all();\n \n    Gtk.main();\n    return 0;\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/vbscript.vbs",
    "content": "myfilename = \"C:\\Wikipedia - VBScript - Example - Hello World.txt\"\nMakeHelloWorldFile myfilename\n \nSub MakeHelloWorldFile (FileName)\n   'Create a new file in C: drive or overwrite existing file\n   Set FSO = CreateObject(\"Scripting.FileSystemObject\")\n   If FSO.FileExists(FileName) Then \n      Answer = MsgBox (\"File \" & FileName & \" exists ... OK to overwrite?\", vbOKCancel)\n      'If button selected is not OK, then quit now\n      'vbOK is a language constant\n      If Answer <> vbOK Then Exit Sub\n   Else\n      'Confirm OK to create\n      Answer = MsgBox (\"File \" & FileName & \" ... OK to create?\", vbOKCancel)\n      If Answer <> vbOK Then Exit Sub\n   End If\n   'Create new file (or replace an existing file)\n   Set FileObject = FSO.CreateTextFile (FileName)\n   FileObject.WriteLine \"Time ... \" & Now()\n   FileObject.WriteLine \"Hello World\"\n   FileObject.Close()\n   MsgBox \"File \" & FileName & \" ... updated.\"\nEnd Sub"
  },
  {
    "path": "demo/kitchen-sink/docs/velocity.vm",
    "content": "#*\n  This is a sample comment block that\n  spans multiple lines.\n*#\n\n#macro ( outputItem $item )\n  <li>${item}</li>\n#end\n\n## Define the items to iterate\n#set ( $items = [1, 2, 3, 4] )\n\n<ul>\n  ## Iterate over the items and output the evens.\n  #foreach ( $item in $items )\n    #if ( $_MathTool.mod($item, 2) == 0 )\n      #outputItem ($item)\n    #end\n  #end\n</ul>\n\n<script>\n  /*\n    A sample function to decomstrate\n    JavaScript highlighting and folding.\n  */\n  function foo(items, nada) {\n    for (var i=0; i<items.length; i++) {\n      alert(items[i] + \"juhu\\n\");\n    }\n  }\n</script>\n\n<style>\n  /*\n    A sample style to decomstrate\n    CSS highlighting and folding.\n  */\n  .class {\n    font-family: Monaco, \"Courier New\", monospace;\n    font-size: 12px;\n    cursor: text;\n  }\n</style>"
  },
  {
    "path": "demo/kitchen-sink/docs/verilog.v",
    "content": "always @(negedge reset or posedge clk) begin\n  if (reset == 0) begin\n    d_out <= 16'h0000;\n    d_out_mem[resetcount] <= d_out;\n    laststoredvalue <= d_out;\n  end else begin\n    d_out <= d_out + 1'b1; \n  end\nend\n\nalways @(bufreadaddr)\n  bufreadval = d_out_mem[bufreadaddr];"
  },
  {
    "path": "demo/kitchen-sink/docs/vhdl.vhd",
    "content": "library IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity COUNT16 is\n\n    port (\n        cOut    :out    std_logic_vector(15 downto 0);  -- counter output\n        clkEn   :in     std_logic;                      -- count enable\n        clk     :in     std_logic;                      -- clock input\n        rst     :in     std_logic                       -- reset input\n        );\n        \nend entity;\n\narchitecture count_rtl of COUNT16 is\n    signal count : unsigned (15 downto 0);\n    \nbegin\n    process (clk, rst) begin\n        \n        if(rst = '1') then\n            count <= (others=>'0');\n        elsif(rising_edge(clk)) then\n            if(clkEn = '1') then\n                count <= count + 1;\n            end if;\n        end if;\n        \n    end process;\n    cOut <= std_logic_vector(count);\n\nend architecture;\n\n"
  },
  {
    "path": "demo/kitchen-sink/docs/visualforce.vfp",
    "content": "<apex:stylesheet value=\"{!URLFOR($Resource.BrowserCompatibility, 'css/style.css')}\"/>\n\n<apex:page action=\"{!IF($User.Alias = 'JohnDoe' || $User.Alias = 'JBloggs' || $User.Alias = 'FooBar',\n    null,\n    urlFor($Action.Account.Delete, $CurrentPage.Parameters.id, [retURL='/001'], true)\n)}\" standardController=\"Account\"></apex:page>\n\n<apex:page action=\"{!IF(OR($User.Alias = 'JohnDoe', $User.Alias = 'JBloggs', $User.Alias = 'FooBar'),\n    NULL,\n    URLFOR($Action.Account.Delete, $CurrentPage.Parameters.id, [retURL='/001'], TRUE)\n)}\" standardController=\"Account\"></apex:page>\n\n<apex:commandLink action=\"{!URLFOR('/apex/' + $CurrentPage.Name, null, ['id'=id])}\" \n                   value=\"Full List\" />\n<ideas:listOutputLink stickyAttributes=\"false\">\n    \n</ideas:listOutputLink>\n{!IF(AND(Price < 1, Quantity < 1), \"Small\", null)}"
  },
  {
    "path": "demo/kitchen-sink/docs/vue.vue",
    "content": "<!--\nThings to verify:\n- comments (this block) are properly highlighted\n- expressions are highlighted as JS\n- <script> highlights ES2015 syntax\n- <style> highlights as CSS\n-->\n\n<template>\n  <div>\n    {{ foo * 10 + 'hi' }}\n    <span\n        v-text=\"foo * 10 + 'hi'\" :id=\"foo + 'baz'\"\n        @click=\"onClick('hello')\"\n        @click.prevent=\"onClick('hello')\">\n      Hello\n    </span>\n    <router-link v-bind:to=\"item.url\"/>\n    <!-- v-bind with dynamic key -->\n    <div v-bind:[key]=\"value\"></div>\n\n    <!-- v-bind shorthand with dynamic key -->\n    <div :[key]=\"value\"></div>\n\n    <!-- v-on with dynamic event -->\n    <div v-on:[event]=\"handler\"></div>\n\n    <!-- v-on shorthand with dynamic event -->\n    <div @[event]=\"handler\"></div>\n  </div>\n</template>\n\n<script>\nexport default {\n  data: () => ({\n    foo: 'bar'\n  })\n};\n</script>\n\n<style>\ndiv {\n  color: red;\n}\n</style>\n\n<style lang=\"sass\">\n// sass ace mode;\n\n@import url(http://fonts.googleapis.com/css?family=Ace:700)\n\nhtml, body\n  :background-color #ace\n  text-align: center\n  height: 100%\n  /*;*********;\n    ;comment  ;\n    ;*********;\n\n\n  &:before\n    $radius: $size * 0.845\n    $glow: $size * 0.125\n\n    box-shadow: 0 0 $glow $glow / 2 #fff\n    border-radius: $radius\n\n    &:active\n      ~ .button\n        box-shadow: 0 15px 25px -4px rgba(0, 0, 0, 0.4)\n\n      ~ .label\n        font-size: 40px\n        color: rgba(0, 0, 0, 0.45)\n\n    &:checked\n      ~ .button\n        box-shadow: 0 15px 25px -4px #ace\n\n      ~ .label\n        font-size: 40px\n        color: #c9c9c9\n</style>\n\n<style lang=\"scss\">\n/* style.scss */\n\n#navbar {\n  $navbar-width: 800px;\n  $items: 5;\n  $navbar-color: #ce4dd6;\n\n  width: $navbar-width;\n  border-bottom: 2px solid $navbar-color;\n\n  li {\n    float: left;\n    width: $navbar-width/$items - 10px;\n\n    background-color: lighten($navbar-color, 20%);\n\n    &:hover {\n      background-color: lighten($navbar-color, 10%);\n    }\n  }\n}\n\n</style>\n\n<template lang=\"jade\">\n  mixin article(obj, parents)\n    -var x = \"0\";\n\n  - var items = [\"one\", \"two\", \"three\"]\n  each item in items\n    li= item\n</template>\n\n<template v-slot:item.parentkey.subkey.subkey.subkey.subkey.subkey=\"{ value }\"></template>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/wollok.wlk",
    "content": "class Actividad {\n\tmethod calcularMejora()\n}\n\nclass EstudiarMateria inherits Actividad {\n\tvar materia\n\tvar puntos = 0\n\t\n\tnew(m, p) {\n\t\tmateria = m\n\t\tpuntos = p\n\t}\n\t\n\toverride method calcularMejora() = puntos\n}\n\nclass EjercitarEnSimulador inherits Actividad {\n\tvar horas = 0\n\tnew(h) { horas = h }\n\toverride method calcularMejora() = 10 * horas\n}\n\nobject pepita {\n\tvar energia = 100\n\tmethod volar(m) {\n\t\tenergia -= m\n\t}\n}"
  },
  {
    "path": "demo/kitchen-sink/docs/xml.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<query xmlns:yahoo=\"http://www.yahooapis.com/v1/base.rng\"\n    yahoo:count=\"7\" yahoo:created=\"2011-10-11T08:40:23Z\" yahoo:lang=\"en-US\">\n    <diagnostics>\n        <publiclyCallable>true</publiclyCallable>\n        <url execution-start-time=\"0\" execution-stop-time=\"25\" execution-time=\"25\"><![CDATA[http://where.yahooapis.com/v1/continents;start=0;count=10]]></url>\n        <user-time>26</user-time>\n        <service-time>25</service-time>\n        <build-version>21978</build-version>\n    </diagnostics> \n    <results>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/24865670\">\n            <woeid>24865670</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>Africa</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/24865675\">\n            <woeid>24865675</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>Europe</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/24865673\">\n            <woeid>24865673</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>South America</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/28289421\">\n            <woeid>28289421</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>Antarctic</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/24865671\">\n            <woeid>24865671</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>Asia</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/24865672\">\n            <woeid>24865672</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>North America</name>\n        </place>\n        <place xmlns=\"http://where.yahooapis.com/v1/schema.rng\"\n            xml:lang=\"en-US\" yahoo:uri=\"http://where.yahooapis.com/v1/place/55949070\">\n            <woeid>55949070</woeid>\n            <placeTypeName code=\"29\">Continent</placeTypeName>\n            <name>Australia</name>\n        </place>\n    </results>\n</query>"
  },
  {
    "path": "demo/kitchen-sink/docs/xquery.xq",
    "content": "xquery version \"1.0\";\n\nlet $message := \"Hello World!\"\nreturn <results>\n  <message>{$message}</message>\n</results>\n"
  },
  {
    "path": "demo/kitchen-sink/docs/yaml.yaml",
    "content": "# This sample document was taken from wikipedia:\n# http://en.wikipedia.org/wiki/YAML#Sample_document\n---\nreceipt:     Oz-Ware Purchase Invoice\ndate:        2007-08-06\ncustomer:\n    given:   Dorothy\n    family:  Gale\n\nitems:\n    - part_no:   'A4786'\n      descrip:   Water Bucket (Filled)\n      price:     1.47\n      quantity:  4\n\n    - part_no:   'E1628'\n      descrip:   High Heeled \"Ruby\" Slippers\n      size:      8\n      price:     100.27\n      quantity:  1\n      version:   1.2.3.4\n\nbill-to:  &id001\n    street: |\n            123 Tornado Alley\n            Suite 16\n    city:   East Centerville\n    state:  KS\n\nship-to:  *id001\n\nspecialDelivery:  >\n    Follow the Yellow Brick\n    Road to the Emerald City.\n    Pay no attention to the\n    man behind the curtain.\n"
  },
  {
    "path": "demo/kitchen-sink/docs/zeek.zeek",
    "content": "# An example of the Zeek scripting language.\n\n##! A Zeekygen-style summmary comment.\n\n# TODO: just an example of a todo-indicator\n\n@load base/frameworks/notice\n\n@if ( F )\n@endif\n\nmodule Example;\n\nexport {\n\n  type SimpleEnum: enum { ONE, TWO, THREE };\n\n  redef enum SimpleEnum += {\n\n    ## A Zeekygen-style comment.\n    FOUR,\n    FIVE, ##< A Zeekygen-style comment.\n  };\n\n  type SimpleRecord: record {\n    field1: count;\n    field2: bool;\n  } &redef;\n\n  redef record SimpleRecord += {\n\n    field3: string &optional;\n\n    field4: string &default=\"blah\";\n  };\n\n  const init_option: bool = T;\n\n  option runtime_option: bool = F;\n\n  global test_opaque: opaque of md5;\n\n  global test_vector: vector of count;\n\n  global myfunction: function(msg: string, c: count &default=0): count;\n\n  global myhook: hook(tag: string);\n\n  global myevent: event(tag: string);\n}\n\nfunction myfunction(msg: string, c: count): count\n  {\n  print \"in myfunction\", msg, c;\n  return 0;\n  }\n\nevent myevent(msg: string) &priority=1\n  {\n  print \"in myevent\";\n  }\n\nhook myhook(msg: string)\n  {\n  print \"in myevent\";\n  }\n\nevent zeek_init()\n  {\n  local b = T;\n  local s = \"\\xff\\xaf\\\"and more after the escaped quote\";\n  local p = /foo|bar\\xbe\\/and more after the escaped slash/;\n  local c = 10;\n\n  local sr = SimpleRecord($field1 = 0, $field2 = T, $field3 = \"hi\");\n\n  print sr?$field3, sr$field1;\n\n  local myset: set[string] = set(\"one\", \"two\", \"three\");\n\n  add myset[\"four\"];\n  delete myset[\"one\"];\n\n  for ( ms in myset )\n    {\n    print ms is string, s as string;\n\n    print s[1:3];\n\n    local tern: count = s == \"two\" ? 2 : 0;\n\n    if ( s !in myset )\n       print fmt(\"error %4.2f: %s\", 3.14159, \"wtf?\");\n    }\n\n  switch ( c ) {\n  case 1:\n    break;\n  case 2:\n    fallthrough;\n  default:\n    break;\n  }\n\n  if ( ! b )\n    print \"here\";\n  else\n    print \"there\";\n\n  while ( c != 0 )\n    {\n    if ( c >= 5 )\n      c += 0;\n    else if ( c == 8 )\n      c -= 0;\n\n    c = c / 1;\n    c = c / 1;\n    c = c - 1;\n    }\n\n  print |myset|;\n  print ~5;\n  print 1 & 0xff;\n  print 2 ^ 5;\n\n  myfunction(\"hello function\");\n  hook myhook(\"hell hook\");\n  event myevent(\"hello event\");\n  schedule 1sec { myevent(\"hello scheduled event\") };\n\n  print 0, 7;\n  print 0xff, 0xdeadbeef;\n\n  print 3.14159;\n  print 1234.0;\n  print 1234e0;\n  print .003E-23;\n  print .003E+23;\n\n  print 123/udp;\n  print 8000/tcp;\n  print 13/icmp;\n  print 42/unknown;\n\n  print google.com;\n  print 192.168.50.1;\n  print 255.255.255.255;\n  print 0.0.0.0;\n\n  print 10.0.0.0/16;\n\n  print [2001:0db8:85a3:0000:0000:8a2e:0370:7334];\n  # test for case insensitivity\n  print [2001:0DB8:85A3:0000:0000:8A2E:0370:7334];\n  # any case mixture is allowed\n  print [2001:0dB8:85a3:0000:0000:8A2E:0370:7334];\n  # leading zeroes of a 16-bit group may be omitted\n  print [2001:db8:85a3:0:0:8a2e:370:7334];\n  # a single occurrence of consecutive groups of zeroes may be replaced by ::\n  print [2001:db8:85a3::8a2e:370:7334];\n  # all zeroes should work\n  print [0:0:0:0:0:0:0:0];\n  # all zeroes condensed should work\n  print [::];\n  # hybrid ipv6-ipv4 address should work\n  print [2001:db8:0:0:0:FFFF:192.168.0.5];\n  # hybrid ipv6-ipv4 address with zero ommission should work\n  print [2001:db8::FFFF:192.168.0.5];\n\n  print [2001:0db8:85a3:0000:0000:8a2e:0370:7334]/64;\n\n  print 1day, 1days, 1.0day, 1.0days;\n  print 1hr, 1hrs, 1.0hr, 1.0hrs;\n  print 1min, 1mins, 1.0min, 1.0mins;\n  print 1sec, 1secs, 1.0sec, 1.0secs;\n  print 1msec, 1msecs, 1.0msec, 1.0msecs;\n  print 1usec, 1usecs, 1.0usec, 1.0usecs;\n  }\n"
  },
  {
    "path": "demo/kitchen-sink/docs/zig.zig",
    "content": "const std = @import(\"std\");\n\npub fn main() !void {\n    const stdout = std.io.getStdOut().writer();\n    try stdout.print(\"Hello, {s}!\\n\", .{\"world\"});\n}"
  },
  {
    "path": "demo/kitchen-sink/file_drop.js",
    "content": "var config = require(\"ace/config\");\nvar event = require(\"ace/lib/event\");\nvar modelist = require(\"ace/ext/modelist\");\n\nmodule.exports = function(editor) {\n    event.addListener(editor.container, \"dragover\", function(e) {\n        var types = e.dataTransfer.types;\n        if (types && Array.prototype.indexOf.call(types, 'Files') !== -1)\n            return event.preventDefault(e);\n    });\n\n    event.addListener(editor.container, \"drop\", function(e) {\n        var file;\n        try {\n            file = e.dataTransfer.files[0];\n            if (window.FileReader) {\n                var reader = new FileReader();\n                reader.onload = function() {\n                    var mode = modelist.getModeForPath(file.name);\n                    editor.session.doc.setValue(reader.result);\n                    editor.session.setMode(mode.mode);\n                    editor.session.modeName = mode.name;\n                };\n                reader.readAsText(file);\n            }\n            return event.preventDefault(e);\n        } catch(err) {\n            return event.stopEvent(e);\n        }\n    });\n};\n\nvar Editor = require(\"ace/editor\").Editor;\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    loadDroppedFile: {\n        set: function() { module.exports(this); },\n        value: true\n    }\n});\n"
  },
  {
    "path": "demo/kitchen-sink/inline_editor.js",
    "content": "\"use strict\";\n\nvar LineWidgets = require(\"ace/line_widgets\").LineWidgets;\nvar Editor = require(\"ace/editor\").Editor;\nvar Renderer = require(\"ace/virtual_renderer\").VirtualRenderer;\nvar dom = require(\"ace/lib/dom\");\n\n\nrequire(\"ace/commands/default_commands\").commands.push({\n    name: \"openInlineEditor\",\n    bindKey: \"F3\",\n    exec: function(editor) {\n        var split = window.env.split;\n        var s = editor.session;\n        var inlineEditor = new Editor(new Renderer());\n        var splitSession = split.$cloneSession(s);\n\n        var row = editor.getCursorPosition().row;\n        if (editor.session.lineWidgets && editor.session.lineWidgets[row]) {\n            editor.session.lineWidgets[row].destroy();\n            return;\n        }\n        \n        var rowCount = 10;\n        var w = {\n            row: row, \n           // rowCount: rowCount, \n            fixedWidth: true,\n            el: dom.createElement(\"div\"),\n            editor: inlineEditor\n        };\n        var el = w.el;\n        el.appendChild(inlineEditor.container);\n\n        if (!editor.session.widgetManager) {\n            editor.session.widgetManager = new LineWidgets(editor.session);\n            editor.session.widgetManager.attach(editor);\n        }\n        \n        var h = rowCount*editor.renderer.layerConfig.lineHeight;\n        inlineEditor.container.style.height = h + \"px\";\n\n        el.style.position = \"absolute\";\n        el.style.zIndex = \"4\";\n        el.style.borderTop = \"solid blue 2px\";\n        el.style.borderBottom = \"solid blue 2px\";\n        \n        inlineEditor.setSession(splitSession);\n        editor.session.widgetManager.addLineWidget(w);\n        \n        var kb = {\n            handleKeyboard:function(_,hashId, keyString) {\n                if (hashId === 0 && keyString === \"esc\") {\n                    w.destroy();\n                    return true;\n                }\n            }\n        };\n        \n        w.destroy = function() {\n            editor.keyBinding.removeKeyboardHandler(kb);\n            s.widgetManager.removeLineWidget(w);\n        };\n        \n        editor.keyBinding.addKeyboardHandler(kb);\n        inlineEditor.keyBinding.addKeyboardHandler(kb);\n        inlineEditor.setTheme(\"ace/theme/solarized_light\");\n    }\n});\n"
  },
  {
    "path": "demo/kitchen-sink/layout.js",
    "content": "\"use strict\";\n\nvar dom = require(\"ace/lib/dom\");\nvar event = require(\"ace/lib/event\");\n\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\nvar Renderer = require(\"ace/virtual_renderer\").VirtualRenderer;\nvar Editor = require(\"ace/editor\").Editor;\nvar MultiSelect = require(\"ace/multi_select\").MultiSelect;\n\ndom.importCssString(\"\\\nsplitter {\\\n    border: 1px solid #C6C6D2;\\\n    width: 0px;\\\n    cursor: ew-resize;\\\n    z-index:10}\\\nsplitter:hover {\\\n    margin-left: -2px;\\\n    width:3px;\\\n    border-color: #B5B4E0;\\\n}\\\n\", \"splitEditor\");\n\nexports.edit = function(el) {\n    if (typeof(el) == \"string\")\n        el = document.getElementById(el);\n\n    var editor = new Editor(new Renderer(el, require(\"ace/theme/textmate\")));\n\n    editor.resize();\n    event.addListener(window, \"resize\", function() {\n        editor.resize();\n    });\n    return editor;\n};\n\n\nvar SplitRoot = function(el, theme, position, getSize) {\n    el.style.position = position || \"relative\";\n    this.container = el;\n    this.getSize = getSize || this.getSize;\n    this.resize = this.$resize.bind(this);\n\n    event.addListener(el.ownerDocument.defaultView, \"resize\", this.resize);\n    this.editor = this.createEditor();\n};\n\n(function(){\n    this.createEditor = function() {\n        var el = document.createElement(\"div\");\n        el.className = this.$editorCSS;\n        el.style.cssText = \"position: absolute; top:0px; bottom:0px\";\n        this.$container.appendChild(el);\n        var session = new EditSession(\"\");\n        var editor = new Editor(new Renderer(el, this.$theme));\n\n        /*editor.on(\"focus\", function() {\n            this._emit(\"focus\", editor);\n        }.bind(this));*/\n\n        this.$editors.push(editor);\n        editor.setFontSize(this.$fontSize);\n        return editor;\n    };\n    this.$resize = function() {\n        var size = this.getSize(this.container);\n        this.rect = {\n            x: size.left,\n            y: size.top,\n            w: size.width,\n            h: size.height\n        };\n        this.item.resize(this.rect);\n    };\n    this.getSize = function(el) {\n        return el.getBoundingClientRect();\n    };\n    this.destroy = function() {\n        var win = this.container.ownerDocument.defaultView;\n        event.removeListener(win, \"resize\", this.resize);\n    };\n\n\n}).call(SplitRoot.prototype);\n\n\n\nvar Split = function(){\n\n};\n(function(){\n    this.execute = function(options) {\n        this.$u.execute(options);\n    };\n\n}).call(Split.prototype);\n\n\n\nexports.singleLineEditor = function(el) {\n    var renderer = new Renderer(el);\n    el.style.overflow = \"hidden\";\n\n    renderer.screenToTextCoordinates = function(x, y) {\n        var pos = this.pixelToScreenCoordinates(x, y);\n        return this.session.screenToDocumentPosition(\n            Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)),\n            Math.max(pos.column, 0)\n        );\n    };\n\n    renderer.$maxLines = 4;\n\n    renderer.setStyle(\"ace_one-line\");\n    var editor = new Editor(renderer);\n    editor.session.setUndoManager(new UndoManager());\n\n    editor.setShowPrintMargin(false);\n    editor.renderer.setShowGutter(false);\n    editor.renderer.setHighlightGutterLine(false);\n    editor.$mouseHandler.$focusWaitTimout = 0;\n\n    return editor;\n};\n"
  },
  {
    "path": "demo/kitchen-sink/require.js",
    "content": "/* eslint-env browser */\n/* global importScripts Response Request */\n\n/**\n * requirejs compatible loader for cloud9\n *\n * supports the following loaders\n *     require(\"text!./path.md\")  - load a file as text\n *     require(\"json!./file.json\")  - load a file as json\n *     require(\"asset-url!./directory-or-a-file\")  - get a url for a image, html or audio file or\n *          a whole directory, files required this way are copied to the cdn without modifications\n *     require(\"webworker!./modulname\")  - get a url that can be used to start a webworker\n *     require(\"webworker!<tagname>!./modulname\")  - get a url for webworker, and include all the\n *          instances of require(\"<tagname>!./modulname\") in a bundle for that worker\n *     require(\"language!./modulname\")  - the commonly used tagname for language worker\n *     require(\"vfs!./module\") - bundles js file with it's dependencies in a way that can be used\n *          on vfs worker, either as a vfs extension or a standalone executable\n *     require(\"architect!./modulname\") - wraps module in a function allowing\n *          delayed initialization of architect plugins\n *     TODO:\n *     require(\"glob!./ace/mode/*(:-_test|_highlight_rules).js\").load(\"css\", function() {}) -\n *     require(\"lazy!./module\").load(function() {}) -\n */\n(function() {\n    var global = (function() {\n        return this;\n    })();\n    if (!global && typeof window != \"undefined\") global = window; // can happen in strict mode\n    if (!global && typeof self != \"undefined\") global = self; // can happen in webworker\n\n    var commentRegExp = /(\\/\\*([\\s\\S]*?)\\*\\/|([^:]|^)\\/\\/(.*)$|`([^`\\\\]|\\\\.)*`)/gm;\n    var cjsRequireRegExp = /require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g;\n\n    function getInlineDeps(fn) {\n        var deps = [];\n        if (fn.length) {\n            fn\n                .toString()\n                .replace(commentRegExp, \"\")\n                .replace(cjsRequireRegExp, function(match, dep, index, str) {\n                    var i = index;\n                    while (str.charCodeAt((i -= 1)) <= 32) {}\n                    if (str.charAt(i) !== \".\") deps.push(dep);\n                });\n            deps = [\"require\", \"exports\", \"module\"].concat(deps);\n        }\n        return deps;\n    }\n\n    var define = function(name, deps, callback) {\n        // Allow for anonymous modules\n        if (typeof name !== \"string\") {\n            callback = deps;\n            deps = name;\n            name = null;\n        }\n        // This module may not have dependencies\n        if (deps && !Array.isArray(deps)) {\n            callback = deps;\n            deps = null;\n        }\n\n        if (nextModule) {\n            if (!name || name == nextModule.name) {\n                name = nextModule.name;\n                deps = deps || nextModule.deps;\n                nextModule = null;\n            }\n        }\n\n        if (!name) return defQueue.push([deps, callback]);\n\n        if (define.loaded[name]) return;\n\n        if (!deps && typeof callback == \"function\") deps = getInlineDeps(callback);\n\n        define.loaded[name] = {\n            id: name,\n            deps: normalizeNames(name, deps || []),\n            factory: callback,\n            exports: {},\n            packaged: true,\n        };\n        if (define.loading[name]) delete define.loading[name];\n        if (define.lastModule) define.pending.push(name);\n        else define.lastModule = name;\n    };\n    var defQueue = [];\n    var nextModule;\n    var addToLoadQueue = function(missing, deps, callback, errback) {\n        var toLoad = missing.length;\n        var map = {};\n        define.queue.push({\n            deps: deps,\n            map: map,\n            toLoad: toLoad,\n            callback: callback,\n            errback: errback,\n        });\n\n        for (var i = 0; i < missing.length; ++i) {\n            var p = missing[i];\n            map[p] = 1;\n            if (!define.loading[p]) {\n                define.loading[p] = 1;\n                require.load(p);\n            }\n        }\n    };\n\n    var processLoadQueue = function(err, id) {\n        var changed = false;\n        if (err) {\n            if (!id) id = err.id;\n            define.errors[id] = err;\n            define.queue.forEach(function(r) {\n                if (r.map[id]) {\n                    r.toLoad = -1;\n                    if (r.errback) r.errback(err);\n                }\n            });\n            if (define.lastModule == id) define.lastModule = null;\n            define.pending = define.pending.filter(function(p) {\n                return p != id;\n            });\n            changed = true;\n            err.from = [];\n            for (var i in define.loaded) {\n                var index = define.loaded[i].deps.indexOf(id);\n                if (index != -1) {\n                    err.from.push(define.loaded[i].id);\n                }\n            }\n            console.error(\"Error loading \" + id + \" required from \" + err.from.slice(0, 2));\n        } else if (id && !defQueue.length && !define.loaded[id]) {\n            // the script didn't call define\n            defQueue = [(config.shim && config.shim[id]) || [[], null]];\n        }\n\n        if (defQueue.length) {\n            if (defQueue.length > 1) throw new Error(\"more than one module in defqueue\");\n            define(id, defQueue[0][0], defQueue[0][1]);\n            defQueue.length = 0;\n        }\n\n        var pending = define.pending;\n        define.queue.forEach(function(r) {\n            pending.forEach(function(id) {\n                if (r.map[id]) r.toLoad--;\n            });\n            if (r.map[define.lastModule]) r.toLoad--;\n            if (!r.toLoad) {\n                changed = true;\n                _require(\"\", r.deps, r.callback, r.errback);\n            }\n        });\n\n        define.lastModule = null;\n        if (pending.length) define.pending = [];\n\n        if (changed) {\n            define.queue = define.queue.filter(function(r) {\n                return r.toLoad > 0;\n            });\n        }\n    };\n\n    define.amd = {};\n    define.queue = [];\n    define.loaded = {};\n    define.errors = {};\n    define.loading = {};\n    define.pending = [];\n    define.modules = {require: 1, exports: 1, module: 1};\n    define.fetchedUrls = {};\n\n    var activateModule = function(name) {\n        var module = define.loaded[name];\n        var exports = module.exports;\n        if (typeof module.factory !== \"function\") {\n            exports = module.factory;\n        } else {\n            var req = function(path, callback) {\n                return _require(name, path, callback);\n            };\n            req.config = config;\n            req.toUrl = function(id) {\n                return require.toUrl(id);\n            };\n\n            var missing = checkMissing(module.deps);\n            if (missing.length) return missing;\n\n            module.define = define;\n            var specialModules = {\n                require: req,\n                exports: exports,\n                module: module,\n            };\n\n            if (name.lastIndexOf(\"architect!\", 0) == 0 && !module.pluginFactory) {\n                module.pluginFactory = module.factory;\n                module.factory = activateArchitectModule;\n            }\n\n            define.modules[name] = exports;\n            var args = module.deps.slice(0, module.factory.length);\n            var returnValue = args.length\n                ? module.factory.apply(\n                      module,\n                      args.map(function(name) {\n                          return specialModules[name] || lookup(name);\n                      })\n                  )\n                : module.factory(req, exports, module);\n\n            exports = returnValue == undefined ? module.exports : returnValue;\n        }\n        if (!config.$keepLoaders) delete define.loaded[name];\n        define.modules[name] = exports;\n    };\n\n    var checkMissing = function(deps, seen, missing) {\n        missing = missing || {};\n        seen = seen || {};\n        for (var i = 0; i < deps.length; ++i) {\n            var depName = deps[i];\n            if (!define.modules[depName]) {\n                var dep = define.loaded[depName];\n                if (!dep) missing[depName] = 1;\n                else if (!missing[depName] && !seen[depName]) {\n                    seen[depName] = 1;\n                    checkMissing(dep.deps, seen, missing);\n                }\n            }\n        }\n        return Object.keys(missing);\n    };\n\n    var lookup = function(moduleName) {\n        var mod = define.modules[moduleName];\n        if (mod === undefined && define.loaded[moduleName]) {\n            activateModule(moduleName);\n            mod = define.modules[moduleName];\n        }\n        return mod;\n    };\n\n    var _require = function(parentId, moduleName, callback, errback) {\n        if (typeof moduleName === \"string\") {\n            var depName = normalizeName(parentId, moduleName);\n            var module = lookup(depName);\n            if (module !== undefined) {\n                if (typeof callback == \"function\") callback(module);\n                return module;\n            } else if (typeof importScripts != \"undefined\" || syncLoaders.test(moduleName)) {\n                addToLoadQueue([depName], [depName]);\n                return lookup(depName);\n            }\n        } else if (Array.isArray(moduleName)) {\n            var deps = normalizeNames(parentId, moduleName);\n            var missing = checkMissing(deps);\n            if (!missing.length) {\n                var args = deps.map(lookup);\n                return callback && callback.apply(null, args);\n            } else {\n                return addToLoadQueue(missing, deps, callback, errback);\n            }\n        }\n    };\n\n    var normalizeName = function(parentId, moduleName) {\n        if (/!/.test(parentId)) parentId = parentId.split(\"!\").pop();\n        // normalize plugin requires\n        var i = moduleName.indexOf(\"!\");\n        if (i !== -1) {\n            return (\n                normalizeName(parentId, moduleName.slice(0, i)) +\n                \"!\" +\n                normalizeName(parentId, moduleName.slice(i + 1))\n            );\n        }\n        // normalize relative requires\n        if (moduleName.charAt(0) == \".\") {\n            var parentChunks = parentId.split(\"/\");\n            var parentModule = parentChunks.shift();\n            if (parentModule.charAt(0) == \"@\") {\n                parentModule = parentModule + \"/\" + parentChunks.shift();\n            }\n\n            var path = parentChunks.slice(0, -1).join(\"/\");\n            moduleName = parentModule + (path ? \"/\" + path : \"\") + \"/\" + moduleName;\n\n            while (moduleName.indexOf(\".\") !== -1 && previous != moduleName) {\n                var previous = moduleName;\n                moduleName = moduleName.replace(/\\/\\.\\//, \"/\").replace(/[^\\/]+\\/\\.\\.\\//, \"\");\n            }\n        }\n\n        return moduleName;\n    };\n\n    var normalizeNames = function(parentId, moduleNames) {\n        return moduleNames.map(function(name) {\n            return normalizeName(parentId, name);\n        });\n    };\n\n    var require = function(module, callback, errback) {\n        return _require(\"\", module, callback, errback);\n    };\n\n    var config = (require.config = function(cfg) {\n        if (cfg.baseUrl) config.baseUrl = cfg.baseUrl.replace(/\\/*$/, \"/\");\n\n        if (cfg.host) host = cfg.host;\n\n        if (Array.isArray(cfg.packages)) {\n            cfg.packages.forEach(function(pkg) {\n                if (typeof pkg === \"string\") pkg = {name: pkg};\n                config.packages[pkg.name] = {\n                    name: pkg.name,\n                    location: (pkg.location || pkg.name).replace(/\\/*$/, \"/\"),\n                    main: (pkg.main || \"main\").replace(/\\.js$/, \"\").replace(/^\\.\\//, \"\"),\n                };\n            });\n        } else if (cfg.packages) {\n            config.packages = cfg.packages;\n        }\n\n        cfg.paths &&\n            Object.keys(cfg.paths).forEach(function(p) {\n                config.paths[p] = cfg.paths[p];\n            });\n\n        if (\n            cfg.useCache &&\n            global.caches &&\n            (location.protocol === \"https:\" || location.hostname == \"localhost\")\n        ) {\n            config.useCache = true;\n            checkCache();\n        }\n\n        if (cfg.transform) config.transform = cfg.transform;\n        if (/\\bes5\\b/.test(cfg.transform) && !global.shimIncluded) {\n            if (!console.assert) {\n                console.assert = function assert() {}; // This method is used by the following es6 shim.\n            }\n            var oldFlags = RegExp.prototype.flags;\n            RegExp.prototype.flags = true;\n            require([\"js-polyfills/es6\"]);\n            RegExp.prototype.flags = oldFlags;\n            global.shimIncluded = true;\n        }\n\n        if (cfg.assetUrl) config.assetUrl = cfg.assetUrl;\n\n        if (cfg.$keepLoaders != undefined) config.$keepLoaders = cfg.$keepLoaders;\n    });\n\n    require.resetConfig = function(cfg) {\n        var location = global.location;\n        var baseUrl = location ? location.protocol + \"//\" + location.host \n            + location.pathname.split(\"/\").slice(0, -1).join(\"/\") : \"\";\n        config.packages = Object.create(null);\n        config.paths = Object.create(null);\n        config.baseUrl = baseUrl;\n        config.useCache = false;\n        config.transform = \"\";\n        if (cfg) require.config(cfg);\n    };\n\n    require.getConfig = function() {\n        var script = document.querySelector(\"script[src*=require]\");\n        return {\n            packages: config.packages,\n            paths: config.paths,\n            baseUrl: config.baseUrl,\n            useCache: config.useCache,\n            transform: config.transform,\n            host: host,\n            requireSourceUrl: !config.packed && script && script.src,\n            assetUrl: config.assetUrl,\n        };\n    };\n\n    require.resetConfig();\n\n    define.undef = require.undef = function(module, recursive) {\n        module = normalizeName(\"\", module);\n        if (recursive) {\n            var root = (module + \"/\").replace(/\\/+$/, \"/\");\n            undefAll(root, define.errors);\n            undefAll(root, define.loaded);\n            undefAll(root, define.modules);\n            undefAll(root, define.loading);\n        } else {\n            undefOne(module, require.toUrl(module, \".js\"));\n        }\n    };\n\n    function undefOne(module, path) {\n        delete define.errors[module];\n        delete define.loaded[module];\n        delete define.modules[module];\n        delete define.loading[module];\n        delete define.fetchedUrls[path];\n    }\n\n    function undefAll(module, hash) {\n        Object.keys(hash).forEach(function(key) {\n            var i = key.indexOf(\"!\") + 1;\n            if (key.lastIndexOf(module, 0) == 0) undefOne(key, require.toUrl(key, \".js\"));\n            if (i) {\n                var plugin = key.slice(0, i - 1);\n                var resource = key.slice(i);\n                if (resource.lastIndexOf(module, 0) == 0 || plugin.lastIndexOf(module, 0) == 0) {\n                    undefOne(key, require.toUrl(key, \"\"));\n                    undefOne(resource, require.toUrl(resource, \"\"));\n                }\n            }\n        });\n    }\n\n    require.toUrl = function(moduleName, ext, skipExt, isStatic) {\n        var absRe = /^([\\w\\+\\.\\-]+:|\\/)/;\n        var index = moduleName.indexOf(\"!\");\n        if (index !== -1 || !ext || /^\\//.test(moduleName)) ext = \"\";\n\n        var paths = config.paths;\n        var pkgs = config.packages;\n\n        var testPath = moduleName;\n        var tail = \"\";\n        while (testPath) {\n            if (paths[testPath]) {\n                moduleName = paths[testPath] + tail;\n                break;\n            }\n            if (pkgs[testPath]) {\n                moduleName = pkgs[testPath].location + (tail || pkgs[testPath].main);\n                break;\n            }\n            var i = testPath.lastIndexOf(\"/\");\n            if (i === -1) break;\n            tail = testPath.substr(i) + tail;\n            testPath = testPath.slice(0, i);\n        }\n\n        if (skipExt) return testPath;\n\n        var url = ext == \".js\" && moduleName.slice(-3) == ext ? moduleName : moduleName + ext;\n        if (moduleName.slice(-3) == \".ts\") {\n            url = moduleName.slice(0, -3) + ext;\n        }\n        if (!absRe.test(url)) {\n            if (ext == \".js\" && require.config.transform) url = addTransform(url, moduleName);\n            var baseUrl = config.baseUrl;\n            if (baseUrl.slice(-1) != \"/\") baseUrl += \"/\";\n            url = baseUrl + url;\n        }\n        if (url[0] == \"/\") url = host + url;\n        return url;\n    };\n\n    function addTransform(url, moduleName) {\n        var transform = require.config.transform;\n        if (!Array.isArray(transform)) transform = [transform];\n        return (\n            \"~/\" +\n            transform\n                .map(function(part) {\n                    if (typeof part == \"string\") return part;\n                    if (moduleName.lastIndexOf(part[0], 0) != -1) return part[1];\n                })\n                .filter(Boolean)\n                .join(\",\") +\n            \"/\" +\n            url\n        ).replace(\"//\", \"/\");\n    }\n\n    function loadText(path, callback) {\n        var xhr = new global.XMLHttpRequest();\n        xhr.open(\"GET\", path, true);\n        xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n        xhr.onload = function(e) {\n            if (xhr.status > 399 && xhr.status < 600) return callback(xhr);\n            callback(null, xhr.responseText, xhr);\n        };\n        xhr.onabort = xhr.onerror = function(e) {\n            callback(e);\n        };\n        xhr.send(\"\");\n    }\n\n    /*** cache ***/\n    var host =\n        location.protocol + \"//\" + location.hostname + (location.port ? \":\" + location.port : \"\");\n    var loadScript = function(path, id, callback) {\n        if (!/^\\w+:/.test(path)) path = host + path;\n        var onLoad = function(e, val) {\n            if (e) return processLoadQueue({id: id, path: path});\n            if (!/^(\\s|\\/\\*([^*]|[*](?!\\/))*\\*\\/|\\/\\/.*[\\r]?\\n)*define\\s*\\(\\s*function\\s*\\(\\s*require\\b/.test(val) && !/define\\(\\[\\],/.test(val))\n                val = \"define(function(require, exports, module){\" + val + \"\\n});\"\n            nextModule = {name: id};\n            /* eslint no-eval:0 */\n            global.eval(val + \"\\n//# sourceURL=\" + path);\n            callback(null, id);\n            return define.loaded[id];\n        };\n        loadCached(path, onLoad);\n    };\n\n    var loadCached = function(path, callback) {\n        return loadText(path, callback);\n    };\n\n    require.load = function(module) {\n        var i = module.indexOf(\"!\") + 1;\n        if (i) {\n            var plugin = module.substring(0, i);\n            module = module.substr(i);\n            if (typeof require[plugin] == \"function\") {\n                require[plugin](module, processLoadQueue);\n            } else if (config.baseUrl) {\n                if (require[plugin]) return (require[plugin][plugin + module] = 1);\n                require[plugin] = Object.create(null);\n                require[plugin][plugin + module] = 1;\n                require([plugin.slice(0, -1)], function(p) {\n                    var pending = require[plugin];\n                    definePlugin(plugin, p);\n                    Object.keys(pending).forEach(function(p) {\n                        delete define.loading[p];\n                    });\n                    require(Object.keys(pending));\n                });\n            } else {\n                console.error(\"require plugin \" + plugin + \"missing\");\n            }\n        } else {\n            var url = require.toUrl(module, \".js\");\n            if (define.fetchedUrls[url] & 1) return false;\n            define.fetchedUrls[url] |= 1;\n            loadScript(url, module, processLoadQueue);\n        }\n    };\n\n    function definePlugin(plugin, p) {\n        require[plugin] = function(moduleName, processLoadQueue) {\n            p.load(moduleName, require, function(value) {\n                define(plugin + moduleName, [], function() {\n                    return value;\n                });\n                processLoadQueue();\n            });\n        };\n    }\n\n    /*** plugins ***/\n    var syncLoaders = /^(language!|webworker!|vfs!|asset-url!)/;\n    require[\"language!\"] = function(module, callback) {\n        define(\"language!\" + module, [], module);\n        callback();\n    };\n    require[\"webworker!\"] = function(module, callback) {\n        var url = require.toUrl(module.split(\"!\").pop(), \".js\");\n        define(\"webworker!\" + module, [], url);\n        callback();\n    };\n    require[\"asset-url!\"] = function(module, callback) {\n        var url = require.toUrl(module.split(\"!\").pop(), \"\", \"\", true);\n        define(\"asset-url!\" + module, [], url);\n        callback();\n    };\n    require[\"vfs!\"] = function(module, callback) {\n        var url = require.MODULE_LOAD_URL + \"/~node/\" + module;\n        if (define.fetchedUrls[url] & 4) return false;\n        define.fetchedUrls[url] |= 4;\n        define(\"vfs!\" + module, [], {\n            srcUrl: url,\n            path: module,\n        });\n        callback();\n    };\n    require[\"text!\"] = function(module, callback) {\n        var url = require.toUrl(module);\n        if (define.fetchedUrls[url] & 2) return false;\n        define.fetchedUrls[url] |= 2;\n        var onLoad = function(e, val) {\n            if (e) console.error(\"Couldn't load module \" + module, e);\n            define(\"text!\" + module, [], val);\n            callback();\n        };\n        loadCached(url, onLoad);\n    };\n    require[\"json!\"] = function(module, callback) {\n        require[\"text!\"](module, function() {\n            var val = JSON.parse(require(\"text!\" + module));\n            define(\"json!\" + module, [], val);\n            callback();\n        });\n    };\n    require[\"ace/requirejs/text!\"] = function(module, callback) {\n        var url = require.toUrl(module);\n        if (define.fetchedUrls[url] & 2) return false;\n        define.fetchedUrls[url] |= 2;\n        var onLoad = function(e, val) {\n            if (e) console.error(\"Couldn't load module \" + module, e);\n            define(\"ace/requirejs/text!\" + module, [], val);\n            callback();\n        };\n        loadCached(url, onLoad);\n    };\n    require[\"architect!\"] = function(module, callback) {\n        var url = require.toUrl(module, \".js\");\n        if (define.fetchedUrls[url] & 1) return false;\n        define.fetchedUrls[url] |= 1;\n        loadScript(url, \"architect!\" + module, processLoadQueue);\n    };\n    function activateArchitectModule(_1, _2, _3) {\n        var module = this;\n        return function() {\n            module.pluginFactory(_1, _2, _3);\n            if (typeof module.exports == \"function\" && module.exports.consumes) {\n                return module.exports.apply(this, arguments);\n            }\n            return module.exports;\n        };\n    }\n\n    /*** add global define ***/\n    if (!global.define || !global.define.packaged) {\n        define.original = global.define;\n        global.define = define;\n        global.define.packaged = true;\n    }\n\n    if (!global.require || !global.require.packaged) {\n        global.require = require;\n        global.require.packaged = true;\n    }\n\n    if (!global.requirejs) global.requirejs = require;\n\n    global.miniRequire = require;\n})();\n"
  },
  {
    "path": "demo/kitchen-sink/styles.css",
    "content": "html {\n    height: 100%;\n    width: 100%;\n    overflow: hidden;\n}\n\nbody {\n    overflow: hidden;\n    margin: 0;\n    padding: 0;\n    height: 100%;\n    width: 100%;\n    font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana, sans-serif;\n    font-size: 12px;\n    background: rgb(14, 98, 165);\n    color: white;\n}\n\n#c9-logo, #ace-logo {\n    padding: 0;\n    border: none;\n}\n\n#editor-container {\n    position: absolute;\n    top:  0px;\n    left: 280px;\n    bottom: 0px;\n    right: 0px;\n    background: white;\n}\n\n#controls {\n    padding: 5px;\n}\n\n#controls td {\n    text-align: right;\n}\n\n#controls td + td {\n    text-align: left;\n}\n.ace_status-indicator {\n    color: gray;\n    position: absolute;\n    right: 0;\n    border-left: 1px solid;\n}\n\n.toggleButton {\n  display: inline-block;\n  cursor: pointer;\n  position: absolute;\n}\n.toggleButton>div {\n    width: 15px;\n    height: 2px;\n    margin: 3px 2px;\n    background-color: #eee;\n    pointer-events: none;\n    transition: 0.5s;\n}\n\n#sidePanel *:focus {\n    outline: 3px solid orange;\n}\n\n#sidePanel a {\n    display: inline-block;\n}\n\n#sidePanel:not(.closed) .toggleButton >div:nth-child(1) {transform: translate(0px, 5px) rotate(-45deg)}\n#sidePanel:not(.closed) .toggleButton >div:nth-child(2) {opacity: 0}\n#sidePanel:not(.closed) .toggleButton >div:nth-child(3) {transform: translate(0px, -5px) rotate(45deg)}\n#sidePanel.closed>*:not(.toggleButton) {display: none}\n\n.show-text-input .ace_text-input {\n    z-index: 10!important;\n    opacity: 1!important;\n    background: rgb(84, 0, 255)!important;\n    color: rgb(255, 255, 255)!important;\n    width: 10em!important;\n}\n.text-input-debug {\n    height: 100px!important;\n    position: absolute!important;\n    transform: none!important;\n    top: 0px!important;\n    left: 7px!important;\n    width: 260px!important;\n    z-index: 1000!important;\n    opacity: 1!important;\n    font-size: 1em!important;\n}\n\n\n.language_highlight_error {\n\tposition: absolute;\n\tborder-bottom: dotted 1px #e00404;\n\tz-index: 2000;\n    border-radius: 0;\n}\n.language_highlight_warning {\n\tposition: absolute;\n\tborder-bottom: solid 1px #DDC50F;\n\tz-index: 2000;\n    border-radius: 0;\n}\n.language_highlight_info {\n\tposition: absolute;\n\tborder-bottom: dotted 1px #999;\n\tz-index: 2000;\n    border-radius: 0;\n}\n.language_highlight_text, .language_highlight_read, .language_highlight_write {\n\tposition: absolute;\n\tbox-sizing: border-box;\n\tborder: solid 1px #888;\n\tz-index: 2000;\n}\n.language_highlight_write {\n    border: solid 1px #F88;\n}\n.ace_tooltip pre {\n    margin: 0;\n}"
  },
  {
    "path": "demo/kitchen-sink/token_tooltip.js",
    "content": "\"use strict\";\n\nvar dom = require(\"ace/lib/dom\");\nvar oop = require(\"ace/lib/oop\");\nvar event = require(\"ace/lib/event\");\nvar Range = require(\"ace/range\").Range;\nvar Tooltip = require(\"ace/tooltip\").Tooltip;\n\nclass TokenTooltip extends Tooltip {\n    constructor(editor) {\n        if (editor.tokenTooltip)\n            return;\n        super(editor.container);\n        editor.tokenTooltip = this;\n        this.editor = editor;\n\n        this.update = this.update.bind(this);\n        this.onMouseMove = this.onMouseMove.bind(this);\n        this.onMouseOut = this.onMouseOut.bind(this);\n        event.addListener(editor.renderer.scroller, \"mousemove\", this.onMouseMove);\n        event.addListener(editor.renderer.content, \"mouseout\", this.onMouseOut);\n    }\n    token = {};\n    \n    range = new Range();\n    \n    update() {\n        this.$timer = null;\n        \n        var r = this.editor.renderer;\n        if (this.lastT - (r.timeStamp || 0) > 1000) {\n            r.rect = null;\n            r.timeStamp = this.lastT;\n            this.maxHeight = window.innerHeight;\n            this.maxWidth = window.innerWidth;\n        }\n\n        var canvasPos = r.rect || (r.rect = r.scroller.getBoundingClientRect());\n        var offset = (this.x + r.scrollLeft - canvasPos.left - r.$padding) / r.characterWidth;\n        var row = Math.floor((this.y + r.scrollTop - canvasPos.top) / r.lineHeight);\n        var col = Math.round(offset);\n\n        var screenPos = {row: row, column: col, side: offset - col > 0 ? 1 : -1};\n        var session = this.editor.session;\n        var docPos = session.screenToDocumentPosition(screenPos.row, screenPos.column);\n        var token = session.getTokenAt(docPos.row, docPos.column);\n\n        if (!token && !session.getLine(docPos.row)) {\n            token = {\n                type: \"\",\n                value: \"\",\n                state: session.bgTokenizer.getState(0)\n            };\n        }\n        if (!token) {\n            session.removeMarker(this.marker);\n            this.hide();\n            return;\n        }\n\n        var tokenText = token.type;\n        if (token.state)\n            tokenText += \"|\" + token.state;\n        if (token.merge)\n            tokenText += \"\\n  merge\";\n        if (token.stateTransitions)\n            tokenText += \"\\n  \" + token.stateTransitions.join(\"\\n  \");\n\n        if (this.tokenText != tokenText) {\n            this.setText(tokenText);\n            this.width = this.getWidth();\n            this.height = this.getHeight();\n            this.tokenText = tokenText;\n        }\n        if (!this.isOpen) {\n            this.setTheme(r.theme);\n        }\n\n        this.show(null, this.x, this.y);\n\n        this.token = token;\n        session.removeMarker(this.marker);\n        this.range = new Range(docPos.row, token.start, docPos.row, token.start + token.value.length);\n        this.marker = session.addMarker(this.range, \"ace_bracket\", \"text\");\n    };\n    \n    onMouseMove(e) {\n        this.x = e.clientX;\n        this.y = e.clientY;\n        if (this.isOpen) {\n            this.lastT = e.timeStamp;\n            this.setPosition(this.x, this.y);\n        }\n        if (!this.$timer)\n            this.$timer = setTimeout(this.update, 100);\n    };\n\n    onMouseOut(e) {\n        if (e && e.currentTarget.contains(e.relatedTarget))\n            return;\n        this.hide();\n        this.editor.session.removeMarker(this.marker);\n        this.$timer = clearTimeout(this.$timer);\n    };\n\n    setPosition(x, y) {\n        if (x + 10 + this.width > this.maxWidth)\n            x = window.innerWidth - this.width - 10;\n        if (y > window.innerHeight * 0.75 || y + 20 + this.height > this.maxHeight)\n            y = y - this.height - 30;\n\n        Tooltip.prototype.setPosition.call(this, x + 10, y + 20);\n    };\n\n    destroy() {\n        this.onMouseOut();\n        event.removeListener(this.editor.renderer.scroller, \"mousemove\", this.onMouseMove);\n        event.removeListener(this.editor.renderer.content, \"mouseout\", this.onMouseOut);\n        delete this.editor.tokenTooltip;\n    };\n\n}\n\nexports.TokenTooltip = TokenTooltip;\n"
  },
  {
    "path": "demo/kitchen-sink/util.js",
    "content": "\"use strict\";\n\nvar dom = require(\"ace/lib/dom\");\nvar event = require(\"ace/lib/event\");\n\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\nvar Renderer = require(\"ace/virtual_renderer\").VirtualRenderer;\nvar Editor = require(\"ace/editor\").Editor;\nvar MultiSelect = require(\"ace/multi_select\").MultiSelect;\n\nvar urlOptions = {}\ntry {\n    window.location.search.slice(1).split(/[&]/).forEach(function(e) {\n        var parts = e.split(\"=\");\n        urlOptions[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);\n    });\n} catch(e) {\n    console.error(e);\n}\nexports.createEditor = function(el) {\n    return new Editor(new Renderer(el));\n};\n\nexports.getOption = function(name) {\n    if (urlOptions[name])\n        return urlOptions[name];\n    return localStorage && localStorage.getItem(name);\n};\n\nexports.saveOption = function(name, value) {\n    if (value == false)\n        value = \"\";\n    localStorage && localStorage.setItem(name, value);\n};\n\nexports.createSplitEditor = function(el) {\n    if (typeof(el) == \"string\")\n        el = document.getElementById(el);\n\n    var e0 = document.createElement(\"div\");\n    var s = document.createElement(\"splitter\");\n    var e1 = document.createElement(\"div\");\n    el.appendChild(e0);\n    el.appendChild(e1);\n    el.appendChild(s);\n    e0.style.position = e1.style.position = s.style.position = \"absolute\";\n    el.style.position = \"relative\";\n    var split = {$container: el};\n\n    split.editor0 = split[0] = new Editor(new Renderer(e0));\n    split.editor0.session.setUndoManager(new UndoManager());\n    split.editor1 = split[1] = new Editor(new Renderer(e1));\n    split.editor1.session.setUndoManager(new UndoManager());\n    split.splitter = s;\n\n    s.ratio = 0.5;\n\n    split.resize = function resize(){\n        var height = el.parentNode.clientHeight - el.offsetTop;\n        var total = el.clientWidth;\n        var w1 = total * s.ratio;\n        var w2 = total * (1- s.ratio);\n        s.style.left = w1 - 1 + \"px\";\n        s.style.height = el.style.height = height + \"px\";\n\n        var st0 = split[0].container.style;\n        var st1 = split[1].container.style;\n        st0.width = w1 + \"px\";\n        st1.width = w2 + \"px\";\n        st0.left = 0 + \"px\";\n        st1.left = w1 + \"px\";\n\n        st0.top = st1.top = \"0px\";\n        st0.height = st1.height = height + \"px\";\n\n        split[0].resize();\n        split[1].resize();\n    };\n\n    split.onMouseDown = function(e) {\n        var rect = el.getBoundingClientRect();\n        var x = e.clientX;\n        var y = e.clientY;\n\n        var button = e.button;\n        if (button !== 0) {\n            return;\n        }\n\n        var onMouseMove = function(e) {\n            x = e.clientX;\n            y = e.clientY;\n        };\n        var onResizeEnd = function(e) {\n            clearInterval(timerId);\n        };\n\n        var onResizeInterval = function() {\n            s.ratio = (x - rect.left) / rect.width;\n            split.resize();\n        };\n\n        event.capture(s, onMouseMove, onResizeEnd);\n        var timerId = setInterval(onResizeInterval, 40);\n\n        return e.preventDefault();\n    };\n\n\n\n    event.addListener(s, \"mousedown\", split.onMouseDown);\n    event.addListener(window, \"resize\", split.resize);\n    split.resize();\n    return split;\n};\n\n/***************************/\nexports.stripLeadingComments = function(str) {\n    if(str.slice(0,2)=='/*') {\n        var j = str.indexOf('*/')+2;\n        str = str.substr(j);\n    }\n    return str.trim() + \"\\n\";\n};\n\n/***************************/\nfunction saveOptionFromElement(el, val) {\n    if (!el.onchange && !el.onclick)\n        return;\n\n    if (\"checked\" in el) {\n        localStorage && localStorage.setItem(el.id, el.checked ? 1 : 0);\n    }\n    else {\n        localStorage && localStorage.setItem(el.id, el.value);\n    }\n}\n\nexports.bindCheckbox = function(id, callback, noInit) {\n    if (typeof id == \"string\")\n        var el = document.getElementById(id);\n    else {\n        var el = id;\n        id = el.id;\n    }\n    var el = document.getElementById(id);\n    \n    if (urlOptions[id])\n        el.checked = urlOptions[id] == \"1\";\n    else if (localStorage && localStorage.getItem(id))\n        el.checked = localStorage.getItem(id) == \"1\";\n\n    var onCheck = function() {\n        callback(!!el.checked);\n        saveOptionFromElement(el);\n    };\n    el.onclick = onCheck;\n    noInit || onCheck();\n    return el;\n};\n\nexports.bindDropdown = function(id, callback, noInit) {\n    if (typeof id == \"string\")\n        var el = document.getElementById(id);\n    else {\n        var el = id;\n        id = el.id;\n    }\n    \n    if (urlOptions[id])\n        el.value = urlOptions[id];\n    else if (localStorage && localStorage.getItem(id))\n        el.value = localStorage.getItem(id);\n\n    var onChange = function() {\n        callback(el.value);\n        saveOptionFromElement(el);\n    };\n\n    el.onchange = onChange;\n    noInit || onChange();\n};\n\nexports.fillDropdown = function(el, values) {\n    if (typeof el == \"string\")\n        el = document.getElementById(el);\n\n    dropdown(values).forEach(function(e) {\n        el.appendChild(e);\n    });\n};\n\nfunction elt(tag, attributes, content) {\n    var el = dom.createElement(tag);\n    if (typeof content == \"string\") {\n        el.appendChild(document.createTextNode(content));\n    } else if (content) {\n        content.forEach(function(ch) {\n            el.appendChild(ch);\n        });\n    }\n\n    for (var i in attributes)\n        el.setAttribute(i, attributes[i]);\n    return el;\n}\n\nfunction optgroup(values) {\n    return values.map(function(item) {\n        if (typeof item == \"string\")\n            item = {name: item, caption: item};\n        return elt(\"option\", {value: item.value || item.name}, item.caption || item.desc);\n    });\n}\n\nfunction dropdown(values) {\n    if (Array.isArray(values))\n        return optgroup(values);\n\n    return Object.keys(values).map(function(i) {\n        return elt(\"optgroup\", {\"label\": i}, optgroup(values[i]));\n    });\n}\n"
  },
  {
    "path": "demo/modelist.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ACE Editor Modelist Demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n    \n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/modelist\"], function(ace) {\n    var editor = ace.edit(\"editor\");\n    editor.setTheme(\"ace/theme/twilight\");\n    (function () {\n        var modelist = require(\"ace/ext/modelist\");\n        // the file path could come from an xmlhttp request, a drop event,\n        // or any other scriptable file loading process.\n        // Extensions could consume the modelist and use it to dynamically\n        // set the editor mode. Webmasters could use it in their scripts\n        // for site specific purposes as well.\n        var filePath = \"blahblah/weee/some.js\";\n        var mode = modelist.getModeForPath(filePath).mode;\n        console.log(mode);\n        editor.session.setMode(mode);\n    }());\n})\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/r.js/build.js",
    "content": "({\n    optimize: \"none\",\n    preserveLicenseComments: false,\n    name: \"node_modules/almond/almond.js\",\n    baseUrl: \".\",\n    paths: {\n        ace : \"../../lib/ace\",\n        demo: \"../../demo/kitchen-sink\"\n    },\n    packages: [\n    ],\n    include: [\n        \"ace/ace\"\n    ],\n    exclude: [\n    ],\n    out: \"./dist/bundle.js\",\n    useStrict: true,\n    wrap: false\n})\n"
  },
  {
    "path": "demo/r.js/editor.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n    <title>Editor</title>\n    <link rel=\"stylesheet\" href=\"../kitchen-sink/styles.css\" type=\"text/css\" media=\"screen\" charset=\"utf-8\">    \n</head>\n<body>\n    <div id=\"optionsPanel\" style=\"position:absolute;height:100%;width:260px\">\n        <a href=\"http://c9.io\" title=\"Cloud9 IDE | Your code anywhere, anytime\">\n            <img id=\"c9-logo\" src=\"../kitchen-sink/logo.png\" style=\"width: 172px;margin: -9px 30px -12px 51px;\">\n        </a>\n    </div>\n    <pre id=\"editor-container\">\n        <div style=\"color:black; padding: 10px\">\n            demo showing Ace usage with r.js:\n            \n            install r.js and almond\n            and run `<code>r.js -o demo/r.js/build.js</code>`\n            \n            note that you also need ace/build/src to lazy load modes and themes\n            require(\"ace/config\").set(\"basePath\", \"../../build/src\");\n            require(\"ace/config\").set(\"packaged\", true);\n        <div>\n    </pre>\n\n    <script src=\"./dist/bundle.js\" data-ace-base=\"src\" type=\"text/javascript\" charset=\"utf-8\"></script>  \n    <script type=\"text/javascript\" charset=\"utf-8\">\n        require(\"ace/config\").set(\"basePath\", \"../../build/src\")\n        require(\"ace/config\").set(\"packaged\", true)\n        var editor = require(\"ace/ace\").edit(\"editor-container\");\n        editor.session.setMode(\"ace/mode/javascript\");\n        // editor.session.setValue(\"var editor = Ace!\")\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/requirejs+build.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n\n    #editor {\n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\">function foo(items) {\n    var i;\n    for (i = 0; i &lt; items.length; i++) {\n        alert(\"Ace Rocks \" + items[i]);\n    }\n}</pre>\n\n<script src=\"../demo/kitchen-sink/require.js\"></script>\n<script>\n    require.config({paths: {ace: \"../build/src\"}})\n    define('testace', ['ace/ace'],\n        function(ace, langtools) {\n            console.log(\"This is the testace module\");\n            var editor = ace.edit(\"editor\");\n            editor.setTheme(\"ace/theme/twilight\");\n            editor.session.setMode(\"ace/mode/javascript\");\n            require([\"ace/requirejs/text!src/ace\"], function(e){\n                editor.setValue(e);\n            })\n        }\n    );\n    require(['testace'])\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/scrollable-page.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    .ace_editor {\n        position: relative !important;\n        border: 1px solid lightgray;\n        margin: auto;\n        height: 200px;\n        width: 80%;\n    }\n\n    .ace_editor.fullScreen {\n        height: auto;\n        width: auto;\n        border: 0;\n        margin: 0;\n        position: fixed !important;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n        z-index: 10;\n    }\n\n    body.fullScreen {\n        overflow: hidden;\n        /*transform breaks position fixed*/\n        transform: none!important;\n    }\n\n    .scrollmargin {\n        height: 500px;\n        text-align: center;\n    }\n\n    .large-button {\n        color: lightblue;\n        cursor: pointer;\n        font: 30px arial;\n        padding: 20px;\n        text-align: center;\n        border: medium solid transparent;\n        display: inline-block;\n    }\n    .large-button:hover {\n        border: medium solid lightgray;\n        border-radius: 10px 10px 10px 10px;\n        box-shadow: 0 0 12px 0 lightblue;\n    }\n    body {\n        transform: translateZ(0);\n    }\n  </style>\n</head>\n<body>\n<div class=\"scrollmargin\">\n    <span onclick=\"scroll()\" class=\"large-button\">\n    scroll down &dArr;\n    </span>\n</div>\n<pre id=\"editor\">function foo(items) {\n    var i;\n    for (i = 0; i &lt; items.length; i++) {\n        alert(\"Ace Rocks \" + items[i]);\n    }\n\n}</pre>\n<div class=\"scrollmargin\">\n    <div style=\"padding:20px\">\n        press F11 to switch to fullscreen mode\n    </div>\n    <span onclick=\"add()\" class=\"large-button\">\n        +\n    </span>\n\n</div>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\nrequire.config({paths: { \"ace\" : \"../src\"}});\nrequire([\"ace/ace\", \"ace/ext/themelist\", \"ace/ext/language_tools\"], function(ace) {\n\nvar $ = document.getElementById.bind(document);\nvar dom = require(\"ace/lib/dom\");\n\nace.config.set(\"enableBasicAutocompletion\", true);\n\n//add command to all new editor instances\nrequire(\"ace/commands/default_commands\").commands.push({\n    name: \"Toggle Fullscreen\",\n    bindKey: \"F11\",\n    exec: function(editor) {\n        var fullScreen = dom.toggleCssClass(document.body, \"fullScreen\")\n        dom.setCssClass(editor.container, \"fullScreen\", fullScreen)\n        editor.setAutoScrollEditorIntoView(!fullScreen)\n        editor.resize()\n    }\n})\n\n// create first editor\nvar editor = ace.edit(\"editor\");\neditor.setTheme(\"ace/theme/twilight\");\neditor.session.setMode(\"ace/mode/javascript\");\neditor.renderer.setScrollMargin(10, 10);\neditor.setOptions({\n    // \"scrollPastEnd\": 0.8,\n    autoScrollEditorIntoView: true\n});\n\nvar count = 1;\nfunction add() {\n    var oldEl = editor.container\n    var pad = document.createElement(\"div\")\n    pad.style.padding = \"40px\"\n    oldEl.parentNode.insertBefore(pad, oldEl.nextSibling)\n\n    var el = document.createElement(\"div\")\n    oldEl.parentNode.insertBefore(el, pad.nextSibling)\n\n    count++\n    var theme = themes[Math.floor(themes.length * Math.random() - 1e-5)]\n    editor = ace.edit(el)\n    editor.setOptions({\n        mode: \"ace/mode/javascript\",\n        theme: theme,\n        autoScrollEditorIntoView: true\n    })\n\n    editor.setValue([\n        \"this is editor number: \", count, \"\\n\",\n        \"using theme \\\"\", theme, \"\\\"\\n\",\n        \":)\"\n    ].join(\"\"), -1)\n\n    scroll()\n}\n\nfunction scroll(speed) {\n    var top = editor.container.getBoundingClientRect().top\n    speed = speed || 10\n    if (top > 60 && speed < 500) {\n        if (speed > top - speed - 50)\n            speed = top - speed - 50\n        else\n            setTimeout(scroll, 10, speed + 10)\n        window.scrollBy(0, speed)\n    }\n}\n\nvar themes = require(\"ace/ext/themelist\").themes.map(function(t){return t.theme});\n\nwindow.add = add;\nwindow.scroll = scroll;\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/settings_menu.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n    \n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/settings_menu\"], function(ace) {\n    var editor = ace.edit(\"editor\");\n    require('ace/ext/settings_menu').init(editor);\n    editor.setTheme(\"ace/theme/twilight\");\n    editor.session.setMode(\"ace/mode/html\");\n\teditor.commands.addCommands([{\n\t\tname: \"showSettingsMenu\",\n\t\tbindKey: {win: \"Ctrl-q\", mac: \"Ctrl-q\"},\n\t\texec: function(editor) {\n\t\t\teditor.showSettingsMenu();\n\t\t},\n\t\treadOnly: true\n\t}]);\n})\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/shadow-dom.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    .scrollmargin {\n        text-align: center;\n    }\n    .large-button {\n        color: lightblue;\n        cursor: pointer;\n        font: 30px arial;\n        padding: 20px;\n        text-align: center;\n        border: medium solid transparent;\n        display: inline-block;\n    }\n    .large-button:hover {\n        border: medium solid lightgray;\n        border-radius: 10px 10px 10px 10px;\n        box-shadow: 0 0 12px 0 lightblue;\n    }\n    body {\n        transform: translateZ(0);\n    }\n  </style>\n</head>\n<body>\n\n<div class=\"scrollmargin\">\n    <span onclick=\"add()\" class=\"large-button\">+</span>\n</div>\n\n<ace-playground></ace-playground>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\nrequire.config({paths: { \"ace\" : \"../src\"}});\nrequire([\"ace/ace\"], function(ace) {\n\nvar dom = require(\"ace/lib/dom\");\n\n\nclass AcePlayground extends HTMLElement {\n    constructor() {\n        super();\n        \n        var shadow = this.attachShadow({mode: \"open\"});\n        \n        var dom = require(\"ace/lib/dom\");\n        dom.buildDom([\"div\", {id: \"host\"},\n            [\"div\", {id: \"html\"}],\n            [\"div\", {id: \"css\"}], \n            [\"iframe\", {id: \"preview\"}],\n            [\"style\", `\n                #host {\n                    border: solid 1px gray;\n                    display: grid;\n                    grid-template-areas: \"html preview\" \"css preview\";\n                }\n                #html {\n                    grid-area: html;\n                    height: 200px;\n                }\n                #css {\n                    grid-area: css;\n                    height: 200px;\n                }\n                #preview {\n                    grid-area: preview;\n                    width: 100%;\n                    height: 100%;\n                    border: none;\n                }\n            `]\n        ], shadow);\n        \n        var htmlEditor = ace.edit(shadow.querySelector(\"#html\"), {\n            theme: \"ace/theme/solarized_light\",\n            mode: \"ace/mode/html\",\n            value: \"<div>\\n\\thollow world!\\n</div>\\n<script><\\/script>\",\n            autoScrollEditorIntoView: true\n        });\n        var cssEditor = ace.edit(shadow.querySelector(\"#css\"), {\n            theme: \"ace/theme/solarized_dark\",\n            mode: \"ace/mode/css\",\n            value: \"*{\\n\\tcolor:red\\n}\",\n            autoScrollEditorIntoView: true\n        });\n        \n        var preview = shadow.querySelector(\"#preview\");\n        \n        this.htmlEditor = htmlEditor;        \n        this.cssEditor = cssEditor;\n        this.preview = preview;\n        \n        htmlEditor.renderer.attachToShadowRoot();\n        \n        this.updatePreview = this.updatePreview.bind(this)\n        htmlEditor.on(\"input\", this.updatePreview);\n        cssEditor.on(\"input\", this.updatePreview);\n    \n        this.updatePreview();\n    }\n    updatePreview() {\n        var code = this.htmlEditor.getValue() + \"<style>\" + this.cssEditor.getValue() + \"</style>\";\n        this.preview.src = \"data:text/html,\" + encodeURIComponent(code)\n    }\n}\n\ncustomElements.define('ace-playground', AcePlayground);\n\nwindow.add = function() {\n    var el = document.createElement(\"ace-playground\");    \n    document.body.appendChild(el);\n};\n\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/show_own_source.js",
    "content": "if (typeof ace == \"undefined\" && typeof require == \"undefined\") {\n    document.body.innerHTML = \"<p style='padding: 20px 50px;'>couldn't find ace.js file, <br>\"\n        + \"to build it run <code>node Makefile.dryice.js full<code>\"\n} else if (typeof ace == \"undefined\" && typeof require != \"undefined\") {\n    require([\"ace/ace\"], function() {\n        setValue();\n    });\n    require([\"ace/config\"], function() {\n        var config = require(\"ace/config\");\n        config.setLoader(function(moduleName, cb) {\n            require([moduleName], function(module) {\n                cb(null, module);\n            });\n        });\n    })\n} else {\n    require = ace.require;\n    setValue()\n}\n\nfunction setValue() {\n    require(\"ace/lib/net\").get(document.baseURI, function(text) {\n        var el = document.getElementById(\"editor\");\n        if (el) el.env.editor.session.setValue(text);\n    });\n    loadAceLinters();\n}\n\nfunction loadAceLinters() {\n    if (typeof  define == \"function\" && define.amd) {\n         require([\n            \"https://mkslanc.github.io/ace-linters/build/ace-linters.js\"\n        ], function(m) {\n            addLinters(m.LanguageProvider);\n        });\n    } else {\n        require(\"ace/lib/net\").loadScript(\n            \"https://mkslanc.github.io/ace-linters/build/ace-linters.js\", \n            function() {\n                addLinters(window.LanguageProvider);\n            }\n        ) \n    }\n    function addLinters(LanguageProvider) {\n        var languageProvider = LanguageProvider.fromCdn(\"https://mkslanc.github.io/ace-linters/build\", {\n            functionality: {\n                hover: true,\n                completion: {\n                    overwriteCompleters: false\n                },\n                completionResolve: true,\n                format: true,\n                documentHighlights: true,\n                signatureHelp: false\n            }\n        });\n        window.languageProvider = languageProvider;\n        document.querySelectorAll(\".ace_editor\").forEach(function(el) {\n            var editor = el.env && el.env.editor;\n            if (editor) {\n                editor.setOption(\"enableBasicAutocompletion\", true)\n                languageProvider.registerEditor(editor);\n            }\n        });\n    }\n}\n\n"
  },
  {
    "path": "demo/static-highlighter/client.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<title>Static Code highlighter using Ace</title>\n\t<meta name=\"author\" content=\"Fabian Jakobs\">\n</head>\n<body>\n\n<h2>Client Side Syntax Highlighting</h2>\n\n<p>Syntax highlighting using Ace language modes and themes.</p>\n    \n<div id=\"code\"></div>\n\n<script type=\"text/javascript\">\n    var require = {\n        paths: {\n            demo: \"..\",\n            ace: \"../../lib/ace\"\n        }\n    };\n</script>\n<script src=\"../kitchen-sink/require.js\"></script>\n<script>\n    \nrequire([\"ace/ext/static_highlight\", \"ace/mode/javascript\", \"ace/theme/twilight\", \"ace/lib/dom\"], function() {\n\n    var highlighter = require(\"ace/ext/static_highlight\");\n    var JavaScriptMode = require(\"ace/mode/javascript\").Mode;\n    var theme = require(\"ace/theme/twilight\");\n    var dom = require(\"ace/lib/dom\");\n\n    var codeEl = document.getElementById(\"code\");\n    var data = document.body.innerHTML;\n\n    var highlighted = highlighter.render(data, new JavaScriptMode(), theme);\n\n    dom.importCssString(highlighted.css, \"ace_highlight\");\n    codeEl.innerHTML = highlighted.html;\n});\n    \n</script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/static-highlighter/server.js",
    "content": "/**\n * Simple node.js server, which generates the synax highlighted version of itself \n * using the Ace modes and themes on the server and serving a static web page.\n */\n\n// include ace search path and modules\nrequire(\"amd-loader\");\n\nvar http = require(\"http\");\nvar fs = require(\"fs\");\nvar resolve = require(\"path\").resolve;\n\n// load the highlighter and the desired mode and theme\nvar highlighter = require(\"../../lib/ace/ext/static_highlight\");\nvar JavaScriptMode = require(\"../../lib/ace/mode/javascript\").Mode;\nvar theme = require(\"../../lib/ace/theme/twilight\");\n\nvar port = process.env.PORT || 2222;\n\nhttp.createServer(function(req, res) {\n    var url = req.url;\n    var path = /[^#?\\x00]*/.exec(url)[0];\n    var root = resolve(__dirname + \"/../../\").replace(/\\\\/g, \"/\");\n    path = resolve(root + \"/\" + path).replace(/\\\\/g, \"/\");\n    if (path.indexOf(root + \"/\") != 0)\n        path = __filename;\n    res.writeHead(200, {\"Content-Type\": \"text/html; charset=utf-8\"});\n    fs.readFile(path, \"utf8\", function(err, data) {\n        if (err) data = err.message;\n        var t = Date.now();\n        var highlighted = highlighter.render(data, new JavaScriptMode(), theme);\n        console.log(\"Rendered \" + (data.length/1000) + \"kb in \" + (Date.now() - t) + \"ms\");\n        res.end(\n            '<html><body>\\n' +\n                '<style type=\"text/css\" media=\"screen\">\\n' +\n                    highlighted.css +\n                '</style>\\n' + \n                highlighted.html +\n            '</body></html>'\n        );\n    });\n}).listen(port);\n\nconsole.log(\"Listening on port \" + port);\n"
  },
  {
    "path": "demo/static-highlighter.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Static Code highlighter using Ace</title>\n    <meta name=\"author\" content=\"Matthew Kastor\">\n    <style type=\"text/css\">\n        .code {\n            width: 50%;\n            white-space: pre-wrap;\n            border: solid lightgrey 1px\n        }\n    </style>\n</head>\n<body>\n\n<h2>Client Side Syntax Highlighting</h2>\n\n<p>Syntax highlighting using Ace language modes and themes.</p>\n\n<div class=\"code\" ace-mode=\"ace/mode/css\" ace-theme=\"ace/theme/chrome\" ace-gutter=\"true\">\n.code {\n    width: 50%;\n    white-space: pre-wrap;\n    border: solid lightgrey 1px\n}\n\n</div>\n\n<pre class=\"code\" ace-mode=\"ace/mode/javascript\" ace-theme=\"ace/theme/twilight\">\nfunction wobble (flam) {\n    return flam.wobbled = true;\n}\n\n</pre>\n\n\n<div class=\"code\" ace-mode=\"ace/mode/lua\" ace-theme=\"ace/theme/chrome\" ace-gutter=\"true\" style=\"width: 30em;\">\n--[[--\nnum_args takes in 5.1 byte code and extracts the number of arguments from its function header.\n--]]--\n\nfunction int(t)\n    return t:byte(1) + t:byte(2) * 0x100 + t:byte(3) * 0x10000 + t:byte(4) * 0x1000000\nend\n\nfunction num_args(func)\n    local dump = string.dump(func)\n    local offset, cursor = int(dump:sub(13)), offset + 26\n    --Get the params and var flag (whether there's a ... in the param)\n    return dump:sub(cursor):byte(), dump:sub(cursor+1):byte()\nend\n\n</div>\n\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\nrequire.config({paths: { \"ace\" : \"../src\"}});\n\nrequire([\"ace/ace\", \"ace/ext/static_highlight\"], function(ace) {\n    var highlight = require(\"ace/ext/static_highlight\")\n    var dom = require(\"ace/lib/dom\")\n    function qsa(sel) {\n        return Array.apply(null, document.querySelectorAll(sel));\n    }\n\n    qsa(\".code\").forEach(function (codeEl) {\n        highlight(codeEl, {\n            mode: codeEl.getAttribute(\"ace-mode\"),\n            theme: codeEl.getAttribute(\"ace-theme\"),\n            firstLineNumber: 1,\n            showGutter: codeEl.getAttribute(\"ace-gutter\"),\n            trim: true\n        }, function (highlighted) {\n            \n        });\n    });\n})\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/statusbar.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ACE Editor StatusBar Demo</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    #editor { \n        margin: 0;\n        position: absolute;\n        top: 0;\n        bottom: 20px;\n        left: 0;\n        right: 0;\n    }\n    #statusBar {\n        margin: 0;\n        padding: 0;\n        position: absolute;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        height: 20px;\n        background-color: rgb(245, 245, 245);\n        color: gray;\n    }\n    .ace_status-indicator {\n        color: gray;\n        position: absolute;\n        right: 0;\n        border-left: 1px solid;\n    }\n  </style>\n</head>\n<body>\n\n<pre id=\"editor\"></pre>\n<div id=\"statusBar\">ace rocks!</div>\n    \n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/statusbar\"], function(ace) {\n    var editor = ace.edit(\"editor\");\n    var StatusBar = require(\"ace/ext/statusbar\").StatusBar;\n    // create a simple selection status indicator\n    var statusBar = new StatusBar(editor, document.getElementById(\"statusBar\"));\n    editor.setTheme(\"ace/theme/dawn\");\n    editor.session.setMode(\"ace/mode/html\");\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "demo/test_ace_builds/index.ts",
    "content": "import * as ace from \"ace-builds\";\nimport {Range, Ace} from \"ace-builds\";\nimport \"ace-builds/src-noconflict/ext-language_tools\";\nimport \"../../src/test/mockdom.js\";\n\nvar HoverTooltip = ace.require(\"ace/tooltip\").HoverTooltip;\nimport \"ace-builds/src-noconflict/mode-javascript\";\nimport \"ace-builds/src-noconflict/theme-monokai\";\nimport {DiffViewOptions } from \"ace-builds/src-noconflict/ext-diff\";\nimport \"ace-builds/src-noconflict/ext-diff\";\nconst diff = ace.require(\"ace/ext/diff\");\n\nconst MarkerGroup = ace.require(\"ace/marker_group\").MarkerGroup;\nconst MouseEvent = ace.require(\"ace/mouse/mouse_event\").MouseEvent;\nvar Tooltip = ace.require(\"ace/tooltip\").Tooltip;\nvar popupManager = ace.require(\"ace/tooltip\").popupManager;\n\nconst editor = ace.edit(null); // should not be an error\neditor.setTheme(\"ace/theme/monokai\");\neditor.session.setMode(\"ace/mode/javascript\");\n\nfunction configure(config: Ace.Config) {\n    config.setDefaultValues(\"editor\", {\n        fontSize: 14,\n        showPrintMargin: false,\n    })\n}\n\nconfigure(ace.config) // should not be a error\n\nconst markerGroup: Ace.MarkerGroup = new MarkerGroup(editor.session);\nconst markers: Ace.MarkerGroupItem[] = [\n    {\n        range: new Range(0, 0, 10, 10),\n        className: \"test-class\"\n    }\n]\nmarkerGroup.setMarkers(markers);\nmarkerGroup.markers.every(marker => {\n    console.log(marker.range);\n    return true;\n});\n\nconst hover: Ace.HoverTooltip = new HoverTooltip();\nhover.setDataProvider((e: any, editor: Ace.Editor) => {\n    const domNode = document.createElement(\"div\");\n    hover.showForRange(editor, new Range(1, 3, 3, 1), domNode, e);\n});\nhover.addToEditor(editor);\n\neditor.commands.on('afterExec', ({editor, command}) => {\n    console.log(editor.getValue(), command.name);\n});\n\neditor.commands.on('exec', ({editor, command}) => {\n    console.log(editor.getValue(), command.name);\n});\n\neditor.container.addEventListener('click', (e: MouseEvent) => {\n    var mouseEvent: Ace.MouseEvent = new MouseEvent(e, editor);\n    mouseEvent.x = e.x * 2;\n});\n\nvar tooltip: Ace.Tooltip = new Tooltip(editor.container);\ntooltip.show('hello');\n\npopupManager.addPopup(tooltip);\n\neditor.destroy && editor.destroy();\n\nconst diffViewOptions: DiffViewOptions =  {\n    maxDiffs: 1000,\n    folding: true\n}\n\nvar diffView = diff.createDiffView({\n    valueB: \"test\",\n    inline: \"b\"\n}, diffViewOptions);\n\ndiffView.setProvider(new diff.DiffProvider());\n\ndiffView.destroy();"
  },
  {
    "path": "demo/test_ace_builds/package.json",
    "content": "{\n  \"name\": \"ace-test-package\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Test package for Ace builds\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"build\": \"tsc -p tsconfig.json\",\n    \"test\": \"node index.js\"\n  },\n  \"dependencies\": {\n    \"ace-builds\": \"file:../../ace-builds-latest.tgz\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.8.2\"\n  }\n}\n"
  },
  {
    "path": "demo/test_ace_builds/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"noImplicitAny\": true,\n    \"strictNullChecks\": true,\n    \"strictFunctionTypes\": true,\n    \"strictBindCallApply\": true,\n    \"strictPropertyInitialization\": true,\n    \"noImplicitThis\": true,\n    \"alwaysStrict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    // \"noUncheckedIndexedAccess\": true,\n    // \"noImplicitOverride\": true,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es2020\",\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"*.ts\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "demo/test_package/index.ts",
    "content": "import * as ace from \"ace-code\";\nimport {EditSession, Range} from \"ace-code\";\nimport {Autocomplete, FilteredList} from \"ace-code/src/autocomplete\";\nimport {beautify} from \"ace-code/src/ext/beautify\";\nimport {registerCodeLensProvider, setLenses} from \"ace-code/src/ext/code_lens\";\nimport {CommandBarTooltip} from \"ace-code/src/ext/command_bar\";\nimport {ElasticTabstopsLite} from \"ace-code/src/ext/elastic_tabstops_lite\";\nimport {MarkerGroup, MarkerGroupItem} from \"ace-code/src/marker_group\";\nimport {HoverTooltip} from \"ace-code/src/tooltip\";\nimport {hardWrap} from \"ace-code/src/ext/hardwrap\";\nimport {SearchBox} from \"ace-code/src/ext/searchbox\";\nimport {themesByName} from 'ace-code/src/ext/themelist';\n\nimport(\"ace-code/src/ext/language_tools\");\nimport \"../../src/test/mockdom.js\";\nimport {tokenize} from \"ace-code/src/ext/simple_tokenizer\";\nimport {JavaScriptHighlightRules} from \"ace-code/src/mode/javascript_highlight_rules\";\nimport {highlight} from \"ace-code/src/ext/static_highlight\";\nimport {createDiffView, DiffProvider, DiffViewOptions} from \"ace-code/src/ext/diff\";\nimport {Mode as HtmlMode} from \"ace-code/src/mode/html\";\n\n// TODO this does not work in node\n// import \"ace-code/esm-resolver\";\nimport { config } from \"ace-code\";\nimport {AcePopup} from \"ace-code/src/autocomplete/popup\";\nconfig.setLoader(async function(moduleName, cb) {\n    moduleName = moduleName.replace(\"ace/\", \"ace-code/src/\")\n    let module = await import(moduleName);\n    cb(null, module);\n});\n\nconst editor = ace.edit(null, {\n    mode: new HtmlMode()\n}); // should not be an error\neditor.setTheme(\"ace/theme/monokai\");\neditor.session.setMode(\"ace/mode/javascript\");\n\nfunction configure(config: ace.Ace.Config) {\n    config.setDefaultValues(\"editor\", {\n        fontSize: 14,\n        showPrintMargin: false,\n    })\n}\n\nconfigure(ace.config) // should not be a error\n\nAutocomplete.for(editor).getCompletionProvider() // should not be an error\n\nconst markerGroup = new MarkerGroup(editor.session);\nconst markers: MarkerGroupItem[] = [\n    {\n        range: new Range(0, 0, 10, 10),\n        className: \"test-class\"\n    }\n]\nmarkerGroup.setMarkers(markers);\nmarkerGroup.markers.every(marker => {\n    console.log(marker.range);\n    return true;\n});\n\nconst hover = new HoverTooltip();\nhover.setDataProvider((e, editor) => {\n    const domNode = document.createElement(\"div\");\n    hover.showForRange(editor, new Range(1, 3, 3, 1), domNode, e);\n});\nhover.addToEditor(editor);\n\nbeautify(editor.session);\n\nregisterCodeLensProvider(editor, {\n    provideCodeLenses: function (session, callback) {\n        const lenses = [{\n            start: {row: 2, column: 1},\n            command: {title: \"2\"}\n        }];\n        setTimeout(function () {\n            callback(null, [{\n                start: {row: 2, column: 1},\n                command: {title: \"2\"}\n            }]);\n\n            setLenses(session, lenses);\n        });\n    }\n});\n\nvar commandBar = new CommandBarTooltip(editor.container);\nvar command: ace.Ace.TooltipCommand = {\n    name: \"test\",\n    exec: function (editor: ace.Editor) {\n        alert(editor.getValue());\n    },\n    type: \"checkbox\"\n}\ncommandBar.registerCommand(\"test\", command);\n\nconst elasticTabStopLite = new ElasticTabstopsLite(editor);\nelasticTabStopLite.processRows([1, 2, 4]);\n\n\nhardWrap(editor, {\n    startRow: 1,\n    endRow: 2,\n});\n\n\nconst searchBox = new SearchBox(editor);\n\nsearchBox.show(\"Test\", true);\n\ntokenize(\"some content\", new JavaScriptHighlightRules());\nhighlight(editor.container, {\n    mode: \"ace/mode/abap\",\n    showGutter: true\n})\n\nsetTimeout(function() {\n    editor.destroy();\n}, 20)\n\nfunction createPopup() {\n    const popup = new AcePopup();\n\n    popup.container.style.width = \"100%\";\n    popup.renderer.textarea.setAttribute(\"tabindex\", \"-1\");\n    popup.setSelectOnHover(true);\n    return popup;\n}\n\nconst acePopup = createPopup();\nconst activeCommand = acePopup.getData(acePopup.getRow());\nif (activeCommand && activeCommand.command && activeCommand.command.name) {\n    acePopup.setData([]);\n}\nacePopup.destroy();\n\nconst filter = new FilteredList([]);\nfilter.setFilter(\"test\");\n\neditor.session.startOperation();\neditor.session.endOperation();\n\neditor.on(\"paste\", (e, emitter) => {\n    if (e.event && e.event.clipboardData) {\n        var htmlString = e.event.clipboardData.getData(\"text/html\")\n        if (htmlString) {\n            e.text = htmlString\n        }\n        if (emitter.session) {\n            console.log(\"no error\");\n        }\n    }\n})\n\neditor.session.on(\"changeMode\", (e, emitter) => {\n    return e && emitter instanceof EditSession\n})\n\nif (themesByName.textmate)\n    console.log(themesByName.textmate.theme);\n\neditor.commands.on('afterExec', ({editor, command}) => {\n    console.log(editor.getValue(), command.name);\n});\n\neditor.commands.on('exec', ({editor, command}) => {\n    console.log(editor.getValue(), command.name);\n});\n\nconst diffViewOptions: DiffViewOptions =  {\n    maxDiffs: 1000,\n    folding: true\n}\n\nvar diffView = createDiffView({\n    valueB: \"test\",\n    inline: \"b\"\n}, diffViewOptions);\n\ndiffView.setProvider(new DiffProvider());\n\ndiffView.destroy();\neditor.setSession(null);\nconsole.log(editor.destroyed);\neditor.destroy();\nconsole.log(editor.destroyed);\n"
  },
  {
    "path": "demo/test_package/package.json",
    "content": "{\n  \"name\": \"ace-test-package\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Test package for Ace\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"build\": \"tsc -p tsconfig.json\",\n    \"test\": \"node index.js\"\n  },\n  \"dependencies\": {\n    \"ace-code\": \"file:../../ace-code-latest.tgz\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.6.2\"\n  }\n}\n"
  },
  {
    "path": "demo/test_package/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"noImplicitAny\": true,\n    \"strictNullChecks\": true,\n    \"strictFunctionTypes\": true,\n    \"strictBindCallApply\": true,\n    \"strictPropertyInitialization\": true,\n    \"noImplicitThis\": true,\n    \"alwaysStrict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    // \"noUncheckedIndexedAccess\": true,\n    // \"noImplicitOverride\": true,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es2020\",\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"*.ts\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "demo/toolbar.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n\n    .ace_editor, .toolbar {\n        border: 1px solid lightgray;\n        margin: auto;\n        width: 80%;\n    } \n    .ace_editor {\n        height: 200px;\n    }\n    </style>\n</head>\n<body>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/language_tools\"], function(ace) {\n    var buildDom = require(\"ace/lib/dom\").buildDom;\n    var editor = ace.edit();\n    editor.setOptions({\n        theme: \"ace/theme/tomorrow_night_eighties\",\n        mode: \"ace/mode/markdown\",\n        maxLines: 30,\n        minLines: 30,\n        autoScrollEditorIntoView: true,\n    });\n    var refs = {};\n    function updateToolbar() {\n        refs.saveButton.disabled = editor.session.getUndoManager().isClean();\n        refs.undoButton.disabled = !editor.session.getUndoManager().hasUndo();\n        refs.redoButton.disabled = !editor.session.getUndoManager().hasRedo();\n    }\n    editor.on(\"input\", updateToolbar);\n    editor.session.setValue(localStorage.savedValue || \"Welcome to ace Toolbar demo!\")\n    function save() {\n        localStorage.savedValue = editor.getValue(); \n        editor.session.getUndoManager().markClean();\n        updateToolbar();\n    }\n    editor.commands.addCommand({\n        name: \"save\",\n        exec: save,\n        bindKey: { win: \"ctrl-s\", mac: \"cmd-s\" }\n    });\n    \n    buildDom([\"div\", { class: \"toolbar\" },\n        [\"button\", {\n            ref: \"saveButton\",\n            onclick: save\n        }, \"save\"],\n        [\"button\", {\n            ref: \"undoButton\",\n            onclick: function() {\n                editor.undo();\n            }\n        }, \"undo\"],\n        [\"button\", {\n            ref: \"redoButton\",\n            onclick: function() {\n                editor.redo();\n            }\n        }, \"redo\"],\n        [\"button\", {\n            style: \"font-weight: bold\",\n            onclick: function() {\n                editor.insertSnippet(\"**${1:$SELECTION}**\");\n                editor.renderer.scrollCursorIntoView()\n            }\n        }, \"bold\"],\n        [\"button\", {\n            style: \"font-style: italic\",\n            onclick: function() {\n                editor.insertSnippet(\"*${1:$SELECTION}*\");\n                editor.renderer.scrollCursorIntoView()\n            }\n        }, \"Italic\"],\n    ], document.body, refs);\n    document.body.appendChild(editor.container)\n    \n    window.editor = editor;\n});\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/transform.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n\n    .ace_editor {\n        border: 1px solid lightgray;\n        margin: auto;\n        height: 800px;\n        width: 400px;\n        font-size: 26px!important;\n        max-width: 30%;\n    }\n    .scrollmargin {\n        height: 80px;\n        text-align: center;\n        \n    }\n    #editor1, #editor2, #editor3 {\n        display:inline-block\n    }\n    .wrapper {\n        text-align: center;\n        perspective: 500px;\n        margin-top: 50px;\n    }\n\n    #editor1 {\n        transform: rotateY(10deg) rotateX(-1deg);\n    }\n    #editor2 {\n        transform: translateZ(-36px) rotateX(-1deg);\n    }\n    #editor3 {\n        transform: rotateY(-10deg) rotateX(-1deg);\n    }\n    #editor4 {\n        transform: scale(-1,1) rotateX(-1deg);\n    }\n    .transformed {\n        transform: scale(0.5);\n        transform-origin: center 12%\n    }\n    #editor {\n        width: 100%;\n        min-width: 100%\n    }\n    body {\n        background: #a9bfc7;\n    }\n    .scrollmargin input > {margin: 10px}\n    </style>\n</head>\n<body>\n<div class=\"transformed\">\n    <div class=\"wrapper\">\n        <pre id=\"editor1\">editor1</pre>\n        <pre id=\"editor2\">editor2</pre>\n        <pre id=\"editor3\">editor3</pre> \n    </div>\n    <div class=\"scrollmargin\"></div>\n    <pre id=\"editor4\">editor4</pre>\n    <div class=\"scrollmargin\">\n        <textarea></textarea>\n    </div>\n    <pre id=\"editor\">editor</pre>\n    <div class=\"scrollmargin\" style=\"transform: scale(2) translateY(3em);\">\n        <input type=\"checkbox\" id=\"option\">Auto scroll into view</input>\n\n        <input type=\"range\" onchange=\"document.body.style.zoom = 1 + value/250\">css Zoom</input>\n        <input type=\"range\" onchange=\"document.body.style.transform = 'rotateZ(' + (this.value * 18) +'deg)'\">css Transform</input>\n    </div>\n</div>\n\n<div class=\"scrollmargin\">\n</div>\n\n<script src=\"kitchen-sink/require.js\"></script>\n<script>\n// setup paths\nrequire.config({paths: { \"ace\" : \"../src\"}});\n// load ace and extensions\nrequire([\"ace/ace\", \"ace/ext/language_tools\"], function(ace) {\n\n    var editor1 = ace.edit(\"editor1\");\n    editor1.setOptions({\n        hasCssTransforms: true,\n        theme: \"ace/theme/tomorrow_night_blue\",\n        mode: \"ace/mode/html\"\n    });\n    \n    var editor2 = ace.edit(\"editor2\", {\n        hasCssTransforms: true,\n        theme: \"ace/theme/kuroir\",\n        mode: \"ace/mode/html\",\n        enableBasicAutocompletion: true,\n    });\n    \n    var editor3 = ace.edit(\"editor3\", {\n        hasCssTransforms: true,\n        theme: \"ace/theme/tomorrow_night_eighties\",\n        mode: \"ace/mode/html\",\n        enableBasicAutocompletion: true,\n    });\n    \n    \n    var editor4 = ace.edit(\"editor4\", {\n        hasCssTransforms: true,\n        theme: \"ace/theme/solarized_light\",\n        mode: \"ace/mode/html\",\n        enableBasicAutocompletion: true,\n    });\n\n    var editor = ace.edit(\"editor\", {\n        hasCssTransforms: true,\n        mode: \"ace/mode/html\",\n        value: \"editor 4\\n from a mirror\",\n        enableBasicAutocompletion: true,\n    });\n    editor.renderer.setScrollMargin(10, 10, 10, 10);\n    \n    \n    var checkbox = document.getElementById(\"option\");\n    checkbox.onchange = function() {\n        editor1.setOption(\"autoScrollEditorIntoView\", checkbox.checked);\n        editor2.setOption(\"autoScrollEditorIntoView\", checkbox.checked);\n        editor3.setOption(\"autoScrollEditorIntoView\", checkbox.checked);\n        editor4.setOption(\"autoScrollEditorIntoView\", checkbox.checked);\n        editor.setOption(\"autoScrollEditorIntoView\", checkbox.checked);\n    };\n    checkbox.onchange();\n    window.editor = editor;\n    window.editor4 = editor4;\n});\n</script>\n\n<script src=\"./show_own_source.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/webpack/demo.js",
    "content": "\"use strict\";\n\n// import ace\nimport ace from '../../build'\n// import Range from ace (it is also available as ace.Range)\nimport {Range, EditSession} from '../../build/'\n\n// import modes that you want to include into your main bundle\nimport \"../../build/src-noconflict/mode-javascript\";\n\n// import webpack resolver to dynamically load modes, you need to install file-loader for this to work!\nimport \"../../build/webpack-resolver\";\n// if you want to allow dynamic loading of only a few modules use setModuleUrl for each of them manually\n/*\nimport jsWorkerUrl from \"file-loader!../../build/src-noconflict/worker-javascript\";\nace.config.setModuleUrl(\"ace/mode/javascript_worker\", jsWorkerUrl)\n*/\n\nvar editor = ace.edit(null, {\n    maxLines: 50,\n    minLines: 10,\n    value: \"var hello = 'world'\" + \"\\n\",\n    mode: \"ace/mode/javascript\",\n    bug: 1\n})\n\neditor.selection.setRange(new Range(0,0,0,3))\n\ndocument.body.appendChild(editor.container)\n\n/*\nimport {Mode as JSMode} from \"../../build/src-noconflict/mode-javascript\"\neditor.setMode( new JSMode())\n*/\n"
  },
  {
    "path": "demo/webpack/demo.ts",
    "content": "\"use strict\";\n\n// import ace\nimport ace from '../../build'\n// import Range from ace (it is also available as ace.Range)\nimport {Range, EditSession} from '../../build/'\n\n// import modes that you want to include into your main bundle\nimport \"../../build/src-noconflict/mode-javascript\";\n\n// import webpack resolver to dynamically load modes, you need to install file-loader for this to work!\nimport \"../../build/webpack-resolver\";\n// if you want to allow dynamic loading of only a few modules use setModuleUrl for each of them manually\n/*\nimport jsWorkerUrl from \"file-loader!../../build/src-noconflict/worker-javascript\";\nace.config.setModuleUrl(\"ace/mode/javascript_worker\", jsWorkerUrl)\n*/\n\nvar editor = ace.edit(null, {\n    maxLines: 50,\n    minLines: 10,\n    value: \"var hello = 'world'\" + \"\\n\",\n    mode: \"ace/mode/javascript\",\n    bug: 1\n})\n\neditor.selection.setRange(new Range(0,0,0,3))\n\ndocument.body.appendChild(editor.container)\n\n/*\nimport {Mode as JSMode} from \"../../build/src-noconflict/mode-javascript\"\neditor.setMode( new JSMode())\n*/\n"
  },
  {
    "path": "demo/webpack/index.html",
    "content": "<!doctype html>\n<meta charset=\"utf-8\">\n<body>\n</body>\n<script src=\"bundle.js\"></script>"
  },
  {
    "path": "demo/webpack/package.json",
    "content": "{\n    \"name\": \"ace-webpack-demo\",\n    \"version\": \"1.0.0\",\n    \"description\": \"\",\n    \"scripts\": {\n        \"start\": \"webpack-dev-server\"\n    },\n    \"keywords\": [],\n    \"author\": \"\",\n    \"dependencies\": {\n        \"file-loader\": \"^1.1.11\",\n        \"webpack\": \"^4.0.1\",\n        \"webpack-cli\": \"^2.0.10\"\n    },\n    \"devDependencies\": {\n        \"webpack-dev-server\": \"^3.1.0\"\n    }\n}\n"
  },
  {
    "path": "demo/webpack/webpack.config.js",
    "content": "\"use strict\";\n\nmodule.exports = {\n    mode: \"development\",\n    entry: \"./demo.js\",\n    output: {\n        path: __dirname + \"/dist\",\n        filename: \"bundle.js\"\n    },\n    node: {\n        global: false,\n        process: false,\n        Buffer: false,\n        __filename: \"mock\",\n        __dirname: \"mock\",\n        setImmediate: false\n    },\n    resolveLoader: {\n        modules: [\n            \"node_modules\", \n            __dirname + \"/node_modules\",\n        ],\n    },\n    devServer: {\n        contentBase: __dirname,\n        compress: true,\n        port: 9000\n    }\n};"
  },
  {
    "path": "demo/xml.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\"></meta>\n    <title>ACE Autocompletion demo</title>\n    <style type=\"text/css\" media=\"screen\">\n        body { overflow: hidden; }\n        #editor {\n            margin: 0; position: absolute;\n            top: 0; bottom: 0; left: 0; right: 0;\n        }\n    </style>\n</head>\n<body>\n    <pre id=\"editor\"></pre>\n\n    <script src=\"kitchen-sink/require.js\"></script>\n    <script><![CDATA[\n    // setup paths\n    require.config({paths: { \"ace\" : \"../src\"}});\n    // load ace and extensions\n    require([\"ace/ace\", \"ace/ext/language_tools\"], function(ace) {\n        var langagueTools = require(\"ace/ext/language_tools\");\n        var editor = ace.edit(\"editor\");\n        editor.session.setMode(\"ace/mode/xml\");\n        editor.setTheme(\"ace/theme/tomorrow\");\n    });    \n    ]]></script>\n\n    <script src=\"./show_own_source.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "doc/README.md",
    "content": "# Introduction\n\nThe API doc build takes a look a source Javascript files in the _lib_ directory, and turns it into HTML output in the _api_ directory. It uses [Panino](https://github.com/gjtorikian/panino-docs) to perform the conversion.\n\nFor any questions on the build system, please see that repo.\n\n# Building\n\nIn the root directory, just run:\n\n    make doc\n\nIn this directory, just run:\n\n    npm install\n    node build.js\n\n"
  },
  {
    "path": "doc/additionalObjs.json",
    "content": "{\n\t\"Array\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array\",\n\t\"Boolean\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean\",\n\t\"Date\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date\",\n\t\"Error\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error\",\n\t\"EvalError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/EvalError\",\n\t\"RangeError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RangeError\",\n\t\"ReferenceError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError\",\n\t\"SyntaxError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/SyntaxError\",\n\t\"TypeError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/TypeError\",\n\t\"URIError\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/URIError\",\n\t\"Function\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function\",\n\t\"Infinity\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Infinity\",\n\t\"JSON\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON\",\n\t\"Math\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math\",\n\t\"NaN\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN\",\n\t\"Number\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number\",\n\t\"Object\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object\",\n\t\"RegExp\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp\",\n\t\"String\" : \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String\",\n    \n    \"DOMElement\": \"https://developer.mozilla.org/en/DOM/element\",\n    \"Event\": \"https://github.com/ajaxorg/ace/blob/master/lib/ace/lib/event.js\",\n    \"TextMode\": \"https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/text.js\",\n    \"KeyBinding\": \"https://github.com/ajaxorg/ace/blob/master/lib/ace/keyboard/keybinding.js\",\n    \"Cursor\": \"https://github.com/ajaxorg/ace/blob/master/lib/ace/layer/cursor.js\"\n}"
  },
  {
    "path": "doc/build.js",
    "content": "var fs = require(\"fs\");\nvar path = require(\"path\");\nvar panino = require(\"panino\");\nvar srcPath = __dirname + \"/../lib/ace\";\nvar buildType = process.argv.splice(2)[0];\n\nvar options = {\n  title       : \"Ace API\",\n  parseType   : \"jsd\",\n  linkFormat  : function(linkHtml) {\n      var href = linkHtml.href;\n      var o = href.match(/(.+)\\.html(#.+)/);\n      var c = href.match(/#(.+)/);\n      \n      if ( o !== null ) {\n          href = href.replace(href, '#nav=api&api=' + o[1]);// + '&section=' + o[2]);\n      }\n      \n      linkHtml.href = href;\n      \n      return linkHtml;\n  },\n  output      : \"../api/\",\n  outputAssets : \"../api/resources\",\n  skin        : \"./template/jade/layout.jade\",\n  assets      : \"./template/resources\",\n  additionalObjs : \"./additionalObjs.json\",\n  exclude     : [\"**/*_test.js\", \"**/mode/**\", \"default_commands.js\", \"multi_select_commands.js\", \"**/test/**\", \"**/theme/**\", \"**/worker/**\"],\n  index       : \"./index.md\"\n};\n\nfiles = [srcPath];\n\npanino.parse(files, options, function (err, ast) {\n  if (err) {\n    console.error(err);\n    process.exit(1);\n  }\n  \n  panino.render(buildType || 'html', ast, options, function (err) {\n    if (err) {\n      console.error(err);\n      process.exit(1);\n    }\n    \n    /*fs.readdir(options.output, function (err, files) {\n        files.forEach(function(file) {\n            if (file.match(/\\.html$/)) {\n                var outFile = options.output + \"/\" + file;\n                fs.readFile(outFile, \"utf8\", function(err, data) {\n                    var otherPageRegExp = new RegExp('<a href=\"(.+?.html)(#.+?)?\"', \"g\");\n                    var m;\n                    \n                    if ( (m = data.match(otherPageRegExp)) ) {\n                        console.log(m)\n                        data = data.replace(otherPageRegExp, '<a href=\"#nav=api&api=' + m[1] + '&section=' + m[2] + '\"')\n                    }\n                    \n                    fs.writeFile(outFile, data, function (err) {\n                      if (err) throw err;\n                    });\n                });\n            }\n        });\n    });*/\n  });\n});"
  },
  {
    "path": "doc/index.md",
    "content": "# Ace API Reference\n\nWelcome to the Ace API Reference Guide. Ace is a standalone code editor written in JavaScript that you can embed onto any website. We're used in a bunch of places already, like GitHub, Google, and Facebook.\n\nOn the left, you'll find a list of all of our currently documented classes. There are plenty more to do, but these represent the \"core\" set. For more information on how to work with Ace, check out the [main Ace website](https://ace.c9.io).\n"
  },
  {
    "path": "doc/package.json",
    "content": "{\n    \"name\": \"ace-api\",\n    \"version\": \"0.1.0\",\n    \"dependencies\": {\n        \"panino\" : \">=2.2.0\",\n        \"asset-smasher\": \"0.2.0\"\n    }\n}"
  },
  {
    "path": "doc/site/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 3.2.1\n *  the iconic font designed for Bootstrap\n *  ------------------------------------------------------------------------------\n *  The full suite of pictographic icons, examples, and documentation can be\n *  found at http://fontawesome.io.  Stay up to date on Twitter at\n *  http://twitter.com/fontawesome.\n *\n *  License\n *  ------------------------------------------------------------------------------\n *  - The Font Awesome font is licensed under SIL OFL 1.1 -\n *    http://scripts.sil.org/OFL\n *  - Font Awesome CSS, LESS, and SASS files are licensed under MIT License -\n *    http://opensource.org/licenses/mit-license.html\n *  - Font Awesome documentation licensed under CC BY 3.0 -\n *    http://creativecommons.org/licenses/by/3.0/\n *  - Attribution is no longer required in Font Awesome 3.0, but much appreciated:\n *    \"Font Awesome by Dave Gandy - http://fontawesome.io\"\n *\n *  Author - Dave Gandy\n *  ------------------------------------------------------------------------------\n *  Email: dave@fontawesome.io\n *  Twitter: http://twitter.com/byscuits\n *  Work: Lead Product Designer @ Kyruus - http://kyruus.com\n */\n/* FONT PATH\n * -------------------------- */\n @font-face {\n  font-family: 'FontAwesome';\n  src: url('../font/fontawesome-webfont.eot?v=3.2.1');\n  src: url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/* FONT AWESOME CORE\n * -------------------------- */\n[class^=\"icon-\"],\n[class*=\" icon-\"] {\n  font-family: FontAwesome;\n  font-weight: normal;\n  font-style: normal;\n  text-decoration: inherit;\n  -webkit-font-smoothing: antialiased;\n  *margin-right: .3em;\n}\n[class^=\"icon-\"]:before,\n[class*=\" icon-\"]:before {\n  text-decoration: inherit;\n  display: inline-block;\n  speak: none;\n}\n/* makes the font 33% larger relative to the icon container */\n.icon-large:before {\n  vertical-align: -10%;\n  font-size: 1.3333333333333333em;\n}\n/* makes sure icons active on rollover in links */\na [class^=\"icon-\"],\na [class*=\" icon-\"] {\n  display: inline;\n}\n/* increased font size for icon-large */\n[class^=\"icon-\"].icon-fixed-width,\n[class*=\" icon-\"].icon-fixed-width {\n  display: inline-block;\n  width: 1.1428571428571428em;\n  text-align: right;\n  padding-right: 0.2857142857142857em;\n}\n[class^=\"icon-\"].icon-fixed-width.icon-large,\n[class*=\" icon-\"].icon-fixed-width.icon-large {\n  width: 1.4285714285714286em;\n}\n.icons-ul {\n  margin-left: 2.142857142857143em;\n  list-style-type: none;\n}\n.icons-ul > li {\n  position: relative;\n}\n.icons-ul .icon-li {\n  position: absolute;\n  left: -2.142857142857143em;\n  width: 2.142857142857143em;\n  text-align: center;\n  line-height: inherit;\n}\n[class^=\"icon-\"].hide,\n[class*=\" icon-\"].hide {\n  display: none;\n}\n.icon-muted {\n  color: #eeeeee;\n}\n.icon-light {\n  color: #ffffff;\n}\n.icon-dark {\n  color: #333333;\n}\n.icon-border {\n  border: solid 1px #eeeeee;\n  padding: .2em .25em .15em;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n.icon-2x {\n  font-size: 2em;\n}\n.icon-2x.icon-border {\n  border-width: 2px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.icon-3x {\n  font-size: 3em;\n}\n.icon-3x.icon-border {\n  border-width: 3px;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n}\n.icon-4x {\n  font-size: 4em;\n}\n.icon-4x.icon-border {\n  border-width: 4px;\n  -webkit-border-radius: 6px;\n  -moz-border-radius: 6px;\n  border-radius: 6px;\n}\n.icon-5x {\n  font-size: 5em;\n}\n.icon-5x.icon-border {\n  border-width: 5px;\n  -webkit-border-radius: 7px;\n  -moz-border-radius: 7px;\n  border-radius: 7px;\n}\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n[class^=\"icon-\"].pull-left,\n[class*=\" icon-\"].pull-left {\n  margin-right: .3em;\n}\n[class^=\"icon-\"].pull-right,\n[class*=\" icon-\"].pull-right {\n  margin-left: .3em;\n}\n/* BOOTSTRAP SPECIFIC CLASSES\n * -------------------------- */\n/* Bootstrap 2.0 sprites.less reset */\n[class^=\"icon-\"],\n[class*=\" icon-\"] {\n  display: inline;\n  width: auto;\n  height: auto;\n  line-height: normal;\n  vertical-align: baseline;\n  background-image: none;\n  background-position: 0% 0%;\n  background-repeat: repeat;\n  margin-top: 0;\n}\n/* more sprites.less reset */\n.icon-white,\n.nav-pills > .active > a > [class^=\"icon-\"],\n.nav-pills > .active > a > [class*=\" icon-\"],\n.nav-list > .active > a > [class^=\"icon-\"],\n.nav-list > .active > a > [class*=\" icon-\"],\n.navbar-inverse .nav > .active > a > [class^=\"icon-\"],\n.navbar-inverse .nav > .active > a > [class*=\" icon-\"],\n.dropdown-menu > li > a:hover > [class^=\"icon-\"],\n.dropdown-menu > li > a:hover > [class*=\" icon-\"],\n.dropdown-menu > .active > a > [class^=\"icon-\"],\n.dropdown-menu > .active > a > [class*=\" icon-\"],\n.dropdown-submenu:hover > a > [class^=\"icon-\"],\n.dropdown-submenu:hover > a > [class*=\" icon-\"] {\n  background-image: none;\n}\n/* keeps Bootstrap styles with and without icons the same */\n.btn [class^=\"icon-\"].icon-large,\n.nav [class^=\"icon-\"].icon-large,\n.btn [class*=\" icon-\"].icon-large,\n.nav [class*=\" icon-\"].icon-large {\n  line-height: .9em;\n}\n.btn [class^=\"icon-\"].icon-spin,\n.nav [class^=\"icon-\"].icon-spin,\n.btn [class*=\" icon-\"].icon-spin,\n.nav [class*=\" icon-\"].icon-spin {\n  display: inline-block;\n}\n.nav-tabs [class^=\"icon-\"],\n.nav-pills [class^=\"icon-\"],\n.nav-tabs [class*=\" icon-\"],\n.nav-pills [class*=\" icon-\"],\n.nav-tabs [class^=\"icon-\"].icon-large,\n.nav-pills [class^=\"icon-\"].icon-large,\n.nav-tabs [class*=\" icon-\"].icon-large,\n.nav-pills [class*=\" icon-\"].icon-large {\n  line-height: .9em;\n}\n.btn [class^=\"icon-\"].pull-left.icon-2x,\n.btn [class*=\" icon-\"].pull-left.icon-2x,\n.btn [class^=\"icon-\"].pull-right.icon-2x,\n.btn [class*=\" icon-\"].pull-right.icon-2x {\n  margin-top: .18em;\n}\n.btn [class^=\"icon-\"].icon-spin.icon-large,\n.btn [class*=\" icon-\"].icon-spin.icon-large {\n  line-height: .8em;\n}\n.btn.btn-small [class^=\"icon-\"].pull-left.icon-2x,\n.btn.btn-small [class*=\" icon-\"].pull-left.icon-2x,\n.btn.btn-small [class^=\"icon-\"].pull-right.icon-2x,\n.btn.btn-small [class*=\" icon-\"].pull-right.icon-2x {\n  margin-top: .25em;\n}\n.btn.btn-large [class^=\"icon-\"],\n.btn.btn-large [class*=\" icon-\"] {\n  margin-top: 0;\n}\n.btn.btn-large [class^=\"icon-\"].pull-left.icon-2x,\n.btn.btn-large [class*=\" icon-\"].pull-left.icon-2x,\n.btn.btn-large [class^=\"icon-\"].pull-right.icon-2x,\n.btn.btn-large [class*=\" icon-\"].pull-right.icon-2x {\n  margin-top: .05em;\n}\n.btn.btn-large [class^=\"icon-\"].pull-left.icon-2x,\n.btn.btn-large [class*=\" icon-\"].pull-left.icon-2x {\n  margin-right: .2em;\n}\n.btn.btn-large [class^=\"icon-\"].pull-right.icon-2x,\n.btn.btn-large [class*=\" icon-\"].pull-right.icon-2x {\n  margin-left: .2em;\n}\n/* Fixes alignment in nav lists */\n.nav-list [class^=\"icon-\"],\n.nav-list [class*=\" icon-\"] {\n  line-height: inherit;\n}\n/* EXTRAS\n * -------------------------- */\n/* Stacked and layered icon */\n.icon-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: -35%;\n}\n.icon-stack [class^=\"icon-\"],\n.icon-stack [class*=\" icon-\"] {\n  display: block;\n  text-align: center;\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  font-size: 1em;\n  line-height: inherit;\n  *line-height: 2em;\n}\n.icon-stack .icon-stack-base {\n  font-size: 2em;\n  *line-height: 1em;\n}\n/* Animated rotating icon */\n.icon-spin {\n  display: inline-block;\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  -webkit-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n}\n/* Prevent stack and spinners from being taken inline when inside a link */\na .icon-stack,\na .icon-spin {\n  display: inline-block;\n  text-decoration: none;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(359deg);\n  }\n}\n@-ms-keyframes spin {\n  0% {\n    -ms-transform: rotate(0deg);\n  }\n  100% {\n    -ms-transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(359deg);\n  }\n}\n/* Icon rotations and mirroring */\n.icon-rotate-90:before {\n  -webkit-transform: rotate(90deg);\n  -moz-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  -o-transform: rotate(90deg);\n  transform: rotate(90deg);\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n}\n.icon-rotate-180:before {\n  -webkit-transform: rotate(180deg);\n  -moz-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  -o-transform: rotate(180deg);\n  transform: rotate(180deg);\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n}\n.icon-rotate-270:before {\n  -webkit-transform: rotate(270deg);\n  -moz-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  -o-transform: rotate(270deg);\n  transform: rotate(270deg);\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n}\n.icon-flip-horizontal:before {\n  -webkit-transform: scale(-1, 1);\n  -moz-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  -o-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.icon-flip-vertical:before {\n  -webkit-transform: scale(1, -1);\n  -moz-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  -o-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n/* ensure rotation occurs inside anchor tags */\na .icon-rotate-90:before,\na .icon-rotate-180:before,\na .icon-rotate-270:before,\na .icon-flip-horizontal:before,\na .icon-flip-vertical:before {\n  display: inline-block;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.icon-glass:before {\n  content: \"\\f000\";\n}\n.icon-music:before {\n  content: \"\\f001\";\n}\n.icon-search:before {\n  content: \"\\f002\";\n}\n.icon-envelope-alt:before {\n  content: \"\\f003\";\n}\n.icon-heart:before {\n  content: \"\\f004\";\n}\n.icon-star:before {\n  content: \"\\f005\";\n}\n.icon-star-empty:before {\n  content: \"\\f006\";\n}\n.icon-user:before {\n  content: \"\\f007\";\n}\n.icon-film:before {\n  content: \"\\f008\";\n}\n.icon-th-large:before {\n  content: \"\\f009\";\n}\n.icon-th:before {\n  content: \"\\f00a\";\n}\n.icon-th-list:before {\n  content: \"\\f00b\";\n}\n.icon-ok:before {\n  content: \"\\f00c\";\n}\n.icon-remove:before {\n  content: \"\\f00d\";\n}\n.icon-zoom-in:before {\n  content: \"\\f00e\";\n}\n.icon-zoom-out:before {\n  content: \"\\f010\";\n}\n.icon-power-off:before,\n.icon-off:before {\n  content: \"\\f011\";\n}\n.icon-signal:before {\n  content: \"\\f012\";\n}\n.icon-gear:before,\n.icon-cog:before {\n  content: \"\\f013\";\n}\n.icon-trash:before {\n  content: \"\\f014\";\n}\n.icon-home:before {\n  content: \"\\f015\";\n}\n.icon-file-alt:before {\n  content: \"\\f016\";\n}\n.icon-time:before {\n  content: \"\\f017\";\n}\n.icon-road:before {\n  content: \"\\f018\";\n}\n.icon-download-alt:before {\n  content: \"\\f019\";\n}\n.icon-download:before {\n  content: \"\\f01a\";\n}\n.icon-upload:before {\n  content: \"\\f01b\";\n}\n.icon-inbox:before {\n  content: \"\\f01c\";\n}\n.icon-play-circle:before {\n  content: \"\\f01d\";\n}\n.icon-rotate-right:before,\n.icon-repeat:before {\n  content: \"\\f01e\";\n}\n.icon-refresh:before {\n  content: \"\\f021\";\n}\n.icon-list-alt:before {\n  content: \"\\f022\";\n}\n.icon-lock:before {\n  content: \"\\f023\";\n}\n.icon-flag:before {\n  content: \"\\f024\";\n}\n.icon-headphones:before {\n  content: \"\\f025\";\n}\n.icon-volume-off:before {\n  content: \"\\f026\";\n}\n.icon-volume-down:before {\n  content: \"\\f027\";\n}\n.icon-volume-up:before {\n  content: \"\\f028\";\n}\n.icon-qrcode:before {\n  content: \"\\f029\";\n}\n.icon-barcode:before {\n  content: \"\\f02a\";\n}\n.icon-tag:before {\n  content: \"\\f02b\";\n}\n.icon-tags:before {\n  content: \"\\f02c\";\n}\n.icon-book:before {\n  content: \"\\f02d\";\n}\n.icon-bookmark:before {\n  content: \"\\f02e\";\n}\n.icon-print:before {\n  content: \"\\f02f\";\n}\n.icon-camera:before {\n  content: \"\\f030\";\n}\n.icon-font:before {\n  content: \"\\f031\";\n}\n.icon-bold:before {\n  content: \"\\f032\";\n}\n.icon-italic:before {\n  content: \"\\f033\";\n}\n.icon-text-height:before {\n  content: \"\\f034\";\n}\n.icon-text-width:before {\n  content: \"\\f035\";\n}\n.icon-align-left:before {\n  content: \"\\f036\";\n}\n.icon-align-center:before {\n  content: \"\\f037\";\n}\n.icon-align-right:before {\n  content: \"\\f038\";\n}\n.icon-align-justify:before {\n  content: \"\\f039\";\n}\n.icon-list:before {\n  content: \"\\f03a\";\n}\n.icon-indent-left:before {\n  content: \"\\f03b\";\n}\n.icon-indent-right:before {\n  content: \"\\f03c\";\n}\n.icon-facetime-video:before {\n  content: \"\\f03d\";\n}\n.icon-picture:before {\n  content: \"\\f03e\";\n}\n.icon-pencil:before {\n  content: \"\\f040\";\n}\n.icon-map-marker:before {\n  content: \"\\f041\";\n}\n.icon-adjust:before {\n  content: \"\\f042\";\n}\n.icon-tint:before {\n  content: \"\\f043\";\n}\n.icon-edit:before {\n  content: \"\\f044\";\n}\n.icon-share:before {\n  content: \"\\f045\";\n}\n.icon-check:before {\n  content: \"\\f046\";\n}\n.icon-move:before {\n  content: \"\\f047\";\n}\n.icon-step-backward:before {\n  content: \"\\f048\";\n}\n.icon-fast-backward:before {\n  content: \"\\f049\";\n}\n.icon-backward:before {\n  content: \"\\f04a\";\n}\n.icon-play:before {\n  content: \"\\f04b\";\n}\n.icon-pause:before {\n  content: \"\\f04c\";\n}\n.icon-stop:before {\n  content: \"\\f04d\";\n}\n.icon-forward:before {\n  content: \"\\f04e\";\n}\n.icon-fast-forward:before {\n  content: \"\\f050\";\n}\n.icon-step-forward:before {\n  content: \"\\f051\";\n}\n.icon-eject:before {\n  content: \"\\f052\";\n}\n.icon-chevron-left:before {\n  content: \"\\f053\";\n}\n.icon-chevron-right:before {\n  content: \"\\f054\";\n}\n.icon-plus-sign:before {\n  content: \"\\f055\";\n}\n.icon-minus-sign:before {\n  content: \"\\f056\";\n}\n.icon-remove-sign:before {\n  content: \"\\f057\";\n}\n.icon-ok-sign:before {\n  content: \"\\f058\";\n}\n.icon-question-sign:before {\n  content: \"\\f059\";\n}\n.icon-info-sign:before {\n  content: \"\\f05a\";\n}\n.icon-screenshot:before {\n  content: \"\\f05b\";\n}\n.icon-remove-circle:before {\n  content: \"\\f05c\";\n}\n.icon-ok-circle:before {\n  content: \"\\f05d\";\n}\n.icon-ban-circle:before {\n  content: \"\\f05e\";\n}\n.icon-arrow-left:before {\n  content: \"\\f060\";\n}\n.icon-arrow-right:before {\n  content: \"\\f061\";\n}\n.icon-arrow-up:before {\n  content: \"\\f062\";\n}\n.icon-arrow-down:before {\n  content: \"\\f063\";\n}\n.icon-mail-forward:before,\n.icon-share-alt:before {\n  content: \"\\f064\";\n}\n.icon-resize-full:before {\n  content: \"\\f065\";\n}\n.icon-resize-small:before {\n  content: \"\\f066\";\n}\n.icon-plus:before {\n  content: \"\\f067\";\n}\n.icon-minus:before {\n  content: \"\\f068\";\n}\n.icon-asterisk:before {\n  content: \"\\f069\";\n}\n.icon-exclamation-sign:before {\n  content: \"\\f06a\";\n}\n.icon-gift:before {\n  content: \"\\f06b\";\n}\n.icon-leaf:before {\n  content: \"\\f06c\";\n}\n.icon-fire:before {\n  content: \"\\f06d\";\n}\n.icon-eye-open:before {\n  content: \"\\f06e\";\n}\n.icon-eye-close:before {\n  content: \"\\f070\";\n}\n.icon-warning-sign:before {\n  content: \"\\f071\";\n}\n.icon-plane:before {\n  content: \"\\f072\";\n}\n.icon-calendar:before {\n  content: \"\\f073\";\n}\n.icon-random:before {\n  content: \"\\f074\";\n}\n.icon-comment:before {\n  content: \"\\f075\";\n}\n.icon-magnet:before {\n  content: \"\\f076\";\n}\n.icon-chevron-up:before {\n  content: \"\\f077\";\n}\n.icon-chevron-down:before {\n  content: \"\\f078\";\n}\n.icon-retweet:before {\n  content: \"\\f079\";\n}\n.icon-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.icon-folder-close:before {\n  content: \"\\f07b\";\n}\n.icon-folder-open:before {\n  content: \"\\f07c\";\n}\n.icon-resize-vertical:before {\n  content: \"\\f07d\";\n}\n.icon-resize-horizontal:before {\n  content: \"\\f07e\";\n}\n.icon-bar-chart:before {\n  content: \"\\f080\";\n}\n.icon-twitter-sign:before {\n  content: \"\\f081\";\n}\n.icon-facebook-sign:before {\n  content: \"\\f082\";\n}\n.icon-camera-retro:before {\n  content: \"\\f083\";\n}\n.icon-key:before {\n  content: \"\\f084\";\n}\n.icon-gears:before,\n.icon-cogs:before {\n  content: \"\\f085\";\n}\n.icon-comments:before {\n  content: \"\\f086\";\n}\n.icon-thumbs-up-alt:before {\n  content: \"\\f087\";\n}\n.icon-thumbs-down-alt:before {\n  content: \"\\f088\";\n}\n.icon-star-half:before {\n  content: \"\\f089\";\n}\n.icon-heart-empty:before {\n  content: \"\\f08a\";\n}\n.icon-signout:before {\n  content: \"\\f08b\";\n}\n.icon-linkedin-sign:before {\n  content: \"\\f08c\";\n}\n.icon-pushpin:before {\n  content: \"\\f08d\";\n}\n.icon-external-link:before {\n  content: \"\\f08e\";\n}\n.icon-signin:before {\n  content: \"\\f090\";\n}\n.icon-trophy:before {\n  content: \"\\f091\";\n}\n.icon-github-sign:before {\n  content: \"\\f092\";\n}\n.icon-upload-alt:before {\n  content: \"\\f093\";\n}\n.icon-lemon:before {\n  content: \"\\f094\";\n}\n.icon-phone:before {\n  content: \"\\f095\";\n}\n.icon-unchecked:before,\n.icon-check-empty:before {\n  content: \"\\f096\";\n}\n.icon-bookmark-empty:before {\n  content: \"\\f097\";\n}\n.icon-phone-sign:before {\n  content: \"\\f098\";\n}\n.icon-twitter:before {\n  content: \"\\f099\";\n}\n.icon-facebook:before {\n  content: \"\\f09a\";\n}\n.icon-github:before {\n  content: \"\\f09b\";\n}\n.icon-unlock:before {\n  content: \"\\f09c\";\n}\n.icon-credit-card:before {\n  content: \"\\f09d\";\n}\n.icon-rss:before {\n  content: \"\\f09e\";\n}\n.icon-hdd:before {\n  content: \"\\f0a0\";\n}\n.icon-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.icon-bell:before {\n  content: \"\\f0a2\";\n}\n.icon-certificate:before {\n  content: \"\\f0a3\";\n}\n.icon-hand-right:before {\n  content: \"\\f0a4\";\n}\n.icon-hand-left:before {\n  content: \"\\f0a5\";\n}\n.icon-hand-up:before {\n  content: \"\\f0a6\";\n}\n.icon-hand-down:before {\n  content: \"\\f0a7\";\n}\n.icon-circle-arrow-left:before {\n  content: \"\\f0a8\";\n}\n.icon-circle-arrow-right:before {\n  content: \"\\f0a9\";\n}\n.icon-circle-arrow-up:before {\n  content: \"\\f0aa\";\n}\n.icon-circle-arrow-down:before {\n  content: \"\\f0ab\";\n}\n.icon-globe:before {\n  content: \"\\f0ac\";\n}\n.icon-wrench:before {\n  content: \"\\f0ad\";\n}\n.icon-tasks:before {\n  content: \"\\f0ae\";\n}\n.icon-filter:before {\n  content: \"\\f0b0\";\n}\n.icon-briefcase:before {\n  content: \"\\f0b1\";\n}\n.icon-fullscreen:before {\n  content: \"\\f0b2\";\n}\n.icon-group:before {\n  content: \"\\f0c0\";\n}\n.icon-link:before {\n  content: \"\\f0c1\";\n}\n.icon-cloud:before {\n  content: \"\\f0c2\";\n}\n.icon-beaker:before {\n  content: \"\\f0c3\";\n}\n.icon-cut:before {\n  content: \"\\f0c4\";\n}\n.icon-copy:before {\n  content: \"\\f0c5\";\n}\n.icon-paperclip:before,\n.icon-paper-clip:before {\n  content: \"\\f0c6\";\n}\n.icon-save:before {\n  content: \"\\f0c7\";\n}\n.icon-sign-blank:before {\n  content: \"\\f0c8\";\n}\n.icon-reorder:before {\n  content: \"\\f0c9\";\n}\n.icon-list-ul:before {\n  content: \"\\f0ca\";\n}\n.icon-list-ol:before {\n  content: \"\\f0cb\";\n}\n.icon-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.icon-underline:before {\n  content: \"\\f0cd\";\n}\n.icon-table:before {\n  content: \"\\f0ce\";\n}\n.icon-magic:before {\n  content: \"\\f0d0\";\n}\n.icon-truck:before {\n  content: \"\\f0d1\";\n}\n.icon-pinterest:before {\n  content: \"\\f0d2\";\n}\n.icon-pinterest-sign:before {\n  content: \"\\f0d3\";\n}\n.icon-google-plus-sign:before {\n  content: \"\\f0d4\";\n}\n.icon-google-plus:before {\n  content: \"\\f0d5\";\n}\n.icon-money:before {\n  content: \"\\f0d6\";\n}\n.icon-caret-down:before {\n  content: \"\\f0d7\";\n}\n.icon-caret-up:before {\n  content: \"\\f0d8\";\n}\n.icon-caret-left:before {\n  content: \"\\f0d9\";\n}\n.icon-caret-right:before {\n  content: \"\\f0da\";\n}\n.icon-columns:before {\n  content: \"\\f0db\";\n}\n.icon-sort:before {\n  content: \"\\f0dc\";\n}\n.icon-sort-down:before {\n  content: \"\\f0dd\";\n}\n.icon-sort-up:before {\n  content: \"\\f0de\";\n}\n.icon-envelope:before {\n  content: \"\\f0e0\";\n}\n.icon-linkedin:before {\n  content: \"\\f0e1\";\n}\n.icon-rotate-left:before,\n.icon-undo:before {\n  content: \"\\f0e2\";\n}\n.icon-legal:before {\n  content: \"\\f0e3\";\n}\n.icon-dashboard:before {\n  content: \"\\f0e4\";\n}\n.icon-comment-alt:before {\n  content: \"\\f0e5\";\n}\n.icon-comments-alt:before {\n  content: \"\\f0e6\";\n}\n.icon-bolt:before {\n  content: \"\\f0e7\";\n}\n.icon-sitemap:before {\n  content: \"\\f0e8\";\n}\n.icon-umbrella:before {\n  content: \"\\f0e9\";\n}\n.icon-paste:before {\n  content: \"\\f0ea\";\n}\n.icon-lightbulb:before {\n  content: \"\\f0eb\";\n}\n.icon-exchange:before {\n  content: \"\\f0ec\";\n}\n.icon-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.icon-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.icon-user-md:before {\n  content: \"\\f0f0\";\n}\n.icon-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.icon-suitcase:before {\n  content: \"\\f0f2\";\n}\n.icon-bell-alt:before {\n  content: \"\\f0f3\";\n}\n.icon-coffee:before {\n  content: \"\\f0f4\";\n}\n.icon-food:before {\n  content: \"\\f0f5\";\n}\n.icon-file-text-alt:before {\n  content: \"\\f0f6\";\n}\n.icon-building:before {\n  content: \"\\f0f7\";\n}\n.icon-hospital:before {\n  content: \"\\f0f8\";\n}\n.icon-ambulance:before {\n  content: \"\\f0f9\";\n}\n.icon-medkit:before {\n  content: \"\\f0fa\";\n}\n.icon-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.icon-beer:before {\n  content: \"\\f0fc\";\n}\n.icon-h-sign:before {\n  content: \"\\f0fd\";\n}\n.icon-plus-sign-alt:before {\n  content: \"\\f0fe\";\n}\n.icon-double-angle-left:before {\n  content: \"\\f100\";\n}\n.icon-double-angle-right:before {\n  content: \"\\f101\";\n}\n.icon-double-angle-up:before {\n  content: \"\\f102\";\n}\n.icon-double-angle-down:before {\n  content: \"\\f103\";\n}\n.icon-angle-left:before {\n  content: \"\\f104\";\n}\n.icon-angle-right:before {\n  content: \"\\f105\";\n}\n.icon-angle-up:before {\n  content: \"\\f106\";\n}\n.icon-angle-down:before {\n  content: \"\\f107\";\n}\n.icon-desktop:before {\n  content: \"\\f108\";\n}\n.icon-laptop:before {\n  content: \"\\f109\";\n}\n.icon-tablet:before {\n  content: \"\\f10a\";\n}\n.icon-mobile-phone:before {\n  content: \"\\f10b\";\n}\n.icon-circle-blank:before {\n  content: \"\\f10c\";\n}\n.icon-quote-left:before {\n  content: \"\\f10d\";\n}\n.icon-quote-right:before {\n  content: \"\\f10e\";\n}\n.icon-spinner:before {\n  content: \"\\f110\";\n}\n.icon-circle:before {\n  content: \"\\f111\";\n}\n.icon-mail-reply:before,\n.icon-reply:before {\n  content: \"\\f112\";\n}\n.icon-github-alt:before {\n  content: \"\\f113\";\n}\n.icon-folder-close-alt:before {\n  content: \"\\f114\";\n}\n.icon-folder-open-alt:before {\n  content: \"\\f115\";\n}\n.icon-expand-alt:before {\n  content: \"\\f116\";\n}\n.icon-collapse-alt:before {\n  content: \"\\f117\";\n}\n.icon-smile:before {\n  content: \"\\f118\";\n}\n.icon-frown:before {\n  content: \"\\f119\";\n}\n.icon-meh:before {\n  content: \"\\f11a\";\n}\n.icon-gamepad:before {\n  content: \"\\f11b\";\n}\n.icon-keyboard:before {\n  content: \"\\f11c\";\n}\n.icon-flag-alt:before {\n  content: \"\\f11d\";\n}\n.icon-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.icon-terminal:before {\n  content: \"\\f120\";\n}\n.icon-code:before {\n  content: \"\\f121\";\n}\n.icon-reply-all:before {\n  content: \"\\f122\";\n}\n.icon-mail-reply-all:before {\n  content: \"\\f122\";\n}\n.icon-star-half-full:before,\n.icon-star-half-empty:before {\n  content: \"\\f123\";\n}\n.icon-location-arrow:before {\n  content: \"\\f124\";\n}\n.icon-crop:before {\n  content: \"\\f125\";\n}\n.icon-code-fork:before {\n  content: \"\\f126\";\n}\n.icon-unlink:before {\n  content: \"\\f127\";\n}\n.icon-question:before {\n  content: \"\\f128\";\n}\n.icon-info:before {\n  content: \"\\f129\";\n}\n.icon-exclamation:before {\n  content: \"\\f12a\";\n}\n.icon-superscript:before {\n  content: \"\\f12b\";\n}\n.icon-subscript:before {\n  content: \"\\f12c\";\n}\n.icon-eraser:before {\n  content: \"\\f12d\";\n}\n.icon-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.icon-microphone:before {\n  content: \"\\f130\";\n}\n.icon-microphone-off:before {\n  content: \"\\f131\";\n}\n.icon-shield:before {\n  content: \"\\f132\";\n}\n.icon-calendar-empty:before {\n  content: \"\\f133\";\n}\n.icon-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.icon-rocket:before {\n  content: \"\\f135\";\n}\n.icon-maxcdn:before {\n  content: \"\\f136\";\n}\n.icon-chevron-sign-left:before {\n  content: \"\\f137\";\n}\n.icon-chevron-sign-right:before {\n  content: \"\\f138\";\n}\n.icon-chevron-sign-up:before {\n  content: \"\\f139\";\n}\n.icon-chevron-sign-down:before {\n  content: \"\\f13a\";\n}\n.icon-html5:before {\n  content: \"\\f13b\";\n}\n.icon-css3:before {\n  content: \"\\f13c\";\n}\n.icon-anchor:before {\n  content: \"\\f13d\";\n}\n.icon-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.icon-bullseye:before {\n  content: \"\\f140\";\n}\n.icon-ellipsis-horizontal:before {\n  content: \"\\f141\";\n}\n.icon-ellipsis-vertical:before {\n  content: \"\\f142\";\n}\n.icon-rss-sign:before {\n  content: \"\\f143\";\n}\n.icon-play-sign:before {\n  content: \"\\f144\";\n}\n.icon-ticket:before {\n  content: \"\\f145\";\n}\n.icon-minus-sign-alt:before {\n  content: \"\\f146\";\n}\n.icon-check-minus:before {\n  content: \"\\f147\";\n}\n.icon-level-up:before {\n  content: \"\\f148\";\n}\n.icon-level-down:before {\n  content: \"\\f149\";\n}\n.icon-check-sign:before {\n  content: \"\\f14a\";\n}\n.icon-edit-sign:before {\n  content: \"\\f14b\";\n}\n.icon-external-link-sign:before {\n  content: \"\\f14c\";\n}\n.icon-share-sign:before {\n  content: \"\\f14d\";\n}\n.icon-compass:before {\n  content: \"\\f14e\";\n}\n.icon-collapse:before {\n  content: \"\\f150\";\n}\n.icon-collapse-top:before {\n  content: \"\\f151\";\n}\n.icon-expand:before {\n  content: \"\\f152\";\n}\n.icon-euro:before,\n.icon-eur:before {\n  content: \"\\f153\";\n}\n.icon-gbp:before {\n  content: \"\\f154\";\n}\n.icon-dollar:before,\n.icon-usd:before {\n  content: \"\\f155\";\n}\n.icon-rupee:before,\n.icon-inr:before {\n  content: \"\\f156\";\n}\n.icon-yen:before,\n.icon-jpy:before {\n  content: \"\\f157\";\n}\n.icon-renminbi:before,\n.icon-cny:before {\n  content: \"\\f158\";\n}\n.icon-won:before,\n.icon-krw:before {\n  content: \"\\f159\";\n}\n.icon-bitcoin:before,\n.icon-btc:before {\n  content: \"\\f15a\";\n}\n.icon-file:before {\n  content: \"\\f15b\";\n}\n.icon-file-text:before {\n  content: \"\\f15c\";\n}\n.icon-sort-by-alphabet:before {\n  content: \"\\f15d\";\n}\n.icon-sort-by-alphabet-alt:before {\n  content: \"\\f15e\";\n}\n.icon-sort-by-attributes:before {\n  content: \"\\f160\";\n}\n.icon-sort-by-attributes-alt:before {\n  content: \"\\f161\";\n}\n.icon-sort-by-order:before {\n  content: \"\\f162\";\n}\n.icon-sort-by-order-alt:before {\n  content: \"\\f163\";\n}\n.icon-thumbs-up:before {\n  content: \"\\f164\";\n}\n.icon-thumbs-down:before {\n  content: \"\\f165\";\n}\n.icon-youtube-sign:before {\n  content: \"\\f166\";\n}\n.icon-youtube:before {\n  content: \"\\f167\";\n}\n.icon-xing:before {\n  content: \"\\f168\";\n}\n.icon-xing-sign:before {\n  content: \"\\f169\";\n}\n.icon-youtube-play:before {\n  content: \"\\f16a\";\n}\n.icon-dropbox:before {\n  content: \"\\f16b\";\n}\n.icon-stackexchange:before {\n  content: \"\\f16c\";\n}\n.icon-instagram:before {\n  content: \"\\f16d\";\n}\n.icon-flickr:before {\n  content: \"\\f16e\";\n}\n.icon-adn:before {\n  content: \"\\f170\";\n}\n.icon-bitbucket:before {\n  content: \"\\f171\";\n}\n.icon-bitbucket-sign:before {\n  content: \"\\f172\";\n}\n.icon-tumblr:before {\n  content: \"\\f173\";\n}\n.icon-tumblr-sign:before {\n  content: \"\\f174\";\n}\n.icon-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.icon-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.icon-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.icon-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.icon-apple:before {\n  content: \"\\f179\";\n}\n.icon-windows:before {\n  content: \"\\f17a\";\n}\n.icon-android:before {\n  content: \"\\f17b\";\n}\n.icon-linux:before {\n  content: \"\\f17c\";\n}\n.icon-dribbble:before {\n  content: \"\\f17d\";\n}\n.icon-skype:before {\n  content: \"\\f17e\";\n}\n.icon-foursquare:before {\n  content: \"\\f180\";\n}\n.icon-trello:before {\n  content: \"\\f181\";\n}\n.icon-female:before {\n  content: \"\\f182\";\n}\n.icon-male:before {\n  content: \"\\f183\";\n}\n.icon-gittip:before {\n  content: \"\\f184\";\n}\n.icon-sun:before {\n  content: \"\\f185\";\n}\n.icon-moon:before {\n  content: \"\\f186\";\n}\n.icon-archive:before {\n  content: \"\\f187\";\n}\n.icon-bug:before {\n  content: \"\\f188\";\n}\n.icon-vk:before {\n  content: \"\\f189\";\n}\n.icon-weibo:before {\n  content: \"\\f18a\";\n}\n.icon-renren:before {\n  content: \"\\f18b\";\n}"
  },
  {
    "path": "doc/site/iphone.css",
    "content": "#wrapper {\n    position:relative;\n    overflow:hidden;\n}\n\n#wrapper .content .column1 {\n    margin:0 16px 0 15px;\n}\n\n#header .content .signature {\n    font-size:18px;\n    bottom:0;\n}\n\nUL.menu-list LI {\n    font-size:22px;\n}\n\nUL.menu-footer LI {\n    font-size:22px;\n}\n\nPRE{\n    font-size:22px;\n}"
  },
  {
    "path": "doc/site/js/ga.js",
    "content": " var _gaq = _gaq || [];\n _gaq.push(['_setAccount', 'UA-31998201-1']);\n _gaq.push(['_trackPageview']);\n \n (function() {\n   var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n   var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n })();"
  },
  {
    "path": "doc/site/js/main.js",
    "content": "var editor;\nvar embedded_editor;\n$(function() {\n    if (typeof ace !== \"undefined\") {\n        ace.config.set(\"workerPath\", \"build/src-min\");\n        editor = ace.edit(\"ace_editor_demo\");\n        editor.container.style.opacity = \"\";\n        embedded_editor = ace.edit(\"embedded_ace_code\");\n        embedded_editor.container.style.opacity = \"\";\n        embedded_editor.session.setMode(\"ace/mode/html\");\n        embedded_editor.setAutoScrollEditorIntoView(true);\n        embedded_editor.setOption(\"maxLines\", 40);\n        \n        editor.setOptions({\n            maxLines: 30,\n            mode: \"ace/mode/javascript\",\n            autoScrollEditorIntoView: true\n        });\n        \n        ace.config.loadModule(\"ace/ext/language_tools\", function() {\n            embedded_editor.setOptions({\n                enableSnippets: true,\n                enableBasicAutocompletion: true\n            });\n            editor.setOptions({\n                enableSnippets: true,\n                enableBasicAutocompletion: true\n            });\n        });\n    } else {\n        document.body.insertAdjacentHTML(\"afterbegin\", '<div class=\"bs-docs-example\">\\\n            <div class=\"alert alert-error\">\\\n              <button type=\"button\" class=\"close\" data-dismiss=\"alert\">\\xd7</button>\\\n              <strong>Oh No!</strong> Couldn\\'t load <code>build/src/ace.js</code>.<br>\\\n                You can build it by running <code>npm install ; node Makefile.dryice.js</code><br>\\\n                Or download older version by running <code>git submodule update --init --recursive</code><br>\\\n            </div>\\\n          </div>');\n    }\n    $(\"ul.menu-list\").mousedown(function(e) {\n        if (e.button === 1) {\n            e.preventDefault();\n        }\n    });\n    \n    $(\"ul.menu-list li\").on(\"click auxclick\", function(e) {\n        if (e.target.tagName !== \"A\") {\n            var href = $(this).find(\"a\").attr(\"href\");\n            if (e.originalEvent.button == 1)\n                window.open(href, \"_blank\");\n            else if (e.originalEvent.button == 0)\n                window.location = href;\n        }\n    });\n    \n    // used when page is access directly\n    function magicClickInterceptor(e) {\n        e.preventDefault();\n            \n        var state = {};\n        state.api = $(this).attr(\"href\").substring(6, $(this).attr(\"href\").length - 5);\n        $.bbq.pushState(state);\n        \n        var _self = $(this);\n        $(\"#apiHolder\").load($(this).attr(\"href\") + \" #documentation\", function(){\n        $(\"#apiHolder\").removeClass(\"apiIntro\").removeClass(\"span9\");\n        $(\"#documentation\").removeClass(\"span9\").addClass(\"span7\");\n            ux();\n            setupClicker();\n        \n            // handles dropping in from new link\n            var section = $.bbq.getState(\"section\");\n            if (section) {\n                $(\"li#dropdown_\" + section.replace(/\\./g, '\\\\.') + \" a\").triggerHandler('click');\n            }\n            \n            //setupDisqus(_self.attr(\"href\"));\n        });\n    }\n    \n    $('.menu-item a').click(magicClickInterceptor);\n    $('a.argument').click(magicClickInterceptor);\n    \n    $('a.external').click(function(e) {\n        e.preventDefault();\n    });\n\n    var tabs = $(\"#tabnav\"),\n        tab_a_selector = \"a\";\n\n    var firstLoad = true;\n     \n    tabs.find(tab_a_selector).click(function(e) {\n        if ($(this).attr(\"href\").indexOf(\"http\") === 0) {\n            return;\n        }\n\n        e.preventDefault();\n        if ($(this).attr(\"href\") === \"/\") {\n            window.location = \"https://ace.c9.io\";\n            return;\n        }\n        if ($(this).attr(\"href\").indexOf(\"#api\") === 0) {\n            $(\"#top_container\").addClass(\"collapse\");\n            scrollIntoPosition(null, 0);\n        }\n        else if ($(this).is(\":visible\")) {\n            if (firstLoad) {\n                firstLoad = false;\n                setTimeout(function() {\n                    $(\"#top_container\").removeClass(\"collapse\");\n                    scrollIntoPosition(e.target);\n                }, 700);\n            }\n            else {\n                $(\"#top_container\").removeClass(\"collapse\");\n                scrollIntoPosition(e.target);\n            }\n        }\n\n        function scrollIntoPosition(el, overridePosition) {\n            if (typeof overridePosition !== \"undefined\") {\n                $(\"body\").stop().animate({\n                    scrollTop: overridePosition\n                }, 400);\n            }\n            else if ($(\"body\").scrollTop() > 345) {\n                $(\"body\").stop().animate({\n                    scrollTop: ($(el).offset().top - 10)\n                }, 400);\n            }\n        }\n        \n        $($(this).attr(\"href\") + \" img[lazy-src]\").each(function() {\n              var val = $.attr(this, \"lazy-src\");\n              $.attr(this, \"src\", val);\n              $.removeAttr(this, \"lazy-src\");\n        });\n        \n        $(this).tab(\"show\");\n\n        var state = {};\n        state.nav = $(this).attr(\"href\").substr(1);\n        var oldState = $.bbq.getState(\"nav\") || \"about\";\n        if (state.nav != oldState)\n            $.bbq.pushState(state);\n     });\n\n    $(window).on(\"hashchange\", function(e) {\n        _gaq.push(['_trackPageview',location.pathname + location.search  + location.hash]);\n        tabs.each(function() {\n            var idx = $.bbq.getState(\"nav\") || \"about\";\n            var section = e.fragment.split(\"&\")[1] || \"\";\n            $(this).find(tab_a_selector + \"[href='#\" + idx + \"']\").triggerHandler('click');\n           \n            // handles dropping in from new link\n            var api = $.bbq.getState(\"api\");\n            if (api) {\n                $(tab_a_selector + \"[href='./api/\" + api + \".html']\").triggerHandler('click');\n            }\n        });\n    }).trigger(\"hashchange\");\n     \n    highlight();\n});\n\n\n\nfunction highlight() {\n    var highlighter = ace.require(\"ace/ext/static_highlight\")\n    var dom = ace.require(\"ace/lib/dom\")\n    function qsa(sel) {\n        var els = document.querySelectorAll(sel);\n        var result = [];\n        for (var i = 0, l = els.length; i < l; i++)\n            result[i] = els[i];\n        return result;\n    }\n\n    qsa(\"code[class]\").forEach(function(el) {\n        var m = el.className.match(/language-(\\w+)|(javascript)/);\n        if (!m) return\n        var mode = \"ace/mode/\" + (m[1] || m[2]);\n        highlighter.highlight(el, {mode: mode, theme: \"ace/theme/xcode\"})\n    });\n}"
  },
  {
    "path": "doc/site/style.css",
    "content": "body {\n    margin:0;\n    padding:0;\n    background-color:#e6f5fc;\n    font-family: Helvetica, Arial;\n    padding-left: calc(100vw - 100%);\n    background: url(images/body_background.png) repeat-x 0 -15px;\n    padding-left: calc(100vw - 100%);\n    background-color:#e6f5fc;\n}\n\n\n\n#ace_editor_demo, #embedded_ace_code {\n    height: 275px;\n    border: 1px solid #DDD;\n    border-radius: 4px;\n    border-bottom-right-radius: 0px;\n    margin-top: 5px;\n}\n\n#ace_editor_demo {\n    margin-bottom: 0px;\n}\n\n#embedded_ace_code {\n    height: 525px;\n}\n\nh1, h2, h3, h4, h5, h6 {\n    font-family: Helvetica;\n    font-weight: 100;\n    margin:0;\n    padding:0;\n}\n\nh2, h3, h4, h5, h6 {\n    padding-top: 30px;\n    border-bottom: 1px solid #bedaea;\n}\n\nH2 {\n    font-size:28px;\n    color:#263842;\n    padding-bottom:6px;\n}\n\nH3 {\n    font-size:22px;\n    color:#253741;\n    margin-bottom:8px;\n}\n\nH4 {\n    font-size:21px;\n    color:#222222;\n    margin-bottom:8px;\n}\n\nP {\n    padding:13px 0;\n    margin:0;\n    line-height:21px;\n    font-size: 15px;\n}\n\nUL{\n    font-size: 15px;\n}\n\n#header {\n\theight: 93px;\n\tposition: relative;\n\tbackground: linear-gradient(to bottom, #c0deef, #cde9fa 17px, #daf0fb 100px, #e4f4fc 150px, #e6f5fc 250px, #e6f5fc 100%);\n\tborder-bottom: 1px solid #C9E8FA;\n\tmargin-top: 40px;\n}\n\n#header .content .signature {\n    font-family:Trebuchet MS;\n    font-size:11px;\n    color:#ebe4d6;\n    position:absolute;\n    bottom:5px;\n    right:42px;\n    letter-spacing : 1px;\n}\n\n.content {\n    width:970px;\n    position:relative;\n    margin:0 auto;\n}\n\n#header .content {\n\theight: 100%;\n\tz-index: 90000;\n}\n\n#header .content .logo {\n\twidth: 141px;\n\theight: 92px;\n\tbackground: url(images/logo_half.png) no-repeat 0 0;\n\tposition: absolute;\n\ttop: -14px;\n\tleft: 0;\n}\n\n#header .content .title {\n\twidth: 605px;\n\theight: 58px;\n\tbackground: url(images/ace.png) no-repeat 0 0;\n\tposition: absolute;\n\ttop: 22px;\n\tleft: 329px;\n}\n\n#wrapper .content {\n    font-family:Arial;\n    font-size:14px;\n    color:#222222;\n    width: 960px;\n}\n\n#wrapper .content .column1 {\n    position:relative;\n    overflow:hidden;\n    float:left;\n    width:315px;\n    margin-right:31px;\n}\n\n#wrapper .content .column2 {\n    position:relative;\n    overflow:hidden;\n    float:left;\n    /*width:600px;*/\n}\n\n#top_container h1 {\n    font-size: 68px;\n    line-height: 60px;\n    width: 515px;\n    float: left;\n    font-weight: 100;\n    font-family: Helvetica;\n    padding: 65px 0 0 14px;\n    color: #333;\n}\n\n#top_container {\n    background: linear-gradient(to bottom, #fff 0, #fff 2px, #f7f7f7 2px, #f2f2f2 298px);\n    overflow: hidden;\n    padding: 11px 36px 19px 40px;\n    height: 267px;\n    transition: height 0.4s ease-out, opacity 0.4s ease-out, padding 0.4s ease-out, margin 0.4s ease-out;\n    opacity: 1;\n    margin-top: 25px;\n}\n\n#top_container.collapse {\n    padding: 0px;\n    height: 0px;\n    opacity: 0;\n    margin: 0;\n}\n\n#page_logo {\n    padding: 35px 0 15px 0;\n    width: 350px;\n    float: right;\n    text-align: center;\n    height: 220px;\n}\n\n.fork_on_github {\n    width:310px;\n    height:80px;\n    background:url(images/fork_on_github.png) no-repeat 0 0;\n    position:relative;\n    overflow:hidden;\n    margin-top:49px;\n    cursor:pointer;\n}\n\n.fork_on_github:hover {\n    background-position:0 -80px;\n}\n\n.divider {\n    height: 1px;\n    background-color:#bedaea;\n    margin-bottom:3px;\n}\n\n.menu, .site-menu {\n    padding: 25px 0 0 35px;\n}\n\nUL.content-list {\n    padding: 15px 0 15px 20px;\n    margin:0;\n}\n\nUL.content-list li {\n    padding-left: 10px;\n    padding-bottom: 3px;\n}\n\nul.menu-list {\n    padding: 15px 0;\n    margin: 0 0 20px 0;\n    list-style-type: none;\n    line-height: 16px;\n    overflow: auto;\n}\n\nul.menu-list li {\n    color: #2557B4;\n    font-family: Helvetica, Trebuchet MS;\n    font-size: 12px;\n    padding: 5px;\n    cursor: pointer;\n    display: block;\n    float: left;\n    margin-right: 15px;\n    margin-bottom: 20px;\n    width: 100px;\n    height: 90px;\n    border-radius: 5px;\n    position: relative;\n    background: rgba(255, 255, 255, 0.7);\n    margin-left: 22px;\n    margin-top: 20px;\n    box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);\n    transition: box-shadow 0.4s;\n    border: 1px solid #999;\n    background-image:   -webkit-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0)   6%, hsla(0,0%,100%, .1) 7.5%),\t\t\t\t\t\n\t\t\t\t\t\t-webkit-repeating-linear-gradient(left, hsla(0,0%,  0%,0) 0%, hsla(0,0%,  0%,0)   4%, hsla(0,0%,  0%,.03) 4.5%),\t\t\t\t\t\n\t\t\t\t\t\t-webkit-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.15) 2.2%),\n\t\t\t\t\t\t\n\t\t\t\t\t\t-webkit-linear-gradient(-90deg, hsl(0,0%,78%)  0%, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,90%) 47%, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,78%) 53%,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,70%)100%);\n    background-image:   -moz-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0)   6%, hsla(0,0%,100%, .1) 7.5%),    \t\t\t\t\n\t\t\t\t\t\t-moz-repeating-linear-gradient(left, hsla(0,0%,  0%,0) 0%, hsla(0,0%,  0%,0)   4%, hsla(0,0%,  0%,.03) 4.5%),\t\t\t\t\t\n\t\t\t\t\t\t-moz-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.15) 2.2%),\n\t\t\t\t\t\t\n\t\t\t\t\t\t-moz-linear-gradient(-90deg, hsl(0,0%,78%)  0%, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,90%) 47%, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,78%) 53%,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thsl(0,0%,70%)100%);\n}\n\nul.menu-list li:hover {\n    box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);\n    -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);\n}\n\nul.menu-list li a {\n    position: absolute;\n    bottom: 0px;\n    left: 0px;\n    color: white;\n    text-align: center;\n    font-weight: bold;\n    text-shadow: 0px 0px 4px rgba(0, 0, 0, 0.8);\n    width: 100%;\n    display: block;\n    background: rgba(0, 0, 0, 0.6);\n    line-height: 12px;\n    padding: 4px 0;\n}\n\nUL.menu-list LI a:hover {\n    text-decoration: none;\n}\n\nli#add_your_site p {\n    font-size: 32px;\n    border: 3px solid #34A034;\n    color: #34A034;\n    border-radius: 34px;\n    padding: 3px 4px 4px 5px;\n    width: 20px;\n    height: 22px;\n    line-height: 18px;\n    position: relative;\n    left: 33px;\n    top: 22px;\n    background: #fff;\n}\n\nul.menu-list li#add_your_site a {\n    color: #A3EEA3;\n}\n\n/* This is the animation code. */\n@keyframes example {\n    0% { transform: rotate(0deg); }\n    25% { transform: rotate(3deg); }\n    50%   { transform: rotate(0deg); }\n    75%   { transform: rotate(-3deg); }\n}\n\n/* This is the element that we apply the animation to. */\nli#add_your_site {\n   animation-name: example;\n   animation-duration: 0.4s;\n   animation-timing-function: ease; /* ease is the default */\n   animation-delay: 0s;             /* 0 is the default */\n   animation-iteration-count: infinite;    /* 1 is the default */\n   animation-direction: alternate;  /* normal is the default */\n}\n\nA {\n    color:#2557b4;\n    text-decoration:none;\n}\n\nA:hover {\n    text-decoration:underline;\n}\n\n#footer {\n    height:40px;\n    position:relative;\n    overflow:hidden;\n    background:url(images/bottombar.png) repeat-x 0 0;\n    position:relative;\n    margin-top:40px;\n}\n\nUL.menu-footer {\n    padding:0;\n    margin:8px 11px 0 0;\n    list-style-type:none;\n    float:right;\n}\n\nUL.menu-footer LI {\n    color:white;\n    font-family:Arial;\n    font-size:12px;\n    display:inline-block;\n    margin:0 1px;\n}\n\nUL.menu-footer LI A {\n    color:#8dd0ff;\n    text-decoration:none;\n}\n\nUL.menu-footer LI A:hover {\n    text-decoration:underline;\n}\n\n.nav-pills.nav {\n    margin: 10px 0 25px 0;\n    padding: 0;\n    border-radius: 5px;\n    border: 1px solid #d7d7d7;\n    background: #eeeeee;\n    background: linear-gradient(to bottom,  #eeeeee 0%,#cccccc 100%);\n    overflow: hidden;\n}\n\n.nav-pills > .active > a, .nav-pills > .active > a:hover {\n    color: white;\n    background-color: #555;\n    box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.8)!important;\n    text-shadow: 0px 0px 3px #000;\n}\n\n.nav-tabs > li > a, .nav-pills > li > a {\n    padding-right: 17px;\n    padding-left: 17px;\n    border-right: 1px solid #bbb;\n    border-radius: 0;\n    margin: 0;\n    line-height: 25px;\n    font-size: 14px;\n    color: #333;\n    text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);\n    box-shadow: 0 0 1px rgba(255, 255, 255, 1);\n    transition: background 0.2s;\n}\n\n.nav.nav-pills li:first-child > a {\n    padding-left: 28px;\n    padding-right: 28px;\n}\n\n.nav.nav-pills li:first-child > a > img {\n    width: 34px;\n}\n\n.nav.nav-pills li:last-child > a {\n    border-right: none;\n    box-shadow: none;\n    -moz-box-shadow: none;\n}\n\n.tab-content {\n    margin-bottom: 50px;\n}\n\n.tab-content > .active, .pill-content > .active {\n    padding: 25px 30px;\n}\n\n#top_container, .tab-content > .active, .pill-content > .active {\n    border: 1px solid #DDD;\n    border-radius: 5px;\n    -moz-border-radius: 5px;\n}\n\n.tab-content > .active, .pill-content > .active {\n    background: rgba(255, 255, 255, 0.7);\n}\n\npre .xml .javascript, pre .xml .css {\n    opacity: 1;\n}\n\n#embed_link {\n    text-align: right;\n    padding-top: 0;\n}\n#embed_link a {\n    color: #059C05;\n    font-weight: 100;\n    font-family: helvetica;\n    font-size: 13px;\n    display: inline-block;\n    padding: 2px 10px;\n    background: #f4f4f4;\n    border: 1px solid #ddd;\n    border-top: none;\n    border-bottom-left-radius: 4px;\n    border-bottom-right-radius: 4px;\n    text-shadow: 0px 1px 0px rgba(255, 255, 255, 1);\n    text-decoration: none;\n}\n\np.highlight_note {\n    padding: 8px 35px 8px 14px;\n    margin-top: 10px;\n    color: #A0762E;\n    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n    background-color: #FCF8E3;\n    border: 1px solid #CA9C44;\n    border-radius: 4px;\n}\n\np.highlight_note a {\n    color: #537CC7;\n}\n\n.prod_no_image {\n    position: relative; left: -10px; top: -12px;\n}\n\n\n#api {\n    padding: 0;\n}\n\n/*https://github.com/twitter/bootstrap/issues/5262*/\nimg {\n    max-width: none;\n}\n\n.text-logo{\n    color: black;\n    font-size: 24px;\n    font-weight: lighter;\n    margin-top: 23px;\n    text-align: center;\n    text-shadow: 1px 17px 2px gray, 1px 1px 2px gray;\n}\n\n.menu-list>li>img {\n    position: relative;\n}\n\n.rotating-logo {\n    transform: rotate(0deg);\n    transition: all 0.5s ease-out;\n}\n.rotating-logo:hover {\n    transform: rotate(360deg);\n    transition: all 0.5s ease-in-out;\n}\n\n.nav>li>a.external-nav:hover {\n    text-decoration: underline;\n}\n\npre { background-color: white!important }"
  },
  {
    "path": "doc/template/jade/common_layout.jade",
    "content": "-var dirPrefix = \"./\";\n-var sitePrefix = \"../doc/site/\";\n-var landingPage = 'false'\n-var versions = []\n\nmixin doctype\n    !!! 5\n\n    <!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en\"> <![endif]-->\n    <!--[if IE 7]> <html class=\"no-js ie7 oldie\" lang=\"en\"> <![endif]-->\n    <!--[if IE 8]> <html class=\"no-js ie8 oldie\" lang=\"en\"> <![endif]-->\n    <!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\"> <!--<![endif]-->\n\nmixin head\n    meta(http-equiv='Content-Type', content='text/html; charset=UTF-8')\n\n    -if (isIndex)\n        title #{title}\n    -else\n        title #{classId} - #{title}\n\n    meta(name=\"generator\", content=\"panino-doc-build\")\n    meta(name=\"description\", content=\"Ace API documentation for the online code editor\")\n    meta(name=\"author\", content=\"Garen J. Torikian\")\n\n    script(src='#{sitePrefix}/js/main.js')\n    link(rel='stylesheet', media='all and (max-device-width: 480px)', href='doc/site/iphone.css')\n    link(rel='stylesheet', media='all and (min-device-width: 481px) and (max-device-width: 1024px)', href='doc/site/iphone.css')\n    link(href='#{dirPrefix}resources/ace/skeleton/images/favicon.ico', rel='icon', type='image/x-icon')\n\n    link(href='#{sitePrefix}/style.css', rel='stylesheet', type='text/css')\n    link(rel=\"stylesheet\", href=\"#{dirPrefix}resources/csses/ace_api.css\")\n    link(rel=\"stylesheet\", href=\"#{dirPrefix}resources/csses/font-awesome.css\")\n\n    link(href=\"#{dirPrefix}resources/images/favicon.ico\", rel=\"icon\", type=\"image/x-icon\")\n\n    script(src='#{dirPrefix}resources/javascripts/bbq.js')\n    script(src=\"#{dirPrefix}resources/javascripts/jquery.collapse.js\")\n    script(src=\"#{dirPrefix}resources/javascripts/jquery.cookie.js\")\n    script(src=\"#{dirPrefix}resources/javascripts/bootstrap.js\")\n\n\nmixin endingScripts\n    script(defer, src=\"#{dirPrefix}resources/javascripts/ux.js\")\n    script(src=\"#{dirPrefix}resources/javascripts/clicker.js\")\n    script(src=\"#{dirPrefix}resources/javascripts/jquery-scrollspy.js\")\n    script(defer, src=\"#{dirPrefix}resources/javascripts/disqus-ext.js\")\n    script(defer, src=\"#{dirPrefix}resources/javascripts/ga.js\")\n\nmixin identifyBuild(tree, type)\n        landingPage = 'true'\n        -dirPrefix = './'\n\nmixin markdown(text, inline)\n    != markdown(text, inline)"
  },
  {
    "path": "doc/template/jade/layout.jade",
    "content": "include common_layout\ninclude lib\n\n#documentation.span9\n    -if (isIndex)\n        != indexContent\n    -else\n        mixin api()\n\n    mixin endingScripts\n\n    div(id=\"disqus_thread\")"
  },
  {
    "path": "doc/template/jade/lib.jade",
    "content": "- var methodSection, constructorSection, propertySection, eventSection;\n\n-function renameMemberTitle(title, count)\n  if title.indexOf(\"ethods\") >= 0\n    span Functions (#{count})\n  else if title.indexOf(\"ropert\") >= 0\n    span Properties (#{count})   \n  else\n    span #{title} (#{count})\n\nmixin article(obj, parents)\n  if typeof obj === 'string'\n    obj = list[obj]\n\n  if (obj.private !== true && obj.name.charAt(0) !== \"$\")\n    title = obj.path + (obj.type ? ' (' + obj.type + ')' : '')\n    article.article(id=obj.path, data-title=title)\n      if obj.type === 'section' || obj.type === 'namespace' || obj.type === 'class' || obj.type === 'mixin'\n\n        if obj.stability\n          mixin markdown(\">\" + obj.stability)\n\n        if obj.description\n          .section.description\n            .memberContent\n              mixin markdown(obj.description)\n      \n      else\n        .section.method\n          .memberContent\n            if obj.signatures\n              div.title\n                i(id='#{obj.path}', class='methodToggle methodClicker inactive icon-caret-right')\n                ul.signatures\n                  -var loops = 0;\n                  for sig in obj.signatures\n                    li.signature\n                      ul\n                        li.signature-call!= signature(obj, sig, [\"methodClicker\"])\n                          if sig.returns\n                            li.signature-returns\n                              ul.argument-types\n                                for ret in sig.returns\n                                  li.argument-type!= returnLink(obj, ret, [])\n                      -if (loops == 0)\n                        -loops = 1 // ensure that we only print ONE meta info UL per signature (some methods have multiple signatures)\n                        ul.metaInfo\n                            if obj.undocumented\n                              li\n                                span.label.undocumented Undocumented\n                            if obj.experimental\n                              li\n                                span.label.experimental Experimental\n                            if obj.readonly\n                              li\n                                span.label.read-only Read-Only\n                            if obj.chainable\n                              li\n                                span.label.chainable Chainable\n                            if obj.internal\n                              li\n                                span.label.internal Internal\n                            if obj.deprecated\n                              li\n                                span.label.deprecated\n                                  | Deprecated\n                                  if obj.deprecated.from\n                                    | &nbsp; (since #{obj.deprecated.from})\n                                    if obj.deprecated.off\n                                      | &nbsp;and will be removed on #{obj.deprecated.off}\n                            if obj.alias_of\n                              li\n                                span.label.alias.single\n                                  | Aliased as: \n                                  != link(obj.alias_of)\n                            else if obj.aliases.length\n                              li\n                                span.label.alias.multiple\n                                  | Aliased as:\n                                  ul.alias\n                                    for alias in obj.aliases\n                                      li\n                                        mixin link(alias)\n\n                            if obj.related_to\n                              li\n                                span.label.related-to\n                                  | Related to \n                                  mixin link(obj.related_to, [\"relatedToLink\"])  \n                                    \n            div.sideToggler\n\n              div(id='ellipsis_#{obj.path}', class='ellipsis_description')\n                mixin markdown(obj.short_description)\n\n\n              div.description\n\n                mixin markdown(obj.description)\n\n                if obj.bound && ~obj.bound.indexOf('#')\n                  p.note.methodized\n                    | This method can be called <em>either</em> as an \n                    != link(obj.bound, ['link-short'], 'instance method')\n                    |  <em>or</em> as a generic method. If calling as generic, pass the instance in as the first argument.\n                else if obj.bound && !~obj.bound.indexOf('#')\n                  p.note.functionalized\n                    | This method can be called <em>either</em> as an instance method <em>or</em> as a \n                    != link(obj.bound, ['link-short'], 'generic method')\n                    |. If calling as generic, pass the instance in as the first argument.\n\n                if obj.arguments && obj.arguments.length\n                  h4 Arguments\n                  != argumentTable(obj.arguments, [\"argument-list\", \"table\", \"table-striped\", \"table-bordered\"])\n\n                if obj.returns && obj.returns.length\n                  h4 Returns\n                  != returnTable(obj.returns, [\"return-list\", \"table\", \"table-striped\", \"table-bordered\"])\n\n  //- children\n  for child in obj.children.filter(function(x){return x.type === 'section'})\n    mixin article(child, parents.concat(obj))\n  for child in obj.children.filter(function(x){return x.type === 'utility'})\n    mixin article(child, parents.concat(obj))\n\n  for child in obj.children.filter(function(x){return x.type === 'constructor'})\n    - if (!constructorSection)\n      - constructorSection = true\n      h3.sectionHeader Constructors\n    mixin article(child, parents.concat(obj))\n\n  for child in obj.children.filter(function(x){return x.type === 'event'})\n    - if (!eventSection)\n      - eventSection = true\n      h3.sectionHeader Events\n    mixin article(child, parents.concat(obj), 'event')\n\n  for child in obj.children.filter(function(x){return x.type === 'class method'})  \n    - if (!methodSection)\n      - methodSection = true\n      h3.sectionHeader Methods\n    mixin article(child, parents.concat(obj))\n\n  for child in obj.children.filter(function(x){return x.type === 'class property'})\n    - if (!propertySection)\n      - propertySection = true\n      h3.sectionHeader Properties\n    mixin article(child, parents.concat(obj))\n\n  for child in obj.children.filter(function(x){return x.type === 'instance method'})\n    mixin article(child, parents.concat(obj))\n  for child in obj.children.filter(function(x){return x.type === 'instance property'})\n    mixin article(child, parents.concat(obj))\n  for child in obj.children.filter(function(x){return x.type === 'constant'})\n    mixin article(child, parents.concat(obj))\n\n\n\nmixin api()\n  -pos = 0\n  for obj in tree.children\n    -if (obj.subclasses.length == 0)\n      mixin render_starting_tabs(obj, pos)\n    -else\n      mixin render_starting_tabs(obj, pos)\n      for child in obj.children.filter(function(x){return x.type === 'namespace' || x.type === 'class' || x.type === 'mixin'})\n        -pos++\n        mixin render_starting_tabs(child, pos)\n\n\nmixin render_starting_tabs(obj, pos)\n  .classContent\n    .membersBackground\n\n    div(class=' members pos#{pos}')\n      div(class=' membersContent pos#{pos}')\n          h1.memberHeader\n            -var heading = obj.path\n            span.name #{heading}\n                  \n          -if (true || obj.filename.indexOf(\"index\") < 0)\n            ul(class='nav tabs pos#{pos}', data-tabs='tabs')\n              for selector, title in {'Events': ['event', 'events'], 'Constructors': ['constructor', 'constructors'], 'Class methods': ['class method', 'class_methods'], 'Class properties': ['class property', 'class_properties'], 'Instance methods': ['instance method', 'instance_methods'], 'Instance properties': ['instance property', 'instance_properties'], 'Constants': ['constant', 'constants']}\n                members = obj.children.filter(function(x){return x.type === selector[0]})\n                  li(class=\"dropdown\", data-dropdown=\"dropdown\")\n                    if members.length\n                       a(href=\"\\#\", class=\"dropdown-toggle\", data-toggle=\"dropdown\")\n                          != renameMemberTitle(title, members.length)\n                          b.caret\n                      ul.dropdown-menu\n                        for m in members\n                          if (m.private !== true && m.name.charAt(0) !== \"$\")\n                            li(id='dropdown_#{m.path}', data-id='#{m.path}', class='memberLink')\n                              mixin link(m, [], true)\n     -methodSection = constructorSection = propertySection = eventSection = false;\n     mixin article(obj, [])\n\nmixin short_description_list(collection)\n  ul.method-details-list\n    for obj in collection\n      if typeof obj === 'string'\n        obj = list[obj]\n      li.method-description\n        h4\n          mixin link(obj)\n        if obj.short_description\n          mixin markdown(obj.short_description)\n\nmixin link(obj, classes, short)\n  l = link(obj, classes, short)\n  != l\n\nmixin links(collection)\n  ul.method-list\n    for obj in collection\n      li\n        mixin link(obj)"
  },
  {
    "path": "doc/template/resources/csses/ace_api.css",
    "content": "/*\n  Generic \"affects everything\" stuff\n*/\n\n#wrapper .content .column2 {\n    float: none;\n}\n\n#documentation ul {\n    font-size: 13px;\n}\n\n#documentation li {\n    color: black;\n}\n\npre {\n    background-color: #FFFFFF;\n}\n\ncode {\n    font-size: 12px;\n    line-height: 16px;\n    font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important;\n    background-color: #F9F9F9;\n    border-radius: 3px 3px 3px 3px;\n    display: inline-block;\n    padding: 0 4px;\n    margin: 2px 1px;\n    color: inherit;\n}\n\n#documentation pre {\n    margin-top: 10px;\n    border-radius: none;\n    box-shadow: none;\n    background : white;\n    /*background : #f5f5f5;\n    border: 0;*/\n    \n    -webkit-border-radius: 6px 6px 0 0;\n    -moz-border-radius: 6px 6px 0 0;\n    border-radius: 6px 6px 0 0;\n    \n    padding: 5px;\n}\n\n.method pre, .event pre, .property pre  {\n    background : white;\n}\n\n#documentation pre code {\n    background-color: transparent;\n    border-radius: none;\n    box-shadow: none;\n}\n\n#documentation a code {\n    color: #00438a;\n}\n\n#documentation h2 {\n    font-size: 26px;\n}\n#documentation p {\n    font-size: 13px;\n}\n#documentation li p:last-child {\n    margin-bottom : 5px;\n}\n\n#documentation blockquote p{\n    font-size: 14px;\n    font-weight: 500;\n    line-height: 23px;\n    font-style: italic;\n}\n\n.alert-message{\n    margin-bottom : 13px;\n}\n/* \n  Header and shoulders\n*/\n\n.navbar .nav > li {\n    float:none;\n    display:inline-block;\n    *display:inline; /* ie7 fix */\n     zoom:1; /* hasLayout ie7 trigger */\n}\n\n.navbar .nav > li > a {\n    padding: 10px 15px 11px;\n}\n\n.navbar {\n    text-align:center;\n}\n\n#topSection {\n    width: 1000px;\n}\n.small_win #topSection {\n    width: 100%;\n}\n.small_win #topSection .dropdown {\n    margin-right: 40%;\n}\n.navbar .brand {\n    margin-left: 0px;\n}\n.brand {\n    background: transparent url(../images/ace_logo_menu.png) no-repeat 33px 5px;\n    width: 80px;\n    outline: none;\n    height: 40px;\n    padding: 0 10px !important;\n    border: none;\n}\n.brand.dropdown-toggle:after {\n    content: none;\n    display: block;\n    height: 40px;\n    border: none;\n}\n\n.ace_logo {\n    position: absolute;\n    top: 45px;\n    z-index: 20000;\n    left: 210px;\n}\n\n.headerTitle {\n    position: relative;\n    top: 100px;\n    left: 250px;\n}\n\n/*\n  Menu venue\n*/\n\n\nh3.api_title {\n    padding-top: 10px;\n}\n\nul.menu {\n    margin-left: 2px;\n}\n\n.menu li {\n    list-style-image: url(../images/menu_disc.png);\n    margin-bottom: 4px;\n    font-weight: 700;\n    padding-left: 10px;\n    margin-left: 0;\n}\n\n.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink {\n    color: #3E7096;\n    font-weight: 100;\n}\n.menuTwo {\n    margin-bottom: 5px;\n    margin-top: 2px;\n}\n.menuTwo li .menu-item a.menuLink {\n    color: #3E7096;\n    font-weight: 100;\n}\n\n/* need specificity to \"beat\" the above colors */\n.menu li .menu-item a.currentItem, .menuTwo li .menu-item  {\n    color: #0072bc;\n}\n\n/*\n  Members and the tabs that represent them\n*/\n\n.srolled .members {\n    width: 100%;\n/*    -webkit-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35);\n    -moz-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35);\n    box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); */\n    padding-bottom: 15px;\n/*    height: 31px;*/\n    position: fixed;\n}\n.shadow.members{\n    background: #edf8fd;\n    box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3);\n    -moz-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3);\n    -o-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3);\n    -webkit-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3);\n}\n\n.membersContent {\n  \n/*  border-bottom: 0.1em solid #FFF;*/\n  height: 3em;\n  padding-top: 4px;\n/*  line-height: 4;*/\n/*  margin-top: -0.1em;*/\n  position: relative;\n/*  transition-property: border-color, line-height;\n  transition-duration: 125ms, 250ms;\n  transition-timing-function: ease-out, ease-out;\n  -moz-transition-property: border-color, line-height;\n  -moz-transition-duration: 125ms, 250ms;\n  -moz-transition-timing-function: ease-out, ease-out;\n  -o-transition-property: border-color, line-height;\n  -o-transition-duration: 125ms, 250ms;\n  -o-transition-timing-function: ease-out, ease-out;\n  -webkit-transition-property: border-color, line-height;\n  -webkit-transition-duration: 125ms, 250ms;\n  -webkit-transition-timing-function: ease-out, ease-out;*/\n  \n  /*transition-duration: 125ms;\n  transition-property: top;\n  transition-timing-function: ease-out;\n  \n  top : 11px;*/\n  z-index: 103;\n  padding-right: 10px;\n  margin-right: -5px;\n  /*width: 700px;*/\n}\n.srolledHeader .membersContent {\n    line-height: 3;\n}\n.srolled .membersContent {\n    /*top : 0;*/\n    width: 625px;\n    padding-left: 327px;\n    margin : 0 auto 0 auto;\n}\n\n.srolled ul.nav {\n    padding-right: 10px;\n}\n\n.membersBackground {\n/*    background-color: white;\n    position: fixed;\n    z-index: 2;\n    top: 40px;\n    left: 0px;\n    right: 0px;\n    width: 100%;\n    height: 55px;\n    opacity: 0;\n    display: none;\n    box-shadow: rgba(0, 0, 0, 0.398438) 1px 4px 6px;*/\n\n    background-color: transparent;\n    height: 47px;\n    /*width: 700px;*/\n    position: absolute;\n}\n.srolled .membersBackground {\n    position: relative;\n}\n.srolledHeader .membersBackground {\n/*    display: block;*/\n}\n.memberHeader {\n    float: left;\n    padding-right: 10px;\n    margin-bottom: 5px;\n    position: absolute;\n    padding-top: 4px;\n\n}\n\nul.tabs li:first-child ul{\n    left: -63px;\n}\n\n.tabs a.menu:after, .tabs .dropdown-toggle:after {\n    margin-top: 22px;\n}\n\n.nav .dropdown-toggle .caret  {\n    margin-top: 12px;\n    border-top-color: #6D8CA0;\n    border-bottom-color: #6D8CA0;\n}\n\nli.dropdown {\n    color: #2D2D2D;\n    font-weight: bold;\n}\n\n.editInC9 {\n    font-size: 11px;\n    color: #657383;\n}\n\n.editInC9 a {\n    color: #657383;\n    font-weight: normal;\n    position : relative;\n    top : -2px;\n}\n\n.tabs {\n    padding-top: 14px;\n    /*border-bottom: 1px solid #848484;*/\n    min-height : 27px;\n    padding-bottom : 5px;\n}\n.tabsSansBorder {\n    border: 0;\n}\n.tabs, .pills {\n    margin-bottom: 0;\n}\n.srolledHeader .members .tabs {\n    background-color: white;\n}\n\nli.dropdown {\n    color: #2D2D2D;\n    font-weight: bold;\n}\n\n.members .tabs .dropdown a,\n.members .tabs a.menu:after, \n.members .tabs .dropdown-toggle:after {\n    margin-right: 0;\n    margin-left: 6px;\n}\n\n.memberLink a {\n    margin-left: 0 !important;\n}\n.menu-dropdown {\n    min-width : 105px;\n    max-height: 350px;\n    overflow: auto;\n    border-color : rgba(0, 0, 0, 0.1);\n}\n.topbar div > ul .menu-dropdown li a:hover,\n.nav .menu-dropdown li a:hover,\n.topbar div > ul .dropdown-menu li a:hover,\n.nav .dropdown-menu li a:hover {\n    background-color: #ffffff;\n    color: #000000;\n}\n\n.tabs a.menu:after, .tabs .dropdown-toggle:after {\n    margin-top: 13px;\n    line-height: 28px;\n}\n.open .menu, .dropdown.open .menu, .open .dropdown-toggle, .dropdown.open .dropdown-toggle  {\n    background: transparent;\n    color: black;\n/*    font-weight: bold;*/\n}\n#topSection .open .menu, #topSection .dropdown.open .menu, #topSection .open .dropdown-toggle, \n#topSection .dropdown.open .dropdown-toggle  {\n    color: #bfbfbf;\n}\n\n.tabs > li {\n    font-weight: bold;\n}\n\n.tabs > li > a {\n    border: none;\n    outline: none;\n    line-height: 28px;\n    font-size: 11px;\n    padding: 0 5px;\n}\n.tabs > li > a:hover {\n    color: #000000;\n    text-decoration: none;\n    background-color: transparent;\n    border: none;\n}\n.tabs > li, .pills > li {\n    float: right;\n}\n.topbar .dropdown-menu a, .dropdown-menu a {\n    font-size: 11px;\n/*    padding: 2px 12px;*/\n    line-height: 14px;\n}\n.tabs .active > a, .tabs .active > a:hover {\n    color: #000000;\n    border: none;\n    cursor: default;\n}\n.tabs .menu-dropdown, .tabs .dropdown-menu {\n    border-radius: 0 0 6px 6px;\n    left: 10px;\n    width: 160px;\n}\n.srolled .tabs .menu-dropdown, .srolled .tabs .dropdown-menu {\n    top: 32px;\n}\n.dropdown-toggle {\n    color: #6D8CA0;\n}\n\nul.tabs .double ul, ul.tabs .triple ul, ul.tabs .quad ul{\n    width:760px;\n    margin-bottom:20px;\n    overflow:hidden;\n    border-top:1px solid #ccc;\n}\n/*ul.tabs .double li, ul.tabs .triple li, ul.tabs .quad li{\n    line-height:1.5em;\n    border-bottom:1px solid #ccc;\n    float:left;\n    display:inline;\n}*/\n\n/*\n  Center content (the \"real stuff\")\n*/\n\n#nonFooter {\n    padding-top: 40px;\n}\n#wrapper {\n    height: 100%;\n}\n\n.content {\n    height: 100%;\n}\n\nheader.filler {\n    position: relative;\n    height: 40px;\n    width: 100%;\n}\n\n/*\n.container-fluid .row-fluid {\n    width: 1000px;\n    margin-left: auto;\n    margin-right: auto;\n}*/\n\n.divider {\n    height: 3px;\n    background-color: #BEDAEA;\n    margin-bottom: 3px;\n}\n\n#sidebar h3 a,\n#sidebar h3 a:hover {\n    color: #404040;\n}\n\n#sidebarContainer {\n    padding-top: 20px;\n}\n\n#mainContent {\n    margin-left: 30px;\n}\n\n#documentation {\n    padding-top: 35px;\n    padding-bottom: 10px;\n}\n\n#documentation article.article {\n    border-top: 1px solid #e9e9e9;\n    padding: 16px 10px 2px;\n    -webkit-transition: padding 0.2s;\n    -moz-transition: padding 0.2s;\n    -o-transition: padding 0.2s;\n}\n\n#documentation h3.sectionHeader + article.article {\n    border-top: none;\n}\n\ndiv#documentation article:last-child {\n    border-bottom: 1px solid #e9e9e9;\n    padding-bottom: 40px;\n}\n#documentation article.article.methodToggleOpen {\n    background: rgba(255, 255, 255, 0.5);\n    font-size: 13px;\n    line-height: 24px;\n    margin: 0 0 10px 0;\n}\n\n#documentation article:first-child {\n    border:none;\n}\n\n.site_logo {\n    display: block;  \n    margin-left: auto;   \n    margin-right: auto;\n}\n/*\n    Edit in Cloud9, sucka\n*/\n\n.snippet pre {\n    margin-bottom: 0;\n}\n\n.snippet .toolbar {\n    -webkit-border-radius: 0 0 6px 6px;\n    -moz-border-radius: 0 0 6px 6px;\n    border-radius: 0 0 6px 6px;\n    \n    text-align: right;\n    padding: 3px 10px;\n    margin-top : -1px;\n}\n\n.snippet .filename, .snippet .toolbar {\n    font-family: Ubuntu, sans-serif;\n    font-size: 12px;\n    color: #EEE;\n}\n\n.snippet .filename {\n    padding: 0 5px 2px 5px;\n    font-size: 10px;\n    background: rgba(230,230,230,0.5);\n    padding: 0 5px 2px 5px;\n    border-radius: 0 6px 0 6px;\n    margin : 1px;\n    position : absolute;\n    right : 0;\n    top : 0;\n}\n\n.snippet .filename span{\n    color : #666;\n}\n\n.snippet .toolbar {\n    background-color: rgba(30,30,30,0.5);\n}\n\ndiv.snippet {\n    margin-bottom: 18px;\n    position : relative;\n}\n\ndiv.snippet a, div.toolbar a {\n    color: #FFF;\n}\n\n/*\n  All about signatures\n*/\n\n.signatures {\n/*    width: 800px;*/\n    margin-left: 20px;\n    margin-bottom: 5px;\n}\n.sideToggler {\n    padding-left: 20px;\n}\nul.signatures ul {\n    list-style: none;\n    display: inline;\n}\n\nli.signature {\n    list-style: none;\n}\n\n.signature ul {\n    padding: 0;\n    margin: 0;\n}\n\n.signature li {\n    display: inline;\n}\n\n.signature ul.argument-types::before {\n    content: '→';\n    margin: 0 5px;\n}\n\n.signature li.argument-type::after {\n    content: '|';\n    padding: 0 5px 0 5px;\n}\n\n.signature li.argument-type:last-child:after {\n    content: '';\n    padding: 0 5px 0 5px;\n}\n\n.member-name {\n    color: #4397cd;\n    font-weight: bold;\n    text-decoration: none;\n    cursor: pointer;\n    padding-right: 3px;\n}\n\n.signature-call {\n    cursor: pointer;\n}\n\n#documentation .signature-call a {\n    color: #8e487e;\n}\n\n.sigClassName {\n    display: none;\n}\n\n.eventObjName {\n    font-style: italic;\n}\n.eventListenerStart, .eventListenerClose, .eventFunctionOpen, .eventFunctionClose {\n    color: #999999;\n}\n.eventMember {\n    padding-right: 0px;\n}\n\n.metaInfo {\n    float: right;\n    z-index: 1;\n    position: relative;\n}\n\n.chainable {\n    background-color: #0072bc;\n    color: #ffffff;\n}\n\n.deprecated {\n    background-color: #f7941d;\n    color: #ffffff;\n}\n\n.alias {\n    background-color: #6c951e;\n    color: #ffffff;\n}\n\n.related-to {\n    background-color: #89289a;\n    color: #ffffff;\n    font-size: 10px;\n    padding: 2px 5px 3px;\n    text-transform: capitalize;\n}\n\n.undocumented {\n    background-color: #B94A48;\n    color: #ffffff;\n}\n\n#documentation .alias a, #documentation .related-to a {\n    color: #ffffff;\n    /* text-decoration: underline; */ \n}\n#documentation .alias a:hover, #documentation .related-to a:hover {\n    text-decoration: none;\n}\n.#documentation alias:hover, #documentation .related-to:hover {\n    opacity: 0.8;\n    cursor: pointer;\n}\n.memberContent .title {\n    \n}\n.memberContent .description {\n    position:relative;\n    /*top: -13px;*/\n    display: none;\n}\n.snip-container .actions .toggle-plaintext label {\n    margin-top: 1px;\n    padding-top: 0;\n    text-align: left;\n}\n.snip-container .actions .toggle-plaintext input {\n    margin-top: 4px !important;\n}\n.snip-container label {\n    color: #ffffff;\n}\n.description h4 {\n    padding-top: 10px;\n    font-size: 18px;\n    line-height : 18px;\n}\n\n.table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th {\n    background-color: #F9F9F9;\n}\n.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th {\n    background-color: #fbfbfb;\n} \n\n.argument-list {\n    margin-bottom : 13px;\n}\n.argName {\n    font-style: italic;\n}\n\n\n/*\n  Everyday I'm togglin'\n*/\n\n#documentation i.methodToggle {\n    cursor: pointer;\n    color: #9f9f9f;\n    padding-top: 2px;\n    float: left;\n}\n#documentation i.methodToggle.methodToggleHover {\n    text-shadow: 0 0 10px #4699d5;\n    color: #4699d5;\n}\n#documentation i.methodToggle.active {\n    text-shadow: 0 0 10px #4699d5;\n    color: #4699d5;\n    /* Safari */\n    -webkit-transform: rotate(45deg);\n    \n    /* Firefox */\n    -moz-transform: rotate(45deg);\n    \n    /* IE */\n    -ms-transform: rotate(45deg);\n    \n    /* Opera */\n    -o-transform: rotate(45deg);\n    padding-top: 9px;\n}\n\n#documentation h3.sectionHeader {\n    line-height : 24px;\n}\n\ndiv.method {\n    position: relative;\n}\n\n.methodToggle a {\n    color: #fff;\n    border-bottom: 0px;\n    text-decoration: none;\n}\n\nh3.methodToggle {\n    height               : 13px; \n    width                : 8px; \n    background-position  : 0px 0px; \n    position: absolute;\n    top: -20px;\n    background-image     : url(../images/member-sprites.png); \n    background-color     : transparent; \n    background-repeat    : no-repeat; \n    overflow: hidden;\n    left: 0px;\n}\n\nh3.methodToggleHover {\n    /* background-position  : 0px -28px; */\n}\n\nh3.methodToggle.inactive {\n    top: 4px;\n}\n\nh3.methodToggle.active {\n    top:                  6px;\n    height               : 13px; \n    width                : 8px; \n    background-position  : 0px -59px; \n} \n\n.hidden {\n    display: none;\n    visibility: hidden;\n}\n\n.hiddenSpan {\n    display: none;\n}\n\n.ellipsis_description, .short_description {\n/*    width: 800px;*/\n}\n.methodToggleOpen .ellipsis_description {\n    display: none;\n}\n.sideToggler .short_description,\n.sideToggler .description{\n    display: none;\n}\n.methodToggleOpen .short_description,\n.methodToggleOpen .description {\n    display: block;\n}\n.description td p {\n    margin: 0;\n}\n/*\n  Footer? I hardly know her\n*/\n\n#footer {\n    width:100%;\n    background: #101010 url(../images/dashed_back.png) repeat 0 0;\n    font-size: 12px;\n    color: white;\n    height: 40px;\n}\n#footer .footerInner {\n    padding-left: 300px;\n    margin-left: auto;\n    margin-right: auto;\n    min-height: 40px;\n}\n#footer .footer-text {\n    display: block;\n    font-size: 12px;\n    float: right;\n}\n#footer div.footerInner div.footer-text p {\n    font-size: 12px;\n    font-family: Arial;\n    line-height: 18px;\n    margin: 10px 15px 0px 1px;\n}\n\n#footer a, #footer a:hover {\n    color: #8DD0FF;\n}\n\n.logoText, .logoImg {\n    /*position: absolute;*/\n    margin-bottom: 5px;\n}\n\n.logoImg {\n    top: 40px;\n}\n.topbar div > ul .menu-dropdown li a:hover,\n.nav .menu-dropdown li a:hover,\n.topbar div > ul .dropdown-menu li a:hover,\n.nav .dropdown-menu li a:hover {\n  background-color: #191919;\n  background-repeat: repeat-x;\n  background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919));\n  background-image: -moz-linear-gradient(top, #292929, #191919);\n  background-image: -ms-linear-gradient(top, #292929, #191919);\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919));\n  background-image: -webkit-linear-gradient(top, #292929, #191919);\n  background-image: -o-linear-gradient(top, #292929, #191919);\n  background-image: linear-gradient(top, #292929, #191919);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0);\n  color: #ffffff;\n}\n\n.alert-message.block-message {\n    background: #fefaca;\n    border-color : #fefaca;\n    padding : 8px 14px 8px 14px;\n}\n\nbody .dsq-reply{\n    margin-top : 10px;\n}\n\n#disqus_thread{\n    border-top : 1px solid #ddd;\n    margin-top : 30px;\n}\n\n#disqus_thread h3, body #dsq-content h3 {\n    font-size : 12px;\n    margin : 0 0 20px 0;\n    line-height : 12px;\n}\nbody #dsq-reply h3{\n    font-size : 18px;\n    line-height : 18px;\n    margin : 15px 0 20px 0;\n}\n\n#disqus_thread select{\n    font-size : 11px;\n    height : 20px;\n    color : #444;\n}\n\n#dsq-global-toolbar, #dsq-pagination, .dsq-trackback-url{\n    display : none;\n}\n"
  },
  {
    "path": "doc/template/resources/javascripts/bbq.js",
    "content": "/*\n * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010\n * http://benalman.com/projects/jquery-bbq-plugin/\n * \n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d=\"hashchange\",A=\"querystring\",D=\"fragment\",y=\"elemUrlAttr\",g=\"location\",k=\"href\",t=\"src\",x=/^.*\\?|#.*$/g,w=/^.*\\#/,h,C={};function E(F){return typeof F===\"string\"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,\"$1\")}function o(F){return F.replace(/(?:^[^?#]*\\?([^#]*).*$)?.*/,\"$1\")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\\#?(.*)$/:/^([^#?]*)\\??([^#]*)(#?.*)/);J=K[3]||\"\";if(G===2&&E(I)){L=I.replace(H?w:x,\"\")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?\"#\":L||!K[1]?\"?\":\"\")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||\"\";var F=$.map(G.split(\"\"),encodeURIComponent);h=new RegExp(F.join(\"|\"),\"g\")};c.noEscape(\",/\");$.deparam=l=function(I,F){var H={},G={\"true\":!0,\"false\":!1,\"null\":null};$.each(I.replace(/\\+/g,\" \").split(\"&\"),function(L,Q){var K=Q.split(\"=\"),P=r(K[0]),J,O=H,M=0,R=P.split(\"][\"),N=R.length-1;if(/\\[/.test(R[0])&&/\\]$/.test(R[N])){R[N]=R[N].replace(/\\]$/,\"\");R=R.shift().split(\"[\").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J===\"undefined\"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===\"\"?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:\"\"}}});return H};function z(H,F,G){if(F===i||typeof F===\"boolean\"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,\"\"):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:\"action\",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!==\"object\"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||\"\").toLowerCase()]||\"\",K=J&&L.attr(J)||\"\";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?\"\":\"#\")};b.getState=u=function(F,G){return F===i||typeof F===\"boolean\"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K===\"boolean\"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);\n/*\n * jQuery hashchange event - v1.4-pre - 7/21/2010\n * http://benalman.com/projects/jquery-hashchange-plugin/\n * \n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function($,e,b){var c=\"hashchange\",h=document,f,g=$.event.special,i=h.documentMode,d=\"on\"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return\"#\"+j.replace(/^[^#]*#?(.*)$/,\"$1\")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,\"\")+q}}p=setTimeout(n,$.fn[c].delay)}/msie/.test(navigator.userAgent.toLowerCase())&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('<iframe tabindex=\"-1\" title=\"empty\"/>').hide().one(\"load\",function(){r||l(a());n()}).attr(\"src\",r||\"javascript:0\").insertAfter(\"body\")[0].contentWindow;h.onpropertychange=function(){try{if(event.propertyName===\"title\"){q.document.title=h.title}}catch(s){}}}};j.stop=k;o=function(){return a(q.location.href)};l=function(v,s){var u=q.document,t=$.fn[c].domain;if(v!==s){u.title=h.title;u.open();t&&u.write('<script>document.domain=\"'+t+'\"<\\/script>');u.close();q.location.hash=v}}})();return j})()})(jQuery,this);"
  },
  {
    "path": "doc/template/resources/javascripts/bootstrap.js",
    "content": "/* ============================================================\n * bootstrap-dropdown.js v2.1.1\n * http://twitter.github.com/bootstrap/javascript.html#dropdowns\n * ============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* DROPDOWN CLASS DEFINITION\n  * ========================= */\n\n  var toggle = '[data-toggle=dropdown]'\n    , Dropdown = function (element) {\n        var $el = $(element).on('click.dropdown.data-api', this.toggle)\n        $('html').on('click.dropdown.data-api', function () {\n          $el.parent().removeClass('open')\n        })\n      }\n\n  Dropdown.prototype = {\n\n    constructor: Dropdown\n\n  , toggle: function (e) {\n      var $this = $(this)\n        , $parent\n        , isActive\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      clearMenus()\n\n      if (!isActive) {\n        $parent.toggleClass('open')\n        $this.focus()\n      }\n\n      return false\n    }\n\n  , keydown: function (e) {\n      var $this\n        , $items\n        , $active\n        , $parent\n        , isActive\n        , index\n\n      if (!/(38|40|27)/.test(e.keyCode)) return\n\n      $this = $(this)\n\n      e.preventDefault()\n      e.stopPropagation()\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      if (!isActive || (isActive && e.keyCode == 27)) return $this.click()\n\n      $items = $('[role=menu] li:not(.divider) a', $parent)\n\n      if (!$items.length) return\n\n      index = $items.index($items.filter(':focus'))\n\n      if (e.keyCode == 38 && index > 0) index--                                        // up\n      if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n      if (!~index) index = 0\n\n      $items\n        .eq(index)\n        .focus()\n    }\n\n  }\n\n  function clearMenus() {\n    getParent($(toggle))\n      .removeClass('open')\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n      , $parent\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    $parent = $(selector)\n    $parent.length || ($parent = $this.parent())\n\n    return $parent\n  }\n\n\n  /* DROPDOWN PLUGIN DEFINITION\n   * ========================== */\n\n  $.fn.dropdown = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('dropdown')\n      if (!data) $this.data('dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  /* APPLY TO STANDARD DROPDOWN ELEMENTS\n   * =================================== */\n\n  $(function () {\n    $('html')\n      .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)\n    $('body')\n      .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n      .on('click.dropdown.data-api touchstart.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)\n      .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n  })\n\n}(window.jQuery);\n/* ========================================================\n * bootstrap-tab.js v2.1.1\n * http://twitter.github.com/bootstrap/javascript.html#tabs\n * ========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TAB CLASS DEFINITION\n  * ==================== */\n\n  var Tab = function (element) {\n    this.element = $(element)\n  }\n\n  Tab.prototype = {\n\n    constructor: Tab\n\n  , show: function () {\n      var $this = this.element\n        , $ul = $this.closest('ul:not(.dropdown-menu)')\n        , selector = $this.attr('data-target')\n        , previous\n        , $target\n        , e\n\n      if (!selector) {\n        selector = $this.attr('href')\n        selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n      }\n\n      if ( $this.parent('li').hasClass('active') ) return\n\n      previous = $ul.find('.active a').last()[0]\n\n      e = $.Event('show', {\n        relatedTarget: previous\n      })\n\n      $this.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      $target = $(selector)\n\n      this.activate($this.parent('li'), $ul)\n      this.activate($target, $target.parent(), function () {\n        $this.trigger({\n          type: 'shown'\n        , relatedTarget: previous\n        })\n      })\n    }\n\n  , activate: function ( element, container, callback) {\n      var $active = container.find('> .active')\n        , transition = callback\n            && $.support.transition\n            && $active.hasClass('fade')\n\n      function next() {\n        $active\n          .removeClass('active')\n          .find('> .dropdown-menu > .active')\n          .removeClass('active')\n\n        element.addClass('active')\n\n        if (transition) {\n          element[0].offsetWidth // reflow for transition\n          element.addClass('in')\n        } else {\n          element.removeClass('fade')\n        }\n\n        if ( element.parent('.dropdown-menu') ) {\n          element.closest('li.dropdown').addClass('active')\n        }\n\n        callback && callback()\n      }\n\n      transition ?\n        $active.one($.support.transition.end, next) :\n        next()\n\n      $active.removeClass('in')\n    }\n  }\n\n\n /* TAB PLUGIN DEFINITION\n  * ===================== */\n\n  $.fn.tab = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('tab')\n      if (!data) $this.data('tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tab.Constructor = Tab\n\n\n /* TAB DATA-API\n  * ============ */\n\n  $(function () {\n    $('body').on('click.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n      e.preventDefault()\n      $(this).tab('show')\n    })\n  })\n\n}(window.jQuery);\n/* ==========================================================\n * bootstrap-affix.js v2.1.1\n * http://twitter.github.com/bootstrap/javascript.html#affix\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* AFFIX CLASS DEFINITION\n  * ====================== */\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, $.fn.affix.defaults, options)\n    this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this))\n    this.$element = $(element)\n    this.checkPosition()\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var scrollHeight = $(document).height()\n      , scrollTop = this.$window.scrollTop()\n      , position = this.$element.offset()\n      , offset = this.options.offset\n      , offsetBottom = offset.bottom\n      , offsetTop = offset.top\n      , reset = 'affix affix-top affix-bottom'\n      , affix\n\n    if (typeof offset != 'object') offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function') offsetTop = offset.top()\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()\n\n    affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?\n      false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?\n      'bottom' : offsetTop != null && scrollTop <= offsetTop ?\n      'top'    : false\n\n    if (this.affixed === affix) return\n\n    this.affixed = affix\n    this.unpin = affix == 'bottom' ? position.top - scrollTop : null\n\n    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))\n  }\n\n\n /* AFFIX PLUGIN DEFINITION\n  * ======================= */\n\n  $.fn.affix = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('affix')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.affix.Constructor = Affix\n\n  $.fn.affix.defaults = {\n    offset: 0\n  }\n\n\n /* AFFIX DATA-API\n  * ============== */\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n        , data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      data.offsetBottom && (data.offset.bottom = data.offsetBottom)\n      data.offsetTop && (data.offset.top = data.offsetTop)\n\n      $spy.affix(data)\n    })\n  })\n\n\n}(window.jQuery);"
  },
  {
    "path": "doc/template/resources/javascripts/clicker.js",
    "content": "function setupClicker() {\n  // when hovering over arrow, add highlight (only if inactive)\n  $(\"i.methodToggle\").hover(function () {\n      if (!$(\"i.methodToggle\").hasClass('active'))\n        $(this).addClass(\"methodToggleHover\");\n    },\n    function () {\n      $(this).removeClass(\"methodToggleHover\");\n    }\n  );\n\n  function handleClick(e, linkHref) {\n      //if (linkHref.indexOf(\"nav=api&api=\") >= 0)\n      //  return;\n      if (linkHref == \"api\")\n        return;\n        \n      e.preventDefault();\n      \n      var dstElem;\n      if (linkHref) {\n          dstElem = $(\"article[id='\" + linkHref + \"']\");\n      }\n      \n      var $article = (dstElem || $(this)).closest('.article'),\n          $arrow   = $('i.methodClicker', $article);\n\n      if (!$article.hasClass('methodToggleOpen') || this.force) {\n          $article.addClass('methodToggleOpen');\n          $arrow.removeClass('inactive').addClass('active');\n\n          if (!$arrow[0])\n            return;\n\n          var data = $arrow[0].id.replace(/^js_/, \"\");\n          //var state = {};\n          //state.section = data;\n          //$.bbq.pushState(state);\n          \n          scrollTo(null, data);\n      }\n      else {\n          $article.removeClass('methodToggleOpen');\n          $arrow.removeClass('active').addClass('inactive');\n      }\n  }\n  \n  function transformHash(e) {\n      // some bs to figure out link hash\n      var hashId = (e.srcElement ? e.srcElement.href : (e.hash || e.target.href)) || e.currentTarget.hash;\n      \n      handleClick(e, hashId.substring(hashId.indexOf(\"#\") + 1));\n  }\n  \n  // for the arrow\n  $(\"i.methodToggle\").click(handleClick);\n  \n  // for the signature\n  $('.member-name').click(handleClick);\n  \n  // for the top dropdown\n  $('li.memberLink a').click(transformHash);\n  \n  //$('a[href^=\"#\"]').click(transformHash);\n  \n  $('.related-to', '.metaInfo').click(function(){\n      location.hash = $(this).find('a').attr('href').split('#')[1];\n  });\n}"
  },
  {
    "path": "doc/template/resources/javascripts/disqus-ext.js",
    "content": "function setupDisqus(href) {\n    var disqus_shortname = 'aceapi';\n    \n    //var paths = window.location.pathname.split(\"/\");\n    //var fileName = paths[paths.length - 2] + \"/\" + paths[paths.length - 1];\n    \n    //var disqus_identifier = fileName;\n    var disqus_identifier =  href.substring(2);\n    \n    (function() {\n        if (document.getElementById(\"disqusScript\") === null) {\n            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;\n            dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';\n            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);       \n        }\n    })();\n}"
  },
  {
    "path": "doc/template/resources/javascripts/jquery-scrollspy.js",
    "content": "/*!\n * jQuery Scrollspy Plugin\n * Author: @sxalexander\n * Licensed under the MIT license\n */\n\n\n;(function ( $, window, document, undefined ) {\n\n    $.fn.extend({\n      scrollspy: function ( options ) {\n        \n          var defaults = {\n            min: 0,\n            max: 0,\n            mode: 'vertical',\n            buffer: 0,\n            container: window,\n            onEnter: options.onEnter ? options.onEnter : [],\n            onLeave: options.onLeave ? options.onLeave : [],\n            onTick: options.onTick ? options.onTick : []\n          }\n          \n          var options = $.extend( {}, defaults, options );\n\n          return this.each(function (i) {\n\n              var element = this;\n              var o = options;\n              var $container = $(o.container);\n              var mode = o.mode;\n              var buffer = o.buffer;\n              var enters = leaves = 0;\n              var inside = false;\n                            \n              /* add listener to container */\n              $container.bind('scroll', function(e){\n                  var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()};\n                  var xy = (mode == 'vertical') ? position.top + buffer : position.left + buffer;\n                  var max = o.max;\n                  var min = o.min;\n                  \n                  /* fix max */\n                  if($.isFunction(o.max)){\n                    max = o.max();\n                  }\n\n                  /* fix max */\n                  if($.isFunction(o.min)){\n                    min = o.min();\n                  }\n\n                  if(max == 0){\n                      max = (mode == 'vertical') ? $container.height() : $container.outerWidth() + $(element).outerWidth();\n                  }\n                  \n                  /* if we have reached the minimum bound but are below the max ... */\n                  if(xy >= o.min && xy <= max){\n                    /* trigger enter event */\n                    if(!inside){\n                       inside = true;\n                       enters++;\n                       \n                       /* fire enter event */\n                       $(element).trigger('scrollEnter', {position: position})\n                       if($.isFunction(o.onEnter)){\n                         o.onEnter(element, position);\n                       }\n                      \n                     }\n                     \n                     /* triger tick event */\n                     $(element).trigger('scrollTick', {position: position, inside: inside, enters: enters, leaves: leaves})\n                     if($.isFunction(o.onTick)){\n                       o.onTick(element, position, inside, enters, leaves);\n                     }\n                  }else{\n                    \n                    if(inside){\n                      inside = false;\n                      leaves++;\n                      /* trigger leave event */\n                      $(element).trigger('scrollLeave', {position: position, leaves:leaves})\n\n                      if($.isFunction(o.onLeave)){\n                        o.onLeave(element, position);\n                      }\n                    }\n                  }\n              }); \n\n          });\n      }\n\n    })\n\n    \n})( jQuery, window );\n"
  },
  {
    "path": "doc/template/resources/javascripts/jquery.collapse.js",
    "content": "/*!\n * Collapse plugin for jQuery\n * http://github.com/danielstocks/jQuery-Collapse/\n *\n * @author Daniel Stocks (http://webcloud.se)\n * @version 0.9.1\n * @updated 17-AUG-2010\n * \n * Copyright 2010, Daniel Stocks\n * Released under the MIT, BSD, and GPL Licenses.\n */\n \n(function($) {\n    \n    // Use a cookie counter to allow multiple instances of the plugin\n    var cookieCounter = 0;\n    \n    $.fn.extend({\n        collapse: function(options) {\n            \n            var defaults = {\n                head : \"h3\",\n                group : \"div, ul\",\n                cookieName : \"collapse\",\n                // Default function for showing content\n                show: function() { \n                    this.show();\n                },\n                // Default function for hiding content\n                hide: function() { \n                    this.hide();\n                }\n            };\n            var op = $.extend(defaults, options);\n            \n            // Default CSS classes\n            var active = \"active\",\n                inactive = \"inactive\";\n            \n            return this.each(function() {\n                \n                // Increment coookie counter to ensure cookie name integrity\n                cookieCounter++;\n                var obj = $(this),\n                    // Find all headers and wrap them in <a> for accessibility.\n                    sections = obj.find(op.head).wrapInner('<a href=\"#\"></a>'),\n                    l = sections.length,\n                    cookie = op.cookieName + \"_\" + cookieCounter;\n                    // Locate all panels directly following a header\n                    var panel = obj.find(op.head).map(function() {\n                        var head = $(this)\n                        if(!head.hasClass(active)) {\n                            return head.next(op.group).hide()[0];\n                        }\n                        return head.next(op.group)[0];\n                    });\n    \n                // Bind event for showing content\n                obj.bind(\"show\", function(e, bypass) {\n                    var obj = $(e.target);\n                    // ARIA attribute\n                    obj.attr('aria-hidden', false)\n                        .prev()\n                        .removeClass(inactive)\n                        .addClass(active);\n                    // Bypass method for instant display\n                    if(bypass) {\n                        obj.show();\n                    } else {\n                        op.show.call(obj);\n                    }\n                });\n\n                // Bind event for hiding content\n                obj.bind(\"hide\", function(e, bypass) {\n                    var obj = $(e.target);\n                    obj.attr('aria-hidden', true)\n                        .prev()\n                        .removeClass(active)\n                        .addClass(inactive);\n                    if(bypass) {\n                        obj.hide();\n                    } else {\n                        op.hide.call(obj);\n                    }\n                });\n                \n                // Look for existing cookies\n                if(cookieSupport) {\n                    for (var c=0;c<=l;c++) {\n                        var val = $.cookie(cookie + c);\n                        // Show content if associating cookie is found\n                        if ( val == c + \"open\" ) {\n                            panel.eq(c).trigger('show', [true]);\n                        // Hide content\n                        } else if ( val == c + \"closed\") {\n                            panel.eq(c).trigger('hide', [true]);\n                        }\n                    }\n                }\n                \n                // Delegate click event to show/hide content.\n                obj.bind(\"click\", function(e) {\n                    var t = $(e.target);\n                    // Check if header was clicked\n                    if(!t.is(op.head)) {\n                        // What about link inside header.\n                        if ( t.parent().is(op.head) ) {\n                            t = t.parent();\n                        } else {\n                            return;\n                        }\n                        e.preventDefault();\n                    }\n                    // Figure out what position the clicked header has.\n                    var num = sections.index(t),\n                        cookieName = cookie + num,\n                        cookieVal = num,\n                        content = t.next(op.group);\n                    // If content is already active, hide it.\n                    if(t.hasClass(active)) {\n                        content.trigger('hide');\n                        cookieVal += 'closed';\n                        if(cookieSupport) {\n                            $.cookie(cookieName, cookieVal, { path: '/', expires: 10 });\n                        }\n                        return;\n                    }\n                    // Otherwise show it.\n                    content.trigger('show');\n                    cookieVal += 'open';\n                    if(cookieSupport) {\n                        $.cookie(cookieName, cookieVal, { path: '/', expires: 10 });\n                    }\n                });\n            });\n        }\n    });\n\n    // Make sure can we eat cookies without getting into trouble.\n    var cookieSupport = (function() {\n        try {\n            $.cookie('x', 'x', { path: '/', expires: 10 });\n            $.cookie('x', null);\n        }\n        catch(e) {\n            return false;\n        }\n        return true;\n    })();\n})(jQuery);"
  },
  {
    "path": "doc/template/resources/javascripts/jquery.cookie.js",
    "content": "/**\n * Cookie plugin\n *\n * Copyright (c) 2006 Klaus Hartl (stilbuero.de)\n * Dual licensed under the MIT and GPL licenses:\n * http://www.opensource.org/licenses/mit-license.php\n * http://www.gnu.org/licenses/gpl.html\n *\n */\n\n/**\n * Create a cookie with the given name and value and other optional parameters.\n *\n * @example $.cookie('the_cookie', 'the_value');\n * @desc Set the value of a cookie.\n * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });\n * @desc Create a cookie with all available options.\n * @example $.cookie('the_cookie', 'the_value');\n * @desc Create a session cookie.\n * @example $.cookie('the_cookie', null);\n * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain\n *       used when the cookie was set.\n *\n * @param String name The name of the cookie.\n * @param String value The value of the cookie.\n * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.\n * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.\n *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.\n *                             If set to null or omitted, the cookie will be a session cookie and will not be retained\n *                             when the the browser exits.\n * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).\n * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).\n * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will\n *                        require a secure protocol (like HTTPS).\n * @type undefined\n *\n * @name $.cookie\n * @cat Plugins/Cookie\n * @author Klaus Hartl/klaus.hartl@stilbuero.de\n */\n\n/**\n * Get the value of a cookie with the given name.\n *\n * @example $.cookie('the_cookie');\n * @desc Get the value of a cookie.\n *\n * @param String name The name of the cookie.\n * @return The value of the cookie.\n * @type String\n *\n * @name $.cookie\n * @cat Plugins/Cookie\n * @author Klaus Hartl/klaus.hartl@stilbuero.de\n */\njQuery.cookie = function(name, value, options) {\n    if (typeof value != 'undefined') { // name and value given, set cookie\n        options = options || {};\n        if (value === null) {\n            value = '';\n            options.expires = -1;\n        }\n        var expires = '';\n        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {\n            var date;\n            if (typeof options.expires == 'number') {\n                date = new Date();\n                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));\n            } else {\n                date = options.expires;\n            }\n            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE\n        }\n        // CAUTION: Needed to parenthesize options.path and options.domain\n        // in the following expressions, otherwise they evaluate to undefined\n        // in the packed version for some reason...\n        var path = options.path ? '; path=' + (options.path) : '';\n        var domain = options.domain ? '; domain=' + (options.domain) : '';\n        var secure = options.secure ? '; secure' : '';\n        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');\n    } else { // only name given, get cookie\n        var cookieValue = null;\n        if (document.cookie && document.cookie != '') {\n            var cookies = document.cookie.split(';');\n            for (var i = 0; i < cookies.length; i++) {\n                var cookie = jQuery.trim(cookies[i]);\n                // Does this cookie string begin with the name we want?\n                if (cookie.substring(0, name.length + 1) == (name + '=')) {\n                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\n                    break;\n                }\n            }\n        }\n        return cookieValue;\n    }\n};"
  },
  {
    "path": "doc/template/resources/javascripts/plugins.js",
    "content": "window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){arguments.callee=arguments.callee.caller;var a=[].slice.call(arguments);(typeof console.log===\"object\"?log.apply.call(console.log,console,a):console.log.apply(console,a))}};\n(function(b){function c(){}for(var d=\"assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn\".split(\",\"),a;a=d.pop();){b[a]=b[a]||c}})((function(){try\n{console.log();return window.console;}catch(err){return window.console={};}})());\n\n/*\n * jQuery throttle / debounce - v1.1 - 3/7/2010\n * http://benalman.com/projects/jquery-throttle-debounce-plugin/\n * \n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!==\"boolean\"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);\n"
  },
  {
    "path": "doc/template/resources/javascripts/prettify-extension.js",
    "content": "// Stolen from StackOverflow. Find all </code><pre><code> \n// elements on the page and add the \"prettyprint\" style. If at least one \n// prettyprint element was found, call the Google Prettify prettyPrint() API.\n//http://sstatic.net/so/js/master.js?v=6523\nfunction styleCode() \n{\n    if (typeof disableStyleCode != \"undefined\") \n    {\n        return;\n    }\n\n    var a = false;\n\n    $(\"pre code\").parent().each(function() \n    {\n        if (!$(this).hasClass(\"prettyprint\")) \n        {\n            $(this).addClass(\"prettyprint\");\n            a = true\n        }\n    });\n    \n    if (a) { prettyPrint() } \n}"
  },
  {
    "path": "doc/template/resources/javascripts/prettify.js",
    "content": "var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;\n(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:\"0\"<=b&&b<=\"7\"?parseInt(a.substring(1),8):b===\"u\"||b===\"x\"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?\"\\\\x0\":\"\\\\x\")+a.toString(16);a=String.fromCharCode(a);if(a===\"\\\\\"||a===\"-\"||a===\"[\"||a===\"]\")a=\"\\\\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\\\u[\\dA-Fa-f]{4}|\\\\x[\\dA-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\S\\s]|[^\\\\]/g),a=\n[],b=[],o=f[0]===\"^\",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&\"-\"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=[\"[\"];o&&b.push(\"^\");b.push.apply(b,a);for(c=0;c<\nf.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push(\"-\"),b.push(e(i[1])));b.push(\"]\");return b.join(\"\")}function y(a){for(var f=a.source.match(/\\[(?:[^\\\\\\]]|\\\\[\\S\\s])*]|\\\\u[\\dA-Fa-f]{4}|\\\\x[\\dA-Fa-f]{2}|\\\\\\d+|\\\\[^\\dux]|\\(\\?[!:=]|[()^]|[^()[\\\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j===\"(\"?++i:\"\\\\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j===\"(\"?(++i,d[i]===void 0&&(f[c]=\"(?:\")):\"\\\\\"===j.charAt(0)&&\n(j=+j.substring(1))&&j<=i&&(f[c]=\"\\\\\"+d[i]);for(i=c=0;c<b;++c)\"^\"===f[c]&&\"^\"!==f[c+1]&&(f[c]=\"\");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a===\"[\"?f[c]=h(j):a!==\"\\\\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return\"[\"+String.fromCharCode(a&-33,a|32)+\"]\"}));return f.join(\"\")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\\\u[\\da-f]{4}|\\\\x[\\da-f]{2}|\\\\[^UXux]/gi,\"\"))){s=!0;l=!1;break}}for(var r=\n{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(\"\"+g);n.push(\"(?:\"+y(g)+\")\")}return RegExp(n.join(\"|\"),l?\"gi\":\"g\")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if(\"BR\"===g||\"LI\"===g)h[s]=\"\\n\",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\\r\\n?/g,\"\\n\"):g.replace(/[\\t\\n\\r ]+/g,\" \"),h[s]=g,t[s<<1]=y,y+=g.length,\nt[s++<<1|1]=a)}}var e=/(?:^|\\s)nocode(?:\\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue(\"white-space\"));var p=l&&\"pre\"===l.substring(0,3);m(a);return{a:h.join(\"\").replace(/\\n$/,\"\"),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,\"pln\"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===\n\"string\")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b=\"pln\")}if((c=b.length>=5&&\"lang-\"===b.substring(0,5))&&!(o&&typeof o[1]===\"string\"))c=!1,b=\"src\";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),\nl=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=\"\"+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\\S\\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push([\"str\",/^(?:'''(?:[^'\\\\]|\\\\[\\S\\s]|''?(?=[^']))*(?:'''|$)|\"\"\"(?:[^\"\\\\]|\\\\[\\S\\s]|\"\"?(?=[^\"]))*(?:\"\"\"|$)|'(?:[^'\\\\]|\\\\[\\S\\s])*(?:'|$)|\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$))/,q,\"'\\\"\"]):a.multiLineStrings?m.push([\"str\",/^(?:'(?:[^'\\\\]|\\\\[\\S\\s])*(?:'|$)|\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$)|`(?:[^\\\\`]|\\\\[\\S\\s])*(?:`|$))/,\nq,\"'\\\"`\"]):m.push([\"str\",/^(?:'(?:[^\\n\\r'\\\\]|\\\\.)*(?:'|$)|\"(?:[^\\n\\r\"\\\\]|\\\\.)*(?:\"|$))/,q,\"\\\"'\"]);a.verbatimStrings&&e.push([\"str\",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push([\"com\",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,\"#\"]):m.push([\"com\",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\\b|[^\\n\\r]*)/,q,\"#\"]),e.push([\"str\",/^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h|[a-z]\\w*)>/,q])):m.push([\"com\",/^#[^\\n\\r]*/,\nq,\"#\"]));a.cStyleComments&&(e.push([\"com\",/^\\/\\/[^\\n\\r]*/,q]),e.push([\"com\",/^\\/\\*[\\S\\s]*?(?:\\*\\/|$)/,q]));a.regexLiterals&&e.push([\"lang-regex\",/^(?:^^\\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|,|-=|->|\\/|\\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\\^=|\\^\\^|\\^\\^=|{|\\||\\|=|\\|\\||\\|\\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*(\\/(?=[^*/])(?:[^/[\\\\]|\\\\[\\S\\s]|\\[(?:[^\\\\\\]]|\\\\[\\S\\s])*(?:]|$))+\\/)/]);(h=a.types)&&e.push([\"typ\",h]);a=(\"\"+a.keywords).replace(/^ | $/g,\n\"\");a.length&&e.push([\"kwd\",RegExp(\"^(?:\"+a.replace(/[\\s,]+/g,\"|\")+\")\\\\b\"),q]);m.push([\"pln\",/^\\s+/,q,\" \\r\\n\\t\\xa0\"]);e.push([\"lit\",/^@[$_a-z][\\w$@]*/i,q],[\"typ\",/^(?:[@_]?[A-Z]+[a-z][\\w$@]*|\\w+_t\\b)/,q],[\"pln\",/^[$_a-z][\\w$@]*/i,q],[\"lit\",/^(?:0x[\\da-f]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+-]?\\d+)?)[a-z]*/i,q,\"0123456789\"],[\"pln\",/^\\\\[\\S\\s]?/,q],[\"pun\",/^.[^\\s\\w\"-$'./@\\\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if(\"BR\"===a.nodeName)h(a),\na.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}\nfor(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\\s)nocode(?:\\s|$)/,t=/\\r\\n?|\\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue(\"white-space\"));var p=l&&\"pre\"===l.substring(0,3);for(l=s.createElement(\"LI\");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute(\"value\",\nm);var r=s.createElement(\"OL\");r.className=\"linenums\";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className=\"L\"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode(\"\\xa0\")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn(\"cannot override language handler %s\",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\\s*</.test(m)?\"default-markup\":\"default-code\";return A[a]}function E(a){var m=\na.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\\bMSIE\\b/.test(navigator.userAgent),m=/\\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,\"\\r\"));i.nodeValue=\nj;var u=i.ownerDocument,v=u.createElement(\"SPAN\");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){\"console\"in window&&console.log(w&&w.stack?w.stack:w)}}var v=[\"break,continue,do,else,for,if,return,while\"],w=[[v,\"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile\"],\n\"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof\"],F=[w,\"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where\"],G=[w,\"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient\"],\nH=[G,\"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var\"],w=[w,\"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN\"],I=[v,\"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None\"],\nJ=[v,\"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END\"],v=[v,\"case,done,elif,esac,eval,fi,function,in,local,set,then,until\"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\\d*)/,N=/\\S/,O=u({keywords:[F,H,w,\"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END\"+\nI,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,[\"default-code\"]);k(x([],[[\"pln\",/^[^<?]+/],[\"dec\",/^<!\\w[^>]*(?:>|$)/],[\"com\",/^<\\!--[\\S\\s]*?(?:--\\>|$)/],[\"lang-\",/^<\\?([\\S\\s]+?)(?:\\?>|$)/],[\"lang-\",/^<%([\\S\\s]+?)(?:%>|$)/],[\"pun\",/^(?:<[%?]|[%?]>)/],[\"lang-\",/^<xmp\\b[^>]*>([\\S\\s]+?)<\\/xmp\\b[^>]*>/i],[\"lang-js\",/^<script\\b[^>]*>([\\S\\s]*?)(<\\/script\\b[^>]*>)/i],[\"lang-css\",/^<style\\b[^>]*>([\\S\\s]*?)(<\\/style\\b[^>]*>)/i],[\"lang-in.tag\",/^(<\\/?[a-z][^<>]*>)/i]]),\n[\"default-markup\",\"htm\",\"html\",\"mxml\",\"xhtml\",\"xml\",\"xsl\"]);k(x([[\"pln\",/^\\s+/,q,\" \\t\\r\\n\"],[\"atv\",/^(?:\"[^\"]*\"?|'[^']*'?)/,q,\"\\\"'\"]],[[\"tag\",/^^<\\/?[a-z](?:[\\w-.:]*\\w)?|\\/?>$/i],[\"atn\",/^(?!style[\\s=]|on)[a-z](?:[\\w:-]*\\w)?/i],[\"lang-uq.val\",/^=\\s*([^\\s\"'>]*(?:[^\\s\"'/>]|\\/(?=\\s)))/],[\"pun\",/^[/<->]+/],[\"lang-js\",/^on\\w+\\s*=\\s*\"([^\"]+)\"/i],[\"lang-js\",/^on\\w+\\s*=\\s*'([^']+)'/i],[\"lang-js\",/^on\\w+\\s*=\\s*([^\\s\"'>]+)/i],[\"lang-css\",/^style\\s*=\\s*\"([^\"]+)\"/i],[\"lang-css\",/^style\\s*=\\s*'([^']+)'/i],[\"lang-css\",\n/^style\\s*=\\s*([^\\s\"'>]+)/i]]),[\"in.tag\"]);k(x([],[[\"atv\",/^[\\S\\s]+/]]),[\"uq.val\"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),[\"c\",\"cc\",\"cpp\",\"cxx\",\"cyc\",\"m\"]);k(u({keywords:\"null,true,false\"}),[\"json\"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),[\"cs\"]);k(u({keywords:G,cStyleComments:!0}),[\"java\"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),[\"bsh\",\"csh\",\"sh\"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),\n[\"cv\",\"py\"]);k(u({keywords:\"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END\",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),[\"perl\",\"pl\",\"pm\"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),[\"rb\"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),[\"js\"]);k(u({keywords:\"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes\",\nhashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),[\"coffee\"]);k(x([],[[\"str\",/^[\\S\\s]+/]]),[\"regex\"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement(\"PRE\");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf(\"prettyprint\")>=0){var k=k.match(g),f,b;if(b=\n!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&\"CODE\"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName===\"pre\"||o.tagName===\"code\"||o.tagName===\"xmp\")&&o.className&&o.className.indexOf(\"prettyprint\")>=0){b=!0;break}b||((b=(b=n.className.match(/\\blinenums\\b(?::(\\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,\n250):a&&a()}for(var e=[document.getElementsByTagName(\"pre\"),document.getElementsByTagName(\"code\"),document.getElementsByTagName(\"xmp\")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\\blang(?:uage)?-([\\w.]+)(?!\\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:\"atn\",PR_ATTRIB_VALUE:\"atv\",PR_COMMENT:\"com\",PR_DECLARATION:\"dec\",PR_KEYWORD:\"kwd\",PR_LITERAL:\"lit\",\nPR_NOCODE:\"nocode\",PR_PLAIN:\"pln\",PR_PUNCTUATION:\"pun\",PR_SOURCE:\"src\",PR_STRING:\"str\",PR_TAG:\"tag\",PR_TYPE:\"typ\"}})();\n"
  },
  {
    "path": "doc/template/resources/javascripts/ux.js",
    "content": "$(function () {\n    'use strict';\n\n   var pagePath = document.location.pathname.substring(document.location.pathname.lastIndexOf(\"/\") + 1);\n\n   // select current page in sidenav and set up prev/next links if they exist\n   var $selNavLink = $('#sidebar').find('a[href=\"' + pagePath + '\"]');\n   if ($selNavLink.length) {\n      //$selListItem = $selNavLink.closest('li');\n\n      $selNavLink.addClass('currentItem');\n   }\n\n    if (window.addEventListener) window.addEventListener('load', loadCallback, true);\n    else window.attachEvent('load', loadCallback, true);\n\n    function loadCallback(evt) {\n        var form = document.getElementById(\"searchbox\");\n\n        if (form) {\n            var input = form.query;\n            form.onsubmit = function (evt) {\n                var query = input.value;\n                if (query) {\n                    input.value = \"\";\n                    input.blur();\n                    var url = \"https://www.google.com/search?q=\" + encodeURIComponent(\"site:ace.c9.io\" + \" \" + query);\n                    window.open(url);\n                }\n                return false;\n            };\n        }\n    }\n\n    // init search\n    $('#search')\n    // prevent from form submit\n    .on('submit', function () {\n        return false;\n    }).find('input');\n});\n\nfunction ux() {\n    var d = 'a.menu, .dropdown-toggle'\n\n    function clearMenus() {\n        $(d).parent('li').each(function () {\n            $(this).removeClass('open')\n        });\n    }\n\n    var s, sx;\n\n    // scrolling offset calculation via www.quirksmode.org\n    if (window.pageYOffset || window.pageXOffset) {\n        s = window.pageYOffset;\n        sx = window.pageXOffset;\n    }\n    else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {\n        s = document.documentElement.scrollTop;\n        sx = document.documentElement.scrollLeft;\n    }\n    else if (document.body) {\n        s = document.body.scrollTop;\n        sx = document.body.scrollLeft;\n    }\n\n    if (document.documentElement.offsetWidth < 1010) {\n        if (sx <= 0) sx = 0;\n        else if (sx + document.documentElement.offsetWidth > 1010) sx = 1010 - document.documentElement.offsetWidth;\n    }\n    else sx = 0;\n\n    $('span.methodClicker, article.article, i.methodClicker').each(function () {\n        var a = $(this);\n        var constructorPos = a.attr(\"id\").indexOf(\"new \");\n\n        var objName = a.attr(\"id\");\n        if (constructorPos >= 0) {\n            objName = objName.substring(constructorPos + 4);\n            objName += \".new\";\n        }\n\n        a.attr(\"id\", objName);\n    });\n    \n    function showMethodContent() {\n        var locationHash = location.hash.replace(/^#/, '').replace(/\\./g, '\\\\.');\n        var equalsPos = location.hash.indexOf(\"=\");\n        \n        if (equalsPos >=0) {\n            locationHash = locationHash.substring(0, location.hash.indexOf(\"=\"));\n        }\n        \n        var $clickerEl = $('span#' + locationHash);\n        if ($clickerEl.length > 0 && $clickerEl.hasClass('methodClicker')) {\n            var p = $clickerEl.parent();\n            p[0].force = true;\n            p.trigger('click');\n            p[0].force = false;\n        }\n    }\n\n    if (location.hash.indexOf(\"section\") >= 1) {\n        showMethodContent();\n        var data = location.hash;\n        scrollTo(null, data.substr(1));\n    }\n\n    window.onhashchange = function () {\n        showMethodContent();\n    }\n};\n\nfunction scrollTo(el, data) {\n    if (!data) {\n        data = el.getAttribute(\"data-id\");\n        //location.hash = data;\n    }\n    var el = $(\"span#\" + data.replace(/\\./g, \"\\\\.\"))[0];\n    if (!el) return;\n\n    var article = $(el).closest('.article')[0];\n\n    var top = article.offsetTop - 100;\n\n    if (document.body.scrollTop > top || document.body.scrollTop != top && document.body.scrollTop + (window.innerHeight || document.documentElement.offsetHeight) < top + article.offsetHeight) {\n        $('body').animate({\n            scrollTop: top\n        }, {\n            duration: 200,\n            easing: \"swing\"\n        });\n    }\n}"
  },
  {
    "path": "experiments/animate_folding.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n<!--\n\nAnimate Code Folding Experiment\n\nAnimates closing of folds in Chrome and WebKit. Requires 3D CSS and CSS \ntransitions.\n\nTODO\n\n* animate opening\n* fix closing at the bottom of the file\n* support folding with closed folds on the screen (rows are off)\n* support more browsers\n* speed\n\n-->\n\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Editor</title>\n  <style type=\"text/css\" media=\"screen\">\n    body {\n        overflow: hidden;\n    }\n    \n    pre {\n        margin: 0;\n    }\n    \n    #editor { \n        position: absolute;\n        height: 100%;\n        width: 100%;\n    }\n    \n    #container {\n        -webkit-transform: scaleZ(0.0000001);\n        margin: 0;\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        overflow: hidden;\n    }\n    \n    .ace_slide {\n        position: absolute;\n        width: 100%;\n        overflow: hidden;\n        \n        background-image: url(zenbg.png);\n    \n        /* ease in sine */ \n        -webkit-transition: height 500ms cubic-bezier(0.470, 0.000, 0.745, 0.715);\n        \n        -webkit-perspective: 2000;\n        -webkit-perspective-origin: 50% 50%;\n    }\n    \n    .ace_anim_slide_top {\n        z-index: -1;\n        background-color: white;\n        background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.05) 50%);\n        top: 0;\n        \n        -webkit-transition: -webkit-transform 500ms linear;\n        \n        -webkit-transform-style: preserve-3d;\n        -webkit-transform-origin: top;\n        -webkit-transform: rotateX(0deg);\n    }\n    \n    .ace_anim_slide_bottom {\n        background-color: white;\n        background-image: -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.05) 100%);\n        bottom: 0;\n        \n        -webkit-transition: -webkit-transform 500ms linear;\n        \n        -webkit-transform-style: preserve-3d;\n        -webkit-transform-origin: bottom;\n        -webkit-transform: rotateX(0deg);\n    }\n    \n    .ace_anim_hidden .ace_anim_slide_top {\n        -webkit-transform: rotateX(-90deg);\n    }\n    \n    .ace_anim_hidden .ace_anim_slide_bottom {\n        -webkit-transform: rotateX(90deg);\n    }\n    \n    .ace_anim_bottom {\n        /* ease in sine */ \n        -webkit-transition: top 500ms cubic-bezier(0.470, 0.000, 0.745, 0.715);\n        -webkit-transform: scaleZ(0.0000001);\n    }\n    \n  </style>\n</head>\n<body>\n\n<div id=\"container\">\n<div id=\"editor\"></div>\n</div>\n\n<script src=\"../build/src/ace-uncompressed.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script src=\"../build/src/mode-javascript.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script id=\"main\">\n\nwindow.onload = function() {\n    var editor = ace.edit(\"editor\");\n    \n    var JavaScriptMode = require(\"ace/mode/javascript\").Mode;\n    var EditSession = require(\"ace/edit_session\").EditSession;\n    var lang = require(\"ace/lib/lang\");\n    var Range = require(\"ace/range\").Range;\n    editor.getSession().setMode(new JavaScriptMode());\n    editor.getSession().setValue(document.getElementById(\"main\").innerHTML);\n    \n    \n    function cloneSession(session) {\n        var s = new EditSession(session.getDocument(), session.getMode());\n\n        // Copy over 'settings' from the session.\n        s.setTabSize(session.getTabSize());\n        s.setUseSoftTabs(session.getUseSoftTabs());\n        s.setOverwrite(session.getOverwrite());\n        s.setBreakpoints(session.getBreakpoints());\n        s.setUseWrapMode(session.getUseWrapMode());\n        s.setUseWorker(false);\n        s.setWrapLimitRange(session.$wrapLimitRange.min, session.$wrapLimitRange.max);\n        s.$foldData = session.$cloneFoldData();\n    \n        return s;\n    }\n    \n    function animateFold(editor, placeholder, range) {\n        var session = editor.getSession();\n        var ed = document.getElementById(\"editor\");\n        var parent = ed.parentNode;\n        \n        var clone = ed.cloneNode();\n        var cloneEd = ace.edit(clone);\n        var renderer = cloneEd.renderer;\n        \n        cloneEd.setSession(cloneSession(session));\n        cloneEd.setTheme(editor.getTheme());\n        renderer.scrollToY(editor.renderer.getScrollTop());\n        \n        parent.appendChild(clone);\n\n        cloneEd.resize();\n        renderer.$size = lang.copyObject(cloneEd.renderer.$size);\n        renderer.layerConfig = lang.copyObject(cloneEd.renderer.layerConfig);\n        renderer.$textLayer.$characterSize = lang.copyObject(editor.renderer.$textLayer.$characterSize);\n        renderer.$textLayer._emit(\"changeCharaterSize\", {data: renderer.$textLayer.$characterSize});\n        \n        renderer.$loop.onRender(renderer.$loop.changes);\n\n        // top area\n        var clone2 = clone.cloneNode(true);\n        var topHeight = range.start.row * renderer.lineHeight - renderer.scrollTop\n        clone2.style.height = topHeight + \"px\";\n        \n        parent.appendChild(clone2);\n\n        // middle\n        cloneEd.scrollToRow(range.start.row);\n        renderer.$loop.onRender(renderer.$loop.changes);\n        var middleHeight = (range.end.row - range.start.row) * renderer.lineHeight;        \n        \n        var slide = document.createElement(\"div\");\n        slide.className = \"ace_slide\";\n        slide.style.top = topHeight + \"px\";\n        slide.style.height = middleHeight + \"px\";\n        \n        var clone3 = clone.cloneNode(true);\n        clone3.className += \" ace_anim_slide_top\";\n        clone3.style.height = middleHeight + \"px\";\n        slide.appendChild(clone3);\n        \n        renderer.scrollToY(renderer.scrollTop + Math.floor(middleHeight / 2));\n        renderer.$loop.onRender(renderer.$loop.changes);\n        \n        var clone3 = clone.cloneNode(true);\n        clone3.className += \" ace_anim_slide_bottom\";\n        clone3.style.top = null;\n        clone3.style.height = (middleHeight / 2) + \"px\";\n        slide.appendChild(clone3);\n        \n        parent.appendChild(slide);\n\n        // bottom\n        cloneEd.scrollToRow(range.start.row)\n        cloneEd.getSession().addFold(placeholder, range);\n        renderer.$loop.onRender(renderer.$loop.changes);\n        \n        var clone4 = clone.cloneNode(true);\n        clone4.className += \" ace_anim_bottom\";\n        clone4.style.top = (topHeight + middleHeight) + \"px\";\n        parent.appendChild(clone4);\n        \n        cloneEd.destroy();\n        parent.removeChild(clone);\n        ed.style.left = \"-10000px\";\n    \n        setTimeout(function() {\n            clone4.style.top = topHeight + \"px\";\n            slide.style.height = 0;\n            slide.className += \" ace_anim_hidden\";\n            \n            setTimeout(function() {\n                ed.style.left = 0;\n                \n                setTimeout(function() {\n                    parent.removeChild(clone2);\n                    parent.removeChild(slide);\n                    parent.removeChild(clone4);\n                }, 0);\n            }, 500);\n        }, 0);\n    } \n\n    var origOnFoldWidgetClick = EditSession.prototype.onFoldWidgetClick;\n    EditSession.prototype.onFoldWidgetClick = function() {\n        \n        var orig = EditSession.prototype.addFold;\n        \n        EditSession.prototype.addFold = function(placeholder, range) {\n            EditSession.prototype.addFold = orig;\n            animateFold(editor, placeholder, range);\n            this.addFold(placeholder, range);\n        }\n        \n        var ret = origOnFoldWidgetClick.apply(this, arguments);\n        \n        return ret;\n    }\n};\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "experiments/basic_animation.html",
    "content": "<!DOCTYPE html>\n<html  xmlns=\"http://www.w3.org/1999/xhtml\">\n    <head profile=\"http://www.w3.org/2005/10/profile\">\n        <title> </title>\n        \n          <style type=\"text/css\" media=\"screen\">\n          \n#container {\n    position: absolute;\n    width: 400px;\n    height: 500px;\n    border: 1px solid black;\n    overflow: hidden;\n}\n\n#top {\n    position: absolute;\n    width: 100%;\n    height: 150px;\n    background: green;\n}\n\n#slide {\n    position: absolute;\n    width: 100%;\n    top: 150px;\n    height: 0;\n    background: orange;\n    overflow: hidden;\n    \n    -webkit-transition: height 5000ms cubic-bezier(0.390, 0.575, 0.565, 1.000);\n    \n    -webkit-perspective: 360;\n    -webkit-perspective-origin: 50% 50%;\n}\n\n#slide-top {\n    position: absolute;\n    width: 100%;\n    top: 0;\n    height: 100px;\n    \n    background-color: yellow;\n    /* easeOutSine */\n    background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.20) 100%);\n    \n    -webkit-transition: -webkit-transform 5000ms linear;\n    \n    -webkit-transform-style: preserve-3d;\n    -webkit-transform-origin: top;\n    -webkit-transform: rotateX(-90deg);\n}\n\n.visible #slide-top {\n    -webkit-transform: rotateX(0deg);\n}\n\n.visible #slide-bottom {\n    -webkit-transform: rotateX(0deg);\n}\n\n#slide-bottom {\n    position: absolute;\n    width: 100%;\n    top: auto;\n    bottom: 0;\n    height: 200px;\n    z-index: -1;\n    \n    background-color: blue;\n    background-image: -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.20) 50%);\n    \n    -webkit-transition: -webkit-transform 5000ms linear;\n    \n    -webkit-transform-style: preserve-3d;\n    -webkit-transform-origin: bottom;\n    -webkit-transform: rotateX(90deg);\n}\n\n#bottom {\n    position: absolute;\n    width: 100%;\n    top: 150px;\n    height: 500px;\n    background: red;\n    /* easeOutSine */\n    -webkit-transition: top 5000ms cubic-bezier(0.390, 0.575, 0.565, 1.000);\n}\n          \n          </style>\n    </head>\n    <body>\n\n    <div id=\"container\">\n        <div id=\"top\">Lorem ipsum dolor sit amet, consectetuer adipiscing elit,\n        sed diam nonummy nibh euismod tincidunt ut laoreet dolore\n        magna aliquam erat volutpat. Ut wisi enim ad minim veniam,\n        quis nostrud exerci tation ullamcorper suscipit lobortis nisl\n        ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n        dolor in hendrerit in vulputate velit esse molestie consequat,\n        vel illum dolore eu feugiat nulla facilisis at vero eros et\n        accumsan et iusto odio dignissim qui blandit praesent luptatum\n        zzril delenit augue duis dolore te feugait nulla facilisi.\n        Nam liber tempor cum soluta nobis eleifend option congue\n        nihil imperdiet doming id quod mazim placerat facer possim\n        assum. Typi non habent claritatem insitam; est usus legentis\n        in iis qui facit eorum claritatem. Investigationes\n        demonstraverunt lectores legere me lius quod ii legunt saepius.\n        Claritas est etiam processus dynamicus, qui sequitur mutationem\n        consuetudium lectorum. Mirum est notare quam littera gothica,\n        quam nunc putamus parum claram, anteposuerit litterarum formas\n        humanitatis per seacula quarta decima et quinta decima. Eodem\n        modo typi, qui nunc nobis videntur parum clari, fiant sollemnes\n        in futurum.</div>\n        <div id=\"slide\">\n            <div id=\"slide-top\">Lorem ipsum dolor sit amet, consectetuer adipiscing elit,\n            sed diam nonummy nibh euismod tincidunt ut laoreet dolore\n            magna aliquam erat volutpat. Ut wisi enim ad minim veniam,\n            quis nostrud exerci tation ullamcorper suscipit lobortis nisl\n            ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n            dolor in hendrerit in vulputate velit esse molestie consequat,\n            vel illum dolore eu feugiat nulla facilisis at vero eros et\n            accumsan et iusto odio dignissim qui blandit praesent luptatum\n            zzril delenit augue duis dolore te feugait nulla facilisi.\n            Nam liber tempor cum soluta nobis eleifend option congue\n            nihil imperdiet doming id quod mazim placerat facer possim\n            assum. Typi non habent claritatem insitam; est usus legentis\n            in iis qui facit eorum claritatem. Investigationes\n            demonstraverunt lectores legere me lius quod ii legunt saepius.\n            Claritas est etiam processus dynamicus, qui sequitur mutationem\n            consuetudium lectorum. Mirum est notare quam littera gothica,\n            quam nunc putamus parum claram, anteposuerit litterarum formas\n            humanitatis per seacula quarta decima et quinta decima. Eodem\n            modo typi, qui nunc nobis videntur parum clari, fiant sollemnes\n            in futurum.</div>\n            <div id=\"slide-bottom\">Lorem ipsum dolor sit amet, consectetuer adipiscing elit,\n            sed diam nonummy nibh euismod tincidunt ut laoreet dolore\n            magna aliquam erat volutpat. Ut wisi enim ad minim veniam,\n            quis nostrud exerci tation ullamcorper suscipit lobortis nisl\n            ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n            dolor in hendrerit in vulputate velit esse molestie consequat,\n            vel illum dolore eu feugiat nulla facilisis at vero eros et\n            accumsan et iusto odio dignissim qui blandit praesent luptatum\n            zzril delenit augue duis dolore te feugait nulla facilisi.\n            Nam liber tempor cum soluta nobis eleifend option congue\n            nihil imperdiet doming id quod mazim placerat facer possim\n            assum. Typi non habent claritatem insitam; est usus legentis\n            in iis qui facit eorum claritatem. Investigationes\n            demonstraverunt lectores legere me lius quod ii legunt saepius.\n            Claritas est etiam processus dynamicus, qui sequitur mutationem\n            consuetudium lectorum. Mirum est notare quam littera gothica,\n            quam nunc putamus parum claram, anteposuerit litterarum formas\n            humanitatis per seacula quarta decima et quinta decima. Eodem\n            modo typi, qui nunc nobis videntur parum clari, fiant sollemnes\n            in futurum.</div>\n        </div>\n        <div id=\"bottom\">Lorem ipsum dolor sit amet, consectetuer adipiscing elit,\n        sed diam nonummy nibh euismod tincidunt ut laoreet dolore\n        magna aliquam erat volutpat. Ut wisi enim ad minim veniam,\n        quis nostrud exerci tation ullamcorper suscipit lobortis nisl\n        ut aliquip ex ea commodo consequat. Duis autem vel eum iriure\n        dolor in hendrerit in vulputate velit esse molestie consequat,\n        vel illum dolore eu feugiat nulla facilisis at vero eros et\n        accumsan et iusto odio dignissim qui blandit praesent luptatum\n        zzril delenit augue duis dolore te feugait nulla facilisi.\n        Nam liber tempor cum soluta nobis eleifend option congue\n        nihil imperdiet doming id quod mazim placerat facer possim\n        assum. Typi non habent claritatem insitam; est usus legentis\n        in iis qui facit eorum claritatem. Investigationes\n        demonstraverunt lectores legere me lius quod ii legunt saepius.\n        Claritas est etiam processus dynamicus, qui sequitur mutationem\n        consuetudium lectorum. Mirum est notare quam littera gothica,\n        quam nunc putamus parum claram, anteposuerit litterarum formas\n        humanitatis per seacula quarta decima et quinta decima. Eodem\n        modo typi, qui nunc nobis videntur parum clari, fiant sollemnes\n        in futurum.</div>\n    </div>\n\n    <script>\n\nsetTimeout(function() {\n    document.getElementById(\"bottom\").style.top = \"350px\";\n    document.getElementById(\"slide\").style.height = \"200px\";\n    document.getElementById(\"slide\").className += \" visible\";\n    \n}, 1000);\n\n    </script>\n\n    </body>\n</html>\n"
  },
  {
    "path": "experiments/capture.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<meta name=\"author\" content=\"Fabian Jakobs\">\n\t<!-- Date: 2010-04-07 -->\n\t\n\t<style type=\"text/css\" media=\"screen\">\n\t#juhu {\n\t  width: 100px;\n\t  height: 50px;\n\t  background: yellow;\t  \n\t}\n\t</style>\n</head>\n<body>\n\n<div id=\"juhu\">\n  \n</div>\n\n<script src=\"../src/ace.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script type=\"text/javascript\" charset=\"utf-8\">\n\nvar el = document.getElementById(\"juhu\");\n\nace.addListener(el, \"mousedown\", function(e) {  \n  el.innerHTML = ace.getDocumentX(e) + \" \" + ace.getDocumentY(e);\n  ace.capture(\n    el,\n    function(e) {\n      el.innerHTML = ace.getDocumentX(e) + \" \" + ace.getDocumentY(e);\n    }, function() {\n      el.innerHTML = \"\";\n    }\n  );\n});\n\n\n  \n</script>\n</body>\n</html>\n"
  },
  {
    "path": "experiments/cut_copy.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<!--<meta name=\"viewport\" content=\"width=device-width,height=device-height\" />-->\n\t<title>Text Events</title>\n\t<meta name=\"author\" content=\"Fabian Jakobs\">\n\t\n\t<style type=\"text/css\" media=\"screen\">\n\t\n\t#container {\n\t    border: 1px solid black;\n\t    width: 600px;\n\t}\n\t\n\t#canvas {\n\t    border: 1px solid black;\n        margin: 4px;\n\t    width: 590px;\n\t    height: 400px;\n\t}\n\t\n\t#text {\n\t    position: absolute;\n\t}\n\n\t</style>\n\t\n</head>\n<body>\n    \n    <div id=\"container\">    \n        <textarea id=\"text\"></textarea>    \n        <div id=\"canvas\"></div>\n    </div>\n\n    <input type=\"button\" value=\"Clear\" id=\"some_name\" onclick=\"document.getElementById('logger').innerHTML = ''\">\n    <div id=\"logger\">\n        \n    </div>\n    \n<script type=\"text/javascript\" charset=\"utf-8\">\n    \nif (!window.console) window.console = {};\nif (!console.log) {\n    var logger = document.getElementById(\"logger\");\n    console.log = function() {\n        logger.innerHTML += Array.prototype.join.call(arguments, \", \") + \"<br>\";\n    }\n}\n\nfunction addListener(elem, type, callback) {\n    if (elem.addEventListener) {\n        return elem.addEventListener(type, callback, false);\n    }\n    if (elem.attachEvent) {\n        elem.attachEvent(\"on\" + type, function() {\n            callback(window.event);\n        });\n    }\n}\n\n    \nvar container = document.getElementById(\"container\");\nvar canvas = document.getElementById(\"canvas\");\nvar text = document.getElementById(\"text\");\n    \nfunction log(e) {\n    console.log(e.type, e);\n}\n\nfunction logKey(e) {\n    console.log(e.type, e.charCode, e.keyCode, e);\n}\n\naddListener(canvas, \"mousedown\", function(e) {\n    text.focus();\n    e.preventDefault();\n}, false);\n\nvar pos;\naddListener(canvas, \"touchstart\", function(e) {\n    text.value = \"\"\n    pos = e.touches[0]\n    text.focus();\n}, false);\naddListener(canvas, \"contextmenu\", function(e) {\n    text.value = \"xxxxx\";\n    var rect = canvas.getBoundingClientRect()\n    // text.selectionStart = 0\n    // text.selectionEnd = 20\n    text.style.opacity = 0\n    text.style.top = pos.clientY - 15 - rect.top + \"px\"\n    text.style.left = pos.clientX - 15 - rect.left + \"px\"\n    // canvas.style.fontSize = \"300px\"\n    // text.readOnly = true\n    // text.focus();\n    text.style.width = \"50px\"\n    text.style.height =  \"50px\"\n    text.select();\n    setTimeout(function() {\n        text.readOnly = false\n        // text.style.top = pos.clientY - 5 + \"px\"\n        // text.style.left = pos.clientY - 5 + \"px\"\n    }, 100)\n    //e.preventDefault();\n}, false);\n\naddListener(text, \"keydown\", logKey, false);\naddListener(text, \"keyup\", logKey, false);\naddListener(text, \"keypress\", logKey, false);\n\naddListener(text, \"textInput\", function(e) {\n    console.log(e.type, e.data, e);\n}, false);\n\nvar i = 0;\nfunction fillSelection() {\n  text.value = \"Juhu Kinners \" + (i++);\n  text.select();\n}\n\naddListener(text, \"copy\", fillSelection, false);\naddListener(text, \"paste\", log, false);\naddListener(text, \"cut\", fillSelection, false);\n\naddListener(text, \"beforecopy\", log, false);\naddListener(text, \"beforepaste\", log, false);\naddListener(text, \"beforecut\", log, false);\n\naddListener(text, \"compositionstart\", log, false);\naddListener(text, \"compositionupdate\", log, false);\naddListener(text, \"compositionend\", log, false);\n\naddListener(text, \"propertychange\", function(e) {\n    console.log(e.type, e.propertyName, e);\n}, false);\n    \n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "experiments/debug_mem_leak.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\">\n        <script src=\"../demo/kitchen-sink/require.js\"></script>\n        <script type=\"text/javascript\">\n            require.config({\n                paths: { ace: \"../lib/ace\" },\n                waitSeconds: 0\n            });\n        </script>\n    </head>\n    <body>\n        <p><button onclick=\"toggleEditor()\">Toggle editor</button></p>\n\n        <div id=\"container\"></div>\n        <script>\n            var editor;\n            var counter = 0\n\n            function toggleEditor() {\n                if (!editor) {\n                    var root = document.createElement(\"div\");\n                    root.style.height = \"100px\";\n                    root.setAttribute(\"id\", \"editor\");\n                    root.textContent = \"function foo(items) {\\nvar x = 'All this is syntax highlighted';\\nreturn x;\\n}\";\n\n                    document.getElementById(\"container\").appendChild(root);\n\n                    editor = ace.edit(root);\n\n                    if (counter++ % 2)\n                        editor.setTheme(\"ace/theme/monokai\");\n                    else\n                        editor.setTheme(\"ace/theme/clouds\");\n\n                    editor.session.setMode(\"ace/mode/javascript\");\n                } else {\n                    editor.destroy();\n                    var el = editor.container;\n                    el.parentNode.removeChild(el);\n\n                    editor.container = null\n                    editor.renderer = null\n\n                    editor = null;\n\n                    var root = document.getElementById(\"editor\")\n                    if (root)\n                        root.parentNode.removeChild(root);\n                }\n            }\n            require([\"ace/ace\"], function(ace) {\n                window.ace = ace;\n                toggleEditor();            \n            })\n        </script>\n    </body>\n</html>"
  },
  {
    "path": "experiments/dom.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Dom test</title>\n</head>\n<body>\n\n<pre id=\"root\"></pre>\n\n<script type=\"text/javascript\" charset=\"utf-8\">\n    var tests = {};\n    tests.innerHTML = function() {\n        function update(rootEl, lines) {\n            var html = []\n            for (var i = 0; i < lines.length; i++) {\n                html.push(\"<div class='line'>\")\n                renderLine(html, lines[i])\n                html.push(\"</div>\")\n            }\n            rootEl.innerHTML = html.join(\"\")\n        }\n    \n        function renderLine(html, tokens) {\n            for (var i = 0; i < tokens.length; i ++) {\n                html.push(\"<span class='\", tokens[i], \"'>\", tokens[i], \"</span>\")\n            }\n        }\n        return update;\n    }\n    tests.domNewNodes = function() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el) {\n            while (el.lastChild)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            clearEl(rootEl)\n            for (var i = 0; i < lines.length; i++) {\n                var el = elt(rootEl, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n        }\n    \n        function renderLine(html, tokens) {\n            for (var i = 0; i < tokens.length; i ++) {\n                elt(html, \"span\", tokens[i], tokens[i])\n            }\n        }\n        return update;\n    }\n    tests.domCloneNode = function() {\n        var els = {}\n        function elt(parent, name, className, content) {\n            if (!els[name]) els[name] = document.createElement(name);\n            var el = els[name].cloneNode(false)\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el) {\n            while (el.lastChild)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            clearEl(rootEl)\n            for (var i = 0; i < lines.length; i++) {\n                var el = elt(rootEl, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n        }\n    \n        function renderLine(html, tokens) {\n            for (var i = 0; i < tokens.length; i ++) {\n                elt(html, \"span\", tokens[i], tokens[i])\n            }\n        }\n        return update;\n    }\n    tests.domReuseNodes = function() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el, l) {\n            while (l --> 0)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < lines.length; i++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = \"line\"\n                }\n                else\n                    var el = elt(rootEl, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n    \n        function renderLine(rootEl, tokens) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < tokens.length; i ++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = tokens[i]\n                    el.firstChild.nodeValue = tokens[i]\n                }\n                else\n                    elt(rootEl, \"span\", tokens[i], tokens[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n        return update;\n    }\n    tests.domReuseNodesWithFragment = function() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el, l) {\n            while (l --> 0)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            var fr = document.createDocumentFragment()\n            var ch = rootEl.childNodes\n            for (var i = 0; i < lines.length; i++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = \"line\"\n                    fr.appendChild(el)\n                }\n                else\n                    var el = elt(fr, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n            clearEl(rootEl, ch.length - i)\n            rootEl.appendChild(fr)\n        }\n    \n        function renderLine(rootEl, tokens) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < tokens.length; i ++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = tokens[i]\n                    el.firstChild.nodeValue = tokens[i]\n                }\n                else\n                    elt(rootEl, \"span\", tokens[i], tokens[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n        return update;\n    }\n    tests.domWithFragment = function() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el) {\n            while (el.lastChild)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            var fr = document.createDocumentFragment()\n            clearEl(rootEl)\n            for (var i = 0; i < lines.length; i++) {\n                var el = elt(fr, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n            rootEl.appendChild(fr)\n        }\n    \n        function renderLine(html, tokens) {\n            for (var i = 0; i < tokens.length; i ++) {\n                elt(html, \"span\", tokens[i], tokens[i])\n            }\n        }\n        return update;\n    }\n    \n    tests.domdomReuseNodes_allowTextNodes = function dom31() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el, l) {\n            while (l --> 0)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < lines.length; i++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = \"line\"\n                }\n                else\n                    var el = elt(rootEl, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n    \n        function renderLine(rootEl, tokens) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < tokens.length; i ++) {\n                if (i % 2) {\n                    if (ch[i]) {\n                        var el = ch[i]\n                        el.className = tokens[i]\n                        el.firstChild.nodeValue = tokens[i]\n                    }\n                    else\n                        elt(rootEl, \"span\", tokens[i], tokens[i])\n                }\n                else {\n                    if (ch[i]) {\n                        var el = ch[i]\n                        el.nodeValue = tokens[i]\n                    }\n                    else\n                        txtEl(rootEl, tokens[i])\n                }\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n        return update;\n    }\n    tests.domdomReuseNodes_AllWrapped = function dom32() {\n        function elt(parent, name, className, content) {\n            var el = document.createElement(name);\n            if (content) {\n                el.appendChild(document.createTextNode(content))\n            }\n            parent && parent.appendChild(el)\n            el.className = className\n            return el;\n        }\n        function txtEl(parent, str) {\n            return parent.appendChild(document.createTextNode(str))\n        }\n        function clearEl(el, l) {\n            while (l --> 0)\n                el.removeChild(el.lastChild);\n        }\n\n        \n        function update(rootEl, lines) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < lines.length; i++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = \"line\"\n                }\n                else\n                    var el = elt(rootEl, \"div\", \"line\")\n                renderLine(el, lines[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n    \n        function renderLine(rootEl, tokens) {\n            var ch = rootEl.childNodes\n            for (var i = 0; i < tokens.length; i ++) {\n                if (ch[i]) {\n                    var el = ch[i]\n                    el.className = tokens[i]\n                    el.firstChild.nodeValue = tokens[i]\n                }\n                else\n                    elt(rootEl, \"span\", tokens[i], tokens[i])\n            }\n            clearEl(rootEl, ch.length - i)\n        }\n        return update;\n    }\n    \n    function runTest(render, cb) {\n        var rootEl = document.getElementById(\"root\")\n        rootEl.innerHTML = \"\";\n        var lines = [];\n        for (var i = 0; i < LINES; i++) {\n            var line = []\n            lines.push(line)\n            for (var j = 0; j < COLS; j ++) {\n                var ch = ((i + j) % COLS).toString(20)\n                var ch = \" \" + Array(5).join(ch) + \" \"\n                line.push(ch)\n            }\n        }\n        var now = performance.now();\n        var repeat = 100\n        function next() {\n            if (repeat --< 0) {\n                var dt = now - performance.now()\n                console.log(dt)\n                return cb && cb(null, dt)\n            }\n            lines.push(lines.shift())\n            render(rootEl, lines);\n            requestAnimationFrame(next)\n        }\n        next()\n    }\n    \n    var LINES = 100\n    var COLS = 50\n    var method = /test=(\\w+)|$/.exec(location.search)[1]\n    window.clearResults = function() {\n        Object.keys(localStorage).forEach(function(x) {\n            if (/^m_/.test(x)) delete localStorage[x]\n        })\n        showResults()\n    }\n    \n    function showResults() {\n        document.getElementById(\"root\").innerHTML = Object.keys(tests).map(function(x) { \n            return \"<a href='?test=\" + x + \"'>\" + x + \"</a>: \" + (localStorage[\"m_\" + x] || \"no results\");\n        }).join(\"<br>\")\n        + \"<br><br><a onclick='clearResults()' href='?'>clearResults</a>\";\n    }\n    \n    if (method && tests[method]) {\n        var update = tests[method]();\n        runTest(update, function(e, a) {\n            var all = localStorage[\"m_\" + method];\n            localStorage[\"m_\" + method] = all ?   all + \",\" + a : a;\n            showResults()\n        })\n    } else {\n        showResults();\n    }\n    \n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "experiments/triple_click.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<title>triple_click</title>\n\t<meta name=\"author\" content=\"Fabian Jakobs\">\n</head>\n<body>\n\n\n<div id=\"juhu\">\n  Juhu Kinners\n</div>\n\n<script src=\"../src/ace/lib/core.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script src=\"../src/ace/lib/event.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n<script type=\"text/javascript\" charset=\"utf-8\">\n\nvar el = document.getElementById(\"juhu\");\nace.addTripleClickListener(el, function() {\n  console.log(\"triple\");\n});\n\nace.addListener(el, \"selectstart\", function(e) {\n    return ace.preventDefault(e);\n});\n\n  \n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "experiments/worker.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<title>worker</title>\n\t<meta name=\"generator\" content=\"TextMate http://macromates.com/\">\n\t<meta name=\"author\" content=\"Fabian Jakobs\">\n\t<!-- Date: 2010-04-08 -->\n</head>\n<body>\n\n<script type=\"text/javascript\" charset=\"utf-8\">\n  \nvar worker = new Worker(\"worker.js\");\n\nworker.onmessage = function(e) {\n  console.log(e.data);\n};\n\nworker.onerror = function(e) {\n  console.log(e.data);\n};\n\nworker.postMessage(\"postMessage('juhu')\");\nworker.postMessage(\"postMessage('juhu')\");\n\n  \n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "experiments/worker.js",
    "content": "onmessage = function(e) {\n    onmessage = new Function(\"e\", e.data);\n};"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html> \n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n        <title>Ace - The High Performance Code Editor for the Web</title>\n        <link rel=\"stylesheet\" href=\"./doc/site/css/bootstrap.no-icons.min.css\" />\n        <link rel=\"stylesheet\" href=\"./doc/site/css/font-awesome.css\" />\n        <link href=\"./doc/site/style.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"./doc/site/images/favicon.ico\" rel=\"icon\" type=\"image/x-icon\" />\n\n        <script src=\"./build/src/ace.js\"></script>\n        <script src=\"./build/src/ext-static_highlight.js\"></script>\n        <!--[if lt IE 9]>\n            <script src=\"./build/src/ext-old_ie.js\"></script>\n        <![endif]-->\n    </head>\n    <body>\n        <a href=\"https://github.com/ajaxorg/ace\">\n            <img style=\"z-index: 50000; position: absolute; top: 0; right: 0; border: 0; width: 125px; height: 125px\" src=\"https://github.blog/wp-content/uploads/2008/12/forkme_right_red_aa0000.png?resize=149%2C149\" alt=\"Fork me on GitHub\">\n        </a>\n        <div id=\"wrapper\">\n            <div class=\"content\">\n                <div class=\"column2\">\n                    <div id=\"top_container\">\n                        <h1><img src=\"./doc/site/images/textimage.png\" alt=\"The high performance code editor for the web.\" /></h1>\n                        <div id=\"page_logo\">\n                            <img src=\"./doc/site/images/ace-logo.png\" />\n                            <iframe style=\"padding-top:5px\" src=\"https://ghbtns.com/github-btn.html?user=ajaxorg&amp;repo=ace&amp;type=watch&amp;count=true\" allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"110px\" height=\"20px\" sandbox=\"allow-scripts allow-popups\"></iframe>\n                            <iframe src=\"https://ghbtns.com/github-btn.html?user=ajaxorg&amp;repo=ace&amp;type=fork&amp;count=true\" allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"110px\" height=\"20px\" sandbox=\"allow-scripts allow-popups\"></iframe>\n                        </div>\n                    </div>\n                    <div style=\"clear: both\"></div>\n                    <ul id=\"tabnav\" class=\"nav nav-pills\">\n                        <li>\n                            <a href=\"/\"><img src=\"./doc/site/images/ace-tab.png\" /></a>\n                        </li>\n                        <li>\n                            <a href=\"#about\" data-toggle=\"tab\">About</a>\n                        </li>\n                        <li>\n                            <a href=\"#embedding\" data-toggle=\"tab\">Embedding Guide</a>\n                        </li>\n                        <li>\n                            <a href=\"#howto\" data-toggle=\"tab\">How-To Guide</a>\n                        </li>\n                        <li>\n                            <a href=\"#higlighter\" data-toggle=\"tab\">Syntax Highlighters</a>\n                        </li>\n                        <li>\n                            <a href=\"https://ajaxorg.github.io/ace-api-docs/index.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"external-nav\">API Reference</a>\n                        </li>\n                        <li>\n                            <a href=\"#production\" data-toggle=\"tab\">Real World Users</a>\n                        </li>\n                        <li class=\"last-tab\">\n                            <a href=\"https://mkslanc.github.io/ace-playground/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"external-nav\">Try</a>\n                        </li>\n                    </ul>\n                    <div class=\"tab-content\">\n                        <div class=\"tab-pane fade\" id=\"about\">\n                            <h1>Built for Code</h1>\n                            <p id=\"first\">Ace is an embeddable code editor written in JavaScript.\n                                It matches the features and performance of native\n                                editors such as Sublime, Vim and TextMate. It can be easily embedded\n                                in any web page and JavaScript application. Ace is maintained as the\n                                primary editor for <a href=\"https://c9.io\">Cloud9 IDE</a>\n                                and is the successor of the Mozilla Skywriter (Bespin) project.\n                            </p>\n                            \n                                <pre id=\"ace_editor_demo\" style=\"opacity:0\">/**\n * In fact, you're looking at ACE right now. Go ahead and play with it!\n *\n * We are currently showing off the JavaScript mode. ACE has support for 45\n * language modes and 24 color themes!\n */\n\nfunction add(x, y) {\n    var resultString = \"Hello, ACE! The result of your math is: \";\n    var result = x + y;\n    return resultString + result;\n}\n\nvar addResult = add(3, 2);\nconsole.log(addResult);\n</pre>\n                            <p id=\"embed_link\"><a href=\"#nav=embedding\">Learn how to embed this in your own site</a></p>\n                            <p class=\"highlight_note\">Looking for a more full-featured demo? Check out the\n                                <a href=\"build/kitchen-sink.html\" target=\"_blank\" rel=\"noopener noreferrer\">kitchen sink</a>.\n                            </p>\n                            <h2>Features</h2>\n                            <ul class=\"content-list\">\n                                <li><a href=\"https://pcwalton.blogspot.com/2010/11/syntax-highlighting-specification.html\">Syntax highlighting</a> for over 110 languages (TextMate/Sublime Text<em>.tmlanguage</em> files can be imported)</li>\n                                <li>Over 20 themes (TextMate/Sublime Text <em>.tmtheme</em> files can be imported)</li>\n                                <li>Automatic indent and outdent</li>\n                                <li>An optional command line</li>\n                                <li>Handles huge documents (four million lines seems to be the limit!)</li>\n                                <li>Fully customizable key bindings including vim and Emacs modes</li>\n                                <li>Search and replace with regular expressions</li>\n                                <li>Highlight matching parentheses</li>\n                                <li>Toggle between soft tabs and real tabs</li>\n                                <li>Displays hidden characters</li>\n                                <li>Drag and drop text using the mouse</li>\n                                <li>Line wrapping</li>\n                                <li>Code folding</li>\n                                <li>Multiple cursors and selections</li>\n                                <li>Live syntax checker (currently JavaScript/CoffeeScript/CSS/XQuery)</li>\n                                <li>Cut, copy, and paste functionality</li>\n                            </ul>\n                            <h2>Get the Open-Source Code</h2>\n                            <p>Ace is a community project. We actively encourage and support\n                                contributions! The Ace source code is <a href=\"https://github.com/ajaxorg/ace\">hosted on GitHub</a>\n                                and released under the BSD license &dash; \n                                very simple and friendly to all kinds of projects, whether open-source\n                                or not. Take charge of your editor and add your favorite language\n                                highlighting and keybindings!\n                            </p>\n                            <pre>git clone git://github.com/ajaxorg/ace.git</pre>\n                            <h2>History</h2>\n                            <p>Skywriter/Bespin and Ace started\n                                as two independent projects both aiming to build a no compromise\n                                code editor component for the web. Bespin started as part of\n                                Mozilla Labs and was based on the &lt;canvas> tag, while Ace is\n                                the editor component of <a href=\"https://c9.io\">Cloud9 IDE</a>\n                                and uses the DOM for rendering. After the release of Ace at\n                                <a href=\"https://www.youtube.com/watch?v=hN_7tAKh0dM\" title=\"[JSConfEU 2010] Fabian Jakobs: Kick ass code editing and end to end JavaScript debugging\">JSConf.eu 2010</a>\n                                in Berlin the Skywriter team decided to merge Ace with a simplified \n                                version of Skywriter's plugin system and some of Skywriter&apos;s\n                                extensibility points. All these changes have been merged back to Ace\n                                now, which supersedes Skywriter. Both <a href=\"https://c9.io\">Cloud9 IDE</a>\n                                and <a href=\"https://mozilla.org\">Mozilla</a> are actively developing and\n                                maintaining Ace.\n                            </p>\n                            <h2>Related Projects</h2>\n                            <ul class=\"content-list\">\n                                <li><a href=\"https://github.com/convergencelabs/ace-collab-ext\">Ace collaboration extension</a></li>\n                                <li><a href=\"https://github.com/rksm/paredit.js\">Paredit extension for ace</a></li>\n                                <li><a href=\"https://github.com/cadorn/ace-extjs\">Ace wrapper for ExtJS</a></li>\n                                <li><a href=\"https://github.com/daveho/AceGWT\">Ace wrapper for GWT</a></li>\n                            </ul>\n                            <h2>Getting Help</h2>\n                            <ul class=\"content-list\">\n                                <li><a href=\"https://github.com/ajaxorg/ace/issues\">Report bugs</a></li>\n                                <li><a href=\"https://github.com/ajaxorg/ace/discussions\">Discuss</a></li>\n                            </ul>\n                        </div>\n                        <div class=\"tab-pane fade active in\" id=\"embedding\">\n                            <h1>Embedding Ace in Your Site</h1>\n                            <p>Ace can be easily embedded into a web page. Get prebuilt version of ace from \n                            <a href=\"https://github.com/ajaxorg/ace-builds/\">ace-builds</a> repository and use the code below:</p>\n                                <pre id=\"embedded_ace_code\" style=\"opacity:0\">&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n&lt;head>\n&lt;title>ACE in Action&lt;/title>\n&lt;style type=\"text/css\" media=\"screen\">\n    #editor { \n        position: absolute;\n        top: 0;\n        right: 0;\n        bottom: 0;\n        left: 0;\n    }\n&lt;/style>\n&lt;/head>\n&lt;body>\n\n&lt;div id=\"editor\">function foo(items) {\n    var x = \"All this is syntax highlighted\";\n    return x;\n}&lt;/div>\n    \n&lt;script src=\"/ace-builds/src-noconflict/ace.js\" type=\"text/javascript\" charset=\"utf-8\">&lt;/script>\n&lt;script>\n    var editor = ace.edit(\"editor\");\n    editor.setTheme(\"ace/theme/monokai\");\n    editor.session.setMode(\"ace/mode/javascript\");\n&lt;/script>\n&lt;/body>\n&lt;/html></pre>\n                            <p>Now check out the <a href=\"#nav=howto\">How-To Guide</a> for instructions on\n                                common operations, such as setting a different language mode or\n                                getting the contents from the editor.\n                            </p>\n                            <h2>Loading Ace from a Local URL</h2>                            \n                            <p>If you want to clone and host Ace locally you can\n                                use one of the <a href=\"https://github.com/ajaxorg/ace-builds/\">pre-packaged versions</a>. Just copy\n                                one of <code>src*</code> subdirectories somewhere into your project, or use RequireJS to load the\n                                contents of <a href=\"https://github.com/ajaxorg/ace/tree/master/lib/ace\">lib/ace</a> folder as <code>ace</code>:\n                            </p>\n\t\t\t    <h2>Loading Ace from a CDN</h2>                            \n                            <p>The packaged version can also be loaded from CDN's such as <a href=\"https://www.jsdelivr.com/package/npm/ace-builds\">jsDelivr</a> or <a href=\"http://cdnjs.com/libraries/ace/\">cdnjs</a>.\n                            </p>\n                        </div>\n                        <div class=\"tab-pane fade\" id=\"howto\">\n                            <h1>Working with Ace</h1>\n                            <p><em>In all of these examples Ace has been invoked \n                                as shown in the <a href=\"#nav=embedding\">embedding guide</a>.</em>\n                            </p>\n                            <h2>Configuring the editor</h2>\n                            <p>there are several ways to pass configuration to Ace</p>\n                            <pre><code class=\"javascript\">// pass options to ace.edit\nace.edit(element, {\n    mode: \"ace/mode/javascript\",\n    selectionStyle: \"text\"\n})\n// use setOptions method to set several options at once\neditor.setOptions({\n    autoScrollEditorIntoView: true,\n    copyWithEmptySelection: true,\n});\n// use setOptions method\neditor.setOption(\"mergeUndoDeltas\", \"always\");\n\n// some options are also available as methods e.g. \neditor.setTheme(...)\n\n// to get the value of the option use\neditor.getOption(\"optionName\");\n</code>\n</pre>\n                            <p>See <a href=\"https://github.com/ajaxorg/ace/wiki/Configuring-Ace\">Configuring-Ace wiki page</a> for a more detailed list of options.</p>\n                            <h3>Changing the size of the editor</h3>\n                            <p>Ace only checks for changes of the size of it's container when window is resized. If you resize the editor div in another manner, and need Ace to resize, use the following:</p>\n                            <pre><code class=\"javascript\">editor.resize()</code></pre>\n                            <p>if you want editor to change it's size based on contents, use maxLines option as shown in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ace.c9.io/demo/autoresize.html\">https://ace.c9.io/demo/autoresize.html</a></p>\n                            <h2>Setting Themes</h2>\n                            <p>Themes are loaded on demand; all you have to do is pass the string name:</p>\n                            <pre><code class=\"javascript\">editor.setTheme(\"ace/theme/twilight\");</code></pre>\n                            <p><span class=\"expand_arrow\">&gt;</span> <a href=\"https://github.com/ajaxorg/ace/tree/master/src/theme\" target=\"_blank\" rel=\"noopener noreferrer\">See all themes.</a>\n                            Or use <a href=\"https://github.com/ajaxorg/ace/blob/master/src/ext/themelist.js\" target=\"_blank\" rel=\"noopener noreferrer\">themelist extension</a> to get the list of available themes at runtime.\n                            </p>\n                            <h2>Setting the Programming Language Mode</h2>\n                            <p>By default, the editor supports plain text mode. All other language modes are available as separate modules, loaded on demand like this:</p>\n                            <pre><code class=\"javascript\">editor.session.setMode(\"ace/mode/javascript\");</code></pre>\n                            <h2>One Editor, Multiple Sessions</h2>\n                                <p>Ace keeps everything about the state of the editor (selection, scroll position, etc.)\n                                    in <code class=\"javascript\">editor.session</code>. This means you can grab the\n                                    session, store it in a var, and set the editor to another session (e.g. a tabbed editor).</p>\n                                <p>You might accomplish this like so:</p>\n                                \n                                <pre><code class=\"javascript\">var js = ace.createEditSession(\"some js code\");\nvar css = ace.createEditSession([\"some\", \"css\", \"code here\"]);\n// and then to load document into editor, just call\neditor.setSession(js);</code></pre>\n                            <h2>Common Operations</h2>\n                            <p>Set and get content:</p>\n                            <pre><code class=\"javascript\">editor.setValue(\"the new text here\");\neditor.setValue(\"text2\", -1); // set value and move cursor to the start of the text\neditor.session.setValue(\"the new text here\"); // set value and reset undo history\neditor.getValue(); // or session.getValue</code></pre>\n                            <p>Get selected text:</p>\n                            <pre><code class=\"javascript\">editor.getSelectedText(); // or for a specific range\neditor.session.getTextRange(editor.getSelectionRange()); </code></pre>\n                            <p>Insert at cursor, emulating user input:</p>\n                            <pre><code class=\"javascript\">editor.insert(\"Something cool\");</code></pre>\n                            <p>Replace text in range:</p>\n                            <pre><code class=\"javascript\">editor.session.replace(new ace.Range(0, 0, 1, 1), \"new text\");</code></pre>\n                            <p>Get the current cursor line and column:</p>\n                            <pre><code class=\"javascript\">editor.selection.getCursor();</code></pre>\n                            <p>Go to a line:</p>\n                            <pre><code class=\"javascript\">editor.gotoLine(lineNumber);</code></pre>\n                            <p>Get total number of lines:</p>\n                            <pre><code class=\"javascript\">editor.session.getLength();</code></pre>\n                            <p>Set the default tab size:</p>\n                            <pre><code class=\"javascript\">editor.session.setTabSize(4);</code></pre>\n                            <p>Use soft tabs:</p>\n                            <pre><code class=\"javascript\">editor.session.setUseSoftTabs(true);</code></pre>\n                            <p>Set the font size:</p>\n                            <pre><code class=\"javascript\">document.getElementById('editor').style.fontSize='12px';</code></pre>\n                            <p>Toggle word wrapping:</p>\n                            <pre><code class=\"javascript\">editor.session.setUseWrapMode(true);</code></pre>\n                            <p>Set line highlighting:</p>\n                            <pre><code class=\"javascript\">editor.setHighlightActiveLine(false);</code></pre>\n                            <p>Set the print margin visibility:</p>\n                            <pre><code class=\"javascript\">editor.setShowPrintMargin(false);</code></pre>\n                            <p>Set the editor to read-only:</p>\n                            <pre><code class=\"javascript\">editor.setReadOnly(true);  // false to make it editable</code></pre>\n                            <h3>Using undo manager</h3>\n                            <p>To group undo delta of the next edit with the previous one set `mergeUndoDeltas` to true</p>\n                            <pre><code class=\"language-javascript\">editor.session.mergeUndoDeltas = true; \neditor.session.insert({row: 0, column:0}, Date()+\"\");</code></pre>\n\n                            <p>To start new undo group use `markUndoGroup` method</p>\n                            <pre><code class=\"language-javascript\">editor.insertSnippet(\"a$0b\"); \neditor.session.markUndoGroup(); \neditor.insertSnippet(\"x$0y\");</code></pre>\n                            <p>To disable undo of a an edit in a collaborative editor</p>\n                            <pre><code class=\"language-javascript\">var rev = session.$undoManager.startNewGroup(); // start new undo group\n... // apply the edit \nsession.$undoManager.markIgnored(rev); // mark the new group as ignored</code></pre>\n\n\n                            <p>To implement undo/redo buttons see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ace.c9.io/demo/toolbar.html\">https://ace.c9.io/demo/toolbar.html</a></p>\n\n                            <h3>Searching</h3>\n                            <pre><code class=\"language-javascript\">editor.find('needle',{\n    backwards: false,\n    wrap: false,\n    caseSensitive: false,\n    wholeWord: false,\n    regExp: false\n});\neditor.findNext();\neditor.findPrevious();</code></pre>\n                            <p>The following options are available to you for your search parameters:</p>\n                            <ul>\n                                <li>\n                                    <code>needle</code>: The string or regular expression you're looking for\n                                </li>\n                                <li>\n                                    <code>backwards</code>: Whether to search backwards from where cursor currently is. Defaults to <code>false</code>.\n                                </li>\n                                <li>\n                                    <code>wrap</code>: Whether to wrap the search back to the beginning when it hits the end. Defaults to <code>false</code>.\n                                </li>\n                                <li>\n                                    <code>caseSensitive</code>: Whether the search ought to be case-sensitive. Defaults to <code>false</code>.\n                                </li>\n                                <li>\n                                    <code>wholeWord</code>: Whether the search matches only on whole words. Defaults to <code>false</code>.\n                                </li>\n                                <li>\n                                    <code>range</code>: The <a class=\"internal absent\" href=\"/ajaxorg/ace/wiki/Range\">Range</a> to search within. Set this to <code>null</code> for the whole document\n                                </li>\n                                <li>\n                                    <code>regExp</code>: Whether the search is a regular expression or not. Defaults to <code>false</code>.\n                                </li>\n                                <li>\n                                    <code>start</code>: The starting <a class=\"internal absent\" href=\"/ajaxorg/ace/wiki/Range\">Range</a> or cursor position to begin the search\n                                </li>\n                                <li>\n                                    <code>skipCurrent</code>: Whether or not to include the current line in the search. Default to <code>false</code>.\n                                </li>\n\t\t\t\t <li>\n                                    <code>preventScroll</code>: Whether or not to move the cursor to the next match. Default to <code>false</code>.\n                                </li>\n                            </ul>\n                            <p>Here's how you can perform a replace:</p>\n                            <pre><code class=\"javascript\">editor.find('foo');\neditor.replace('bar');</code></pre>\n                            <p>And here's a replace all: </p>\n                            <pre><code class=\"javascript\">editor.replaceAll('bar');</code></pre>\n                            <p>(<code>editor.replaceAll</code> uses the needle set earlier by <code>editor.find('needle', ...</code>)</p>\n                            <h3>Listening to Events</h3>\n                            <p>To listen for an <code>onchange</code>:</p>\n                            <pre><code class=\"javascript\">editor.session.on('change', function(delta) {\n    // delta.start, delta.end, delta.lines, delta.action\n});</code></pre>\n                            <p>To listen for an <code>selection</code> change:</p>\n                            <pre><code class=\"javascript\">editor.session.selection.on('changeSelection', function(e) {\n});</code></pre>\n                            <p>To listen for a <code>cursor</code> change:</p>\n                            <pre><code class=\"javascript\">editor.session.selection.on('changeCursor', function(e) {\n});</code></pre>\n                            <h3>Adding New Commands and Keybindings</h3>\n                            <p>To assign key bindings to a custom function:</p>\n                            <pre><code class=\"javascript\">editor.commands.addCommand({\n    name: 'myCommand',\n    bindKey: {win: 'Ctrl-M',  mac: 'Command-M'},\n    exec: function(editor) {\n        //...\n    },\n    readOnly: true, // false if this command should not apply in readOnly mode\n    // multiSelectAction: \"forEach\", optional way to control behavior with multiple cursors\n    // scrollIntoView: \"cursor\", control how cursor is scolled into view after the command\n});</code></pre>\n                            <h3>Configure dynamic loading of modes and themes</h3>\n                            <p>By default ace detcts the url for dynamic loading by finding the script node for ace.js.\n                            This doesn't work if ace.js is not loaded with a separate script tag, and in this case it is required to set url explicitely</p>\n                            <pre><code class=\"javascript\">ace.config.set(\"basePath\", \"https://url.to.a/folder/that/contains-ace-modes\");</code></pre>\n                            <p>Path for one module alone can be configured with:</p>\n                            <pre><code class=\"javascript\">ace.config.setModuleUrl(\"ace/theme/textmate\", \"url for textmate.js\");</code></pre>\n                            <p>When using ace with webpack, it is possible to configure paths for all submodules using</p>                            \n                            <pre><code class=\"javascript\">require(\"ace-builds/esm-resolver\"); // for new bundlers: webpack 5, rollup, vite</code></pre>\n                            For webpack 4 use\n                            <pre><code class=\"javascript\">require(\"ace-builds/webpack-resolver\"); </code></pre>                            \n                            <p>which depends on <a href=\"https://github.com/webpack-contrib/file-loader\">file-loader</a></p>\n                        </div>\n                        <div class=\"tab-pane fade\" id=\"higlighter\">\n                            <h1>Creating a Syntax Highlighter for Ace</h1>\n                            <p>Creating a new syntax highlighter for Ace is extremely simple. You'll need to define two pieces of code: a new mode, and a new set of highlighting rules.</p>\n                            <h2 id=\"where-to-start\"><a class=\"heading_anchor\" href=\"#where-to-start\"><i class=\"headerLinkIcon\"></i></a>Where to Start</h2>\n                            <p>We recommend using the <a href=\"tool/mode_creator.html\">Ace Mode Creator</a> when defining your highlighter. This allows you to inspect your code's tokens, as well as providing a live preview of the syntax highlighter in action.</p>\n                            <h2 id=\"defining-a-mode\"><a class=\"heading_anchor\" href=\"#defining-a-mode\"><i class=\"headerLinkIcon\"></i></a>Defining a Mode</h2>\n                            <p>Every language needs a mode. A mode contains the paths to a language's syntax highlighting rules, indentation rules, and code folding rules. Without defining a mode, Ace won't know anything about the finer aspects of your language.</p>\n                            <p>Here is the starter template we'll use to create a new mode:</p>\n                            <pre><code class=\"language-javascript\">define(function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n// defines the parent mode\nvar TextMode = require(\"./text\").Mode;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\n// defines the language specific highlighters and folding rules\nvar MyNewHighlightRules = require(\"./mynew_highlight_rules\").MyNewHighlightRules;\nvar MyNewFoldMode = require(\"./folding/mynew\").MyNewFoldMode;\n\nvar Mode = function() {\n    // set everything up\n    this.HighlightRules = MyNewHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new MyNewFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // configure comment start/end characters\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    // special logic for indent/outdent. \n    // By default ace keeps indentation of previous line\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    // create worker for live syntax checking\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/mynew_worker\", \"NewWorker\");\n        worker.attachToDocument(session.getDocument());\n        worker.on(\"errors\", function(e) {\n            session.setAnnotations(e.data);\n        });\n        return worker;\n    };\n    \n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n});</code></pre>\n                            <p>What's going on here? First, you're defining the path to <code>TextMode</code> (more on this later). Then you're pointing the mode to your definitions for the highlighting rules, as well as your rules for code folding. Finally, you're setting everything up to find those rules, and exporting the Mode so that it can be consumed. That's it!</p>\n                            <p>Regarding <code>TextMode</code>, you'll notice that it's only being used once: <code>oop.inherits(Mode, TextMode);</code>. If your new language depends on the rules of another language, you can choose to inherit the same rules, while expanding on it with your language's own requirements. For example, PHP inherits from HTML, since it can be embedded directly inside <em>.html</em> pages. You can either inherit from <code>TextMode</code>, or any other existing mode, if it already relates to your language.</p>\n                            <p>All Ace modes can be found in the <em>lib/ace/mode</em> folder.</p>\n                            <h2 id=\"defining-syntax-highlighting-rules\"><a class=\"heading_anchor\" href=\"#defining-syntax-highlighting-rules\"><i class=\"headerLinkIcon\"></i></a>Defining Syntax Highlighting Rules</h2>\n                            <p>The Ace highlighter can be considered to be a state machine. Regular expressions define the tokens for the current state, as well as the transitions into another state. Let's define <em>mynew_highlight_rules.js</em>, which our mode above uses.</p>\n                            <p>All syntax highlighters start off looking something like this:</p>\n                            <pre><code class=\"language-javascript\">define(function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MyNewHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -&gt; the first match is used\n   this.$rules = {\n        \"start\" : [\n            {\n                token: token, // String, Array, or Function: the CSS token to apply\n                regex: regex, // String or RegExp: the regexp to match\n                next:  next   // [Optional] String: next state to enter\n            }\n        ]\n    };\n};\n\noop.inherits(MyNewHighlightRules, TextHighlightRules);\n\nexports.MyNewHighlightRules = MyNewHighlightRules;\n\n});</code></pre>\n                            <p>The token state machine operates on whatever is defined in <code>this.$rules</code>. The highlighter always begins at the <code>start</code> state, and progresses down the list, looking for a matching <code>regex</code>. When one is found, the resulting text is wrapped within a <code>&lt;span class=&quot;ace_&lt;token&gt;&quot;&gt;</code> tag, where <code>&lt;token&gt;</code> is defined as the <code>token</code> property. Note that all tokens are preceded by the <code>ace_</code> prefix when they're rendered on the page.</p>\n                            <p>Once again, we're inheriting from <code>TextHighlightRules</code> here. We could choose to make this any other language set we want, if our new language requires previously defined syntaxes. For more information on extending languages, see &quot;<a href=\"#extending-highlighters\">extending Highlighters</a>&quot; below.</p>\n                            <h3 id=\"defining-tokens\"><a class=\"heading_anchor\" href=\"#defining-tokens\"><i class=\"headerLinkIcon\"></i></a>Defining Tokens</h3>\n                            <p>The Ace highlighting system is heavily inspired by the <a href=\"http://manual.macromates.com/en/language_grammars\">TextMate language grammar</a>. Most tokens will follow the conventions of TextMate when naming grammars. A thorough (albeit incomplete) list of tokens can be found <a href=\"https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-commonTokens\">on the Ace Wiki</a>.</p>\n                            <p>For the complete list of tokens, see <em><a href=\"https://github.com/ajaxorg/ace/blob/master/tool/tmtheme.js\">tool/tmtheme.js</a></em>. It is possible to add new token names, but the scope of that knowledge is outside of this document.</p>\n                            <p>Multiple tokens can be applied to the same text by adding dots in the token, <em>e.g.</em> <code>token: support.function</code> wraps the text in a <code>&lt;span class=&quot;ace_support ace_function&quot;&gt;</code> tag.</p>\n                            <h3 id=\"defining-regular-expressions\"><a class=\"heading_anchor\" href=\"#defining-regular-expressions\"><i class=\"headerLinkIcon\"></i></a>Defining Regular Expressions</h3>\n                            <p>Regular expressions can either be a RegExp or String definition</p>\n                            <p>If you're using a regular expression, remember to start and end the line with the <code>/</code> character, like this:</p>\n                            <pre><code class=\"language-javascript\">{\n    token : \"constant.language.escape\",\n    regex : /\\$[\\w\\d]+/\n}</code></pre>\n                            <p>A caveat of using stringed regular expressions is that any <code>\\</code> character must be escaped. That means that even an innocuous regular expression like this:</p>\n                            <pre><code class=\"language-javascript\">regex: \"function\\s*\\(\\w+\\)\"</code></pre>\n                            <p>Must actually be written like this:</p>\n                            <pre><code class=\"language-javascript\">regex: \"function\\\\s*\\(\\\\w+\\)\"</code></pre>\n                            <h4 id=\"groupings\"><a class=\"heading_anchor\" href=\"#groupings\"><i class=\"headerLinkIcon\"></i></a>Groupings</h4>\n                            <p>You can also include flat regexps--<code>(var)</code>--or have matching groups--<code>((a+)(b+))</code>. There is a strict requirement whereby matching groups <strong>must</strong> cover the entire matched string; thus, <code>(hel)lo</code> is invalid. If you want to create a non-matching group, simply start the group with the <code>?:</code> predicate; thus, <code>(hel)(?:lo)</code> is okay. You can, of course, create longer non-matching groups. For example:</p>\n                            <pre><code class=\"language-javascript\">{\n    token : \"constant.language.boolean\",\n    regex : /(?:true|false)\\b/\n},</code></pre>\n                            <p>For flat regular expression matches, <code>token</code> can be a String, or a Function that takes a single argument (the match) and returns a string token. For example, using a function might look like this:</p>\n                            <pre><code class=\"language-javascript\">var colors = lang.arrayToMap(\n    (\"aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|\" +\n    \"purple|red|silver|teal|white|yellow\").split(\"|\")\n);\n\nvar fonts = lang.arrayToMap(\n    (\"arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|\" +\n    \"symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|\" +\n    \"serif|monospace\").split(\"|\")\n);\n\n...\n\n{\n    token: function(value) {\n        if (colors.hasOwnProperty(value.toLowerCase())) {\n            return \"support.constant.color\";\n        }\n        else if (fonts.hasOwnProperty(value.toLowerCase())) {\n            return \"support.constant.fonts\";\n        }\n        else {\n            return \"text\";\n        }\n    },\n    regex: \"\\\\-?[a-zA-Z_][a-zA-Z0-9_\\\\-]*\"\n}</code></pre>\n                            <p>If <code>token</code> is a function,it should take the same number of arguments as there are groups, and return an array of tokens.</p>\n                            <p>For grouped regular expressions, <code>token</code> can be a String, in which case all matched groups are given that same token, like this:</p>\n                            <pre><code class=\"language-javascript\">{\n    token: \"identifier\",\n    regex: \"(\\\\w+\\\\s*:)(\\\\w*)\"\n}</code></pre>\n                            <p>More commonly, though, <code>token</code> is an Array (of the same length as the number of groups), whereby matches are given the token of the same alignment as in the match. For a complicated regular expression, like defining a function, that might look something like this:</p>\n                            <pre><code class=\"language-javascript\">{\n    token : [\"storage.type\", \"text\", \"entity.name.function\"],\n    regex : \"(function)(\\\\s+)([a-zA-Z_][a-zA-Z0-9_]*\\\\b)\"\n}</code></pre>\n                            <h2 id=\"defining-states\"><a class=\"heading_anchor\" href=\"#defining-states\"><i class=\"headerLinkIcon\"></i></a>Defining States</h2>\n                            <p>The syntax highlighting state machine stays in the <code>start</code> state, until you define a <code>next</code> state for it to advance to. At that point, the tokenizer stays in that new <code>state</code>, until it advances to another state. Afterwards, you should return to the original <code>start</code> state.</p>\n                            <p>Here's an example:</p>\n                            <pre><code class=\"language-javascript\">this.$rules = {\n    \"start\" : [ {\n        token : \"text\",\n        regex : \"&lt;\\\\!\\\\[CDATA\\\\[\",\n        next : \"cdata\"\n    } ],\n\n    \"cdata\" : [ {\n        token : \"text\",\n        regex : \"\\\\]\\\\]&gt;\",\n        next : \"start\"\n    }, {\n        defaultToken : \"text\"\n    } ]\n};</code></pre>\n                            <p>In this extremely short sample, we're defining some highlighting rules for when Ace detects a <code>&lt;![CDATA</code> tag. When one is encountered, the tokenizer moves from <code>start</code> into the <code>cdata</code> state. It remains there, applying the <code>text</code> token to any string it encounters. Finally, when it hits a closing <code>]&gt;</code> symbol, it returns to the <code>start</code> state and continues to tokenize anything else.</p>\n                            <h2>Using the TMLanguage Tool</h2>\n                            <p>There is a tool that \n                                will take an existing <em>tmlanguage</em> file and do its best to convert it into Javascript for Ace to consume. Here's what you need to get started:\n                            </p>\n                            <ol>\n                                <li>In the Ace repository, navigate to the <em><a href=\"https://github.com/ajaxorg/ace/tree/master/tool\">tools</a></em> folder.</li>\n                                <li>Run <code>npm install</code>  to install required dependencies.</li>\n                                <li>Run <code>node tmlanguage.js &lt;path_to_tmlanguage_file&gt;</code>; for example, <code>node &lt;path_to_tmlanguage_file&gt; /Users/Elrond/elven.tmLanguage</code></li>\n                            </ol>\n                            <p>Two files are created and placed in <em>lib/ace/mode</em>: one for the language mode, and one for the set of highlight rules. You will still need to add the code into <em>ace/ext/modelist.js</em>, and add a sample file for testing.</p>\n                            <h3 id=\"a-note-on-accuracy\"><a class=\"heading_anchor\" href=\"#a-note-on-accuracy\"><i class=\"headerLinkIcon\"></i></a>A Note on Accuracy</h3>\n                            <p>Your <em>.tmlanguage</em> file will then be converted to the best of the converter’s ability. It is an understatement to say that the tool is imperfect. Probably, language mode creation will never be able to be fully autogenerated. There's a list of non-determinable items; for example:</p>\n                            <ul>\n                                <li>The use of regular expression lookbehinds<br />This is a concept that JavaScript simply does not have and needs to be faked</li>\n                                <li>Deciding which state to transition to<br />While the tool does create new states correctly, it labels them with generic terms like <code>state_2</code>, <code>state_10</code>, <em>e.t.c.</em></li>\n                                <li>Extending modes<br />Many modes say something like <code>include source.c</code>, to mean, “add all the rules in C highlighting.” That syntax does not make sense to Ace or this tool (though of course you can <a href=\"/extension-development-resources/guides/extending_highlighters.html\">extending existing highlighters</a>).</li>\n                                <li>Rule preference order</li>\n                                <li>Gathering keywords<br />Most likely, you’ll need to take keywords from your language file and run them through <code>createKeywordMapper()</code></li>\n                            </ul>\n                            <p>However, the tool is an excellent way to get a quick start, if you already possess a <em>tmlanguage</em> file for you language.</p>\n                            <h2>Extending Highlighters</h2>\n                            <p>Suppose you&#39;re working on a LuaPage, PHP embedded in HTML, or a Django template. You&#39;ll need to create a syntax highlighter that takes all the rules from the original language (Lua, PHP, or Python) and extends it with some additional identifiers (<code>&lt;?lua</code>, <code>&lt;?php</code>, <code>{%</code>, for example). Ace allows you to easily extend a highlighter using a few helper functions.</p>\n                            <h3 id=\"getting-existing-rules\"><a class=\"heading_anchor\" href=\"#getting-existing-rules\"><i class=\"headerLinkIcon\"></i></a>Getting Existing Rules</h3>\n                            <p>To get the existing syntax highlighting rules for a particular language, use the <code>getRules()</code> function. For example:</p>\n                            <pre><code class=\"language-javascript\">var HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nthis.$rules = new HtmlHighlightRules().getRules();\n\n/*\n    this.$rules == Same this.$rules as HTML highlighting\n*/</code></pre>\n                            <h3 id=\"extending-a-highlighter\"><a class=\"heading_anchor\" href=\"#extending-a-highlighter\"><i class=\"headerLinkIcon\"></i></a>Extending a Highlighter</h3>\n                            <p>The <code>addRules</code> method does one thing, and it does one thing well: it adds new rules to an existing rule set, and prefixes any state with a given tag. For example, let&#39;s say you&#39;ve got two sets of rules, defined like this:</p>\n                            <pre><code class=\"language-javascript\">this.$rules = {\n    \"start\": [ /* ... */ ]\n};\n\nvar newRules = {\n    \"start\": [ /* ... */ ]\n}</code></pre>\n                            <p>If you want to incorporate <code>newRules</code> into <code>this.$rules</code>, you&#39;d do something like this:</p>\n                            <pre><code class=\"language-javascript\">this.addRules(newRules, \"new-\");\n\n/*\n    this.$rules = {\n        \"start\": [ ... ],\n        \"new-start\": [ ... ]\n    };\n*/</code></pre>\n                            <h3 id=\"extending-two-highlighters\"><a class=\"heading_anchor\" href=\"#extending-two-highlighters\"><i class=\"headerLinkIcon\"></i></a>Extending Two Highlighters</h3>\n                            <p>The last function available to you combines both of these concepts, and it&#39;s called <code>embedRules</code>. It takes three parameters:</p>\n                            <ol>\n                                <li>An existing rule set to embed with</li>\n                                <li>A prefix to apply for each state in the existing rule set</li>\n                                <li>A set of new states to add</li>\n                            </ol>\n                            <p>Like <code>addRules</code>, <code>embedRules</code> adds on to the existing <code>this.$rules</code> object. </p>\n                            <p>To explain this visually, let&#39;s take a look at the syntax highlighter for Lua pages, which combines all of these concepts:</p>\n                            <pre><code class=\"language-javascript\">var HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar LuaHighlightRules = require(\"./lua_highlight_rules\").LuaHighlightRules;\n\nvar LuaPageHighlightRules = function() {\n    this.$rules = new HtmlHighlightRules().getRules();\n\n    for (var i in this.$rules) {\n        this.$rules[i].unshift({\n            token: \"keyword\",\n            regex: \"&lt;\\\\%\\\\=?\",\n            next: \"lua-start\"\n        }, {\n            token: \"keyword\",\n            regex: \"&lt;\\\\?lua\\\\=?\",\n            next: \"lua-start\"\n        });\n    }\n    this.embedRules(LuaHighlightRules, \"lua-\", [\n        {\n            token: \"keyword\",\n            regex: \"\\\\%&gt;\",\n            next: \"start\"\n        },\n        {\n            token: \"keyword\",\n            regex: \"\\\\?&gt;\",\n            next: \"start\"\n        }\n    ]);\n};</code></pre>\n                            <p>Here, <code>this.$rules</code> starts off as a set of HTML highlighting rules. To this set, we add two new checks for <code>&lt;%=</code> and <code>&lt;?lua=</code>. We also delegate that if one of these rules are matched, we should move onto the <code>lua-start</code> state. Next, <code>embedRules</code> takes the already existing set of <code>LuaHighlightRules</code> and applies the <code>lua-</code> prefix to each state there. Finally, it adds two new checks for <code>%&gt;</code> and <code>?&gt;</code>, allowing the state machine to return to <code>start</code>.</p>\n                            <h3>Code Folding</h3>\n                            <p>Adding new folding rules to your mode can be a little tricky. First, insert the following lines of code into your mode definition:</p>\n                            <pre><code class=\"language-javascript\">var MyFoldMode = require(\"./folding/newrules\").FoldMode;\n\n...\nvar MyMode = function() {\n\n    ...\n\n    this.foldingRules = new MyFoldMode();\n};</code></pre>\n                            <p>You&#39;ll be defining your code folding rules into the <em>lib/ace/mode/folding</em> folder. Here&#39;s a template that you can use to get started:</p>\n                            <pre><code class=\"language-javascript\">define(function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    // regular expressions that identify starting and stopping points\n    this.foldingStartMarker; \n    this.foldingStopMarker;\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n\n        // test each line, and return a range of segments to collapse\n    };\n\n}).call(FoldMode.prototype);\n\n});</code></pre>\n                            <p>Just like with <code>TextMode</code> for syntax highlighting, <code>BaseFoldMode</code> contains the starting point for code folding logic. <code>foldingStartMarker</code> defines your opening folding point, while <code>foldingStopMarker</code> defines the stopping point. For example, for a C-style folding system, these values might look like this:</p>\n                            <pre><code class=\"language-javascript\">this.foldingStartMarker = /(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/;\nthis.foldingStopMarker = /^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/;</code></pre>\n                            <p>These regular expressions identify various symbols--<code>{</code>, <code>[</code>, <code>//</code>--to pay attention to. <code>getFoldWidgetRange</code> matches on these regular expressions, and when found, returns the range of relevant folding points. For more information on the <code>Range</code> object, see <a href=\"#nav=api&amp;api=range\">the Ace API documentation</a>.</p>\n                            <p>Again, for a C-style folding mechanism, a range to return for the starting fold might look like this:</p>\n                            <pre><code class=\"language-javascript\">var line = session.getLine(row);\nvar match = line.match(this.foldingStartMarker);\nif (match) {\n    var i = match.index;\n\n    if (match[1])\n        return this.openingBracketBlock(session, match[1], row, i);\n\n    var range = session.getCommentFoldRange(row, i + match[0].length);\n    range.end.column -= 2;\n    return range;\n}</code></pre>\n                            <p>Let&#39;s say we stumble across the code block <code>hello_world() {</code>. Our range object here becomes:</p>\n                            <pre><code class=\"language-json\">{\n  startRow: 0,\n  endRow: 0,\n  startColumn: 0,\n  endColumn: 13\n}</code></pre>\n                            <h2>Testing Your Highlighter</h2>\n                            <p>The best way to test your tokenizer is to see it live, right? To do that, you&#39;ll want to modify the <a href=\"build/kitchen-sink.html\">live Ace demo</a> to preview your changes. You can find this file in the root Ace directory with the name <em>kitchen-sink.html</em>.</p>\n                            <ol>\n                                <li>\n                                    add an entry to <code>supportedModes</code> in <a href=\"https://github.com/ajaxorg/ace/blob/master/lib/ace/ext/modelist.js#L53\"><code>ace/ext/modelist.js</code></a>\n                                </li>\n                                <li>\n                                    <p>add a sample file to <code>demo/kitchen-sink/docs/</code> with same name as the mode file\n                                </li>\n                            </ol>\n                            <p>Once you set this up, you should be able to witness a live demonstration of your new highlighter.</p>\n                            <h3 id=\"adding-automated-tests\"><a class=\"heading_anchor\" href=\"#adding-automated-tests\"><i class=\"headerLinkIcon\"></i></a>Adding Automated Tests</h3>\n                            <p>Adding automated tests for a highlighter is trivial so you are not required to do it, but it can help during development.</p>\n                            <p>In <code>lib/ace/mode/_test</code> create a file named <code><pre>text_<span style=\"color:#AA0D91\">&lt;modeName&gt;</span>.txt</pre></code> with some example code. (You can skip this if the document you have added in <code>demo/docs</code> both looks good and covers various edge cases in your language syntax).\n                            </p>\n                            <p> Run <code><span style=\"color:#AA0D91\">node</span> <span style=\"color:#008800\">highlight_rules_test.js</span> <span style=\"color:#000088\">-gen</span></code> to preserve current output of your tokenizer in <code>tokens_<span style=\"color:#AA0D91\">&lt;modeName&gt;</span>.json</code>\n                            </p>\n                            <p>After this running <code><span style=\"color:#008800\">highlight_rules_test.js</span> <span style=\"color:#000088\">optionalLanguageName</span></code> will compare output of your tokenizer with the correct output you've created.\n                            </p>\n                            <p>Any files ending with the <em>_test.js</em> suffix are automatically run by Ace&#39;s <a href=\"https://travis-ci.org/#!/ajaxorg/ace\">Travis CI</a> server.</p>\n                        </div>\n                        <div class=\"tab-pane fade\" id=\"api\">\n                            <div class=\"row centerpiece\">\n                                <div id=\"sidebarContainer\" class=\"span2\">\n                                    <div id=\"sidebar\">\n                                        <div id=\"well\">\n                                            \n                                            <ul class=\"menu\">\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/ace.html\" class=\"menuLink namespace\">Ace</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/anchor.html\" class=\"menuLink namespace\">Anchor</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/background_tokenizer.html\" class=\"menuLink namespace\">BackgroundTokenizer     </a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/document.html\" class=\"menuLink namespace\">Document    </a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/edit_session.html\" class=\"menuLink namespace\">EditSession</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/editor.html\" class=\"menuLink namespace\">Editor</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/range.html\" class=\"menuLink namespace\">Range</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/scrollbar.html\" class=\"menuLink namespace\">Scrollbar</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/search.html\" class=\"menuLink namespace\">Search                     </a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/selection.html\" class=\"menuLink namespace\">Selection   </a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/token_iterator.html\" class=\"menuLink namespace\">TokenIterator</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/tokenizer.html\" class=\"menuLink namespace\">Tokenizer</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/undomanager.html\" class=\"menuLink namespace\">UndoManager</a></div>\n                                                </li>\n                                                <li>\n                                                    <div class=\"menu-item\"><a href=\"./api/virtual_renderer.html\" class=\"menuLink namespace\">VirtualRenderer</a></div>\n                                                </li>\n                                            </ul>\n                                        </div>\n                                    </div>\n                                </div>\n                                <div id=\"apiHolder\">\n                                    <div id=\"documentation\" class=\"span7\">\n                                    <h1>Ace API Reference</h1>\n                                    <p>Welcome to the Ace API Reference!</p>\n                                    <p>On the left, you'll find a list of all of our currently documented classes. \n                                        These is not a complete set of classes, but rather, the \"core\" set. For more \n                                        information on how to work with Ace, check out the <a href=\"#nav=embedding\">embedding guide</a>.\n                                    </p>\n                                    <p>Below is an ERD diagram describing some fundamentals about how the internals of Ace works:</p>\n                                    <img lazy-src=\"doc/template/resources/images/Ace_ERD.png\" style=\"max-width:100%; max-height:100%\" />\n                                </div>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"tab-pane fade\" id=\"production\">\n                            <h1>Projects Using Ace</h1>\n                            <p>Ace is used all over the web in all kinds of production applications. Here is\n                                just a small sampling:</p>\n                            <ul class=\"menu-list\" style=\"overflow: hidden;\">\n                                <li>\n                                    <div style=\"height: 100%;background: url(https://a0.awsstatic.com/main/images/logos/aws_smile-header-desktop-en-white_59x35@2x.png) no-repeat 0 7px/100px;\"></div>\n                                    <a href=\"https://aws.amazon.com/\">AWS</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/khan-logo.png\"\n                                        style=\"left: -10px; top: -27px; width: 120px\" />\n                                    <a href=\"http://ejohn.org/blog/introducing-khan-cs/\">Khan Academy</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/cloud9-logo.png\"\n                                        style=\"left: -11px;top:-12px; width:122px\" />\n                                    <a href=\"https://github.com/ajaxorg/cloud9\">Cloud9 IDE</a>\n                                </li>\n                                \n                                <li>\n                                    <img lazy-src=\"doc/site/images/codecademy-logo.png\"\n                                        style=\"left: -5px; top: 10px;\" />\n                                    <a href=\"http://www.codecademy.com/\">Codecademy</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/rstudio_logo_64.png\"\n                                        style=\"left: 19px; top: 2px;\" />\n                                    <a href=\"http://rstudio.org/\">RStudio</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://zedapp.s3.amazonaws.com/uploads/2014/02/zed-small.png\" style=\"left: -1px;top: -20px;width: 103px;\">\n                                    <a href=\"http://zedapp.org\">Zed</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://raw.githubusercontent.com/creationix/tedit/gh-pages/icons/icon-128.png\"\n                                        style=\"width: 104px; left: -1px; top: -17px;\">\n                                    <a href=\"https://github.com/creationix/tedit\">Tedit</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png\" style=\"left: -5px; top: -35px; width: 110px;\">\n                                    <a href=\"https://en.wikipedia.org/wiki/Special:Version\" style=\"font-family: 'Linux Libertine','Hoefler Text',Georgia,'Times New Roman',Times,serif;\">W<span style=\"font-variant: small-caps;\">ikipedi</span>A</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/codiad.png\"\n                                        style=\"left: 10px; top: -4px; width:80px\" />\n                                    <a href=\"http://codiad.com/\">Codiad</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://afreetools.com/wp-content/uploads/2024/04/logo-dark.png\"\n                                        style=\"left: 10px; top: -4px; width:80px\" />\n                                    <a href=\"https://afreetools.com\">aFreeTools</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/shiftedit-logo.png\"\n                                        style=\"left: -10px; top: -20px; width: 120px\" />\n                                    <a href=\"http://shiftedit.net/\">ShiftEdit</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/sassmeister-logo.png\"\n                                        style=\"left: 10px;top: -5px;width: 80px;\" />\n                                    <a href=\"http://sassmeister.com/\">SassMeister</a>\n                                </li> \n                                <li>\n                                    <img lazy-src=\"doc/site/images/sx-logo.png\"\n                                        style=\"left: -11px; top: -12px;\">\n                                    <a href=\"http://www.scroipe.com\">Scroipe</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/ideone-logo.png\"\n                                        style=\"left: -5px; top: 20px;\">\n                                    <a href=\"http://ideone.com\">Ideone.com</a>\n                                </li>\n                                <li>\n                                    <div style=\"\n                                        background: url(https://lively-web.org/core/media/lively-web-logo.png) no-repeat;\n                                        position: absolute; left: -5px; height: 71px; width: 103px; background-size: 390px;\n                                        background-position: 19px;\"></div>\n                                    \n                                    <a href=\"http://lively-web.org\">Lively Web</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"doc/site/images/modx-logo-4.png\"\n                                        style=\"left: 18px; top: 6px;\">\n                                    <a href=\"http://modx.com/extras/package/ace\">MODX</a>\n                                </li>\n                                <li>\n                                    <div class=\"rotating-logo\" style=\"background:url(doc/site/images/habitat-logo.svg) center no-repeat;\n                                        left: 19px; top: 6px;width: 60px;height: 60px;background-size: 60px;position: relative;\"></div>\n                                    <a href=\"http://habitat.inkling.com\">Inkling Habitat</a>\n                                </li>\n                                <li style=\"width: 248px;\">\n                                    <img lazy-src=\"https://codecombat.com/images/pages/base/logo.png\" style=\"left: 0px; top: 1px; width: 248px\">\n                                    <a href=\"http://codecombat.com\">Code Combat</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://papeeria.com/assets/all/images/papeeria_small.png\" style=\"width: 95px; left: 2px; top: 8px;\">\n                                    <a href=\"http://papeeria.com\">Papeeria</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://www.codingame.com/blog/wp-content/uploads/2016/11/logo_codingame_hud.png\"\n                                        style=\"left: -15px;top: 27px;width: 127px;background: black;\" />\n                                    <a href=\"https://www.codingame.com\">CodinGame</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">Dillinger</div>\n                                    <a href=\"http://dillinger.io/\">Dillinger</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">Edicy</div>\n                                    <a href=\"http://www.edicy.com/blog/new-code-editor-for-creating-unique-website-designs\">Edicy</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">pixelJET</div>\n                                    <a href=\"http://www.pixeljet.net/index.html\">pixelJET</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://approximatrix.com/static/images/simplytext/logo-long-white.png\"\n                                        style=\"width: 106px; left: -4px; top: 26px;\">\n                                    <a href=\"http://approximatrix.com/products/simplytext\">Simply Text</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\" style=\"font-size: 18px;\">ACEView</div>\n                                    <a href=\"https://github.com/faceleg/ACEView\">ACEView</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\" style=\"margin-left:-12px;\">BootTheme</div>\n                                    <a href=\"http://www.boottheme.com/\">BootTheme</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://codebender.cc/images/codebender-transparent.png\"\n                                        style=\"left: -9px; width: 117px;top: -22px;\">\n                                    <a href=\"http://codebender.cc/\">Codebender</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\" style=\"margin-left:-5px;\">Debuggex</div>\n                                    <a href=\"http://www.debuggex.com\">Debuggex</a>\n                                </li>\n                                <li>\n                                    <script>\n                                        ace.require(\"ace/lib/dom\").importCssStylsheet(\"https://fonts.googleapis.com/css?family=Henny+Penny\", document);\n                                    </script>\n                                    <div class=\"text-logo\" style=\"margin-left:-17px;font-family:'Henny Penny',cursive;\">ChocolateJs</div>\n                                    <a href=\"https://chocolatejs.org\">Chocolatejs</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://playir.com/common/icon_playir.png\"\n                                        style=\"left: 11px; width: 96px;top: -17px;\">\n                                    <a href=\"http://playir.com\">Playir</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://joshnuss.github.io/mruby-web-irb/images/favicon.png\"\n                                        style=\"left: 4px; width: 90px;top: -17px;\">\n                                    <a href=\"http://joshnuss.github.io/mruby-web-irb/\">Mruby-web-irb</a>\n                                </li>\n                                <li>\n                                    <div style=\"font-size:50px\" class=\"text-logo\">t<span style=\"color:green\">p<span></div>\n                                    <a href=\"https://www.tutorialspoint.com/online_html_editor.php\">tutorialspoint</a>\n                                </li>\n                                <li title=\"Online conference and code review tool\">\n                                    <div style=\"width: 90px; left: 10px; top: 0px;background:rgb(24,73,92);color: white;position: absolute;\n                                        font-size: 68px;text-align: center;font-weight: bold;font-family: inherit;line-height: normal;\">sT</div>\n                                    <a href=\"http://sourcetalk.net/\">SourceTalk</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\" style=\"margin-top:4px\">Run PHP Code</div>\n                                    <a href=\"https://github.com/websiteduck/Run-PHP-Code\">RunPHPCode</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://cloudcmd.io/img/logo/cloudcmd.png\"\n                                        style=\"width: 108px; left: -4px; top: -2px;\">\n                                    <a href=\"http://cloudcmd.io\">Cloud Commander</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">NapCat</div>\n                                    <a href=\"http://napcatapp.tumblr.com/post/60598006734/version-1-3-is-released\">NapCat</a>\n                                </li>\n                                <li>\n                                    <div style=\"color:orange;font-size:50px\" class=\"text-logo\">OJ</div>\n                                    <a href=\"http://ojjs.org/index.html\">OJjs</a>\n                                </li>\n                                <li>\n                                    <div style=\"color:green;font-size:50px\" class=\"text-logo\">&lt;/&gt;</div>\n                                    <a href=\"https://thlorenz.github.io/scriptie-talkie/\">Scriptie-Talkie</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">md</div>\n                                    <a href=\"https://thlorenz.github.io/browserify-markdown-editor/\">browserify-markdown-editor</a>\n                                </li>\n                                <li>\n                                    <!-- <img src=\"https://www.siteleaf.com/images/logo.svg\" style=\"left: 20px; top: -15px; width: 60px;\"> -->\n                                    <a href=\"https://www.siteleaf.com/\">Siteleaf</a>\n                                </li>\n                                <li>\n                                    <div class=\"\" style=\"\n                                        background: url(https://colorsublime.github.io/assets/img/ColorSublime_logo.png);\n                                        position: absolute;height: 65px;width: 99px;\n                                        background-size: 310px 128px;background-position: 210px top;\n                                    \"></div>\n                                    <a href=\"https://colorsublime.github.io/\">ColorSublime</a>\n                                </li>\n                                <li>\n                                    <div style=\"\n                                        background: url(https://s3.amazonaws.com/spark-website/spark.png) no-repeat;\n                                        position: absolute; height: 65px; width: 83px; background-size: 200px 65px;\n                                        background-position: 19px;\"></div>\n                                    <a href=\"http://spark.io/build\">Spark Core</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://2.gravatar.com/avatar/021e207e86fe81a7d81c67ef1ff38a0c\" style=\"left: 11px; top: -5px;\">\n                                    <a href=\"http://owncloud.org\">ownCloud</a>\n                                </li>\n                                <li>\n                                   <!--  <img src=\"https://www.ezoui.com/prod/images/EZo_logo.png\" style=\"left: 11px; top: -5px;\"> -->\n                                    <a href=\"http://jqmdesigner.appspot.com\">JQM Designer</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">qooxdoo</div>\n                                    <a href=\"http://demo.qooxdoo.org/devel/playground/#\">Qooxdoo playground</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">ShareJS</div>\n                                    <a href=\"http://sharejs.org/hello-ace.html\">ShareJS</a>\n                                </li>\n                                <li>\n                                    <div style=\"\n                                        background: url(https://www.pythonanywhere.com/static/anywhere/images/logo-234x35.png) no-repeat;\n                                        position: absolute; height: 65px; width: 94px; background-size: 234px 35px;\n                                        background-position: 19px;\"></div>\n                                    <a href=\"http://www.pythonanywhere.com/\">PythonAnywhere</a>\n                                </li>\n                                <li>\n                                   <!--  <img src=\"https://asciidocfx.com/images/logo.png\" style=\"width: 75px; left: 12px; top: 0px;\"> -->\n                                    <a href=\"http://asciidocfx.com/\">Asciidoc FX</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://raw.githubusercontent.com/wintercms/winter/refs/heads/develop/modules/backend/assets/images/logo.svg\" style=\"width: 86px; left: 7px; top: -12px;\">\n                                    <a href=\"https://wintercms.com\">Winter CMS</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://octobercms.com/themes/website/assets/images/october.png\" style=\"width: 75px; left: 13px; top: -2px;\">\n                                    <a href=\"http://octobercms.com\">October CMS</a>\n                                </li>\n                                <li style=\"width: 248px;\">\n                                    <img lazy-src=\"https://www.codeavengers.com/image/RedLogoSmall.png\" style=\"width: 248px; top: 30px;\">\n                                    <a href=\"http://www.codeavengers.com/image/RedLogoSmall.png\">Code Avengers</a>\n                                </li>\n                                <li>\n                                    <div style=\"font-size:23px\" class=\"text-logo\">{dev<span style=\"color:#ef4423\">un</span>ity}</div>\n                                    <a href=\"http://devunity.com/\">Devunity</a>\n                                </li>\n                                <li style=\"width: 248px;\">\n                                    <img lazy-src=\"https://d2j5eocv5gptnv.cloudfront.net/assets/non_game_misc/site_header_logo.png?v=2\" style=\"width: 238px; top: 15px; left: 5px\">\n                                    <a href=\"http://www.codemonkey.co.il/\">CodeMonkey</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://funprogramming.org/i/fun_programming_logo_for_ace.png\" style=\"width: 75px; left: 12px; top: -5px;\">\n                                    <a href=\"http://funprogramming.org\">Fun Programming</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://lh4.ggpht.com/hG5bDu1GBXwxpPnrgPcAmTNQyZK4ICBDC9aeLNmMZahEYQOz_2vYT6sBqLNGLIGPopWjdveEvPuM9NBuErUSLQ=s60\" style=\"width: 75px; left: 12px; top: -5px;\">\n                                    <a href=\"http://bootzee.com\">Bootzee</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://www.branchcms.com/layout/images/branch-brand-logo-2.png\" style=\"width: 125px; left: -12px; top: 15px;\">\n                                    <a href=\"http://www.branchcms.com/blog/post/new-code-editor-ace\">Branch CMS</a>\n                                </li>\n                                <li>\n                                   <!--  <img src=\"https://neocities.org/assets/img/cat.png\" style=\"width: 95px; left: 2px; top: 0px;\"> -->\n                                    <a href=\"https://neocities.org\">Neocities</a>\n                                </li>\n                                <li>\n                                   <!--  <img src=\"https://webftp.selfbuild.fr/images/logo/logo_128.png\" style=\"width: 95px; left: 2px; top: -17px;\"> -->\n                                    <a href=\"http://webftp.selfbuild.fr\">SelfBuild </a>\n                                </li>\n                                <li>\n                                    <!-- <img src=\"https://sbp.selfbuild.fr/sbp.png\" style=\"width: 95px; left: 2px; top: -8px;\"> -->\n                                    <a href=\"http://sbp.selfbuild.fr/\">SBP</a>\n                                </li>\n                                <li>\n                                    <!-- <img src=\"https://eseecode.com/web/sites/eseecode.com/files/favicon.png\" style=\"width: 100px; left: 0px; top: -20px;\"> -->\n                                    <a href=\"http://eseecode.com/\">eSeeCode</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://codinghire.com/static/img/twitter.png\" style=\"width: 80px; left: 10px; top: -3px;\">\n                                    <a href=\"https://codinghire.com/\">Coding Hire</a>\n                                </li>\n                                <li>\n                                    <div style=\"\"></div>\n                                    <a href=\"http://apiary.io/\">Apiary</a>\n                                </li>\n                                <li>\n                                    <!-- <img src=\"https://exist-db.org/exist/apps/eXide/resources/images/logo.png\" style=\"width: 120px; left: -10px; top: 15px;\"> -->\n                                    <a href=\"http://exist-db.org\">ExistDB</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://jscalc.io/img/icons/jscalc_full_bleed_24.svg\" style=\"width: 90px; left: 5px; top: -10px;\">\n                                    <a href=\"https://jscalc.io/\">JSCalc</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://www.gestixi.com/assets/img/icons/gestixi-64.png\" style=\"width: 90px; left: 5px; top: 20px;\">\n                                    <a href=\"https://www.gestixi.com/\">GestiXi</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\" style=\"font-size:22px;text-shadow:none;margin-top:13px\">Code-Fight.Club</div>\n                                    <a href=\"http://code-fight.club\">Code-Fight.Club</a>\n                                </li>\n                                \n                                <li>\n                                    <a href=\"http://www.wavemaker.com/\">WaveMaker</a>\n                                </li>\n                                \n                                <li>\n                                    <div class=\"text-logo\">Semantic Ui</div>\n                                    <a href=\"http://semantic-ui.com/\">Semantic Ui</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">tmpltr</div>\n                                    <a href=\"http://rocktronica.github.io/tmpltr/\">tmpltr</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">Git-Edit</div>\n                                    <a href=\"https://github.com/krispo/git-edit\">Git-Edit</a>\n                                </li>\n                                <li>\n                                    <a href=\"http://codebender.cc/\">Codebender</a>\n                                </li>\n                                <li>\n                                    <a href=\"http://beautifytools.com/\">BeautifyTools</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">trinket</div>\n                                     <a href=\"https://trinket.io/\">trinket</a>\n                                </li>\n                                <li>\n                                    <a href=\"https://goonlinetools.com/\">GoOnlineTools</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://sqlize.online/favicons/sqlize/android-chrome-192x192.png\" style=\"width: 72px; left: 15px; top: 0px;\">\n                                    <a href=\"https://sqlize.online/\">SQLize.online</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://phpize.online/favicons/phpize/android-chrome-192x192.png\" style=\"width: 72px; left: 15px; top: 0px;\">\n                                    <a href=\"https://phpize.online/\">PHPize.online</a>\n                                </li>\n                                <li>\n                                    <div class=\"text-logo\">Domoticz</div>\n                                    <a href=\"https://www.domoticz.com/\">Domoticz</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://nixx.dev/static/hotlink-ok/logo-alt.png\" style=\"width: 72px; left: 15px; top: 0px;\">\n                                    <a href=\"https://nixx.dev\">Nixx Web Tools</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://acode.foxdebug.com/logo.svg\" style=\"width: 72px; left: 15px; top: 10px;\">\n                                    <a href=\"https://acode.foxdebug.com\">Acode</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://tool.next2d.app/assets/img/logo.svg\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://next2d.app/\">Next2D</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://github.com/devlive-community/datacap/blob/dev/core/datacap-ui/public/static/images/logo.png?raw=true\" style=\"width: 72px; left: 15px; top: 0px;\">\n                                    <a href=\"https://github.com/devlive-community/datacap\">DataCap</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://aijs.io/images/purpleLogo.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://aijs.io/editor\">AIJS</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://k8studio.io/logo.png\" style=\"width: 85px; left: 7px; top: 25px; background-color: black; margin: -5px; padding: 5px;\">\n                                    <a href=\"https://k8studio.io/\">K8Studio</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://hardcoder.xyz/favicon.ico\" style=\"width: 72px; left: 15px; top: -2px;\">\n                                    <a href=\"https://hardcoder.xyz/?mkp=fncd\">Funcdown</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://sqltest.online/favicons/android-chrome-192x192.png\" style=\"width: 72px; left: 15px; top: 0px;\">\n                                    <a href=\"https://sqltest.online/\">SQLtest.online</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://hiren.js.org/H.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://hiren.js.org/\">HirenJS Code Editor</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://hyena-code.web.app/assets/universal/imgs/logo.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://hyena-code.web.app/\">Hyena Code</a>\n                                </li>\n\t\t\t                    <li>\n                                    <img lazy-src=\"https://techcopes.com/logo.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://techcopes.com/\">Techcopes</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://media.geeksforgeeks.org/gfg-gg-logo.svg\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://www.geeksforgeeks.org/\">Geeks for geeks</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://jsonedit.com/assets/img/jsoneditlogo.png\" style=\"width: 85px; left: 7px; top: 20px; background-color: rgb(4, 19, 19);\">\n                                    <a href=\"https://jsonedit.com/\">JSONEdit</a>\n                                </li>\t\t\n                                <li>\n                                    <img lazy-src=\"https://panel.bastify.com/dist/images/logo.svg\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://www.bastify.com/\">Bastify</a>\n                                </li>\t\n                                <li>\n                                    <img lazy-src=\"https://xuantuyen.education/assets/img/logo.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://www.xuantuyen.education/\">XUÂN TUYẾN Education</a>\n                                </li>\t\t\n\t\t\t\t<li>\n                                    <img lazy-src=\"https://gamaddy.com/gamaddy.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://gamaddy.com/\">Gamaddy</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://opensolr.com/img/logo-simple.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://opensolr.com/\">Opensolr</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://oppydev.ai/wp-content/uploads/2024/09/LogoIcon.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://oppydev.ai/\">OppyDev</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://contao.org/files/images/contao-logo.svg\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://contao.org/\">Contao</a>\n                                </li>\n\t\t\t\t<li>\n                                    <img lazy-src=\"https://image.aisofto.com/avatars/17f6c731-257c-4aa4-9654-279a8e099c8c.png\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://aisofto.com/\">AiSofto</a>\n                                </li>\n                                <li>\n                                    <img lazy-src=\"https://chartbrew-static.b-cdn.net/logos/Cuplogo.svg\" style=\"width: 85px; left: 7px; top: -7px;\">\n                                    <a href=\"https://chartbrew.com/\">Chartbrew</a>\n                                </li>\n\t\t\t\t\t    \n                                <li id=\"add_your_site\">\n                                    <p>+</p>\n                                    <a href=\"https://github.com/ajaxorg/ace/issues/new?assignees=&labels=website%2Cneeds-triage&projects=&template=add-to-website.yml&title=Add+project+%28project+name%29+to+the+list+of+projects+using+Ace+on+its+website\">Your Site Here</a>\n                                </li>\n                            </ul>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <script src=\"./doc/site/js/jquery.min.js\"></script>\n        <script src=\"./doc/site/js/bootstrap.min.js\"></script>\n        <script src=\"./doc/template/resources/javascripts/bbq.js\"></script>        \n        <script src=\"./doc/site/js/main.js\"></script>        \n        <script defer src=\"./doc/site/js/ga.js\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "kitchen-sink.html",
    "content": "<!DOCTYPE html>\n\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width,height=device-height\" />\n    <title>Ace Kitchen Sink</title>\n    <meta name=\"author\" content=\"Fabian Jakobs\">\n\n    <link rel=\"stylesheet\" href=\"demo/kitchen-sink/styles.css\" type=\"text/css\" media=\"screen\" charset=\"utf-8\">\n\n    <link href=\"./doc/site/images/favicon.ico\" rel=\"icon\" type=\"image/x-icon\">\n</head>\n<body>\n<div id=\"sidePanel\" style=\"position:absolute;height:100%;width:280px;\">\n  <div class=\"toggleButton\" id=\"optionToggle\" role=\"button\" aria-label=\"Hide Options\" tabindex=\"0\">\n    <div></div><div></div><div></div>\n  </div>\n  <a href=\"https://c9.io\">\n    <img id=\"c9-logo\" alt=\"Cloud9 IDE | Your code anywhere, anytime\" src=\"demo/kitchen-sink/logo.png\" style=\"width: 172px;margin: -9px 30px -12px 51px;\">\n  </a>\n  <div style=\"position: absolute; overflow: hidden; top:100px; bottom:0;width:100%;\">\n  <div id=\"optionsPanel\" style=\"height:100%; width:100%; overflow-y: auto\">\n\n  \n  <a href=\"https://ace.c9.io\">\n    <img id=\"ace-logo\" alt=\"Ace Website\" src=\"doc/site/images/ace-logo.png\" style=\"width: 134px;margin: 46px 0px 4px 66px;\">\n  </a>\n<!--DEVEL-->\n  <div style=\"text-align: left; padding: 0.5em 1em;\">\n    <a style=\"color: whitesmoke;\" target=\"_test\"  rel=\"noreferer\" href=\"./src/test/tests.html\">tests</a>\n  </div>\n  <div style=\"text-align: left; padding: 0.5em 1em;\">\n    <a style=\"color: whitesmoke;\" target=\"_test\"  rel=\"noreferer\" href=\"./tool/mode_creator.html\">Mode Creator</a>\n  </div>\n  <div style=\"text-align: left; padding: 0.5em 1em;\">\n    <a style=\"color: whitesmoke;\" target=\"_test\"  rel=\"noreferer\" href=\"./tool/perf-test.html\">Performance test</a>\n  </div>\n  <div style=\"text-align: left; padding: 0.5em 1em;\">\n    <a style=\"color: whitesmoke;\" href=\"?lib=1\">Load from lib/ace</a>\n  </div>\n  <div style=\"text-align: left; padding: 0.5em 1em;\">\n    <a style=\"color: whitesmoke;\" href=\"./demo/diff/index.html\">Diff viewer</a>\n  </div>\n<!--DEVEL-->\n  </div>\n  </div>\n</div>\n  <div id=\"editor-container\"></div>\n\n<!--DEVEL-->\n  <script type=\"text/javascript\">\n    var os = /os=(\\w+)|$/.exec(location.search)[1];\n    if (os) Object.defineProperty(navigator, \"platform\", {configurable:true, value: os});\n  </script>\n  <script src=\"demo/kitchen-sink/require.js\" type=\"text/javascript\"></script>\n  <script>\n    var useLib = /lib=1/.test(location.search);\n    var paths = useLib ? {\n      ace: \"lib/ace\",\n      demo: \"demo/kitchen-sink\"\n    } : {\n      ace: \"src\",\n      demo: \"demo/kitchen-sink\",\n      \"ace/worker/worker_client\": \"lib/ace/worker/worker_client_v2\",\n      \"ace/worker\": \"lib/ace/worker\",\n    };\n    \n    if (!useLib) {\n      [\n        \"json_worker\",\n        \"xquery_worker\",\n        \"yaml_worker\",\n        \"xquery/xqlint\",\n        \"xquery/jsoniq_lexer\",\n        \"xquery/xquery_lexer\",\n        \"css/csslint\",\n        \"coffee_worker\",\n        \"css_worker\",\n        \"xquery\",\n        \"html/saxparser\",\n        \"php/php\",\n        \"lua/luaparse\",\n        \"xml/sax\",\n        \"xml/dom-parser\",\n        \"xml/dom\",\n        \"lua_worker\",\n        \"jsoniq\",\n        \"json/json_parse\",\n        \"xml_worker\",\n        \"coffee/coffee\",\n        \"javascript_worker\",\n        \"php_worker\",\n        \"yaml/yaml-lint\",\n        \"javascript/jshint\",\n        \"html_worker\",\n      ].forEach(function(m) {\n        paths[\"ace/mode/\" + m] = \"lib/ace/mode/\" + m\n      })\n    }\n    \n    require.config({\n        paths: paths\n    });\n    require([\"ace/ace\"], function (ace) {\n        require([\"demo/demo.js\"], function (demo) {\n        });\n    });\n  </script>\n<!--DEVEL-->\n\n<!--PACKAGE\n  <script src=\"src/ace.js\" data-ace-base=\"src\" type=\"text/javascript\" charset=\"utf-8\"></script>\n  <script src=\"demo/kitchen-sink/demo.js\"></script>\n  <script type=\"text/javascript\" charset=\"utf-8\">\n    require(\"kitchen-sink/demo\");\n  </script>\n    PACKAGE-->\n\n</body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"ace-code\",\n    \"description\": \"Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE\",\n    \"version\": \"1.43.6\",\n    \"homepage\": \"https://github.com/ajaxorg/ace\",\n    \"engines\": {\n        \"node\": \">= 0.6.0\"\n    },\n    \"author\": \"Fabian Jakobs <fabian@c9.io>\",\n    \"main\": \"src/ace.js\",\n    \"typings\": \"ace.d.ts\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/ajaxorg/ace.git\"\n    },\n    \"devDependencies\": {\n        \"amd-loader\": \"~0.0.4\",\n        \"architect-build\": \"https://github.com/c9/architect-build/tarball/43a6fdeffe\",\n        \"asyncjs\": \"~0.0.12\",\n        \"c8\": \"^11.0.0\",\n        \"dryice\": \"0.4.11\",\n        \"eslint\": \"^8.20.0\",\n        \"mocha\": \"^11.7.5\",\n        \"standard-version\": \"^9.3.2\",\n        \"typescript\": \"5.9.2\"\n    },\n    \"mappings\": {\n        \"ace\": \".\"\n    },\n    \"license\": \"BSD-3-Clause\",\n    \"files\": [\n        \"src\",\n        \"styles\",\n        \"ace.d.ts\",\n        \"ace-modes.d.ts\",\n        \"types\",\n        \"esm-resolver.js\",\n        \"translations\",\n        \"!**/*_test.js\",\n        \"!**/_test\"\n    ],\n    \"scripts\": {\n        \"start\": \"node static.js\",\n        \"test\": \"mocha \\\"./src/**/*_test.js\\\"  --exit -p --color\",\n        \"cover\": \"c8 --reporter=lcov  --reporter=text-summary npm run test\",\n        \"cover-json\": \"c8 --reporter=json npm run test\",\n        \"lint\": \"eslint \\\"src/**/*.js\\\" \\\"*.js\\\"\",\n        \"fix\": \"npm run lint -- --fix\",\n        \"typecheck\": \"tsc -p tsconfig.json\",\n        \"update-types\": \"node ./tool/ace_declaration_generator.js\",\n        \"changelog\": \"standard-version\",\n        \"prepack\": \"node tool/esm_resolver_generator.js && node tool/ace_declaration_generator.js && node Makefile.dryice.js css --target build-styles && rm -rf styles && mv build-styles/css styles\"\n    },\n    \"standard-version\": {\n        \"skip\": {\n            \"commit\": true,\n            \"tag\": true\n        }\n    },\n    \"prettier\": {\n        \"printWidth\": 120,\n        \"tabWidth\": 4,\n        \"useTabs\": false,\n        \"semi\": true,\n        \"singleQuote\": false,\n        \"trailingComma\": \"none\",\n        \"bracketSpacing\": false,\n        \"arrowParens\": \"always\",\n        \"requirePragma\": false,\n        \"insertPragma\": false,\n        \"proseWrap\": \"preserve\"\n    }\n}\n"
  },
  {
    "path": "src/ace.js",
    "content": "/**\n * The main class required to set up an Ace instance in the browser.\n *\n * @namespace Ace\n **/\n\"use strict\";\n\"include loader_build\";\n\nvar dom = require(\"./lib/dom\");\n\nvar Range = require(\"./range\").Range;\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar Renderer = require(\"./virtual_renderer\").VirtualRenderer;\n\n// The following require()s are for inclusion in the built ace file\nrequire(\"./worker/worker_client\");\nrequire(\"./keyboard/hash_handler\");\nrequire(\"./placeholder\");\nrequire(\"./multi_select\");\nrequire(\"./mode/folding/fold_mode\");\nrequire(\"./theme/textmate\");\nrequire(\"./ext/error_marker\");\n\nexports.config = require(\"./config\");\n\n\n/**\n * Embeds the Ace editor into the DOM, at the element provided by `el`.\n * @param {String | HTMLElement & {env?: any, value?: any} | null} [el] Either the id of an element, or the element itself\n * @param {Partial<import(\"../ace-internal\").Ace.EditorOptions> } [options] Options for the editor\n * @returns {Editor}\n **/\nexports.edit = function(el, options) {\n    if (typeof el == \"string\") {\n        var _id = el;\n        el = document.getElementById(_id);\n        if (!el)\n            throw new Error(\"ace.edit can't find div #\" + _id);\n    }\n\n    if (el && el.env && el.env.editor instanceof Editor)\n        return el.env.editor;\n\n    var value = \"\";\n    if (el && /input|textarea/i.test(el.tagName)) {\n        var oldNode = el;\n        value = oldNode.value;\n        el = dom.createElement(\"pre\");\n        oldNode.parentNode.replaceChild(el, oldNode);\n    } else if (el) {\n        value = el.textContent;\n        el.innerHTML = \"\";\n    }\n\n    var doc = exports.createEditSession(value);\n    var editor = new Editor(new Renderer(el), doc, options);\n\n    var env = {\n        document: doc,\n        editor: editor,\n        onResize: editor.resize.bind(editor, null)\n    };\n    if (oldNode) env.textarea = oldNode;\n    editor.on(\"destroy\", function() {\n        env.editor.container.env = null; // prevent memory leak on old ie\n    });\n    editor.container.env = editor.env = env;\n    return editor;\n};\n\n/**\n * Creates a new [[EditSession]], and returns the associated [[Document]].\n * @param {import('./document').Document | String} text {:textParam}\n * @param {import(\"../ace-internal\").Ace.SyntaxMode} [mode] {:modeParam}\n * @returns {EditSession}\n **/\nexports.createEditSession = function(text, mode) {\n    var doc = new EditSession(text, mode);\n    doc.setUndoManager(new UndoManager());\n    return doc;\n};\nexports.Range = Range;\nexports.Editor = Editor;\nexports.EditSession = EditSession;\nexports.UndoManager = UndoManager;\nexports.VirtualRenderer = Renderer;\nvar version = exports.config.version;\nexports.version = version;\n"
  },
  {
    "path": "src/ace_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar dom = require(\"./lib/dom\");\nvar ace = require(\"./ace\");\nvar assert = require(\"./test/assertions\");\nvar lang = require(\"./lib/lang\");\n\nmodule.exports = {\n   \"test: ace edit\" : function() {\n        var editor = ace.edit(null, {\n            value: \"Helo world\"\n        });\n        assert.equal(editor.getValue(), \"Helo world\");\n        \n        var session = ace.createEditSession(\"Juhu kinners!\");\n        editor.setSession(session);\n        assert.equal(editor.getValue(), \"Juhu kinners!\");\n        \n        assert.equal(editor, ace.edit(editor.container));\n        editor.destroy();\n    },\n    \"test: edit textarea\" : function() {\n        var el = document.createElement(\"textarea\");\n        document.body.appendChild(el);\n        var editor = ace.edit(el);\n        assert.notEqual(editor.container, el);\n        \n        editor.container.id = \"editor1\";\n        assert.equal(editor, ace.edit(\"editor1\"));\n        editor.destroy();\n        document.body.removeChild(editor.container);\n    },\n    \"test: edit element by id\" : function() {\n        var el = document.createElement(\"div\");\n        document.body.appendChild(el);\n        var editor = null;\n        try {\n            editor = ace.edit(\"x\");\n        } catch(e) {\n        }\n        assert.equal(editor, null);\n        \n        el.id = \"editor2\";\n        el.textContent = \"h\";\n        editor = ace.edit(\"editor2\");\n        assert.equal(el, editor.container);\n        assert.equal(\"h\", editor.getValue());\n        document.body.removeChild(el);\n    },\n    \"test: destroy\": async function(done) {\n        var editor = ace.edit();\n        var mouseTarget = editor.renderer.getMouseEventTarget();\n        var textarea = editor.textInput.getElement();\n        \n        // editor.curOp is undefined after commands\n        sendText(textarea, \"x\");\n        assert.ok(!editor.curOp);\n        assert.equal(editor.getValue(), \"x\");\n        \n        // editor.curOp is defined if api is used without endOperation\n        editor.insert(\"1\");\n        assert.ok(editor.curOp);\n        \n        // clicking on editor calls focus\n        var focusCalled = 0;\n        editor.focus = function() { focusCalled++; };\n        click(mouseTarget);\n        assert.equal(focusCalled, 1);\n        \n        editor.destroy();\n\n        // clicking on destroyed editor doesn't call focus\n        click(mouseTarget);\n        assert.equal(focusCalled, 1);\n\n        await lang.sleep(0);\n        assert.notOk(!!editor.curOp);\n\n        // input commands on destroed editor without session do not throw errors\n        editor.setSession(null);\n        sendText(textarea, \"2\");\n\n        done();\n    },\n    \"test: useStrictCSP\": function() {\n        ace.config.set(\"useStrictCSP\", undefined);\n        function getStyleNode() {\n            return document.getElementById(\"test.css\");\n        }\n        assert.ok(!getStyleNode());\n        dom.importCssString(\"test{}\", \"test.css\", false);\n        assert.ok(!getStyleNode());\n\n        ace.config.set(\"useStrictCSP\", true);\n        assert.ok(!getStyleNode());\n\n        ace.config.set(\"useStrictCSP\", false);\n        assert.ok(getStyleNode());\n    },\n    \"test: resizeObserver\": async function(done) {\n        var mockObserver = {\n            disconnect: function() { mockObserver.target = null; },\n            observe: function(el) {\n                mockObserver.target = el;\n            },\n            $create: function(fn) {\n                mockObserver.callback = fn;\n                return mockObserver;\n            },\n            call: function() {\n                setTimeout(function() {\n                    if (mockObserver.target)\n                        mockObserver.callback([{contentRect: mockObserver.target.getBoundingClientRect()}]);\n                });\n            }\n        };\n        if (!window.ResizeObserver) {\n            window.ResizeObserver = mockObserver.$create;\n        }\n        var editor = ace.edit(null);\n        document.body.appendChild(editor.container);\n        editor.container.style.width = \"100px\";\n        editor.container.style.height = \"100px\";\n        mockObserver.call();\n        editor.resize(true);\n        assert.ok(!editor.renderer.$resizeTimer.isPending());\n        assert.equal(editor.renderer.$size.width, 100);\n        editor.container.style.width = \"200px\";\n        mockObserver.call();\n\n        await lang.sleep(15);\n        if (editor.renderer.$resizeTimer.isPending())\n            editor.renderer.$resizeTimer.call();\n        assert.equal(editor.renderer.$size.width, 200);\n        editor.container.style.height = \"200px\";\n        mockObserver.call();\n\n        await lang.sleep(15);\n        assert.ok(editor.renderer.$resizeTimer.isPending());\n        editor.container.style.height = \"100px\";\n        mockObserver.call();\n\n        await lang.sleep(15);\n        assert.ok(!editor.renderer.$resizeTimer.isPending());\n        editor.setOption(\"useResizeObserver\", false);\n        editor.container.style.height = \"300px\";\n        mockObserver.call();\n        assert.ok(!editor.renderer.$resizeObserver);\n        editor.setOption(\"useResizeObserver\", true);\n        assert.ok(editor.renderer.$resizeObserver);\n        if (window.ResizeObserver === mockObserver.$create)\n            window.ResizeObserver = undefined;\n        editor.destroy();\n        done();\n    },\n    \"test: edit template\" : function() {\n        var template = document.createElement(\"template\");\n        var div = document.createElement(\"div\");\n        template.content = document.createDocumentFragment();\n        template.content.appendChild(div);\n        var fragment = template.content.cloneNode(true);\n        var el = fragment.firstChild;\n        //emulating template content document fragment behaviour in browser\n        //which cause #4634 issue (virtual Document that doesn't have `documentElement`)\n        el.ownerDocument = {};\n        var editor = ace.edit(el);\n        assert.equal(editor.container, el);\n        editor.destroy();\n    }\n};\n\n/*global CustomEvent*/\nfunction click(node) {\n    node.dispatchEvent(new CustomEvent(\"mousedown\"));\n}\n\nfunction sendText(textarea, text) {\n    textarea.value = textarea.value.slice(0, textarea.selectionStart) + text\n        +  textarea.value.slice(textarea.selectionEnd);\n    textarea.dispatchEvent(new CustomEvent(\"input\"));\n}\n\n\nrequire(\"./test/run\")(module);\n"
  },
  {
    "path": "src/anchor.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./document\").Document} Document\n */\nvar oop = require(\"./lib/oop\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n\n/**\n * Defines a floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the anchor is updated.\n **/\nclass Anchor {\n    /**\n     * Creates a new `Anchor` and associates it with a document.\n     *\n     * @param {Document} doc The document to associate with the anchor\n     * @param {Number|import(\"../ace-internal\").Ace.Point} row The starting row position\n     * @param {Number} [column] The starting column position\n     **/\n    constructor(doc, row, column) {\n        this.$onChange = this.onChange.bind(this);\n        this.attach(doc);\n\n        if (typeof row != \"number\")\n            this.setPosition(row.row, row.column);\n        else\n            this.setPosition(row, column);\n    }\n\n    /**\n     * Returns an object identifying the `row` and `column` position of the current anchor.\n     * @returns {import(\"../ace-internal\").Ace.Point}\n     **/\n    getPosition() {\n        return this.$clipPositionToDocument(this.row, this.column);\n    }\n\n    /**\n     *\n     * Returns the current document.\n     * @returns {Document}\n     **/\n    getDocument() {\n        return this.document;\n    }\n\n    /**\n     * Internal function called when `\"change\"` event fired.\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     * @internal\n     */\n    onChange(delta) {\n        if (delta.start.row == delta.end.row && delta.start.row != this.row)\n            return;\n\n        if (delta.start.row > this.row)\n            return;\n\n        var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);\n        this.setPosition(point.row, point.column, true);\n    }\n\n    /**\n     * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.\n     * @param {Number} row The row index to move the anchor to\n     * @param {Number} column The column index to move the anchor to\n     * @param {Boolean} [noClip] Identifies if you want the position to be clipped\n     **/\n    setPosition(row, column, noClip) {\n        var pos;\n        if (noClip) {\n            pos = {\n                row: row,\n                column: column\n            };\n        } else {\n            pos = this.$clipPositionToDocument(row, column);\n        }\n\n        if (this.row == pos.row && this.column == pos.column)\n            return;\n\n        var old = {\n            row: this.row,\n            column: this.column\n        };\n\n        this.row = pos.row;\n        this.column = pos.column;\n        this._signal(\"change\", {\n            old: old,\n            value: pos\n        });\n    }\n\n    /**\n     * When called, the `\"change\"` event listener is removed.\n     *\n     **/\n    detach() {\n        this.document.off(\"change\", this.$onChange);\n    }\n\n    /**\n     * When called, the `\"change\"` event listener is appended.\n     * @param {Document} doc The document to associate with\n     *\n     **/\n    attach(doc) {\n        /**@type{Document}*/\n        this.document = doc || this.document;\n        this.document.on(\"change\", this.$onChange);\n    }\n\n    /**\n     * Clips the anchor position to the specified row and column.\n     * @param {Number} row The row index to clip the anchor to\n     * @param {Number} column The column index to clip the anchor to\n     * @returns {import(\"../ace-internal\").Ace.Point}\n     *\n     **/\n    $clipPositionToDocument(row, column) {\n        var pos = {};\n\n        if (row >= this.document.getLength()) {\n            pos.row = Math.max(0, this.document.getLength() - 1);\n            pos.column = this.document.getLine(pos.row).length;\n        }\n        else if (row < 0) {\n            pos.row = 0;\n            pos.column = 0;\n        }\n        else {\n            pos.row = row;\n            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));\n        }\n\n        if (column < 0)\n            pos.column = 0;\n\n        return pos;\n    }\n}\n\n/**\n * experimental: allows anchor to stick to the next on the left\n */\nAnchor.prototype.$insertRight = false;\n\noop.implement(Anchor.prototype, EventEmitter);\n\nfunction $pointsInOrder(point1, point2, equalPointsInOrder) {\n    var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;\n    return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);\n}\n\nfunction $getTransformedPoint(delta, point, moveIfEqual) {\n    // Get delta info.\n    var deltaIsInsert = delta.action == \"insert\";\n    var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row    - delta.start.row);\n    var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);\n    var deltaStart = delta.start;\n    var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.\n\n    // DELTA AFTER POINT: No change needed.\n    if ($pointsInOrder(point, deltaStart, moveIfEqual)) {\n        return {\n            row: point.row,\n            column: point.column\n        };\n    }\n\n    // DELTA BEFORE POINT: Move point by delta shift.\n    if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {\n        return {\n            row: point.row + deltaRowShift,\n            column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)\n        };\n    }\n\n    // DELTA ENVELOPS POINT (delete only): Move point to delta start.\n    // TODO warn if delta.action != \"remove\" ?\n\n    return {\n        row: deltaStart.row,\n        column: deltaStart.column\n    };\n}\n\nexports.Anchor = Anchor;\n"
  },
  {
    "path": "src/anchor_test.js",
    "content": "\"use strict\";\n\nvar Document = require(\"./document\").Document;\nvar Anchor = require(\"./anchor\").Anchor;\nvar Range = require(\"./range\").Range;\nvar assert = require(\"./test/assertions\");\n\nmodule.exports = {\n\n    \"test create anchor\" : function() {\n        var doc = new Document(\"juhu\");\n        var anchor = new Anchor(doc, 0, 0);\n        \n        assert.position(anchor.getPosition(), 0, 0);\n        assert.equal(anchor.getDocument(), doc);\n    },\n    \n    \"test insert text in same row before cursor should move anchor column\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.insert({row: 1, column: 1}, \"123\");\n        assert.position(anchor.getPosition(), 1, 7);\n    },\n\n    \"test insert text at anchor should not move anchor when insertRight is true\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        anchor.$insertRight = true;\n        \n        doc.insert({row: 1, column: 4}, \"123\");\n        assert.position(anchor.getPosition(), 1, 4);\n    },    \n    \n    \"test insert lines before cursor should move anchor row\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.insertFullLines(1, [\"123\", \"456\"]);\n        assert.position(anchor.getPosition(), 3, 4);    \n    },\n\n    \"test insert lines at anchor position should move anchor down\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 0);\n        \n        doc.insertLines(1, [\"line\"]);\n        assert.position(anchor.getPosition(), 2, 0);\n    },\n    \n    \"test insert lines at anchor position should not move anchor down when insertRight is true and column is 0\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 0);\n        anchor.$insertRight = true;\n        \n        doc.insertLines(1, [\"line\"]);\n        assert.position(anchor.getPosition(), 1, 0);\n    }, \n\n    \"test insert lines at anchor row should move anchor down when column > 0\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 2);\n        anchor.$insertRight = true;\n        \n        doc.insertLines(1, [\"line\"]);\n        assert.position(anchor.getPosition(), 2, 2);            \n    },\n    \n    \"test insert new line before cursor should move anchor column\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.insertMergedLines({row: 0, column: 0}, ['', '']);\n        assert.position(anchor.getPosition(), 2, 4);    \n    },\n    \n    \"test insert new line in anchor line before anchor should move anchor column and row\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.insertMergedLines({row: 1, column: 2}, ['', '']);\n        assert.position(anchor.getPosition(), 2, 2);\n    },\n    \n    \"test delete text in anchor line before anchor should move anchor column\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.remove(new Range(1, 1, 1, 3));\n        assert.position(anchor.getPosition(), 1, 2);\n    },\n    \n    \"test remove range which contains the anchor should move the anchor to the start of the range\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 0, 3);\n        \n        doc.remove(new Range(0, 1, 1, 3));\n        assert.position(anchor.getPosition(), 0, 1);\n    },\n    \n    \"test delete character before the anchor should have no effect\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.remove(new Range(1, 4, 1, 5));\n        assert.position(anchor.getPosition(), 1, 4);\n    },\n    \n    \"test delete lines in anchor line before anchor should move anchor row\": function() {\n        var doc = new Document(\"juhu\\n1\\n2\\nkinners\");\n        var anchor = new Anchor(doc, 3, 4);\n        \n        doc.removeFullLines(1, 2);\n        assert.position(anchor.getPosition(), 1, 4);\n    },\n    \n    \"test remove new line before the cursor\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.removeNewLine(0);\n        assert.position(anchor.getPosition(), 0, 8);\n    },\n    \n    \"test delete range which contains the anchor should move anchor to the end of the range\": function() {\n        var doc = new Document(\"juhu\\nkinners\");\n        var anchor = new Anchor(doc, 1, 4);\n        \n        doc.remove(new Range(0, 2, 1, 2));\n        assert.position(anchor.getPosition(), 0, 4);\n    },\n    \n    \"test delete line which contains the anchor should move anchor to the end of the range\": function() {\n        var doc = new Document(\"juhu\\nkinners\\n123\");\n        var anchor = new Anchor(doc, 1, 5);\n        \n        doc.removeFullLines(1, 1);\n        assert.position(anchor.getPosition(), 1, 0);\n    },\n    \n    \"test remove after the anchor should have no effect\": function() {\n        var doc = new Document(\"juhu\\nkinners\\n123\");\n        var anchor = new Anchor(doc, 1, 2);\n        \n        doc.remove(new Range(1, 4, 2, 2));\n        assert.position(anchor.getPosition(), 1, 2);\n    },\n    \n    \"test anchor changes triggered by document changes should emit change event\": function(next) {\n        var doc = new Document(\"juhu\\nkinners\\n123\");\n        var anchor = new Anchor(doc, 1, 5);\n        \n        anchor.on(\"change\", function(e) {\n            assert.position(anchor.getPosition(), 0, 0);\n            next();\n        });\n        \n        doc.remove(new Range(0, 0, 2, 1));\n    },\n    \n    \"test only fire change event if position changes\": function() {\n        var doc = new Document(\"juhu\\nkinners\\n123\");\n        var anchor = new Anchor(doc, 1, 5);\n        \n        anchor.on(\"change\", function(e) {\n            assert.fail();\n        });\n        \n        doc.remove(new Range(2, 0, 2, 1));\n    },\n    \n    \"test insert/remove lines at the end of the document\": function() {\n        var doc = new Document(\"juhu\\nkinners\\n123\");\n        var anchor = new Anchor(doc, 2, 4);\n        \n        doc.removeFullLines(0, 3);\n        assert.position(anchor.getPosition(), 0, 0);\n        doc.insertFullLines(0, [\"a\", \"b\", \"c\"]);        \n        assert.position(anchor.getPosition(), 3, 0);\n        assert.equal(doc.getValue(), \"a\\nb\\nc\\n\");\n    }\n};\n\n\nrequire(\"./test/run\")(module);\n"
  },
  {
    "path": "src/apply_delta.js",
    "content": "\"use strict\";\n\nfunction throwDeltaError(delta, errorText){\n    console.log(\"Invalid Delta:\", delta);\n    throw \"Invalid Delta: \" + errorText;\n}\n\nfunction positionInDocument(docLines, position) {\n    return position.row    >= 0 && position.row    <  docLines.length &&\n           position.column >= 0 && position.column <= docLines[position.row].length;\n}\n\nfunction validateDelta(docLines, delta) {\n    // Validate action string.\n    if (delta.action != \"insert\" && delta.action != \"remove\")\n        throwDeltaError(delta, \"delta.action must be 'insert' or 'remove'\");\n    \n    // Validate lines type.\n    if (!(delta.lines instanceof Array))\n        throwDeltaError(delta, \"delta.lines must be an Array\");\n\n    // Validate range type.\n    if (!delta.start || !delta.end)\n       throwDeltaError(delta, \"delta.start/end must be an present\");\n\n    // Validate that the start point is contained in the document.\n    var start = delta.start;\n    if (!positionInDocument(docLines, delta.start))\n        throwDeltaError(delta, \"delta.start must be contained in document\");\n    \n    // Validate that the end point is contained in the document (remove deltas only).\n    var end = delta.end;\n    if (delta.action == \"remove\" && !positionInDocument(docLines, end))\n        throwDeltaError(delta, \"delta.end must contained in document for 'remove' actions\");\n    \n    // Validate that the .range size matches the .lines size.\n    var numRangeRows = end.row - start.row;\n    var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0));\n    if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars)\n        throwDeltaError(delta, \"delta.range must match delta lines\");\n}\n\n/**\n * Applies a delta to a document.\n * @param {string[]} docLines\n * @param {import(\"../ace-internal\").Ace.Delta} delta\n * @param [doNotValidate]\n */\nexports.applyDelta = function(docLines, delta, doNotValidate) {\n    // disabled validation since it breaks autocompletion popup\n    // if (!doNotValidate)\n    //    validateDelta(docLines, delta);\n    \n    var row = delta.start.row;\n    var startColumn = delta.start.column;\n    var line = docLines[row] || \"\";\n    switch (delta.action) {\n        case \"insert\":\n            var lines = delta.lines;\n            if (lines.length === 1) {\n                docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);\n            } else {\n                // @ts-ignore\n                var args = [row, 1].concat(delta.lines);\n                docLines.splice.apply(docLines, args);\n                docLines[row] = line.substring(0, startColumn) + docLines[row];\n                docLines[row + delta.lines.length - 1] += line.substring(startColumn);\n            }\n            break;\n        case \"remove\":\n            var endColumn = delta.end.column;\n            var endRow = delta.end.row;\n            if (row === endRow) {\n                docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);\n            } else {\n                docLines.splice(\n                    row, endRow - row + 1,\n                    line.substring(0, startColumn) + docLines[endRow].substring(endColumn)\n                );\n            }\n            break;\n    }\n};\n"
  },
  {
    "path": "src/autocomplete/inline.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\nvar snippetManager = require(\"../snippets\").snippetManager;\nvar AceInlineScreenReader = require(\"./inline_screenreader\").AceInlineScreenReader;\n\n/**\n * This object is used to manage inline code completions rendered into an editor with ghost text.\n */\nclass AceInline {\n    /**\n     * Creates the inline completion renderer which renders the inline code completions directly in the target editor.\n     */\n    constructor() {\n        this.editor = null;\n    }\n    \n    /**\n     * Renders the completion as ghost text to the current cursor position\n     * @param {Editor} editor\n     * @param {import(\"../../ace-internal\").Ace.Completion} completion\n     * @param {string} prefix\n     * @returns {boolean} True if the completion could be rendered to the editor, false otherwise\n     */\n    show(editor, completion, prefix) {\n        prefix = prefix || \"\";\n        if (editor && this.editor && this.editor !== editor) {\n            this.hide();\n            this.editor = null;\n            this.inlineScreenReader = null;\n        }\n        if (!editor || !completion) {\n            return false;\n        }\n        if (!this.inlineScreenReader) {\n            this.inlineScreenReader = new AceInlineScreenReader(editor);\n        }\n        var displayText = completion.snippet ? snippetManager.getDisplayTextForSnippet(editor, completion.snippet) : completion.value;\n        if (completion.hideInlinePreview || !displayText || !displayText.startsWith(prefix)) {\n            return false;\n        }\n        this.editor = editor;\n\n        this.inlineScreenReader.setScreenReaderContent(displayText);\n\n        displayText = displayText.slice(prefix.length);\n        if (displayText === \"\") {\n            editor.removeGhostText();\n        } else {\n            editor.setGhostText(displayText);\n        }\n        return true;\n    }\n\n    isOpen() {\n        if (!this.editor) {\n            return false;\n        }\n        return !!this.editor.renderer.$ghostText;\n    }\n\n    hide() {\n        if (!this.editor) {\n            return false;\n        }\n        this.editor.removeGhostText();\n        return true;\n    }\n\n    destroy() {\n        this.hide();\n        this.editor = null;\n        if (this.inlineScreenReader) {\n            this.inlineScreenReader.destroy();\n            this.inlineScreenReader = null;\n        }\n    }\n}\n\n\nexports.AceInline = AceInline;\n"
  },
  {
    "path": "src/autocomplete/inline_screenreader.js",
    "content": "\"use strict\";\n\n/**\n * This object is used to communicate inline code completions rendered into an editor with ghost text to screen reader users.\n */\nclass AceInlineScreenReader {\n    /**\n     * Creates the off-screen div in which the ghost text content in redered and which the screen reader reads.\n     * @param {import(\"../editor\").Editor} editor\n     */\n    constructor(editor) {\n        this.editor = editor;\n\n        this.screenReaderDiv = document.createElement(\"div\");\n        this.screenReaderDiv.classList.add(\"ace_screenreader-only\");\n        this.editor.container.appendChild(this.screenReaderDiv);\n    }\n\n    /**\n     * Set the ghost text content to the screen reader div\n     * @param {string} content\n     */\n    setScreenReaderContent(content) {\n        // Path for when inline preview is used with 'normal' completion popup.\n        if (!this.popup && this.editor.completer && /**@type{import(\"../autocomplete\").Autocomplete}*/(this.editor.completer).popup) {\n            this.popup = /**@type{import(\"../autocomplete\").Autocomplete}*/(this.editor.completer).popup;\n\n            this.popup.renderer.on(\"afterRender\", function() {\n                let row = this.popup.getRow();\n                let t = this.popup.renderer.$textLayer;\n                let selected = t.element.childNodes[row - t.config.firstRow];\n                if (selected) {\n                    let idString = \"doc-tooltip \";\n                    for (let lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {\n                        idString += `ace-inline-screenreader-line-${lineIndex} `;\n                    }\n                    selected.setAttribute(\"aria-describedby\", idString);      \n                }\n            }.bind(this));\n        }\n\n        // TODO: Path for when special inline completion popup is used.\n        // https://github.com/ajaxorg/ace/issues/5348\n\n        // Remove all children of the div\n        while (this.screenReaderDiv.firstChild) {\n            this.screenReaderDiv.removeChild(this.screenReaderDiv.firstChild);\n        }\n        this._lines = content.split(/\\r\\n|\\r|\\n/);\n        const codeElement = this.createCodeBlock();\n        this.screenReaderDiv.appendChild(codeElement);\n    }\n\n    destroy() {\n        this.screenReaderDiv.remove();\n    }\n\n    /**\n     * Take this._lines, render it as <code> blocks and add those to the screen reader div.\n     */\n    createCodeBlock() {\n        const container = document.createElement(\"pre\");\n        container.setAttribute(\"id\", \"ace-inline-screenreader\");\n\n        for (let lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {\n            const codeElement = document.createElement(\"code\");\n            codeElement.setAttribute(\"id\", `ace-inline-screenreader-line-${lineIndex}`);\n            const line = document.createTextNode(this._lines[lineIndex]);\n\n            codeElement.appendChild(line);\n            container.appendChild(codeElement);\n        }\n\n        return container;\n    }\n}\n\nexports.AceInlineScreenReader = AceInlineScreenReader;\n"
  },
  {
    "path": "src/autocomplete/inline_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"../test/assertions\");\nvar AceInline = require(\"./inline\").AceInline;\nvar Editor = require(\"../ace\").Editor;\nvar EditSession = require(\"../ace\").EditSession;\nvar VirtualRenderer = require(\"../ace\").VirtualRenderer;\nvar lang = require(\"../lib/lang\");\n\nvar editor;\nvar editor2;\nvar inline;\n\nvar textBase = \"abc123\\n\\n    \";\n\nvar completions = [\n    {\n        value: \"foo\",\n        score: 4\n    },\n    {\n        value: \"function\",\n        score: 3\n    },\n    {\n        value: \"foobar\",\n        score: 2\n    },\n    {\n        snippet: \"function foo() {\\n    console.log('test');\\n}\",\n        score: 1\n    },\n    {\n        snippet: \"foobar2\",\n        score: 0\n    },\n    {\n        value: \"f should not show inline\",\n        score: 0,\n        hideInlinePreview: true\n    },\n    {\n        value: \"long\\nlong\\nlong\\nlong\\nlong\\nlong\",\n        score: 0\n    },\n    {\n        value: \"long\\nlong\\nlong\\nlong\\nlong\\nlong\".repeat(100),\n        score: 0\n    },\n    {\n        value: \"foo suggestion with a\\n\\n\\ngap\",\n        score: 0\n    }\n];\n\nvar getAllLines = function(editorOverride) {\n    editorOverride = editorOverride || editor;\n    return Array.from(editorOverride.renderer.$textLayer.element.childNodes).map(function (node) {\n        return node.textContent;\n    }).join(\"\\n\");\n};\n\nvar createEditor = function(element) {\n    var renderer = new VirtualRenderer(element);\n    var session = new EditSession(\"\");\n    return new Editor(renderer, session);\n};\n\nmodule.exports = {\n    setUp: function() {\n        var el = document.createElement(\"div\");\n        el.style.left = \"20px\";\n        el.style.top = \"30px\";\n        el.style.width = \"500px\";\n        el.style.height = \"500px\";\n        document.body.appendChild(el);\n        editor = createEditor(el);\n        editor.execCommand(\"insertstring\", textBase + \"f\");\n        inline = new AceInline();\n        editor.getSelection().moveCursorFileEnd();\n        editor.renderer.$loop._flush();\n    },\n    \"test: displays the ghost text in the editor on show\": function() {\n        inline.show(editor, completions[0], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"foo\");\n    },\n    \"test: replaces the ghost text in the editor with the latest show\": function() {\n        inline.show(editor, completions[0], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"foo\");\n        inline.show(editor, completions[1], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"function\");\n    },\n    \"test: renders multi-line ghost text indentation\": function() {\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        inline.show(editor, completions[3], \"f\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"function foo() {\");\n        assert.strictEqual(editor.renderer.$ghostTextWidget.el.innerHTML, `<div><span class=\"ace_ghost_text\">        console.log('test');</span></div><div><span class=\"ace_ghost_text\">    }</span><span></span></div>`);\n    },\n    \"test: boundary tests\": function() {\n        var noRenderTestCases = [\n            [null, null, null],\n            [editor, null, null],\n            [editor, null, \"\"],\n            [null, completions[3], \"\"]\n        ];\n        var result;\n        noRenderTestCases.forEach(function(params) {\n            result = inline.show(params[0], params[1], params[2]);\n            editor.renderer.$loop._flush();\n            assert.notOk(result);\n            assert.equal(editor.renderer.$ghostText, null);\n            assert.equal(editor.renderer.$ghostTextWidget, null);\n        });\n\n        var renderTestCases = [\n            [editor, completions[1], undefined],\n            [editor, completions[1], null],\n            [editor, completions[1], \"\"]\n        ];\n        renderTestCases.forEach(function(params) {\n            result = inline.show(params[0], params[1], params[2]);\n            editor.renderer.$loop._flush();\n            assert.ok(result);\n            assert.strictEqual(editor.renderer.$ghostText.text, \"function\");\n            assert.strictEqual(getAllLines(), textBase + \"ffunction\");\n            assert.equal(editor.renderer.$ghostTextWidget, null);\n        });\n\n        result = inline.show(editor, completions[0], \"foo\");\n        editor.renderer.$loop._flush();\n        assert.ok(result);\n        assert.equal(editor.renderer.$ghostText, null);\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n    },\n    \"test: only renders the ghost text without the prefix\": function() {\n        inline.show(editor, completions[1], \"fun\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"fction\");\n    },\n    \"test: verify explicit and implicit hide\": function() {\n        inline.show(editor, completions[1], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"function\");\n        assert.strictEqual(inline.isOpen(), true);\n        inline.hide();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n        assert.strictEqual(inline.isOpen(), false);\n\n        inline.show(editor, completions[1], \"function\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n        assert.strictEqual(inline.isOpen(), false);\n    },\n    \"test: does not hide previous ghost text if cannot show current one\": function() {\n        inline.show(editor, completions[1], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"function\");\n        assert.strictEqual(inline.isOpen(), true);\n        inline.show(editor, null, \"\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"function\");\n        assert.strictEqual(inline.isOpen(), true);\n        inline.hide();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n        assert.strictEqual(inline.isOpen(), false);\n    },\n    \"test: removes ghost text from previous editor if new valid editor is passed to show function\": function() {\n        var el = document.createElement(\"div\");\n        el.style.left = \"520px\";\n        el.style.top = \"530px\";\n        el.style.width = \"500px\";\n        el.style.height = \"500px\";\n        document.body.appendChild(el);\n        editor2 = createEditor(el);\n        var editor2Text = \"different text\\n\\n    f\";\n        editor2.execCommand(\"insertstring\", editor2Text);\n\n        inline.show(editor, completions[1], \"f\");\n        editor.renderer.$loop._flush();\n        editor2.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"function\");\n        assert.strictEqual(getAllLines(editor2), editor2Text);\n        assert.strictEqual(inline.isOpen(), true);\n\n        inline.show(editor2, completions[2], \"f\");\n        editor.renderer.$loop._flush();\n        editor2.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n        assert.strictEqual(getAllLines(editor2), editor2Text + \"oobar\");\n        assert.strictEqual(inline.isOpen(), true);\n\n        inline.show(null, completions[2], \"f\");\n        editor.renderer.$loop._flush();\n        editor2.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n        assert.strictEqual(getAllLines(editor2), editor2Text + \"oobar\");\n        assert.strictEqual(inline.isOpen(), true);\n    },\n    \"test: verify destroy\": function() {\n        inline.show(editor, completions[0], \"f\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"foo\");\n\n        inline.destroy();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(inline.isOpen(), false);\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n\n        inline.destroy();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(inline.isOpen(), false);\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n\n        inline.hide();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(inline.isOpen(), false);\n        assert.strictEqual(getAllLines(), textBase + \"f\");\n    },\n    \"test: should respect hideInlinePreview\": function() {\n        // By default, this option is set to hide.\n        inline.show(editor, completions[5], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"f\");\n        assert.strictEqual(inline.isOpen(), false);\n        inline.hide();\n        editor.renderer.$loop._flush();\n\n        // Now it should be shown.\n        completions[5].hideInlinePreview = false;\n\n        inline.show(editor, completions[5], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"f should not show inline\");\n        assert.strictEqual(inline.isOpen(), true);\n        inline.hide();\n        editor.renderer.$loop._flush();\n\n        // Now it should be shown.\n        completions[5].hideInlinePreview = undefined;\n\n        inline.show(editor, completions[5], \"f\");\n        editor.renderer.$loop._flush();\n        assert.equal(getAllLines(), textBase + \"f should not show inline\");\n        assert.strictEqual(inline.isOpen(), true);\n        inline.hide();\n        editor.renderer.$loop._flush();\n\n        // Reset to state before test.\n        completions[5].hideInlinePreview = true;\n    },\n    \"test: should scroll if inline preview outside\": async function(done) {\n        // Fill the editor with new lines to get the cursor to the bottom\n        // of the container\n        editor.execCommand(\"insertstring\", \"\\n\".repeat(200));\n\n        var deltaY, row;\n        var initialScrollBy = editor.renderer.scrollBy;\n        var initialScrollToRow = editor.renderer.scrollToRow;\n        editor.renderer.scrollBy = function(_, varY) {\n            deltaY = varY;\n        };\n        editor.renderer.scrollToRow = function(varRow) {\n            row = varRow;\n        };\n\n        inline.show(editor, completions[6], \"l\");\n        editor.renderer.$loop._flush();\n\n        await lang.sleep(50);\n        // Should scroll 5 lines to get the inline preview into view\n        assert.strictEqual(deltaY, 50);\n\n        inline.hide();\n        editor.renderer.$loop._flush();\n\n        inline.show(editor, completions[7], \"l\");\n        editor.renderer.$loop._flush();\n\n        await lang.sleep(50);\n        // Should scroll as much as possbile while keeping the cursor on screen\n        assert.strictEqual(row, 202);\n        editor.renderer.scrollBy = initialScrollBy;\n        editor.renderer.scrollToRow = initialScrollToRow;\n        done();\n    },\n    \"test: renders multi-line ghost text with empty lines\": function() {\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        inline.show(editor, completions[8], \"f\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase + \"foo suggestion with a\");\n        assert.strictEqual(editor.renderer.$ghostTextWidget.el.innerHTML, `<div><span class=\"ace_ghost_text\"> </span></div><div><span class=\"ace_ghost_text\"> </span></div><div><span class=\"ace_ghost_text\">gap</span><span></span></div>`);\n    },\n    \"test: moves tokens to the right of cursor to the end of ghost text for multi line ghost text\": function() {\n        editor.execCommand(\"removetolinestarthard\");\n        editor.execCommand(\"insertstring\", \"f hi I should be hidden\");\n        editor.execCommand(\"gotolinestart\");\n        editor.execCommand(\"gotoright\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        inline.show(editor, completions[8], \"f\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase.replaceAll(\" \", \"\") + \"foo suggestion with a hi I should be hidden\");\n\n        // The string to the right of the cursor should be hidden tokens now.\n        var tokens = editor.session.getTokens(2);\n        assert.strictEqual(tokens[2].value, \" hi I should be hidden\");\n        assert.strictEqual(tokens[2].type, \"hidden_token\");\n\n        // And should be added to the ghost text widget.\n        assert.strictEqual(editor.renderer.$ghostTextWidget.el.textContent, \"  gap hi I should be hidden\");\n\n        // Hide inline\n        inline.hide();\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n\n        // Text to the right of the cursor should be tokenized normally again.\n        var tokens = editor.session.getTokens(2);\n        assert.strictEqual(tokens[0].value, \"f hi I should be hidden\");\n        assert.strictEqual(tokens[0].type, \"text\");\n    },\n    \"test: moves tokens to the right of cursor to the end of ghost text for multi line ghost text when triggered inside token\": function() {\n        editor.execCommand(\"removetolinestarthard\");\n        editor.execCommand(\"insertstring\", \"fhi I should be hidden\");\n        editor.execCommand(\"gotolinestart\");\n        editor.execCommand(\"gotoright\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        inline.show(editor, completions[8], \"f\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), textBase.replaceAll(\" \", \"\") + \"foo suggestion with ahi I should be hidden\");\n\n        // The string to the right of the cursor should be hidden tokens now.\n        var tokens = editor.session.getTokens(2);\n        assert.strictEqual(tokens[2].value, \"hi I should be hidden\");\n        assert.strictEqual(tokens[2].type, \"hidden_token\");\n\n        // And should be added to the ghost text widget.\n        assert.strictEqual(editor.renderer.$ghostTextWidget.el.textContent, \"  gaphi I should be hidden\");\n\n        // Hide inline\n        inline.hide();\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n\n        // Text to the right of the cursor should be tokenized normally again.\n        var tokens = editor.session.getTokens(2);\n        assert.strictEqual(tokens[0].value, \"fhi I should be hidden\");\n        assert.strictEqual(tokens[0].type, \"text\");\n    },\n    tearDown: function() {\n        inline.destroy();\n        editor.destroy();\n        if (editor2) {\n            editor2.destroy();\n        }\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/autocomplete/popup.js",
    "content": "\"use strict\";\nvar Renderer = require(\"../virtual_renderer\").VirtualRenderer;\nvar Editor = require(\"../editor\").Editor;\nvar Range = require(\"../range\").Range;\nvar event = require(\"../lib/event\");\nvar lang = require(\"../lib/lang\");\nvar dom = require(\"../lib/dom\");\nvar nls = require(\"../config\").nls;\nvar userAgent = require(\"./../lib/useragent\");\n\nvar getAriaId = function (index) {\n    return `suggest-aria-id:${index}`;\n};\n\n// Safari requires different ARIA A11Y attributes compared to other browsers\nvar popupAriaRole = userAgent.isSafari ? \"menu\" : \"listbox\";\nvar optionAriaRole = userAgent.isSafari ? \"menuitem\" : \"option\";\nvar ariaActiveState = userAgent.isSafari ? \"aria-current\" : \"aria-selected\";\n\n/**\n *\n * @param {HTMLElement} [el]\n * @return {Editor}\n */\nvar $singleLineEditor = function(el) {\n    var renderer = new Renderer(el);\n\n    renderer.$maxLines = 4;\n    var editor = new Editor(renderer);\n\n    editor.setHighlightActiveLine(false);\n    editor.setShowPrintMargin(false);\n    editor.renderer.setShowGutter(false);\n    editor.renderer.setHighlightGutterLine(false);\n\n    editor.$mouseHandler.$focusTimeout = 0;\n    editor.$highlightTagPending = true;\n\n    return editor;\n};\n\n/**\n * This object is used in some places where needed to show popups - like prompt; autocomplete etc.\n */\nclass AcePopup {\n    /**\n     * Creates and renders single line editor in popup window. If `parentNode` param is isset, then attaching it to this element.\n     * @param {Element} [parentNode]\n     */\n    constructor(parentNode) {\n        var el = dom.createElement(\"div\");\n        /**@type {AcePopup}*/\n        // @ts-ignore\n        var popup = $singleLineEditor(el);\n\n        if (parentNode) {\n            parentNode.appendChild(el);\n        }\n        el.style.display = \"none\";\n        popup.renderer.content.style.cursor = \"default\";\n        popup.renderer.setStyle(\"ace_autocomplete\");\n\n        // Set aria attributes for the popup\n        popup.renderer.$textLayer.element.setAttribute(\"role\", popupAriaRole);\n        popup.renderer.$textLayer.element.setAttribute(\"aria-roledescription\", nls(\"autocomplete.popup.aria-roledescription\", \"Autocomplete suggestions\"));\n        popup.renderer.$textLayer.element.setAttribute(\"aria-label\", nls(\"autocomplete.popup.aria-label\", \"Autocomplete suggestions\"));\n        popup.renderer.textarea.setAttribute(\"aria-hidden\", \"true\");\n\n        popup.setOption(\"displayIndentGuides\", false);\n        popup.setOption(\"dragDelay\", 150);\n\n        var noop = function(){};\n\n        popup.focus = noop;\n        popup.$isFocused = true;\n\n        popup.renderer.$cursorLayer.restartTimer = noop;\n        popup.renderer.$cursorLayer.element.style.opacity = \"0\";\n\n        popup.renderer.$maxLines = 8;\n        popup.renderer.$keepTextAreaAtCursor = false;\n\n        popup.setHighlightActiveLine(false);\n        // set default highlight color\n        // @ts-ignore\n        popup.session.highlight(\"\");\n        popup.session.$searchHighlight.clazz = \"ace_highlight-marker\";\n\n        popup.on(\"mousedown\", function(e) {\n            var pos = e.getDocumentPosition();\n            popup.selection.moveToPosition(pos);\n            selectionMarker.start.row = selectionMarker.end.row = pos.row;\n            e.stop();\n        });\n\n        var lastMouseEvent;\n        var hoverMarker = new Range(-1, 0, -1, Infinity);\n        var selectionMarker = new Range(-1, 0, -1, Infinity);\n        selectionMarker.id = popup.session.addMarker(selectionMarker, \"ace_active-line\", \"fullLine\");\n        popup.setSelectOnHover = function (val) {\n            if (!val) {\n                hoverMarker.id = popup.session.addMarker(hoverMarker, \"ace_line-hover\", \"fullLine\");\n            } else if (hoverMarker.id) {\n                popup.session.removeMarker(hoverMarker.id);\n                hoverMarker.id = null;\n            }\n        };\n        popup.setSelectOnHover(false);\n        popup.on(\"mousemove\", function(e) {\n            if (!lastMouseEvent) {\n                lastMouseEvent = e;\n                return;\n            }\n            if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {\n                return;\n            }\n            lastMouseEvent = e;\n            lastMouseEvent.scrollTop = popup.renderer.scrollTop;\n            popup.isMouseOver = true;\n            var row = lastMouseEvent.getDocumentPosition().row;\n            if (hoverMarker.start.row != row) {\n                if (!hoverMarker.id)\n                    popup.setRow(row);\n                setHoverMarker(row);\n            }\n        });\n        popup.renderer.on(\"beforeRender\", function() {\n            if (lastMouseEvent && hoverMarker.start.row != -1) {\n                lastMouseEvent.$pos = null;\n                var row = lastMouseEvent.getDocumentPosition().row;\n                if (!hoverMarker.id)\n                    popup.setRow(row);\n                setHoverMarker(row, true);\n            }\n        });\n        // set aria attributes on all visible elements of the popup\n        popup.renderer.on(\"afterRender\", function () {\n            var t = popup.renderer.$textLayer;\n            for (var row = t.config.firstRow, l = t.config.lastRow; row <= l; row++) {\n                const popupRowElement = /** @type {HTMLElement|null} */(t.element.childNodes[row - t.config.firstRow]);\n\n                popupRowElement.setAttribute(\"role\", optionAriaRole);\n                popupRowElement.setAttribute(\"aria-roledescription\", nls(\"autocomplete.popup.item.aria-roledescription\", \"item\"));\n                popupRowElement.setAttribute(\"aria-setsize\", popup.data.length);\n                popupRowElement.setAttribute(\"aria-describedby\", \"doc-tooltip\");\n                popupRowElement.setAttribute(\"aria-posinset\", row + 1);\n\n                const rowData = popup.getData(row);\n                if (rowData) {\n                    const ariaLabel = `${rowData.caption || rowData.value}${rowData.meta ? `, ${rowData.meta}` : ''}`;\n                    popupRowElement.setAttribute(\"aria-label\", ariaLabel);\n                }\n\n                const highlightedSpans = popupRowElement.querySelectorAll(\".ace_completion-highlight\");\n                highlightedSpans.forEach(span => {\n                    span.setAttribute(\"role\", \"mark\");\n                });\n            }\n        });\n        popup.renderer.on(\"afterRender\", function () {\n            var row = popup.getRow();\n            var t = popup.renderer.$textLayer;\n            var selected = /** @type {HTMLElement|null} */(t.element.childNodes[row - t.config.firstRow]);\n            var el = document.activeElement; // Active element is textarea of main editor\n            if (selected !== popup.selectedNode && popup.selectedNode) {\n                dom.removeCssClass(popup.selectedNode, \"ace_selected\");\n                popup.selectedNode.removeAttribute(ariaActiveState);\n                popup.selectedNode.removeAttribute(\"id\");\n            }\n            el.removeAttribute(\"aria-activedescendant\");\n\n            popup.selectedNode = selected;\n            if (selected) {\n                var ariaId = getAriaId(row);\n                dom.addCssClass(selected, \"ace_selected\");\n                selected.id = ariaId;\n                t.element.setAttribute(\"aria-activedescendant\", ariaId);\n                el.setAttribute(\"aria-activedescendant\", ariaId);\n                selected.setAttribute(ariaActiveState, \"true\");\n            }\n        });\n        var hideHoverMarker = function() { setHoverMarker(-1); };\n        var setHoverMarker = function(row, suppressRedraw) {\n            if (row !== hoverMarker.start.row) {\n                hoverMarker.start.row = hoverMarker.end.row = row;\n                if (!suppressRedraw)\n                    popup.session._emit(\"changeBackMarker\");\n                popup._emit(\"changeHoverMarker\");\n            }\n        };\n        popup.getHoveredRow = function() {\n            return hoverMarker.start.row;\n        };\n\n        event.addListener(popup.container, \"mouseout\", function() {\n            popup.isMouseOver = false;\n            hideHoverMarker();\n        });\n        popup.on(\"hide\", hideHoverMarker);\n        popup.on(\"changeSelection\", hideHoverMarker);\n\n        popup.session.doc.getLength = function() {\n            return popup.data.length;\n        };\n        popup.session.doc.getLine = function(i) {\n            var data = popup.data[i];\n            if (typeof data == \"string\")\n                return data;\n            return (data && data.value) || \"\";\n        };\n\n        var bgTokenizer = popup.session.bgTokenizer;\n        bgTokenizer.$tokenizeRow = function(row) {\n            /**@type {import(\"../../ace-internal\").Ace.Completion &{name?, className?, matchMask?, message?}}*/\n            var data = popup.data[row];\n            var tokens = [];\n            if (!data)\n                return tokens;\n            if (typeof data == \"string\")\n                data = {value: data};\n            var caption = data.caption || data.value || data.name;\n\n            function addToken(value, className) {\n                value && tokens.push({\n                    type: (data.className || \"\") + (className || \"\"),\n                    value: value\n                });\n            }\n\n            var lower = caption.toLowerCase();\n            var filterText = (popup.filterText || \"\").toLowerCase();\n            var lastIndex = 0;\n            var lastI = 0;\n            for (var i = 0; i <= filterText.length; i++) {\n                if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {\n                    var sub = filterText.slice(lastI, i);\n                    lastI = i;\n                    var index = lower.indexOf(sub, lastIndex);\n                    if (index == -1) continue;\n                    addToken(caption.slice(lastIndex, index), \"\");\n                    lastIndex = index + sub.length;\n                    addToken(caption.slice(index, lastIndex), \"completion-highlight\");\n                }\n            }\n            addToken(caption.slice(lastIndex, caption.length), \"\");\n\n            tokens.push({type: \"completion-spacer\", value: \" \"});\n            if (data.meta)\n                tokens.push({type: \"completion-meta\", value: data.meta});\n            if (data.message)\n                tokens.push({type: \"completion-message\", value: data.message});\n\n            return tokens;\n        };\n        bgTokenizer.$updateOnChange = noop;\n        bgTokenizer.start = noop;\n\n        popup.session.$computeWidth = function() {\n            return this.screenWidth = 0;\n        };\n\n        // public\n        popup.isOpen = false;\n        popup.isTopdown = false;\n        popup.autoSelect = true;\n        popup.filterText = \"\";\n        popup.isMouseOver = false;\n\n        popup.data = [];\n        popup.setData = function(list, filterText) {\n            popup.filterText = filterText || \"\";\n            popup.setValue(lang.stringRepeat(\"\\n\", list.length), -1);\n            popup.data = list || [];\n            popup.setRow(0);\n        };\n        popup.getData = function(row) {\n            return popup.data[row];\n        };\n\n        popup.getRow = function() {\n            return selectionMarker.start.row;\n        };\n        popup.setRow = function(line) {\n            line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length - 1, line));\n            if (selectionMarker.start.row != line) {\n                popup.selection.clearSelection();\n                selectionMarker.start.row = selectionMarker.end.row = line || 0;\n                popup.session._emit(\"changeBackMarker\");\n                popup.moveCursorTo(line || 0, 0);\n                if (popup.isOpen)\n                    popup._signal(\"select\");\n            }\n        };\n\n        popup.on(\"changeSelection\", function() {\n            if (popup.isOpen)\n                popup.setRow(popup.selection.lead.row);\n            popup.renderer.scrollCursorIntoView();\n        });\n\n        popup.hide = function() {\n            this.container.style.display = \"none\";\n            popup.anchorPos = null;\n            popup.anchor = null;\n            if (popup.isOpen) {\n                popup.isOpen = false;\n                this._signal(\"hide\");\n            }\n        };\n\n        /**\n         * Tries to show the popup anchored to the given position and anchors.\n         * If the anchor is not specified it tries to align to bottom and right as much as possible.\n         * If the popup does not have enough space to be rendered with the given anchors, it returns false without rendering the popup.\n         * The forceShow flag can be used to render the popup in these cases, which slides the popup so it entirely fits on the screen.\n         * @param {{top: number, left: number}} pos\n         * @param {number} lineHeight\n         * @param {\"top\" | \"bottom\" | undefined} anchor\n         * @param {boolean} forceShow\n         * @returns {boolean}\n         */\n        popup.tryShow = function(pos, lineHeight, anchor, forceShow) {\n            if (!forceShow && popup.isOpen && popup.anchorPos && popup.anchor &&\n                popup.anchorPos.top === pos.top && popup.anchorPos.left === pos.left &&\n                popup.anchor === anchor\n            ) {\n                return true;\n            }\n\n            var el = this.container;\n            var scrollBarSize = this.renderer.scrollBar.width || 10;\n            var screenHeight = window.innerHeight - scrollBarSize;\n            var screenWidth = window.innerWidth - scrollBarSize;\n            var renderer = this.renderer;\n            // var maxLines = Math.min(renderer.$maxLines, this.session.getLength());\n            var maxH = renderer.$maxLines * lineHeight * 1.4;\n            var dims = { top: 0, bottom: 0, left: 0 };\n\n            var spaceBelow = screenHeight - pos.top - 3 * this.$borderSize - lineHeight;\n            var spaceAbove = pos.top - 3 * this.$borderSize;\n            if (!anchor) {\n                if (spaceAbove <= spaceBelow || spaceBelow >= maxH) {\n                    anchor = \"bottom\";\n                } else {\n                    anchor = \"top\";\n                }\n            }\n\n            if (anchor === \"top\") {\n                dims.bottom = pos.top - this.$borderSize;\n                dims.top = dims.bottom - maxH;\n            } else if (anchor === \"bottom\") {\n                dims.top = pos.top + lineHeight + this.$borderSize;\n                dims.bottom = dims.top + maxH;\n            }\n\n            var fitsX = dims.top >= 0 && dims.bottom <= screenHeight;\n\n            if (!forceShow && !fitsX) {\n                return false;\n            }\n\n            if (!fitsX) {\n                if (anchor === \"top\") {\n                    renderer.$maxPixelHeight = spaceAbove;\n                } else {\n                    renderer.$maxPixelHeight = spaceBelow;\n                }\n            } else {\n                renderer.$maxPixelHeight = null;\n            }\n\n\n            if (anchor === \"top\") {\n                el.style.top = \"\";\n                el.style.bottom = (screenHeight + scrollBarSize - dims.bottom) + \"px\";\n                popup.isTopdown = false;\n            } else {\n                el.style.top = dims.top + \"px\";\n                el.style.bottom = \"\";\n                popup.isTopdown = true;\n            }\n\n            el.style.display = \"\";\n\n            var left = pos.left;\n            if (left + el.offsetWidth > screenWidth)\n                left = screenWidth - el.offsetWidth;\n\n            el.style.left = left + \"px\";\n            el.style.right = \"\";\n            dom.$fixPositionBug(el);\n\n            if (!popup.isOpen) {\n                popup.isOpen = true;\n                this._signal(\"show\");\n                lastMouseEvent = null;\n            }\n\n            popup.anchorPos = pos;\n            popup.anchor = anchor;\n            \n\n            return true;\n        };\n\n        popup.show = function(pos, lineHeight, topdownOnly) {\n            this.tryShow(pos, lineHeight, topdownOnly ? \"bottom\" : undefined, true);\n        };\n\n        popup.goTo = function(where) {\n            var row = this.getRow();\n            var max = this.session.getLength() - 1;\n\n            switch(where) {\n                case \"up\": row = row <= 0 ? max : row - 1; break;\n                case \"down\": row = row >= max ? -1 : row + 1; break;\n                case \"start\": row = 0; break;\n                case \"end\": row = max; break;\n            }\n\n            this.setRow(row);\n        };\n\n\n        popup.getTextLeftOffset = function() {\n            return this.$borderSize + this.renderer.$padding + this.$imageSize;\n        };\n\n        popup.$imageSize = 0;\n        popup.$borderSize = 1;\n\n        return popup;\n    }\n}\n\ndom.importCssString(`\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #CAD6FA;\n    z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid #abbffe;\n    margin-top: -1px;\n    background: rgba(233,233,253,0.4);\n    position: absolute;\n    z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid rgba(109, 150, 13, 0.8);\n    background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n    opacity: 0.5;\n    margin-left: 0.9em;\n}\n.ace_completion-message {\n    margin-left: 0.9em;\n    color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n    width: 300px;\n    z-index: 200000;\n    border: 1px lightgray solid;\n    position: fixed;\n    box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n    line-height: 1.4;\n    background: #fefefe;\n    color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n    border: 1px #484747 solid;\n    box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n    line-height: 1.4;\n    background: #25282c;\n    color: #c1c1c1;\n}\n.ace_autocomplete .ace_text-layer  {\n    width: calc(100% - 8px);\n}\n.ace_autocomplete .ace_line {\n    display: flex;\n    align-items: center;\n}\n.ace_autocomplete .ace_line > * {\n    min-width: 0;\n    flex: 0 0 auto;\n}\n.ace_autocomplete .ace_line .ace_ {\n    flex: 0 1 auto;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n.ace_autocomplete .ace_completion-spacer {\n    flex: 1;\n}\n.ace_autocomplete.ace_loading:after  {\n    content: \"\";\n    position: absolute;\n    top: 0px;\n    height: 2px;\n    width: 8%;\n    background: blue;\n    z-index: 100;\n    animation: ace_progress 3s infinite linear;\n    animation-delay: 300ms;\n    transform: translateX(-100%) scaleX(1);\n}\n@keyframes ace_progress {\n    0% { transform: translateX(-100%) scaleX(1) }\n    50% { transform: translateX(625%) scaleX(2) } \n    100% { transform: translateX(1500%) scaleX(3) } \n}\n@media (prefers-reduced-motion) {\n    .ace_autocomplete.ace_loading:after {\n        transform: translateX(625%) scaleX(2);\n        animation: none;\n     }\n}\n`, \"autocompletion.css\", false);\n\nexports.AcePopup = AcePopup;\nexports.$singleLineEditor = $singleLineEditor;\nexports.getAriaId = getAriaId;\n"
  },
  {
    "path": "src/autocomplete/popup_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"../test/assertions\");\nvar AcePopup = require(\"./popup\").AcePopup;\n\n/**@type {AcePopup} */\nvar popup;\nvar lineHeight = 14;\nvar renderHeight = 8 * lineHeight;\nvar renderWidth = 300;\nvar iframe;\n\nvar notEnoughSpaceOnRight = window.innerWidth - 50;\nvar notEnoughSpaceOnBottom = window.innerHeight - 50;\n\nvar originalDocument;\n\nvar completions = [];\n\nfor (var i = 0; i < 8; i++) {\n    completions.push({ value: \"foo\" + i, caption: \"foo\" + i, name: \"foo\" + i, score: 4 });\n}\n\nvar tryShowAndRender = function(pos, lineHeight, anchor, forceShow) {\n    var result = popup.tryShow(pos, lineHeight, anchor, forceShow);\n    popup.renderer.updateFull(true);\n    return result;\n};\n\n\nvar setupPopup = function() {\n    popup = new AcePopup(document.body);\n\n    // Mock the CSS behaviour\n    popup.container.style.width = \"300px\";\n    popup.setData(completions, \"\");\n};\n\nvar tearDown = function(done) {\n    if (popup) {\n        popup.destroy();\n        var el = popup.container;\n        if (el && el.parentNode)\n            el.parentNode.removeChild(el);\n    }\n    if (iframe)\n        document.body.removeChild(iframe);\n    if (originalDocument) {\n        window.document = originalDocument;\n        originalDocument = null;\n    }\n    done && done();\n};\n\nmodule.exports = {\n    \"test: verify width and height\": function() {\n        setupPopup();\n        tryShowAndRender({ top: 0, left: 0 }, lineHeight, \"bottom\");\n        renderHeight = popup.container.offsetHeight;\n        assert.strictEqual(popup.isOpen, true);\n        assert.strictEqual(renderHeight > 0, true);\n        popup.hide();\n        assert.strictEqual(popup.isOpen, false);\n    },\n    \"test: tryShow does not display popup if there is not enough space on the anchor side\": function() {\n        setupPopup();\n        var result = tryShowAndRender({ top: notEnoughSpaceOnBottom, left: 0}, lineHeight, \"bottom\");\n        assert.strictEqual(result, false);\n        assert.strictEqual(popup.isOpen, false);\n        result = tryShowAndRender({ top: 50, left: 0}, lineHeight, \"top\");\n        assert.strictEqual(result, false);\n        assert.strictEqual(popup.isOpen, false);\n    },\n    \"test: tryShow slides popup on the X axis if there are not enough space on the right\": function() {\n        setupPopup();\n        \n        var result = tryShowAndRender({ top: 0, left: notEnoughSpaceOnRight }, lineHeight, \"bottom\");\n        assert.strictEqual(result, true);\n        assert.strictEqual(popup.isOpen, true);\n        assert.strictEqual(popup.container.getBoundingClientRect().right, window.innerWidth - (popup.renderer.scrollBar.width || 10));\n        assert.strictEqual(Math.abs(popup.container.getBoundingClientRect().width - renderWidth) < 5, true);\n        popup.hide();\n        assert.strictEqual(popup.isOpen, false);\n\n        result = tryShowAndRender({ top: notEnoughSpaceOnBottom, left: notEnoughSpaceOnRight }, lineHeight, \"top\");\n        assert.strictEqual(result, true);\n        assert.strictEqual(popup.isOpen, true);\n        assert.strictEqual(popup.container.getBoundingClientRect().right, window.innerWidth - (popup.renderer.scrollBar.width || 10));\n        assert.strictEqual(Math.abs(popup.container.getBoundingClientRect().width - renderWidth) < 5, true);\n        popup.hide();\n        assert.strictEqual(popup.isOpen, false);\n    },\n    \"test: tryShow called with forceShow resizes popup height to fit popup\": function() {\n        setupPopup();\n        \n        var result = tryShowAndRender({ top: notEnoughSpaceOnBottom, left: 0 }, lineHeight, \"bottom\", true);\n        assert.strictEqual(result, true);\n        assert.strictEqual(popup.isOpen, true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height <= 50, true);\n        assert.strictEqual(popup.container.getBoundingClientRect().top > notEnoughSpaceOnBottom + lineHeight, true);\n        assert.strictEqual(Math.abs(popup.container.getBoundingClientRect().width - renderWidth) < 5, true);\n        popup.hide();\n        assert.strictEqual(popup.isOpen, false);\n\n        result = tryShowAndRender({ top: 50, left: 0 }, lineHeight, \"top\", true);\n        assert.strictEqual(result, true);\n        assert.strictEqual(popup.isOpen, true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height <= 50, true);\n        assert.strictEqual(popup.container.getBoundingClientRect().bottom <= 50, true);\n        assert.strictEqual(Math.abs(popup.container.getBoundingClientRect().width - renderWidth) < 5, true);\n        popup.hide();\n        assert.strictEqual(popup.isOpen, false);\n    },\n    \"test: show displays popup in all 4 corners correctly without topdownOnly specified\": function() {\n        setupPopup();\n        popup.show({ top: 50, left: 0 }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().top >= 50 + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: notEnoughSpaceOnBottom, left: 0 }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().bottom <= notEnoughSpaceOnBottom);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: 50, left: notEnoughSpaceOnRight }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().top >= 50 + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: notEnoughSpaceOnBottom, left: notEnoughSpaceOnRight }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().bottom <= notEnoughSpaceOnBottom);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n    },\n    \"test: show displays popup in all 4 corners correctly with topdownOnly specified\": function() {\n        setupPopup();\n        popup.show({ top: 50, left: 0 }, lineHeight, true);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().top >= 50 + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: 50, left: notEnoughSpaceOnRight }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.strictEqual(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().top >= 50 + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: notEnoughSpaceOnBottom, left: 0 }, lineHeight, true);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.ok(popup.container.getBoundingClientRect().height <= 50);\n        assert.ok(popup.container.getBoundingClientRect().top >= notEnoughSpaceOnBottom + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: notEnoughSpaceOnBottom, left: notEnoughSpaceOnRight }, lineHeight, true);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.ok(popup.container.getBoundingClientRect().height <= 50);\n        assert.ok(popup.container.getBoundingClientRect().top >= notEnoughSpaceOnBottom + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n    },\n    \"test: resets popup size if space is available again\": function() {\n        setupPopup();\n        popup.show({ top: notEnoughSpaceOnBottom, left: notEnoughSpaceOnRight }, lineHeight, true);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.ok(popup.container.getBoundingClientRect().height <= 50);\n        assert.ok(popup.container.getBoundingClientRect().top >= notEnoughSpaceOnBottom + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n\n        popup.show({ top: 50, left: notEnoughSpaceOnRight }, lineHeight);\n        popup.renderer.updateFull(true);\n        assert.notEqual(popup.container.style.display, \"none\");\n        assert.ok(popup.container.getBoundingClientRect().height, renderHeight);\n        assert.ok(popup.container.getBoundingClientRect().top >= 50 + lineHeight);\n        popup.hide();\n        assert.strictEqual(popup.container.style.display, \"none\");\n    },\n    tearDown: tearDown\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/autocomplete/text_completer.js",
    "content": "var Range = require(\"../range\").Range;\n\nvar splitRegex = /[^a-zA-Z_0-9\\$\\-\\u00C0-\\u1FFF\\u2C00-\\uD7FF\\w]+/;\n\nfunction getWordIndex(doc, pos) {\n    var textBefore = doc.getTextRange(Range.fromPoints({\n        row: 0,\n        column: 0\n    }, pos));\n    return textBefore.split(splitRegex).length - 1;\n}\n\n/**\n * Does a distance analysis of the word `prefix` at position `pos` in `doc`.\n * @return Map\n */\nfunction wordDistance(doc, pos) {\n    var prefixPos = getWordIndex(doc, pos);\n    var words = doc.getValue().split(splitRegex);\n    var wordScores = Object.create(null);\n\n    var currentWord = words[prefixPos];\n\n    words.forEach(function (word, idx) {\n        if (!word || word === currentWord) return;\n\n        var distance = Math.abs(prefixPos - idx);\n        var score = words.length - distance;\n        if (wordScores[word]) {\n            wordScores[word] = Math.max(score, wordScores[word]);\n        }\n        else {\n            wordScores[word] = score;\n        }\n    });\n    return wordScores;\n}\n\nexports.id = \"textCompleter\";\n\nexports.getCompletions = function (editor, session, pos, prefix, callback) {\n    var wordScore = wordDistance(session, pos);\n    var wordList = Object.keys(wordScore);\n    callback(null, wordList.map(function (word) {\n        return {\n            caption: word,\n            value: word,\n            score: wordScore[word],\n            meta: \"local\"\n        };\n    }));\n};\n"
  },
  {
    "path": "src/autocomplete/util.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\n\nexports.parForEach = function(array, fn, callback) {\n    var completed = 0;\n    var arLength = array.length;\n    if (arLength === 0)\n        callback();\n    for (var i = 0; i < arLength; i++) {\n        fn(array[i], function(result, err) {\n            completed++;\n            if (completed === arLength)\n                callback(result, err);\n        });\n    }\n};\n\nvar ID_REGEX = /[a-zA-Z_0-9\\$\\-\\u00A2-\\u2000\\u2070-\\uFFFF]/;\n\nexports.retrievePrecedingIdentifier = function(text, pos, regex) {\n    regex = regex || ID_REGEX;\n    var buf = [];\n    for (var i = pos-1; i >= 0; i--) {\n        if (regex.test(text[i]))\n            buf.push(text[i]);\n        else\n            break;\n    }\n    return buf.reverse().join(\"\");\n};\n\nexports.retrieveFollowingIdentifier = function(text, pos, regex) {\n    regex = regex || ID_REGEX;\n    var buf = [];\n    for (var i = pos; i < text.length; i++) {\n        if (regex.test(text[i]))\n            buf.push(text[i]);\n        else\n            break;\n    }\n    return buf;\n};\n\n/**\n * @param editor\n * @return {string}\n */\nexports.getCompletionPrefix = function (editor) {\n    var pos = editor.getCursorPosition();\n    var line = editor.session.getLine(pos.row);\n    var prefix;\n    editor.completers.forEach(function(completer) {\n        if (completer.identifierRegexps) {\n            completer.identifierRegexps.forEach(function(identifierRegex) {\n                if (!prefix && identifierRegex)\n                    prefix = this.retrievePrecedingIdentifier(line, pos.column, identifierRegex);\n            }.bind(this));\n        }\n    }.bind(this));\n    return prefix || this.retrievePrecedingIdentifier(line, pos.column);\n};\n\n/**\n * @param {Editor} editor\n * @param {string} [previousChar] if not provided, it falls back to the preceding character in the editor\n * @returns {boolean} whether autocomplete should be triggered\n */\nexports.triggerAutocomplete = function (editor, previousChar) {\n    var previousChar = previousChar == null\n        ? editor.session.getPrecedingCharacter()\n        : previousChar;\n    return editor.completers.some((completer) => {\n        if (completer.triggerCharacters && Array.isArray(completer.triggerCharacters)) {\n            return completer.triggerCharacters.includes(previousChar);\n        }\n    });\n};\n"
  },
  {
    "path": "src/autocomplete.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./editor\").Editor} Editor\n * @typedef {import(\"../ace-internal\").Ace.CompletionProviderOptions} CompletionProviderOptions\n * @typedef {import(\"../ace-internal\").Ace.CompletionOptions} CompletionOptions\n * @typedef {import(\"../ace-internal\").Ace.Position} Position\n */\nvar HashHandler = require(\"./keyboard/hash_handler\").HashHandler;\nvar AcePopup = require(\"./autocomplete/popup\").AcePopup;\nvar AceInline = require(\"./autocomplete/inline\").AceInline;\nvar getAriaId = require(\"./autocomplete/popup\").getAriaId;\nvar util = require(\"./autocomplete/util\");\nvar lang = require(\"./lib/lang\");\nvar dom = require(\"./lib/dom\");\nvar snippetManager = require(\"./snippets\").snippetManager;\nvar config = require(\"./config\");\nvar event = require(\"./lib/event\");\nvar preventParentScroll = require(\"./lib/scroll\").preventParentScroll;\n\n/**\n * @typedef BaseCompletion\n * @property {number} [score] - a numerical value that determines the order in which completions would be displayed.\n * A lower score means that the completion would be displayed further from the start\n * @property {string} [meta] - a short description of the completion\n * @property {string} [caption] - the text that would be displayed in the completion list. If omitted, value or snippet\n * would be shown instead.\n * @property {string} [docHTML] - an HTML string that would be displayed as an additional popup\n * @property {string} [docText] - a plain text that would be displayed as an additional popup. If `docHTML` exists,\n * it would be used instead of `docText`.\n * @property {string} [completerId] - the identifier of the completer\n * @property {boolean} [skipFilter] - a boolean value to decide if the popup item is going to skip the filtering process done using prefix text.\n * @property {import(\"../ace-internal\").Ace.IRange} [range] - An object specifying the range of text to be replaced with the new completion value (experimental)\n * @property {any} [command] - A command to be executed after the completion is inserted (experimental)\n * @property {string} [snippet] - a text snippet that would be inserted when the completion is selected\n * @property {string} [value] - The text that would be inserted when selecting this completion.\n * @property {import(\"../ace-internal\").Ace.Completer} [completer]\n * @property {boolean} [hideInlinePreview]\n * @export\n */\n\n/**\n * @typedef {BaseCompletion & {snippet: string}} SnippetCompletion\n * @property {string} snippet\n * @property {string} [value]\n * @export\n */\n\n/**\n * @typedef {BaseCompletion & {value: string}} ValueCompletion\n * @property {string} value\n * @property {string} [snippet]\n * @export\n */\n\n/**\n * Represents a suggested text snippet intended to complete a user's input\n * @typedef Completion\n * @type {SnippetCompletion|ValueCompletion}\n * @export\n */\n\nvar destroyCompleter = function(e, editor) {\n    editor.completer && editor.completer.destroy();\n};\n\n/**\n * This object controls the autocompletion components and their lifecycle.\n * There is an autocompletion popup, an optional inline ghost text renderer and a docuent tooltip popup inside.\n */\nclass Autocomplete {\n    constructor() {\n        this.autoInsert = false;\n        this.autoSelect = true;\n        this.autoShown = false;\n        this.exactMatch = false;\n        this.inlineEnabled = false;\n        this.keyboardHandler = new HashHandler();\n        this.keyboardHandler.bindKeys(this.commands);\n        this.parentNode = null;\n        this.setSelectOnHover = false;\n        /**@private*/\n        this.hasSeen = new Set();\n\n        /**\n         *  @property {Boolean} showLoadingState - A boolean indicating whether the loading states of the Autocompletion should be shown to the end-user. If enabled\n         * it shows a loading indicator on the popup while autocomplete is loading.\n         *\n         * Experimental: This visualisation is not yet considered stable and might change in the future.\n         */\n        this.showLoadingState = false;\n\n        /**\n         *  @property {number} stickySelectionDelay - a numerical value that determines after how many ms the popup selection will become 'sticky'.\n         *  Normally, when new elements are added to an open popup, the selection is reset to the first row of the popup. If sticky, the focus will remain\n         *  on the currently selected item when new items are added to the popup. Set to a negative value to disable this feature and never set selection to sticky.\n         */\n        this.stickySelectionDelay = 500;\n\n        this.blurListener = this.blurListener.bind(this);\n        this.changeListener = this.changeListener.bind(this);\n        this.mousedownListener = this.mousedownListener.bind(this);\n        this.mousewheelListener = this.mousewheelListener.bind(this);\n        this.onLayoutChange = this.onLayoutChange.bind(this);\n\n        this.changeTimer = lang.delayedCall(function() {\n            this.updateCompletions(true);\n        }.bind(this));\n\n        this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);\n        this.popupTimer = lang.delayedCall(this.$updatePopupPosition.bind(this), 50);\n\n        this.stickySelectionTimer = lang.delayedCall(function() {\n            this.stickySelection = true;\n        }.bind(this), this.stickySelectionDelay);\n\n        this.$firstOpenTimer = lang.delayedCall(/**@this{Autocomplete}*/function() {\n            var initialPosition = this.completionProvider && this.completionProvider.initialPosition;\n            if (this.autoShown || (this.popup && this.popup.isOpen) || !initialPosition || this.editor.completers.length === 0) return;\n\n            this.completions = new FilteredList(Autocomplete.completionsForLoading);\n            this.openPopup(this.editor, initialPosition.prefix, false);\n            this.popup.renderer.setStyle(\"ace_loading\", true);\n        }.bind(this), this.stickySelectionDelay);\n    }\n\n    static get completionsForLoading() { return [{\n            caption: config.nls(\"autocomplete.loading\", \"Loading...\"),\n            value: \"\"\n        }];\n    }\n\n    $init() {\n        /**@type {AcePopup}**/\n        this.popup = new AcePopup(this.parentNode || document.body || document.documentElement);\n        this.popup.on(\"click\", function(e) {\n            this.insertMatch();\n            e.stop();\n        }.bind(this));\n        this.popup.focus = this.editor.focus.bind(this.editor);\n        this.popup.on(\"show\", this.$onPopupShow.bind(this));\n        this.popup.on(\"hide\", this.$onHidePopup.bind(this));\n        this.popup.on(\"select\", this.$onPopupChange.bind(this));\n        event.addListener(this.popup.container, \"mouseout\", this.mouseOutListener.bind(this));\n        this.popup.on(\"changeHoverMarker\", this.tooltipTimer.bind(null, null));\n        this.popup.renderer.on(\"afterRender\", this.$onPopupRender.bind(this));\n        return this.popup;\n    }\n\n\n    $initInline() {\n        if (!this.inlineEnabled || this.inlineRenderer)\n            return;\n        this.inlineRenderer = new AceInline();\n        return this.inlineRenderer;\n    }\n\n    /**\n     * @return {AcePopup}\n     */\n    getPopup() {\n        return this.popup || this.$init();\n    }\n\n    $onHidePopup() {\n        if (this.inlineRenderer) {\n            this.inlineRenderer.hide();\n        }\n        this.hideDocTooltip();\n        this.stickySelectionTimer.cancel();\n        this.popupTimer.cancel();\n        this.stickySelection = false;\n    }\n    $seen(completion) {\n        if (!this.hasSeen.has(completion) && completion && completion.completer && completion.completer.onSeen && typeof completion.completer.onSeen === \"function\") {\n            completion.completer.onSeen(this.editor, completion);\n            this.hasSeen.add(completion);\n        }\n    }\n    $onPopupChange(hide) {\n        if (this.inlineRenderer && this.inlineEnabled) {\n            var completion = hide ? null : this.popup.getData(this.popup.getRow());\n            this.$updateGhostText(completion);\n            // If the mouse is over the tooltip, and we're changing selection on hover don't\n            // move the tooltip while hovering over the popup.\n            if (this.popup.isMouseOver && this.setSelectOnHover) {\n                // @ts-expect-error TODO: potential wrong arguments\n                this.tooltipTimer.call(null, null);\n                return;\n            }\n\n            // Update the popup position after a short wait to account for potential scrolling\n            this.popupTimer.schedule();\n            this.tooltipTimer.schedule();\n        } else {\n            // @ts-expect-error TODO: potential wrong arguments\n            this.popupTimer.call(null, null);\n            // @ts-expect-error TODO: potential wrong arguments\n            this.tooltipTimer.call(null, null);\n        }\n    }\n\n    $updateGhostText(completion) {\n        // Ghost text can include characters normally not part of the prefix (e.g. whitespace).\n        // When typing ahead with ghost text however, we want to simply prefix with respect to the\n        // base of the completion.\n        var row = this.base.row;\n        var column = this.base.column;\n        var cursorColumn = this.editor.getCursorPosition().column;\n        var prefix = this.editor.session.getLine(row).slice(column, cursorColumn);\n\n        if (!this.inlineRenderer.show(this.editor, completion, prefix)) {\n            this.inlineRenderer.hide();\n        } else {\n            this.$seen(completion);\n        }\n    }\n\n    $onPopupRender() {\n        const inlineEnabled = this.inlineRenderer && this.inlineEnabled;\n        if (this.completions && this.completions.filtered && this.completions.filtered.length > 0) {\n            for (var i = this.popup.getFirstVisibleRow(); i <= this.popup.getLastVisibleRow(); i++) {\n                var completion = this.popup.getData(i);\n                if (completion && (!inlineEnabled || completion.hideInlinePreview)) {\n                    this.$seen(completion);\n                }\n            }\n        }\n    }\n\n    $onPopupShow(hide) {\n        this.$onPopupChange(hide);\n        this.stickySelection = false;\n        if (this.stickySelectionDelay >= 0)\n            this.stickySelectionTimer.schedule(this.stickySelectionDelay);\n    }\n\n    observeLayoutChanges() {\n        if (this.$elements || !this.editor) return;\n        window.addEventListener(\"resize\", this.onLayoutChange, {passive: true});\n        window.addEventListener(\"wheel\", this.mousewheelListener);\n\n        var el = this.editor.container.parentNode;\n        var elements = [];\n        while (el) {\n            elements.push(el);\n            el.addEventListener(\"scroll\", this.onLayoutChange, {passive: true});\n            el = el.parentNode;\n        }\n        this.$elements = elements;\n    }\n    unObserveLayoutChanges() {\n        // @ts-expect-error This is expected for some browsers\n        window.removeEventListener(\"resize\", this.onLayoutChange, {passive: true});\n        window.removeEventListener(\"wheel\", this.mousewheelListener);\n        this.$elements && this.$elements.forEach((el) => {\n            // @ts-expect-error This is expected for some browsers\n            el.removeEventListener(\"scroll\", this.onLayoutChange, {passive: true});\n        });\n        this.$elements = null;\n    }\n\n    /**\n     * @internal\n     */\n    onLayoutChange() {\n        if (!this.popup.isOpen) return this.unObserveLayoutChanges();\n        this.$updatePopupPosition();\n        this.updateDocTooltip();\n    }\n\n    $updatePopupPosition() {\n        var editor = this.editor;\n        var renderer = editor.renderer;\n\n        var lineHeight = renderer.layerConfig.lineHeight;\n        var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);\n        pos.left -= this.popup.getTextLeftOffset();\n\n        var rect = editor.container.getBoundingClientRect();\n        pos.top += rect.top - renderer.layerConfig.offset;\n        pos.left += rect.left - editor.renderer.scrollLeft;\n        pos.left += renderer.gutterWidth;\n\n        var posGhostText = {\n            top: pos.top,\n            left: pos.left\n        };\n\n        if (renderer.$ghostText && renderer.$ghostTextWidget) {\n            if (this.base.row === renderer.$ghostText.position.row) {\n                posGhostText.top += renderer.$ghostTextWidget.el.offsetHeight;\n            }\n        }\n\n        // posGhostText can be below the editor rendering the popup away from the editor.\n        // In this case, we want to render the popup such that the top aligns with the bottom of the editor.\n        var editorContainerBottom = editor.container.getBoundingClientRect().bottom - lineHeight;\n        var lowestPosition = editorContainerBottom < posGhostText.top ?\n            {top: editorContainerBottom, left: posGhostText.left} :\n            posGhostText;\n\n        // Try to render below ghost text, then above ghost text, then over ghost text\n        if (this.popup.tryShow(lowestPosition, lineHeight, \"bottom\")) {\n            return;\n        }\n\n        if (this.popup.tryShow(pos, lineHeight, \"top\")) {\n            return;\n        }\n\n        this.popup.show(pos, lineHeight);\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {string} prefix\n     * @param {boolean} [keepPopupPosition]\n     */\n    openPopup(editor, prefix, keepPopupPosition) {\n        this.$firstOpenTimer.cancel();\n\n        if (!this.popup)\n            this.$init();\n\n        if (this.inlineEnabled && !this.inlineRenderer)\n            this.$initInline();\n\n        this.popup.autoSelect = this.autoSelect;\n        this.popup.setSelectOnHover(this.setSelectOnHover);\n\n        var oldRow = this.popup.getRow();\n        var previousSelectedItem = this.popup.data[oldRow];\n\n        this.popup.setData(this.completions.filtered, this.completions.filterText);\n        if (this.editor.textInput.setAriaOptions) {\n            this.editor.textInput.setAriaOptions({\n                activeDescendant: getAriaId(this.popup.getRow()),\n                inline: this.inlineEnabled\n            });\n        }\n\n        editor.keyBinding.addKeyboardHandler(this.keyboardHandler);\n\n        var newRow;\n        if (this.stickySelection)\n            newRow = this.popup.data.indexOf(previousSelectedItem);\n        if (!newRow || newRow === -1)\n            newRow = 0;\n\n        this.popup.setRow(this.autoSelect ? newRow : -1);\n\n        // If we stay on the same row, but the content is different, we want to update the popup.\n        if (newRow === oldRow && previousSelectedItem !== this.completions.filtered[newRow])\n            this.$onPopupChange();\n\n        // If we stay on the same line and have inlinePreview enabled, we want to make sure the\n        // ghost text remains up-to-date.\n        const inlineEnabled = this.inlineRenderer && this.inlineEnabled;\n        if (newRow === oldRow && inlineEnabled) {\n            var completion = this.popup.getData(this.popup.getRow());\n            this.$updateGhostText(completion);\n        }\n\n        if (!keepPopupPosition) {\n            this.popup.setTheme(editor.getTheme());\n            this.popup.setFontSize(editor.getFontSize());\n\n            this.$updatePopupPosition();\n            if (this.tooltipNode) {\n                this.updateDocTooltip();\n            }\n        }\n        this.changeTimer.cancel();\n        this.observeLayoutChanges();\n    }\n\n    /**\n     * Detaches all elements from the editor, and cleans up the data for the session\n     */\n    detach() {\n        if (this.editor) {\n            this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);\n            this.editor.off(\"changeSelection\", this.changeListener);\n            this.editor.off(\"blur\", this.blurListener);\n            this.editor.off(\"mousedown\", this.mousedownListener);\n            this.editor.off(\"mousewheel\", this.mousewheelListener);\n        }\n        this.$firstOpenTimer.cancel();\n\n        this.changeTimer.cancel();\n        this.hideDocTooltip();\n\n        if (this.completionProvider) {\n            this.completionProvider.detach();\n        }\n\n        if (this.popup && this.popup.isOpen)\n            this.popup.hide();\n\n        if (this.popup && this.popup.renderer) {\n            this.popup.renderer.off(\"afterRender\", this.$onPopupRender);\n        }\n\n        if (this.base)\n            this.base.detach();\n        this.activated = false;\n        this.completionProvider = this.completions = this.base = null;\n        this.unObserveLayoutChanges();\n    }\n\n    changeListener(e) {\n        var cursor = this.editor.selection.lead;\n        if (cursor.row != this.base.row || cursor.column < this.base.column) {\n            this.detach();\n        }\n        if (this.activated)\n            this.changeTimer.schedule();\n        else\n            this.detach();\n    }\n\n    blurListener(e) {\n        // we have to check if activeElement is a child of popup because\n        // on IE preventDefault doesn't stop scrollbar from being focussed\n        var el = document.activeElement;\n        var text = this.editor.textInput.getElement();\n        var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);\n        var container = this.popup && this.popup.container;\n        if (el != text && el.parentNode != container && !fromTooltip\n            && el != this.tooltipNode && e.relatedTarget != text\n        ) {\n            this.detach();\n        }\n    }\n\n    mousedownListener(e) {\n        this.detach();\n    }\n\n    mousewheelListener(e) {\n        if (this.popup && !this.popup.isMouseOver)\n            this.detach();\n    }\n\n    mouseOutListener(e) {\n        // Check whether the popup is still open after the mouseout event,\n        // if so, attempt to move it to its desired position.\n        if (this.popup.isOpen)\n            this.$updatePopupPosition();\n    }\n\n   goTo(where) {\n        this.popup.goTo(where);\n    }\n\n    /**\n     * @param {Completion} data\n     * @param {undefined} [options]\n     * @return {boolean | void}\n     */\n    insertMatch(data, options) {\n        if (!data)\n            data = this.popup.getData(this.popup.getRow());\n        if (!data)\n            return false;\n        if (data.value === \"\") // Explicitly given nothing to insert, e.g. \"No suggestion state\"\n            return this.detach();\n        var completions = this.completions;\n        // @ts-expect-error TODO: potential wrong arguments\n        var result = this.getCompletionProvider().insertMatch(this.editor, data, completions.filterText, options);\n        // detach only if new popup was not opened while inserting match\n        if (this.completions == completions)\n            this.detach();\n        return result;\n    }\n\n    /**\n     * This is the entry point for the autocompletion class, triggers the actions which collect and display suggestions\n     * @param {Editor} editor\n     * @param {CompletionOptions} [options]\n     */\n    showPopup(editor, options) {\n        if (this.editor)\n            this.detach();\n\n        this.activated = true;\n\n        this.editor = editor;\n        if (editor.completer != this) {\n            if (editor.completer)\n                editor.completer.detach();\n            editor.completer = this;\n        }\n\n        editor.on(\"changeSelection\", this.changeListener);\n        editor.on(\"blur\", this.blurListener);\n        editor.on(\"mousedown\", this.mousedownListener);\n        editor.on(\"mousewheel\", this.mousewheelListener);\n\n        this.updateCompletions(false, options);\n    }\n\n    /**\n     *\n     * @param {{pos: Position, prefix: string}} [initialPosition]\n     * @return {CompletionProvider}\n     */\n    getCompletionProvider(initialPosition) {\n        if (!this.completionProvider)\n            this.completionProvider = new CompletionProvider(initialPosition);\n        return this.completionProvider;\n    }\n\n    /**\n     * This method is deprecated, it is only kept for backwards compatibility.\n     * Use the same method include CompletionProvider instead for the same functionality.\n     * @deprecated\n     */\n    gatherCompletions(editor, callback) {\n        return this.getCompletionProvider().gatherCompletions(editor, callback);\n    }\n\n    /**\n     * @param {boolean} keepPopupPosition\n     * @param {CompletionOptions} [options]\n     */\n    updateCompletions(keepPopupPosition, options) {\n        if (keepPopupPosition && this.base && this.completions) {\n            var pos = this.editor.getCursorPosition();\n            var prefix = this.editor.session.getTextRange({start: this.base, end: pos});\n            if (prefix == this.completions.filterText)\n                return;\n            this.completions.setFilter(prefix);\n            if (!this.completions.filtered.length)\n                return this.detach();\n            if (this.completions.filtered.length == 1\n            && this.completions.filtered[0].value == prefix\n            && !this.completions.filtered[0].snippet)\n                return this.detach();\n            this.openPopup(this.editor, prefix, keepPopupPosition);\n            return;\n        }\n\n        if (options && options.matches) {\n            var pos = this.editor.getSelectionRange().start;\n            this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);\n            this.base.$insertRight = true;\n            this.completions = new FilteredList(options.matches);\n            this.getCompletionProvider().completions = this.completions;\n            return this.openPopup(this.editor, \"\", keepPopupPosition);\n        }\n\n        var session = this.editor.getSession();\n        var pos = this.editor.getCursorPosition();\n        var prefix = util.getCompletionPrefix(this.editor);\n        this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);\n        this.base.$insertRight = true;\n        var completionOptions = {\n            exactMatch: this.exactMatch,\n            // @ts-expect-error TODO: couldn't find initializer\n            ignoreCaption: this.ignoreCaption\n        };\n        this.getCompletionProvider({\n            prefix,\n            pos\n        }).provideCompletions(this.editor, completionOptions,\n            /**\n             * @type {(err: any, completions: FilteredList, finished: boolean) => void | boolean}\n             * @this {Autocomplete}\n             */\n            function (err, completions, finished) {\n                var filtered = completions.filtered;\n                var prefix = util.getCompletionPrefix(this.editor);\n            this.$firstOpenTimer.cancel();\n\n                if (finished) {\n                    // No results\n                    if (!filtered.length) {\n                        var emptyMessage = !this.autoShown && this.emptyMessage;\n                        if (typeof emptyMessage == \"function\") emptyMessage = this.emptyMessage(prefix);\n                        if (emptyMessage) {\n                        var completionsForEmpty = [{\n                            caption: emptyMessage,\n                                    value: \"\"\n                                }\n                            ];\n                            this.completions = new FilteredList(completionsForEmpty);\n                            this.openPopup(this.editor, prefix, keepPopupPosition);\n                            this.popup.renderer.setStyle(\"ace_loading\", false);\n                            this.popup.renderer.setStyle(\"ace_empty-message\", true);\n                            return;\n                        }\n                        return this.detach();\n                    }\n\n                    // One result equals to the prefix\n                    if (filtered.length == 1 && filtered[0].value == prefix\n                        && !filtered[0].snippet) return this.detach();\n\n                    // Autoinsert if one result\n                    if (this.autoInsert && !this.autoShown && filtered.length == 1) return this.insertMatch(\n                        filtered[0]);\n                }\n            // If showLoadingState is true and there is still a completer loading, show 'Loading...'\n            // in the top row of the completer popup.\n            this.completions = !finished && this.showLoadingState ?\n                new FilteredList(\n                    Autocomplete.completionsForLoading.concat(filtered), completions.filterText\n                ) :\n                completions;\n\n                this.openPopup(this.editor, prefix, keepPopupPosition);\n\n            this.popup.renderer.setStyle(\"ace_empty-message\", false);\n            this.popup.renderer.setStyle(\"ace_loading\", !finished);\n        }.bind(this));\n\n        if (this.showLoadingState && !this.autoShown && !(this.popup && this.popup.isOpen)) {\n            this.$firstOpenTimer.delay(this.stickySelectionDelay/2);\n        }\n    }\n\n    cancelContextMenu() {\n        this.editor.$mouseHandler.cancelContextMenu();\n    }\n\n    updateDocTooltip() {\n        var popup = this.popup;\n        var all = this.completions && this.completions.filtered;\n        var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);\n        var doc = null;\n        if (!selected || !this.editor || !this.popup.isOpen)\n            return this.hideDocTooltip();\n\n        var completersLength = this.editor.completers.length;\n        for (var i = 0; i < completersLength; i++) {\n            var completer = this.editor.completers[i];\n            if (completer.getDocTooltip && selected.completerId === completer.id) {\n                doc = completer.getDocTooltip(selected);\n                break;\n            }\n        }\n        if (!doc && typeof selected != \"string\")\n            doc = selected;\n\n        if (typeof doc == \"string\")\n            doc = {docText: doc};\n        if (!doc || !(doc.docHTML || doc.docText))\n            return this.hideDocTooltip();\n        this.showDocTooltip(doc);\n    }\n\n    showDocTooltip(item) {\n        if (!this.tooltipNode) {\n            this.tooltipNode = dom.createElement(\"div\");\n            this.tooltipNode.style.margin = \"0\";\n            this.tooltipNode.style.pointerEvents = \"auto\";\n            this.tooltipNode.style.overscrollBehavior = \"contain\";\n            this.tooltipNode.tabIndex = -1;\n            this.tooltipNode.onblur = this.blurListener.bind(this);\n            this.tooltipNode.onclick = this.onTooltipClick.bind(this);\n            this.tooltipNode.id = \"doc-tooltip\";\n            this.tooltipNode.setAttribute(\"role\", \"tooltip\");\n            // prevent editor scroll if tooltip is inside an editor\n            this.tooltipNode.addEventListener(\"wheel\", preventParentScroll);\n        }\n        var theme = this.editor.renderer.theme;\n        this.tooltipNode.className = \"ace_tooltip ace_doc-tooltip \" +\n            (theme.isDark? \"ace_dark \" : \"\") + (theme.cssClass || \"\");\n\n        var tooltipNode = this.tooltipNode;\n        if (item.docHTML) {\n            tooltipNode.innerHTML = item.docHTML;\n        } else if (item.docText) {\n            tooltipNode.textContent = item.docText;\n        }\n\n        if (!tooltipNode.parentNode)\n            this.popup.container.appendChild(this.tooltipNode);\n\n        var popup = this.popup;\n        var rect = popup.container.getBoundingClientRect();\n\n        var targetWidth = 400;\n        var targetHeight = 300;\n        var scrollBarSize = popup.renderer.scrollBar.width || 10;\n\n        var leftSize = rect.left;\n        var rightSize = window.innerWidth - rect.right - scrollBarSize;\n        var topSize = popup.isTopdown ?  window.innerHeight - scrollBarSize - rect.bottom : rect.top;\n        var scores = [\n            Math.min(rightSize / targetWidth, 1),\n            Math.min(leftSize / targetWidth, 1),\n            Math.min(topSize / targetHeight, 1) * 0.9,\n        ];\n        var max = Math.max.apply(Math, scores);\n        var tooltipStyle = tooltipNode.style;\n        tooltipStyle.display = \"block\";\n\n        if (max == scores[0] || scores[0] >= 1) {\n            tooltipStyle.left = (rect.right + 1) + \"px\";\n            tooltipStyle.right = \"\";\n            tooltipStyle.maxWidth = targetWidth * max + \"px\";\n            tooltipStyle.top = rect.top + \"px\";\n            tooltipStyle.bottom = \"\";\n            tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + \"px\";\n        } else if (max == scores[1] || scores[1] >= 1) {\n            tooltipStyle.right = window.innerWidth - rect.left + \"px\";\n            tooltipStyle.left = \"\";\n            tooltipStyle.maxWidth = targetWidth * max + \"px\";\n            tooltipStyle.top = rect.top + \"px\";\n            tooltipStyle.bottom = \"\";\n            tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + \"px\";\n        } else if (max == scores[2]) {\n            tooltipStyle.left = rect.left + \"px\";\n            tooltipStyle.right = \"\";\n            tooltipStyle.maxWidth = Math.min(targetWidth, window.innerWidth - rect.left) + \"px\";\n\n            if (popup.isTopdown) {\n                tooltipStyle.top = rect.bottom + \"px\";\n                tooltipStyle.bottom = \"\";\n                tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.bottom, targetHeight) + \"px\";\n            } else {\n                tooltipStyle.top = \"\";\n                tooltipStyle.bottom = (window.innerHeight  - rect.top) + \"px\";\n                tooltipStyle.maxHeight = Math.min(rect.top, targetHeight) + \"px\";\n            }\n        }\n        dom.$fixPositionBug(tooltipNode);\n    }\n\n    hideDocTooltip() {\n        this.tooltipTimer.cancel();\n        if (!this.tooltipNode) return;\n        var el = this.tooltipNode;\n        if (!this.editor.isFocused() && document.activeElement == el)\n            this.editor.focus();\n        this.tooltipNode = null;\n        if (el.parentNode)\n            el.parentNode.removeChild(el);\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onTooltipClick(e) {\n        var a = e.target;\n        while (a && a != this.tooltipNode) {\n            if (a.nodeName == \"A\" && a.href) {\n                a.rel = \"noreferrer\";\n                a.target = \"_blank\";\n                break;\n            }\n            a = a.parentNode;\n        }\n    }\n\n    destroy() {\n        this.detach();\n        if (this.popup) {\n            this.popup.destroy();\n            var el = this.popup.container;\n            if (el && el.parentNode)\n                el.parentNode.removeChild(el);\n        }\n        if (this.editor && this.editor.completer == this) {\n            this.editor.off(\"destroy\", destroyCompleter);\n            this.editor.completer = null;\n        }\n        this.inlineRenderer = this.popup = this.editor = null;\n    }\n\n    /**\n     * @param {Editor} editor\n     * @return {Autocomplete}\n     */\n    static for(editor) {\n        if (editor.completer instanceof Autocomplete) {\n            return editor.completer;\n        }\n        if (editor.completer) {\n            editor.completer.destroy();\n            editor.completer = null;\n        }\n        if (config.get(\"sharedPopups\")) {\n            if (!Autocomplete[\"$sharedInstance\"])\n                Autocomplete[\"$sharedInstance\"] = new Autocomplete();\n            editor.completer = Autocomplete[\"$sharedInstance\"];\n        } else {\n            editor.completer = new Autocomplete();\n            editor.once(\"destroy\", destroyCompleter);\n        }\n        // @ts-expect-error\n        return editor.completer;\n    }\n\n}\n\nAutocomplete.prototype.commands = {\n    \"Up\": function(editor) { editor.completer.goTo(\"up\"); },\n    \"Down\": function(editor) { editor.completer.goTo(\"down\"); },\n    \"Ctrl-Up|Ctrl-Home\": function(editor) { editor.completer.goTo(\"start\"); },\n    \"Ctrl-Down|Ctrl-End\": function(editor) { editor.completer.goTo(\"end\"); },\n\n    \"Esc\": function(editor) { editor.completer.detach(); },\n    \"Return\": function(editor) { return editor.completer.insertMatch(); },\n    \"Shift-Return\": function(editor) { editor.completer.insertMatch(null, {deleteSuffix: true}); },\n    \"Tab\": function(editor) {\n        var result = editor.completer.insertMatch();\n        if (!result && !editor.tabstopManager)\n            editor.completer.goTo(\"down\");\n        else\n            return result;\n    },\n    \"Backspace\": function(editor) {\n        editor.execCommand(\"backspace\");\n        var prefix = util.getCompletionPrefix(editor);\n        if (!prefix && editor.completer)\n            editor.completer.detach();\n    },\n\n    \"PageUp\": function(editor) { editor.completer.popup.gotoPageUp(); },\n    \"PageDown\": function(editor) { editor.completer.popup.gotoPageDown(); }\n};\n\nAutocomplete.startCommand = {\n    name: \"startAutocomplete\",\n    exec: function(editor, options) {\n        var completer = Autocomplete.for(editor);\n        completer.autoInsert = false;\n        completer.autoSelect = true;\n        completer.autoShown = false;\n        completer.showPopup(editor, options);\n        // prevent ctrl-space opening context menu on firefox on mac\n        completer.cancelContextMenu();\n    },\n    bindKey: \"Ctrl-Space|Ctrl-Shift-Space|Alt-Space\"\n};\n\n/**\n * This class is responsible for providing completions and inserting them to the editor\n */\nclass CompletionProvider {\n\n\n    /**\n     * @param {{pos: Position, prefix: string}} [initialPosition]\n     */\n    constructor(initialPosition) {\n        this.initialPosition = initialPosition;\n        this.active = true;\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {number} index\n     * @param {CompletionProviderOptions} [options]\n     * @returns {boolean}\n     */\n    insertByIndex(editor, index, options) {\n        if (!this.completions || !this.completions.filtered) {\n            return false;\n        }\n        return this.insertMatch(editor, this.completions.filtered[index], options);\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {Completion} data\n     * @param {CompletionProviderOptions} [options]\n     * @returns {boolean}\n     */\n    insertMatch(editor, data, options) {\n        if (!data)\n            return false;\n\n        editor.startOperation({command: {name: \"insertMatch\"}});\n        if (data.completer && data.completer.insertMatch) {\n            data.completer.insertMatch(editor, data);\n        } else {\n            // TODO add support for options.deleteSuffix\n            if (!this.completions)\n                return false;\n\n            var replaceBefore = this.completions.filterText.length;\n            var replaceAfter = 0;\n            if (data.range && data.range.start.row === data.range.end.row) {\n                replaceBefore -= this.initialPosition.prefix.length;\n                replaceBefore += this.initialPosition.pos.column - data.range.start.column;\n                replaceAfter += data.range.end.column - this.initialPosition.pos.column;\n            }\n\n            if (replaceBefore || replaceAfter) {\n                var ranges;\n                if (editor.selection.getAllRanges) {\n                    ranges = editor.selection.getAllRanges();\n                }\n                else {\n                    ranges = [editor.getSelectionRange()];\n                }\n                for (var i = 0, range; range = ranges[i]; i++) {\n                    range.start.column -= replaceBefore;\n                    range.end.column += replaceAfter;\n                    editor.session.remove(range);\n                }\n            }\n\n            if (data.snippet) {\n                snippetManager.insertSnippet(editor, data.snippet);\n            }\n            else {\n                this.$insertString(editor, data);\n            }\n            if (data.completer && data.completer.onInsert && typeof data.completer.onInsert == \"function\") {\n                data.completer.onInsert(editor, data);\n            }\n\n            if (data.command && data.command === \"startAutocomplete\") {\n                editor.execCommand(data.command);\n            }\n        }\n        editor.endOperation();\n        return true;\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {Completion} data\n     */\n    $insertString(editor, data) {\n        var text = data.value || data;\n        editor.execCommand(\"insertstring\", text);\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {import(\"../ace-internal\").Ace.CompletionCallbackFunction} callback\n     */\n    gatherCompletions(editor, callback) {\n        var session = editor.getSession();\n        var pos = editor.getCursorPosition();\n\n        var prefix = util.getCompletionPrefix(editor);\n\n        var matches = [];\n        this.completers = editor.completers;\n        var total = editor.completers.length;\n        editor.completers.forEach(function(completer, i) {\n            completer.getCompletions(editor, session, pos, prefix, function(err, results) {\n                if (completer.hideInlinePreview)\n                    results = results.map((result) =>  {\n                        return Object.assign(result, {hideInlinePreview: completer.hideInlinePreview});\n                    });\n\n                if (!err && results)\n                    matches = matches.concat(results);\n                // Fetch prefix again, because they may have changed by now\n                callback(null, {\n                    prefix: util.getCompletionPrefix(editor),\n                    matches: matches,\n                    finished: (--total === 0)\n                });\n            });\n        });\n        return true;\n    }\n\n    /**\n     * This is the entry point to the class, it gathers, then provides the completions asynchronously via callback.\n     * The callback function may be called multiple times, the last invokation is marked with a `finished` flag\n     * @param {Editor} editor\n     * @param {CompletionProviderOptions} options\n     * @param {(err: Error | undefined, completions: FilteredList | [], finished: boolean) => void} callback\n     */\n    provideCompletions(editor, options, callback) {\n        var processResults = function(results) {\n            var prefix = results.prefix;\n            var matches = results.matches;\n\n            this.completions = new FilteredList(matches);\n\n            if (options.exactMatch)\n                this.completions.exactMatch = true;\n\n            if (options.ignoreCaption)\n                this.completions.ignoreCaption = true;\n\n            this.completions.setFilter(prefix);\n\n            if (results.finished || this.completions.filtered.length)\n                callback(null, this.completions, results.finished);\n        }.bind(this);\n\n        var isImmediate = true;\n        var immediateResults = null;\n        this.gatherCompletions(editor, function(err, results) {\n            if (!this.active) {\n                return;\n            }\n            if (err) {\n                callback(err, [], true);\n                this.detach();\n            }\n            var prefix = results.prefix;\n\n            // Wrong prefix or wrong session -> ignore\n            if (prefix.indexOf(results.prefix) !== 0)\n                return;\n\n            // If multiple completers return their results immediately, we want to process them together\n            if (isImmediate) {\n                immediateResults = results;\n                return;\n            }\n\n            processResults(results);\n        }.bind(this));\n\n        isImmediate = false;\n        if (immediateResults) {\n            var results = immediateResults;\n            immediateResults = null;\n            processResults(results);\n        }\n    }\n\n    detach() {\n        this.active = false;\n        this.completers && this.completers.forEach(function(completer) {\n            if (typeof completer.cancel === \"function\") {\n                completer.cancel();\n            }\n        });\n    }\n}\n\nclass FilteredList {\n    /**\n     * @param {any} array\n     * @param {string} [filterText]\n     */\n    constructor(array, filterText) {\n        this.all = array;\n        this.filtered = array;\n        this.filterText = filterText || \"\";\n        this.exactMatch = false;\n        this.ignoreCaption = false;\n    }\n\n    setFilter(str) {\n        if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)\n            var matches = this.filtered;\n        else\n            var matches = this.all;\n\n        this.filterText = str;\n        matches = this.filterCompletions(matches, this.filterText);\n        matches = matches.sort(function(a, b) {\n            return b.exactMatch - a.exactMatch || b.$score - a.$score\n                || (a.caption || a.value).localeCompare(b.caption || b.value);\n        });\n\n        // make unique\n        var prev = null;\n        matches = matches.filter(function(item){\n            var caption = item.snippet || item.caption || item.value;\n            if (caption === prev) return false;\n            prev = caption;\n            return true;\n        });\n\n        this.filtered = matches;\n    }\n\n    filterCompletions(items, needle) {\n        var results = [];\n        var upper = needle.toUpperCase();\n        var lower = needle.toLowerCase();\n        loop: for (var i = 0, item; item = items[i]; i++) {\n            if (item.skipFilter) {\n                item.$score = item.score;\n                results.push(item);\n                continue;\n            }\n            var caption = (!this.ignoreCaption && item.caption) || item.value || item.snippet;\n            if (!caption) continue;\n            var lastIndex = -1;\n            var matchMask = 0;\n            var penalty = 0;\n            var index, distance;\n\n            if (this.exactMatch) {\n                if (needle !== caption.substr(0, needle.length))\n                    continue loop;\n            } else {\n                /**\n                 * It is for situation then, for example, we find some like 'tab' in item.value=\"Check the table\"\n                 * and want to see \"Check the TABle\" but see \"Check The tABle\".\n                 */\n                var fullMatchIndex = caption.toLowerCase().indexOf(lower);\n                if (fullMatchIndex > -1) {\n                    penalty = fullMatchIndex;\n                } else {\n                    // caption char iteration is faster in Chrome but slower in Firefox, so lets use indexOf\n                    for (var j = 0; j < needle.length; j++) {\n                        // TODO add penalty on case mismatch\n                        var i1 = caption.indexOf(lower[j], lastIndex + 1);\n                        var i2 = caption.indexOf(upper[j], lastIndex + 1);\n                        index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;\n                        if (index < 0)\n                            continue loop;\n                        distance = index - lastIndex - 1;\n                        if (distance > 0) {\n                            // first char mismatch should be more sensitive\n                            if (lastIndex === -1)\n                                penalty += 10;\n                            penalty += distance;\n                            matchMask = matchMask | (1 << j);\n                        }\n                        lastIndex = index;\n                    }\n                }\n            }\n            item.matchMask = matchMask;\n            item.exactMatch = penalty ? 0 : 1;\n            item.$score = (item.score || 0) - penalty;\n            results.push(item);\n        }\n        return results;\n    }\n}\n\nexports.Autocomplete = Autocomplete;\nexports.CompletionProvider = CompletionProvider;\nexports.FilteredList = FilteredList;\n"
  },
  {
    "path": "src/autocomplete_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar sendKey = require(\"./test/user\").type;\nvar ace = require(\"./ace\");\nvar assert = require(\"./test/assertions\");\nvar user = require(\"./test/user\");\nvar Range = require(\"./range\").Range;\nvar lang = require(\"./lib/lang\");\nrequire(\"./ext/language_tools\");\nvar Autocomplete = require(\"./autocomplete\").Autocomplete;\nvar config = require(\"./config\");\n\nvar MouseEvent = function(type, opts){\n    var e = document.createEvent(\"MouseEvents\");\n    e.initMouseEvent(/click|wheel/.test(type) ? type : \"mouse\" + type,\n        true, true, window,\n        opts.detail,\n        opts.x, opts.y, opts.x, opts.y,\n        opts.ctrl, opts.alt, opts.shift, opts.meta,\n        opts.button || 0, opts.relatedTarget);\n    return e;\n};\n\nvar editor;\nfunction initEditor(value) {\n    if (editor) {\n        editor.destroy();\n        editor.container.remove();\n        editor = null;\n    }\n    editor = ace.edit(null, {\n        value: value,\n        minLines: 10,\n        maxLines: 10,\n        enableBasicAutocompletion: true,\n        enableLiveAutocompletion: true\n    });\n    document.body.appendChild(editor.container);\n    editor.focus();\n\n    return editor;\n}\n\nvar slowCompleter = {\n    getCompletions: async function (editor, session, pos, prefix, callback) {\n        var completions = [\n            {\n                caption: \"slow option 1\",\n                value: \"s1\",\n                score: 3\n            }, {\n                caption: \"slow option 2\",\n                value: \"s2\",\n                score: 0\n            }\n        ];\n        await lang.sleep(200);\n        callback(null, completions);\n    }\n};\n\nvar fastCompleter = {\n    getCompletions: function (editor, session, pos, prefix, callback) {\n        var completions = [\n            {\n                caption: \"fast option 1\",\n                value: \"f1\",\n                score: 2\n            }, {\n                caption: \"fast option 2\",\n                value: \"f2\",\n                score: 1\n            },  {\n                caption: \"fast option 3\",\n                value: \"f3\",\n                score: 1\n            }\n        ];\n        callback(null, completions);\n    }\n};\n\nmodule.exports = {\n    tearDown: function() {\n        if (editor) {\n            editor.destroy();\n            editor.container.remove();\n            editor = null;\n        }\n    },\n    \"test: highlighting in the popup\": async function (done) {\n        editor = initEditor(\"\\narraysort alooooooooooooooooooooooooooooong_word\");\n\n        assert.ok(!editor.container.querySelector(\"style\"));\n\n        sendKey(\"a\");\n        await checkInnerHTML('<d \"ace_line ace_selected\" role=\"option\" aria-roledescription=\"item\" aria-setsize=\"2\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"arraysort, local\" id=\"suggest-aria-id:0\" aria-selected=\"true\"><s \"ace_completion-highlight\" role=\"mark\">a</s><s \"ace_\">rraysort</s><s \"ace_completion-spacer\"> </s><s \"ace_completion-meta\">local</s></d><d \"ace_line\" role=\"option\" aria-roledescription=\"item\" aria-setsize=\"2\" aria-describedby=\"doc-tooltip\" aria-posinset=\"2\" aria-label=\"alooooooooooooooooooooooooooooong_word, local\"><s \"ace_completion-highlight\" role=\"mark\">a</s><s \"ace_\">looooooooooooooooooooooooooooong_word</s><s \"ace_completion-spacer\"> </s><s \"ace_completion-meta\">local</s></d>');\n        sendKey(\"rr\");\n\n        await checkInnerHTML('<d \"ace_line ace_selected\" role=\"option\" aria-roledescription=\"item\" aria-setsize=\"1\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"arraysort, local\" id=\"suggest-aria-id:0\" aria-selected=\"true\"><s \"ace_completion-highlight\" role=\"mark\">arr</s><s \"ace_\">aysort</s><s \"ace_completion-spacer\"> </s><s \"ace_completion-meta\">local</s></d>');\n        sendKey(\"r\");\n\n        await checkInnerHTML('<d \"ace_line ace_selected\" role=\"option\" aria-roledescription=\"item\" aria-setsize=\"1\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"arraysort, local\" id=\"suggest-aria-id:0\" aria-selected=\"true\"><s \"ace_completion-highlight\" role=\"mark\">arr</s><s \"ace_\">ayso</s><s \"ace_completion-highlight\" role=\"mark\">r</s><s \"ace_\">t</s><s \"ace_completion-spacer\"> </s><s \"ace_completion-meta\">local</s></d>');\n        sendKey(\"Return\");\n        assert.equal(editor.getValue(), \"arraysort\\narraysort alooooooooooooooooooooooooooooong_word\");\n        editor.execCommand(\"insertstring\", \" looooooooooooooooooooooooooooong_\");\n\n        await checkInnerHTML('<d \"ace_line ace_selected\" role=\"option\" aria-roledescription=\"item\" aria-setsize=\"1\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"alooooooooooooooooooooooooooooong_word, local\" id=\"suggest-aria-id:0\" aria-selected=\"true\"><s \"ace_\">a</s><s \"ace_completion-highlight\" role=\"mark\">looooooooooooooooooooooooooooong_</s><s \"ace_\">word</s><s \"ace_completion-spacer\"> </s><s \"ace_completion-meta\">local</s></d>');\n        sendKey(\"Return\");\n\n        var last;\n\n        async function checkInnerHTML(expected) {\n            var popup = editor.completer.popup;\n\n            do {\n                await popup.renderer.once(\"afterRender\");\n                var innerHTML = popup.renderer.$textLayer.element.innerHTML\n                    .replace(/\\s*style=\"[^\"]+\"|class=|(d)iv|(s)pan/g, \"$1$2\");\n            } while(innerHTML == last);\n            assert.equal(innerHTML, expected);\n            last = innerHTML;\n        }\n\n        done();\n    },\n    \"test: completions range and command properties\": async function (done) {\n        editor = initEditor(\"goods \");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"will\",\n                            snippet: \"will: $1\",\n                            meta: \"snippet\",\n                            command: \"startAutocomplete\",\n                            range: new Range(0, 4, 0, 7)\n                        }, {\n                            caption: \"here\",\n                            value: \"-here\",\n                            range: new Range(0, 8, 0, 10)\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        editor.moveCursorTo(0, 6);\n        sendKey(\"w\");\n        var popup = editor.completer.popup;\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 1);\n        editor.onCommandKey(null, 0, 13);\n        assert.equal(popup.data.length, 2);\n        assert.equal(editor.getValue(), \"goodwill: \");\n\n        await popup.renderer.once(\"afterRender\");\n        editor.onCommandKey(null, 0, 13);\n        assert.equal(editor.getValue(), \"goodwill-here\");\n        done();\n    },\n    \"test: correct completion replacement range when completion prefix has more than one letter\": async function (done) {\n        editor = initEditor(\"<\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"div\",\n                            value: \"div\",\n                            range: new Range(0, 1, 0, 3)\n                        }, {\n                            caption: \"dialog\",\n                            value: \"dialog\",\n                            range: new Range(0, 1, 0, 3)\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        editor.moveCursorTo(0, 1);\n        sendKey(\"di\");\n        var popup = editor.completer.popup;\n        await lang.sleep(10);\n\n        assert.equal(popup.data.length, 2);\n        editor.onCommandKey(null, 0, 13);\n\n        await lang.sleep(10);\n        assert.equal(editor.getValue(), \"<dialog\");\n        done();\n    },\n    \"test: symbols after selection are not removed when replacement range is present\": async function (done) {\n        editor = initEditor(\"{}\");\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"apple\",\n                            snippet: \"apple: $1\",\n                            meta: \"snippet\",\n                            range: new Range(0, 1, 0, 2)\n                        }, {\n                            caption: \"pineapple\",\n                            value: \"pineapple\",\n                            range: new Range(0, 1, 0, 2)\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n        editor.moveCursorTo(0, 1);\n        sendKey(\"a\");\n        var popup = editor.completer.popup;\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 2);\n        editor.onCommandKey(null, 0, 13);\n        assert.equal(editor.getValue(), \"{apple: }\");\n\n        done();\n    },\n    \"test: should set correct aria attributes for popup items\": async function(done) {\n        editor = initEditor(\"\");\n        var newLineCharacter = editor.session.doc.getNewLineCharacter();\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = Array(10).fill(null).map(function (i, n) { return { caption: String(n), value: String(n)};});\n                    callback(null, completions);\n                },\n                triggerCharacters: [\".\", newLineCharacter]\n            }\n        ];\n        sendKey('Return');\n        var popup = editor.completer.popup;\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 10);\n        // check that the aria attributes have been set on  all the elements of the popup and that aria selected attributes are set on the first item\n        assert.ok(checkAria(\n            popup.renderer.$textLayer.element.innerHTML,\n            '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"0\" id=\"suggest-aria-id:0\" aria-selected=\"true\"><s >0</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"2\" aria-label=\"1\"><s >1</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"3\" aria-label=\"2\"><s >2</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"4\" aria-label=\"3\"><s >3</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"5\" aria-label=\"4\"><s >4</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"6\" aria-label=\"5\"><s >5</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"7\" aria-label=\"6\"><s >6</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"8\" aria-label=\"7\"><s >7</s><s > </s></d>'\n            + '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"9\" aria-label=\"8\"><s >8</s><s > </s></d>'\n        ));\n        const prevSelected = popup.selectedNode;\n        sendKey('Down');\n\n        await popup.renderer.once(\"afterRender\");\n        assert.ok(checkAria(\n            popup.selectedNode.outerHTML,\n            '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"2\" aria-label=\"1\" id=\"suggest-aria-id:1\" aria-selected=\"true\"><s >1</s><s > </s></d>'\n        ));\n        // check that the aria selected attributes have been removed from the previously selected element\n        assert.ok(checkAria(\n            prevSelected.outerHTML,\n            '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"1\" aria-label=\"0\"><s >0</s><s > </s></d>'\n        ));\n        sendKey('Down');\n\n        await popup.renderer.once(\"afterRender\");\n        assert.ok(checkAria(\n            popup.selectedNode.outerHTML,\n            '<d  role=\"option\" aria-roledescription=\"item\" aria-setsize=\"10\" aria-describedby=\"doc-tooltip\" aria-posinset=\"3\" aria-label=\"2\" id=\"suggest-aria-id:2\" aria-selected=\"true\"><s >2</s><s > </s></d>'\n        ));\n\n        function checkAria(htmlElement, expected) {\n            var actual = htmlElement.replace(/\\s*style=\"[^\"]+\"|class=\"[^\"]+\"|(d)iv|(s)pan/g, \"$1$2\");\n            return actual === expected;\n        }\n\n        done();\n    },\n    \"test: different completers tooltips\": async function (done) {\n        editor = initEditor(\"\");\n        var firstDoc = \"<b>First</b>\";\n        var secondDoc = \"Second\";\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"abc\",\n                            snippet: \"ab: $1\",\n                            meta: \"snippet\",\n                            completerId: \"firstCompleter\"\n                        }, {\n                            caption: \"cde\",\n                            value: \"cde\",\n                            completerId: \"firstCompleter\"\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                getDocTooltip: function (item) {\n                    if (!item.docHTML) {\n                        item.docHTML = firstDoc;\n                    }\n                },\n                id: \"firstCompleter\"\n            }, {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"abcd\",\n                            snippet: \"abcd: $1\",\n                            meta: \"snippet\",\n                            completerId: \"secondCompleter\"\n                        }, {\n                            caption: \"cdef\",\n                            value: \"cdef\",\n                            completerId: \"secondCompleter\"\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                getDocTooltip: function (item) {\n                    if (!item.docText) {\n                        item.docText = secondDoc;\n                    }\n                },\n                id: \"secondCompleter\"\n            }\n        ];\n\n        sendKey(\"c\");\n        var popup = editor.completer.popup;\n\n        await lang.sleep(10);\n        assert.equal(popup.data.length, 4);\n        assert.equal(popup.container.lastChild.innerHTML, firstDoc);\n        sendKey(\"Down\");\n\n        await lang.sleep(10);\n        assert.equal(popup.container.lastChild.innerHTML, secondDoc);\n        sendKey(\"Down\");\n\n        await lang.sleep(10);\n        assert.equal(popup.container.lastChild.innerHTML, firstDoc);\n        sendKey(\"Down\");\n\n        await lang.sleep(10);\n        assert.equal(popup.container.lastChild.innerHTML, secondDoc);\n\n        done();\n    },\n    \"test: completers tooltip filtering\": async function (done) {\n        editor = initEditor(\"\");\n        var firstDoc = \"First tooltip\";\n        var secondDoc = \"Second tooltip\";\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"case\",\n                            value: \"case\"\n                        }, {\n                            caption: \"catch\",\n                            value: \"catch\"\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                getDocTooltip: function (item) {\n                    if (item.value === 'case') {\n                        item.docHTML = firstDoc;\n                    }\n                    if (item.value === 'catch') {\n                        item.docHTML = secondDoc;\n                    }\n                }\n            }\n        ];\n\n        sendKey(\"ca\");\n        var popup = editor.completer.popup;\n\n        await lang.sleep(10);\n        assert.equal(popup.data.length, 2);\n        assert.equal(popup.container.lastChild.innerHTML, firstDoc);\n        sendKey(\"t\");\n\n        await lang.sleep(10);\n        assert.equal(popup.data.length, 1);\n        assert.equal(popup.container.lastChild.innerHTML, secondDoc);\n        done();\n    },\n    \"test: slow and fast completers\": async function(done) {\n        var syncCompleter={\n            getCompletions: function(editor, session, pos, prefix, callback) {\n                callback(null,[{\n                    value: \"test\"\n                }]);\n            },\n            id: \"asyncCompleter\"\n        };\n\n        var asyncCompleter = {\n            getCompletions: async function(editor, session, pos, prefix, callback) {\n                await lang.sleep(10);\n                callback(null, [\n                    {\n                        value: \"some\"\n                    }\n                ]);\n            },\n            id: \"asyncCompleter\"\n        };\n        editor = initEditor(\"\");\n        editor.completers=[\n            syncCompleter,asyncCompleter\n        ];\n        editor.resize(true);\n        editor.execCommand(\"insertstring\", \"o\");\n        assert.notOk(!!editor.completer.popup);\n\n        await lang.sleep(10);\n        assert.ok(editor.completer.popup.isOpen);\n        assert.equal(editor.completer.popup.renderer.scrollTop, 0);\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(editor.completer.popup.renderer.scrollTop, 0);\n        assert.equal(editor.completer.popup.renderer.scroller.textContent, \"some \");\n        sendKey(\"Return\");\n        assert.equal(editor.getValue(), \"some\");\n        sendKey(\" \");\n        assert.equal(editor.completer.popup.isOpen, false);\n        sendKey(\"t\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        sendKey(\"Return\");\n        sendKey(\" \");\n        sendKey(\"q\");\n        assert.equal(editor.completer.popup.isOpen, false);\n\n        done();\n    },\n    \"test: trigger autocomplete for specific characters\": async function (done) {\n        editor = initEditor(\"document\");\n        var newLineCharacter = editor.session.doc.getNewLineCharacter();\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"append\",\n                            value: \"append\"\n                        }, {\n                            caption: \"all\",\n                            value: \"all\"\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                triggerCharacters: [\".\", newLineCharacter]\n            }\n        ];\n\n        editor.moveCursorTo(0, 8);\n        user.type(\".\");\n        var popup = editor.completer.popup;\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 2);\n        user.type(\"Return\");  // Accept suggestion\n        assert.equal(editor.getValue(), \"document.all\");\n\n        user.type(Array(4).fill(\"Backspace\"));  // Delete '.all'\n        user.type(\"Return\");  // Enter new line\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 2);\n        user.type(\"Return\");  // Accept suggestion\n        assert.equal(editor.getValue(), `document${newLineCharacter}all`);\n\n        done();\n    },\n    \"test: empty message if no suggestions available\": function() {\n        editor = initEditor(\"\");\n        var emptyMessageText = \"No suggestions.\";\n        var autocomplete = Autocomplete.for(editor);\n        autocomplete.emptyMessage = () => emptyMessageText;\n\n        user.type(\"thereisnoautosuggestionforthisword\");\n\n        // Open autocompletion via key-binding and verify empty message\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.data[0].caption, emptyMessageText);\n        assert.ok(editor.completer.popup.renderer.container.classList.contains(\"ace_empty-message\"));\n\n        user.type(\"Return\");\n        assert.equal(editor.completer.popup.isOpen, false);\n    },\n    \"test: no empty message class if suggestions available\": function() {\n        editor = initEditor(\"\");\n        var emptyMessageText = \"No suggestions.\";\n        var autocomplete = Autocomplete.for(editor);\n        autocomplete.emptyMessage = () => emptyMessageText;\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"append\",\n                            value: \"append\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        user.type(\"b\");\n\n        // Open autocompletion via key-binding and verify empty message class\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.data[0].caption, emptyMessageText);\n        assert.ok(editor.completer.popup.renderer.container.classList.contains(\"ace_empty-message\"));\n\n        user.type(\"Backspace\");\n        assert.equal(editor.completer.popup.isOpen, false);\n\n        // Open autocompletion via key-binding and verify no empty message class\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.data[0].caption, \"append\");\n        assert.ok(!editor.completer.popup.renderer.container.classList.contains(\"ace_empty-message\"));\n    },\n    \"test: liveAutocompleteDelay\": async function(done) {\n        editor = initEditor(\"hello world \");\n        editor.setOptions({\n            liveAutocompletionDelay: 10,\n            liveAutocompletionThreshold: 2\n        });\n\n        editor.completers = [{\n                getCompletions: function(editor, session, pos, prefix, callback) {\n                    callback(null,[{\n                        value: \"test\"\n                    }]);\n                }\n            },\n            {\n                getCompletions: function(editor, session, pos, prefix, callback) {\n                    this.timeout = setTimeout(() => {\n                        callback(null,[{\n                            value: \"slow test\"\n                        }]);\n                    }, 50);\n                },\n                cancel: function() {\n                    clearTimeout(this.timeout);\n                    this.timeout = null;\n                }\n            }\n        ];\n\n        user.type(\" \");\n        user.type(\"t\");\n        user.type(\"e\");\n\n        var popup = editor.completer.popup;\n\n        assert.ok(!popup || !popup.isOpen);\n\n        await lang.sleep(11);\n        assert.ok(editor.completer.popup.isOpen);\n        assert.ok(editor.completers[1].timeout);\n        user.type(\"Home\");\n\n        await lang.sleep(0);\n        assert.ok(editor.completer.popup.isOpen);\n        assert.ok(editor.completers[1].timeout);\n\n        user.type(\"Left\");\n        await lang.sleep(0);\n        assert.ok(!editor.completer.popup.isOpen);\n        assert.ok(!editor.completers[1].timeout);\n        done();\n    },\n    \"test: scroll and resize\": function() {\n        editor = initEditor(\"hello world\\n\");\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        var called = false;\n        editor.completer.$updatePopupPosition = function() {\n            called = true;\n        };\n        editor.container.parentNode.dispatchEvent(new CustomEvent(\"scroll\"));\n        assert.ok(called);\n\n        editor.destroy();\n        editor.container.remove();\n    },\n    \"test: selection should follow hovermarker if setSelectOnHover true\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"option 1\",\n                            value: \"one\"\n                        }, {\n                            caption: \"option 2\",\n                            value: \"two\"\n                        }, {\n                            caption: \"option 3\",\n                            value: \"three\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.setSelectOnHover = true;\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(completer.popup.getRow(), 0);\n\n        editor.completer.popup.renderer.$loop._flush();\n\n        var text = completer.popup.renderer.content.childNodes[2];\n        var rect = text.getBoundingClientRect();\n\n        // We need two mouse events to trigger the updating of the hover marker.\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left, y: rect.top}));\n        // Hover over the second row.\n        var lineHeight = completer.popup.renderer.lineHeight;\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + 1, y: rect.top + 1.5 * lineHeight}));\n\n        // Selected row should follow mouse.\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.getRow(), 1);\n    },\n    \"test: selection should not follow hovermarker if setSelectOnHover not set\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"option 1\",\n                            value: \"one\"\n                        }, {\n                            caption: \"option 2\",\n                            value: \"two\"\n                        }, {\n                            caption: \"option 3\",\n                            value: \"three\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(completer.popup.getRow(), 0);\n\n        var text = completer.popup.renderer.content.childNodes[2];\n        var rect = text.getBoundingClientRect();\n\n        // We need two mouse events to trigger the updating of the hover marker.\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left, y: rect.top}));\n        // Hover over the second row.\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + 1, y: rect.top + 20}));\n\n        // Selected row should not follow mouse.\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.getRow(), 0);\n    },\n    \"test: should respect hideInlinePreview\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"option 1\",\n                            value: \"one\",\n                            score: 3\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                hideInlinePreview: true\n            }, {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"option 2\",\n                            value: \"two\",\n                            score: 2\n                        }\n                    ];\n                    callback(null, completions);\n                },\n                hideInlinePreview: false\n            }, {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"option 3\",\n                            value: \"three\",\n                            score: 1\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"Ctrl-Space\");\n        var inline = completer.inlineRenderer;\n\n        assert.equal(editor.completer.popup.isOpen, true);\n\n        // Row 0, should hide inline preview.\n        assert.equal(completer.popup.getRow(), 0);\n        assert.strictEqual(inline.isOpen(), false);\n\n        sendKey(\"Down\");\n\n        // Row 1, should show inline preview.\n        assert.equal(completer.popup.getRow(), 1);\n        assert.strictEqual(inline.isOpen(), true);\n\n        sendKey(\"Down\");\n\n        // Row 2, should show inline preview.\n        assert.equal(completer.popup.getRow(), 2);\n        assert.strictEqual(inline.isOpen(), true);\n    },\n    \"test: should maintain selection on fast completer item when slow completer results come in\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [fastCompleter, slowCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.stickySelectionDelay = 100;\n        user.type(\"Ctrl-Space\");\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.data.length, 3);\n        assert.equal(completer.popup.getRow(), 0);\n\n        await lang.sleep(300);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 5);\n        assert.equal(completer.popup.getRow(), 1);\n\n        done();\n    },\n    \"test: should not maintain selection on fast completer item when slow completer results come in when stickySelectionDelay negative\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        var slowCompleter = {\n            getCompletions: async function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"slow option 1\",\n                        value: \"s1\",\n                        score: 3\n                    }, {\n                        caption: \"slow option 2\",\n                        value: \"s2\",\n                        score: 0\n                    }\n                ];\n                await lang.sleep(200);\n                callback(null, completions);\n            }\n        };\n\n        editor.completers = [fastCompleter, slowCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.stickySelectionDelay = -1;\n        user.type(\"Ctrl-Space\");\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.data.length, 3);\n        assert.equal(completer.popup.getRow(), 0);\n\n        await lang.sleep(300);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 5);\n        assert.equal(completer.popup.getRow(), 0);\n\n        done();\n    },\n    \"test: should filter using caption if ignoreCaption false\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        var completer = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"caption\",\n                        value: \"value\"\n                    }\n                ];\n                callback(null,  completions);\n            }\n        };\n\n        editor.completers = [completer];\n\n        var completer = Autocomplete.for(editor);\n\n        // Should filter using the caption if set to false.\n        completer.ignoreCaption = false;\n        user.type(\"cap\");\n        assert.equal(completer.popup.isOpen, true);\n    },\n    \"test: should filter using value if ignoreCaption true\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        var completer = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"caption\",\n                        value: \"value\"\n                    }\n                ];\n                callback(null,  completions);\n            }\n        };\n\n        editor.completers = [completer];\n\n        var completer = Autocomplete.for(editor);\n\n        // Should not filter using the caption if set to true.\n        completer.ignoreCaption = true;\n        user.type(\"cap\");\n        assert.equal(completer.popup, undefined);\n\n        // Should filter using the value instead.\n        user.type(\" value\");\n        assert.equal(completer.popup.isOpen, true);\n    },\n    \"test: should skip filter if skipFilter flag is set to true in completion\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        var completer = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        value: \"example value\",\n                        skipFilter: true\n                    }\n                ];\n                callback(null, completions);\n            }\n        };\n\n        editor.completers = [completer];\n\n        var completer = Autocomplete.for(editor);\n        // should not do filter out the completion item where skipFilter is true\n        user.type(\"notMatchingText\");\n        assert.equal(completer.popup.data.length, 1);\n        assert.equal(completer.popup.isOpen, true);\n    },\n    \"test: should use filter if skipFilter flag is set to false in completion\": function() {\n        editor = initEditor(\"hello world\\n\");\n\n        var completer = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        value: \"example value\",\n                        skipFilter: false\n                    }\n                ];\n                callback(null, completions);\n            }\n        };\n\n        editor.completers = [completer];\n\n        var completer = Autocomplete.for(editor);\n\n        // should do filter out the completion item where skipFilter is false\n        user.type(\"notMatchingText\");\n        assert.equal(completer.popup, undefined);\n\n        // normal filtering mechanism should work fine\n        user.type(\" ex\");\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.data.length, 1);\n    },\n\n    \"test: should add inline preview content to aria-describedby\": function() {\n        editor = initEditor(\"fun\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"function\",\n                            value: \"function\\nthat does something\\ncool\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"Ctrl-Space\");\n        var inline = completer.inlineRenderer;\n\n        // Popup should be open, with inline text renderered.\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.getRow(), 0);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"function\\nthat does something\\ncool\");\n\n        completer.popup.renderer.$loop._flush();\n\n        // aria-describedby of selected popup item should have aria-describedby set to the offscreen inline screen reader div and doc-tooltip.\n        assert.strictEqual(completer.popup.selectedNode.getAttribute(\"aria-describedby\"), \"doc-tooltip ace-inline-screenreader-line-0 ace-inline-screenreader-line-1 ace-inline-screenreader-line-2 \");\n\n        // The elements with these IDs should have the correct content.\n        assert.strictEqual(document.getElementById(\"ace-inline-screenreader-line-0\").textContent,\"function\");\n        assert.strictEqual(document.getElementById(\"ace-inline-screenreader-line-1\").textContent,\"that does something\");\n        assert.strictEqual(document.getElementById(\"ace-inline-screenreader-line-2\").textContent,\"cool\");\n    },\n    \"test: update popup position only on mouse out when inline enabled and setSelectOnHover true\": function() {\n        editor = initEditor(\"fun\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"functionshort\",\n                            value: \"function that does something uncool\",\n                            score: 1\n                        },\n                        {\n                            caption: \"functionlong\",\n                            value: \"function\\nthat does something\\ncool\",\n                            score: 0\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.setSelectOnHover = true;\n        completer.inlineEnabled = true;\n\n        user.type(\"Ctrl-Space\");\n        assert.equal(editor.completer.popup.isOpen, true);\n        var called = false;\n        editor.completer.$updatePopupPosition = function() {\n            called = true;\n        };\n\n        var inline = completer.inlineRenderer;\n\n        assert.equal(completer.popup.getRow(), 0);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"function that does something uncool\");\n\n        var text = completer.popup.renderer.content.childNodes[2];\n        var rect = text.getBoundingClientRect();\n\n        // We need two mouse events to trigger the updating of the hover marker.\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left, y: rect.top}));\n        // Hover over the second row.\n        text.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + 1, y: rect.top + 20}));\n\n        editor.completer.popup.renderer.$loop._flush();\n\n        // Check that the completion item changed to the longer item.\n        assert.equal(completer.popup.getRow(), 1);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"function\\nthat does something\\ncool\");\n\n        // Check that position update of popup is not called.\n        assert.ok(!called);\n\n        text.dispatchEvent(new MouseEvent(\"out\", {x: rect.left, y: rect.top}));\n        editor.completer.popup.renderer.$loop._flush();\n\n        // Check that position update of popup is called after the mouseout.\n        assert.ok(called);\n\n        editor.destroy();\n        editor.container.remove();\n    },\n    \"test: should display loading state\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [slowCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.stickySelectionDelay = 100;\n        completer.showLoadingState = true;\n        user.type(\"Ctrl-Space\");\n        assert.ok(!(completer.popup && completer.popup.isOpen));\n\n        await lang.sleep(100);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 1);\n        assert.ok(isLoading());\n\n        await lang.sleep(150);\n        assert.equal(completer.popup.data.length, 2);\n        assert.ok(!isLoading());\n        user.type(\"Escape\");\n        assert.ok(!(completer.popup && completer.popup.isOpen));\n\n\n        editor.completers = [fastCompleter, slowCompleter];\n        user.type(\"Ctrl-Space\");\n        assert.equal(completer.popup.data.length, 4);\n\n        // Should have top row saying 'Loading...' together with results.\n        assert.ok(isLoading());\n        assert.equal(completer.popup.data[0].caption, \"Loading...\");\n\n        await lang.sleep(250);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 5);\n        assert.ok(!isLoading());\n        done();\n\n        function isLoading() {\n            return completer.popup.renderer.container.classList.contains(\"ace_loading\");\n        }\n    },\n    \"test: should not display loading state on no suggestion state\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [slowCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.stickySelectionDelay = 100;\n        completer.emptyMessage = \"no completions\";\n        completer.showLoadingState = true;\n\n        user.type(\"doesntmatchanything\");\n        user.type(\"Ctrl-Space\");\n        assert.ok(!(completer.popup && completer.popup.isOpen));\n\n        await lang.sleep(100);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 1);\n        assert.ok(isLoading());\n\n        await lang.sleep(150);\n        // Should show no suggestions state without loading indicator\n        assert.equal(completer.popup.data.length, 1);\n        assert.equal(completer.popup.data[0].caption, \"no completions\");\n        assert.ok(!isLoading());\n\n        done();\n\n        function isLoading() {\n            return completer.popup.renderer.container.classList.contains(\"ace_loading\");\n        }\n    },\n    \"test: should display ghost text after loading state if inline preview enabled\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        editor.completers = [slowCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.stickySelectionDelay = 100;\n        completer.inlineEnabled = true;\n        completer.showLoadingState = true;\n\n        user.type(\"Ctrl-Space\");\n        assert.ok(!(completer.popup && completer.popup.isOpen));\n\n        await lang.sleep(100);\n        completer.popup.renderer.$loop._flush();\n        assert.equal(completer.popup.data.length, 1);\n        assert.ok(isLoading());\n\n        await lang.sleep(150);\n        assert.equal(completer.popup.data.length, 2);\n        assert.ok(!isLoading());\n\n        assert.strictEqual(editor.renderer.$ghostText.text, \"s1\");\n        done();\n\n        function isLoading() {\n            return completer.popup.renderer.container.classList.contains(\"ace_loading\");\n        }\n    },\n    \"test: when completion gets inserted and call the onInsert method\": function() {\n        var isInserted = false;\n        editor = initEditor(\"hello world\");\n        var completer = {\n            onInsert: function (_editor, el) {\n                assert.ok(!isInserted, \"should not have inserted something already\");\n                isInserted = el.value === \"one\";\n            },\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"option 1\",\n                        value: \"one\",\n                        completer\n                    }, {\n                        caption: \"option 2\",\n                        value: \"two\",\n                        completer\n                    }, {\n                        caption: \"option 3\",\n                        value: \"three\",\n                        completer\n                    }\n                ];\n                callback(null, completions);\n            }\n        };\n        editor.completers = [completer];\n        user.type(\"Ctrl-Space\");\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.getRow(), 0);\n        user.type(\"Return\");\n\n        assert.ok(isInserted);\n    },\n    \"test: when completions get shown, call the onSeen method\": function() {\n        var seen = [false, false, false];\n        editor = initEditor(\"hello world\");\n        var completer = {\n            onSeen: function (_editor, el) {\n                const index = [\"one\", \"two\", \"three\"].indexOf(el.value);\n                if (index >= 0) {\n                    assert.ok(!seen[index], \"should not be called double\");\n                    seen[index] = true;\n                }\n            },\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"option 1\",\n                        value: \"one\",\n                        completer\n                    }, {\n                        caption: \"option 2\",\n                        value: \"two\",\n                        completer\n                    }, {\n                        caption: \"option 3\",\n                        value: \"three\",\n                        completer\n                    }\n                ];\n                callback(null, completions);\n            }\n        };\n        editor.completers = [\n            completer\n        ];\n        Autocomplete.for(editor).inlineEnabled = true;\n        user.type(\"Ctrl-Space\");\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.getRow(), 0);\n        assert.deepEqual(seen, [true, false, false]);\n    },\n    \"test: when inline completions get shown, call the onSeen method\": function() {\n        var seen = [false, false, false];\n        var calledDouble = false;\n        editor = initEditor(\"hello world\");\n        var completer = {\n            onSeen: function (_editor, el) {\n                const index = [\"one\", \"two\", \"three\"].indexOf(el.value);\n                if (index >= 0) {\n                    if (seen[index]) calledDouble = true;\n                    seen[index] = true;\n                }\n            },\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"option 1\",\n                        value: \"one\",\n                        completer\n                    }, {\n                        caption: \"option 2\",\n                        value: \"two\",\n                        completer\n                    }, {\n                        caption: \"option 3\",\n                        value: \"three\",\n                        completer\n                    }\n                ];\n                callback(null, completions);\n            }\n        };\n        editor.completers = [\n            completer\n        ];\n        user.type(\"Ctrl-Space\");\n        editor.completer.popup.renderer.$loop._flush();\n        assert.equal(editor.completer.popup.isOpen, true);\n        assert.equal(editor.completer.popup.getRow(), 0);\n        assert.deepEqual(seen, [true, true, true]);\n        assert.ok(!calledDouble);\n    },\n    \"test: if there is very long ghost text, popup should be rendered at the bottom of the editor container\": async function(done) {\n        editor = initEditor(\"hello world\\n\");\n\n        // Give enough space for the popup to appear below the editor\n        var initialDocumentHeight = document.body.style.height;\n        document.body.style.height = editor.container.getBoundingClientRect().height + 200 + \"px\";\n        editor.renderer.$loop._flush();\n\n        var longCompleter = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"loooooong\",\n                        value: \"line\\n\".repeat(20),\n                        score: 0\n                    }\n                ];\n                callback(null,  completions);\n            }\n        };\n\n        editor.completers = [longCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"Ctrl-Space\");\n        assert.ok(completer.popup && completer.popup.isOpen);\n\n        // Wait to account for the renderer scrolling for the virtual renderer\n        await lang.sleep(100);\n        completer.popup.renderer.$loop._flush();\n\n        // Popup should start one pixel below the bottom of the editor container\n        assert.equal(\n            completer.popup.container.getBoundingClientRect().top,\n            editor.container.getBoundingClientRect().bottom + 1\n        );\n\n        // Reset back to initial values\n        document.body.style.height = initialDocumentHeight;\n        editor.renderer.$loop._flush();\n\n        done();\n    },\n    \"test: if there is ghost text, popup should be rendered at the bottom of the ghost text\": async function(done) {\n        editor = initEditor(\"\");\n\n        var longCompleter = {\n            getCompletions: function (editor, session, pos, prefix, callback) {\n                var completions = [\n                    {\n                        caption: \"loooooong\",\n                        value: \"line\\n\".repeat(5),\n                        score: 0\n                    }\n                ];\n                callback(null,  completions);\n            }\n        };\n\n        editor.completers = [longCompleter];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"Ctrl-Space\");\n        assert.ok(completer.popup && completer.popup.isOpen);\n\n        // Wait to account for the renderer scrolling for the virtual renderer\n        await lang.sleep(100);\n        completer.popup.renderer.$loop._flush();\n\n        // Popup should start one pixel below the bottom of the ghost text\n        assert.equal(\n            completer.popup.container.getBoundingClientRect().top,\n            editor.renderer.$ghostTextWidget.el.getBoundingClientRect().bottom + 1\n        );\n\n        done();\n    },\n    \"test: should not show loading state when empty completer array is provided\": function() {\n        editor = initEditor(\"\");\n        editor.completers = [];\n        var completer = Autocomplete.for(editor);\n        completer.showLoadingState = true;\n\n        user.type(\"Ctrl-Space\");\n\n        // Tooltip should not be open\n        assert.ok(!(completer.popup && completer.popup.isOpen));\n    },\n    \"test: should update inline preview when typing when it's the only item in the popup\": async function(done) {\n        editor = initEditor(\"\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            caption: \"function\",\n                            value: \"function\\nthat does something\\ncool\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"f\");\n        var inline = completer.inlineRenderer;\n\n        // Popup should be open, with inline text renderered.\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.getRow(), 0);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"unction\\nthat does something\\ncool\");\n\n        // when you keep typing, the ghost text should update accordingly\n        user.type(\"unc\");\n\n        await lang.sleep(100);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"tion\\nthat does something\\ncool\");\n\n        user.type(\"tio\");\n\n        await lang.sleep(100);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"n\\nthat does something\\ncool\");\n\n        done();\n    },\n    \"test: should keep showing ghost text when typing ahead with whitespace\": async function(done) {\n        editor = initEditor(\"\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            value: \"function that does something cool\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"f\");\n        var inline = completer.inlineRenderer;\n\n        // Popup should be open, with inline text renderered.\n        assert.equal(completer.popup.isOpen, true);\n        assert.equal(completer.popup.getRow(), 0);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"unction that does something cool\");\n\n        // when you keep typing, the ghost text should update accordingly\n        user.type(\"unction th\");\n\n        await lang.sleep(100);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"at does something cool\");\n\n        user.type(\"at do\");\n\n        await lang.sleep(100);\n        assert.strictEqual(inline.isOpen(), true);\n        assert.strictEqual(editor.renderer.$ghostText.text, \"es something cool\");\n\n        done();\n    },\n    \"test: passing matches from execCommand\": function() {\n        editor = initEditor(\"\");\n        editor.execCommand('startAutocomplete', {\n            matches: [\n                { value: 'example value' }\n            ]\n        });\n        user.type(\"\\n\");\n\n        assert.equal(editor.getValue(), \"example value\");\n\n        editor.resize(true);\n        editor.insertSnippet(\"<$1-${1|a1,b2,c3|}>\");\n        user.type(\"Down\");\n        user.type(\"\\n\");\n\n        assert.equal(editor.getValue(), \"example value<b2-b2>\");\n    },\n    \"test: should close popup if backspacing until input is fully deleted\": function() {\n        editor = initEditor(\"\");\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = [\n                        {\n                            value: \"tabularhappiness\"\n                        }\n                    ];\n                    callback(null, completions);\n                }\n            }\n        ];\n\n        var completer = Autocomplete.for(editor);\n        completer.inlineEnabled = true;\n\n        user.type(\"tab\");\n\n        // Popup should be open\n        assert.equal(completer.popup.isOpen, true);\n\n        user.type(\"Backspace\");\n        user.type(\"Backspace\");\n\n        // Popup should still be open\n        assert.equal(completer.popup.isOpen, true);\n\n        user.type(\"Backspace\");\n\n        // Popup should be closed now\n        assert.equal(completer.popup.isOpen, false);\n    },\n    \"test: should set create shared Autocomplete with sharedPopups on\": function() {\n        assert.equal(Autocomplete.$sharedInstance == undefined, true);\n        config.set(\"sharedPopups\", true);\n        var editor = initEditor(\"\");\n        var completer = Autocomplete.for(editor);\n        assert.equal(Autocomplete.$sharedInstance == undefined, false);\n        config.set(\"sharedPopups\", false);\n    },\n    \"test: changing completion should render scrollbars correctly\": async function(done) {\n        editor = initEditor(\"document\");\n        var newLineCharacter = editor.session.doc.getNewLineCharacter();\n        var initialCompletions = [\n            {\n                caption: \"small\",\n                meta: \"small\",\n                value: \"small\"\n            }\n        ];\n        var longCompletions = Array(10)\n            .fill(null)\n            .map((_, i) => ({\n                caption: `this is a really long string that I want to use for testing horizontal scroll ${i}`,\n                meta: `meta ${i}`,\n                value: `value ${i}`\n            }));\n\n        var currentCompletions = initialCompletions;\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    var completions = currentCompletions;\n                    callback(null, completions);\n                },\n                triggerCharacters: [newLineCharacter]\n            }\n        ];\n\n        editor.moveCursorTo(0, 8);\n        user.type(\"Return\"); // Accept suggestion\n        var popup = editor.completer.popup;\n\n        await popup.renderer.once(\"afterRender\");\n        assert.equal(popup.data.length, 1);\n        assert.notOk(popup.renderer.scrollBar.isVisible);\n        user.type(\"Return\"); // Accept suggestion\n        assert.equal(editor.getValue(), `document${newLineCharacter}small`);\n        // change completion values\n        currentCompletions = longCompletions;\n\n        user.type(\"Return\"); // Enter new line\n        assert.equal(popup.renderer.layerConfig.height, popup.renderer.lineHeight * 1);\n        assert.equal(popup.data.length, 10);\n\n        await popup.renderer.once(\"afterRender\");\n        assert.ok(popup.renderer.scrollBar.isVisible);\n        assert.equal(popup.renderer.layerConfig.height, popup.renderer.lineHeight * 8);\n        user.type(\"Return\"); // Accept suggestion\n        assert.equal(editor.getValue(), `document${newLineCharacter}small${newLineCharacter}value 0`);\n\n        done();\n    },\n    \"test: doc tooltip positioning\": async function(done) {\n        var editor = initEditor(\"\");\n        var longDoc = \"This is a very long documentation text that should wrap and test the tooltip width constraints.\";\n\n        editor.completers = [\n            {\n                getCompletions: function (editor, session, pos, prefix, callback) {\n                    callback(null, [\n                        {\n                            caption: \"completion1\",\n                            value: \"completion1\",\n                            docHTML: longDoc\n                        },\n                        {\n                            caption: \"completion2\",\n                            value: \"completion2\"\n                        },\n                        {\n                            caption: \"completion3\",\n                            value: \"completion3\"\n                        }\n                    ]);\n                }\n            }\n        ];\n\n\n        editor.resize();\n        await editor.renderer.once(\"afterRender\");\n        editor.completer.showPopup(editor);\n\n        var popup = editor.completer.popup;\n        var popupRect, tooltipRect;\n\n        async function waitForDocTooltip() {\n            editor.renderer.$loop._flush();\n            await lang.sleep(50);\n            editor.completer.onLayoutChange();\n            var tooltipNode = editor.completer.tooltipNode;\n            popupRect = popup.container.getBoundingClientRect();\n            tooltipRect = tooltipNode.getBoundingClientRect();\n        }\n\n        // Mock the CSS behaviour\n        popup.container.style.width = \"300px\";\n        popup.container.style.height = \"300px\";\n        var editorWidth = 400;\n        editor.container.style.width = editorWidth + \"px\";\n        editor.container.style.height = \"100px\";\n        editor.container.style.left = \"0px\";\n        editor.container.style.top = \"0px\";\n        popup.container.style.positionHint = \"fixed\";\n        \n        \n        user.type(\"c\");\n        await waitForDocTooltip();\n        assert.ok(tooltipRect.left > popupRect.right, \"Tooltip should appear on the right\");\n\n        editor.container.style.left = (window.innerWidth - editorWidth) + \"px\";\n        user.type(\"o\");\n\n        await waitForDocTooltip();\n\n        assert.ok(tooltipRect.right <= popupRect.left, \"Tooltip should appear on the left\");\n\n        editor.container.style.left = \"400px\";\n        editor.container.style.top = \"0px\";\n        popup.container.style.width = (window.innerWidth - 100) + \"px\"; \n        user.type(\"Escape\");\n        user.type(\"Enter\");\n        user.type(\"c\");\n        \n        await waitForDocTooltip();\n        assert.ok(tooltipRect.top >= popupRect.bottom, \"Tooltip should appear below\");\n\n        editor.container.style.top = (window.innerHeight - 100) + \"px\";\n        editor.container.style.left = \"0px\";\n        user.type(\"Escape\");\n        user.type(\"Enter\");\n        user.type(\"c\");\n\n        await waitForDocTooltip();\n        assert.ok(tooltipRect.bottom <= popupRect.top, \"Tooltip should appear above\");\n\n        done();\n    },\n};\n\nrequire(\"./test/run\")(module);\n"
  },
  {
    "path": "src/background_tokenizer.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./document\").Document} Document\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"./tokenizer\").Tokenizer} Tokenizer\n */\nvar oop = require(\"./lib/oop\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n\n/**\n * Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use. \n * \n * If a certain row is changed, everything below that row is re-tokenized.\n **/\nclass BackgroundTokenizer {\n    \n    /**\n     * Creates a new `BackgroundTokenizer` object.\n     * @param {Tokenizer} tokenizer The tokenizer to use\n     * @param {EditSession} [session] The editor session to associate with\n     **/\n    constructor(tokenizer, session) {\n        /**@type {false | ReturnType<typeof setTimeout>}*/\n        this.running = false;\n        this.lines = [];\n        /**@type {string[]|string[][]}*/\n        this.states = [];\n        this.currentLine = 0;\n        this.tokenizer = tokenizer;\n\n        var self = this;\n\n        this.$worker = function() {\n            if (!self.running) { return; }\n\n            var workerStart = new Date();\n            var currentLine = self.currentLine;\n            var endLine = -1;\n            var doc = self.doc;\n\n            var startLine = currentLine;\n            while (self.lines[currentLine])\n                currentLine++;\n\n            var len = doc.getLength();\n            var processedLines = 0;\n            self.running = false;\n            while (currentLine < len) {\n                self.$tokenizeRow(currentLine);\n                endLine = currentLine;\n                do {\n                    currentLine++;\n                } while (self.lines[currentLine]);\n\n                // only check every 5 lines\n                processedLines ++;\n                // @ts-ignore\n                if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) {\n                    self.running = setTimeout(self.$worker, 20);\n                    break;\n                }\n            }\n            self.currentLine = currentLine;\n\n            if (endLine == -1)\n                endLine = currentLine;\n\n            if (startLine <= endLine)\n                self.fireUpdateEvent(startLine, endLine);\n        };\n    }\n    \n    /**\n     * Sets a new tokenizer for this object.\n     * @param {Tokenizer} tokenizer The new tokenizer to use\n     **/\n    setTokenizer(tokenizer) {\n        this.tokenizer = tokenizer;\n        this.lines = [];\n        this.states = [];\n\n        this.start(0);\n    }\n\n    /**\n     * Sets a new document to associate with this object.\n     * @param {Document} doc The new document to associate with\n     **/\n    setDocument(doc) {\n        this.doc = doc;\n        this.lines = [];\n        this.states = [];\n\n        this.stop();\n    }\n\n\n    /**\n     * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated.\n     * @param {Number} firstRow The starting row region\n     * @param {Number} lastRow The final row region\n     **/\n    fireUpdateEvent(firstRow, lastRow) {\n        var data = {\n            first: firstRow,\n            last: lastRow\n        };\n        this._signal(\"update\", {data: data});\n    }\n\n    /**\n     * Starts tokenizing at the row indicated.\n     * @param {Number} startRow The row to start at\n     **/\n    start(startRow) {\n        this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());\n\n        // remove all cached items below this line\n        this.lines.splice(this.currentLine, this.lines.length);\n        this.states.splice(this.currentLine, this.states.length);\n\n        this.stop();\n        // pretty long delay to prevent the tokenizer from interfering with the user\n        this.running = setTimeout(this.$worker, 700);\n    }\n\n    /**\n     * Sets pretty long delay to prevent the tokenizer from interfering with the user\n     */\n    scheduleStart() {\n        if (!this.running)\n            this.running = setTimeout(this.$worker, 700);\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     */\n    $updateOnChange(delta) {\n        var startRow = delta.start.row;\n        var len = delta.end.row - startRow;\n\n        if (len === 0) {\n            this.lines[startRow] = null;\n        } else if (delta.action == \"remove\") {\n            this.lines.splice(startRow, len + 1, null);\n            this.states.splice(startRow, len + 1, null);\n        } else {\n            var args = Array(len + 1);\n            args.unshift(startRow, 1);\n            this.lines.splice.apply(this.lines, args);\n            this.states.splice.apply(this.states, args);\n        }\n\n        this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());\n\n        this.stop();\n    }\n\n    /**\n     * Stops tokenizing.\n     **/\n    stop() {\n        if (this.running)\n            clearTimeout(this.running);\n        this.running = false;\n    }\n\n    /**\n     * Gives list of [[Token]]'s of the row. (tokens are cached)\n     * @param {Number} row The row to get tokens at\n     * @returns {import(\"../ace-internal\").Ace.Token[]}\n     **/\n    getTokens(row) {\n        return this.lines[row] || this.$tokenizeRow(row);\n    }\n\n    /**\n     * Returns the state of tokenization at the end of a row.\n     * @param {Number} row The row to get state at\n     * @returns {string | string[]}\n     **/\n    getState(row) {\n        if (this.currentLine == row)\n            this.$tokenizeRow(row);\n        return this.states[row] || \"start\";\n    }\n\n    /**\n     * @param {number} row\n     */\n    $tokenizeRow(row) {\n        var line = this.doc.getLine(row);\n        var state = this.states[row - 1];\n        // @ts-expect-error TODO: potential wrong argument\n        var data = this.tokenizer.getLineTokens(line, state, row);\n\n        if (this.states[row] + \"\" !== data.state + \"\") {\n            this.states[row] = data.state;\n            this.lines[row + 1] = null;\n            if (this.currentLine > row + 1)\n                this.currentLine = row + 1;\n        } else if (this.currentLine == row) {\n            this.currentLine = row + 1;\n        }\n\n        return this.lines[row] = data.tokens;\n    }\n\n    cleanup() {\n        this.running = false;\n        this.lines = [];\n        this.states = [];\n        this.currentLine = 0;\n        this.removeAllListeners();\n    }\n\n}\n\noop.implement(BackgroundTokenizer.prototype, EventEmitter);\n\nexports.BackgroundTokenizer = BackgroundTokenizer;\n"
  },
  {
    "path": "src/background_tokenizer_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar LuaMode = require(\"./mode/lua\").Mode;\nvar Range = require(\"./range\").Range;\nvar assert = require(\"./test/assertions\");\n\nfunction forceTokenize(session, startLine) {\n    for (var i = startLine || 0, l = session.getLength(); i < l; i++)\n        session.getTokens(i);\n}\n\nfunction testStates(session, states) {\n    for (var i = 0, l = session.getLength(); i < l; i++)\n        assert.equal(session.bgTokenizer.states[i], states[i]);\n    assert.ok(l == states.length);\n}\n\nmodule.exports = {\n\n    \"test background tokenizer update on session change\" : function() {\n        var doc = new EditSession([\n            \"/*\",\n            \"*/\",\n            \"var juhu\"\n        ]);\n        doc.setMode(\"./mode/javascript\");  \n        \n        forceTokenize(doc);\n        testStates(doc, [\"comment1\", \"start\", \"no_regex\"]);\n        \n        doc.remove(new Range(0,2,1,2));\n        testStates(doc, [null, \"no_regex\"]);\n        \n        forceTokenize(doc);\n        testStates(doc, [\"comment1\", \"comment1\"]);\n        \n        doc.insert({row:0, column:2}, \"\\n*/\");\n        testStates(doc, [undefined, undefined, \"comment1\"]);\n        \n        forceTokenize(doc);\n        testStates(doc, [\"comment1\", \"start\", \"no_regex\"]);\n    },\n    \"test background tokenizer sends update event\" : function() {\n        var doc = new EditSession([\n            \"/*\",\n            \"var\",\n            \"juhu\",\n            \"*/\"\n        ]);\n        doc.setMode(\"./mode/javascript\");\n        \n        var updateEvent = null;\n        doc.bgTokenizer.on(\"update\", function(e) {\n            updateEvent = e.data;\n        });\n        function checkEvent(first, last) {\n            assert.ok(!updateEvent, \"unneccessary update event\");\n            doc.bgTokenizer.running = 1;\n            doc.bgTokenizer.$worker();\n            assert.ok(updateEvent);\n            assert.equal([first, last] + \"\", \n                [updateEvent.first, updateEvent.last] + \"\");\n            updateEvent = null;\n        }\n        \n        forceTokenize(doc);\n        var comment = \"comment1\";\n        testStates(doc, [comment, comment, comment, \"start\"]);\n        \n        doc.remove(new Range(0,0,0,2));\n        testStates(doc, [comment, comment, comment, \"start\"]);\n        \n        checkEvent(0, 3);\n        testStates(doc, [\"start\", \"no_regex\", \"no_regex\", \"regex\"]);\n        \n        // insert /* and and press down several times quickly\n        doc.insert({row:0, column:0}, \"/*\");\n        doc.getTokens(0);\n        doc.getTokens(1);\n        doc.getTokens(2);\n        checkEvent(0, 3);\n        \n        forceTokenize(doc);\n        testStates(doc, [comment, comment, comment, \"start\"]);\n    },\n    \"test background tokenizer sends update event 2\" : function(next) {\n        var doc = new EditSession([\n            \"-[[\",\n            \"juhu\",\n            \"kinners]]--\",\n            \"\"\n        ]);\n        doc.setMode(\"./mode/lua\");\n        forceTokenize(doc);\n        var string = \"bracketedString,2,start\";\n        var comment = \"bracketedComment,2,start\";\n        testStates(doc, [string, string, \"start\", \"start\"]);\n        \n        doc.insert({row:0, column:0}, \"-\");\n        forceTokenize(doc);\n        doc.bgTokenizer.once(\"update\", function(e) {\n            assert.equal([0, 4] + \"\", [e.data.first, e.data.last] + \"\");\n            testStates(doc, [comment, comment, \"start\", \"start\"]);\n            next();\n        });\n        doc.bgTokenizer.running = 1;\n        doc.bgTokenizer.$worker();\n    }\n};\n\n\nrequire(\"./test/run\")(module);\n"
  },
  {
    "path": "src/bidihandler.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n */\n\nvar bidiUtil = require(\"./lib/bidiutil\");\nvar lang = require(\"./lib/lang\");\nvar bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac\\u202B]/;\n\n/**\n * This object is used to ensure Bi-Directional support (for languages with text flowing from right to left, like Arabic or Hebrew)\n * including correct caret positioning, text selection mouse and keyboard arrows functioning\n **/\nclass BidiHandler {\n    /**\n     * Creates a new `BidiHandler` object\n     * @param {EditSession} session The session to use\n     **/\n    constructor(session) {\n        this.session = session;\n        this.bidiMap = {};\n        /* current screen row */\n        this.currentRow = null;\n        this.bidiUtil = bidiUtil;\n        /* Arabic/Hebrew character width differs from regular character width */\n        this.charWidths = [];\n        this.EOL = \"\\xAC\";\n        this.showInvisibles = true;\n        this.isRtlDir = false;\n        this.$isRtl = false;\n        this.line = \"\";\n        this.wrapIndent = 0;\n        this.EOF = \"\\xB6\";\n        this.RLE = \"\\u202B\";\n        this.contentWidth = 0;\n        this.fontMetrics = null;\n        this.rtlLineOffset = 0;\n        this.wrapOffset = 0;\n        this.isMoveLeftOperation = false;\n        this.seenBidi = bidiRE.test(session.getValue());\n    }\n\n    /**\n     * Returns 'true' if row contains Bidi characters, in such case\n     * creates Bidi map to be used in operations related to selection\n     * (keyboard arrays, mouse click, select)\n     * @param {Number} screenRow the screen row to be checked\n     * @param {Number} [docRow] the document row to be checked [optional]\n     * @param {Number} [splitIndex] the wrapped screen line index [ optional]\n    **/\n    isBidiRow(screenRow, docRow, splitIndex) {\n        if (!this.seenBidi)\n            return false;\n        if (screenRow !== this.currentRow) {\n            this.currentRow = screenRow;\n            this.updateRowLine(docRow, splitIndex);\n            this.updateBidiMap();\n        }\n        return this.bidiMap.bidiLevels;\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     * @internal\n     */\n    onChange(delta) {\n        if (!this.seenBidi) {\n            if (delta.action == \"insert\" && bidiRE.test(delta.lines.join(\"\\n\"))) {\n                this.seenBidi = true;\n                this.currentRow = null;\n            }\n        }\n        else {\n            this.currentRow = null;\n        }\n    }\n\n    getDocumentRow() {\n        var docRow = 0;\n        var rowCache = this.session.$screenRowCache;\n        if (rowCache.length) {\n            var index = this.session.$getRowCacheIndex(rowCache, this.currentRow);\n            if (index >= 0)\n                docRow = this.session.$docRowCache[index];\n        }\n\n        return docRow;\n    }\n\n    getSplitIndex() {\n        var splitIndex = 0;\n        var rowCache = this.session.$screenRowCache;\n        if (rowCache.length) {\n            var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow);\n            while (this.currentRow - splitIndex > 0) {\n                currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1);\n                if (currentIndex !== prevIndex)\n                    break;\n\n                prevIndex = currentIndex;\n                splitIndex++;\n            }\n        } else {\n            splitIndex = this.currentRow;\n        }\n\n        return splitIndex;\n    }\n\n    updateRowLine(docRow, splitIndex) {\n        if (docRow === undefined)\n            docRow = this.getDocumentRow();\n\n        var isLastRow = (docRow === this.session.getLength() - 1),\n            endOfLine = isLastRow ? this.EOF : this.EOL;\n\n        this.wrapIndent = 0;\n        this.line = this.session.getLine(docRow);\n        this.isRtlDir = this.$isRtl || this.line.charAt(0) === this.RLE;\n        if (this.session.$useWrapMode) {\n            var splits = this.session.$wrapData[docRow];\n            if (splits) {\n                if (splitIndex === undefined)\n                    splitIndex = this.getSplitIndex();\n\n                if(splitIndex > 0 && splits.length) {\n                    this.wrapIndent = splits.indent;\n                    this.wrapOffset = this.wrapIndent * this.charWidths[bidiUtil.L];\n                    this.line = (splitIndex < splits.length) ?\n                        this.line.substring(splits[splitIndex - 1], splits[splitIndex]) :\n                            this.line.substring(splits[splits.length - 1]);\n                } else {\n                    this.line = this.line.substring(0, splits[splitIndex]);\n                }\n\n                if (splitIndex == splits.length) {\n                    this.line += (this.showInvisibles) ? endOfLine : bidiUtil.DOT;\n                }\n            }\n        } else {\n            this.line += this.showInvisibles ? endOfLine : bidiUtil.DOT;\n        }\n\n        /* replace tab and wide characters by commensurate spaces */\n        var session = this.session, shift = 0, size;\n        this.line = this.line.replace(/\\t|[\\u1100-\\u2029, \\u202F-\\uFFE6]/g, function(ch, i){\n            if (ch === '\\t' || session.isFullWidth(ch.charCodeAt(0))) {\n                size = (ch === '\\t') ? session.getScreenTabSize(i + shift) : 2;\n                shift += size - 1;\n                return lang.stringRepeat(bidiUtil.DOT, size);\n            }\n            return ch;\n        });\n\n        if (this.isRtlDir) {\n            this.fontMetrics.$main.textContent = (this.line.charAt(this.line.length - 1) == bidiUtil.DOT) ? this.line.substr(0, this.line.length - 1) : this.line;\n            this.rtlLineOffset = this.contentWidth - this.fontMetrics.$main.getBoundingClientRect().width;\n        }\n    }\n\n    updateBidiMap() {\n        var textCharTypes = [];\n        if (bidiUtil.hasBidiCharacters(this.line, textCharTypes) || this.isRtlDir) {\n             this.bidiMap = bidiUtil.doBidiReorder(this.line, textCharTypes, this.isRtlDir);\n        } else {\n            this.bidiMap = {};\n        }\n    }\n\n    /**\n     * Resets stored info related to current screen row\n    **/\n    markAsDirty() {\n        this.currentRow = null;\n    }\n\n    /**\n     * Updates array of character widths\n     * @param {Object} fontMetrics metrics\n     *\n    **/\n    updateCharacterWidths(fontMetrics) {\n        if (this.characterWidth === fontMetrics.$characterSize.width)\n            return;\n\n        this.fontMetrics = fontMetrics;\n        var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;\n        var bidiCharWidth = fontMetrics.$measureCharWidth(\"\\u05d4\");\n\n        this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth;\n        this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth;\n        this.charWidths[bidiUtil.R_H] = bidiCharWidth * 0.45;\n        this.charWidths[bidiUtil.B] = this.charWidths[bidiUtil.RLE] = 0;\n\n        this.currentRow = null;\n    }\n\n    setShowInvisibles(showInvisibles) {\n        this.showInvisibles = showInvisibles;\n        this.currentRow = null;\n    }\n\n    setEolChar(eolChar) {\n        this.EOL = eolChar;\n    }\n\n    setContentWidth(width) {\n        this.contentWidth = width;\n    }\n\n    isRtlLine(row) {\n        if (this.$isRtl) return true;\n        if (row != undefined)\n            return (this.session.getLine(row).charAt(0) == this.RLE);\n        else\n            return this.isRtlDir;\n    }\n\n    setRtlDirection(editor, isRtlDir) {\n        var cursor = editor.getCursorPosition();\n        for (var row = editor.selection.getSelectionAnchor().row; row <= cursor.row; row++) {\n            if (!isRtlDir && editor.session.getLine(row).charAt(0) === editor.session.$bidiHandler.RLE)\n                editor.session.doc.removeInLine(row, 0, 1);\n            else if (isRtlDir && editor.session.getLine(row).charAt(0) !== editor.session.$bidiHandler.RLE)\n                editor.session.doc.insert({column: 0, row: row}, editor.session.$bidiHandler.RLE);\n        }\n    }\n\n\n    /**\n     * Returns offset of character at position defined by column.\n     * @param {Number} col the screen column position\n     *\n     * @return {Number} horizontal pixel offset of given screen column\n     **/\n    getPosLeft(col) {\n        col -= this.wrapIndent;\n        var leftBoundary = (this.line.charAt(0) === this.RLE) ? 1 : 0;\n        var logicalIdx = (col > leftBoundary) ? (this.session.getOverwrite() ? col : col - 1) : leftBoundary;\n        var visualIdx = bidiUtil.getVisualFromLogicalIdx(logicalIdx, this.bidiMap),\n            levels = this.bidiMap.bidiLevels, left = 0;\n\n        if (!this.session.getOverwrite() && col <= leftBoundary && levels[visualIdx] % 2 !== 0)\n            visualIdx++;\n\n        for (var i = 0; i < visualIdx; i++) {\n            left += this.charWidths[levels[i]];\n        }\n\n        if (!this.session.getOverwrite() && (col > leftBoundary) && (levels[visualIdx] % 2 === 0))\n            left += this.charWidths[levels[visualIdx]];\n\n        if (this.wrapIndent)\n            left += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n\n        if (this.isRtlDir)\n            left += this.rtlLineOffset;\n\n        return left;\n    }\n\n    /**\n     * Returns 'selections' - array of objects defining set of selection rectangles\n     * @param {Number} startCol the start column position\n     * @param {Number} endCol the end column position\n     *\n     * @return {Object[]} Each object contains 'left' and 'width' values defining selection rectangle.\n    **/\n    getSelections(startCol, endCol) {\n        var map = this.bidiMap, levels = map.bidiLevels, level, selections = [], offset = 0,\n            selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent,\n                isSelected = false, isSelectedPrev = false, selectionStart = 0;\n\n        if (this.wrapIndent)\n            offset += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n\n        for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) {\n            logIdx = map.logicalFromVisual[visIdx];\n            level = levels[visIdx];\n            isSelected = (logIdx >= selColMin) && (logIdx < selColMax);\n            if (isSelected && !isSelectedPrev) {\n                selectionStart = offset;\n            } else if (!isSelected && isSelectedPrev) {\n                selections.push({left: selectionStart, width: offset - selectionStart});\n            }\n            offset += this.charWidths[level];\n            isSelectedPrev = isSelected;\n        }\n\n        if (isSelected && (visIdx === levels.length)) {\n            selections.push({left: selectionStart, width: offset - selectionStart});\n        }\n\n        if(this.isRtlDir) {\n            for (var i = 0; i < selections.length; i++) {\n                selections[i].left += this.rtlLineOffset;\n            }\n        }\n        return selections;\n    }\n\n    /**\n     * Converts character coordinates on the screen to respective document column number\n     * @param {Number} posX character horizontal offset\n     *\n     * @return {Number} screen column number corresponding to given pixel offset\n    **/\n    offsetToCol(posX) {\n        if(this.isRtlDir)\n            posX -= this.rtlLineOffset;\n\n        var logicalIdx = 0, posX = Math.max(posX, 0),\n            offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels,\n                charWidth = this.charWidths[levels[visualIdx]];\n\n        if (this.wrapIndent)\n           posX -= this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n\n        while(posX > offset + charWidth/2) {\n            offset += charWidth;\n            if(visualIdx === levels.length - 1) {\n                /* quit when we on the right of the last character, flag this by charWidth = 0 */\n                charWidth = 0;\n                break;\n            }\n            charWidth = this.charWidths[levels[++visualIdx]];\n        }\n\n        if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){\n        /* Bidi character on the left and None Bidi character on the right */\n            if(posX < offset)\n                visualIdx--;\n            logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n\n        } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){\n        /* None Bidi character on the left and Bidi character on the right */\n            logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx]\n                    : this.bidiMap.logicalFromVisual[visualIdx - 1]);\n\n        } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0))\n                || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){\n        /* To the right of last character, which is None Bidi, in RTL direction or */\n        /* to the left of first Bidi character, in LTR direction */\n            logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx];\n        } else {\n            /* Tweak visual position when Bidi character on the left in order to map it to corresponding logical position */\n            if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0)\n                visualIdx--;\n\n            /* Regular case */\n            logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n        }\n\n        if (logicalIdx === 0 && this.isRtlDir)\n            logicalIdx++;\n\n        return (logicalIdx + this.wrapIndent);\n    }\n\n}\n\nexports.BidiHandler = BidiHandler;\n"
  },
  {
    "path": "src/clipboard.js",
    "content": "\"use strict\";\n\nvar $cancelT;\nmodule.exports = { \n    /** @type {string|false} */\n    lineMode: false,\n    pasteCancelled: function() {\n        if ($cancelT && $cancelT > Date.now() - 50)\n            return true;\n        return $cancelT = false;\n    },\n    cancel: function() {\n        $cancelT = Date.now();\n    }\n};\n"
  },
  {
    "path": "src/commands/command_manager.js",
    "content": "\"use strict\";\n/**\n *\n * @typedef {import(\"../editor\").Editor} Editor\n */\nvar oop = require(\"../lib/oop\");\nvar MultiHashHandler = require(\"../keyboard/hash_handler\").MultiHashHandler;\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nclass CommandManager extends MultiHashHandler{\n    /**\n     * new CommandManager(platform, commands)\n     * @param {import(\"../keyboard/hash_handler\").Platform} platform Identifier for the platform; must be either `\"mac\"` or `\"win\"`\n     * @param {any[]} commands A list of commands\n     **/\n    constructor(platform, commands) {\n        super(commands, platform);\n        this.byName = this.commands;\n        this.setDefaultHandler(\"exec\", function(e) {\n            if (!e.args) {\n                return e.command.exec(e.editor, {}, e.event, true);\n            }\n            return e.command.exec(e.editor, e.args, e.event, false);\n        });\n    }\n\n    /**\n     * \n     * @param {string | string[] | import(\"../../ace-internal\").Ace.Command} command\n     * @param {Editor} editor\n     * @param {any} args\n     * @returns {boolean}\n     */\n    exec(command, editor, args) {\n        if (Array.isArray(command)) {\n            for (var i = command.length; i--; ) {\n                if (this.exec(command[i], editor, args)) return true;\n            }\n            return false;\n        }\n        \n        if (typeof command === \"string\")\n            command = this.commands[command];\n\n        var e = {editor: editor, command: command, args: args};\n        \n        if (!this.canExecute(command, editor)) {\n            this._signal(\"commandUnavailable\", e);\n            return false; \n        }\n        \n        e.returnValue = this._emit(\"exec\", e);\n        this._signal(\"afterExec\", e);\n\n        return e.returnValue === false ? false : true;\n    }\n\n    /**\n     *\n     * @param {string | import(\"../../ace-internal\").Ace.Command} command\n     * @param {Editor} editor\n     * @returns {boolean}\n     */\n    canExecute(command, editor) {\n        if (typeof command === \"string\")\n            command = this.commands[command];\n        \n        if (!command)\n            return false;\n\n        if (editor && editor.$readOnly && !command.readOnly)\n            return false;\n\n        if (this.$checkCommandState != false && command.isAvailable && !command.isAvailable(editor))\n            return false;\n        \n        return true;\n    }\n    \n\n    /**\n     * @param {Editor} editor\n     * @returns {boolean}\n     */\n    toggleRecording(editor) {\n        if (this.$inReplay)\n            return;\n\n        editor && editor._emit(\"changeStatus\");\n        if (this.recording) {\n            this.macro.pop();\n            this.off(\"exec\", this.$addCommandToMacro);\n\n            if (!this.macro.length)\n                this.macro = this.oldMacro;\n\n            return this.recording = false;\n        }\n        if (!this.$addCommandToMacro) {\n            this.$addCommandToMacro = function(e) {\n                this.macro.push([e.command, e.args]);\n            }.bind(this);\n        }\n\n        this.oldMacro = this.macro;\n        this.macro = [];\n        this.on(\"exec\", this.$addCommandToMacro);\n        return this.recording = true;\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    replay(editor) {\n        if (this.$inReplay || !this.macro)\n            return;\n\n        if (this.recording)\n            return this.toggleRecording(editor);\n\n        try {\n            this.$inReplay = true;\n            this.macro.forEach(function(x) {\n                if (typeof x == \"string\")\n                    this.exec(x, editor);\n                else\n                    this.exec(x[0], editor, x[1]);\n            }, this);\n        } finally {\n            this.$inReplay = false;\n        }\n    }\n\n    trimMacro(m) {\n        return m.map(function(x){\n            if (typeof x[0] != \"string\")\n                x[0] = x[0].name;\n            if (!x[1])\n                x = x[0];\n            return x;\n        });\n    }\n\n}\noop.implement(CommandManager.prototype, EventEmitter);\n\nexports.CommandManager = CommandManager;\n"
  },
  {
    "path": "src/commands/command_manager_test.js",
    "content": "\"use strict\";\n\nvar CommandManager = require(\"./command_manager\").CommandManager;\nvar keys = require(\"../lib/keys\");\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n\n    setUp: function() {\n        this.command = {\n            name: \"gotoline\",\n            bindKey: {\n                mac: \"Command-L\",\n                win: \"Ctrl-L\"\n            },\n            called: false,\n            available: true,\n            exec: function(editor) { this.called = true; },\n            isAvailable: function(editor) { return this.available; }\n        };\n\n        this.cm = new CommandManager(\"mac\", [this.command]);\n    },\n\n    \"test: register command\": function() {\n        this.cm.exec(\"gotoline\");\n        assert.ok(this.command.called);\n    },\n\n    \"test: mac hotkeys\": function() {\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.command, \"l\");\n        assert.equal(command, this.command);\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, \"l\");\n        assert.equal(command, undefined);\n    },\n\n    \"test: win hotkeys\": function() {\n        var cm = new CommandManager(\"win\", [this.command]);\n\n        var command = cm.findKeyCommand(keys.KEY_MODS.command, \"l\");\n        assert.equal(command, undefined);\n\n        var command = cm.findKeyCommand(keys.KEY_MODS.ctrl, \"l\");\n        assert.equal(command, this.command);\n    },\n\n    \"test: command isAvailable\": function() {\n        this.command.available = false;\n\n        this.cm.exec(\"gotoline\");\n        assert.ok(!this.command.called);\n        this.cm.$checkCommandState = false;\n        this.cm.exec(\"gotoline\");\n        assert.ok(this.command.called);\n    },\n\n    \"test: remove command by object\": function() {\n        this.cm.removeCommand(this.command);\n\n        this.cm.exec(\"gotoline\");\n        assert.ok(!this.command.called);\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.command, \"l\");\n        assert.equal(command, null);\n    },\n\n    \"test: remove command by name\": function() {\n        this.cm.removeCommand(\"gotoline\");\n\n        this.cm.exec(\"gotoline\");\n        assert.ok(!this.command.called);\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.command, \"l\");\n        assert.equal(command, null);\n    },\n\n    \"test: adding a new command with the same name as an existing one should remove the old one first\": function() {\n        var command = {\n            name: \"gotoline\",\n            bindKey: {\n                mac: \"Command-L\",\n                win: \"Ctrl-L\"\n            },\n            called: false,\n            exec: function(editor) { this.called = true; }\n        };\n        this.cm.addCommand(command);\n\n        this.cm.exec(\"gotoline\");\n        assert.ok(command.called);\n        assert.ok(!this.command.called);\n\n        assert.equal(this.cm.findKeyCommand(keys.KEY_MODS.command, \"l\"), command);\n    },\n\n    \"test: adding commands and recording a macro\": function() {\n        var called = \"\";\n        this.cm.addCommands({\n            togglerecording: function(editor) {\n                editor.cm.toggleRecording(editor);\n            },\n            replay: function(editor) {\n                editor.cm.replay();\n            },\n            cm1: function(editor, arg) {\n                called += \"1\" + (arg || \"\");\n            },\n            cm2: function(editor) {\n                called += \"2\";\n            }\n        });\n\n\n        var statusUpdateEmitted = false;\n        this._emit = function() {statusUpdateEmitted = true;};\n\n        this.cm.exec(\"togglerecording\", this);\n        assert.ok(this.cm.recording);\n        assert.ok(statusUpdateEmitted);\n\n        this.cm.exec(\"cm1\", this, \"-\");\n        this.cm.exec(\"cm2\");\n        this.cm.exec(\"replay\", this);\n        assert.ok(!this.cm.recording);\n        assert.equal(called, \"1-2\");\n\n        called = \"\";\n        this.cm.exec(\"replay\", this);\n        assert.equal(called, \"1-2\");\n    },\n\n    \"test: bindkeys\": function() {\n        this.cm.bindKeys({\n            \"Ctrl-L|Command-C\": \"cm1\",\n            \"Ctrl-R\": \"cm2\"\n        });\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.command, \"c\");\n        assert.equal(command, \"cm1\");\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, \"r\");\n        assert.equal(command, \"cm2\");\n\n        this.cm.bindKeys({\n            \"Ctrl-R\": null\n        });\n\n        var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, \"r\");\n        assert.equal(command, null);\n    },\n\n    \"test: binding keys without modifiers\": function() {\n        this.cm.bindKeys({\n            \"R\": \"cm1\",\n            \"Shift-r\": \"cm2\",\n            \"Return\": \"cm4\",\n            \"Enter\": \"cm3\"\n        });\n\n        var command = this.cm.findKeyCommand(-1, \"r\");\n        assert.equal(command, \"cm1\");\n\n        var command = this.cm.findKeyCommand(-1, \"R\");\n        assert.equal(command, \"cm2\");\n\n        var command = this.cm.findKeyCommand(0, \"return\");\n        assert.equal(command + \"\", [\"cm4\", \"cm3\"] + \"\");\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/commands/default_commands.js",
    "content": "\"use strict\";\n\nvar lang = require(\"../lib/lang\");\nvar config = require(\"../config\");\nvar Range = require(\"../range\").Range;\n\nfunction bindKey(win, mac) {\n    return {win: win, mac: mac};\n}\n\n/*\n    multiSelectAction: \"forEach\"|\"forEachLine\"|function|undefined,\n    scrollIntoView: true|\"cursor\"|\"center\"|\"selectionPart\"\n*/\n/**@type {import(\"../../ace-internal\").Ace.Command[]} */\nexports.commands = [{\n    name: \"showSettingsMenu\",\n    description: \"Show settings menu\",\n    bindKey: bindKey(\"Ctrl-,\", \"Command-,\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/settings_menu\", function(module) {\n            module.init(editor);\n            editor.showSettingsMenu();\n        });\n    },\n    readOnly: true\n}, {\n    name: \"goToNextError\",\n    description: \"Go to next error\",\n    bindKey: bindKey(\"Alt-E\", \"F4\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/error_marker\", function(module) {\n            module.showErrorMarker(editor, 1);\n        });\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"goToPreviousError\",\n    description: \"Go to previous error\",\n    bindKey: bindKey(\"Alt-Shift-E\", \"Shift-F4\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/error_marker\", function(module) {\n            module.showErrorMarker(editor, -1);\n        });\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"selectall\",\n    description: \"Select all\",\n    bindKey: bindKey(\"Ctrl-A\", \"Command-A\"),\n    exec: function(editor) { editor.selectAll(); },\n    readOnly: true\n}, {\n    name: \"centerselection\",\n    description: \"Center selection\",\n    bindKey: bindKey(null, \"Ctrl-L\"),\n    exec: function(editor) { editor.centerSelection(); },\n    readOnly: true\n}, {\n    name: \"gotoline\",\n    description: \"Go to line...\",\n    bindKey: bindKey(\"Ctrl-L\", \"Command-L\"),\n    exec: function(editor, line) {\n        // backwards compatibility\n        if (typeof line === \"number\" && !isNaN(line))\n            editor.gotoLine(line);\n        editor.prompt({ $type: \"gotoLine\" });\n    },\n    readOnly: true\n}, {\n    name: \"fold\",\n    bindKey: bindKey(\"Alt-L|Ctrl-F1\", \"Command-Alt-L|Command-F1\"),\n    exec: function(editor) { editor.session.toggleFold(false); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"unfold\",\n    bindKey: bindKey(\"Alt-Shift-L|Ctrl-Shift-F1\", \"Command-Alt-Shift-L|Command-Shift-F1\"),\n    exec: function(editor) { editor.session.toggleFold(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"toggleFoldWidget\",\n    description: \"Toggle fold widget\",\n    bindKey: bindKey(\"F2\", \"F2\"),\n    exec: function(editor) { editor.session.toggleFoldWidget(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"toggleParentFoldWidget\",\n    description: \"Toggle parent fold widget\",\n    bindKey: bindKey(\"Alt-F2\", \"Alt-F2\"),\n    exec: function(editor) { editor.session.toggleFoldWidget(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"foldall\",\n    description: \"Fold all\",\n    bindKey: bindKey(null, \"Ctrl-Command-Option-0\"),\n    exec: function(editor) { editor.session.foldAll(); },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"foldAllComments\",\n    description: \"Fold all comments\",\n    bindKey: bindKey(null, \"Ctrl-Command-Option-0\"),\n    exec: function(editor) { editor.session.foldAllComments(); },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"foldOther\",\n    description: \"Fold other\",\n    bindKey: bindKey(\"Alt-0\", \"Command-Option-0\"),\n    exec: function(editor) { \n        editor.session.foldAll();\n        editor.session.unfold(editor.selection.getAllRanges());\n    },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"unfoldall\",\n    description: \"Unfold all\",\n    bindKey: bindKey(\"Alt-Shift-0\", \"Command-Option-Shift-0\"),\n    exec: function(editor) { editor.session.unfold(); },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"findnext\",\n    description: \"Find next\",\n    bindKey: bindKey(\"Ctrl-K\", \"Command-G\"),\n    exec: function(editor) { editor.findNext(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"findprevious\",\n    description: \"Find previous\",\n    bindKey: bindKey(\"Ctrl-Shift-K\", \"Command-Shift-G\"),\n    exec: function(editor) { editor.findPrevious(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"selectOrFindNext\",\n    description: \"Select or find next\",\n    bindKey: bindKey(\"Alt-K\", \"Ctrl-G\"),\n    exec: function(editor) {\n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        else\n            editor.findNext(); \n    },\n    readOnly: true\n}, {\n    name: \"selectOrFindPrevious\",\n    description: \"Select or find previous\",\n    bindKey: bindKey(\"Alt-Shift-K\", \"Ctrl-Shift-G\"),\n    exec: function(editor) { \n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        else\n            editor.findPrevious();\n    },\n    readOnly: true\n}, {\n    name: \"find\",\n    description: \"Find\",\n    bindKey: bindKey(\"Ctrl-F\", \"Command-F\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {e.Search(editor);});\n    },\n    readOnly: true\n}, {\n    name: \"overwrite\",\n    description: \"Overwrite\",\n    bindKey: \"Insert\",\n    exec: function(editor) { editor.toggleOverwrite(); },\n    readOnly: true\n}, {\n    name: \"selecttostart\",\n    description: \"Select to start\",\n    bindKey: bindKey(\"Ctrl-Shift-Home\", \"Command-Shift-Home|Command-Shift-Up\"),\n    exec: function(editor) { editor.getSelection().selectFileStart(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"gotostart\",\n    description: \"Go to start\",\n    bindKey: bindKey(\"Ctrl-Home\", \"Command-Home|Command-Up\"),\n    exec: function(editor) { editor.navigateFileStart(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"selectup\",\n    description: \"Select up\",\n    bindKey: bindKey(\"Shift-Up\", \"Shift-Up|Ctrl-Shift-P\"),\n    exec: function(editor) { editor.getSelection().selectUp(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"golineup\",\n    description: \"Go line up\",\n    bindKey: bindKey(\"Up\", \"Up|Ctrl-P\"),\n    exec: function(editor, args) { editor.navigateUp(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttoend\",\n    description: \"Select to end\",\n    bindKey: bindKey(\"Ctrl-Shift-End\", \"Command-Shift-End|Command-Shift-Down\"),\n    exec: function(editor) { editor.getSelection().selectFileEnd(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"gotoend\",\n    description: \"Go to end\",\n    bindKey: bindKey(\"Ctrl-End\", \"Command-End|Command-Down\"),\n    exec: function(editor) { editor.navigateFileEnd(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"selectdown\",\n    description: \"Select down\",\n    bindKey: bindKey(\"Shift-Down\", \"Shift-Down|Ctrl-Shift-N\"),\n    exec: function(editor) { editor.getSelection().selectDown(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"golinedown\",\n    description: \"Go line down\",\n    bindKey: bindKey(\"Down\", \"Down|Ctrl-N\"),\n    exec: function(editor, args) { editor.navigateDown(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectwordleft\",\n    description: \"Select word left\",\n    bindKey: bindKey(\"Ctrl-Shift-Left\", \"Option-Shift-Left\"),\n    exec: function(editor) { editor.getSelection().selectWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotowordleft\",\n    description: \"Go to word left\",\n    bindKey: bindKey(\"Ctrl-Left\", \"Option-Left\"),\n    exec: function(editor) { editor.navigateWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttolinestart\",\n    description: \"Select to line start\",\n    bindKey: bindKey(\"Alt-Shift-Left\", \"Command-Shift-Left|Ctrl-Shift-A\"),\n    exec: function(editor) { editor.getSelection().selectLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotolinestart\",\n    description: \"Go to line start\",\n    bindKey: bindKey(\"Alt-Left|Home\", \"Command-Left|Home|Ctrl-A\"),\n    exec: function(editor) { editor.navigateLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectleft\",\n    description: \"Select left\",\n    bindKey: bindKey(\"Shift-Left\", \"Shift-Left|Ctrl-Shift-B\"),\n    exec: function(editor) { editor.getSelection().selectLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotoleft\",\n    description: \"Go to left\",\n    bindKey: bindKey(\"Left\", \"Left|Ctrl-B\"),\n    exec: function(editor, args) { editor.navigateLeft(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectwordright\",\n    description: \"Select word right\",\n    bindKey: bindKey(\"Ctrl-Shift-Right\", \"Option-Shift-Right\"),\n    exec: function(editor) { editor.getSelection().selectWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotowordright\",\n    description: \"Go to word right\",\n    bindKey: bindKey(\"Ctrl-Right\", \"Option-Right\"),\n    exec: function(editor) { editor.navigateWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttolineend\",\n    description: \"Select to line end\",\n    bindKey: bindKey(\"Alt-Shift-Right\", \"Command-Shift-Right|Shift-End|Ctrl-Shift-E\"),\n    exec: function(editor) { editor.getSelection().selectLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotolineend\",\n    description: \"Go to line end\",\n    bindKey: bindKey(\"Alt-Right|End\", \"Command-Right|End|Ctrl-E\"),\n    exec: function(editor) { editor.navigateLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectright\",\n    description: \"Select right\",\n    bindKey: bindKey(\"Shift-Right\", \"Shift-Right\"),\n    exec: function(editor) { editor.getSelection().selectRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotoright\",\n    description: \"Go to right\",\n    bindKey: bindKey(\"Right\", \"Right|Ctrl-F\"),\n    exec: function(editor, args) { editor.navigateRight(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectpagedown\",\n    description: \"Select page down\",\n    bindKey: \"Shift-PageDown\",\n    exec: function(editor) { editor.selectPageDown(); },\n    readOnly: true\n}, {\n    name: \"pagedown\",\n    description: \"Page down\",\n    bindKey: bindKey(null, \"Option-PageDown\"),\n    exec: function(editor) { editor.scrollPageDown(); },\n    readOnly: true\n}, {\n    name: \"gotopagedown\",\n    description: \"Go to page down\",\n    bindKey: bindKey(\"PageDown\", \"PageDown|Ctrl-V\"),\n    exec: function(editor) { editor.gotoPageDown(); },\n    readOnly: true\n}, {\n    name: \"selectpageup\",\n    description: \"Select page up\",\n    bindKey: \"Shift-PageUp\",\n    exec: function(editor) { editor.selectPageUp(); },\n    readOnly: true\n}, {\n    name: \"pageup\",\n    description: \"Page up\",\n    bindKey: bindKey(null, \"Option-PageUp\"),\n    exec: function(editor) { editor.scrollPageUp(); },\n    readOnly: true\n}, {\n    name: \"gotopageup\",\n    description: \"Go to page up\",\n    bindKey: \"PageUp\",\n    exec: function(editor) { editor.gotoPageUp(); },\n    readOnly: true\n}, {\n    name: \"scrollup\",\n    description: \"Scroll up\",\n    bindKey: bindKey(\"Ctrl-Up\", null),\n    exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },\n    readOnly: true\n}, {\n    name: \"scrolldown\",\n    description: \"Scroll down\",\n    bindKey: bindKey(\"Ctrl-Down\", null),\n    exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },\n    readOnly: true\n}, {\n    name: \"selectlinestart\",\n    description: \"Select line start\",\n    bindKey: \"Shift-Home\",\n    exec: function(editor) { editor.getSelection().selectLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectlineend\",\n    description: \"Select line end\",\n    bindKey: \"Shift-End\",\n    exec: function(editor) { editor.getSelection().selectLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"togglerecording\",\n    description: \"Toggle recording\",\n    bindKey: bindKey(\"Ctrl-Alt-E\", \"Command-Option-E\"),\n    exec: function(editor) { editor.commands.toggleRecording(editor); },\n    readOnly: true\n}, {\n    name: \"replaymacro\",\n    description: \"Replay macro\",\n    bindKey: bindKey(\"Ctrl-Shift-E\", \"Command-Shift-E\"),\n    exec: function(editor) { editor.commands.replay(editor); },\n    readOnly: true\n}, {\n    name: \"jumptomatching\",\n    description: \"Jump to matching\",\n    bindKey: bindKey(\"Ctrl-\\\\|Ctrl-P\", \"Command-\\\\\"),\n    exec: function(editor) { editor.jumpToMatching(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"selecttomatching\",\n    description: \"Select to matching\",\n    bindKey: bindKey(\"Ctrl-Shift-\\\\|Ctrl-Shift-P\", \"Command-Shift-\\\\\"),\n    exec: function(editor) { editor.jumpToMatching(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"expandToMatching\",\n    description: \"Expand to matching\",\n    bindKey: bindKey(\"Ctrl-Shift-M\", \"Ctrl-Shift-M\"),\n    exec: function(editor) { editor.jumpToMatching(true, true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"passKeysToBrowser\",\n    description: \"Pass keys to browser\",\n    bindKey: bindKey(null, null),\n    exec: function() {},\n    passEvent: true,\n    readOnly: true\n}, {\n    name: \"copy\",\n    description: \"Copy\",\n    exec: function(editor) {\n        // placeholder for replay macro\n    },\n    readOnly: true\n},\n\n// commands disabled in readOnly mode\n{\n    name: \"cut\",\n    description: \"Cut\",\n    exec: function(editor) {\n        var cutLine = editor.$copyWithEmptySelection && editor.selection.isEmpty();\n        var range = cutLine ? editor.selection.getLineRange() : editor.selection.getRange();\n        editor._emit(\"cut\", range);\n\n        if (!range.isEmpty())\n            editor.session.remove(range);\n        editor.clearSelection();\n    },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"paste\",\n    description: \"Paste\",\n    exec: function(editor, args) {\n        editor.$handlePaste(args);\n    },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removeline\",\n    description: \"Remove line\",\n    bindKey: bindKey(\"Ctrl-D\", \"Command-D\"),\n    exec: function(editor) { editor.removeLines(); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEachLine\"\n}, {\n    name: \"duplicateSelection\",\n    description: \"Duplicate selection\",\n    bindKey: bindKey(\"Ctrl-Shift-D\", \"Command-Shift-D\"),\n    exec: function(editor) { editor.duplicateSelection(); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"sortlines\",\n    description: \"Sort lines\",\n    bindKey: bindKey(\"Ctrl-Alt-S\", \"Command-Alt-S\"),\n    exec: function(editor) { editor.sortLines(); },\n    scrollIntoView: \"selection\",\n    multiSelectAction: \"forEachLine\"\n}, {\n    name: \"togglecomment\",\n    description: \"Toggle comment\",\n    bindKey: bindKey(\"Ctrl-/\", \"Command-/\"),\n    exec: function(editor) { editor.toggleCommentLines(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"toggleBlockComment\",\n    description: \"Toggle block comment\",\n    bindKey: bindKey(\"Ctrl-Shift-/\", \"Command-Shift-/\"),\n    exec: function(editor) { editor.toggleBlockComment(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"modifyNumberUp\",\n    description: \"Modify number up\",\n    bindKey: bindKey(\"Ctrl-Shift-Up\", \"Alt-Shift-Up\"),\n    exec: function(editor) { editor.modifyNumber(1); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"modifyNumberDown\",\n    description: \"Modify number down\",\n    bindKey: bindKey(\"Ctrl-Shift-Down\", \"Alt-Shift-Down\"),\n    exec: function(editor) { editor.modifyNumber(-1); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"replace\",\n    description: \"Replace\",\n    bindKey: bindKey(\"Ctrl-H\", \"Command-Option-F\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {e.Search(editor, true);});\n    }\n}, {\n    name: \"undo\",\n    description: \"Undo\",\n    bindKey: bindKey(\"Ctrl-Z\", \"Command-Z\"),\n    exec: function(editor) { editor.undo(); }\n}, {\n    name: \"redo\",\n    description: \"Redo\",\n    bindKey: bindKey(\"Ctrl-Shift-Z|Ctrl-Y\", \"Command-Shift-Z|Command-Y\"),\n    exec: function(editor) { editor.redo(); }\n}, {\n    name: \"copylinesup\",\n    description: \"Copy lines up\",\n    bindKey: bindKey(\"Alt-Shift-Up\", \"Command-Option-Up\"),\n    exec: function(editor) { editor.copyLinesUp(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"movelinesup\",\n    description: \"Move lines up\",\n    bindKey: bindKey(\"Alt-Up\", \"Option-Up\"),\n    exec: function(editor) { editor.moveLinesUp(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"copylinesdown\",\n    description: \"Copy lines down\",\n    bindKey: bindKey(\"Alt-Shift-Down\", \"Command-Option-Down\"),\n    exec: function(editor) { editor.copyLinesDown(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"movelinesdown\",\n    description: \"Move lines down\",\n    bindKey: bindKey(\"Alt-Down\", \"Option-Down\"),\n    exec: function(editor) { editor.moveLinesDown(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"del\",\n    description: \"Delete\",\n    bindKey: bindKey(\"Delete\", \"Delete|Ctrl-D|Shift-Delete\"),\n    exec: function(editor) { editor.remove(\"right\"); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"backspace\",\n    description: \"Backspace\",\n    bindKey: bindKey(\n        \"Shift-Backspace|Backspace\",\n        \"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"\n    ),\n    exec: function(editor) { editor.remove(\"left\"); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"cut_or_delete\",\n    description: \"Cut or delete\",\n    bindKey: bindKey(\"Shift-Delete\", null),\n    exec: function(editor) { \n        if (editor.selection.isEmpty()) {\n            editor.remove(\"left\");\n        } else {\n            return false;\n        }\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolinestart\",\n    description: \"Remove to line start\",\n    bindKey: bindKey(\"Alt-Backspace\", \"Command-Backspace\"),\n    exec: function(editor) { editor.removeToLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolineend\",\n    description: \"Remove to line end\",\n    bindKey: bindKey(\"Alt-Delete\", \"Ctrl-K|Command-Delete\"),\n    exec: function(editor) { editor.removeToLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolinestarthard\",\n    description: \"Remove to line start hard\",\n    bindKey: bindKey(\"Ctrl-Shift-Backspace\", null),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n        range.start.column = 0;\n        editor.session.remove(range);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolineendhard\",\n    description: \"Remove to line end hard\",\n    bindKey: bindKey(\"Ctrl-Shift-Delete\", null),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n        range.end.column = Number.MAX_VALUE;\n        editor.session.remove(range);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removewordleft\",\n    description: \"Remove word left\",\n    bindKey: bindKey(\"Ctrl-Backspace\", \"Alt-Backspace|Ctrl-Alt-Backspace\"),\n    exec: function(editor) { editor.removeWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removewordright\",\n    description: \"Remove word right\",\n    bindKey: bindKey(\"Ctrl-Delete\", \"Alt-Delete\"),\n    exec: function(editor) { editor.removeWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"outdent\",\n    description: \"Outdent\",\n    bindKey: bindKey(\"Shift-Tab\", \"Shift-Tab\"),\n    exec: function(editor) { editor.blockOutdent(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"indent\",\n    description: \"Indent\",\n    bindKey: bindKey(\"Tab\", \"Tab\"),\n    exec: function(editor) { editor.indent(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"blockoutdent\",\n    description: \"Block outdent\",\n    bindKey: bindKey(\"Ctrl-[\", \"Ctrl-[\"),\n    exec: function(editor) { editor.blockOutdent(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"blockindent\",\n    description: \"Block indent\",\n    bindKey: bindKey(\"Ctrl-]\", \"Ctrl-]\"),\n    exec: function(editor) { editor.blockIndent(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"insertstring\",\n    description: \"Insert string\",\n    exec: function(editor, str) { editor.insert(str); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"inserttext\",\n    description: \"Insert text\",\n    exec: function(editor, args) {\n        editor.insert(lang.stringRepeat(args.text  || \"\", args.times || 1));\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"splitline\",\n    description: \"Split line\",\n    bindKey: bindKey(null, \"Ctrl-O\"),\n    exec: function(editor) { editor.splitLine(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"transposeletters\",\n    description: \"Transpose letters\",\n    bindKey: bindKey(\"Alt-Shift-X\", \"Ctrl-T\"),\n    exec: function(editor) { editor.transposeLetters(); },\n    multiSelectAction: function(editor) {editor.transposeSelections(1); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"touppercase\",\n    description: \"To uppercase\",\n    bindKey: bindKey(\"Ctrl-U\", \"Ctrl-U\"),\n    exec: function(editor) { editor.toUpperCase(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"tolowercase\",\n    description: \"To lowercase\",\n    bindKey: bindKey(\"Ctrl-Shift-U\", \"Ctrl-Shift-U\"),\n    exec: function(editor) { editor.toLowerCase(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"autoindent\",\n    description: \"Auto Indent\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) { editor.autoIndent(); },\n    scrollIntoView: \"animate\"\n}, {\n    name: \"expandtoline\",\n    description: \"Expand to line\",\n    bindKey: bindKey(\"Ctrl-Shift-L\", \"Command-Shift-L\"),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n\n        range.start.column = range.end.column = 0;\n        range.end.row++;\n        editor.selection.setRange(range, false);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"openlink\",\n    bindKey: bindKey(\"Ctrl+F3\", \"F3\"),\n    exec: function(editor) { editor.openLink(); }\n}, {\n    name: \"joinlines\",\n    description: \"Join lines\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        var isBackwards = editor.selection.isBackwards();\n        var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();\n        var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();\n        var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;\n        var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());\n        var selectedCount = selectedText.replace(/\\n\\s*/, \" \").length;\n        var insertLine = editor.session.doc.getLine(selectionStart.row);\n\n        for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {\n            var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));\n            if (curLine.length !== 0) {\n                curLine = \" \" + curLine;\n            }\n            insertLine += curLine;\n        }\n\n        if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {\n            // Don't insert a newline at the end of the document\n            insertLine += editor.session.doc.getNewLineCharacter();\n        }\n\n        editor.clearSelection();\n        editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);\n\n        if (selectedCount > 0) {\n            // Select the text that was previously selected\n            editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);\n            editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);\n        } else {\n            // If the joined line had something in it, start the cursor at that something\n            firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;\n            editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);\n        }\n    },\n    multiSelectAction: \"forEach\",\n    readOnly: true\n}, {\n    name: \"invertSelection\",\n    description: \"Invert selection\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        var endRow = editor.session.doc.getLength() - 1;\n        var endCol = editor.session.doc.getLine(endRow).length;\n        var ranges = editor.selection.rangeList.ranges;\n        var newRanges = [];\n\n        // If multiple selections don't exist, rangeList will return 0 so replace with single range\n        if (ranges.length < 1) {\n            ranges = [editor.selection.getRange()];\n        }\n\n        for (var i = 0; i < ranges.length; i++) {\n            if (i == (ranges.length - 1)) {\n                // The last selection must connect to the end of the document, unless it already does\n                if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {\n                    newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));\n                }\n            }\n\n            if (i === 0) {\n                // The first selection must connect to the start of the document, unless it already does\n                if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {\n                    newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));\n                }\n            } else {\n                newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));\n            }\n        }\n\n        editor.exitMultiSelectMode();\n        editor.clearSelection();\n\n        for(var i = 0; i < newRanges.length; i++) {\n            editor.selection.addRange(newRanges[i], false);\n        }\n    },\n    readOnly: true,\n    scrollIntoView: \"none\"\n}, {\n    name: \"addLineAfter\",\n    description: \"Add new line after the current line\",\n    exec: function(editor) {\n        editor.selection.clearSelection();\n        editor.navigateLineEnd();\n        editor.insert(\"\\n\");\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"addLineBefore\",\n    description: \"Add new line before the current line\",\n    exec: function(editor) {\n        editor.selection.clearSelection();\n        var cursor = editor.getCursorPosition();\n        editor.selection.moveTo(cursor.row - 1, Number.MAX_VALUE);\n        editor.insert(\"\\n\");\n        if (cursor.row === 0) editor.navigateUp();\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"openCommandPallete\",\n    exec: function(editor) {\n        console.warn(\"This is an obsolete command. Please use `openCommandPalette` instead.\");\n        editor.prompt({ $type: \"commands\" });\n    },\n    readOnly: true\n}, {\n    name: \"openCommandPalette\",\n    description: \"Open command palette\",\n    bindKey: bindKey(\"F1\", \"F1\"),\n    exec: function(editor) {\n        editor.prompt({ $type: \"commands\" });\n    },\n    readOnly: true\n}, {\n    name: \"modeSelect\",\n    description: \"Change language mode...\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        editor.prompt({ $type: \"modes\" });\n    },\n    readOnly: true\n}];\n\nfor (var i = 1; i < 9; i++) {\n    exports.commands.push({\n        name: \"foldToLevel\" + i,\n        description: \"Fold To Level \" + i,\n        level: i,\n        exec: function(editor) { editor.session.foldToLevel(this.level); },\n        scrollIntoView: \"center\",\n        readOnly: true\n    });\n}\n"
  },
  {
    "path": "src/commands/incremental_search_commands.js",
    "content": "var config = require(\"../config\");\nvar oop = require(\"../lib/oop\");\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar occurStartCommand = require(\"./occur_commands\").occurStartCommand;\n\n// These commands can be installed in a normal key handler to start iSearch:\nexports.iSearchStartCommands = [{\n    name: \"iSearch\",\n    bindKey: {win: \"Ctrl-F\", mac: \"Command-F\"},\n    exec: function(editor, options) {\n        config.loadModule([\"core\", \"ace/incremental_search\"], function(e) {\n            var iSearch = e.iSearch = e.iSearch || new e.IncrementalSearch();\n            iSearch.activate(editor, options.backwards);\n            if (options.jumpToFirstMatch) iSearch.next(options);\n        });\n    },\n    readOnly: true\n}, {\n    name: \"iSearchBackwards\",\n    exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {backwards: true}); },\n    readOnly: true\n}, {\n    name: \"iSearchAndGo\",\n    bindKey: {win: \"Ctrl-K\", mac: \"Command-G\"},\n    exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {jumpToFirstMatch: true, useCurrentOrPrevSearch: true}); },\n    readOnly: true\n}, {\n    name: \"iSearchBackwardsAndGo\",\n    bindKey: {win: \"Ctrl-Shift-K\", mac: \"Command-Shift-G\"},\n    exec: function(editor) { editor.execCommand('iSearch', {jumpToFirstMatch: true, backwards: true, useCurrentOrPrevSearch: true}); },\n    readOnly: true\n}];\n\n// These commands are only available when incremental search mode is active:\nexports.iSearchCommands = [{\n    name: \"restartSearch\",\n    bindKey: {win: \"Ctrl-F\", mac: \"Command-F\"},\n    exec: function(iSearch) {\n        iSearch.cancelSearch(true);\n    }\n}, {\n    name: \"searchForward\",\n    bindKey: {win: \"Ctrl-S|Ctrl-K\", mac: \"Ctrl-S|Command-G\"},\n    exec: function(iSearch, options) {\n        options.useCurrentOrPrevSearch = true;\n        iSearch.next(options);\n    }\n}, {\n    name: \"searchBackward\",\n    bindKey: {win: \"Ctrl-R|Ctrl-Shift-K\", mac: \"Ctrl-R|Command-Shift-G\"},\n    exec: function(iSearch, options) {\n        options.useCurrentOrPrevSearch = true;\n        options.backwards = true;\n        iSearch.next(options);\n    }\n}, {\n    name: \"extendSearchTerm\",\n    exec: function(iSearch, string) {\n        iSearch.addString(string);\n    }\n}, {\n    name: \"extendSearchTermSpace\",\n    bindKey: \"space\",\n    exec: function(iSearch) { iSearch.addString(' '); }\n}, {\n    name: \"shrinkSearchTerm\",\n    bindKey: \"backspace\",\n    exec: function(iSearch) {\n        iSearch.removeChar();\n    }\n}, {\n    name: 'confirmSearch',\n    bindKey: 'return',\n    exec: function(iSearch) { iSearch.deactivate(); }\n}, {\n    name: 'cancelSearch',\n    bindKey: 'esc|Ctrl-G',\n    exec: function(iSearch) { iSearch.deactivate(true); }\n}, {\n    name: 'occurisearch',\n    bindKey: 'Ctrl-O',\n    exec: function(iSearch) {\n        var options = oop.mixin({}, iSearch.$options);\n        iSearch.deactivate();\n        occurStartCommand.exec(iSearch.$editor, options);\n    }\n}, {\n    name: \"yankNextWord\",\n    bindKey: \"Ctrl-w\",\n    exec: function(iSearch) {\n        var ed = iSearch.$editor,\n            range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorWordRight(); }),\n            string = ed.session.getTextRange(range);\n        iSearch.addString(string);\n    }\n}, {\n    name: \"yankNextChar\",\n    bindKey: \"Ctrl-Alt-y\",\n    exec: function(iSearch) {\n        var ed = iSearch.$editor,\n            range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorRight(); }),\n            string = ed.session.getTextRange(range);\n        iSearch.addString(string);\n    }\n}, {\n    name: 'recenterTopBottom',\n    bindKey: 'Ctrl-l',\n    exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); }\n}, {\n    name: 'selectAllMatches',\n    bindKey: 'Ctrl-space',\n    exec: function(iSearch) {\n        var ed = iSearch.$editor,\n            hl = ed.session.$isearchHighlight,\n            ranges = hl && hl.cache ? hl.cache\n                .reduce(function(ranges, ea) {\n                    return ranges.concat(ea ? ea : []); }, []) : [];\n        iSearch.deactivate(false);\n        ranges.forEach(ed.selection.addRange.bind(ed.selection));\n    }\n}, {\n    name: 'searchAsRegExp',\n    bindKey: 'Alt-r',\n    exec: function(iSearch) {\n        iSearch.convertNeedleToRegExp();\n    }\n}].map(function(cmd) {\n    cmd.readOnly = true;\n    cmd.isIncrementalSearchCommand = true;\n    cmd.scrollIntoView = \"animate-cursor\";\n    return cmd;\n});\n\nfunction IncrementalSearchKeyboardHandler(iSearch) {\n    this.$iSearch = iSearch;\n}\n\noop.inherits(IncrementalSearchKeyboardHandler, HashHandler);\n\n(function() {\n    /**\n     * @param editor\n     * @this {IncrementalSearchKeyboardHandler & this & {$commandExecHandler}}\n     */\n    this.attach = function(editor) {\n        var iSearch = this.$iSearch;\n        HashHandler.call(this, exports.iSearchCommands, editor.commands.platform);\n        this.$commandExecHandler = editor.commands.on('exec', function(e) {\n            if (!e.command.isIncrementalSearchCommand)\n                return iSearch.deactivate();\n            e.stopPropagation();\n            e.preventDefault();\n            var scrollTop = editor.session.getScrollTop();\n            var result = e.command.exec(iSearch, e.args || {});\n            editor.renderer.scrollCursorIntoView(null, 0.5);\n            editor.renderer.animateScrolling(scrollTop);\n            return result;\n        });\n    };\n\n    /**\n     * @this {IncrementalSearchKeyboardHandler & this & {$commandExecHandler}}\n     * @param editor\n     */\n    this.detach = function(editor) {\n        if (!this.$commandExecHandler) return;\n        editor.commands.off('exec', this.$commandExecHandler);\n        delete this.$commandExecHandler;\n    };\n\n    var handleKeyboard$super = this.handleKeyboard;\n    /**\n     * @param data\n     * @param hashId\n     * @param key\n     * @param keyCode\n     * @this {IncrementalSearchKeyboardHandler & import(\"../keyboard/hash_handler\").HashHandler}\n     */\n    this.handleKeyboard = function(data, hashId, key, keyCode) {\n        if (((hashId === 1/*ctrl*/ || hashId === 8/*command*/) && key === 'v')\n         || (hashId === 1/*ctrl*/ && key === 'y')) return null;\n        // @ts-ignore\n        var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);\n        if (cmd && cmd.command) { return cmd; }\n        if (hashId == -1) {\n            var extendCmd = this.commands.extendSearchTerm;\n            if (extendCmd) { return {command: extendCmd, args: key}; }\n        }\n        return false;\n    };\n\n}).call(IncrementalSearchKeyboardHandler.prototype);\n\n\nexports.IncrementalSearchKeyboardHandler = IncrementalSearchKeyboardHandler;\n"
  },
  {
    "path": "src/commands/multi_select_commands.js",
    "content": "\n/**\n * commands to enter multiselect mode\n * @type {import(\"../../ace-internal\").Ace.Command[]}\n */\nexports.defaultCommands = [{\n    name: \"addCursorAbove\",\n    description: \"Add cursor above\",\n    exec: function(editor) { editor.selectMoreLines(-1); },\n    bindKey: {win: \"Ctrl-Alt-Up\", mac: \"Ctrl-Alt-Up\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorBelow\",\n    description: \"Add cursor below\",\n    exec: function(editor) { editor.selectMoreLines(1); },\n    bindKey: {win: \"Ctrl-Alt-Down\", mac: \"Ctrl-Alt-Down\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorAboveSkipCurrent\",\n    description: \"Add cursor above (skip current)\",\n    exec: function(editor) { editor.selectMoreLines(-1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Up\", mac: \"Ctrl-Alt-Shift-Up\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorBelowSkipCurrent\",\n    description: \"Add cursor below (skip current)\",\n    exec: function(editor) { editor.selectMoreLines(1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Down\", mac: \"Ctrl-Alt-Shift-Down\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectMoreBefore\",\n    description: \"Select more before\",\n    exec: function(editor) { editor.selectMore(-1); },\n    bindKey: {win: \"Ctrl-Alt-Left\", mac: \"Ctrl-Alt-Left\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectMoreAfter\",\n    description: \"Select more after\",\n    exec: function(editor) { editor.selectMore(1); },\n    bindKey: {win: \"Ctrl-Alt-Right\", mac: \"Ctrl-Alt-Right\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectNextBefore\",\n    description: \"Select next before\",\n    exec: function(editor) { editor.selectMore(-1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Left\", mac: \"Ctrl-Alt-Shift-Left\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectNextAfter\",\n    description: \"Select next after\",\n    exec: function(editor) { editor.selectMore(1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Right\", mac: \"Ctrl-Alt-Shift-Right\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"toggleSplitSelectionIntoLines\",\n    description: \"Split selection into lines\",\n    exec: function(editor) {\n        if (editor.multiSelect.rangeCount > 1)\n            editor.multiSelect.joinSelections();\n        else\n            editor.multiSelect.splitIntoLines();\n    },\n    bindKey: {win: \"Ctrl-Alt-L\", mac: \"Ctrl-Alt-L\"},\n    readOnly: true\n}, {\n    name: \"splitSelectionIntoLines\",\n    description: \"Split into lines\",\n    exec: function(editor) { editor.multiSelect.splitIntoLines(); },\n    readOnly: true\n}, {\n    name: \"alignCursors\",\n    description: \"Align cursors\",\n    exec: function(editor) { editor.alignCursors(); },\n    bindKey: {win: \"Ctrl-Alt-A\", mac: \"Ctrl-Alt-A\"},\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"findAll\",\n    description: \"Find all\",\n    exec: function(editor) { editor.findAll(); },\n    bindKey: {win: \"Ctrl-Alt-K\", mac: \"Ctrl-Alt-G\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}];\n\n/**\n * commands active only in multiselect mode\n * @type {import(\"../../ace-internal\").Ace.Command[]}\n */\nexports.multiSelectCommands = [{\n    name: \"singleSelection\",\n    description: \"Single selection\",\n    bindKey: \"esc\",\n    exec: function(editor) { editor.exitMultiSelectMode(); },\n    scrollIntoView: \"cursor\",\n    readOnly: true,\n    isAvailable: function(editor) {return editor && editor.inMultiSelectMode;}\n}];\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nexports.keyboardHandler = new HashHandler(exports.multiSelectCommands);\n"
  },
  {
    "path": "src/commands/occur_commands.js",
    "content": "var config = require(\"../config\"),\n    Occur = require(\"../occur\").Occur;\n\n// These commands can be installed in a normal command handler to start occur:\nvar occurStartCommand = {\n    name: \"occur\",\n    exec: function(editor, options) {\n        var alreadyInOccur = !!editor.session.$occur;\n        var occurSessionActive = new Occur().enter(editor, options);\n        if (occurSessionActive && !alreadyInOccur)\n            OccurKeyboardHandler.installIn(editor);\n    },\n    readOnly: true\n};\n\nvar occurCommands = [{\n    name: \"occurexit\",\n    bindKey: 'esc|Ctrl-G',\n    exec: function(editor) {\n        var occur = editor.session.$occur;\n        if (!occur) return;\n        occur.exit(editor, {});\n        if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);\n    },\n    readOnly: true\n}, {\n    name: \"occuraccept\",\n    bindKey: 'enter',\n    exec: function(editor) {\n        var occur = editor.session.$occur;\n        if (!occur) return;\n        occur.exit(editor, {translatePosition: true});\n        if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);\n    },\n    readOnly: true\n}];\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar oop = require(\"../lib/oop\");\n\n\nfunction OccurKeyboardHandler() {}\n\noop.inherits(OccurKeyboardHandler, HashHandler);\n\n(function() {\n\n    this.isOccurHandler = true;\n\n    this.attach = function(editor) {\n        HashHandler.call(this, occurCommands, editor.commands.platform);\n        this.$editor = editor;\n    };\n\n    var handleKeyboard$super = this.handleKeyboard;\n    this.handleKeyboard = function(data, hashId, key, keyCode) {\n        // @ts-ignore\n        var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);\n        return (cmd && cmd.command) ? cmd : undefined;\n    };\n\n}).call(OccurKeyboardHandler.prototype);\n\nOccurKeyboardHandler.installIn = function(editor) {\n    var handler = new this();\n    editor.keyBinding.addKeyboardHandler(handler);\n    editor.commands.addCommands(occurCommands);\n};\n\nOccurKeyboardHandler.uninstallFrom = function(editor) {\n    editor.commands.removeCommands(occurCommands);\n    var handler = editor.getKeyboardHandler();\n    if (handler.isOccurHandler)\n        editor.keyBinding.removeKeyboardHandler(handler);\n};\n\nexports.occurStartCommand = occurStartCommand;\n"
  },
  {
    "path": "src/config.js",
    "content": "\"no use strict\";\n\nvar lang = require(\"./lib/lang\");\nvar net = require(\"./lib/net\");\nvar dom = require(\"./lib/dom\");\nvar AppConfig = require(\"./lib/app_config\").AppConfig;\n\nmodule.exports = exports = new AppConfig();\n\n/** @type {import(\"../ace-internal\").Ace.ConfigOptions} */\nvar options = {\n    packaged: false,\n    workerPath: null,\n    modePath: null,\n    themePath: null,\n    basePath: \"\",\n    suffix: \".js\",\n    $moduleUrls: {},\n    loadWorkerFromBlob: true,\n    sharedPopups: false,\n    useStrictCSP: null\n};\n\n/**\n * @template {keyof import(\"../ace-internal\").Ace.ConfigOptions} K\n * @param {K} key - The key of the config option to retrieve.\n * @returns {import(\"../ace-internal\").Ace.ConfigOptions[K]} - The value of the config option.\n */\nexports.get = function(key) {\n    if (!options.hasOwnProperty(key))\n        throw new Error(\"Unknown config key: \" + key);\n    return options[key];\n};\n\n/**\n * @template {keyof import(\"../ace-internal\").Ace.ConfigOptions} K\n * @param {K} key\n * @param {import(\"../ace-internal\").Ace.ConfigOptions[K]} value\n */\nexports.set = function(key, value) {\n    if (options.hasOwnProperty(key))\n        options[key] = value;\n    else if (this.setDefaultValue(\"\", key, value) == false)\n        throw new Error(\"Unknown config key: \" + key);\n    if (key == \"useStrictCSP\")\n        dom.useStrictCSP(value);\n};\n/**\n * @return {import(\"../ace-internal\").Ace.ConfigOptions}\n */\nexports.all = function() {\n    return lang.copyObject(options);\n};\n\nexports.$modes = {};\n\n/**\n * module loading\n * @param {string} name\n * @param {string} [component]\n * @returns {string}\n */\nexports.moduleUrl = function(name, component) {\n    if (options.$moduleUrls[name])\n        return options.$moduleUrls[name];\n\n    var parts = name.split(\"/\");\n    component = component || parts[parts.length - 2] || \"\";\n\n    // todo make this configurable or get rid of '-'\n    var sep = component == \"snippets\" ? \"/\" : \"-\";\n    var base = parts[parts.length - 1];\n    if (component == \"worker\" && sep == \"-\") {\n        var re = new RegExp(\"^\" + component + \"[\\\\-_]|[\\\\-_]\" + component + \"$\", \"g\");\n        base = base.replace(re, \"\");\n    }\n\n    if ((!base || base == component) && parts.length > 1)\n        base = parts[parts.length - 2];\n    var path = options[component + \"Path\"];\n    if (path == null) {\n        path = options.basePath;\n    } else if (sep == \"/\") {\n        component = sep = \"\";\n    }\n    if (path && path.slice(-1) != \"/\")\n        path += \"/\";\n    return path + component + sep + base + this.get(\"suffix\");\n};\n/**\n * @param {string} name\n * @param {string} subst\n * @returns {string}\n */\nexports.setModuleUrl = function(name, subst) {\n    return options.$moduleUrls[name] = subst;\n};\n\nvar loader = function(moduleName, cb) {\n    if (moduleName === \"ace/theme/textmate\" || moduleName === \"./theme/textmate\")\n        return cb(null, require(\"./theme/textmate\"));\n    if (customLoader)\n        return customLoader(moduleName, cb);\n    console.error(\"loader is not configured\");\n};\nvar customLoader;\n\n/** @arg {(name: string, callback: (error: any, module: any) => void) => void} cb */\nexports.setLoader = function(cb) {\n    customLoader = cb;\n};\n\nexports.dynamicModules = Object.create(null);\nexports.$loading = {};\nexports.$loaded = {};\n/**\n * @param {string | [string, string]} moduleId\n * @param {(module: any) => void} onLoad\n */\nexports.loadModule = function(moduleId, onLoad) {\n    var loadedModule;\n    if (Array.isArray(moduleId)) {\n        var moduleType = moduleId[0];\n        var moduleName = moduleId[1];\n    } else if (typeof moduleId == \"string\") {\n        var moduleName = moduleId;\n    }\n    var load = function (module) {\n        // require(moduleName) can return empty object if called after require([moduleName], callback)\n        if (module && !exports.$loading[moduleName]) return onLoad && onLoad(module);\n\n        if (!exports.$loading[moduleName]) exports.$loading[moduleName] = [];\n\n        exports.$loading[moduleName].push(onLoad);\n\n        if (exports.$loading[moduleName].length > 1) return;\n\n        var afterLoad = function() {\n            loader(moduleName, function(err, module) {\n                if (module) exports.$loaded[moduleName] = module;\n                exports._emit(\"load.module\", {name: moduleName, module: module});\n                var listeners = exports.$loading[moduleName];\n                exports.$loading[moduleName] = null;\n                listeners.forEach(function(onLoad) {\n                    onLoad && onLoad(module);\n                });\n            });\n        };\n\n        if (!exports.get(\"packaged\")) return afterLoad();\n\n        net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);\n        reportErrorIfPathIsNotConfigured();\n    };\n\n    if (exports.dynamicModules[moduleName]) {\n        exports.dynamicModules[moduleName]().then(function (module) {\n            if (module.default) {\n                load(module.default);\n            }\n            else {\n                load(module);\n            }\n        });\n    } else {\n        // backwards compatibility for node and packaged version\n        try {\n            loadedModule = this.$require(moduleName);\n        } catch (e) {}\n        load(loadedModule || exports.$loaded[moduleName]);\n    }\n};\n\nexports.$require = function(moduleName) {\n    if (typeof module[\"require\"] == \"function\") {\n        var req = \"require\";\n        return module[req](moduleName);\n    }\n};\n\nexports.setModuleLoader = function (moduleName, onLoad) {\n    exports.dynamicModules[moduleName] = onLoad;\n};\n\nvar reportErrorIfPathIsNotConfigured = function() {\n    if (\n        !options.basePath && !options.workerPath\n        && !options.modePath && !options.themePath\n        && !Object.keys(options.$moduleUrls).length\n    ) {\n        console.error(\n            \"Unable to infer path to ace from script src,\",\n            \"use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes\",\n            \"or with webpack use ace/webpack-resolver\"\n        );\n        reportErrorIfPathIsNotConfigured = function() {};\n    }\n};\n\nexports.version = \"1.43.6\";\n\n\n"
  },
  {
    "path": "src/config_test.js",
    "content": "\"use strict\";\n\nvar config = require(\"./config\");\nvar assert = require(\"./test/assertions\");\nvar {defaultEnglishMessages} = require(\"./lib/default_english_messages\");\n\nmodule.exports = {\n    tearDown: function() {\n        config.setMessages(defaultEnglishMessages);\n    },\n    \"test: path resolution\" : function(done) {\n        config.set(\"packaged\", true);\n        var url = config.moduleUrl(\"kr_theme\", \"theme\");\n        assert.equal(url, \"theme-kr_theme.js\");\n        \n        config.set(\"basePath\", \"a/b\");\n        url = config.moduleUrl(\"m/theme\", \"theme\");\n        assert.equal(url, \"a/b/theme-m.js\");\n        \n        url = config.moduleUrl(\"m/theme\", \"ext\");\n        assert.equal(url, \"a/b/ext-theme.js\");\n        \n        config.set(\"workerPath\", \"c/\");\n        url = config.moduleUrl(\"foo/1\", \"worker\");\n        assert.equal(url, \"c/worker-1.js\");\n        \n        config.setModuleUrl(\"foo/1\", \"a/b1.js\");\n        url = config.moduleUrl(\"foo/1\", \"theme\");\n        assert.equal(url, \"a/b1.js\");\n        \n        url = config.moduleUrl(\"snippets/js\");\n        assert.equal(url, \"a/b/snippets/js.js\");\n        \n        config.setModuleUrl(\"snippets/js\", \"_.js\");\n        url = config.moduleUrl(\"snippets/js\");\n        assert.equal(url, \"_.js\");\n        \n        url = config.moduleUrl(\"ace/ext/textarea\");\n        assert.equal(url, \"a/b/ext-textarea.js\");\n        config.set(\"packaged\", false);\n        \n        /* global Promise*/\n        var callback = () => Promise.resolve(\"success\");\n        config.setModuleLoader(\"ace/test-module\", callback);\n        assert.equal(config.dynamicModules[\"ace/test-module\"], callback);\n        config.loadModule(\"ace/test-module\", (module) => {\n            assert.equal(module, \"success\");\n            done();\n        });\n    },\n    \"test: nls\": function() {\n        var nls = config.nls;\n        config.setMessages({\n            foo: \"hello world of $1\",\n            test_key: \"hello world for test key\"\n        });\n        assert.equal(nls(\"untranslated_key\",\"bar $1\"), \"bar $1\");\n        assert.equal(nls(\"untranslated_key\", \"bar\"), \"bar\");\n        assert.equal(nls(\"untranslated_key_but_translated_default_string\", \"foo\"), \"hello world of $1\");\n        assert.equal(nls(\"untranslated_key_but_translated_default_string\", \"foo\", {1: \"goo\"}), \"hello world of goo\");\n        assert.equal(nls(\"untranslated_key\", \"$0B is $1$$\", [0.11, 22]), \"0.11B is 22$\");\n        assert.equal(nls(\"untranslated_key_but_translated_default_string\", \"foo\", {1: \"goo\"}), \"hello world of goo\");\n        assert.equal(nls(\"test_key\", \"this text should not appear\"), \"hello world for test key\");\n    },\n    \"test: nls setting nlsPlaceholders\": function() {\n        var nls = config.nls;\n\n        // Should default to using dollar signs\n        config.setMessages({\n            test_with_curly_brackets: \"hello world $0 of {0} and $1 to the {1} degree\"\n        });\n        assert.equal(nls(\"test_with_curly_brackets\", \"hello world $0 of {1} and $1 to the {1} degree\", [\"bar\", \"third\"]), \"hello world bar of {0} and third to the {1} degree\");\n\n        config.setMessages({\n            test_with_curly_brackets: \"hello world $0 of {0} and $1 to the {1} degree\"\n        }, {placeholders: \"curlyBrackets\"});\n        assert.equal(nls(\"test_with_curly_brackets\", \"hello world $0 of {1} and $1 to the {1} degree\", [\"bar\", \"third\"]), \"hello world $0 of bar and $1 to the third degree\");\n\n        config.setMessages({\n            test_with_curly_brackets: \"hello world $0 of {0} and $1 to the {1} degree\"\n        }, {placeholders: \"dollarSigns\"});\n        assert.equal(nls(\"test_with_curly_brackets\", \"hello world $0 of {1} and $1 to the {1} degree\", [\"bar\", \"third\"]), \"hello world bar of {0} and third to the {1} degree\");\n    },\n    \"test: define options\" : function() {\n        var o = {};\n        config.defineOptions(o, \"test_object\", {\n            opt1: {\n                set: function(val) {\n                    this.x = val;\n                },\n                value: 7\n            },\n            initialValue: {\n                set: function(val) {\n                    this.x = val;\n                },\n                initialValue: 8\n            },\n            opt2: {\n                get: function(val) {\n                    return this.x;\n                }\n            },\n            forwarded: \"model\"\n        });\n        o.model = {};\n        config.defineOptions(o.model, \"model\", {\n            forwarded: {value: 1}\n        });\n        \n        config.resetOptions(o);\n        config.resetOptions(o.model);\n        assert.equal(o.getOption(\"opt1\"), 7);\n        assert.equal(o.getOption(\"opt2\"), 7);\n        o.setOption(\"opt1\", 8);\n        assert.equal(o.getOption(\"opt1\"), 8);\n        assert.equal(o.getOption(\"opt2\"), 8);\n        \n        assert.equal(o.getOption(\"forwarded\"), 1);\n        \n        assert.equal(o.getOption(\"new\"), undefined);\n        o.setOption(\"new\", 0);\n        assert.equal(o.getOption(\"new\"), undefined);\n        \n\n        assert.equal(o.getOption(\"initialValue\"), 8);\n        o.setOption(\"initialValue\", 7);\n        assert.equal(o.getOption(\"opt2\"), 7);\n        \n        config.setDefaultValues(\"test_object\", {\n            opt1: 1,\n            forwarded: 2\n        });\n        config.resetOptions(o);\n        assert.equal(o.getOption(\"opt1\"), 1);\n        assert.equal(o.getOption(\"forwarded\"), 2);\n    }\n};\n\n\nrequire(\"./test/run\")(module);\n"
  },
  {
    "path": "src/css/editor-css.js",
    "content": "/*\nstyles = []\nfor (var i = 1; i < 16; i++) {\n    styles.push(\".ace_br\" + i + \"{\" + (\n        [\"top-left\", \"top-right\", \"bottom-right\", \"bottom-left\"]\n    ).map(function(x, j) {\n        return i & (1<<j) ? \"border-\" + x + \"-radius: 3px;\" : \"\" \n    }).filter(Boolean).join(\" \") + \"}\")\n}\nstyles.join(\"\\\\n\")\n*/\nmodule.exports = `\n.ace_br1 {border-top-left-radius    : 3px;}\n.ace_br2 {border-top-right-radius   : 3px;}\n.ace_br3 {border-top-left-radius    : 3px; border-top-right-radius:    3px;}\n.ace_br4 {border-bottom-right-radius: 3px;}\n.ace_br5 {border-top-left-radius    : 3px; border-bottom-right-radius: 3px;}\n.ace_br6 {border-top-right-radius   : 3px; border-bottom-right-radius: 3px;}\n.ace_br7 {border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px;}\n.ace_br8 {border-bottom-left-radius : 3px;}\n.ace_br9 {border-top-left-radius    : 3px; border-bottom-left-radius:  3px;}\n.ace_br10{border-top-right-radius   : 3px; border-bottom-left-radius:  3px;}\n.ace_br11{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-left-radius:  3px;}\n.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\n.ace_br13{border-top-left-radius    : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\n.ace_br14{border-top-right-radius   : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\n.ace_br15{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\n\n\n.ace_editor {\n    position: relative;\n    overflow: hidden;\n    padding: 0;\n    font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'Source Code Pro', 'source-code-pro', monospace;\n    direction: ltr;\n    text-align: left;\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n    forced-color-adjust: none;\n}\n\n.ace_scroller {\n    position: absolute;\n    overflow: hidden;\n    top: 0;\n    bottom: 0;\n    background-color: inherit;\n    -ms-user-select: none;\n    -moz-user-select: none;\n    -webkit-user-select: none;\n    user-select: none;\n    cursor: text;\n}\n\n.ace_content {\n    position: absolute;\n    box-sizing: border-box;\n    min-width: 100%;\n    contain: style size layout;\n    font-variant-ligatures: no-common-ligatures;\n}\n.ace_invisible {\n    font-variant-ligatures: none;\n}\n\n.ace_keyboard-focus:focus {\n    box-shadow: inset 0 0 0 2px #5E9ED6;\n    outline: none;\n}\n\n.ace_dragging .ace_scroller:before{\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    content: '';\n    background: rgba(250, 250, 250, 0.01);\n    z-index: 1000;\n}\n.ace_dragging.ace_dark .ace_scroller:before{\n    background: rgba(0, 0, 0, 0.01);\n}\n\n.ace_gutter {\n    position: absolute;\n    overflow : hidden;\n    width: auto;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    cursor: default;\n    z-index: 4;\n    -ms-user-select: none;\n    -moz-user-select: none;\n    -webkit-user-select: none;\n    user-select: none;\n    contain: style size layout;\n}\n\n.ace_gutter-active-line {\n    position: absolute;\n    left: 0;\n    right: 0;\n}\n\n.ace_scroller.ace_scroll-left:after {\n    content: \"\";\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\n    pointer-events: none;\n}\n\n.ace_gutter-cell, .ace_gutter-cell_svg-icons {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    padding-left: 19px;\n    padding-right: 6px;\n    background-repeat: no-repeat;\n}\n\n.ace_gutter-cell_svg-icons .ace_gutter_annotation {\n    margin-left: -14px;\n    float: left;\n}\n\n.ace_gutter-cell .ace_gutter_annotation {\n    margin-left: -19px;\n    float: left;\n}\n\n.ace_gutter-cell.ace_error, .ace_icon.ace_error, .ace_icon.ace_error_fold, .ace_gutter-cell.ace_security, .ace_icon.ace_security, .ace_icon.ace_security_fold {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");\n    background-repeat: no-repeat;\n    background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_warning, .ace_icon.ace_warning, .ace_icon.ace_warning_fold {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");\n    background-repeat: no-repeat;\n    background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_info, .ace_icon.ace_info, .ace_gutter-cell.ace_hint, .ace_icon.ace_hint {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\n    background-repeat: no-repeat;\n    background-position: 2px center;\n}\n\n.ace_dark .ace_gutter-cell.ace_info, .ace_dark .ace_icon.ace_info, .ace_dark .ace_gutter-cell.ace_hint, .ace_dark .ace_icon.ace_hint {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\n}\n\n.ace_icon_svg.ace_error {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJyZWQiIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIj4KPGNpcmNsZSBmaWxsPSJub25lIiBjeD0iOCIgY3k9IjgiIHI9IjciIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPGxpbmUgeDE9IjExIiB5MT0iNSIgeDI9IjUiIHkyPSIxMSIvPgo8bGluZSB4MT0iMTEiIHkxPSIxMSIgeDI9IjUiIHkyPSI1Ii8+CjwvZz4KPC9zdmc+\");\n    background-color: crimson;\n}\n.ace_icon_svg.ace_security {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8ZyBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0iZGFya29yYW5nZSIgZmlsbD0ibm9uZSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iPgogICAgICAgIDxwYXRoIGNsYXNzPSJzdHJva2UtbGluZWpvaW4tcm91bmQiIGQ9Ik04IDE0LjgzMDdDOCAxNC44MzA3IDIgMTIuOTA0NyAyIDguMDg5OTJWMy4yNjU0OEM1LjMxIDMuMjY1NDggNy45ODk5OSAxLjM0OTE4IDcuOTg5OTkgMS4zNDkxOEM3Ljk4OTk5IDEuMzQ5MTggMTAuNjkgMy4yNjU0OCAxNCAzLjI2NTQ4VjguMDg5OTJDMTQgMTIuOTA0NyA4IDE0LjgzMDcgOCAxNC44MzA3WiIvPgogICAgICAgIDxwYXRoIGQ9Ik0yIDguMDg5OTJWMy4yNjU0OEM1LjMxIDMuMjY1NDggNy45ODk5OSAxLjM0OTE4IDcuOTg5OTkgMS4zNDkxOCIvPgogICAgICAgIDxwYXRoIGQ9Ik0xMy45OSA4LjA4OTkyVjMuMjY1NDhDMTAuNjggMy4yNjU0OCA4IDEuMzQ5MTggOCAxLjM0OTE4Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9InN0cm9rZS1saW5lam9pbi1yb3VuZCIgZD0iTTggNFY5Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9InN0cm9rZS1saW5lam9pbi1yb3VuZCIgZD0iTTggMTBWMTIiLz4KICAgIDwvZz4KPC9zdmc+\");\n    background-color: crimson;\n}\n.ace_icon_svg.ace_warning {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJkYXJrb3JhbmdlIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+Cjxwb2x5Z29uIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9Im5vbmUiIHBvaW50cz0iOCAxIDE1IDE1IDEgMTUgOCAxIi8+CjxyZWN0IHg9IjgiIHk9IjEyIiB3aWR0aD0iMC4wMSIgaGVpZ2h0PSIwLjAxIi8+CjxsaW5lIHgxPSI4IiB5MT0iNiIgeDI9IjgiIHkyPSIxMCIvPgo8L2c+Cjwvc3ZnPg==\");\n    background-color: darkorange;\n}\n.ace_icon_svg.ace_info {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJibHVlIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+CjxjaXJjbGUgZmlsbD0ibm9uZSIgY3g9IjgiIGN5PSI4IiByPSI3IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjxwb2x5bGluZSBwb2ludHM9IjggMTEgOCA4Ii8+Cjxwb2x5bGluZSBwb2ludHM9IjkgOCA2IDgiLz4KPGxpbmUgeDE9IjEwIiB5MT0iMTEiIHgyPSI2IiB5Mj0iMTEiLz4KPHJlY3QgeD0iOCIgeT0iNSIgd2lkdGg9IjAuMDEiIGhlaWdodD0iMC4wMSIvPgo8L2c+Cjwvc3ZnPg==\");\n    background-color: royalblue;\n}\n.ace_icon_svg.ace_hint {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8ZyBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0ic2lsdmVyIiBmaWxsPSJub25lIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+CiAgICAgICAgPHBhdGggY2xhc3M9InN0cm9rZS1saW5lam9pbi1yb3VuZCIgZD0iTTYgMTRIMTAiLz4KICAgICAgICA8cGF0aCBkPSJNOCAxMUg5QzkgOS40NzAwMiAxMiA4LjU0MDAyIDEyIDUuNzYwMDJDMTIuMDIgNC40MDAwMiAxMS4zOSAzLjM2MDAyIDEwLjQzIDIuNjcwMDJDOSAxLjY0MDAyIDcuMDAwMDEgMS42NDAwMiA1LjU3MDAxIDIuNjcwMDJDNC42MTAwMSAzLjM2MDAyIDMuOTggNC40MDAwMiA0IDUuNzYwMDJDNCA4LjU0MDAyIDcuMDAwMDEgOS40NzAwMiA3LjAwMDAxIDExSDhaIi8+CiAgICA8L2c+Cjwvc3ZnPg==\");\n    background-color: silver;\n}\n\n.ace_icon_svg.ace_error_fold {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAxNiIgZmlsbD0ibm9uZSI+CiAgPHBhdGggZD0ibSAxOC45Mjk4NTEsNy44Mjk4MDc2IGMgMC4xNDYzNTMsNi4zMzc0NjA0IC02LjMyMzE0Nyw3Ljc3Nzg0NDQgLTcuNDc3OTEyLDcuNzc3ODQ0NCAtMi4xMDcyNzI2LC0wLjEyODc1IDUuMTE3Njc4LDAuMzU2MjQ5IDUuMDUxNjk4LC03Ljg3MDA2MTggLTAuNjA0NjcyLC04LjAwMzk3MzQ5IC03LjA3NzI3MDYsLTcuNTYzMTE4OSAtNC44NTczLC03LjQzMDM5NTU2IDEuNjA2LC0wLjExNTE0MjI1IDYuODk3NDg1LDEuMjYyNTQ1OTYgNy4yODM1MTQsNy41MjI2MTI5NiB6IiBmaWxsPSJjcmltc29uIiBzdHJva2Utd2lkdGg9IjIiLz4KICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibSA4LjExNDc1NjIsMi4wNTI5ODI4IGMgMy4zNDkxNjk4LDAgNi4wNjQxMzI4LDIuNjc2ODYyNyA2LjA2NDEzMjgsNS45Nzg5NTMgMCwzLjMwMjExMjIgLTIuNzE0OTYzLDUuOTc4OTIwMiAtNi4wNjQxMzI4LDUuOTc4OTIwMiAtMy4zNDkxNDczLDAgLTYuMDY0MTc3MiwtMi42NzY4MDggLTYuMDY0MTc3MiwtNS45Nzg5MjAyIDAuMDA1MzksLTMuMjk5ODg2MSAyLjcxNzI2NTYsLTUuOTczNjQwOCA2LjA2NDE3NzIsLTUuOTc4OTUzIHogbSAwLC0xLjczNTgyNzE5IGMgLTQuMzIxNDgzNiwwIC03LjgyNDc0MDM4LDMuNDU0MDE4NDkgLTcuODI0NzQwMzgsNy43MTQ3ODAxOSAwLDQuMjYwNzI4MiAzLjUwMzI1Njc4LDcuNzE0NzQ1MiA3LjgyNDc0MDM4LDcuNzE0NzQ1MiA0LjMyMTQ0OTgsMCA3LjgyNDY5OTgsLTMuNDU0MDE3IDcuODI0Njk5OCwtNy43MTQ3NDUyIDAsLTIuMDQ2MDkxNCAtMC44MjQzOTIsLTQuMDA4MzY3MiAtMi4yOTE3NTYsLTUuNDU1MTc0NiBDIDEyLjE4MDIyNSwxLjEyOTk2NDggMTAuMTkwMDEzLDAuMzE3MTU1NjEgOC4xMTQ3NTYyLDAuMzE3MTU1NjEgWiBNIDYuOTM3NDU2Myw4LjI0MDU5ODUgNC42NzE4Njg1LDEwLjQ4NTg1MiA2LjAwODY4MTQsMTEuODc2NzI4IDguMzE3MDAzNSw5LjYwMDc5MTEgMTAuNjI1MzM3LDExLjg3NjcyOCAxMS45NjIxMzgsMTAuNDg1ODUyIDkuNjk2NTUwOCw4LjI0MDU5ODUgMTEuOTYyMTM4LDYuMDA2ODA2NiAxMC41NzMyNDYsNC42Mzc0MzM1IDguMzE3MDAzNSw2Ljg3MzQyOTcgNi4wNjA3NjA3LDQuNjM3NDMzNSA0LjY3MTg2ODUsNi4wMDY4MDY2IFoiIGZpbGw9ImNyaW1zb24iIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4=\");\n    background-color: crimson;\n}\n.ace_icon_svg.ace_security_fold {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMTcgMTQiIGZpbGw9Im5vbmUiPgogICAgPHBhdGggZD0iTTEwLjAwMDEgMTMuNjk5MkMxMC4wMDAxIDEzLjY5OTIgMTEuOTI0MSAxMy40NzYzIDEzIDEyLjY5OTJDMTQuNDEzOSAxMS42NzgxIDE2IDEwLjUgMTYuMTI1MSA2LjgxMTI2VjIuNTg5ODdDMTYuMTI1MSAyLjU0NzY4IDE2LjEyMjEgMi41MDYxOSAxNi4xMTY0IDIuNDY1NTlWMS43MTQ4NUgxNS4yNDE0TDE1LjIzMDcgMS43MTQ4NEwxNC42MjUxIDEuNjk5MjJWNi44MTEyM0MxNC42MjUxIDguNTEwNjEgMTQuNjI1MSA5LjQ2NDYxIDEyLjc4MjQgMTEuNzIxQzEyLjE1ODYgMTIuNDg0OCAxMC4wMDAxIDEzLjY5OTIgMTAuMDAwMSAxMy42OTkyWiIgZmlsbD0iY3JpbXNvbiIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTcuMzM2MDkgMC4zNjc0NzVDNy4wMzIxNCAwLjE1MjY1MiA2LjYyNTQ4IDAuMTUzNjE0IDYuMzIyNTMgMC4zNjk5OTdMNi4zMDg2OSAwLjM3OTU1NEM2LjI5NTUzIDAuMzg4NTg4IDYuMjczODggMC40MDMyNjYgNi4yNDQxNyAwLjQyMjc4OUM2LjE4NDcxIDAuNDYxODYgNi4wOTMyMSAwLjUyMDE3MSA1Ljk3MzEzIDAuNTkxMzczQzUuNzMyNTEgMC43MzQwNTkgNS4zNzk5IDAuOTI2ODY0IDQuOTQyNzkgMS4xMjAwOUM0LjA2MTQ0IDEuNTA5NyAyLjg3NTQxIDEuODgzNzcgMS41ODk4NCAxLjg4Mzc3SDAuNzE0ODQ0VjIuNzU4NzdWNi45ODAxNUMwLjcxNDg0NCA5LjQ5Mzc0IDIuMjg4NjYgMTEuMTk3MyAzLjcwMjU0IDEyLjIxODVDNC40MTg0NSAxMi43MzU1IDUuMTI4NzQgMTMuMTA1MyA1LjY1NzMzIDEzLjM0NTdDNS45MjI4NCAxMy40NjY0IDYuMTQ1NjYgMTMuNTU1OSA2LjMwNDY1IDEzLjYxNjFDNi4zODQyMyAxMy42NDYyIDYuNDQ4MDUgMTMuNjY5IDYuNDkzNDkgMTMuNjg0OEM2LjUxNjIyIDEzLjY5MjcgNi41MzQzOCAxMy42OTg5IDYuNTQ3NjQgMTMuNzAzM0w2LjU2MzgyIDEzLjcwODdMNi41NjkwOCAxMy43MTA0TDYuNTcwOTkgMTMuNzExTDYuODM5ODQgMTMuNzUzM0w2LjU3MjQyIDEzLjcxMTVDNi43NDYzMyAxMy43NjczIDYuOTMzMzUgMTMuNzY3MyA3LjEwNzI3IDEzLjcxMTVMNy4xMDg3IDEzLjcxMUw3LjExMDYxIDEzLjcxMDRMNy4xMTU4NyAxMy43MDg3TDcuMTMyMDUgMTMuNzAzM0M3LjE0NTMxIDEzLjY5ODkgNy4xNjM0NiAxMy42OTI3IDcuMTg2MTkgMTMuNjg0OEM3LjIzMTY0IDEzLjY2OSA3LjI5NTQ2IDEzLjY0NjIgNy4zNzUwMyAxMy42MTYxQzcuNTM0MDMgMTMuNTU1OSA3Ljc1Njg1IDEzLjQ2NjQgOC4wMjIzNiAxMy4zNDU3QzguNTUwOTUgMTMuMTA1MyA5LjI2MTIzIDEyLjczNTUgOS45NzcxNSAxMi4yMTg1QzExLjM5MSAxMS4xOTczIDEyLjk2NDggOS40OTM3NyAxMi45NjQ4IDYuOTgwMThWMi43NTg4QzEyLjk2NDggMi43MTY2IDEyLjk2MTkgMi42NzUxMSAxMi45NTYxIDIuNjM0NTFWMS44ODM3N0gxMi4wODExQzEyLjA3NzUgMS44ODM3NyAxMi4wNzQgMS44ODM3NyAxMi4wNzA0IDEuODgzNzdDMTAuNzk3OSAxLjg4MDA0IDkuNjE5NjIgMS41MTEwMiA4LjczODk0IDEuMTI0ODZDOC43MzUzNCAxLjEyMzI3IDguNzMxNzQgMS4xMjE2OCA4LjcyODE0IDEuMTIwMDlDOC4yOTEwMyAwLjkyNjg2NCA3LjkzODQyIDAuNzM0MDU5IDcuNjk3NzkgMC41OTEzNzNDNy41Nzc3MiAwLjUyMDE3MSA3LjQ4NjIyIDAuNDYxODYgNy40MjY3NiAwLjQyMjc4OUM3LjM5NzA1IDAuNDAzMjY2IDcuMzc1MzkgMC4zODg1ODggNy4zNjIyNCAwLjM3OTU1NEw3LjM0ODk2IDAuMzcwMzVDNy4zNDg5NiAwLjM3MDM1IDcuMzQ4NDcgMC4zNzAwMiA3LjM0NTYzIDAuMzc0MDU0TDcuMzM3NzkgMC4zNjg2NTlMNy4zMzYwOSAwLjM2NzQ3NVpNOC4wMzQ3MSAyLjcyNjkxQzguODYwNCAzLjA5MDYzIDkuOTYwNjYgMy40NjMwOSAxMS4yMDYxIDMuNTg5MDdWNi45ODAxNUgxMS4yMTQ4QzExLjIxNDggOC42Nzk1MyAxMC4xNjM3IDkuOTI1MDcgOC45NTI1NCAxMC43OTk4QzguMzU1OTUgMTEuMjMwNiA3Ljc1Mzc0IDExLjU0NTQgNy4yOTc5NiAxMS43NTI3QzcuMTE2NzEgMTEuODM1MSA2Ljk2MDYyIDExLjg5OTYgNi44Mzk4NCAxMS45NDY5QzYuNzE5MDYgMTEuODk5NiA2LjU2Mjk3IDExLjgzNTEgNi4zODE3MyAxMS43NTI3QzUuOTI1OTUgMTEuNTQ1NCA1LjMyMzczIDExLjIzMDYgNC43MjcxNSAxMC43OTk4QzMuNTE2MDMgOS45MjUwNyAyLjQ2NDg0IDguNjc5NTUgMi40NjQ4NCA2Ljk4MDE4VjMuNTg5MDlDMy43MTczOCAzLjQ2MjM5IDQuODIzMDggMy4wODYzOSA1LjY1MDMzIDIuNzIwNzFDNi4xNDIyOCAyLjUwMzI0IDYuNTQ0ODUgMi4yODUzNyA2LjgzMjU0IDIuMTE2MjRDNy4xMjE4MSAyLjI4NTM1IDcuNTI3IDIuNTAzNTIgOC4wMjE5NiAyLjcyMTMxQzguMDI2MiAyLjcyMzE3IDguMDMwNDUgMi43MjUwNCA4LjAzNDcxIDIuNzI2OTFaTTUuOTY0ODQgMy40MDE0N1Y3Ljc3NjQ3SDcuNzE0ODRWMy40MDE0N0g1Ljk2NDg0Wk01Ljk2NDg0IDEwLjQwMTVWOC42NTE0N0g3LjcxNDg0VjEwLjQwMTVINS45NjQ4NFoiIGZpbGw9ImNyaW1zb24iIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4=\");\n    background-color: crimson;\n}\n.ace_icon_svg.ace_warning_fold {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyMCAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNC43NzY5IDE0LjczMzdMOC42NTE5MiAyLjQ4MzY5QzguMzI5NDYgMS44Mzg3NyA3LjQwOTEzIDEuODM4NzcgNy4wODY2NyAyLjQ4MzY5TDAuOTYxNjY5IDE0LjczMzdDMC42NzA3NzUgMTUuMzE1NSAxLjA5MzgzIDE2IDEuNzQ0MjkgMTZIMTMuOTk0M0MxNC42NDQ4IDE2IDE1LjA2NzggMTUuMzE1NSAxNC43NzY5IDE0LjczMzdaTTMuMTYwMDcgMTQuMjVMNy44NjkyOSA0LjgzMTU2TDEyLjU3ODUgMTQuMjVIMy4xNjAwN1pNOC43NDQyOSAxMS42MjVWMTMuMzc1SDYuOTk0MjlWMTEuNjI1SDguNzQ0MjlaTTYuOTk0MjkgMTAuNzVWNy4yNUg4Ljc0NDI5VjEwLjc1SDYuOTk0MjlaIiBmaWxsPSIjRUM3MjExIi8+CjxwYXRoIGQ9Ik0xMS4xOTkxIDIuOTUyMzhDMTAuODgwOSAyLjMxNDY3IDEwLjM1MzcgMS44MDUyNiA5LjcwNTUgMS41MDlMMTEuMDQxIDEuMDY5NzhDMTEuNjg4MyAwLjk0OTgxNCAxMi4zMzcgMS4yNzI2MyAxMi42MzE3IDEuODYxNDFMMTcuNjEzNiAxMS44MTYxQzE4LjM1MjcgMTMuMjkyOSAxNy41OTM4IDE1LjA4MDQgMTYuMDE4IDE1LjU3NDVDMTYuNDA0NCAxNC40NTA3IDE2LjMyMzEgMTMuMjE4OCAxNS43OTI0IDEyLjE1NTVMMTEuMTk5MSAyLjk1MjM4WiIgZmlsbD0iI0VDNzIxMSIvPgo8L3N2Zz4=\");\n    background-color: darkorange;\n}\n\n.ace_scrollbar {\n    contain: strict;\n    position: absolute;\n    right: 0;\n    bottom: 0;\n    z-index: 6;\n}\n\n.ace_scrollbar-inner {\n    position: absolute;\n    cursor: text;\n    left: 0;\n    top: 0;\n}\n\n.ace_scrollbar-v{\n    overflow-x: hidden;\n    overflow-y: scroll;\n    top: 0;\n}\n\n.ace_scrollbar-h {\n    overflow-x: scroll;\n    overflow-y: hidden;\n    left: 0;\n}\n\n.ace_print-margin {\n    position: absolute;\n    height: 100%;\n}\n\n.ace_text-input {\n    position: absolute;\n    z-index: 0;\n    width: 0.5em;\n    height: 1em;\n    opacity: 0;\n    background: transparent;\n    -moz-appearance: none;\n    appearance: none;\n    border: none;\n    resize: none;\n    outline: none;\n    overflow: hidden;\n    font: inherit;\n    padding: 0 1px;\n    margin: 0 -1px;\n    contain: strict;\n    -ms-user-select: text;\n    -moz-user-select: text;\n    -webkit-user-select: text;\n    user-select: text;\n    /*with \\`pre-line\\` chrome inserts &nbsp; instead of space*/\n    white-space: pre!important;\n}\n.ace_text-input.ace_composition {\n    background: transparent;\n    color: inherit;\n    z-index: 1000;\n    opacity: 1;\n}\n.ace_composition_placeholder { color: transparent }\n.ace_composition_marker { \n    border-bottom: 1px solid;\n    position: absolute;\n    border-radius: 0;\n    margin-top: 1px;\n}\n\n[ace_nocontext=true] {\n    transform: none!important;\n    filter: none!important;\n    clip-path: none!important;\n    mask : none!important;\n    contain: none!important;\n    perspective: none!important;\n    mix-blend-mode: initial!important;\n    z-index: auto;\n}\n\n.ace_layer {\n    z-index: 1;\n    position: absolute;\n    overflow: hidden;\n    /* workaround for chrome bug https://github.com/ajaxorg/ace/issues/2312*/\n    word-wrap: normal;\n    white-space: pre;\n    height: 100%;\n    width: 100%;\n    box-sizing: border-box;\n    /* setting pointer-events: auto; on node under the mouse, which changes\n        during scroll, will break mouse wheel scrolling in Safari */\n    pointer-events: none;\n}\n\n.ace_gutter-layer {\n    position: relative;\n    width: auto;\n    text-align: right;\n    pointer-events: auto;\n    height: 1000000px;\n    contain: style size layout;\n}\n\n.ace_text-layer {\n    font: inherit !important;\n    position: absolute;\n    height: 1000000px;\n    width: 1000000px;\n    contain: style size layout;\n}\n\n.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {\n    contain: style size layout;\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n}\n\n.ace_hidpi .ace_text-layer,\n.ace_hidpi .ace_gutter-layer,\n.ace_hidpi .ace_content,\n.ace_hidpi .ace_gutter {\n    contain: strict;\n}\n.ace_hidpi .ace_text-layer > .ace_line, \n.ace_hidpi .ace_text-layer > .ace_line_group {\n    contain: strict;\n}\n\n.ace_cjk {\n    display: inline-block;\n    text-align: center;\n}\n\n.ace_cursor-layer {\n    z-index: 4;\n}\n\n.ace_cursor {\n    z-index: 4;\n    position: absolute;\n    box-sizing: border-box;\n    border-left: 2px solid;\n    /* workaround for smooth cursor repaintng whole screen in chrome */\n    transform: translatez(0);\n}\n\n.ace_multiselect .ace_cursor {\n    border-left-width: 1px;\n}\n\n.ace_slim-cursors .ace_cursor {\n    border-left-width: 1px;\n}\n\n.ace_overwrite-cursors .ace_cursor {\n    border-left-width: 0;\n    border-bottom: 1px solid;\n}\n\n.ace_hidden-cursors .ace_cursor {\n    opacity: 0.2;\n}\n\n.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {\n    opacity: 0;\n}\n\n.ace_smooth-blinking .ace_cursor {\n    transition: opacity 0.18s;\n}\n\n.ace_animate-blinking .ace_cursor {\n    animation-duration: 1000ms;\n    animation-timing-function: step-end;\n    animation-name: blink-ace-animate;\n    animation-iteration-count: infinite;\n}\n\n.ace_animate-blinking.ace_smooth-blinking .ace_cursor {\n    animation-duration: 1000ms;\n    animation-timing-function: ease-in-out;\n    animation-name: blink-ace-animate-smooth;\n}\n    \n@keyframes blink-ace-animate {\n    from, to { opacity: 1; }\n    60% { opacity: 0; }\n}\n\n@keyframes blink-ace-animate-smooth {\n    from, to { opacity: 1; }\n    45% { opacity: 1; }\n    60% { opacity: 0; }\n    85% { opacity: 0; }\n}\n\n.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\n    position: absolute;\n    z-index: 3;\n}\n\n.ace_marker-layer .ace_selection {\n    position: absolute;\n    z-index: 5;\n}\n\n.ace_marker-layer .ace_bracket {\n    position: absolute;\n    z-index: 6;\n}\n\n.ace_marker-layer .ace_error_bracket {\n    position: absolute;\n    border-bottom: 1px solid #DE5555;\n    border-radius: 0;\n}\n\n.ace_marker-layer .ace_active-line {\n    position: absolute;\n    z-index: 2;\n}\n\n.ace_marker-layer .ace_selected-word {\n    position: absolute;\n    z-index: 4;\n    box-sizing: border-box;\n}\n\n.ace_line .ace_fold {\n    box-sizing: border-box;\n\n    display: inline-block;\n    height: 11px;\n    margin-top: -2px;\n    vertical-align: middle;\n\n    background-image:\n        url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\n        url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\n    background-repeat: no-repeat, repeat-x;\n    background-position: center center, top left;\n    color: transparent;\n\n    border: 1px solid black;\n    border-radius: 2px;\n\n    cursor: pointer;\n    pointer-events: auto;\n}\n\n.ace_dark .ace_fold {\n}\n\n.ace_fold:hover{\n    background-image:\n        url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\n        url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\n}\n\n.ace_tooltip {\n    background-color: #f5f5f5;\n    border: 1px solid gray;\n    border-radius: 1px;\n    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\n    color: black;\n    padding: 3px 4px;\n    position: fixed;\n    z-index: 999999;\n    box-sizing: border-box;\n    cursor: default;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n    line-height: normal;\n    font-style: normal;\n    font-weight: normal;\n    letter-spacing: normal;\n    pointer-events: none;\n    overflow: auto;\n    max-width: min(33em, 66vw);\n    overscroll-behavior: contain;\n}\n.ace_tooltip pre {\n    white-space: pre-wrap;\n}\n\n.ace_tooltip.ace_dark {\n    background-color: #636363;\n    color: #fff;\n}\n\n.ace_tooltip:focus {\n    outline: 1px solid #5E9ED6;\n}\n\n.ace_icon {\n    display: inline-block;\n    width: 18px;\n    vertical-align: top;\n}\n\n.ace_icon_svg {\n    display: inline-block;\n    width: 12px;\n    vertical-align: top;\n    -webkit-mask-repeat: no-repeat;\n    -webkit-mask-size: 12px;\n    -webkit-mask-position: center;\n}\n\n.ace_folding-enabled > .ace_gutter-cell, .ace_folding-enabled > .ace_gutter-cell_svg-icons {\n    padding-right: 13px;\n}\n\n.ace_fold-widget, .ace_custom-widget {\n    box-sizing: border-box;\n\n    margin: 0 -12px 0 1px;\n    display: none;\n    width: 11px;\n    vertical-align: top;\n\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\n    background-repeat: no-repeat;\n    background-position: center;\n\n    border-radius: 3px;\n    \n    border: 1px solid transparent;\n    cursor: pointer;\n    pointer-events: auto;\n}\n\n.ace_custom-widget {\n    background: none;\n}\n\n.ace_folding-enabled .ace_fold-widget {\n    display: inline-block;   \n}\n\n.ace_fold-widget.ace_end {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\n}\n\n.ace_fold-widget.ace_closed {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\n}\n\n.ace_fold-widget:hover {\n    border: 1px solid rgba(0, 0, 0, 0.3);\n    background-color: rgba(255, 255, 255, 0.2);\n    box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n}\n\n.ace_fold-widget:active {\n    border: 1px solid rgba(0, 0, 0, 0.4);\n    background-color: rgba(0, 0, 0, 0.05);\n    box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n}\n/**\n * Dark version for fold widgets\n */\n.ace_dark .ace_fold-widget {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\n}\n.ace_dark .ace_fold-widget.ace_end {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\n}\n.ace_dark .ace_fold-widget.ace_closed {\n    background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\n}\n.ace_dark .ace_fold-widget:hover {\n    box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\n    background-color: rgba(255, 255, 255, 0.1);\n}\n.ace_dark .ace_fold-widget:active {\n    box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\n}\n\n.ace_inline_button {\n    border: 1px solid lightgray;\n    display: inline-block;\n    margin: -1px 8px;\n    padding: 0 5px;\n    pointer-events: auto;\n    cursor: pointer;\n}\n.ace_inline_button:hover {\n    border-color: gray;\n    background: rgba(200,200,200,0.2);\n    display: inline-block;\n    pointer-events: auto;\n}\n\n.ace_fold-widget.ace_invalid {\n    background-color: #FFB4B4;\n    border-color: #DE5555;\n}\n\n.ace_fade-fold-widgets .ace_fold-widget {\n    transition: opacity 0.4s ease 0.05s;\n    opacity: 0;\n}\n\n.ace_fade-fold-widgets:hover .ace_fold-widget {\n    transition: opacity 0.05s ease 0.05s;\n    opacity:1;\n}\n\n.ace_underline {\n    text-decoration: underline;\n}\n\n.ace_bold {\n    font-weight: bold;\n}\n\n.ace_nobold .ace_bold {\n    font-weight: normal;\n}\n\n.ace_italic {\n    font-style: italic;\n}\n\n\n.ace_error-marker {\n    background-color: rgba(255, 0, 0,0.2);\n    position: absolute;\n    z-index: 9;\n}\n\n.ace_highlight-marker {\n    background-color: rgba(255, 255, 0,0.2);\n    position: absolute;\n    z-index: 8;\n}\n\n.ace_mobile-menu {\n    position: absolute;\n    line-height: 1.5;\n    border-radius: 4px;\n    -ms-user-select: none;\n    -moz-user-select: none;\n    -webkit-user-select: none;\n    user-select: none;\n    background: white;\n    box-shadow: 1px 3px 2px grey;\n    border: 1px solid #dcdcdc;\n    color: black;\n}\n.ace_dark > .ace_mobile-menu {\n    background: #333;\n    color: #ccc;\n    box-shadow: 1px 3px 2px grey;\n    border: 1px solid #444;\n\n}\n.ace_mobile-button {\n    padding: 2px;\n    cursor: pointer;\n    overflow: hidden;\n}\n.ace_mobile-button:hover {\n    background-color: #eee;\n    opacity:1;\n}\n.ace_mobile-button:active {\n    background-color: #ddd;\n}\n\n.ace_placeholder {\n    position: relative;\n    font-family: arial;\n    transform: scale(0.9);\n    transform-origin: left;\n    white-space: pre;\n    opacity: 0.7;\n    margin: 0 10px;\n    z-index: 1;\n}\n\n.ace_ghost_text {\n    opacity: 0.5;\n    font-style: italic;\n}\n\n.ace_ghost_text_container > div {\n    white-space: pre;\n}\n\n.ghost_text_line_wrapped::after {\n    content: \"↩\";\n    position: absolute;\n}\n\n.ace_lineWidgetContainer.ace_ghost_text {\n    margin: 0px 4px\n}\n\n.ace_screenreader-only {\n    position:absolute;\n    left:-10000px;\n    top:auto;\n    width:1px;\n    height:1px;\n    overflow:hidden;\n}\n\n.ace_hidden_token {\n    display: none;\n}`;\n"
  },
  {
    "path": "src/document.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"../ace-internal\").Ace.Delta} Delta\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.IRange} IRange\n * @typedef {import(\"../ace-internal\").Ace.NewLineMode} NewLineMode\n */\nvar oop = require(\"./lib/oop\");\nvar applyDelta = require(\"./apply_delta\").applyDelta;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Range = require(\"./range\").Range;\nvar Anchor = require(\"./anchor\").Anchor;\n\n/**\n * Contains the text of the document. Document can be attached to several [[EditSession `EditSession`]]s. \n * At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.\n **/\nclass Document {\n    /**\n     *\n     * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.\n     * @param {String | String[]} textOrLines text The starting text\n     **/\n    constructor(textOrLines) {\n        /**@type {string[]}*/\n        this.$lines = [\"\"];\n\n        // There has to be one line at least in the document. If you pass an empty\n        // string to the insert function, nothing will happen. Workaround.\n        if (textOrLines.length === 0) {\n            this.$lines = [\"\"];\n        } else if (Array.isArray(textOrLines)) {\n            this.insertMergedLines({row: 0, column: 0}, textOrLines);\n        } else {\n            this.insert({row: 0, column:0}, textOrLines);\n        }\n    }\n    \n    /**\n     * Replaces all the lines in the current `Document` with the value of `text`.\n     *\n     * @param {String} text The text to use\n     **/\n    setValue(text) {\n        var len = this.getLength() - 1;\n        this.remove(new Range(0, 0, len, this.getLine(len).length));\n        this.insert({row: 0, column: 0}, text || \"\");\n    }\n\n    /**\n     * Returns all the lines in the document as a single string, joined by the new line character.\n     * @returns {String}\n     **/\n   getValue() {\n        return this.getAllLines().join(this.getNewLineCharacter());\n    }\n\n    /** \n     * Creates a new `Anchor` to define a floating point in the document.\n     * @param {Number} row The row number to use\n     * @param {Number} column The column number to use\n     * @returns {Anchor}\n     **/\n    createAnchor(row, column) {\n        return new Anchor(this, row, column);\n    }\n\n    /**\n     * @param {string} text\n     */\n    $detectNewLine(text) {\n        var match = text.match(/^.*?(\\r\\n|\\r|\\n)/m);\n        this.$autoNewLine = match ? match[1] : \"\\n\";\n        this._signal(\"changeNewLineMode\");\n    }\n\n    /**\n     * Returns the newline character that's being used, depending on the value of `newLineMode`. \n     * @returns {String} If `newLineMode == windows`, `\\r\\n` is returned.  \n     *  If `newLineMode == unix`, `\\n` is returned.  \n     *  If `newLineMode == auto`, the value of `autoNewLine` is returned.\n     *\n     **/\n    getNewLineCharacter() {\n        switch (this.$newLineMode) {\n          case \"windows\":\n            return \"\\r\\n\";\n          case \"unix\":\n            return \"\\n\";\n          default:\n            return this.$autoNewLine || \"\\n\";\n        }\n    }\n\n    /**\n     * [Sets the new line mode.]{: #Document.setNewLineMode.desc}\n     * @param {NewLineMode} newLineMode [The newline mode to use; can be either `windows`, `unix`, or `auto`]\n     \n     **/\n    setNewLineMode(newLineMode) {\n        if (this.$newLineMode === newLineMode)\n            return;\n\n        this.$newLineMode = newLineMode;\n        this._signal(\"changeNewLineMode\");\n    }\n\n    /**\n     * Returns the type of newlines being used; either `windows`, `unix`, or `auto`\n     * @returns {NewLineMode}\n     **/\n    getNewLineMode() {\n        return this.$newLineMode;\n    }\n\n    /**\n     * Returns `true` if `text` is a newline character (either `\\r\\n`, `\\r`, or `\\n`).\n     * @param {String} text The text to check\n     * @returns {boolean}\n     **/\n    isNewLine(text) {\n        return (text == \"\\r\\n\" || text == \"\\r\" || text == \"\\n\");\n    }\n\n    /**\n     * Returns a verbatim copy of the given line as it is in the document\n     * @param {Number} row The row index to retrieve\n     * @returns {string}\n     **/\n    getLine(row) {\n        return this.$lines[row] || \"\";\n    }\n\n    /**\n     * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.\n     * @param {Number} firstRow The first row index to retrieve\n     * @param {Number} lastRow The final row index to retrieve\n     * @returns {string[]}\n     **/\n    getLines(firstRow, lastRow) {\n        return this.$lines.slice(firstRow, lastRow + 1);\n    }\n\n    /**\n     * Returns all lines in the document as string array.\n     * @returns {string[]}\n     **/\n    getAllLines() {\n        return this.getLines(0, this.getLength());\n    }\n\n    /**\n     * Returns the number of rows in the document.\n     * @returns {Number}\n     **/\n    getLength() {\n        return this.$lines.length;\n    }\n\n    /**\n     * Returns all the text within `range` as a single string.\n     * @param {IRange} range The range to work with.\n     * \n     * @returns {String}\n     **/\n    getTextRange(range) {\n        return this.getLinesForRange(range).join(this.getNewLineCharacter());\n    }\n    \n    /**\n     * Returns all the text within `range` as an array of lines.\n     * @param {IRange} range The range to work with.\n     * \n     * @returns {string[]}\n     **/\n    getLinesForRange(range) {\n        var lines;\n        if (range.start.row === range.end.row) {\n            // Handle a single-line range.\n            lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];\n        } else {\n            // Handle a multi-line range.\n            lines = this.getLines(range.start.row, range.end.row);\n            lines[0] = (lines[0] || \"\").substring(range.start.column);\n            var l = lines.length - 1;\n            if (range.end.row - range.start.row == l)\n                lines[l] = lines[l].substring(0, range.end.column);\n        }\n        return lines;\n    }\n\n    // Deprecated methods retained for backwards compatibility.\n    /**\n     * @param row\n     * @param lines\n     \n     * @deprecated\n     */\n    insertLines(row, lines) {\n        console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\");\n        return this.insertFullLines(row, lines);\n    }\n\n    /**\n     * @param firstRow\n     * @param lastRow\n     * @returns {String[]}\n     \n     * @deprecated\n     */\n    removeLines(firstRow, lastRow) {\n        console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\");\n        return this.removeFullLines(firstRow, lastRow);\n    }\n\n    /**\n     * @param position\n     * @returns {Point}\n     \n     * @deprecated\n     */\n    insertNewLine(position) {\n        console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\");\n        return this.insertMergedLines(position, [\"\", \"\"]);\n    }\n\n    /**\n     * Inserts a block of `text` at the indicated `position`.\n     * @param {Point} position The position to start inserting at; it's an object that looks like `{ row: row, column: column}`\n     * @param {String} text A chunk of text to insert\n     * @returns {Point} The position ({row, column}) of the last line of `text`. If the length of `text` is 0, this function simply returns `position`. \n     \n     **/\n    insert(position, text) {\n        // Only detect new lines if the document has no line break yet.\n        if (this.getLength() <= 1)\n            this.$detectNewLine(text);\n        \n        return this.insertMergedLines(position, this.$split(text));\n    }\n    \n    /**\n     * Inserts `text` into the `position` at the current row. This method also triggers the `\"change\"` event.\n     * \n     * This differs from the `insert` method in two ways:\n     *   1. This does NOT handle newline characters (single-line text only).\n     *   2. This is faster than the `insert` method for single-line text insertions.\n     * \n     * @param {Point} position The position to insert at; it's an object that looks like `{ row: row, column: column}`\n     * @param {String} text A chunk of text without new lines\n     * @returns {Point} Returns the position of the end of the inserted text\n     **/\n    insertInLine(position, text) {\n        var start = this.clippedPos(position.row, position.column);\n        var end = this.pos(position.row, position.column + text.length);\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"insert\",\n            lines: [text]\n        }, true);\n        \n        return this.clonePos(end);\n    }\n\n    /**\n     * \n     * @param {number} row\n     * @param {number} column\n     * @return {Point}\n     */\n    clippedPos(row, column) {\n        var length = this.getLength();\n        if (row === undefined) {\n            row = length;\n        } else if (row < 0) {\n            row = 0;\n        } else if (row >= length) {\n            row = length - 1;\n            column = undefined;\n        }\n        var line = this.getLine(row);\n        if (column == undefined)\n            column = line.length;\n        column = Math.min(Math.max(column, 0), line.length);\n        return {row: row, column: column};\n    }\n\n    /**\n     * @param {Point} pos\n     * @return {Point}\n     */\n    clonePos(pos) {\n        return {row: pos.row, column: pos.column};\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @return {Point}\n     */\n    pos(row, column) {\n        return {row: row, column: column};\n    }\n\n    /**\n     * @param {Point} position\n     * @return {Point}\n     * @private\n     */\n    $clipPosition(position) {\n        var length = this.getLength();\n        if (position.row >= length) {\n            position.row = Math.max(0, length - 1);\n            position.column = this.getLine(length - 1).length;\n        } else {\n            position.row = Math.max(0, position.row);\n            position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);\n        }\n        return position;\n    }\n    \n    /**\n     * Inserts the elements in `lines` into the document as full lines (does not merge with existing line), starting at the row index given by `row`. This method also triggers the `\"change\"` event.\n     * @param {Number} row The index of the row to insert at\n     * @param {string[]} lines An array of strings\n     \n     **/\n    insertFullLines(row, lines) {\n        // Clip to document.\n        // Allow one past the document end.\n        row = Math.min(Math.max(row, 0), this.getLength());\n        \n        // Calculate insertion point.\n        var column = 0;\n        if (row < this.getLength()) {\n            // Insert before the specified row.\n            lines = lines.concat([\"\"]);\n            column = 0;\n        } else {\n            // Insert after the last row in the document.\n            lines = [\"\"].concat(lines);\n            row--;\n            column = this.$lines[row].length;\n        }\n        \n        // Insert.\n        this.insertMergedLines({row: row, column: column}, lines);\n    }\n\n    /**\n     * Inserts the elements in `lines` into the document, starting at the position index given by `row`. This method also triggers the `\"change\"` event.\n     * @param {Point} position\n     * @param {string[]} lines An array of strings\n     * @returns {Point} Contains the final row and column, like this:  \n     *   ```\n     *   {row: endRow, column: 0}\n     *   ```  \n     *   If `lines` is empty, this function returns an object containing the current row, and column, like this:  \n     *   ``` \n     *   {row: row, column: 0}\n     *   ```\n     **/    \n    insertMergedLines(position, lines) {\n        var start = this.clippedPos(position.row, position.column);\n        var end = {\n            row: start.row + lines.length - 1,\n            column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length\n        };\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"insert\",\n            lines: lines\n        });\n        \n        return this.clonePos(end);\n    }\n\n    /**\n     * Removes the `range` from the document.\n     * @param {IRange} range A specified Range to remove\n     * @returns {Point} Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.\n     \n     **/\n    remove(range) {\n        var start = this.clippedPos(range.start.row, range.start.column);\n        var end = this.clippedPos(range.end.row, range.end.column);\n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"remove\",\n            lines: this.getLinesForRange({start: start, end: end})\n        });\n        return this.clonePos(start);\n    }\n\n    /**\n     * Removes the specified columns from the `row`. This method also triggers a `\"change\"` event.\n     * @param {Number} row The row to remove from\n     * @param {Number} startColumn The column to start removing at \n     * @param {Number} endColumn The column to stop removing at\n     * @returns {Point} Returns an object containing `startRow` and `startColumn`, indicating the new row and column values.<br/>If `startColumn` is equal to `endColumn`, this function returns nothing.\n     \n     **/\n    removeInLine(row, startColumn, endColumn) {\n        var start = this.clippedPos(row, startColumn);\n        var end = this.clippedPos(row, endColumn);\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"remove\",\n            lines: this.getLinesForRange({start: start, end: end})\n        }, true);\n        \n        return this.clonePos(start);\n    }\n\n    /**\n     * Removes a range of full lines. This method also triggers the `\"change\"` event.\n     * @param {Number} firstRow The first row to be removed\n     * @param {Number} lastRow The last row to be removed\n     * @returns {String[]} Returns all the removed lines.\n     \n     **/\n    removeFullLines(firstRow, lastRow) {\n        // Clip to document.\n        firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);\n        lastRow  = Math.min(Math.max(0, lastRow ), this.getLength() - 1);\n        \n        // Calculate deletion range.\n        // Delete the ending new line unless we're at the end of the document.\n        // If we're at the end of the document, delete the starting new line.\n        var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;\n        var deleteLastNewLine  = lastRow  < this.getLength() - 1;\n        var startRow = ( deleteFirstNewLine ? firstRow - 1                  : firstRow                    );\n        var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0                           );\n        var endRow   = ( deleteLastNewLine  ? lastRow + 1                   : lastRow                     );\n        var endCol   = ( deleteLastNewLine  ? 0                             : this.getLine(endRow).length ); \n        var range = new Range(startRow, startCol, endRow, endCol);\n        \n        // Store delelted lines with bounding newlines ommitted (maintains previous behavior).\n        var deletedLines = this.$lines.slice(firstRow, lastRow + 1);\n        \n        this.applyDelta({\n            start: range.start,\n            end: range.end,\n            action: \"remove\",\n            lines: this.getLinesForRange(range)\n        });\n        \n        // Return the deleted lines.\n        return deletedLines;\n    }\n\n    /**\n     * Removes the new line between `row` and the row immediately following it. This method also triggers the `\"change\"` event.\n     * @param {Number} row The row to check\n     *\n     **/\n    removeNewLine(row) {\n        if (row < this.getLength() - 1 && row >= 0) {\n            this.applyDelta({\n                start: this.pos(row, this.getLine(row).length),\n                end: this.pos(row + 1, 0),\n                action: \"remove\",\n                lines: [\"\", \"\"]\n            });\n        }\n    }\n\n    /**\n     * Replaces a range in the document with the new `text`.\n     * @param {Range | IRange} range A specified Range to replace\n     * @param {String} text The new text to use as a replacement\n     * @returns {Point} Returns an object containing the final row and column, like this:\n     *     {row: endRow, column: 0}\n     * If the text and range are empty, this function returns an object containing the current `range.start` value.\n     * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.\n     *\n     **/\n    replace(range, text) {\n        if (!(range instanceof Range))\n            range = Range.fromPoints(range.start, range.end);\n        // @ts-expect-error\n        if (text.length === 0 && range.isEmpty())\n            return range.start;\n\n        // Shortcut: If the text we want to insert is the same as it is already\n        // in the document, we don't have to replace anything.\n        if (text == this.getTextRange(range))\n            return range.end;\n\n        this.remove(range);\n        var end;\n        if (text) {\n            end = this.insert(range.start, text);\n        }\n        else {\n            end = range.start;\n        }\n        \n        return end;\n    }\n\n    /**\n     * Applies all changes in `deltas` to the document.\n     * @param {Delta[]} deltas An array of delta objects (can include \"insert\" and \"remove\" actions)\n     **/\n    applyDeltas(deltas) {\n        for (var i=0; i<deltas.length; i++) {\n            this.applyDelta(deltas[i]);\n        }\n    }\n    \n    /**\n     * Reverts all changes in `deltas` from the document.\n     * @param {Delta[]} deltas An array of delta objects (can include \"insert\" and \"remove\" actions)\n     **/\n    revertDeltas(deltas) {\n        for (var i=deltas.length-1; i>=0; i--) {\n            this.revertDelta(deltas[i]);\n        }\n    }\n    \n    /**\n     * Applies `delta` to the document.\n     * @param {Delta} delta A delta object (can include \"insert\" and \"remove\" actions)\n     * @param {boolean} [doNotValidate]\n     **/\n    applyDelta(delta, doNotValidate) {\n        var isInsert = delta.action == \"insert\";\n        // An empty range is a NOOP.\n        if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]\n            : !Range.comparePoints(delta.start, delta.end)) {\n            return;\n        }\n        \n        if (isInsert && delta.lines.length > 20000) {\n            this.$splitAndapplyLargeDelta(delta, 20000);\n        }\n        else {\n            applyDelta(this.$lines, delta, doNotValidate);\n            this._signal(\"change\", delta);\n        }\n    }\n\n    /**\n     * @param {Delta} delta\n     */\n    $safeApplyDelta(delta) {\n        var docLength = this.$lines.length;\n        // verify that delta is in the document to prevent applyDelta from corrupting lines array \n        if (\n            delta.action == \"remove\" && delta.start.row < docLength && delta.end.row < docLength\n            || delta.action == \"insert\" && delta.start.row <= docLength\n        ) {\n            this.applyDelta(delta);\n        }\n    }\n\n    /**\n     * \n     * @param {Delta} delta\n     * @param {number} MAX\n     */\n    $splitAndapplyLargeDelta(delta, MAX) {\n        // Split large insert deltas. This is necessary because:\n        //    1. We need to support splicing delta lines into the document via $lines.splice.apply(...)\n        //    2. fn.apply() doesn't work for a large number of params. The smallest threshold is on chrome 40 ~42000.\n        // we use 20000 to leave some space for actual stack\n        // \n        // To Do: Ideally we'd be consistent and also split 'delete' deltas. We don't do this now, because delete\n        //        delta handling is too slow. If we make delete delta handling faster we can split all large deltas\n        //        as shown in https://gist.github.com/aldendaniels/8367109#file-document-snippet-js\n        //        If we do this, update validateDelta() to limit the number of lines in a delete delta.\n        var lines = delta.lines;\n        var l = lines.length - MAX + 1;\n        var row = delta.start.row; \n        var column = delta.start.column;\n        for (var from = 0, to = 0; from < l; from = to) {\n            to += MAX - 1;\n            var chunk = lines.slice(from, to);\n            chunk.push(\"\");\n            this.applyDelta({\n                start: this.pos(row + from, column),\n                end: this.pos(row + to, column = 0),\n                action: delta.action,\n                lines: chunk\n            }, true);\n        }\n        // Update remaining delta.\n        delta.lines = lines.slice(from);\n        delta.start.row = row + from;\n        delta.start.column = column;\n        this.applyDelta(delta, true);\n    }\n    \n    /**\n     * Reverts `delta` from the document.\n     * @param {Delta} delta A delta object (can include \"insert\" and \"remove\" actions)\n     **/\n    revertDelta(delta) {\n        this.$safeApplyDelta({\n            start: this.clonePos(delta.start),\n            end: this.clonePos(delta.end),\n            action: (delta.action == \"insert\" ? \"remove\" : \"insert\"),\n            lines: delta.lines.slice()\n        });\n    }\n    \n    /**\n     * Converts an index position in a document to a `{row, column}` object.\n     *\n     * Index refers to the \"absolute position\" of a character in the document. For example:\n     *\n     * ```javascript\n     * var x = 0; // 10 characters, plus one for newline\n     * var y = -1;\n     * ```\n     * \n     * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second.\n     *\n     * @param {Number} index An index to convert\n     * @param {Number} [startRow=0] The row from which to start the conversion\n     * @returns {Point} A `{row, column}` object of the `index` position\n     */\n    indexToPosition(index, startRow) {\n        var lines = this.$lines || this.getAllLines();\n        var newlineLength = this.getNewLineCharacter().length;\n        for (var i = startRow || 0, l = lines.length; i < l; i++) {\n            index -= lines[i].length + newlineLength;\n            if (index < 0)\n                return {row: i, column: index + lines[i].length + newlineLength};\n        }\n        return {row: l-1, column: index + lines[l-1].length + newlineLength};\n    }\n\n    /**\n     * Converts the `{row, column}` position in a document to the character's index.\n     *\n     * Index refers to the \"absolute position\" of a character in the document. For example:\n     *\n     * ```javascript\n     * var x = 0; // 10 characters, plus one for newline\n     * var y = -1;\n     * ```\n     * \n     * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second.\n     *\n     * @param {Point} pos The `{row, column}` to convert\n     * @param {Number} [startRow=0] The row from which to start the conversion\n     * @returns {Number} The index position in the document\n     */\n    positionToIndex(pos, startRow) {\n        var lines = this.$lines || this.getAllLines();\n        var newlineLength = this.getNewLineCharacter().length;\n        var index = 0;\n        var row = Math.min(pos.row, lines.length);\n        for (var i = startRow || 0; i < row; ++i)\n            index += lines[i].length + newlineLength;\n\n        return index + pos.column;\n    }\n\n    /**\n     * Splits a string of text on any newline (`\\n`) or carriage-return (`\\r`) characters.\n     *\n     * @method $split\n     * @param {String} text The text to work with\n     * @returns {String[]} A String array, with each index containing a piece of the original `text` string.\n     *\n     **/\n    $split(text) {\n        return text.split(/\\r\\n|\\r|\\n/);\n    }\n}\n\nDocument.prototype.$autoNewLine = \"\";\nDocument.prototype.$newLineMode = \"auto\";\n\noop.implement(Document.prototype, EventEmitter);\n\nexports.Document = Document;\n"
  },
  {
    "path": "src/document_test.js",
    "content": "\"use strict\";\n\nvar Document = require(\"./document\").Document;\nvar Range = require(\"./range\").Range;\nvar assert = require(\"./test/assertions\");\n\nmodule.exports = {\n\n    \"test: insert text in line\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insert({row: 0, column: 1}, \"juhu\");\n        assert.equal(doc.getValue(), [\"1juhu2\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"1juhu2\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: insert new line\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insertMergedLines({row: 0, column: 1}, ['', '']);\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: insert lines at the beginning\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insertFullLines(0, [\"aa\", \"bb\"]);\n        assert.equal(doc.getValue(), [\"aa\", \"bb\", \"12\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"aa\", \"bb\", \"12\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: insert lines at the end\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insertFullLines(2, [\"aa\", \"bb\"]);\n        assert.equal(doc.getValue(), [\"12\", \"34\", \"aa\", \"bb\"].join(\"\\n\"));\n    },\n    \n    \"test: insertInLine\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insertInLine({row: 0, column: 1}, \"a\");\n        assert.equal(doc.getValue(), [\"1a2\", \"34\"].join(\"\\n\"));\n        doc.insertInLine({row: 10, column: Infinity}, \"b\");\n        assert.equal(doc.getValue(), [\"1a2\", \"34b\"].join(\"\\n\"));\n        doc.insertInLine({row: undefined, column: Infinity}, \"x\");\n        assert.equal(doc.getValue(), [\"1a2\", \"34b\", \"x\"].join(\"\\n\"));\n        doc.insertInLine({row: -1, column: Infinity}, \"z\");\n        assert.equal(doc.getValue(), [\"1a2z\", \"34b\", \"x\"].join(\"\\n\"));\n        \n        doc.removeInLine(0, 1, 2);\n        assert.equal(doc.getValue(), [\"12z\", \"34b\", \"x\"].join(\"\\n\"));\n        doc.removeInLine(0, 2, 10);\n        assert.equal(doc.getValue(), [\"12\", \"34b\", \"x\"].join(\"\\n\"));\n        doc.removeNewLine(1);\n        assert.equal(doc.getValue(), [\"12\", \"34bx\"].join(\"\\n\"));\n        doc.removeNewLine(1);\n        assert.equal(doc.getValue(), [\"12\", \"34bx\"].join(\"\\n\"));\n    },\n\n    \"test: insert lines in the middle\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insertFullLines(1, [\"aa\", \"bb\"]);\n        assert.equal(doc.getValue(), [\"12\", \"aa\", \"bb\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"aa\", \"bb\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: insert multi line string at the start\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insert({row: 0, column: 0}, \"aa\\nbb\\ncc\");\n        assert.equal(doc.getValue(), [\"aa\", \"bb\", \"cc12\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"aa\", \"bb\", \"cc12\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: insert multi line string at the end\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insert({row: 1, column: 2}, \"aa\\nbb\\ncc\");\n        assert.equal(doc.getValue(), [\"12\", \"34aa\", \"bb\", \"cc\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34aa\", \"bb\", \"cc\"].join(\"\\n\"));\n    },\n\n    \"test: insert multi line string in the middle\" : function() {\n        var doc = new Document([\"12\", \"34\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.insert({row: 0, column: 1}, \"aa\\nbb\\ncc\");\n        assert.equal(doc.getValue(), [\"1aa\", \"bb\", \"cc2\", \"34\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"12\", \"34\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"1aa\", \"bb\", \"cc2\", \"34\"].join(\"\\n\"));\n    },\n\n    \"test: delete in line\" : function() {\n        var doc = new Document([\"1234\", \"5678\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.remove(new Range(0, 1, 0, 3));\n        assert.equal(doc.getValue(), [\"14\", \"5678\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"1234\", \"5678\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"14\", \"5678\"].join(\"\\n\"));\n    },\n\n    \"test: delete new line\" : function() {\n        var doc = new Document([\"1234\", \"5678\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.remove(new Range(0, 4, 1, 0));\n        assert.equal(doc.getValue(), [\"12345678\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"1234\", \"5678\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"12345678\"].join(\"\\n\"));\n    },\n\n    \"test: delete multi line range line\" : function() {\n        var doc = new Document([\"1234\", \"5678\", \"abcd\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.remove(new Range(0, 2, 2, 2));\n        assert.equal(doc.getValue(), [\"12cd\"].join(\"\\n\"));\n\n        var d = deltas.concat();\n        doc.revertDeltas(d);\n        assert.equal(doc.getValue(), [\"1234\", \"5678\", \"abcd\"].join(\"\\n\"));\n\n        doc.applyDeltas(d);\n        assert.equal(doc.getValue(), [\"12cd\"].join(\"\\n\"));\n    },\n\n    \"test: delete full lines\" : function() {\n        var doc = new Document([\"1234\", \"5678\", \"abcd\"]);\n\n        var deltas = [];\n        doc.on(\"change\", function(e) { deltas.push(e); });\n\n        doc.remove(new Range(1, 0, 3, 0));\n        assert.equal(doc.getValue(), [\"1234\", \"\"].join(\"\\n\"));\n    },\n\n    \"test: remove lines should return the removed lines\" : function() {\n        var doc = new Document([\"1234\", \"5678\", \"abcd\"]);\n\n        var removed = doc.removeFullLines(1, 2);\n        assert.equal(removed.join(\"\\n\"), [\"5678\", \"abcd\"].join(\"\\n\"));\n    },\n\n    \"test: should handle unix style new lines\" : function() {\n        var doc = new Document([\"1\", \"2\", \"3\"]);\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\n\"));\n    },\n\n    \"test: should handle windows style new lines\" : function() {\n        var doc = new Document([\"1\", \"2\", \"3\"].join(\"\\r\\n\"));\n\n        doc.setNewLineMode(\"unix\");\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\n\"));\n        assert.equal(doc.getNewLineMode(), \"unix\");\n        assert.ok(doc.isNewLine(\"\\r\"));\n        assert.ok(doc.isNewLine(\"\\n\"));\n        assert.ok(doc.isNewLine(\"\\r\\n\"));\n        assert.notOk(doc.isNewLine(\"\\n\\r\"));\n    },\n\n    \"test: set new line mode to 'windows' should use '\\\\r\\\\n' as new lines\": function() {\n        var doc = new Document([\"1\", \"2\", \"3\"].join(\"\\n\"));\n        doc.setNewLineMode(\"windows\");\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\r\\n\"));\n    },\n\n    \"test: set new line mode to 'unix' should use '\\\\n' as new lines\": function() {\n        var doc = new Document([\"1\", \"2\", \"3\"].join(\"\\r\\n\"));\n\n        doc.setNewLineMode(\"unix\");\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\n\"));\n    },\n\n    \"test: set new line mode to 'auto' should detect the incoming nl type\": function() {\n        var doc = new Document([\"1\", \"2\", \"3\"].join(\"\\n\"));\n\n        doc.setNewLineMode(\"auto\");\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\n\"));\n\n        var doc = new Document([\"1\", \"2\", \"3\"].join(\"\\r\\n\"));\n\n        doc.setNewLineMode(\"auto\");\n        assert.equal(doc.getValue(), [\"1\", \"2\", \"3\"].join(\"\\r\\n\"));\n\n        doc.replace(new Range(0, 0, 2, 1), [\"4\", \"5\", \"6\"].join(\"\\n\"));\n        assert.equal([\"4\", \"5\", \"6\"].join(\"\\n\"), doc.getValue());\n    },\n\n    \"test: set value\": function() {\n        var doc = new Document(\"1\");\n        assert.equal(\"1\", doc.getValue());\n\n        doc.setValue(doc.getValue());\n        assert.equal(\"1\", doc.getValue());\n\n        var doc = new Document(\"1\\n2\");\n        assert.equal(\"1\\n2\", doc.getValue());\n\n        doc.setValue(doc.getValue());\n        assert.equal(\"1\\n2\", doc.getValue());\n    },\n\n    \"test: empty document has to contain one line\": function() {\n        var doc = new Document(\"\");\n        assert.equal(doc.$lines.length, 1);\n    },\n    \n    \"test: ignore empty delta\": function() {\n        var doc = new Document(\"\");\n        doc.on(\"change\", function() {\n            throw \"should ignore empty delta\";\n        });\n        doc.insert({row: 0, column: 0}, \"\");\n        doc.insert({row: 1, column: 1}, \"\");\n        doc.remove({start: {row: 1, column: 1}, end: {row: 1, column: 1}});\n    },\n    \n    \"test: inserting huge delta\": function() {\n        var doc = new Document(\"\");\n        var val = \"\";\n        var MAX = 20000 - 1;\n        for (var i = 0; i < 4 * MAX; i++) {\n            val += i + \"\\n\";\n        }\n        var changeCount = 0;\n        function testDelta(delta) {\n            changeCount++;\n            assert.equal(delta.lines.length, MAX + 1);\n        }\n        doc.on(\"change\", testDelta);\n        doc.setValue(val);\n        doc.off(\"change\", testDelta);\n        assert.equal(changeCount, 4);\n        assert.equal(doc.getValue(), val);\n        \n        for (var i = 2 * MAX + 20; i >= 2 * MAX - 20; i--) {\n            val = doc.getLines(0, i).join(\"\\n\");\n            doc.setValue(\"\\nab\");\n            assert.equal(doc.getValue(), \"\\nab\");\n            doc.insert({row: 1, column: 1}, val);\n            assert.equal(doc.getValue(), \"\\na\" + val + \"b\");\n        }\n    },\n    \n    \"test: indexToPosition\": function() {\n        function test(value) {\n            var doc = new Document(value);\n            var secondLine = value.indexOf(\"|\");\n            for (var i = -2; i < value.length + 4; i++) {\n                if (value[i - 1] == \"\\r\") continue;\n                var pos = doc.indexToPosition(i);\n                var text = doc.getTextRange({start: {row: 0, column: 0}, end: pos});\n                assert.equal(text, value.substring(0, i));\n                assert.equal(doc.positionToIndex(pos), i);\n                if (i >= secondLine) {\n                    assert.deepEqual(doc.indexToPosition(i - secondLine, 1), pos);\n                    assert.equal(doc.positionToIndex(pos, 1), i - secondLine);\n                }\n            }\n        }\n        test(\"abc\\n|defx\\ngh\");\n        test(\"abc\\r\\n|defx\\r\\ngh\");\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/edit_session/bracket_match.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n * @typedef {import(\"../edit_session\").Point} Point\n */\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar Range = require(\"../range\").Range;\n\nfunction BracketMatch() {\n\n    /**\n     * \n     * @param {Point} position\n     * @param {string} [chr]\n     * @this {EditSession}\n     */\n    this.findMatchingBracket = function(position, chr) {\n        if (position.column == 0) return null;\n\n        var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);\n        if (charBeforeCursor == \"\") return null;\n\n        var match = charBeforeCursor.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        if (!match)\n            return null;\n\n        if (match[1])\n            return this.$findClosingBracket(match[1], position);\n        else\n            return this.$findOpeningBracket(match[2], position);\n    };\n\n    /**\n     * @param {Point} pos\n     * @return {null|Range}\n     * @this {EditSession}\n     */\n    this.getBracketRange = function(pos) {\n        var line = this.getLine(pos.row);\n        var before = true, range;\n\n        var chr = line.charAt(pos.column - 1);\n        var match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        if (!match) {\n            chr = line.charAt(pos.column);\n            pos = {row: pos.row, column: pos.column + 1};\n            match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n            before = false;\n        }\n        if (!match)\n            return null;\n\n        if (match[1]) {\n            var bracketPos = this.$findClosingBracket(match[1], pos);\n            if (!bracketPos)\n                return null;\n            range = Range.fromPoints(pos, bracketPos);\n            if (!before) {\n                range.end.column++;\n                range.start.column--;\n            }\n            range.cursor = range.end;\n        } else {\n            var bracketPos = this.$findOpeningBracket(match[2], pos);\n            if (!bracketPos)\n                return null;\n            range = Range.fromPoints(bracketPos, pos);\n            if (!before) {\n                range.start.column++;\n                range.end.column--;\n            }\n            range.cursor = range.start;\n        }\n        \n        return range;\n    };\n\n    /**\n     * Returns:\n     * * null if there is no any bracket at `pos`;\n     * * two Ranges if there is opening and closing brackets;\n     * * one Range if there is only one bracket\n     *\n     * @param {Point} pos\n     * @param {boolean} [isBackwards]\n     * @returns {null|Range[]}\n     * @this {EditSession}\n     */\n    this.getMatchingBracketRanges = function(pos, isBackwards) {\n        var line = this.getLine(pos.row);\n        var bracketsRegExp = /([\\(\\[\\{])|([\\)\\]\\}])/;\n        var chr = !isBackwards && line.charAt(pos.column - 1);\n        var match = chr && chr.match(bracketsRegExp);\n        if (!match) {\n            chr = (isBackwards === undefined || isBackwards) && line.charAt(pos.column);\n            pos = {\n                row: pos.row,\n                column: pos.column + 1\n            };\n            match = chr && chr.match(bracketsRegExp);\n        }\n\n        if (!match)\n            return null;\n\n        var startRange = new Range(pos.row, pos.column - 1, pos.row, pos.column);\n        var bracketPos = match[1] ? this.$findClosingBracket(match[1], pos)\n            : this.$findOpeningBracket(match[2], pos);\n        if (!bracketPos)\n            return [startRange];\n        var endRange = new Range(bracketPos.row, bracketPos.column, bracketPos.row, bracketPos.column + 1);\n\n        return [startRange, endRange];\n    };\n\n    this.$brackets = {\n        \")\": \"(\",\n        \"(\": \")\",\n        \"]\": \"[\",\n        \"[\": \"]\",\n        \"{\": \"}\",\n        \"}\": \"{\",\n        \"<\": \">\",\n        \">\": \"<\"\n    };\n\n    /**\n     * \n     * @param {string} bracket\n     * @param {Point} position\n     * @param {RegExp} [typeRe]\n     * @return {Point|null}\n     * @this {EditSession}\n     */\n    this.$findOpeningBracket = function(bracket, position, typeRe) {\n        var openBracket = this.$brackets[bracket];\n        var depth = 1;\n\n        var iterator = new TokenIterator(this, position.row, position.column);\n        var token = iterator.getCurrentToken();\n        if (!token)\n            token = iterator.stepForward();\n        if (!token)\n            return;\n        \n         if (!typeRe){\n            typeRe = new RegExp(\n                \"(\\\\.?\" +\n                token.type.replace(\".\", \"\\\\.\").replace(\"rparen\", \".paren\")\n                    .replace(/\\b(?:end)\\b/, \"(?:start|begin|end)\")\n                    .replace(/-close\\b/, \"-(close|open)\")\n                + \")+\"\n            );\n        }\n        \n        // Start searching in token, just before the character at position.column\n        var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;\n        var value = token.value;\n        \n        while (true) {\n        \n            while (valueIndex >= 0) {\n                var chr = value.charAt(valueIndex);\n                if (chr == openBracket) {\n                    depth -= 1;\n                    if (depth == 0) {\n                        return {row: iterator.getCurrentTokenRow(),\n                            column: valueIndex + iterator.getCurrentTokenColumn()};\n                    }\n                }\n                else if (chr == bracket) {\n                    depth += 1;\n                }\n                valueIndex -= 1;\n            }\n\n            // Scan backward through the document, looking for the next token\n            // whose type matches typeRe\n            do {\n                token = iterator.stepBackward();\n            } while (token && !typeRe.test(token.type));\n\n            if (token == null)\n                break;\n                \n            value = token.value;\n            valueIndex = value.length - 1;\n        }\n        \n        return null;\n    };\n\n    /**\n     *\n     * @param {string} bracket\n     * @param {Point} position\n     * @param {RegExp} [typeRe]\n     * @return {Point|null}\n     * @this {EditSession}\n     */\n    this.$findClosingBracket = function(bracket, position, typeRe) {\n        var closingBracket = this.$brackets[bracket];\n        var depth = 1;\n\n        var iterator = new TokenIterator(this, position.row, position.column);\n        var token = iterator.getCurrentToken();\n        if (!token)\n            token = iterator.stepForward();\n        if (!token)\n            return;\n\n        if (!typeRe){\n            typeRe = new RegExp(\n                \"(\\\\.?\" +\n                token.type.replace(\".\", \"\\\\.\").replace(\"lparen\", \".paren\")\n                    .replace(/\\b(?:start|begin)\\b/, \"(?:start|begin|end)\")\n                    .replace(/-open\\b/, \"-(close|open)\")\n                + \")+\"\n            );\n        }\n\n        // Start searching in token, after the character at position.column\n        var valueIndex = position.column - iterator.getCurrentTokenColumn();\n\n        while (true) {\n\n            var value = token.value;\n            var valueLength = value.length;\n            while (valueIndex < valueLength) {\n                var chr = value.charAt(valueIndex);\n                if (chr == closingBracket) {\n                    depth -= 1;\n                    if (depth == 0) {\n                        return {row: iterator.getCurrentTokenRow(),\n                            column: valueIndex + iterator.getCurrentTokenColumn()};\n                    }\n                }\n                else if (chr == bracket) {\n                    depth += 1;\n                }\n                valueIndex += 1;\n            }\n\n            // Scan forward through the document, looking for the next token\n            // whose type matches typeRe\n            do {\n                token = iterator.stepForward();\n            } while (token && !typeRe.test(token.type));\n\n            if (token == null)\n                break;\n\n            valueIndex = 0;\n        }\n        \n        return null;\n    };\n\n    /**\n     * Returns [[Range]]'s for matching tags and tag names, if there are any\n     * @param {Point} pos\n     * @returns {{closeTag: Range, closeTagName: Range, openTag: Range, openTagName: Range} | undefined}\n     * @this {EditSession}\n     */\n    this.getMatchingTags = function (pos) {\n        var iterator = new TokenIterator(this, pos.row, pos.column);\n        var token = this.$findTagName(iterator);\n        if (!token) return;\n\n        var prevToken = iterator.stepBackward();\n\n        if (prevToken.value === '<') {\n            return this.$findClosingTag(iterator, token);\n        }\n        else {\n            return this.$findOpeningTag(iterator, token);\n        }\n    };\n\n    this.$findTagName = function (iterator) {\n        var token = iterator.getCurrentToken();\n        var found = false;\n        var backward = false;\n        if (token && token.type.indexOf('tag-name') === -1) {\n            do {\n                if (backward) token = iterator.stepBackward(); else token = iterator.stepForward();\n                if (token) {\n                    if (token.value === \"/>\") {\n                        //changing iterator direction for self-closing tags, when cursor is in between tag\n                        //name and tag closing\n                        backward = true;\n                    }\n                    else if (token.type.indexOf('tag-name') !== -1) {\n                        found = true;\n                    }\n                }\n            } while (token && !found);\n        }\n        return token;\n    };\n\n    this.$findClosingTag = function (iterator, token) {\n        var prevToken;\n        var currentTag = token.value;\n        var tag = token.value;\n        var depth = 0;\n\n        var openTagStart = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n            iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1\n        );\n        token = iterator.stepForward();\n        var openTagName = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n            iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + token.value.length\n        );\n        var foundOpenTagEnd = false;\n        do {\n            prevToken = token;\n            if (prevToken.type.indexOf('tag-close') !== -1 && !foundOpenTagEnd) {\n                var openTagEnd = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n                    iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1\n                ); //Range for `>`\n                foundOpenTagEnd = true;\n            }\n            token = iterator.stepForward();\n            if (token) {\n                if (token.value === '>' && !foundOpenTagEnd) {\n                    var openTagEnd = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n                        iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1\n                    ); //Range for `>`\n                    foundOpenTagEnd = true;\n                }\n                if (token.type.indexOf('tag-name') !== -1) {\n                    currentTag = token.value;\n                    if (tag === currentTag) {\n                        if (prevToken.value === '<') {\n                            depth++;\n                        }\n                        else if (prevToken.value === '</') {\n                            depth--;\n                            if (depth < 0) {//found closing tag\n                                iterator.stepBackward();\n                                var closeTagStart = new Range(iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn(), iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn() + 2\n                                ); //Range for </\n                                token = iterator.stepForward();\n                                var closeTagName = new Range(iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn(), iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn() + token.value.length\n                                );\n                                if (token.type.indexOf('tag-close') === -1) {\n                                    token = iterator.stepForward();\n                                }\n                                if (token && token.value === '>') {\n                                    var closeTagEnd = new Range(iterator.getCurrentTokenRow(),\n                                        iterator.getCurrentTokenColumn(), iterator.getCurrentTokenRow(),\n                                        iterator.getCurrentTokenColumn() + 1\n                                    ); //Range for >\n                                }\n                                else {\n                                    return;\n                                }\n                            }\n                        }\n                    }\n                }\n                else if (tag === currentTag && token.value === '/>') { // self-closing tag\n                    depth--;\n                    if (depth < 0) {//found self-closing tag end\n                        //Example: <tagName attr/>\n                        //`<tagName ` - opening part of tag consist of `openTagStart`, `openTagName` and `openTagEnd`\n                        //`/>` - closing part of tag consist of `closeTagStart`, `closeTagName` and `closeTagEnd`\n                        var closeTagStart = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n                            iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 2\n                        );\n                        var closeTagName = closeTagStart;\n                        var closeTagEnd = closeTagName;\n\n                        var openTagEnd = new Range(openTagName.end.row, openTagName.end.column, openTagName.end.row,\n                            openTagName.end.column + 1\n                        );\n\n                    }\n                }\n            }\n        } while (token && depth >= 0);\n\n        if (openTagStart && openTagEnd && closeTagStart && closeTagEnd && openTagName && closeTagName) {\n            return {\n                openTag: new Range(openTagStart.start.row, openTagStart.start.column, openTagEnd.end.row,\n                    openTagEnd.end.column\n                ),\n                closeTag: new Range(closeTagStart.start.row, closeTagStart.start.column, closeTagEnd.end.row,\n                    closeTagEnd.end.column\n                ),\n                openTagName: openTagName,\n                closeTagName: closeTagName\n            };\n        }\n    };\n\n    this.$findOpeningTag = function (iterator, token) {\n        var prevToken = iterator.getCurrentToken();\n        var tag = token.value;\n        var depth = 0;\n\n        var startRow = iterator.getCurrentTokenRow();\n        var startColumn = iterator.getCurrentTokenColumn();\n        var endColumn = startColumn + 2;\n\n        //closing tag\n        var closeTagStart = new Range(startRow, startColumn, startRow, endColumn); //Range for </\n        iterator.stepForward();\n        var closeTagName = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n            iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + token.value.length\n        );\n\n        if (token.type.indexOf('tag-close') === -1) {\n            token = iterator.stepForward();\n        }\n        if (!token || token.value !== \">\") return;\n        var closeTagEnd = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn(),\n            iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1\n        ); //Range for >\n\n        iterator.stepBackward();\n        iterator.stepBackward();\n        do {\n            token = prevToken;\n            startRow = iterator.getCurrentTokenRow();\n            startColumn = iterator.getCurrentTokenColumn();\n            endColumn = startColumn + token.value.length;\n\n            prevToken = iterator.stepBackward();\n\n            if (token) {\n                if (token.type.indexOf('tag-name') !== -1) {\n                    if (tag === token.value) {\n                        if (prevToken.value === '<') {\n                            depth++;\n                            if (depth > 0) {//found opening tag\n                                var openTagName = new Range(startRow, startColumn, startRow, endColumn);\n                                var openTagStart = new Range(iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn(), iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn() + 1\n                                ); //Range for <\n                                do {\n                                    token = iterator.stepForward();\n                                } while (token && token.value !== '>');\n                                var openTagEnd = new Range(iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn(), iterator.getCurrentTokenRow(),\n                                    iterator.getCurrentTokenColumn() + 1\n                                ); //Range for >\n                            }\n                        }\n                        else if (prevToken.value === '</') {\n                            depth--;\n                        }\n                    }\n                }\n                else if (token.value === '/>') { // self-closing tag\n                    var stepCount = 0;\n                    var tmpToken = prevToken;\n                    while (tmpToken) {\n                        if (tmpToken.type.indexOf('tag-name') !== -1 && tmpToken.value === tag) {\n                            depth--;\n                            break;\n                        }\n                        else if (tmpToken.value === '<') {\n                            break;\n                        }\n                        tmpToken = iterator.stepBackward();\n                        stepCount++;\n                    }\n                    for (var i = 0; i < stepCount; i++) {\n                        iterator.stepForward();\n                    }\n                }\n            }\n        } while (prevToken && depth <= 0);\n\n        if (openTagStart && openTagEnd && closeTagStart && closeTagEnd && openTagName && closeTagName) {\n            return {\n                openTag: new Range(openTagStart.start.row, openTagStart.start.column, openTagEnd.end.row,\n                    openTagEnd.end.column\n                ),\n                closeTag: new Range(closeTagStart.start.row, closeTagStart.start.column, closeTagEnd.end.row,\n                    closeTagEnd.end.column\n                ),\n                openTagName: openTagName,\n                closeTagName: closeTagName\n            };\n        }\n    };\n}\nexports.BracketMatch = BracketMatch;\n"
  },
  {
    "path": "src/edit_session/fold.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./fold_line\").FoldLine} FoldLine\n * @typedef {import(\"../range\").Range} Range\n * @typedef {import(\"../../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../../ace-internal\").Ace.IRange} IRange\n */\nvar RangeList = require(\"../range_list\").RangeList;\n\n/*\n * Simple fold-data struct.\n **/\nclass Fold extends RangeList {\n\n    /**\n     * @param {Range} range\n     * @param {any} placeholder\n     */\n    constructor(range, placeholder) {\n        super();\n        this.foldLine = null;\n        this.placeholder = placeholder;\n        this.range = range;\n        this.start = range.start;\n        this.end = range.end;\n\n        this.sameRow = range.start.row == range.end.row;\n        /**@type {Fold[]}*/\n        this.subFolds = this.ranges = [];\n    }\n    \n    toString() {\n        return '\"' + this.placeholder + '\" ' + this.range.toString();\n    }\n\n    /**\n     * @param {FoldLine} foldLine\n     */\n    setFoldLine(foldLine) {\n        this.foldLine = foldLine;\n        this.subFolds.forEach(function(fold) {\n            fold.setFoldLine(foldLine);\n        });\n    }\n\n    clone() {\n        var range = this.range.clone();\n        var fold = new Fold(range, this.placeholder);\n        this.subFolds.forEach(function(subFold) {\n            fold.subFolds.push(subFold.clone());\n        });\n        fold.collapseChildren = this.collapseChildren;\n        return fold;\n    }\n\n    /**\n     * @param {Fold} fold\n     */\n    addSubFold(fold) {\n        if (this.range.isEqual(fold))\n            return;\n\n        // transform fold to local coordinates\n        consumeRange(fold, this.start);\n\n        var row = fold.start.row, column = fold.start.column;\n        for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {\n            cmp = this.subFolds[i].range.compare(row, column);\n            if (cmp != 1)\n                break;\n        }\n        var afterStart = this.subFolds[i];\n        var firstConsumed = 0;\n\n        if (cmp == 0) {\n            if (afterStart.range.containsRange(fold))\n                return afterStart.addSubFold(fold);\n            else\n                firstConsumed = 1;\n        }\n\n        // cmp == -1\n        var row = fold.range.end.row, column = fold.range.end.column;\n        for (var j = i, cmp = -1; j < this.subFolds.length; j++) {\n            cmp = this.subFolds[j].range.compare(row, column);\n            if (cmp != 1)\n                break;\n        }\n        if (cmp == 0)  j++;\n        var consumedFolds = this.subFolds.splice(i, j - i, fold);\n        var last = cmp == 0 ? consumedFolds.length - 1 : consumedFolds.length;\n        for (var k = firstConsumed; k < last; k++) {\n            fold.addSubFold(consumedFolds[k]);\n        }\n        fold.setFoldLine(this.foldLine);\n\n        return fold;\n    }\n\n    /**\n     * @param {IRange} range\n     */\n    restoreRange(range) {\n        return restoreRange(range, this.start);\n    }\n\n}\n\n/**\n * @param {Point} point\n * @param {Point} anchor\n */\nfunction consumePoint(point, anchor) {\n    point.row -= anchor.row;\n    if (point.row == 0)\n        point.column -= anchor.column;\n}\n/**\n * @param {IRange} range\n * @param {Point} anchor\n */\nfunction consumeRange(range, anchor) {\n    consumePoint(range.start, anchor);\n    consumePoint(range.end, anchor);\n}\n/**\n * @param {Point} point\n * @param {Point} anchor\n */\nfunction restorePoint(point, anchor) {\n    if (point.row == 0)\n        point.column += anchor.column;\n    point.row += anchor.row;\n}\n/**\n * @param {IRange} range\n * @param {Point} anchor\n */\nfunction restoreRange(range, anchor) {\n    restorePoint(range.start, anchor);\n    restorePoint(range.end, anchor);\n}\n\nexports.Fold = Fold;\n"
  },
  {
    "path": "src/edit_session/fold_line.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./fold\").Fold} Fold\n */\nvar Range = require(\"../range\").Range;\n\nclass FoldLine {\n    /**\n     * If an array is passed in, the folds are expected to be sorted already.\n     * @param {FoldLine[]} foldData\n     * @param {Fold[]|Fold} folds\n     */\n    constructor(foldData, folds) {\n        this.foldData = foldData;\n        if (Array.isArray(folds)) {\n            /**@type {Fold[]} */\n            this.folds = folds;\n        } else {\n            folds = this.folds = [ folds ];\n        }\n\n        var last = folds[folds.length - 1];\n        this.range = new Range(folds[0].start.row, folds[0].start.column,\n            last.end.row, last.end.column);\n        this.start = this.range.start;\n        this.end   = this.range.end;\n\n        this.folds.forEach(function(fold) {\n            fold.setFoldLine(this);\n        }, this);\n    }\n    \n    /**\n     * Note: This doesn't update wrapData!\n     * @param {number} shift\n     */\n    shiftRow(shift) {\n        this.start.row += shift;\n        this.end.row += shift;\n        this.folds.forEach(function(fold) {\n            fold.start.row += shift;\n            fold.end.row += shift;\n        });\n    }\n\n    /**\n     * @param {Fold} fold\n     */\n    addFold(fold) {\n        if (fold.sameRow) {\n            // @ts-expect-error TODO: startRow, endRow are missing in Fold and FoldLine\n            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {\n                throw new Error(\"Can't add a fold to this FoldLine as it has no connection\");\n            }\n            this.folds.push(fold);\n            this.folds.sort(function(a, b) {\n                return -a.range.compareEnd(b.start.row, b.start.column);\n            });\n            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {\n                this.end.row = fold.end.row;\n                this.end.column =  fold.end.column;\n            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {\n                this.start.row = fold.start.row;\n                this.start.column = fold.start.column;\n            }\n        } else if (fold.start.row == this.end.row) {\n            this.folds.push(fold);\n            this.end.row = fold.end.row;\n            this.end.column = fold.end.column;\n        } else if (fold.end.row == this.start.row) {\n            this.folds.unshift(fold);\n            this.start.row = fold.start.row;\n            this.start.column = fold.start.column;\n        } else {\n            throw new Error(\"Trying to add fold to FoldRow that doesn't have a matching row\");\n        }\n        fold.foldLine = this;\n    }\n\n    /**\n     * @param {number} row\n     */\n    containsRow(row) {\n        return row >= this.start.row && row <= this.end.row;\n    }\n\n    /**\n     * @param {Function} callback\n     * @param {number} endRow\n     * @param {number} endColumn\n     */\n    walk(callback, endRow, endColumn) {\n        var lastEnd = 0,\n            folds = this.folds,\n            fold,\n            cmp, stop, isNewRow = true;\n\n        if (endRow == null) {\n            endRow = this.end.row;\n            endColumn = this.end.column;\n        }\n\n        for (var i = 0; i < folds.length; i++) {\n            fold = folds[i];\n\n            cmp = fold.range.compareStart(endRow, endColumn);\n            // This fold is after the endRow/Column.\n            if (cmp == -1) {\n                callback(null, endRow, endColumn, lastEnd, isNewRow);\n                return;\n            }\n\n            stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);\n            stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);\n\n            // If the user requested to stop the walk or endRow/endColumn is\n            // inside of this fold (cmp == 0), then end here.\n            if (stop || cmp === 0) {\n                return;\n            }\n\n            // Note the new lastEnd might not be on the same line. However,\n            // it's the callback's job to recognize this.\n            isNewRow = !fold.sameRow;\n            lastEnd = fold.end.column;\n        }\n        callback(null, endRow, endColumn, lastEnd, isNewRow);\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @return {{ fold: Fold, kind: string } | null}\n     */\n    getNextFoldTo(row, column) {\n        var fold, cmp;\n        for (var i = 0; i < this.folds.length; i++) {\n            fold = this.folds[i];\n            cmp = fold.range.compareEnd(row, column);\n            if (cmp == -1) {\n                return {\n                    fold: fold,\n                    kind: \"after\"\n                };\n            } else if (cmp === 0) {\n                return {\n                    fold: fold,\n                    kind: \"inside\"\n                };\n            }\n        }\n        return null;\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @param {number} len\n     */\n    addRemoveChars(row, column, len) {\n        var ret = this.getNextFoldTo(row, column),\n            fold, folds;\n        if (ret) {\n            fold = ret.fold;\n            if (ret.kind == \"inside\"\n                && fold.start.column != column\n                && fold.start.row != row)\n            {\n                //throwing here breaks whole editor\n                //TODO: properly handle this\n                window.console && window.console.log(row, column, fold);\n            } else if (fold.start.row == row) {\n                folds = this.folds;\n                var i = folds.indexOf(fold);\n                if (i === 0) {\n                    this.start.column += len;\n                }\n                for (i; i < folds.length; i++) {\n                    fold = folds[i];\n                    fold.start.column += len;\n                    if (!fold.sameRow) {\n                        return;\n                    }\n                    fold.end.column += len;\n                }\n                this.end.column += len;\n            }\n        }\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @return {FoldLine | null}\n     */\n    split(row, column) {\n        var pos = this.getNextFoldTo(row, column);\n        \n        if (!pos || pos.kind == \"inside\")\n            return null;\n            \n        var fold = pos.fold;\n        var folds = this.folds;\n        var foldData = this.foldData;\n        \n        var i = folds.indexOf(fold);\n        var foldBefore = folds[i - 1];\n        this.end.row = foldBefore.end.row;\n        this.end.column = foldBefore.end.column;\n\n        // Remove the folds after row/column and create a new FoldLine\n        // containing these removed folds.\n        folds = folds.splice(i, folds.length - i);\n\n        var newFoldLine = new FoldLine(foldData, folds);\n        foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);\n        return newFoldLine;\n    }\n\n    /**\n     * @param {FoldLine} foldLineNext\n     */\n    merge(foldLineNext) {\n        var folds = foldLineNext.folds;\n        for (var i = 0; i < folds.length; i++) {\n            this.addFold(folds[i]);\n        }\n        // Remove the foldLineNext - no longer needed, as\n        // it's merged now with foldLineNext.\n        var foldData = this.foldData;\n        foldData.splice(foldData.indexOf(foldLineNext), 1);\n    }\n\n    toString() {\n        var ret = [this.range.toString() + \": [\" ];\n\n        this.folds.forEach(function(fold) {\n            ret.push(\"  \" + fold.toString());\n        });\n        ret.push(\"]\");\n        return ret.join(\"\\n\");\n    }\n\n    /**\n     * @param {number} idx\n     * @return {import(\"../../ace-internal\").Ace.Point}\n     */\n    idxToPosition(idx) {\n        var lastFoldEndColumn = 0;\n\n        for (var i = 0; i < this.folds.length; i++) {\n            var fold = this.folds[i];\n\n            idx -= fold.start.column - lastFoldEndColumn;\n            if (idx < 0) {\n                return {\n                    row: fold.start.row,\n                    column: fold.start.column + idx\n                };\n            }\n\n            idx -= fold.placeholder.length;\n            if (idx < 0) {\n                return fold.start;\n            }\n\n            lastFoldEndColumn = fold.end.column;\n        }\n\n        return {\n            row: this.end.row,\n            column: this.end.column + idx\n        };\n    }\n}\n\nexports.FoldLine = FoldLine;\n"
  },
  {
    "path": "src/edit_session/folding.js",
    "content": "// @ts-nocheck\n\"use strict\";\n\nvar Range = require(\"../range\").Range;\nvar FoldLine = require(\"./fold_line\").FoldLine;\nvar Fold = require(\"./fold\").Fold;\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar MouseEvent = require(\"../mouse/mouse_event\").MouseEvent;\n\n/**\n * @typedef {import(\"../edit_session\").EditSession & import(\"../../ace-internal\").Ace.Folding} IFolding\n * @typedef {import(\"../../ace-internal\").Ace.Delta } Delta\n */\n\n/**\n * @this {IFolding}\n * @type {IFolding}\n */\nfunction Folding() {\n    /**\n     * Looks up a fold at a given row/column. Possible values for side:\n     *   -1: ignore a fold if fold.start = row/column\n     *   +1: ignore a fold if fold.end = row/column\n     * @param {number} row\n     * @param {number} column\n     * @param {number} [side]\n     * @return {Fold}\n     **/\n    this.getFoldAt = function(row, column, side) {\n        var foldLine = this.getFoldLine(row);\n        if (!foldLine)\n            return null;\n\n        var folds = foldLine.folds;\n        for (var i = 0; i < folds.length; i++) {\n            var range = folds[i].range;\n            if (range.contains(row, column)) {\n                if (side == 1 && range.isEnd(row, column) && !range.isEmpty()) {\n                    continue;\n                } else if (side == -1 && range.isStart(row, column) && !range.isEmpty()) {\n                    continue;\n                }\n                return folds[i];\n            }\n        }\n    };\n\n    /**\n     * Returns all folds in the given range. Note, that this will return folds\n     * @param {Range| Delta} range\n     * @returns {Fold[]}\n     **/\n    this.getFoldsInRange = function(range) {\n        var start = range.start;\n        var end = range.end;\n        var foldLines = this.$foldData;\n        var foundFolds = [];\n\n        start.column += 1;\n        end.column -= 1;\n\n        for (var i = 0; i < foldLines.length; i++) {\n            var cmp = foldLines[i].range.compareRange(range);\n            if (cmp == 2) {\n                // Range is before foldLine. No intersection. This means,\n                // there might be other foldLines that intersect.\n                continue;\n            }\n            else if (cmp == -2) {\n                // Range is after foldLine. There can't be any other foldLines then,\n                // so let's give up.\n                break;\n            }\n\n            var folds = foldLines[i].folds;\n            for (var j = 0; j < folds.length; j++) {\n                var fold = folds[j];\n                cmp = fold.range.compareRange(range);\n                if (cmp == -2) {\n                    break;\n                } else if (cmp == 2) {\n                    continue;\n                } else\n                // WTF-state: Can happen due to -1/+1 to start/end column.\n                if (cmp == 42) {\n                    break;\n                }\n                foundFolds.push(fold);\n            }\n        }\n        start.column -= 1;\n        end.column += 1;\n\n        return foundFolds;\n    };\n\n    /**\n     * \n     * @param {Range[]|Range}ranges\n     * @returns {Fold[]}\n     */\n    this.getFoldsInRangeList = function(ranges) {\n        if (Array.isArray(ranges)) {\n            /**@type {Fold[]} */\n            var folds = [];\n            ranges.forEach(function(range) {\n                folds = folds.concat(this.getFoldsInRange(range));\n            }, this);\n        } else {\n            var folds = this.getFoldsInRange(ranges);\n        }\n        return folds;\n    };\n    \n    /**\n     * Returns all folds in the document\n     * @returns {Fold[]}\n     */\n    this.getAllFolds = function() {\n        var folds = [];\n        var foldLines = this.$foldData;\n        \n        for (var i = 0; i < foldLines.length; i++)\n            for (var j = 0; j < foldLines[i].folds.length; j++)\n                folds.push(foldLines[i].folds[j]);\n\n        return folds;\n    };\n\n    /**\n     * Returns the string between folds at the given position.\n     * E.g.\n     *  foo<fold>b|ar<fold>wolrd -> \"bar\"\n     *  foo<fold>bar<fold>wol|rd -> \"world\"\n     *  foo<fold>bar<fo|ld>wolrd -> <null>\n     *\n     * where | means the position of row/column\n     *\n     * The trim option determs if the return string should be trimed according\n     * to the \"side\" passed with the trim value:\n     *\n     * E.g.\n     *  foo<fold>b|ar<fold>wolrd -trim=-1> \"b\"\n     *  foo<fold>bar<fold>wol|rd -trim=+1> \"rld\"\n     *  fo|o<fold>bar<fold>wolrd -trim=00> \"foo\"\n     *  @param {number} row\n     *  @param {number} column\n     *  @param {number} [trim]\n     *  @param {FoldLine} [foldLine]\n     *  @returns {string | null}\n     */\n    this.getFoldStringAt = function(row, column, trim, foldLine) {\n        foldLine = foldLine || this.getFoldLine(row);\n        if (!foldLine)\n            return null;\n\n        var lastFold = {\n            end: { column: 0 }\n        };\n        // TODO: Refactor to use getNextFoldTo function.\n        var str, fold;\n        for (var i = 0; i < foldLine.folds.length; i++) {\n            fold = foldLine.folds[i];\n            var cmp = fold.range.compareEnd(row, column);\n            if (cmp == -1) {\n                str = this\n                    .getLine(fold.start.row)\n                    .substring(lastFold.end.column, fold.start.column);\n                break;\n            }\n            else if (cmp === 0) {\n                return null;\n            }\n            lastFold = fold;\n        }\n        if (!str)\n            str = this.getLine(fold.start.row).substring(lastFold.end.column);\n\n        if (trim == -1)\n            return str.substring(0, column - lastFold.end.column);\n        else if (trim == 1)\n            return str.substring(column - lastFold.end.column);\n        else\n            return str;\n    };\n\n    /**\n     * \n     * @param {number} docRow\n     * @param {FoldLine} [startFoldLine]\n     * @returns {null|FoldLine}\n     */\n    this.getFoldLine = function(docRow, startFoldLine) {\n        var foldData = this.$foldData;\n        var i = 0;\n        if (startFoldLine)\n            i = foldData.indexOf(startFoldLine);\n        if (i == -1)\n            i = 0;\n        for (i; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {\n                return foldLine;\n            } else if (foldLine.end.row > docRow) {\n                return null;\n            }\n        }\n        return null;\n    };\n\n    /**\n     * Returns the fold which starts after or contains docRow\n     * @param {number} docRow\n     * @param {FoldLine} [startFoldLine]\n     * @returns {null|FoldLine}\n     */\n    this.getNextFoldLine = function(docRow, startFoldLine) {\n        var foldData = this.$foldData;\n        var i = 0;\n        if (startFoldLine)\n            i = foldData.indexOf(startFoldLine);\n        if (i == -1)\n            i = 0;\n        for (i; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (foldLine.end.row >= docRow) {\n                return foldLine;\n            }\n        }\n        return null;\n    };\n\n    /**\n     * \n     * @param {number} first\n     * @param {number} last\n     * @return {number}\n     */\n    this.getFoldedRowCount = function(first, last) {\n        var foldData = this.$foldData, rowCount = last-first+1;\n        for (var i = 0; i < foldData.length; i++) {\n            var foldLine = foldData[i],\n                end = foldLine.end.row,\n                start = foldLine.start.row;\n            if (end >= last) {\n                if (start < last) {\n                    if (start >= first)\n                        rowCount -= last-start;\n                    else\n                        rowCount = 0; // in one fold\n                }\n                break;\n            } else if (end >= first){\n                if (start >= first) // fold inside range\n                    rowCount -=  end-start;\n                else\n                    rowCount -=  end-first+1;\n            }\n        }\n        return rowCount;\n    };\n\n    /**\n     * \n     * @param {FoldLine}foldLine\n     * @return {FoldLine}\n     */\n    this.$addFoldLine = function(foldLine) {\n        this.$foldData.push(foldLine);\n        this.$foldData.sort(function(a, b) {\n            return a.start.row - b.start.row;\n        });\n        return foldLine;\n    };\n\n    /**\n     * Adds a new fold.\n     *\n     * @param {Fold|string} placeholder\n     * @param {Range} [range]\n     * @returns {Fold}\n     *      The new created Fold object or an existing fold object in case the\n     *      passed in range fits an existing fold exactly.\n     * @this {IFolding}\n     */\n    this.addFold = function(placeholder, range) {\n        var foldData = this.$foldData;\n        var added = false;\n        /**@type {Fold}*/\n        var fold;\n        \n        if (placeholder instanceof Fold)\n            fold = placeholder;\n        else {\n            fold = new Fold(range, placeholder);\n            // @ts-ignore\n            fold.collapseChildren = range.collapseChildren;\n        }\n        this.$clipRangeToDocument(fold.range);\n\n        var startRow = fold.start.row;\n        var startColumn = fold.start.column;\n        var endRow = fold.end.row;\n        var endColumn = fold.end.column;\n\n        var startFold = this.getFoldAt(startRow, startColumn, 1);\n        var endFold = this.getFoldAt(endRow, endColumn, -1);\n        if (startFold && endFold == startFold)\n            return startFold.addSubFold(fold);\n\n        if (startFold && !startFold.range.isStart(startRow, startColumn))\n            this.removeFold(startFold);\n        \n        if (endFold && !endFold.range.isEnd(endRow, endColumn))\n            this.removeFold(endFold);\n        \n        // Check if there are folds in the range we create the new fold for.\n        var folds = this.getFoldsInRange(fold.range);\n        if (folds.length > 0) {\n            // Remove the folds from fold data.\n            this.removeFolds(folds);\n            // Add the removed folds as subfolds on the new fold.\n            if (!fold.collapseChildren) {\n                folds.forEach(function(subFold) {\n                    fold.addSubFold(subFold);\n                });\n            }\n        }\n\n        for (var i = 0; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (endRow == foldLine.start.row) {\n                foldLine.addFold(fold);\n                added = true;\n                break;\n            } else if (startRow == foldLine.end.row) {\n                foldLine.addFold(fold);\n                added = true;\n                if (!fold.sameRow) {\n                    // Check if we might have to merge two FoldLines.\n                    var foldLineNext = foldData[i + 1];\n                    if (foldLineNext && foldLineNext.start.row == endRow) {\n                        // We need to merge!\n                        foldLine.merge(foldLineNext);\n                        break;\n                    }\n                }\n                break;\n            } else if (endRow <= foldLine.start.row) {\n                break;\n            }\n        }\n\n        if (!added)\n            foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));\n\n        if (this.$useWrapMode)\n            this.$updateWrapData(foldLine.start.row, foldLine.start.row);\n        else\n            this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);\n\n        // Notify that fold data has changed.\n        this.$modified = true;\n        this._signal(\"changeFold\", { data: fold, action: \"add\" });\n\n        return fold;\n    };\n\n    /**\n     * @param {Fold[]} folds\n     */\n    this.addFolds = function(folds) {\n        folds.forEach(function(fold) {\n            this.addFold(fold);\n        }, this);\n    };\n\n    /**\n     * \n     * @param {Fold} fold\n     */\n    this.removeFold = function(fold) {\n        var foldLine = fold.foldLine;\n        var startRow = foldLine.start.row;\n        var endRow = foldLine.end.row;\n\n        var foldLines = this.$foldData;\n        var folds = foldLine.folds;\n        // Simple case where there is only one fold in the FoldLine such that\n        // the entire fold line can get removed directly.\n        if (folds.length == 1) {\n            foldLines.splice(foldLines.indexOf(foldLine), 1);\n        } else\n        // If the fold is the last fold of the foldLine, just remove it.\n        if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {\n            folds.pop();\n            foldLine.end.row = folds[folds.length - 1].end.row;\n            foldLine.end.column = folds[folds.length - 1].end.column;\n        } else\n        // If the fold is the first fold of the foldLine, just remove it.\n        if (foldLine.range.isStart(fold.start.row, fold.start.column)) {\n            folds.shift();\n            foldLine.start.row = folds[0].start.row;\n            foldLine.start.column = folds[0].start.column;\n        } else\n        // We know there are more then 2 folds and the fold is not at the edge.\n        // This means, the fold is somewhere in between.\n        //\n        // If the fold is in one row, we just can remove it.\n        if (fold.sameRow) {\n            folds.splice(folds.indexOf(fold), 1);\n        } else\n        // The fold goes over more then one row. This means remvoing this fold\n        // will cause the fold line to get splitted up. newFoldLine is the second part\n        {\n            var newFoldLine = foldLine.split(fold.start.row, fold.start.column);\n            folds = newFoldLine.folds;\n            folds.shift();\n            newFoldLine.start.row = folds[0].start.row;\n            newFoldLine.start.column = folds[0].start.column;\n        }\n\n        if (!this.$updating) {\n            if (this.$useWrapMode)\n                this.$updateWrapData(startRow, endRow);\n            else\n                this.$updateRowLengthCache(startRow, endRow);\n        }\n        \n        // Notify that fold data has changed.\n        this.$modified = true;\n        this._signal(\"changeFold\", { data: fold, action: \"remove\" });\n    };\n\n    /**\n     * \n     * @param {Fold[]} folds\n     */\n    this.removeFolds = function(folds) {\n        // We need to clone the folds array passed in as it might be the folds\n        // array of a fold line and as we call this.removeFold(fold), folds\n        // are removed from folds and changes the current index.\n        var cloneFolds = [];\n        for (var i = 0; i < folds.length; i++) {\n            cloneFolds.push(folds[i]);\n        }\n\n        cloneFolds.forEach(function(fold) {\n            this.removeFold(fold);\n        }, this);\n        this.$modified = true;\n    };\n\n    /**\n     * @param {Fold} fold\n     */\n    this.expandFold = function(fold) {\n        this.removeFold(fold);\n        fold.subFolds.forEach(function(subFold) {\n            fold.restoreRange(subFold);\n            this.addFold(subFold);\n        }, this);\n        if (fold.collapseChildren > 0) {\n            this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);\n        }\n        fold.subFolds = [];\n    };\n\n    /**\n     * @param {Fold[]}folds\n     */\n    this.expandFolds = function(folds) {\n        folds.forEach(function(fold) {\n            this.expandFold(fold);\n        }, this);\n    };\n\n    /**\n     * \n     * @param {number|null|import(\"../../ace-internal\").Ace.Point|Range|Range[]} [location]\n     * @param {boolean} [expandInner]\n     * @return {Fold[]| undefined}\n     */\n    this.unfold = function(location, expandInner) {\n        var range, folds;\n        if (location == null) {\n            range = new Range(0, 0, this.getLength(), 0);\n            if (expandInner == null) expandInner = true;\n        } else if (typeof location == \"number\") {\n            range = new Range(location, 0, location, this.getLine(location).length);\n        } else if (\"row\" in location) {\n            range = Range.fromPoints(location, location);\n        } else if (Array.isArray(location)) {\n            folds = [];\n            location.forEach(function(range) {\n                folds = folds.concat(this.unfold(range));\n            }, this);\n            return folds;\n        } else {\n            range = location;\n        }\n        \n        folds = this.getFoldsInRangeList(range);\n        var outermostFolds = folds;\n        // if range itself is in a fold, expand that fold instead of removing, \n        // to not accidentally remove sibling folds\n        while (\n            folds.length == 1\n            && Range.comparePoints(folds[0].start, range.start) < 0 \n            && Range.comparePoints(folds[0].end, range.end) > 0\n        ) {\n            this.expandFolds(folds);\n            folds = this.getFoldsInRangeList(range);\n        }\n        \n        if (expandInner != false) {\n            this.removeFolds(folds);\n        } else {\n            this.expandFolds(folds);\n        }\n        if (outermostFolds.length)\n            return outermostFolds;\n    };\n\n    /**\n     * Checks if a given documentRow is folded. This is true if there are some\n     * folded parts such that some parts of the line is still visible.\n     * @param {number} docRow\n     * @param {FoldLine} [startFoldRow]\n     * @returns {boolean}\n     **/\n    this.isRowFolded = function(docRow, startFoldRow) {\n        return !!this.getFoldLine(docRow, startFoldRow);\n    };\n\n    /**\n     * \n     * @param {number} docRow\n     * @param {FoldLine} [startFoldRow]\n     * @return {number}\n     */\n    this.getRowFoldEnd = function(docRow, startFoldRow) {\n        var foldLine = this.getFoldLine(docRow, startFoldRow);\n        return foldLine ? foldLine.end.row : docRow;\n    };\n\n    /**\n     * \n     * @param {number} docRow\n     * @param {FoldLine} [startFoldRow]\n     * @returns {number}\n     */\n    this.getRowFoldStart = function(docRow, startFoldRow) {\n        var foldLine = this.getFoldLine(docRow, startFoldRow);\n        return foldLine ? foldLine.start.row : docRow;\n    };\n\n    /**\n     * \n     * @param {FoldLine} foldLine\n     * @param {number | null} [endRow]\n     * @param {number | null} [endColumn]\n     * @param {number | null} [startRow]\n     * @param {number | null} [startColumn]\n     * @return {string}\n     */\n    this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {\n        if (startRow == null)\n            startRow = foldLine.start.row;\n        if (startColumn == null)\n            startColumn = 0;\n        if (endRow == null)\n            endRow = foldLine.end.row;\n        if (endColumn == null)\n            endColumn = this.getLine(endRow).length;\n        \n\n        // Build the textline using the FoldLine walker.\n        var doc = this.doc;\n        var textLine = \"\";\n\n        foldLine.walk(function(placeholder, row, column, lastColumn) {\n            if (row < startRow)\n                return;\n            if (row == startRow) {\n                if (column < startColumn)\n                    return;\n                lastColumn = Math.max(startColumn, lastColumn);\n            }\n\n            if (placeholder != null) {\n                textLine += placeholder;\n            } else {\n                textLine += doc.getLine(row).substring(lastColumn, column);\n            }\n        }, endRow, endColumn);\n        return textLine;\n    };\n\n    /**\n     * \n     * @param {number} row\n     * @param {number | null} endColumn\n     * @param {number | null} startRow\n     * @param {number | null} startColumn\n     * @return {string}\n     */\n    this.getDisplayLine = function(row, endColumn, startRow, startColumn) {\n        var foldLine = this.getFoldLine(row);\n\n        if (!foldLine) {\n            var line;\n            line = this.doc.getLine(row);\n            return line.substring(startColumn || 0, endColumn || line.length);\n        } else {\n            return this.getFoldDisplayLine(\n                foldLine, row, endColumn, startRow, startColumn);\n        }\n    };\n\n    /**\n     * @return {FoldLine[]}\n     */\n    this.$cloneFoldData = function() {\n        var fd = [];\n        fd = this.$foldData.map(function(foldLine) {\n            var folds = foldLine.folds.map(function(fold) {\n                return fold.clone();\n            });\n            return new FoldLine(fd, folds);\n        });\n\n        return fd;\n    };\n\n    /**\n     * @param {boolean} [tryToUnfold]\n     */\n    this.toggleFold = function(tryToUnfold) {\n        var selection = this.selection;\n        var range = selection.getRange();\n        var fold;\n        var bracketPos;\n\n        if (range.isEmpty()) {\n            var cursor = range.start;\n            fold = this.getFoldAt(cursor.row, cursor.column);\n\n            if (fold) {\n                this.expandFold(fold);\n                return;\n            } else if (tryToUnfold) {\n                var foldLine = this.getFoldLine(cursor.row);\n                if (foldLine)\n                    this.expandFolds(foldLine.folds);\n                return;\n            } else if (bracketPos = this.findMatchingBracket(cursor)) {\n                if (range.comparePoint(bracketPos) == 1) {\n                    range.end = bracketPos;\n                } else {\n                    range.start = bracketPos;\n                    range.start.column++;\n                    range.end.column--;\n                }\n            } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {\n                if (range.comparePoint(bracketPos) == 1)\n                    range.end = bracketPos;\n                else\n                    range.start = bracketPos;\n\n                range.start.column++;\n            } else {\n                range = this.getCommentFoldRange(cursor.row, cursor.column) || range;\n            }\n        } else {\n            var folds = this.getFoldsInRange(range);\n            if (tryToUnfold && folds.length) {\n                this.expandFolds(folds);\n                return;\n            } else if (folds.length == 1 ) {\n                fold = folds[0];\n            }\n        }\n\n        if (!fold)\n            fold = this.getFoldAt(range.start.row, range.start.column);\n\n        if (fold && fold.range.toString() == range.toString()) {\n            this.expandFold(fold);\n            return;\n        }\n\n        var placeholder = \"...\";\n        if (!range.isMultiLine()) {\n            placeholder = this.getTextRange(range);\n            if (placeholder.length < 4)\n                return;\n            placeholder = placeholder.trim().substring(0, 2) + \"..\";\n        }\n\n        this.addFold(placeholder, range);\n    };\n\n    /**\n     * \n     * @param {number} row\n     * @param {number} column\n     * @param {number} [dir]\n     * @return {Range | undefined}\n     */\n    this.getCommentFoldRange = function(row, column, dir) {\n        var iterator = new TokenIterator(this, row, column);\n        var token = iterator.getCurrentToken();\n        var type = token && token.type;\n        if (token && /^comment|string/.test(type)) {\n            type = type.match(/comment|string/)[0];\n            if (type == \"comment\")\n                type += \"|doc-start|\\\\.doc\";\n            var re = new RegExp(type);\n            var range = new Range();\n            if (dir != 1) {\n                do {\n                    token = iterator.stepBackward();\n                } while (token && re.test(token.type));\n                token = iterator.stepForward();\n            }\n            \n            range.start.row = iterator.getCurrentTokenRow();\n            range.start.column = iterator.getCurrentTokenColumn() + token.value.length;\n\n            iterator = new TokenIterator(this, row, column);\n            var initState = this.getState(iterator.$row);\n            \n            if (dir != -1) {\n                var lastRow = -1;\n                do {\n                    token = iterator.stepForward();\n                    if (lastRow == -1) {\n                        var state = this.getState(iterator.$row);\n                        if (initState.toString() !== state.toString())\n                            lastRow = iterator.$row;\n                    } else if (iterator.$row > lastRow) {\n                        break;\n                    }\n                } while (token && re.test(token.type));\n                token = iterator.stepBackward();\n            } else\n                token = iterator.getCurrentToken();\n\n            range.end.row = iterator.getCurrentTokenRow();\n            range.end.column = iterator.getCurrentTokenColumn();\n            if (range.start.row == range.end.row && range.start.column > range.end.column)\n                return;\n            return range;\n        }\n    };\n\n    /**\n     * \n     * @param {number | null} [startRow]\n     * @param {number | null} [endRow]\n     * @param {number | null} [depth]\n     * @param {Function} [test]\n     */\n    this.foldAll = function(startRow, endRow, depth, test) {\n        if (depth == undefined)\n            depth = 100000; // JSON.stringify doesn't hanle Infinity\n        var foldWidgets = this.foldWidgets;\n        if (!foldWidgets)\n            return; // mode doesn't support folding\n        endRow = endRow || this.getLength();\n        startRow = startRow || 0;\n        for (var row = startRow; row < endRow; row++) {\n            if (foldWidgets[row] == null)\n                foldWidgets[row] = this.getFoldWidget(row);\n            if (foldWidgets[row] != \"start\")\n                continue;\n            \n            if (test && !test(row)) continue;\n\n            var range = this.getFoldWidgetRange(row);\n            if (range && range.isMultiLine()\n                && range.end.row <= endRow\n                && range.start.row >= startRow\n            ) {\n                row = range.end.row;\n                range.collapseChildren = depth;\n                // addFold can change the range\n                this.addFold(\"...\", range);\n            }\n        }\n    };\n\n    /**\n     * \n     * @param {number} level\n     */\n    this.foldToLevel = function(level) {\n        this.foldAll();\n        while (level-- > 0)\n            this.unfold(null, false);\n    };\n\n    /**\n     *\n     */\n    this.foldAllComments = function() {\n        var session = this;\n        this.foldAll(null, null, null, function(row) {\n            var tokens = session.getTokens(row);\n            for (var i = 0; i < tokens.length; i++) {\n                var token = tokens[i];\n                if (token.type == \"text\" && /^\\s+$/.test(token.value))\n                    continue;\n                if (/comment/.test(token.type))\n                    return true;\n                return false;\n            }\n        });\n    };\n    \n    // structured folding\n    this.$foldStyles = {\n        \"manual\": 1,\n        \"markbegin\": 1,\n        \"markbeginend\": 1\n    };\n    this.$foldStyle = \"markbegin\";\n    \n    /**\n     * @param {string} style\n     */\n    this.setFoldStyle = function(style) {\n        if (!this.$foldStyles[style])\n            throw new Error(\"invalid fold style: \" + style + \"[\" + Object.keys(this.$foldStyles).join(\", \") + \"]\");\n        \n        if (this.$foldStyle == style)\n            return;\n\n        this.$foldStyle = style;\n        \n        if (style == \"manual\")\n            this.unfold();\n        \n        // reset folding\n        var mode = this.$foldMode;\n        this.$setFolding(null);\n        this.$setFolding(mode);\n    };\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.FoldMode} foldMode\n     */\n    this.$setFolding = function(foldMode) {\n        if (this.$foldMode == foldMode)\n            return;\n\n\n        this.$foldMode = foldMode;\n        \n        this.off('change', this.$updateFoldWidgets);\n        this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);\n        this._signal(\"changeAnnotation\");\n        \n        if (!foldMode || this.$foldStyle == \"manual\") {\n            this.foldWidgets = null;\n            return;\n        }\n        \n        this.foldWidgets = [];\n        this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);\n        this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);\n        \n        this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);\n        this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this);\n        this.on('change', this.$updateFoldWidgets);\n        this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);\n    };\n    /**\n     * @param {number} row\n     * @param {boolean} [ignoreCurrent]\n     * @return {{range?: Range, firstRange?: Range}}\n     */\n    this.getParentFoldRangeData = function (row, ignoreCurrent) {\n        var fw = this.foldWidgets;\n        if (!fw || (ignoreCurrent && fw[row]))\n            return {};\n\n        var i = row - 1, firstRange;\n        while (i >= 0) {\n            var c = fw[i];\n            if (c == null)\n                c = fw[i] = this.getFoldWidget(i);\n\n            if (c == \"start\") {\n                var range = this.getFoldWidgetRange(i);\n                if (!firstRange)\n                    firstRange = range;\n                if (range && range.end.row >= row)\n                    break;\n            }\n            i--;\n        }\n\n        return {\n            range: i !== -1 && range,\n            firstRange: firstRange\n        };\n    };\n\n    /**\n     * \n     * @param {number} row\n     * @param {any} e\n     */\n    this.onFoldWidgetClick = function(row, e) {\n        if (e instanceof MouseEvent)\n            e = e.domEvent;\n\n        var options = {\n            children: e.shiftKey,\n            all: e.ctrlKey || e.metaKey,\n            siblings: e.altKey\n        };\n        \n        var range = this.$toggleFoldWidget(row, options);\n        if (!range) {\n            var el = (e.target || e.srcElement);\n            if (el && /ace_fold-widget/.test(el.className))\n                el.className += \" ace_invalid\";\n        }\n    };\n\n    /**\n     * \n     * @param {number} row\n     * @param options\n     * @return {Fold|*}\n     */\n    this.$toggleFoldWidget = function(row, options) {\n        if (!this.getFoldWidget)\n            return;\n        var type = this.getFoldWidget(row);\n        var line = this.getLine(row);\n\n        var dir = type === \"end\" ? -1 : 1;\n        var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);\n\n        if (fold) {\n            if (options.children || options.all)\n                this.removeFold(fold);\n            else\n                this.expandFold(fold);\n            return fold;\n        }\n\n        var range = this.getFoldWidgetRange(row, true);\n        // sometimes singleline folds can be missed by the code above\n        if (range && !range.isMultiLine()) {\n            fold = this.getFoldAt(range.start.row, range.start.column, 1);\n            if (fold && range.isEqual(fold.range)) {\n                this.removeFold(fold);\n                return fold;\n            }\n        }\n        \n        if (options.siblings) {\n            var data = this.getParentFoldRangeData(row);\n            if (data.range) {\n                var startRow = data.range.start.row + 1;\n                var endRow = data.range.end.row;\n            }\n            this.foldAll(startRow, endRow, options.all ? 10000 : 0);\n        } else if (options.children) {\n            endRow = range ? range.end.row : this.getLength();\n            this.foldAll(row + 1, endRow, options.all ? 10000 : 0);\n        } else if (range) {\n            if (options.all) \n                range.collapseChildren = 10000;\n            this.addFold(\"...\", range);\n        }\n        \n        return range;\n    };\n    \n    /**\n     * \n     * @param {boolean} [toggleParent]\n     */\n    this.toggleFoldWidget = function(toggleParent) {\n        var row = this.selection.getCursor().row;\n        row = this.getRowFoldStart(row);\n        var range = this.$toggleFoldWidget(row, {});\n        \n        if (range)\n            return;\n        // handle toggleParent\n        var data = this.getParentFoldRangeData(row, true);\n        range = data.range || data.firstRange;\n        \n        if (range) {\n            row = range.start.row;\n            var fold = this.getFoldAt(row, this.getLine(row).length, 1);\n\n            if (fold) {\n                this.removeFold(fold);\n            } else {\n                this.addFold(\"...\", range);\n            }\n        }\n    };\n\n    /**\n     * @param {Delta} delta\n     */\n    this.updateFoldWidgets = function(delta) {\n        var firstRow = delta.start.row;\n        var len = delta.end.row - firstRow;\n\n        if (len === 0) {\n            this.foldWidgets[firstRow] = null;\n        } else if (delta.action == 'remove') {\n            this.foldWidgets.splice(firstRow, len + 1, null);\n        } else {\n            var args = Array(len + 1);\n            args.unshift(firstRow, 1);\n            this.foldWidgets.splice.apply(this.foldWidgets, args);\n        }\n    };\n    /**\n     * @param e\n     */\n    this.tokenizerUpdateFoldWidgets = function(e) {\n        var rows = e.data;\n        if (rows.first != rows.last) {\n            if (this.foldWidgets.length > rows.first)\n                this.foldWidgets.splice(rows.first, this.foldWidgets.length);\n        }\n    };\n}\n\nexports.Folding = Folding;\n"
  },
  {
    "path": "src/edit_session.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./layer/font_metrics\").FontMetrics} FontMetrics\n * @typedef {import(\"./edit_session/fold_line\").FoldLine} FoldLine\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.Delta} Delta\n * @typedef {import(\"../ace-internal\").Ace.IRange} IRange\n * @typedef {import(\"../ace-internal\").Ace.SyntaxMode} SyntaxMode\n * @typedef {import(\"../ace-internal\").Ace.LineWidget} LineWidget\n */\n\nvar oop = require(\"./lib/oop\");\nvar lang = require(\"./lib/lang\");\nvar BidiHandler = require(\"./bidihandler\").BidiHandler;\nvar config = require(\"./config\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Selection = require(\"./selection\").Selection;\nvar TextMode = require(\"./mode/text\").Mode;\nvar Range = require(\"./range\").Range;\nvar LineWidgets = require(\"./line_widgets\").LineWidgets;\nvar Document = require(\"./document\").Document;\nvar BackgroundTokenizer = require(\"./background_tokenizer\").BackgroundTokenizer;\nvar SearchHighlight = require(\"./search_highlight\").SearchHighlight;\nvar UndoManager = require(\"./undomanager\").UndoManager;\n\n/**\n * @typedef TextMode\n * @type {SyntaxMode}\n */\n\n/**\n * Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.\n *\n * `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s.\n **/\nclass EditSession {\n    /**\n     * Sets up a new `EditSession` and associates it with the given `Document` and `Mode`.\n     * @param {Document | String} [text] [If `text` is a `Document`, it associates the `EditSession` with it. Otherwise, a new `Document` is created, with the initial text]{: #textParam}\n     * @param {SyntaxMode | string} [mode] [The initial language mode to use for the document]{: #modeParam}\n     **/\n    constructor(text, mode) {\n        /**@type {Document}*/this.doc;\n        this.$breakpoints = [];\n        this.$decorations = [];\n        this.$frontMarkers = {};\n        this.$backMarkers = {};\n        this.$markerId = 1;\n        this.$undoSelect = true;\n        this.$editor = null;\n        this.prevOp = {};\n\n        /** @type {FoldLine[]} */\n        this.$foldData = [];\n        this.id = \"session\" + (++EditSession.$uid);\n        this.$foldData.toString = function() {\n            return this.join(\"\\n\");\n        };\n\n        // @experimental\n        this.$gutterCustomWidgets = {};\n\n        // Set default background tokenizer with Text mode until editor session mode is set\n        this.bgTokenizer = new BackgroundTokenizer((new TextMode()).getTokenizer(), this);\n\n\n        var _self = this;\n        this.bgTokenizer.on(\"update\", function(e) {\n            _self._signal(\"tokenizerUpdate\", e);\n        });\n\n        this.on(\"changeFold\", this.onChangeFold.bind(this));\n        this.$onChange = this.onChange.bind(this);\n\n        if (typeof text != \"object\" || !text.getLine)\n            text = new Document(/**@type{string}*/(text));\n\n        this.setDocument(text);\n\n        this.selection = new Selection(this);\n        this.$onSelectionChange = this.onSelectionChange.bind(this);\n        this.selection.on(\"changeSelection\", this.$onSelectionChange);\n        this.selection.on(\"changeCursor\", this.$onSelectionChange);\n\n        this.$bidiHandler = new BidiHandler(this);\n\n        config.resetOptions(this);\n        this.setMode(mode);\n        config._signal(\"session\", this);\n\n        this.destroyed = false;\n        this.$initOperationListeners();\n    }\n\n    $initOperationListeners() {\n        /**@type {import(\"../ace-internal\").Ace.Operation | null}*/\n        this.curOp = null;\n        this.on(\"change\", () => {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.docChanged = true;\n        }, true);\n        this.on(\"changeSelection\", () => {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.selectionChanged = true;\n        }, true);\n\n        // Fallback mechanism in case current operation doesn't finish more explicitly.\n        // Triggered, for example, when a consumer makes programmatic changes without invoking endOperation afterwards.\n        this.$operationResetTimer = lang.delayedCall(this.endOperation.bind(this, true));\n    }\n\n    /**\n     * Start an Ace operation, which will then batch all the subsequent changes (to either content or selection) under a single atomic operation.\n     * @param {{command?: {name?: string}, args?: any}|undefined} [commandEvent] Optional name for the operation\n     */\n    startOperation(commandEvent) {\n        if (this.curOp) {\n            if (!commandEvent || this.curOp.command) {\n                return;\n            }\n            this.prevOp = this.curOp;\n        }\n        if (!commandEvent) {\n            commandEvent = {};\n        }\n\n        this.$operationResetTimer.schedule();\n        this.curOp = {\n            command: commandEvent.command || {},\n            args: commandEvent.args\n        };\n        this.curOp.selectionBefore = this.selection.toJSON();\n        this._signal(\"startOperation\", commandEvent);\n    }\n\n    /**\n     * End current Ace operation.\n     * Emits \"beforeEndOperation\" event just before clearing everything, where the current operation can be accessed through `curOp` property.\n     * @param {any} [e]\n     */\n    endOperation(e) {\n        if (this.curOp) {\n            if (e && e.returnValue === false) {\n                this.curOp = null;\n                this._signal(\"endOperation\", e);\n                return;\n            }\n            if (e == true && this.curOp.command && this.curOp.command.name == \"mouse\") {\n                // When current operation is mousedown, we wait for the mouseup to end the operation.\n                // So during a user selection, we would only end the operation when the final selection is known.\n                return;\n            }\n\n            const currentSelection = this.selection.toJSON();\n            this.curOp.selectionAfter = currentSelection;\n            this.$lastSel = this.selection.toJSON();\n            this.getUndoManager().addSelection(currentSelection);\n\n            this._signal(\"beforeEndOperation\");\n            this.prevOp = this.curOp;\n            this.curOp = null;\n            this._signal(\"endOperation\", e);\n        }\n    }\n\n    /**\n     * Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`.\n     *\n     * @param {Document} doc The new `Document` to use\n     *\n     **/\n    setDocument(doc) {\n        if (this.doc)\n            this.doc.off(\"change\", this.$onChange);\n        this.doc = doc;\n        doc.on(\"change\", this.$onChange, true);\n\n        this.bgTokenizer.setDocument(this.getDocument());\n\n        this.resetCaches();\n    }\n\n    /**\n     * Returns the `Document` associated with this session.\n     * @return {Document}\n     **/\n    getDocument() {\n        return this.doc;\n    }\n\n    /**\n     * Get \"widgetManager\" from EditSession\n     *\n     * @returns {LineWidgets} object\n     */\n    get widgetManager() {\n        const widgetManager = new LineWidgets(this);\n        // todo remove the widgetManger assignement from lineWidgets constructor when introducing breaking changes\n        this.widgetManager = widgetManager;\n\n        if (this.$editor)\n            widgetManager.attach(this.$editor);\n\n        return widgetManager;\n    }\n\n    /**\n     * Set \"widgetManager\" in EditSession\n     *\n     * @returns void\n     */\n    set widgetManager(value) {\n        Object.defineProperty(this, \"widgetManager\", {\n            writable: true,\n            enumerable: true,\n            configurable: true,\n            value: value,\n        });\n    }\n    /**\n     * @param {Number} docRow The row to work with\n     *\n     **/\n    $resetRowCache(docRow) {\n        if (!docRow) {\n            /** @type {number[]} */\n            this.$docRowCache = [];\n            /** @type {number[]} */\n            this.$screenRowCache = [];\n            return;\n        }\n        var l = this.$docRowCache.length;\n        var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;\n        if (l > i) {\n            this.$docRowCache.splice(i, l);\n            this.$screenRowCache.splice(i, l);\n        }\n    }\n\n    $getRowCacheIndex(cacheArray, val) {\n        var low = 0;\n        var hi = cacheArray.length - 1;\n\n        while (low <= hi) {\n            var mid = (low + hi) >> 1;\n            var c = cacheArray[mid];\n\n            if (val > c)\n                low = mid + 1;\n            else if (val < c)\n                hi = mid - 1;\n            else\n                return mid;\n        }\n\n        return low -1;\n    }\n\n    resetCaches() {\n        this.$modified = true;\n        this.$wrapData = [];\n        this.$rowLengthCache = [];\n        this.$resetRowCache(0);\n        if (!this.destroyed)\n            this.bgTokenizer.start(0);\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onChangeFold(e) {\n        var fold = e.data;\n        this.$resetRowCache(fold.start.row);\n    }\n\n    /**\n     *\n     * @param {Delta} delta\n     * @internal\n     */\n    onChange(delta) {\n        this.$modified = true;\n        this.$bidiHandler.onChange(delta);\n        this.$resetRowCache(delta.start.row);\n\n        var removedFolds = this.$updateInternalDataOnChange(delta);\n        if (!this.$fromUndo && this.$undoManager) {\n            if (removedFolds && removedFolds.length) {\n                this.$undoManager.add({\n                    // @ts-expect-error TODO: this action type is missing in the types\n                    action: \"removeFolds\",\n                    folds:  removedFolds\n                }, this.mergeUndoDeltas);\n                this.mergeUndoDeltas = true;\n            }\n            this.$undoManager.add(delta, this.mergeUndoDeltas);\n            this.mergeUndoDeltas = true;\n\n            this.$informUndoManager.schedule();\n        }\n\n        this.bgTokenizer.$updateOnChange(delta);\n        this._signal(\"change\", delta);\n    }\n\n    onSelectionChange() {\n        this._signal(\"changeSelection\");\n    }\n\n    /**\n     * Sets the session text.\n     * @param {String} text The new text to place\n     **/\n    setValue(text) {\n        this.doc.setValue(text);\n        this.selection.moveTo(0, 0);\n\n        this.$resetRowCache(0);\n        this.setUndoManager(this.$undoManager);\n        this.getUndoManager().reset();\n    }\n\n     /**\n     * Returns a new instance of EditSession with state from JSON.\n     * @method fromJSON\n     * @param {string|object} session The EditSession state.\n     * @returns {EditSession}\n     */\n    static fromJSON(session) {\n        if (typeof session == \"string\")\n            session = JSON.parse(session);\n        const undoManager = new UndoManager();\n        undoManager.$undoStack = session.history.$undoStack;\n        undoManager.$redoStack = session.history.$redoStack;\n        undoManager.mark = session.history.mark;\n        undoManager.$rev = session.history.rev;\n\n        const editSession = new EditSession(session.value);\n        session.folds.forEach(function(fold) {\n          editSession.addFold(\"...\", Range.fromPoints(fold.start, fold.end));\n        });\n        editSession.setAnnotations(session.annotations);\n        editSession.setBreakpoints(session.breakpoints);\n        editSession.setMode(session.mode);\n        editSession.setScrollLeft(session.scrollLeft);\n        editSession.setScrollTop(session.scrollTop);\n        editSession.setUndoManager(undoManager);\n        editSession.selection.fromJSON(session.selection);\n\n        return editSession;\n    }\n\n    /**\n     * Returns the current edit session.\n     * @method toJSON\n     * @returns {Object}\n     */\n    toJSON() {\n        return {\n            annotations: this.$annotations,\n            breakpoints: this.$breakpoints,\n            folds: this.getAllFolds().map(function(fold) {\n                return fold.range;\n            }),\n            history: this.getUndoManager(),\n            mode: this.$mode.$id,\n            scrollLeft: this.$scrollLeft,\n            scrollTop: this.$scrollTop,\n            selection: this.selection.toJSON(),\n            value: this.doc.getValue()\n        };\n    }\n\n    /**\n     * Returns the current [[Document `Document`]] as a string.\n     * @method toString\n     * @returns {String}\n     * @alias EditSession.getValue\n     *\n     **/\n    toString() {\n        return this.doc.getValue();\n    }\n\n    /**\n     * Returns selection object.\n     * @returns {Selection}\n     **/\n    getSelection() {\n        return this.selection;\n    }\n\n    /**\n     * {:BackgroundTokenizer.getState}\n     * @param {Number} row The row to start at\n     * @returns {string | string[]}\n     * @related BackgroundTokenizer.getState\n     **/\n    getState(row) {\n        return this.bgTokenizer.getState(row);\n    }\n\n    /**\n     * Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.\n     * @param {Number} row The row to start at\n     * @returns {import(\"../ace-internal\").Ace.Token[]}\n     **/\n    getTokens(row) {\n        return this.bgTokenizer.getTokens(row);\n    }\n\n    /**\n     * Returns an object indicating the token at the current row. The object has two properties: `index` and `start`.\n     * @param {Number} row The row number to retrieve from\n     * @param {Number} column The column number to retrieve from\n     * @returns {import(\"../ace-internal\").Ace.Token}\n     *\n     **/\n    getTokenAt(row, column) {\n        var tokens = this.bgTokenizer.getTokens(row);\n        var token, c = 0;\n        if (column == null) {\n            var i = tokens.length - 1;\n            c = this.getLine(row).length;\n        } else {\n            for (var i = 0; i < tokens.length; i++) {\n                c += tokens[i].value.length;\n                if (c >= column)\n                    break;\n            }\n        }\n        token = tokens[i];\n        if (!token)\n            return null;\n        token.index = i;\n        token.start = c - token.value.length;\n        return token;\n    }\n\n    /**\n     * Sets the undo manager.\n     * @param {UndoManager} undoManager The new undo manager\n     **/\n    setUndoManager(undoManager) {\n        this.$undoManager = undoManager;\n\n        if (this.$informUndoManager)\n            this.$informUndoManager.cancel();\n\n        if (undoManager) {\n            var self = this;\n            undoManager.addSession(this);\n            this.$syncInformUndoManager = function() {\n                self.$informUndoManager.cancel();\n                self.mergeUndoDeltas = false;\n            };\n            this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);\n        } else {\n            this.$syncInformUndoManager = function() {};\n        }\n    }\n\n    /**\n     * starts a new group in undo history\n     **/\n    markUndoGroup() {\n        if (this.$syncInformUndoManager)\n            this.$syncInformUndoManager();\n    }\n\n    /**\n     * Returns the current undo manager.\n     * @returns {UndoManager}\n     **/\n    getUndoManager() {\n        // @ts-ignore\n        return this.$undoManager || this.$defaultUndoManager;\n    }\n\n    /**\n     * Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by [[EditSession.getTabSize `getTabSize()`]]); otherwise it's simply `'\\t'`.\n     * @returns {String}\n     **/\n    getTabString() {\n        if (this.getUseSoftTabs()) {\n            return lang.stringRepeat(\" \", this.getTabSize());\n        } else {\n            return \"\\t\";\n        }\n    }\n\n    /**\n     * Pass `true` to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character (`'\\t'`).\n     * @param {Boolean} val Value indicating whether or not to use soft tabs\n     **/\n    setUseSoftTabs(val) {\n        this.setOption(\"useSoftTabs\", val);\n    }\n\n    /**\n     * Returns `true` if soft tabs are being used, `false` otherwise.\n     * @returns {Boolean}\n     **/\n    getUseSoftTabs() {\n        // todo might need more general way for changing settings from mode, but this is ok for now\n        return this.$useSoftTabs && !this.$mode.$indentWithTabs;\n    }\n    /**\n     * Set the number of spaces that define a soft tab; for example, passing in `4` transforms the soft tabs to be equivalent to four spaces. This function also emits the `changeTabSize` event.\n     * @param {Number} tabSize The new tab size\n     **/\n    setTabSize(tabSize) {\n        this.setOption(\"tabSize\", tabSize);\n    }\n    /**\n     * Returns the current tab size.\n     * @return {number}\n     **/\n    getTabSize() {\n        return this.$tabSize;\n    }\n\n    /**\n     * Returns `true` if the character at the position is a soft tab.\n     * @param {Point} position The position to check\n     **/\n    isTabStop(position) {\n        return this.$useSoftTabs && (position.column % this.$tabSize === 0);\n    }\n\n    /**\n     * Set whether keyboard navigation of soft tabs moves the cursor within the soft tab, rather than over\n     * @param {Boolean} navigateWithinSoftTabs Value indicating whether or not to navigate within soft tabs\n     **/\n    setNavigateWithinSoftTabs(navigateWithinSoftTabs) {\n        this.setOption(\"navigateWithinSoftTabs\", navigateWithinSoftTabs);\n    }\n    /**\n     * Returns `true` if keyboard navigation moves the cursor within soft tabs, `false` if it moves the cursor over soft tabs.\n     * @returns {Boolean}\n     **/\n    getNavigateWithinSoftTabs() {\n        return this.$navigateWithinSoftTabs;\n    }\n\n    /**\n     * Pass in `true` to enable overwrites in your session, or `false` to disable.\n     *\n     * If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n     *\n     * @param {Boolean} overwrite Defines whether or not to set overwrites\n     *\n     **/\n    setOverwrite(overwrite) {\n        this.setOption(\"overwrite\", overwrite);\n    }\n\n    /**\n     * Returns `true` if overwrites are enabled; `false` otherwise.\n     **/\n    getOverwrite() {\n        return this.$overwrite;\n    }\n\n    /**\n     * Sets the value of overwrite to the opposite of whatever it currently is.\n     **/\n    toggleOverwrite() {\n        this.setOverwrite(!this.$overwrite);\n    }\n\n    /**\n     * Adds `className` to the `row`, to be used for CSS stylings and whatnot.\n     * @param {Number} row The row number\n     * @param {String} className The class to add\n     **/\n    addGutterDecoration(row, className) {\n        if (!this.$decorations[row])\n            this.$decorations[row] = \"\";\n        this.$decorations[row] += \" \" + className;\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Replaces the custom icon with the fold widget if present from a specific row in the gutter\n     * @param {number} row The row number for which to hide the custom icon\n     * @experimental\n     */\n    removeGutterCustomWidget(row) {\n        if(this.$editor) {\n            this.$editor.renderer.$gutterLayer.$removeCustomWidget(row);\n        }\n    }\n\n    /**\n     * Replaces the fold widget if present with the custom icon from a specific row in the gutter\n     * @param {number} row - The row number where the widget will be displayed\n     * @param {Object} attributes - Configuration attributes for the widget\n     * @param {string} attributes.className - CSS class name for styling the widget\n     * @param {string} attributes.label - Text label to display in the widget\n     * @param {string} attributes.title - Tooltip text for the widget\n     * @param {Object} attributes.callbacks - Event callback functions for the widget e.g onClick; \n     * @returns {void}\n     * @experimental\n    */\n    addGutterCustomWidget(row,attributes) {\n        if(this.$editor) {\n            this.$editor.renderer.$gutterLayer.$addCustomWidget(row,attributes);\n        }\n    }\n\n    /**\n     * Removes `className` from the `row`.\n     * @param {Number} row The row number\n     * @param {String} className The class to add\n     **/\n    removeGutterDecoration(row, className) {\n        this.$decorations[row] = (this.$decorations[row] || \"\").replace(\" \" + className, \"\");\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Returns an array of strings, indicating the breakpoint class (if any) applied to each row.\n     * @returns {String[]}\n     **/\n    getBreakpoints() {\n        return this.$breakpoints;\n    }\n\n    /**\n     * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event.\n     * @param {number[]} rows An array of row indices\n     **/\n    setBreakpoints(rows) {\n        this.$breakpoints = [];\n        for (var i=0; i<rows.length; i++) {\n            this.$breakpoints[rows[i]] = \"ace_breakpoint\";\n        }\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Removes all breakpoints on the rows. This function also emits the `'changeBreakpoint'` event.\n     **/\n    clearBreakpoints() {\n        this.$breakpoints = [];\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Sets a breakpoint on the row number given by `row`. This function also emits the `'changeBreakpoint'` event.\n     * @param {Number} row A row index\n     * @param {String} className Class of the breakpoint\n     **/\n    setBreakpoint(row, className) {\n        if (className === undefined)\n            className = \"ace_breakpoint\";\n        if (className)\n            this.$breakpoints[row] = className;\n        else\n            delete this.$breakpoints[row];\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Removes a breakpoint on the row number given by `row`. This function also emits the `'changeBreakpoint'` event.\n     * @param {Number} row A row index\n     **/\n    clearBreakpoint(row) {\n        delete this.$breakpoints[row];\n        this._signal(\"changeBreakpoint\", {});\n    }\n\n    /**\n     * Adds a new marker to the given `Range`. If `inFront` is `true`, a front marker is defined, and the `'changeFrontMarker'` event fires; otherwise, the `'changeBackMarker'` event fires.\n     * @param {Range} range Define the range of the marker\n     * @param {String} clazz Set the CSS class for the marker\n     * @param {import(\"../ace-internal\").Ace.MarkerRenderer | \"fullLine\" | \"screenLine\" | \"text\" | \"line\"} [type] Identify the renderer type of the marker. If string provided, corresponding built-in renderer is used. Supported string types are \"fullLine\", \"screenLine\", \"text\" or \"line\". If a Function is provided, that Function is used as renderer.\n     * @param {Boolean} [inFront] Set to `true` to establish a front marker\n     *\n     * @return {Number} The new marker id\n     **/\n    addMarker(range, clazz, type, inFront) {\n        var id = this.$markerId++;\n\n        var marker = {\n            range : range,\n            type : type || \"line\",\n            renderer: typeof type == \"function\" ? type : null,\n            clazz : clazz,\n            inFront: !!inFront,\n            id: id\n        };\n\n        if (inFront) {\n            this.$frontMarkers[id] = marker;\n            this._signal(\"changeFrontMarker\");\n        } else {\n            this.$backMarkers[id] = marker;\n            this._signal(\"changeBackMarker\");\n        }\n\n        return id;\n    }\n\n    /**\n     * Adds a dynamic marker to the session.\n     * @param {import(\"../ace-internal\").Ace.MarkerLike} marker object with update method\n     * @param {Boolean} [inFront] Set to `true` to establish a front marker\n     *\n     * @return {import(\"../ace-internal\").Ace.MarkerLike} The added marker\n     **/\n    addDynamicMarker(marker, inFront) {\n        if (!marker.update)\n            return;\n        var id = this.$markerId++;\n        marker.id = id;\n        marker.inFront = !!inFront;\n\n        if (inFront) {\n            this.$frontMarkers[id] = marker;\n            this._signal(\"changeFrontMarker\");\n        } else {\n            this.$backMarkers[id] = marker;\n            this._signal(\"changeBackMarker\");\n        }\n\n        return marker;\n    }\n\n    /**\n     * Removes the marker with the specified ID. If this marker was in front, the `'changeFrontMarker'` event is emitted. If the marker was in the back, the `'changeBackMarker'` event is emitted.\n     * @param {Number} markerId A number representing a marker\n     **/\n    removeMarker(markerId) {\n        var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];\n        if (!marker)\n            return;\n\n        var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;\n        delete (markers[markerId]);\n        this._signal(marker.inFront ? \"changeFrontMarker\" : \"changeBackMarker\");\n    }\n\n    /**\n     * Returns an object containing all of the markers, either front or back.\n     * @param {Boolean} [inFront] If `true`, indicates you only want front markers; `false` indicates only back markers\n     *\n     * @returns {{[id: number]: import(\"../ace-internal\").Ace.MarkerLike}}\n     **/\n    getMarkers(inFront) {\n        return inFront ? this.$frontMarkers : this.$backMarkers;\n    }\n\n    /**\n     * @param {RegExp} re\n     */\n    highlight(re) {\n        if (!this.$searchHighlight) {\n            var highlight = new SearchHighlight(null, \"ace_selected-word\", \"text\");\n            this.$searchHighlight = this.addDynamicMarker(highlight);\n        }\n        this.$searchHighlight.setRegexp(re);\n    }\n\n    /**\n     * experimental\n     * @param {number} startRow\n     * @param {number} endRow\n     * @param {string} clazz\n     * @param {boolean} [inFront]\n     * @return {Range}\n     */\n    highlightLines(startRow, endRow, clazz, inFront) {\n        if (typeof endRow != \"number\") {\n            clazz = endRow;\n            endRow = startRow;\n        }\n        if (!clazz)\n            clazz = \"ace_step\";\n\n        var range = new Range(startRow, 0, endRow, Infinity);\n        range.id = this.addMarker(range, clazz, \"fullLine\", inFront);\n        return range;\n    }\n\n    /*\n     * Error:\n     *  {\n     *    row: 12,\n     *    column: 2, //can be undefined\n     *    text: \"Missing argument\",\n     *    type: \"error\" // or \"warning\" or \"info\"\n     *  }\n     */\n    /**\n     * Sets annotations for the `EditSession`. This functions emits the `'changeAnnotation'` event.\n     * @param {import(\"../ace-internal\").Ace.Annotation[]} annotations A list of annotations\n     **/\n    setAnnotations(annotations) {\n        this.$annotations = annotations;\n        this._signal(\"changeAnnotation\", {});\n    }\n\n    /**\n     * Returns the annotations for the `EditSession`.\n     * @returns {import(\"../ace-internal\").Ace.Annotation[]}\n     **/\n    getAnnotations() {\n        return this.$annotations || [];\n    }\n\n    /**\n     * Clears all the annotations for this session. This function also triggers the `'changeAnnotation'` event.\n     **/\n    clearAnnotations() {\n        this.setAnnotations([]);\n    }\n\n    /**\n     * If `text` contains either the newline (`\\n`) or carriage-return ('\\r') characters, `$autoNewLine` stores that value.\n     * @param {String} text A block of text\n     *\n     **/\n    $detectNewLine(text) {\n        var match = text.match(/^.*?(\\r?\\n)/m);\n        if (match) {\n            this.$autoNewLine = match[1];\n        } else {\n            this.$autoNewLine = \"\\n\";\n        }\n    }\n\n    /**\n     * Given a starting row and column, this method returns the `Range` of the first word boundary it finds.\n     * @param {Number} row The row to start at\n     * @param {Number} column The column to start at\n     *\n     * @returns {Range}\n     **/\n    getWordRange(row, column) {\n        var line = this.getLine(row);\n\n        var inToken = false;\n        if (column > 0)\n            inToken = !!line.charAt(column - 1).match(this.tokenRe);\n\n        if (!inToken)\n            inToken = !!line.charAt(column).match(this.tokenRe);\n\n        if (inToken)\n            var re = this.tokenRe;\n        else if (/^\\s+$/.test(line.slice(column-1, column+1)))\n            var re = /\\s/;\n        else\n            var re = this.nonTokenRe;\n\n        var start = column;\n        if (start > 0) {\n            do {\n                start--;\n            }\n            while (start >= 0 && line.charAt(start).match(re));\n            start++;\n        }\n\n        var end = column;\n        while (end < line.length && line.charAt(end).match(re)) {\n            end++;\n        }\n\n        return new Range(row, start, row, end);\n    }\n\n    /**\n     * Gets the range of a word, including its right whitespace.\n     * @param {Number} row The row number to start from\n     * @param {Number} column The column number to start from\n     *\n     * @return {Range}\n     **/\n    getAWordRange(row, column) {\n        var wordRange = this.getWordRange(row, column);\n        var line = this.getLine(wordRange.end.row);\n\n        while (line.charAt(wordRange.end.column).match(/[ \\t]/)) {\n            wordRange.end.column += 1;\n        }\n        return wordRange;\n    }\n\n    /**\n     * {:Document.setNewLineMode.desc}\n     * @param {import(\"../ace-internal\").Ace.NewLineMode} newLineMode {:Document.setNewLineMode.param}\n     *\n     *\n     * @related Document.setNewLineMode\n     **/\n    setNewLineMode(newLineMode) {\n        this.doc.setNewLineMode(newLineMode);\n    }\n\n    /**\n     *\n     * Returns the current new line mode.\n     * @returns {import(\"../ace-internal\").Ace.NewLineMode}\n     * @related Document.getNewLineMode\n     **/\n    getNewLineMode() {\n        return this.doc.getNewLineMode();\n    }\n\n    /**\n     * Identifies if you want to use a worker for the `EditSession`.\n     * @param {Boolean} useWorker Set to `true` to use a worker\n     **/\n    setUseWorker(useWorker) { this.setOption(\"useWorker\", useWorker); }\n\n    /**\n     * Returns `true` if workers are being used.\n     **/\n    getUseWorker() { return this.$useWorker; }\n\n    /**\n     * Reloads all the tokens on the current session. This function calls [[BackgroundTokenizer.start `BackgroundTokenizer.start ()`]] to all the rows; it also emits the `'tokenizerUpdate'` event.\n     * @internal\n     **/\n    onReloadTokenizer(e) {\n        var rows = e.data;\n        this.bgTokenizer.start(rows.first);\n        this._signal(\"tokenizerUpdate\", e);\n    }\n\n    /**\n     * Sets a new text mode for the `EditSession`. This method also emits the `'changeMode'` event. If a [[BackgroundTokenizer `BackgroundTokenizer`]] is set, the `'tokenizerUpdate'` event is also emitted.\n     * @param {SyntaxMode | string} mode Set a new text mode\n     * @param {() => void} [cb] optional callback\n     **/\n    setMode(mode, cb) {\n        if (mode && typeof mode === \"object\") {\n            if (mode.getTokenizer)\n                return this.$onChangeMode(mode);\n            var options = mode;\n            var path = options.path;\n        } else {\n            path = /**@type{string}*/(mode) || \"ace/mode/text\";\n        }\n\n        // this is needed if ace isn't on require path (e.g tests in node)\n        if (!this.$modes[\"ace/mode/text\"])\n            this.$modes[\"ace/mode/text\"] = new TextMode();\n\n        if (this.$modes[path] && !options) {\n            this.$onChangeMode(this.$modes[path]);\n            cb && cb();\n            return;\n        }\n        // load on demand\n        this.$modeId = path;\n        config.loadModule([\"mode\", path], function(m) {\n            if (this.destroyed) {\n                return;\n            }\n            if (this.$modeId !== path)\n                return cb && cb();\n            if (this.$modes[path] && !options) {\n                this.$onChangeMode(this.$modes[path]);\n            } else if (m && m.Mode) {\n                m = new m.Mode(options);\n                if (!options) {\n                    this.$modes[path] = m;\n                    m.$id = path;\n                }\n                this.$onChangeMode(m);\n            }\n            cb && cb();\n        }.bind(this));\n\n        // set mode to text until loading is finished\n        if (!this.$mode)\n            this.$onChangeMode(this.$modes[\"ace/mode/text\"], true);\n    }\n\n    /**\n     * @param mode\n     * @param [$isPlaceholder]\n     */\n    $onChangeMode(mode, $isPlaceholder) {\n        if (!$isPlaceholder)\n            this.$modeId = mode.$id;\n        if (this.$mode === mode)\n            return;\n\n        var oldMode = this.$mode;\n        this.$mode = mode;\n\n        this.$stopWorker();\n\n        if (this.$useWorker)\n            this.$startWorker();\n\n        var tokenizer = mode.getTokenizer();\n\n        if(tokenizer.on !== undefined) {\n            var onReloadTokenizer = this.onReloadTokenizer.bind(this);\n            tokenizer.on(\"update\", onReloadTokenizer);\n        }\n\n        this.bgTokenizer.setTokenizer(tokenizer);\n        this.bgTokenizer.setDocument(this.getDocument());\n\n        /**@type {RegExp}*/\n        this.tokenRe = mode.tokenRe;\n        /**@type {RegExp}*/\n        this.nonTokenRe = mode.nonTokenRe;\n\n\n        if (!$isPlaceholder) {\n            // experimental method, used by c9 findiniles\n            if (mode.attachToSession)\n                mode.attachToSession(this);\n            this.$options.wrapMethod.set.call(this, this.$wrapMethod);\n            this.$setFolding(mode.foldingRules);\n            this.bgTokenizer.start(0);\n            this._emit(\"changeMode\", {oldMode: oldMode, mode: mode});\n        }\n    }\n\n    $stopWorker() {\n        if (this.$worker) {\n            this.$worker.terminate();\n            this.$worker = null;\n        }\n    }\n\n    $startWorker() {\n        try {\n            this.$worker = this.$mode.createWorker(this);\n        } catch (e) {\n            config.warn(\"Could not load worker\", e);\n            this.$worker = null;\n        }\n    }\n\n    /**\n     * Returns the current text mode.\n     * @returns {TextMode} The current text mode\n     **/\n    getMode() {\n        return this.$mode;\n    }\n\n    /**\n     * This function sets the scroll top value. It also emits the `'changeScrollTop'` event.\n     * @param {Number} scrollTop The new scroll top value\n     **/\n    setScrollTop(scrollTop) {\n        // TODO: should we force integer lineheight instead? scrollTop = Math.round(scrollTop);\n        if (this.$scrollTop === scrollTop || isNaN(scrollTop))\n            return;\n\n        this.$scrollTop = scrollTop;\n        this._signal(\"changeScrollTop\", scrollTop);\n    }\n\n    /**\n     * [Returns the value of the distance between the top of the editor and the topmost part of the visible content.]{: #EditSession.getScrollTop}\n     * @returns {Number}\n     **/\n    getScrollTop() {\n        return this.$scrollTop;\n    }\n\n    /**\n     * [Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.setScrollLeft}\n     * @param {number} scrollLeft\n     */\n    setScrollLeft(scrollLeft) {\n        // scrollLeft = Math.round(scrollLeft);\n        if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))\n            return;\n\n        this.$scrollLeft = scrollLeft;\n        this._signal(\"changeScrollLeft\", scrollLeft);\n    }\n\n    /**\n     * [Returns the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.getScrollLeft}\n     * @returns {Number}\n     **/\n    getScrollLeft() {\n        return this.$scrollLeft;\n    }\n\n    /**\n     * Returns the width of the screen.\n     * @returns {Number}\n     **/\n    getScreenWidth() {\n        this.$computeWidth();\n        if (this.lineWidgets)\n            return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);\n        return this.screenWidth;\n    }\n\n    /**\n     * @return {number}\n     */\n    getLineWidgetMaxWidth() {\n        if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;\n        var width = 0;\n        this.lineWidgets.forEach(function(w) {\n            if (w && w.screenWidth > width)\n                width = w.screenWidth;\n        });\n        return this.lineWidgetWidth = width;\n    }\n\n    /**\n     * @param {boolean} [force]\n     */\n    $computeWidth(force) {\n        if (this.$modified || force) {\n            this.$modified = false;\n\n            if (this.$useWrapMode)\n                return this.screenWidth = this.$wrapLimit;\n\n            var lines = this.doc.getAllLines();\n            var cache = this.$rowLengthCache;\n            var longestScreenLine = 0;\n            var foldIndex = 0;\n            var foldLine = this.$foldData[foldIndex];\n            var foldStart = foldLine ? foldLine.start.row : Infinity;\n            var len = lines.length;\n\n            for (var i = 0; i < len; i++) {\n                if (i > foldStart) {\n                    i = foldLine.end.row + 1;\n                    if (i >= len)\n                        break;\n                    foldLine = this.$foldData[foldIndex++];\n                    foldStart = foldLine ? foldLine.start.row : Infinity;\n                }\n\n                if (cache[i] == null)\n                    cache[i] = this.$getStringScreenWidth(lines[i])[0];\n\n                if (cache[i] > longestScreenLine)\n                    longestScreenLine = cache[i];\n            }\n            this.screenWidth = longestScreenLine;\n        }\n    }\n\n    /**\n     * Returns a verbatim copy of the given line as it is in the document\n     * @param {Number} row The row to retrieve from\n     * @returns {String}\n     **/\n    getLine(row) {\n        return this.doc.getLine(row);\n    }\n\n    /**\n     * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.\n     * @param {Number} firstRow The first row index to retrieve\n     * @param {Number} lastRow The final row index to retrieve\n     *\n     * @returns {String[]}\n     *\n     **/\n    getLines(firstRow, lastRow) {\n        return this.doc.getLines(firstRow, lastRow);\n    }\n\n    /**\n     * Returns the number of rows in the document.\n     * @returns {Number}\n     **/\n    getLength() {\n        return this.doc.getLength();\n    }\n\n    /**\n     * {:Document.getTextRange.desc}\n     * @param {IRange} [range] The range to work with\n     *\n     * @returns {String}\n     **/\n    getTextRange(range) {\n        return this.doc.getTextRange(range || this.selection.getRange());\n    }\n\n    /**\n     * Inserts a block of `text` and the indicated `position`.\n     * @param {Point} position The position {row, column} to start inserting at\n     * @param {String} text A chunk of text to insert\n     * @returns {Point} The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.\n     **/\n    insert(position, text) {\n        return this.doc.insert(position, text);\n    }\n\n    /**\n     * Removes the `range` from the document.\n     * @param {IRange} range A specified Range to remove\n     * @returns {Point} The new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.\n     **/\n    remove(range) {\n        return this.doc.remove(range);\n    }\n\n    /**\n     * Removes a range of full lines. This method also triggers the `'change'` event.\n     * @param {Number} firstRow The first row to be removed\n     * @param {Number} lastRow The last row to be removed\n     * @returns {String[]} Returns all the removed lines.\n     *\n     * @related Document.removeFullLines\n     *\n     **/\n    removeFullLines(firstRow, lastRow){\n        return this.doc.removeFullLines(firstRow, lastRow);\n    }\n\n    /**\n     * Reverts previous changes to your document.\n     * @param {Delta[]} deltas An array of previous changes\n     * @param {Boolean} [dontSelect] If `true`, doesn't select the range of where the change occured\n     **/\n    undoChanges(deltas, dontSelect) {\n        if (!deltas.length)\n            return;\n\n        this.$fromUndo = true;\n        for (var i = deltas.length - 1; i != -1; i--) {\n            var delta = deltas[i];\n            if (delta.action == \"insert\" || delta.action == \"remove\") {\n                this.doc.revertDelta(delta);\n            } else if (delta.folds) {\n                this.addFolds(delta.folds);\n            }\n        }\n        if (!dontSelect && this.$undoSelect) {\n            //@ts-expect-error TODO: potential wrong property\n            if (deltas.selectionBefore)\n                //@ts-expect-error TODO: potential wrong property\n                this.selection.fromJSON(deltas.selectionBefore);\n            else\n                this.selection.setRange(this.$getUndoSelection(deltas, true));\n        }\n        this.$fromUndo = false;\n    }\n\n    /**\n     * Re-implements a previously undone change to your document.\n     * @param {Delta[]} deltas An array of previous changes\n     * @param {Boolean} [dontSelect] {:dontSelect}\n     **/\n    redoChanges(deltas, dontSelect) {\n        if (!deltas.length)\n            return;\n\n        this.$fromUndo = true;\n        for (var i = 0; i < deltas.length; i++) {\n            var delta = deltas[i];\n            if (delta.action == \"insert\" || delta.action == \"remove\") {\n                this.doc.$safeApplyDelta(delta);\n            }\n        }\n\n        if (!dontSelect && this.$undoSelect) {\n            //@ts-expect-error TODO: potential wrong property\n            if (deltas.selectionAfter)\n                //@ts-expect-error TODO: potential wrong property\n                this.selection.fromJSON(deltas.selectionAfter);\n            else\n                this.selection.setRange(this.$getUndoSelection(deltas, false));\n        }\n        this.$fromUndo = false;\n    }\n\n    /**\n     * Enables or disables highlighting of the range where an undo occurred.\n     * @param {Boolean} enable If `true`, selects the range of the reinserted change\n     *\n     **/\n    setUndoSelect(enable) {\n        this.$undoSelect = enable;\n    }\n\n    /**\n     *\n     * @param {Delta[]} deltas\n     * @param {boolean} [isUndo]\n     * @return {Range}\n     */\n    $getUndoSelection(deltas, isUndo) {\n        function isInsert(delta) {\n            return isUndo ? delta.action !== \"insert\" : delta.action === \"insert\";\n        }\n\n        var range, point;\n\n        for (var i = 0; i < deltas.length; i++) {\n            var delta = deltas[i];\n            if (!delta.start) continue; // skip folds\n            if (!range) {\n                if (isInsert(delta)) {\n                    range = Range.fromPoints(delta.start, delta.end);\n                } else {\n                    range = Range.fromPoints(delta.start, delta.start);\n                }\n                continue;\n            }\n\n            if (isInsert(delta)) {\n                point = delta.start;\n                if (range.compare(point.row, point.column) == -1) {\n                    range.setStart(point);\n                }\n                point = delta.end;\n                if (range.compare(point.row, point.column) == 1) {\n                    range.setEnd(point);\n                }\n            } else {\n                point = delta.start;\n                if (range.compare(point.row, point.column) == -1) {\n                    range = Range.fromPoints(delta.start, delta.start);\n                }\n            }\n        }\n        return range;\n    }\n\n    /**\n     * Replaces a range in the document with the new `text`.\n     *\n     * @param {IRange} range A specified Range to replace\n     * @param {String} text The new text to use as a replacement\n     * @returns {Point} An object containing the final row and column, like this:\n     * ```\n     * {row: endRow, column: 0}\n     * ```\n     * If the text and range are empty, this function returns an object containing the current `range.start` value.\n     * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.\n     *\n     * @related Document.replace\n     **/\n    replace(range, text) {\n        return this.doc.replace(range, text);\n    }\n\n    /**\n     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n     *  ```json\n     *    { row: newRowLocation, column: newColumnLocation }\n     *  ```\n     * @param {Range} fromRange The range of text you want moved within the document\n     * @param {Point} toPosition The location (row and column) where you want to move the text to\n     * @param {boolean} [copy]\n     * @returns {Range} The new range where the text was moved to.\n     **/\n    moveText(fromRange, toPosition, copy) {\n        var text = this.getTextRange(fromRange);\n        var folds = this.getFoldsInRange(fromRange);\n\n        var toRange = Range.fromPoints(toPosition, toPosition);\n        if (!copy) {\n            this.remove(fromRange);\n            var rowDiff = fromRange.start.row - fromRange.end.row;\n            var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;\n            if (collDiff) {\n                if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)\n                    toRange.start.column += collDiff;\n                if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)\n                    toRange.end.column += collDiff;\n            }\n            if (rowDiff && toRange.start.row >= fromRange.end.row) {\n                toRange.start.row += rowDiff;\n                toRange.end.row += rowDiff;\n            }\n        }\n\n        toRange.end = this.insert(toRange.start, text);\n        if (folds.length) {\n            var oldStart = fromRange.start;\n            var newStart = toRange.start;\n            var rowDiff = newStart.row - oldStart.row;\n            var collDiff = newStart.column - oldStart.column;\n            this.addFolds(folds.map(function(x) {\n                x = x.clone();\n                if (x.start.row == oldStart.row)\n                    x.start.column += collDiff;\n                if (x.end.row == oldStart.row)\n                    x.end.column += collDiff;\n                x.start.row += rowDiff;\n                x.end.row += rowDiff;\n                return x;\n            }));\n        }\n\n        return toRange;\n    }\n\n    /**\n     * Indents all the rows, from `startRow` to `endRow` (inclusive), by prefixing each row with the token in `indentString`.\n     *\n     * If `indentString` contains the `'\\t'` character, it's replaced by whatever is defined by [[EditSession.getTabString `getTabString()`]].\n     * @param {Number} startRow Starting row\n     * @param {Number} endRow Ending row\n     * @param {String} indentString The indent token\n     **/\n    indentRows(startRow, endRow, indentString) {\n        indentString = indentString.replace(/\\t/g, this.getTabString());\n        for (var row=startRow; row<=endRow; row++)\n            this.doc.insertInLine({row: row, column: 0}, indentString);\n    }\n\n    /**\n     * Outdents all the rows defined by the `start` and `end` properties of `range`.\n     * @param {Range} range A range of rows\n     **/\n    outdentRows(range) {\n        var rowRange = range.collapseRows();\n        var deleteRange = new Range(0, 0, 0, 0);\n        var size = this.getTabSize();\n\n        for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {\n            var line = this.getLine(i);\n\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            for (var j = 0; j < size; ++j)\n                if (line.charAt(j) != ' ')\n                    break;\n            if (j < size && line.charAt(j) == '\\t') {\n                deleteRange.start.column = j;\n                deleteRange.end.column = j + 1;\n            } else {\n                deleteRange.start.column = 0;\n                deleteRange.end.column = j;\n            }\n            this.remove(deleteRange);\n        }\n    }\n\n    /**\n     *\n     * @param {number} firstRow\n     * @param {number} lastRow\n     * @param [dir]\n     * @returns {number}\n     */\n    $moveLines(firstRow, lastRow, dir) {\n        firstRow = this.getRowFoldStart(firstRow);\n        lastRow = this.getRowFoldEnd(lastRow);\n        if (dir < 0) {\n            var row = this.getRowFoldStart(firstRow + dir);\n            if (row < 0) return 0;\n            var diff = row-firstRow;\n        } else if (dir > 0) {\n            var row = this.getRowFoldEnd(lastRow + dir);\n            if (row > this.doc.getLength()-1) return 0;\n            var diff = row-lastRow;\n        } else {\n            firstRow = this.$clipRowToDocument(firstRow);\n            lastRow = this.$clipRowToDocument(lastRow);\n            var diff = lastRow - firstRow + 1;\n        }\n\n        var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);\n        var folds = this.getFoldsInRange(range).map(function(x){\n            x = x.clone();\n            x.start.row += diff;\n            x.end.row += diff;\n            return x;\n        });\n\n        var lines = dir == 0\n            ? this.doc.getLines(firstRow, lastRow)\n            : this.doc.removeFullLines(firstRow, lastRow);\n        this.doc.insertFullLines(firstRow+diff, lines);\n        folds.length && this.addFolds(folds);\n        return diff;\n    }\n    /**\n     * Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`.\n     * @param {Number} firstRow The starting row to move up\n     * @param {Number} lastRow The final row to move up\n     * @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.\n     **/\n    moveLinesUp(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, -1);\n    }\n\n    /**\n     * Shifts all the lines in the document down one, starting from `firstRow` and ending at `lastRow`.\n     * @param {Number} firstRow The starting row to move down\n     * @param {Number} lastRow The final row to move down\n     * @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.\n     **/\n    moveLinesDown(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, 1);\n    }\n\n    /**\n     * Duplicates all the text between `firstRow` and `lastRow`.\n     * @param {Number} firstRow The starting row to duplicate\n     * @param {Number} lastRow The final row to duplicate\n     * @returns {Number} Returns the number of new rows added; in other words, `lastRow - firstRow + 1`.\n     **/\n    duplicateLines(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, 0);\n    }\n\n    /**\n     * @param {number} row\n     * @returns {number}\n     */\n    $clipRowToDocument(row) {\n        return Math.max(0, Math.min(row, this.doc.getLength()-1));\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @returns {number}\n     */\n    $clipColumnToRow(row, column) {\n        if (column < 0) return 0;\n        return Math.min(this.doc.getLine(row).length, column);\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     * @returns {Point}\n     */\n    $clipPositionToDocument(row, column) {\n        column = Math.max(0, column);\n\n        if (row < 0) {\n            row = 0;\n            column = 0;\n        } else {\n            var len = this.doc.getLength();\n            if (row >= len) {\n                row = len - 1;\n                column = this.doc.getLine(len-1).length;\n            } else {\n                column = Math.min(this.doc.getLine(row).length, column);\n            }\n        }\n\n        return {\n            row: row,\n            column: column\n        };\n    }\n\n    /**\n     * @param {Range} range\n     * @returns {Range}\n     */\n    $clipRangeToDocument(range) {\n        if (range.start.row < 0) {\n            range.start.row = 0;\n            range.start.column = 0;\n        } else {\n            range.start.column = this.$clipColumnToRow(\n                range.start.row,\n                range.start.column\n            );\n        }\n\n        var len = this.doc.getLength() - 1;\n        if (range.end.row > len) {\n            range.end.row = len;\n            range.end.column = this.doc.getLine(len).length;\n        } else {\n            range.end.column = this.$clipColumnToRow(\n                range.end.row,\n                range.end.column\n            );\n        }\n        return range;\n    }\n\n    /**\n     * Sets whether or not line wrapping is enabled. If `useWrapMode` is different than the current value, the `'changeWrapMode'` event is emitted.\n     * @param {Boolean} useWrapMode Enable (or disable) wrap mode\n     **/\n    setUseWrapMode(useWrapMode) {\n        if (useWrapMode != this.$useWrapMode) {\n            this.$useWrapMode = useWrapMode;\n            this.$modified = true;\n            this.$resetRowCache(0);\n\n            // If wrapMode is activaed, the wrapData array has to be initialized.\n            if (useWrapMode) {\n                var len = this.getLength();\n                this.$wrapData = Array(len);\n                this.$updateWrapData(0, len - 1);\n            }\n\n            this._signal(\"changeWrapMode\");\n        }\n    }\n\n    /**\n     * Returns `true` if wrap mode is being used; `false` otherwise.\n     * @returns {Boolean}\n     **/\n    getUseWrapMode() {\n        return this.$useWrapMode;\n    }\n\n    // Allow the wrap limit to move freely between min and max. Either\n    // parameter can be null to allow the wrap limit to be unconstrained\n    // in that direction. Or set both parameters to the same number to pin\n    // the limit to that value.\n    /**\n     * Sets the boundaries of wrap. Either value can be `null` to have an unconstrained wrap, or, they can be the same number to pin the limit. If the wrap limits for `min` or `max` are different, this method also emits the `'changeWrapMode'` event.\n     * @param {Number} min The minimum wrap value (the left side wrap)\n     * @param {Number} max The maximum wrap value (the right side wrap)\n     **/\n    setWrapLimitRange(min, max) {\n        if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {\n            this.$wrapLimitRange = { min: min, max: max };\n            this.$modified = true;\n            this.$bidiHandler.markAsDirty();\n\n            // This will force a recalculation of the wrap limit\n            if (this.$useWrapMode)\n                this._signal(\"changeWrapMode\");\n        }\n    }\n\n    /**\n     * This should generally only be called by the renderer when a resize is detected.\n     * @param {Number} desiredLimit The new wrap limit\n     * @param [$printMargin]\n     * @returns {Boolean}\n     **/\n    adjustWrapLimit(desiredLimit, $printMargin) {\n        var limits = this.$wrapLimitRange;\n        if (limits.max < 0)\n            limits = {min: $printMargin, max: $printMargin};\n        var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);\n        if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {\n            this.$wrapLimit = wrapLimit;\n            this.$modified = true;\n            if (this.$useWrapMode) {\n                this.$updateWrapData(0, this.getLength() - 1);\n                this.$resetRowCache(0);\n                this._signal(\"changeWrapLimit\");\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     *\n     * @param {number} wrapLimit\n     * @param {number} [min]\n     * @param {number} [max]\n     * @returns {number}\n     */\n    $constrainWrapLimit(wrapLimit, min, max) {\n        if (min)\n            wrapLimit = Math.max(min, wrapLimit);\n\n        if (max)\n            wrapLimit = Math.min(max, wrapLimit);\n\n        return wrapLimit;\n    }\n\n    /**\n     * Returns the value of wrap limit.\n     * @returns {Number} The wrap limit.\n     **/\n    getWrapLimit() {\n        return this.$wrapLimit;\n    }\n\n    /**\n     * Sets the line length for soft wrap in the editor. Lines will break\n     *  at a minimum of the given length minus 20 chars and at a maximum\n     *  of the given number of chars.\n     * @param {number} limit The maximum line length in chars, for soft wrapping lines.\n     */\n    setWrapLimit(limit) {\n        this.setWrapLimitRange(limit, limit);\n    }\n\n    /**\n     * Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this:\n     *\n     *     { min: wrapLimitRange_min, max: wrapLimitRange_max }\n     *\n     * @returns {{ min: number, max: number }}\n     **/\n    getWrapLimitRange() {\n        // Avoid unexpected mutation by returning a copy\n        return {\n            min : this.$wrapLimitRange.min,\n            max : this.$wrapLimitRange.max\n        };\n    }\n\n    /**\n     * @param {Delta} delta\n     */\n    $updateInternalDataOnChange(delta) {\n        var useWrapMode = this.$useWrapMode;\n        var action = delta.action;\n        var start = delta.start;\n        var end = delta.end;\n        var firstRow = start.row;\n        var lastRow = end.row;\n        var len = lastRow - firstRow;\n        var removedFolds = null;\n\n        this.$updating = true;\n        if (len != 0) {\n            if (action === \"remove\") {\n                this[useWrapMode ? \"$wrapData\" : \"$rowLengthCache\"].splice(firstRow, len);\n\n                var foldLines = this.$foldData;\n                removedFolds = this.getFoldsInRange(delta);\n                this.removeFolds(removedFolds);\n\n                var foldLine = this.getFoldLine(end.row);\n                var idx = 0;\n                if (foldLine) {\n                    foldLine.addRemoveChars(end.row, end.column, start.column - end.column);\n                    foldLine.shiftRow(-len);\n\n                    var foldLineBefore = this.getFoldLine(firstRow);\n                    if (foldLineBefore && foldLineBefore !== foldLine) {\n                        foldLineBefore.merge(foldLine);\n                        foldLine = foldLineBefore;\n                    }\n                    idx = foldLines.indexOf(foldLine) + 1;\n                }\n\n                for (idx; idx < foldLines.length; idx++) {\n                    var foldLine = foldLines[idx];\n                    if (foldLine.start.row >= end.row) {\n                        foldLine.shiftRow(-len);\n                    }\n                }\n\n                lastRow = firstRow;\n            } else {\n                var args = Array(len);\n                args.unshift(firstRow, 0);\n                var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache;\n                arr.splice.apply(arr, args);\n\n                // If some new line is added inside of a foldLine, then split\n                // the fold line up.\n                var foldLines = this.$foldData;\n                var foldLine = this.getFoldLine(firstRow);\n                var idx = 0;\n                if (foldLine) {\n                    var cmp = foldLine.range.compareInside(start.row, start.column);\n                    // Inside of the foldLine range. Need to split stuff up.\n                    if (cmp == 0) {\n                        foldLine = foldLine.split(start.row, start.column);\n                        if (foldLine) {\n                            foldLine.shiftRow(len);\n                            foldLine.addRemoveChars(lastRow, 0, end.column - start.column);\n                        }\n                    } else\n                    // Infront of the foldLine but same row. Need to shift column.\n                    if (cmp == -1) {\n                        foldLine.addRemoveChars(firstRow, 0, end.column - start.column);\n                        foldLine.shiftRow(len);\n                    }\n                    // Nothing to do if the insert is after the foldLine.\n                    idx = foldLines.indexOf(foldLine) + 1;\n                }\n\n                for (idx; idx < foldLines.length; idx++) {\n                    var foldLine = foldLines[idx];\n                    if (foldLine.start.row >= firstRow) {\n                        foldLine.shiftRow(len);\n                    }\n                }\n            }\n        } else {\n            // Realign folds. E.g. if you add some new chars before a fold, the\n            // fold should \"move\" to the right.\n            len = Math.abs(delta.start.column - delta.end.column);\n            if (action === \"remove\") {\n                // Get all the folds in the change range and remove them.\n                removedFolds = this.getFoldsInRange(delta);\n                this.removeFolds(removedFolds);\n\n                len = -len;\n            }\n            var foldLine = this.getFoldLine(firstRow);\n            if (foldLine) {\n                foldLine.addRemoveChars(firstRow, start.column, len);\n            }\n        }\n\n        if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {\n            console.error(\"doc.getLength() and $wrapData.length have to be the same!\");\n        }\n        this.$updating = false;\n\n        if (useWrapMode)\n            this.$updateWrapData(firstRow, lastRow);\n        else\n            this.$updateRowLengthCache(firstRow, lastRow);\n\n        return removedFolds;\n    }\n\n    /**\n     * @param {number} firstRow\n     * @param {number} lastRow\n     */\n    $updateRowLengthCache(firstRow, lastRow) {\n        this.$rowLengthCache[firstRow] = null;\n        this.$rowLengthCache[lastRow] = null;\n    }\n\n    /**\n     * @param {number} firstRow\n     * @param {number} lastRow\n     */\n    $updateWrapData(firstRow, lastRow) {\n        var lines = this.doc.getAllLines();\n        var tabSize = this.getTabSize();\n        var wrapData = this.$wrapData;\n        var wrapLimit = this.$wrapLimit;\n        var tokens;\n        var foldLine;\n\n        var row = firstRow;\n        lastRow = Math.min(lastRow, lines.length - 1);\n        while (row <= lastRow) {\n            foldLine = this.getFoldLine(row, foldLine);\n            if (!foldLine) {\n                tokens = this.$getDisplayTokens(lines[row]);\n                wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);\n                row ++;\n            } else {\n                tokens = [];\n                foldLine.walk(function(placeholder, row, column, lastColumn) {\n                        var walkTokens;\n                        if (placeholder != null) {\n                            walkTokens = this.$getDisplayTokens(\n                                            placeholder, tokens.length);\n                            walkTokens[0] = PLACEHOLDER_START;\n                            for (var i = 1; i < walkTokens.length; i++) {\n                                walkTokens[i] = PLACEHOLDER_BODY;\n                            }\n                        } else {\n                            walkTokens = this.$getDisplayTokens(\n                                lines[row].substring(lastColumn, column),\n                                tokens.length);\n                        }\n                        tokens = tokens.concat(walkTokens);\n                    }.bind(this),\n                    foldLine.end.row,\n                    lines[foldLine.end.row].length + 1\n                );\n\n                wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);\n                row = foldLine.end.row + 1;\n            }\n        }\n    }\n\n    /**\n     * @param {number[]}tokens\n     * @param {number} wrapLimit\n     * @param {number} tabSize\n     * @returns {*[]}\n     */\n    $computeWrapSplits(tokens, wrapLimit, tabSize) {\n        if (tokens.length == 0) {\n            return [];\n        }\n\n        var splits = [];\n        var displayLength = tokens.length;\n        var lastSplit = 0, lastDocSplit = 0;\n\n        var isCode = this.$wrapAsCode;\n\n        var indentedSoftWrap = this.$indentedSoftWrap;\n        var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8)\n            || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);\n\n        function getWrapIndent() {\n            var indentation = 0;\n            if (maxIndent === 0)\n                return indentation;\n            if (indentedSoftWrap) {\n                for (var i = 0; i < tokens.length; i++) {\n                    var token = tokens[i];\n                    if (token == SPACE)\n                        indentation += 1;\n                    else if (token == TAB)\n                        indentation += tabSize;\n                    else if (token == TAB_SPACE)\n                        continue;\n                    else\n                        break;\n                }\n            }\n            if (isCode && indentedSoftWrap !== false)\n                indentation += tabSize;\n            return Math.min(indentation, maxIndent);\n        }\n        function addSplit(screenPos) {\n            // The document size is the current size - the extra width for tabs\n            // and multipleWidth characters.\n            var len = screenPos - lastSplit;\n            for (var i = lastSplit; i < screenPos; i++) {\n                var ch = tokens[i];\n                if (ch === 12 || ch === 2) len -= 1;\n            }\n\n            if (!splits.length) {\n                indent = getWrapIndent();\n                //@ts-expect-error TODO: potential wrong property\n                splits.indent = indent;\n            }\n            lastDocSplit += len;\n            splits.push(lastDocSplit);\n            lastSplit = screenPos;\n        }\n        var indent = 0;\n        while (displayLength - lastSplit > wrapLimit - indent) {\n            // This is, where the split should be.\n            var split = lastSplit + wrapLimit - indent;\n\n            // If there is a space or tab at this split position, then making\n            // a split is simple.\n            if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {\n                /* disabled see https://github.com/ajaxorg/ace/issues/1186\n                // Include all following spaces + tabs in this split as well.\n                while (tokens[split] >= SPACE) {\n                    split ++;\n                } */\n                addSplit(split);\n                continue;\n            }\n\n            // === ELSE ===\n            // Check if split is inside of a placeholder. Placeholder are\n            // not splitable. Therefore, seek the beginning of the placeholder\n            // and try to place the split before the placeholder's start.\n            if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {\n                // Seek the start of the placeholder and do the split\n                // before the placeholder. By definition there always\n                // a PLACEHOLDER_START between split and lastSplit.\n                for (split; split != lastSplit - 1; split--) {\n                    if (tokens[split] == PLACEHOLDER_START) {\n                        // split++; << No incremental here as we want to\n                        //  have the position before the Placeholder.\n                        break;\n                    }\n                }\n\n                // If the PLACEHOLDER_START is not the index of the\n                // last split, then we can do the split\n                if (split > lastSplit) {\n                    addSplit(split);\n                    continue;\n                }\n\n                // If the PLACEHOLDER_START IS the index of the last\n                // split, then we have to place the split after the\n                // placeholder. So, let's seek for the end of the placeholder.\n                split = lastSplit + wrapLimit;\n                for (split; split < tokens.length; split++) {\n                    if (tokens[split] != PLACEHOLDER_BODY) {\n                        break;\n                    }\n                }\n\n                // If spilt == tokens.length, then the placeholder is the last\n                // thing in the line and adding a new split doesn't make sense.\n                if (split == tokens.length) {\n                    break;  // Breaks the while-loop.\n                }\n\n                // Finally, add the split...\n                addSplit(split);\n                continue;\n            }\n\n            // === ELSE ===\n            // Search for the first non space/tab/placeholder/punctuation token backwards.\n            var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1);\n            while (split > minSplit && tokens[split] < PLACEHOLDER_START) {\n                split --;\n            }\n            if (isCode) {\n                while (split > minSplit && tokens[split] < PLACEHOLDER_START) {\n                    split --;\n                }\n                while (split > minSplit && tokens[split] == PUNCTUATION) {\n                    split --;\n                }\n            } else {\n                while (split > minSplit && tokens[split] < SPACE) {\n                    split --;\n                }\n            }\n            // If we found one, then add the split.\n            if (split > minSplit) {\n                addSplit(++split);\n                continue;\n            }\n\n            // === ELSE ===\n            split = lastSplit + wrapLimit;\n            // The split is inside of a CHAR or CHAR_EXT token and no space\n            // around -> force a split.\n            if (tokens[split] == CHAR_EXT)\n                split--;\n            addSplit(split - indent);\n        }\n        return splits;\n    }\n\n    /**\n     * Given a string, returns an array of the display characters, including tabs and spaces.\n     * @param {String} str The string to check\n     * @param {Number} [offset] The value to start at\n     * @returns {number[]}\n     **/\n    $getDisplayTokens(str, offset) {\n        var arr = [];\n        var tabSize;\n        offset = offset || 0;\n\n        for (var i = 0; i < str.length; i++) {\n            var c = str.charCodeAt(i);\n            // Tab\n            if (c == 9) {\n                tabSize = this.getScreenTabSize(arr.length + offset);\n                arr.push(TAB);\n                for (var n = 1; n < tabSize; n++) {\n                    arr.push(TAB_SPACE);\n                }\n            }\n            // Space\n            else if (c == 32) {\n                arr.push(SPACE);\n            } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {\n                arr.push(PUNCTUATION);\n            }\n            // full width characters\n            else if (c >= 0x1100 && isFullWidth(c)) {\n                arr.push(CHAR, CHAR_EXT);\n            } else {\n                arr.push(CHAR);\n            }\n        }\n        return arr;\n    }\n\n    /**\n     * Calculates the width of the string `str` on the screen while assuming that the string starts at the first column on the screen.\n     * @param {String} str The string to calculate the screen width of\n     * @param {Number} [maxScreenColumn]\n     * @param {Number} [screenColumn]\n     * @returns {Number[]} Returns an `int[]` array with two elements:<br/>\n     * The first position indicates the number of columns for `str` on screen.<br/>\n     * The second value contains the position of the document column that this function read until.\n     **/\n    $getStringScreenWidth(str, maxScreenColumn, screenColumn) {\n        if (maxScreenColumn == 0)\n            return [0, 0];\n        if (maxScreenColumn == null)\n            maxScreenColumn = Infinity;\n        screenColumn = screenColumn || 0;\n\n        var c, column;\n        for (column = 0; column < str.length; column++) {\n            c = str.charCodeAt(column);\n            // tab\n            if (c == 9) {\n                screenColumn += this.getScreenTabSize(screenColumn);\n            }\n            // full width characters\n            else if (c >= 0x1100 && isFullWidth(c)) {\n                screenColumn += 2;\n            } else {\n                screenColumn += 1;\n            }\n            if (screenColumn > maxScreenColumn) {\n                break;\n            }\n        }\n\n        return [screenColumn, column];\n    }\n\n    /**\n     * Returns number of screenrows in a wrapped line.\n     * @param {Number} row The row number to check\n     * @returns {Number}\n     **/\n    getRowLength(row) {\n        var h = 1;\n        if (this.lineWidgets)\n            h += this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;\n\n        if (!this.$useWrapMode || !this.$wrapData[row])\n            return h;\n        else\n            return this.$wrapData[row].length + h;\n    }\n\n    /**\n     * @param {Number} row\n     * @returns {Number}\n     **/\n    getRowLineCount(row) {\n        if (!this.$useWrapMode || !this.$wrapData[row]) {\n            return 1;\n        } else {\n            return this.$wrapData[row].length + 1;\n        }\n    }\n\n    /**\n     * @param {Number} screenRow\n     * @returns {Number}\n     **/\n    getRowWrapIndent(screenRow) {\n        if (this.$useWrapMode) {\n            var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);\n            var splits = this.$wrapData[pos.row];\n            return splits.length && splits[0] < pos.column ? splits.indent : 0;\n        } else {\n            return 0;\n        }\n    }\n\n    /**\n     * Returns the position (on screen) for the last character in the provided screen row.\n     * @param {Number} screenRow The screen row to check\n     * @returns {Number}\n     *\n     * @related EditSession.documentToScreenColumn\n     **/\n    getScreenLastRowColumn(screenRow) {\n        var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);\n        return this.documentToScreenColumn(pos.row, pos.column);\n    }\n\n    /**\n     * For the given document row and column, this returns the column position of the last screen row.\n     * @param {Number} docRow\n     * @param {Number} docColumn\n     * @returns {number}\n     **/\n    getDocumentLastRowColumn(docRow, docColumn) {\n        var screenRow = this.documentToScreenRow(docRow, docColumn);\n        return this.getScreenLastRowColumn(screenRow);\n    }\n\n    /**\n     * For the given document row and column, this returns the document position of the last row.\n     * @param {Number} docRow\n     * @param {Number} docColumn\n     * @returns {Point}\n     **/\n    getDocumentLastRowColumnPosition(docRow, docColumn) {\n        var screenRow = this.documentToScreenRow(docRow, docColumn);\n        return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);\n    }\n\n    /**\n     * For the given row, this returns the split data.\n     * @param {number} row\n     * @returns {String | undefined}\n     */\n    getRowSplitData(row) {\n        if (!this.$useWrapMode) {\n            return undefined;\n        } else {\n            return this.$wrapData[row];\n        }\n    }\n\n    /**\n     * The distance to the next tab stop at the specified screen column.\n     * @param {Number} screenColumn The screen column to check\n     *\n     * @returns {Number}\n     **/\n    getScreenTabSize(screenColumn) {\n        return this.$tabSize - (screenColumn % this.$tabSize | 0);\n    }\n\n    /**\n     * @param {number} screenRow\n     * @param {number} screenColumn\n     * @returns {number}\n     */\n    screenToDocumentRow(screenRow, screenColumn) {\n        return this.screenToDocumentPosition(screenRow, screenColumn).row;\n    }\n\n    /**\n     * @param {number} screenRow\n     * @param {number} screenColumn\n     * @returns {number}\n     */\n    screenToDocumentColumn(screenRow, screenColumn) {\n        return this.screenToDocumentPosition(screenRow, screenColumn).column;\n    }\n\n    /**\n     * Converts characters coordinates on the screen to characters coordinates within the document. [This takes into account code folding, word wrap, tab size, and any other visual modifications.]{: #conversionConsiderations}\n     * @param {Number} screenRow The screen row to check\n     * @param {Number} screenColumn The screen column to check\n     * @param {Number} [offsetX] screen character x-offset [optional]\n     *\n     * @returns {Point} The object returned has two properties: `row` and `column`.\n     *\n     * @related EditSession.documentToScreenPosition\n     **/\n    screenToDocumentPosition(screenRow, screenColumn, offsetX) {\n        if (screenRow < 0)\n            return {row: 0, column: 0};\n\n        var line;\n        var docRow = 0;\n        var docColumn = 0;\n        var column;\n        var row = 0;\n        var rowLength = 0;\n\n        var rowCache = this.$screenRowCache;\n        var i = this.$getRowCacheIndex(rowCache, screenRow);\n        var l = rowCache.length;\n        if (l && i >= 0) {\n            var row = rowCache[i];\n            var docRow = this.$docRowCache[i];\n            var doCache = screenRow > rowCache[l - 1];\n        } else {\n            var doCache = !l;\n        }\n\n        var maxRow = this.getLength() - 1;\n        var foldLine = this.getNextFoldLine(docRow);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (row <= screenRow) {\n            rowLength = this.getRowLength(docRow);\n            if (row + rowLength > screenRow || docRow >= maxRow) {\n                break;\n            } else {\n                row += rowLength;\n                docRow++;\n                if (docRow > foldStart) {\n                    docRow = foldLine.end.row+1;\n                    foldLine = this.getNextFoldLine(docRow, foldLine);\n                    foldStart = foldLine ? foldLine.start.row : Infinity;\n                }\n            }\n\n            if (doCache) {\n                this.$docRowCache.push(docRow);\n                this.$screenRowCache.push(row);\n            }\n        }\n\n        if (foldLine && foldLine.start.row <= docRow) {\n            line = this.getFoldDisplayLine(foldLine);\n            docRow = foldLine.start.row;\n        } else if (row + rowLength <= screenRow || docRow > maxRow) {\n            // clip at the end of the document\n            return {\n                row: maxRow,\n                column: this.getLine(maxRow).length\n            };\n        } else {\n            line = this.getLine(docRow);\n            foldLine = null;\n        }\n        var wrapIndent = 0, splitIndex = Math.floor(screenRow - row);\n        if (this.$useWrapMode) {\n            var splits = this.$wrapData[docRow];\n            if (splits) {\n                column = splits[splitIndex];\n                if(splitIndex > 0 && splits.length) {\n                    wrapIndent = splits.indent;\n                    docColumn = splits[splitIndex - 1] || splits[splits.length - 1];\n                    line = line.substring(docColumn);\n                }\n            }\n        }\n\n        if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex))\n            screenColumn = this.$bidiHandler.offsetToCol(offsetX);\n\n        docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];\n\n        // We remove one character at the end so that the docColumn\n        // position returned is not associated to the next row on the screen.\n        if (this.$useWrapMode && docColumn >= column)\n            docColumn = column - 1;\n\n        if (foldLine)\n            return foldLine.idxToPosition(docColumn);\n\n        return {row: docRow, column: docColumn};\n    }\n\n    /**\n     * Converts document coordinates to screen coordinates. {:conversionConsiderations}\n     * @param {Number|Point} docRow The document row to check\n     * @param {Number|undefined} [docColumn] The document column to check\n     * @returns {Point} The object returned by this method has two properties: `row` and `column`.\n     *\n     * @related EditSession.screenToDocumentPosition\n     **/\n    documentToScreenPosition(docRow, docColumn) {\n        // Normalize the passed in arguments.\n        if (typeof docColumn === \"undefined\")\n            var pos = this.$clipPositionToDocument(/**@type{Point}*/(docRow).row, /**@type{Point}*/(docRow).column);\n        else\n            pos = this.$clipPositionToDocument(/**@type{number}*/(docRow), docColumn);\n\n        docRow = pos.row;\n        docColumn = pos.column;\n\n        var screenRow = 0;\n        var foldStartRow = null;\n        var fold = null;\n\n        // Clamp the docRow position in case it's inside of a folded block.\n        fold = this.getFoldAt(docRow, docColumn, 1);\n        if (fold) {\n            docRow = fold.start.row;\n            docColumn = fold.start.column;\n        }\n\n        var rowEnd, row = 0;\n\n        var rowCache = this.$docRowCache;\n        var i = this.$getRowCacheIndex(rowCache, docRow);\n        var l = rowCache.length;\n        if (l && i >= 0) {\n            var row = rowCache[i];\n            var screenRow = this.$screenRowCache[i];\n            var doCache = docRow > rowCache[l - 1];\n        } else {\n            var doCache = !l;\n        }\n\n        var foldLine = this.getNextFoldLine(row);\n        var foldStart = foldLine ?foldLine.start.row :Infinity;\n\n        while (row < docRow) {\n            if (row >= foldStart) {\n                rowEnd = foldLine.end.row + 1;\n                if (rowEnd > docRow)\n                    break;\n                foldLine = this.getNextFoldLine(rowEnd, foldLine);\n                foldStart = foldLine ?foldLine.start.row :Infinity;\n            }\n            else {\n                rowEnd = row + 1;\n            }\n\n            screenRow += this.getRowLength(row);\n            row = rowEnd;\n\n            if (doCache) {\n                this.$docRowCache.push(row);\n                this.$screenRowCache.push(screenRow);\n            }\n        }\n\n        // Calculate the text line that is displayed in docRow on the screen.\n        var textLine = \"\";\n        // Check if the final row we want to reach is inside of a fold.\n        if (foldLine && row >= foldStart) {\n            textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);\n            foldStartRow = foldLine.start.row;\n        } else {\n            textLine = this.getLine(docRow).substring(0, docColumn);\n            foldStartRow = docRow;\n        }\n        var wrapIndent = 0;\n        // Clamp textLine if in wrapMode.\n        if (this.$useWrapMode) {\n            var wrapRow = this.$wrapData[foldStartRow];\n            if (wrapRow) {\n                var screenRowOffset = 0;\n                while (textLine.length >= wrapRow[screenRowOffset]) {\n                    screenRow ++;\n                    screenRowOffset++;\n                }\n                textLine = textLine.substring(\n                    wrapRow[screenRowOffset - 1] || 0, textLine.length\n                );\n                wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;\n            }\n        }\n\n        if (this.lineWidgets && this.lineWidgets[row] && this.lineWidgets[row].rowsAbove)\n            screenRow += this.lineWidgets[row].rowsAbove;\n\n        return {\n            row: screenRow,\n            column: wrapIndent + this.$getStringScreenWidth(textLine)[0]\n        };\n    }\n\n    /**\n     * For the given document row and column, returns the screen column.\n     * @param {Number|Point} row\n     * @param {Number} [docColumn]\n     * @returns {Number}\n     **/\n    documentToScreenColumn(row, docColumn) {\n        return this.documentToScreenPosition(row, docColumn).column;\n    }\n\n    /**\n     * For the given document row and column, returns the screen row.\n     * @param {Number|Point} docRow\n     * @param {Number} [docColumn]\n     * @returns {number}\n     **/\n    documentToScreenRow(docRow, docColumn) {\n        return this.documentToScreenPosition(docRow, docColumn).row;\n    }\n\n    /**\n     * Returns the length of the screen.\n     * @returns {Number}\n     **/\n    getScreenLength() {\n        var screenRows = 0;\n        /**@type {FoldLine}*/\n        var fold = null;\n        if (!this.$useWrapMode) {\n            screenRows = this.getLength();\n\n            // Remove the folded lines again.\n            var foldData = this.$foldData;\n            for (var i = 0; i < foldData.length; i++) {\n                fold = foldData[i];\n                screenRows -= fold.end.row - fold.start.row;\n            }\n        } else {\n            var lastRow = this.$wrapData.length;\n            var row = 0, i = 0;\n            var fold = this.$foldData[i++];\n            var foldStart = fold ? fold.start.row :Infinity;\n\n            while (row < lastRow) {\n                var splits = this.$wrapData[row];\n                screenRows += splits ? splits.length + 1 : 1;\n                row ++;\n                if (row > foldStart) {\n                    row = fold.end.row+1;\n                    fold = this.$foldData[i++];\n                    foldStart = fold ?fold.start.row :Infinity;\n                }\n            }\n        }\n\n        // todo\n        if (this.lineWidgets)\n            screenRows += this.$getWidgetScreenLength();\n\n        return screenRows;\n    }\n\n    /**\n     * @param {FontMetrics} fm\n     */\n    $setFontMetrics(fm) {\n        if (!this.$enableVarChar) return;\n        this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {\n            if (maxScreenColumn === 0)\n                return [0, 0];\n            if (!maxScreenColumn)\n                maxScreenColumn = Infinity;\n            screenColumn = screenColumn || 0;\n\n            var c, column;\n            for (column = 0; column < str.length; column++) {\n                c = str.charAt(column);\n                // tab\n                if (c === \"\\t\") {\n                    screenColumn += this.getScreenTabSize(screenColumn);\n                } else {\n                    screenColumn += fm.getCharacterWidth(c);\n                }\n                if (screenColumn > maxScreenColumn) {\n                    break;\n                }\n            }\n\n            return [screenColumn, column];\n        };\n    }\n\n    /**\n     * @returns {string} the last character preceding the cursor in the editor\n     */\n    getPrecedingCharacter() {\n        var pos = this.selection.getCursor();\n\n        if (pos.column === 0) {\n            return pos.row === 0 ? \"\" : this.doc.getNewLineCharacter();\n        }\n\n        var currentLine = this.getLine(pos.row);\n        return currentLine[pos.column - 1];\n    }\n\n    destroy() {\n        if (!this.destroyed) {\n            this.bgTokenizer.setDocument(null);\n            this.bgTokenizer.cleanup();\n            this.destroyed = true;\n        }\n        this.endOperation();\n        this.$stopWorker();\n        this.removeAllListeners();\n        if (this.doc) {\n            this.doc.off(\"change\", this.$onChange);\n        }\n        if (this.selection) {\n            this.selection.off(\"changeCursor\", this.$onSelectionChange);\n            this.selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n        this.selection.detach();\n    }\n}\n\nEditSession.$uid = 0;\nEditSession.prototype.$modes = config.$modes;\n/**\n * Returns the current [[Document `Document`]] as a string.\n * @method getValue\n * @returns {String}\n * @alias EditSession.toString\n **/\nEditSession.prototype.getValue = EditSession.prototype.toString;\n\nEditSession.prototype.$defaultUndoManager = {\n    undo: function() {},\n    redo: function() {},\n    hasUndo: function() {},\n    hasRedo: function() {},\n    reset: function() {},\n    add: function() {},\n    addSelection: function() {},\n    startNewGroup: function() {},\n    addSession: function() {}\n};\nEditSession.prototype.$overwrite = false;\n\nEditSession.prototype.$mode = null;\nEditSession.prototype.$modeId = null;\nEditSession.prototype.$scrollTop = 0;\nEditSession.prototype.$scrollLeft = 0;\n// WRAPMODE\nEditSession.prototype.$wrapLimit = 80;\nEditSession.prototype.$useWrapMode = false;\nEditSession.prototype.$wrapLimitRange = {\n    min : null,\n    max : null\n};\n/**\n *\n * @type {null | import(\"../ace-internal\").Ace.LineWidget[]}\n */\nEditSession.prototype.lineWidgets = null;\nEditSession.prototype.isFullWidth = isFullWidth;\n\noop.implement(EditSession.prototype, EventEmitter);\n\n// \"Tokens\"\nvar CHAR = 1,\n    CHAR_EXT = 2,\n    PLACEHOLDER_START = 3,\n    PLACEHOLDER_BODY =  4,\n    PUNCTUATION = 9,\n    SPACE = 10,\n    TAB = 11,\n    TAB_SPACE = 12;\n// For every keystroke this gets called once per char in the whole doc!!\n// Wouldn't hurt to make it a bit faster for c >= 0x1100\nfunction isFullWidth(c) {\n    if (c < 0x1100)\n        return false;\n    return c >= 0x1100 && c <= 0x115F ||\n        c >= 0x11A3 && c <= 0x11A7 ||\n        c >= 0x11FA && c <= 0x11FF ||\n        c >= 0x2329 && c <= 0x232A ||\n        c >= 0x2E80 && c <= 0x2E99 ||\n        c >= 0x2E9B && c <= 0x2EF3 ||\n        c >= 0x2F00 && c <= 0x2FD5 ||\n        c >= 0x2FF0 && c <= 0x2FFB ||\n        c >= 0x3000 && c <= 0x303E ||\n        c >= 0x3041 && c <= 0x3096 ||\n        c >= 0x3099 && c <= 0x30FF ||\n        c >= 0x3105 && c <= 0x312D ||\n        c >= 0x3131 && c <= 0x318E ||\n        c >= 0x3190 && c <= 0x31BA ||\n        c >= 0x31C0 && c <= 0x31E3 ||\n        c >= 0x31F0 && c <= 0x321E ||\n        c >= 0x3220 && c <= 0x3247 ||\n        c >= 0x3250 && c <= 0x32FE ||\n        c >= 0x3300 && c <= 0x4DBF ||\n        c >= 0x4E00 && c <= 0xA48C ||\n        c >= 0xA490 && c <= 0xA4C6 ||\n        c >= 0xA960 && c <= 0xA97C ||\n        c >= 0xAC00 && c <= 0xD7A3 ||\n        c >= 0xD7B0 && c <= 0xD7C6 ||\n        c >= 0xD7CB && c <= 0xD7FB ||\n        c >= 0xF900 && c <= 0xFAFF ||\n        c >= 0xFE10 && c <= 0xFE19 ||\n        c >= 0xFE30 && c <= 0xFE52 ||\n        c >= 0xFE54 && c <= 0xFE66 ||\n        c >= 0xFE68 && c <= 0xFE6B ||\n        c >= 0xFF01 && c <= 0xFF60 ||\n        c >= 0xFFE0 && c <= 0xFFE6;\n}\nrequire(\"./edit_session/folding\").Folding.call(EditSession.prototype);\nrequire(\"./edit_session/bracket_match\").BracketMatch.call(EditSession.prototype);\n\n\nconfig.defineOptions(EditSession.prototype, \"session\", {\n    wrap: {\n        /**\n         * @param {string | boolean | number} value\n         * @this {EditSession}\n         */\n        set: function(value) {\n            if (!value || value == \"off\")\n                value = false;\n            else if (value == \"free\")\n                value = true;\n            else if (value == \"printMargin\")\n                value = -1;\n            else if (typeof value == \"string\")\n                value = parseInt(value, 10) || false;\n\n            if (this.$wrap == value)\n                return;\n            this.$wrap = value;\n            if (!value) {\n                this.setUseWrapMode(false);\n            } else {\n                var col = typeof value == \"number\" ? value : null;\n                this.setWrapLimitRange(col, col);\n                this.setUseWrapMode(true);\n            }\n        },\n        get: function() {\n            if (this.getUseWrapMode()) {\n                if (this.$wrap == -1)\n                    return \"printMargin\";\n                if (!this.getWrapLimitRange().min)\n                    return \"free\";\n                return this.$wrap;\n            }\n            return \"off\";\n        },\n        handlesSet: true\n    },\n    wrapMethod: {\n        /**\n         * @param {\"code\"|\"text\"|\"auto\"|boolean} val\n         * @this{EditSession}\n         */\n        set: function(val) {\n            val = val == \"auto\"\n                ? this.$mode.type != \"text\"\n                : val != \"text\";\n            if (val != this.$wrapAsCode) {\n                this.$wrapAsCode = val;\n                if (this.$useWrapMode) {\n                    this.$useWrapMode = false;\n                    this.setUseWrapMode(true);\n                }\n            }\n        },\n        initialValue: \"auto\"\n    },\n    indentedSoftWrap: {\n        /**\n         * @this{EditSession}\n         */\n        set: function() {\n            if (this.$useWrapMode) {\n                this.$useWrapMode = false;\n                this.setUseWrapMode(true);\n            }\n        },\n        initialValue: true\n    },\n    firstLineNumber: {\n        set: function() {this._signal(\"changeBreakpoint\");},\n        initialValue: 1\n    },\n    useWorker: {\n        /**\n         * @param {boolean} useWorker\n         * @this{EditSession}\n         */\n        set: function(useWorker) {\n            this.$useWorker = useWorker;\n\n            this.$stopWorker();\n            if (useWorker)\n                this.$startWorker();\n        },\n        initialValue: true\n    },\n    useSoftTabs: {initialValue: true},\n    tabSize: {\n        /**\n         * @param tabSize\n         * @this{EditSession}\n         */\n        set: function(tabSize) {\n            tabSize = parseInt(tabSize);\n            if (tabSize > 0 && this.$tabSize !== tabSize) {\n                this.$modified = true;\n                this.$rowLengthCache = [];\n                this.$tabSize = tabSize;\n                this._signal(\"changeTabSize\");\n            }\n        },\n        initialValue: 4,\n        handlesSet: true\n    },\n    navigateWithinSoftTabs: {initialValue: false},\n    foldStyle: {\n        set: function(val) {this.setFoldStyle(val);},\n        handlesSet: true\n    },\n    overwrite: {\n        set: function(val) {this._signal(\"changeOverwrite\");},\n        initialValue: false\n    },\n    newLineMode: {\n        set: function(val) {this.doc.setNewLineMode(val);},\n        get: function() {return this.doc.getNewLineMode();},\n        handlesSet: true\n    },\n    mode: {\n        set: function(val) { this.setMode(val); },\n        get: function() { return this.$modeId; },\n        handlesSet: true\n    }\n});\n\nexports.EditSession = EditSession;\n"
  },
  {
    "path": "src/edit_session_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar lang = require(\"./lib/lang\");\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar Range = require(\"./range\").Range;\nvar assert = require(\"./test/assertions\");\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar lang = require(\"./lib/lang\");\n\nrequire(\"./multi_select\");\n\nfunction createFoldTestSession() {\n    var lines = [\n        \"function foo(items) {\",\n        \"    for (var i=0; i<items.length; i++) {\",\n        \"        alert(items[i] + \\\"juhu\\\");\",\n        \"    }    // Real Tab.\",\n        \"}\"\n    ];\n    var session = new EditSession(lines.join(\"\\n\"));\n    session.setUndoManager(new UndoManager());\n    session.addFold(\"args...\", new Range(0, 13, 0, 18));\n    session.addFold(\"foo...\", new Range(1, 10, 2, 10));\n    session.addFold(\"bar...\", new Range(2, 20, 2, 25));\n    return session;\n}\n\nfunction assertArray(a, b) {\n    assert.equal(a+\"\", b+\"\");\n    assert.ok(a.length == b.length);\n    for (var i = 0; i < a.length; i++) {\n        assert.equal(a[i], b[i]);\n    }\n}\n\nfunction insert(row, column, text, session) {\n    session.insert({row: row, column: column}, text);\n\n    // Force the session to store all changes made to the document NOW\n    // on the undoManager's queue. Otherwise we can't undo in separate\n    // steps later.\n    session.$syncInformUndoManager();\n}\n\nmodule.exports = {\n\n   \"test: find matching opening bracket in Text mode\" : function() {\n        var session = new EditSession([\"(()(\", \"())))\"]);\n\n        assert.position(session.findMatchingBracket({row: 0, column: 3}), 0, 1);\n        assert.position(session.findMatchingBracket({row: 1, column: 2}), 1, 0);\n        assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 3);\n        assert.position(session.findMatchingBracket({row: 1, column: 4}), 0, 0);\n        assert.equal(session.findMatchingBracket({row: 1, column: 5}), null);\n    },\n\n    \"test: find matching closing bracket in Text mode\" : function() {\n        var session = new EditSession([\"(()(\", \"())))\"]);\n\n        assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);\n        assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);\n        assert.position(session.findMatchingBracket({row: 0, column: 4}), 1, 2);\n        assert.position(session.findMatchingBracket({row: 0, column: 2}), 0, 2);\n        assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 3);\n        assert.equal(session.findMatchingBracket({row: 0, column: 0}), null);\n    },\n\n    \"test: find matching opening bracket in JavaScript mode\" : function() {\n        var lines = [\n            \"function foo() {\",\n            \"    var str = \\\"{ foo()\\\";\",\n            \"    if (debug) {\",\n            \"        // write str (a string) to the console\",\n            \"        console.log(str);\",\n            \"    }\",\n            \"    str += \\\" bar() }\\\";\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        assert.position(session.findMatchingBracket({row: 0, column: 14}), 0, 12);\n        assert.position(session.findMatchingBracket({row: 7, column: 1}), 0, 15);\n        assert.position(session.findMatchingBracket({row: 6, column: 20}), 1, 15);\n        assert.position(session.findMatchingBracket({row: 1, column: 22}), 1, 20);\n        assert.position(session.findMatchingBracket({row: 3, column: 31}), 3, 21);\n        assert.position(session.findMatchingBracket({row: 4, column: 24}), 4, 19);\n        assert.equal(session.findMatchingBracket({row: 0, column: 1}), null);\n    },\n\n    \"test: find matching closing bracket in JavaScript mode\" : function() {\n        var lines = [\n            \"function foo() {\",\n            \"    var str = \\\"{ foo()\\\";\",\n            \"    if (debug) {\",\n            \"        // write str (a string) to the console\",\n            \"        console.log(str);\",\n            \"    }\",\n            \"    str += \\\" bar() }\\\";\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        assert.position(session.findMatchingBracket({row: 0, column: 13}), 0, 13);\n        assert.position(session.findMatchingBracket({row: 0, column: 16}), 7, 0);\n        assert.position(session.findMatchingBracket({row: 1, column: 16}), 6, 19);\n        assert.position(session.findMatchingBracket({row: 1, column: 21}), 1, 21);\n        assert.position(session.findMatchingBracket({row: 3, column: 22}), 3, 30);\n        assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23);\n    },\n\n    \"test: handle unbalanced brackets in JavaScript mode\" : function() {\n        var lines = [\n            \"function foo() {\",\n            \"    var str = \\\"{ foo()\\\";\",\n            \"    if (debug) {\",\n            \"        // write str a string) to the console\",\n            \"        console.log(str);\",\n            \"    \",\n            \"    str += \\\" bar() \\\";\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        assert.equal(session.findMatchingBracket({row: 0, column: 16}), null);\n        assert.equal(session.findMatchingBracket({row: 3, column: 30}), null);\n        assert.equal(session.findMatchingBracket({row: 1, column: 16}), null);\n    },\n\n    \"test: match different bracket types\" : function() {\n        var session = new EditSession([\"({[\", \")]}\"]);\n\n        assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 0);\n        assert.position(session.findMatchingBracket({row: 0, column: 2}), 1, 2);\n        assert.position(session.findMatchingBracket({row: 0, column: 3}), 1, 1);\n\n        assert.position(session.findMatchingBracket({row: 1, column: 1}), 0, 0);\n        assert.position(session.findMatchingBracket({row: 1, column: 2}), 0, 2);\n        assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 1);\n    },\n\n    \"test: move lines down\" : function() {\n        var session = new EditSession([\"a1\", \"a2\", \"a3\", \"a4\"]);\n\n        session.moveLinesDown(0, 1);\n        assert.equal(session.getValue(), [\"a3\", \"a1\", \"a2\", \"a4\"].join(\"\\n\"));\n\n        session.moveLinesDown(1, 2);\n        assert.equal(session.getValue(), [\"a3\", \"a4\", \"a1\", \"a2\"].join(\"\\n\"));\n\n        session.moveLinesDown(2, 3);\n        assert.equal(session.getValue(), [\"a3\", \"a4\", \"a1\", \"a2\"].join(\"\\n\"));\n\n        session.moveLinesDown(2, 2);\n        assert.equal(session.getValue(), [\"a3\", \"a4\", \"a2\", \"a1\"].join(\"\\n\"));\n    },\n\n    \"test: move lines up\" : function() {\n        var session = new EditSession([\"a1\", \"a2\", \"a3\", \"a4\"]);\n\n        session.moveLinesUp(2, 3);\n        assert.equal(session.getValue(), [\"a1\", \"a3\", \"a4\", \"a2\"].join(\"\\n\"));\n\n        session.moveLinesUp(1, 2);\n        assert.equal(session.getValue(), [\"a3\", \"a4\", \"a1\", \"a2\"].join(\"\\n\"));\n\n        session.moveLinesUp(0, 1);\n        assert.equal(session.getValue(), [\"a3\", \"a4\", \"a1\", \"a2\"].join(\"\\n\"));\n\n        session.moveLinesUp(2, 2);\n        assert.equal(session.getValue(), [\"a3\", \"a1\", \"a4\", \"a2\"].join(\"\\n\"));\n    },\n\n    \"test: duplicate lines\" : function() {\n        var session = new EditSession([\"1\", \"2\", \"3\", \"4\"]);\n\n        session.duplicateLines(1, 2);\n        assert.equal(session.getValue(), [\"1\", \"2\", \"3\", \"2\", \"3\", \"4\"].join(\"\\n\"));\n    },\n\n    \"test: duplicate last line\" : function() {\n        var session = new EditSession([\"1\", \"2\", \"3\"]);\n\n        session.duplicateLines(2, 2);\n        assert.equal(session.getValue(), [\"1\", \"2\", \"3\", \"3\"].join(\"\\n\"));\n    },\n\n    \"test: duplicate first line\" : function() {\n        var session = new EditSession([\"1\", \"2\", \"3\"]);\n\n        session.duplicateLines(0, 0);\n        assert.equal(session.getValue(), [\"1\", \"1\", \"2\", \"3\"].join(\"\\n\"));\n    },\n\n    \"test: getScreenLastRowColumn\": function() {\n        var session = new EditSession([\n            \"juhu\",\n            \"12\\t\\t34\",\n            \"ぁぁa\"\n        ]);\n\n        assert.equal(session.getScreenLastRowColumn(0), 4);\n        assert.equal(session.getScreenLastRowColumn(1), 10);\n        assert.equal(session.getScreenLastRowColumn(2), 5);\n    },\n\n    \"test: convert document to screen coordinates\" : function() {\n        var session = new EditSession(\"01234\\t567890\\t1234\");\n        session.setTabSize(4);\n\n        assert.equal(session.documentToScreenColumn(0, 0), 0);\n        assert.equal(session.documentToScreenColumn(0, 4), 4);\n        assert.equal(session.documentToScreenColumn(0, 5), 5);\n        assert.equal(session.documentToScreenColumn(0, 6), 8);\n        assert.equal(session.documentToScreenColumn(0, 12), 14);\n        assert.equal(session.documentToScreenColumn(0, 13), 16);\n\n        session.setTabSize(2);\n\n        assert.equal(session.documentToScreenColumn(0, 0), 0);\n        assert.equal(session.documentToScreenColumn(0, 4), 4);\n        assert.equal(session.documentToScreenColumn(0, 5), 5);\n        assert.equal(session.documentToScreenColumn(0, 6), 6);\n        assert.equal(session.documentToScreenColumn(0, 7), 7);\n        assert.equal(session.documentToScreenColumn(0, 12), 12);\n        assert.equal(session.documentToScreenColumn(0, 13), 14);\n    },\n\n    \"test: convert document to screen coordinates with leading tabs\": function() {\n        var session = new EditSession(\"\\t\\t123\");\n        session.setTabSize(4);\n\n        assert.equal(session.documentToScreenColumn(0, 0), 0);\n        assert.equal(session.documentToScreenColumn(0, 1), 4);\n        assert.equal(session.documentToScreenColumn(0, 2), 8);\n        assert.equal(session.documentToScreenColumn(0, 3), 9);\n    },\n\n    \"test: documentToScreen without soft wrap\": function() {\n        var session = new EditSession([\n            \"juhu\",\n            \"12\\t\\t34\",\n            \"ぁぁa\"\n        ]);\n\n        assert.position(session.documentToScreenPosition(0, 3), 0, 3);\n        assert.position(session.documentToScreenPosition(1, 3), 1, 4);\n        assert.position(session.documentToScreenPosition(1, 4), 1, 8);\n        assert.position(session.documentToScreenPosition(2, 2), 2, 4);\n    },\n\n    \"test: documentToScreen with soft wrap\": function() {\n        var session = new EditSession([\"foo bar foo bar\"]);\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(12, 12);\n        session.adjustWrapLimit(80);\n        session.setOption(\"wrapMethod\", \"text\");\n        assert.position(session.documentToScreenPosition(0, 11), 0, 11);\n        assert.position(session.documentToScreenPosition(0, 12), 1, 0);\n    },\n\n    \"test: documentToScreen with soft wrap and multibyte characters\": function() {\n        var session = new EditSession([\"ぁぁa\"]);\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(2, 2);\n        session.adjustWrapLimit(80);\n\n        assert.position(session.documentToScreenPosition(0, 1), 1, 0);\n        assert.position(session.documentToScreenPosition(0, 2), 2, 0);\n        assert.position(session.documentToScreenPosition(0, 4), 2, 1);\n    },\n\n    \"test: documentToScreen should clip position to the document boundaries\": function() {\n        var session = new EditSession(\"foo bar\\njuhu kinners\");\n\n        assert.position(session.documentToScreenPosition(-1, 4), 0, 0);\n        assert.position(session.documentToScreenPosition(3, 0), 1, 12);\n    },\n\n    \"test: convert screen to document coordinates\" : function() {\n        var session = new EditSession(\"01234\\t567890\\t1234\");\n        session.setTabSize(4);\n\n        assert.equal(session.screenToDocumentColumn(0, 0), 0);\n        assert.equal(session.screenToDocumentColumn(0, 4), 4);\n        assert.equal(session.screenToDocumentColumn(0, 5), 5);\n        assert.equal(session.screenToDocumentColumn(0, 6), 5);\n        assert.equal(session.screenToDocumentColumn(0, 7), 5);\n        assert.equal(session.screenToDocumentColumn(0, 8), 6);\n        assert.equal(session.screenToDocumentColumn(0, 9), 7);\n        assert.equal(session.screenToDocumentColumn(0, 15), 12);\n        assert.equal(session.screenToDocumentColumn(0, 19), 16);\n\n        session.setTabSize(2);\n\n        assert.equal(session.screenToDocumentColumn(0, 0), 0);\n        assert.equal(session.screenToDocumentColumn(0, 4), 4);\n        assert.equal(session.screenToDocumentColumn(0, 5), 5);\n        assert.equal(session.screenToDocumentColumn(0, 6), 6);\n        assert.equal(session.screenToDocumentColumn(0, 12), 12);\n        assert.equal(session.screenToDocumentColumn(0, 13), 12);\n        assert.equal(session.screenToDocumentColumn(0, 14), 13);\n    },\n\n    \"test: screenToDocument with soft wrap\": function() {\n        var session = new EditSession([\"foo bar foo bar\"]);\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(12, 12);\n        session.adjustWrapLimit(80);\n\n        assert.position(session.screenToDocumentPosition(1, 0), 0, 12);\n        assert.position(session.screenToDocumentPosition(0, 11), 0, 11);\n        // Check if the position is clamped the right way.\n        assert.position(session.screenToDocumentPosition(0, 12), 0, 11);\n        assert.position(session.screenToDocumentPosition(0, 20), 0, 11);\n    },\n\n    \"test: screenToDocument with soft wrap and multi byte characters\": function() {\n        var session = new EditSession([\"ぁ a\"]);\n        session.setUseWrapMode(true);\n        session.adjustWrapLimit(80);\n\n        assert.position(session.screenToDocumentPosition(0, 1), 0, 0);\n        assert.position(session.screenToDocumentPosition(0, 2), 0, 1);\n        assert.position(session.screenToDocumentPosition(0, 3), 0, 2);\n        assert.position(session.screenToDocumentPosition(0, 4), 0, 3);\n        assert.position(session.screenToDocumentPosition(0, 5), 0, 3);\n    },\n\n    \"test: screenToDocument should clip position to the document boundaries\": function() {\n        var session = new EditSession(\"foo bar\\njuhu kinners\");\n\n        assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);\n        assert.position(session.screenToDocumentPosition(0, -1), 0, 0);\n        assert.position(session.screenToDocumentPosition(0, 30), 0, 7);\n        assert.position(session.screenToDocumentPosition(2, 4), 1, 12);\n        assert.position(session.screenToDocumentPosition(1, 30), 1, 12);\n        assert.position(session.screenToDocumentPosition(20, 50), 1, 12);\n        assert.position(session.screenToDocumentPosition(20, 5), 1, 12);\n\n        // and the same for folded rows\n        session.addFold(\"...\", new Range(0,1,1,3));\n        assert.position(session.screenToDocumentPosition(1, 2), 1, 12);\n        // for wrapped rows\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(5,5);\n        assert.position(session.screenToDocumentPosition(4, 1), 1, 12);\n    },\n\n    \"test: wrapLine split function\" : function() {\n        function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {\n            wrapLimit = wrapLimit || 12;\n            tabSize = tabSize || 4;\n            line = lang.stringTrimRight(line);\n            var tokens = EditSession.prototype.$getDisplayTokens(line);\n            var splits = EditSession.prototype.$computeWrapSplits(tokens, wrapLimit, tabSize);\n\n            assert.ok(splits.length == assertEqual.length);\n            for (var i = 0; i < splits.length; i++) {\n                assert.ok(splits[i] == assertEqual[i]);\n            }\n        }\n        \n        EditSession.prototype.$wrapAsCode = true;\n        EditSession.prototype.$indentedSoftWrap = false;\n        // Basic splitting.\n        computeAndAssert(\"foo bar foo bar\", [ 12 ]);\n        computeAndAssert(\"foo bar f   bar\", [ 12 ]);\n        computeAndAssert(\"foo bar f     r\", [ 12 ]); // 14 if we enable \n        computeAndAssert(\"foo bar foo bar foo bara foo\", [12, 25]);\n\n        // Don't split if there is only whitespaces/tabs at the end of the line.\n        computeAndAssert(\"foo foo foo \\t \\t\", [ ]);\n\n        // If there is no space to split, force split.\n        computeAndAssert(\"foooooooooooooo\", [ 12 ]);\n        computeAndAssert(\"fooooooooooooooooooooooooooo\", [12, 24]);\n        computeAndAssert(\"foo bar fooooooooooobooooooo\", [8,  20]);\n\n        // Basic splitting + tabs.\n        computeAndAssert(\"foo \\t\\tbar\", [ 6 ]);\n        computeAndAssert(\"foo \\t \\tbar\", [ 7 ]);\n\n        // Ignore spaces/tabs at beginning of split.\n        computeAndAssert(\"foo \\t \\t   \\t \\t bar\", [ 7 ]); // 14\n\n        // Test wrapping for asian characters.\n        computeAndAssert(\"ぁぁ\", [1], 2);\n        computeAndAssert(\" ぁぁ\", [1, 2], 2);\n        computeAndAssert(\" ぁ\\tぁ\", [1, 3], 2);\n        computeAndAssert(\" ぁぁ\\tぁ\", [2, 4], 4);\n        computeAndAssert(\"ぁぁ ぁぁ\\tぁ\", [3, 6], 6);\n\n        // Test wrapping for punctuation.\n        computeAndAssert(\" ab.c;ef++\", [2, 4, 6, 8], 2);\n        computeAndAssert(\" ab.c;ef++\", [3, 5, 8], 3);\n        computeAndAssert(\" a.b\", [1, 2, 3], 1);\n        computeAndAssert(\"#>>\", [1, 2], 1);\n        \n        // Test wrapping for punctuation in\n        EditSession.prototype.$wrapAsCode = false;\n        computeAndAssert(\"ab cde, Juhu kinners\", [3, 8, 13, 19], 6);\n\n        // test indented wrapping\n        EditSession.prototype.$indentedSoftWrap = true;\n        computeAndAssert(\"foo bar foo bar foo bara foo\", [12, 25]);\n        computeAndAssert(\"fooooooooooooooooooooooooooo\", [12, 24]);\n        computeAndAssert(\"\\t\\tfoo bar fooooooooooobooooooo\", [6, 10, 16, 22, 28]);\n        computeAndAssert(\"\\t\\t\\tfoo bar fooooooooooobooooooo\", [3, 7, 11, 17, 23, 29]);\n        computeAndAssert(\"\\tfoo \\t \\t   \\t \\t bar\", [6, 12]); // 14\n    },\n\n    \"test get longest line\" : function() {\n        var session = new EditSession([\"12\"]);\n        session.setTabSize(4);\n        assert.equal(session.getScreenWidth(), 2);\n\n        session.doc.insertMergedLines({row: 0, column: Infinity}, ['', '']);\n        session.doc.insertFullLines(1, [\"123\"]);\n        assert.equal(session.getScreenWidth(), 3);\n\n        session.doc.insertMergedLines({row: 0, column: Infinity}, ['', '']);\n        session.doc.insertFullLines(1, [\"\\t\\t\"]);\n\n        assert.equal(session.getScreenWidth(), 8);\n\n        session.setTabSize(2);\n        assert.equal(session.getScreenWidth(), 4);\n    },\n\n    \"test getDisplayString\": function() {\n        var session = new EditSession([\"12\"]);\n        session.setTabSize(4);\n\n        assert.equal(session.$getDisplayTokens(\"\\t\").length, 4);\n        assert.equal(session.$getDisplayTokens(\"abc\").length, 3);\n        assert.equal(session.$getDisplayTokens(\"abc\\t\").length, 4);\n    },\n\n    \"test issue 83\": function() {\n        var session = new EditSession(\"\");\n        var editor = new Editor(new MockRenderer(), session);\n        var document = session.getDocument();\n\n        session.setUseWrapMode(true);\n\n        document.insertFullLines(0, [\"a\", \"b\"]);\n        document.insertFullLines(2, [\"c\", \"d\"]);\n        document.removeFullLines(1, 2);\n    },\n\n    \"test wrapMode init has to create wrapData array\": function() {\n        var session = new EditSession(\"foo bar\\nfoo bar\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        session.setUseWrapMode(true);\n        session.setWrapLimitRange(3, 3);\n        session.adjustWrapLimit(80);\n\n        // Test if wrapData is there and was computed.\n        assert.equal(session.$wrapData.length, 2);\n        assert.equal(session.$wrapData[0].length, 1);\n        assert.equal(session.$wrapData[1].length, 1);\n    },\n\n    \"test first line blank with wrap\": function() {\n        var session = new EditSession(\"\\nfoo\");\n        session.setUseWrapMode(true);\n        assert.equal(session.doc.getValue(), [\"\", \"foo\"].join(\"\\n\"));\n    },\n\n    \"test first line blank with wrap 2\" : function() {\n        var session = new EditSession(\"\");\n        session.setUseWrapMode(true);\n        session.setValue(\"\\nfoo\");\n\n        assert.equal(session.doc.getValue(), [\"\", \"foo\"].join(\"\\n\"));\n    },\n    \n    \"test foldAll\": function() {\n        var session = createFoldTestSession();\n        var editor = new Editor(new MockRenderer(), session);\n        var value = \"  /*\\n*comment\\n*/\\n\" + editor.getValue() + \"\\n\";\n        editor.setValue(value + value, 1);\n        editor.setOption(\"mode\", new JavaScriptMode());\n\n        editor.execCommand(\"foldToLevel1\");\n        assert.equal(session.$foldData.length, 2);\n        editor.execCommand(\"foldAllComments\");\n        assert.equal(session.$foldData.length, 4);\n        editor.execCommand(\"foldall\");\n        assert.equal(session.$foldData.length, 4);\n        assert.equal(session.$foldData[1].range.start.row, 3);\n        assert.equal(session.$foldData[3].range.start.row, 11);\n        editor.execCommand(\"golineup\");\n        editor.execCommand(\"gotolineend\");\n        editor.execCommand(\"unfold\");\n        assert.equal(session.$foldData.length, 4);\n        assert.equal(session.$foldData[3].range.start.row, 12);\n        editor.execCommand(\"unfoldall\");\n        assert.equal(session.$foldData.length, 0);\n\n        editor.execCommand(\"foldall\");\n        assert.equal(session.$foldData.length, 4);\n        assert.equal(session.$foldData[1].range.start.row, 3);\n\n        // fold function arguments\n        editor.selection.moveTo(3, 13);\n        editor.execCommand(\"fold\");\n        assert.equal(editor.session.getAllFolds().length, 5);\n        assert.equal(session.$foldData[1].range.start.row, 3);\n        \n        // unfold function arguments\n        editor.execCommand(\"unfold\");\n        assert.equal(editor.session.getAllFolds().length, 4);\n        assert.equal(session.$foldData[1].range.start.row, 3);\n        \n        // unfold function\n        editor.execCommand(\"unfold\");\n        assert.equal(session.$foldData.length, 4);\n        assert.equal(session.$foldData[1].range.start.row, 4);\n\n        // check that calling unfold without folds does not add folds\n        editor.execCommand(\"unfold\");\n        assert.equal(session.$foldData.length, 4);\n        assert.equal(session.$foldData[1].range.start.row, 4);\n    },\n\n    \"test setting undefined value\": function() {\n        var session = createFoldTestSession();\n        var editor = new Editor(new MockRenderer(), session);\n        editor.setOption(\"mode\", new JavaScriptMode());\n\n        editor.setValue(\"test\");\n        assert.equal(session.getValue(), \"test\");\n\n        editor.setValue(undefined);\n        assert.equal(session.getValue(), \"\");\n\n        editor.setValue(\"test\");\n        assert.equal(session.getValue(), \"test\");\n    },\n\n    \"test foldOther\": function() {\n        var session = new EditSession(\"{\\n\\t1{\\n\\t\\t\\n\\t\\t1.1 {\\n\\t\\t}\\n\\t}\\n\\t2 {\\n\\t\\t2.1 {\\n\\t\\t\\t2.2 {\\n\\t\\t\\t}\\n\\t\\t\\t2.3 {\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\\n{\\n}\");\n        var editor = new Editor(new MockRenderer(), session);\n        editor.setOption(\"mode\", new JavaScriptMode());\n\n        editor.gotoLine(3, 2);\n        editor.execCommand(\"foldOther\");\n        assert.equal(foldRows(), \"3,6,16\");\n\n        editor.find(\"2.2\");\n        assert.equal(foldRows(), \"3,8,10,16\");\n\n        var removedFolds = session.unfold();\n        assert.equal(removedFolds.length, 4);\n        assert.equal(foldRows(), \"\");\n\n        editor.session.addFold(\"xxx\", new Range(1, 0, 7, 0));\n        assert.equal(foldRows(), \"1\");\n        editor.session.foldAll();\n        assert.equal(foldRows(), \"0,16\");\n        removedFolds = editor.session.unfold(editor.selection.getAllRanges());\n        assert.equal(removedFolds.length, 1);\n        assert.equal(foldRows(), \"1,8,10,16\");\n\n        function foldRows() {\n            return session.$foldData.map(function(x) {return x.start.row;}).join(\",\");\n        }\n    },\n\n    \"test fold getFoldDisplayLine\": function() {\n        var session = createFoldTestSession();\n        function assertDisplayLine(foldLine, str) {\n            var line = session.getLine(foldLine.end.row);\n            var displayLine =\n                session.getFoldDisplayLine(foldLine, foldLine.end.row, line.length);\n            assert.equal(displayLine, str);\n        }\n\n        assertDisplayLine(session.$foldData[0], \"function foo(args...) {\");\n        assertDisplayLine(session.$foldData[1], \"    for (vfoo...ert(items[bar...\\\"juhu\\\");\");\n    },\n\n    \"test foldLine idxToPosition\": function() {\n        var session = createFoldTestSession();\n\n        function assertIdx2Pos(foldLineIdx, idx, row, column) {\n            var foldLine = session.$foldData[foldLineIdx];\n            assert.position(foldLine.idxToPosition(idx), row, column);\n        }\n\n//        \"function foo(items) {\",\n//        \"    for (var i=0; i<items.length; i++) {\",\n//        \"        alert(items[i] + \\\"juhu\\\");\",\n//        \"    }    // Real Tab.\",\n//        \"}\"\n\n        assertIdx2Pos(0, 12, 0, 12);\n        assertIdx2Pos(0, 13, 0, 13);\n        assertIdx2Pos(0, 14, 0, 13);\n        assertIdx2Pos(0, 19, 0, 13);\n        assertIdx2Pos(0, 20, 0, 18);\n\n        assertIdx2Pos(1, 10, 1, 10);\n        assertIdx2Pos(1, 11, 1, 10);\n        assertIdx2Pos(1, 15, 1, 10);\n        assertIdx2Pos(1, 16, 2, 10);\n        assertIdx2Pos(1, 26, 2, 20);\n        assertIdx2Pos(1, 27, 2, 20);\n        assertIdx2Pos(1, 32, 2, 25);\n    },\n\n    \"test fold documentToScreen\": function() {\n        var session = createFoldTestSession();\n        function assertDoc2Screen(docRow, docCol, screenRow, screenCol) {\n            assert.position(\n                session.documentToScreenPosition(docRow, docCol),\n                screenRow, screenCol\n            );\n        }\n\n        // One fold ending in the same row.\n        assertDoc2Screen(0,  0, 0, 0);\n        assertDoc2Screen(0, 13, 0, 13);\n        assertDoc2Screen(0, 14, 0, 13);\n        assertDoc2Screen(0, 17, 0, 13);\n        assertDoc2Screen(0, 18, 0, 20);\n\n        // Fold ending on some other row.\n        assertDoc2Screen(1,  0, 1, 0);\n        assertDoc2Screen(1, 10, 1, 10);\n        assertDoc2Screen(1, 11, 1, 10);\n        assertDoc2Screen(1, 99, 1, 10);\n\n        assertDoc2Screen(2,  0, 1, 10);\n        assertDoc2Screen(2,  9, 1, 10);\n        assertDoc2Screen(2, 10, 1, 16);\n        assertDoc2Screen(2, 11, 1, 17);\n\n        // Fold in the same row with fold over more then one row in the same row.\n        assertDoc2Screen(2, 19, 1, 25);\n        assertDoc2Screen(2, 20, 1, 26);\n        assertDoc2Screen(2, 21, 1, 26);\n\n        assertDoc2Screen(2, 24, 1, 26);\n        assertDoc2Screen(2, 25, 1, 32);\n        assertDoc2Screen(2, 26, 1, 33);\n        assertDoc2Screen(2, 99, 1, 40);\n\n        // Test one position after the folds. Should be all like normal.\n        assertDoc2Screen(3,  0, 2,  0);\n    },\n\n    \"test fold screenToDocument\": function() {\n        var session = createFoldTestSession();\n        function assertScreen2Doc(docRow, docCol, screenRow, screenCol) {\n            assert.position(\n                session.screenToDocumentPosition(screenRow, screenCol),\n                docRow, docCol\n            );\n        }\n\n        // One fold ending in the same row.\n        assertScreen2Doc(0,  0, 0, 0);\n        assertScreen2Doc(0, 13, 0, 13);\n        assertScreen2Doc(0, 13, 0, 14);\n        assertScreen2Doc(0, 18, 0, 20);\n        assertScreen2Doc(0, 19, 0, 21);\n\n        // Fold ending on some other row.\n        assertScreen2Doc(1,  0, 1, 0);\n        assertScreen2Doc(1, 10, 1, 10);\n        assertScreen2Doc(1, 10, 1, 11);\n\n        assertScreen2Doc(1, 10, 1, 15);\n        assertScreen2Doc(2, 10, 1, 16);\n        assertScreen2Doc(2, 11, 1, 17);\n\n        // Fold in the same row with fold over more then one row in the same row.\n        assertScreen2Doc(2, 19, 1, 25);\n        assertScreen2Doc(2, 20, 1, 26);\n        assertScreen2Doc(2, 20, 1, 27);\n\n        assertScreen2Doc(2, 20, 1, 31);\n        assertScreen2Doc(2, 25, 1, 32);\n        assertScreen2Doc(2, 26, 1, 33);\n        assertScreen2Doc(2, 33, 1, 99);\n\n        // Test one position after the folds. Should be all like normal.\n        assertScreen2Doc(3,  0, 2,  0);\n    },\n\n    \"test getFoldsInRange()\": function() {\n        var session = createFoldTestSession();\n        var foldLines = session.$foldData;\n        var folds = foldLines[0].folds.concat(foldLines[1].folds);\n\n        function test(startRow, startColumn, endColumn, endRow, folds) {\n            var r = new Range(startRow, startColumn, endColumn, endRow);\n            var retFolds = session.getFoldsInRange(r);\n\n            assert.ok(retFolds.length == folds.length);\n            for (var i = 0; i < retFolds.length; i++) {\n                assert.equal(retFolds[i].range + \"\", folds[i].range + \"\");\n            }\n        }\n\n        test(0, 0, 0, 13,  [ ]);\n        test(0, 0, 0, 14,  [ folds[0] ]);\n        test(0, 0, 0, 18,  [ folds[0] ]);\n        test(0, 0, 1, 10,  [ folds[0] ]);\n        test(0, 0, 1, 11,  [ folds[0], folds[1] ]);\n        test(0, 18, 1, 11, [ folds[1] ]);\n        test(2, 0,  2, 13, [ folds[1] ]);\n        test(2, 10, 2, 20, [ ]);\n        test(2, 10, 2, 11, [ ]);\n        test(2, 19, 2, 20, [ ]);\n    },\n\n    \"test fold one-line text insert\": function() {\n        // These are mostly test for the FoldLine.addRemoveChars function.\n        var session = createFoldTestSession();\n        var undoManager = session.getUndoManager();\n        var foldLines = session.$foldData;\n\n        var foldLine, fold, folds;\n        // First line.\n        foldLine = session.$foldData[0];\n        fold = foldLine.folds[0];\n\n        insert(0, 0, \"0\", session);\n        assert.range(foldLine.range, 0, 14, 0, 19, session);\n        assert.range(fold.range,     0, 14, 0, 19, session);\n        insert(0, 14, \"1\", session);\n        assert.range(foldLine.range, 0, 15, 0, 20, session);\n        assert.range(fold.range,     0, 15, 0, 20, session);\n        insert(0, 20, \"2\", session);\n        assert.range(foldLine.range, 0, 15, 0, 20, session);\n        assert.range(fold.range,     0, 15, 0, 20, session);\n\n        // Second line.\n        foldLine = session.$foldData[1];\n        folds = foldLine.folds;\n\n        insert(1, 0, \"3\", session);\n        assert.range(foldLine.range, 1, 11, 2, 25);\n        assert.range(folds[0].range, 1, 11, 2, 10);\n        assert.range(folds[1].range, 2, 20, 2, 25);\n\n        insert(1, 11, \"4\", session);\n        assert.range(foldLine.range, 1, 12, 2, 25);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 20, 2, 25);\n\n        insert(2, 10, \"5\", session);\n        assert.range(foldLine.range, 1, 12, 2, 26);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 21, 2, 26);\n\n        insert(2, 21, \"6\", session);\n        assert.range(foldLine.range, 1, 12, 2, 27);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 22, 2, 27);\n\n        insert(2, 27, \"7\", session);\n        assert.range(foldLine.range, 1, 12, 2, 27);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 22, 2, 27);\n\n        // UNDO = REMOVE\n        undoManager.undo(); // 6\n        assert.range(foldLine.range, 1, 12, 2, 27);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 22, 2, 27);\n\n        undoManager.undo(); // 5\n        assert.range(foldLine.range, 1, 12, 2, 26);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 21, 2, 26);\n\n        undoManager.undo(); // 4\n        assert.range(foldLine.range, 1, 12, 2, 25);\n        assert.range(folds[0].range, 1, 12, 2, 10);\n        assert.range(folds[1].range, 2, 20, 2, 25);\n\n        undoManager.undo(); // 3\n        assert.range(foldLine.range, 1, 11, 2, 25);\n        assert.range(folds[0].range, 1, 11, 2, 10);\n        assert.range(folds[1].range, 2, 20, 2, 25);\n\n        undoManager.undo(); // Beginning first line.\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 0, 15, 0, 20);\n        assert.range(foldLines[1].range, 1, 10, 2, 25);\n\n        foldLine = session.$foldData[0];\n        fold = foldLine.folds[0];\n\n        undoManager.undo(); // 2\n        assert.range(foldLine.range, 0, 15, 0, 20);\n        assert.range(fold.range,     0, 15, 0, 20);\n\n        undoManager.undo(); // 1\n        assert.range(foldLine.range, 0, 14, 0, 19);\n        assert.range(fold.range,     0, 14, 0, 19);\n\n        undoManager.undo(); // 0\n        assert.range(foldLine.range, 0, 13, 0, 18);\n        assert.range(fold.range,     0, 13, 0, 18);\n    },\n\n    \"test fold multi-line insert/remove\": function() {\n        var session = createFoldTestSession(),\n            undoManager = session.getUndoManager(),\n            foldLines = session.$foldData;\n        var foldLines = session.$foldData;\n\n        insert(0, 0, \"\\nfo0\", session);\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 2, 10, 3, 25);\n\n        insert(2, 0, \"\\nba1\", session);\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 3, 13, 4, 25);\n\n        insert(3, 10, \"\\nfo2\", session);\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 4,  6, 5, 25);\n\n        insert(5, 10, \"\\nba3\", session);\n        assert.equal(foldLines.length, 3);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 4,  6, 5, 10);\n        assert.range(foldLines[2].range, 6, 13, 6, 18);\n\n        insert(6, 18, \"\\nfo4\", session);\n        assert.equal(foldLines.length, 3);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 4,  6, 5, 10);\n        assert.range(foldLines[2].range, 6, 13, 6, 18);\n\n        undoManager.undo(); // 3\n        assert.equal(foldLines.length, 3);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 4,  6, 5, 10);\n        assert.range(foldLines[2].range, 6, 13, 6, 18);\n\n        undoManager.undo(); // 2\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 4,  6, 5, 25);\n\n        undoManager.undo(); // 1\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 3, 13, 4, 25);\n\n        undoManager.undo(); // 0\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 1, 16, 1, 21);\n        assert.range(foldLines[1].range, 2, 10, 3, 25);\n\n        undoManager.undo(); // Beginning\n        assert.equal(foldLines.length, 2);\n        assert.range(foldLines[0].range, 0, 13, 0, 18);\n        assert.range(foldLines[1].range, 1, 10, 2, 25);\n        // TODO: Add test for inseration inside of folds.\n    },\n\n    \"test fold wrap data compution\": function() {\n        function assertWrap(line0, line1, line2) {\n            line0 && assertArray(wrapData[0], line0);\n            line1 && assertArray(wrapData[1], line1);\n            line2 && assertArray(wrapData[2], line2);\n        }\n\n        function removeFoldAssertWrap(docRow, docColumn, line0, line1, line2) {\n            session.removeFold(session.getFoldAt(docRow, docColumn));\n            assertWrap(line0, line1, line2);\n        }\n\n        var lines = [\n            \"foo bar foo bar\",\n            \"foo bar foo bar\",\n            \"foo bar foo bar\"\n        ];\n\n        var session = new EditSession(lines.join(\"\\n\"));\n        session.setUseWrapMode(true);\n        session.$wrapLimit = 7;\n        session.$updateWrapData(0, 2);\n        var wrapData = session.$wrapData;\n\n        // Do a simple assertion without folds to check basic functionallity.\n        assertWrap([8], [8], [8]);\n\n        // --- Do in line folding ---\n\n        // Adding a fold. The split position is inside of the fold. As placeholder\n        // are not splitable, the split should be before the split.\n        session.addFold(\"woot\", new Range(0, 4, 0, 15));\n        assertWrap([4], [8], [8]);\n\n        // Remove the fold again which should reset the wrapData.\n        removeFoldAssertWrap(0, 4, [8], [8], [8]);\n\n        session.addFold(\"woot\", new Range(0, 6, 0, 9));\n        assertWrap([6, 13], [8], [8]);\n        removeFoldAssertWrap(0, 6, [8], [8], [8]);\n\n        // The fold fits into the wrap limit - no split expected.\n        session.addFold(\"woot\", new Range(0, 3, 0, 15));\n        assertWrap([], [8], [8]);\n        removeFoldAssertWrap(0, 4, [8], [8], [8]);\n\n        // Fold after split position should be all fine.\n        session.addFold(\"woot\", new Range(0, 8, 0, 15));\n        assertWrap([8], [8], [8]);\n        removeFoldAssertWrap(0, 8, [8], [8], [8]);\n\n        // Fold's placeholder is far too long for wrapSplit.\n        session.addFold(\"woot0123456789\", new Range(0, 8, 0, 15));\n        assertWrap([8], [8], [8]);\n        removeFoldAssertWrap(0, 8, [8], [8], [8]);\n\n        // Fold's placeholder is far too long for wrapSplit\n        // + content at the end of the line\n        session.addFold(\"woot0123456789\", new Range(0, 6, 0, 8));\n        assertWrap([6, 20], [8], [8]);\n        removeFoldAssertWrap(0, 8, [8], [8], [8]);\n\n        session.addFold(\"woot0123456789\", new Range(0, 6, 0, 8));\n        session.addFold(\"woot0123456789\", new Range(0, 8, 0, 10));\n        assertWrap([6, 20, 34], [8], [8]);\n        session.removeFold(session.getFoldAt(0, 7));\n        removeFoldAssertWrap(0, 8, [8], [8], [8]);\n\n        session.addFold(\"woot0123456789\", new Range(0, 7, 0, 9));\n        session.addFold(\"woot0123456789\", new Range(0, 13, 0, 15));\n        assertWrap([7, 21, 25], [8], [8]);\n        session.removeFold(session.getFoldAt(0, 7));\n        removeFoldAssertWrap(0, 14, [8], [8], [8]);\n\n        // --- Do some multiline folding ---\n\n        // Add a fold over two lines. Note, that the wrapData[1] stays the\n        // same. This is an implementation detail and expected behavior.\n        session.addFold(\"woot\", new Range(0, 8, 1, 15));\n        assertWrap([8], [8 /* See comments */], [8]);\n        removeFoldAssertWrap(0, 8, [8], [8], [8]);\n\n        session.addFold(\"woot\", new Range(0, 9, 1, 11));\n        assertWrap([8, 14], [8 /* See comments */], [8]);\n        removeFoldAssertWrap(0, 9, [8], [8], [8]);\n\n        session.addFold(\"woot\", new Range(0, 9, 1, 15));\n        assertWrap([8], [8 /* See comments */], [8]);\n        removeFoldAssertWrap(0, 9, [8], [8], [8]);\n\n        return session;\n    },\n    \n    \"test delete fold with wrap enabled\": function() {\n        var session = new EditSession(\"\");\n        session.setValue([\n            \"This is some placeholder text that will be folded inline.\",\n            \"This is some placeholder text that will be folded inline.\",\n            \"More text.\",\n            \"<p>The cursor in this paragraph text will be offset by 1 row.<p>\",\n            \"<p>Everything after this will be offset as well due to the folds in the row before too.</p>\"\n        ].join(\"\\n\"));\n        session.addFold('...', new Range(0, 8, 0, 42));\n        session.addFold('...', new Range(1, 8, 1, 42));\n        session.addFold('...', new Range(3, 7, 3, 51));\n        session.setOption(\"wrap\", 40);\n        session.remove(new Range(0,0, 2, 5));\n        // needed because adjustWrapLimit is called async from renderer\n        session.adjustWrapLimit(80);\n        \n        assert.equal(session.$wrapData + \"\", [[], [], [40, 76]] + \"\");\n    },\n        \n    \"test add fold\": function() {\n        var session = createFoldTestSession();\n        var fold;\n\n        function addFold(placeholder, range) {\n            fold = session.addFold(placeholder, range);\n        }\n\n        addFold(\"foo\", new Range(0, 13, 0, 17));\n        addFold(\"foo\", new Range(0, 14, 0, 18));\n        addFold(\"foo\", new Range(0, 13, 0, 18));\n        assert.equal(session.$foldData[0].folds.length, 1);\n\n        addFold(\"f\", new Range(0, 13, 0, 18));\n        addFold(\"foo\", new Range(0, 18, 0, 21));\n        assert.equal(session.$foldData[0].folds.length, 2);\n        session.removeFold(fold);\n\n        addFold(\"foo\", new Range(0, 18, 0, 22));\n        addFold(\"foo\", new Range(0, 18, 0, 19));\n        addFold(\"foo\", new Range(0, 22, 1, 10));\n        \n        session.unfold();\n        addFold(\"x\", new Range(1, 9, 3, 15));\n        addFold(\"x\", new Range(2, 9, 2, 15));\n        addFold(\"x\", new Range(2, 10, 2, 18));\n        addFold(\"x\", new Range(2, 10, 2, 18));\n        addFold(\"x\", new Range(2, 25, 2, 27));\n        addFold(\"x\", new Range(2, 28, 2, 30));\n        addFold(\"x\", new Range(2, 7, 2, 29));\n        var folds = session.getFoldsInRange(new Range(0,0,100,100));\n        assert.equal(folds.length, 1);\n        session.expandFolds(folds);\n        folds = session.getFoldsInRange(new Range(0,0,100,100));\n        assert.equal(folds.length, 1);\n        session.expandFolds(folds);\n        folds = session.getFoldsInRange(new Range(0,0,100,100));\n        assert.equal(folds.length, 2);\n        session.expandFolds(folds);\n        folds = session.getFoldsInRange(new Range(0,0,100,100));\n        assert.equal(folds.length, 0);\n    },\n\n    \"test add subfolds\": function() {\n        var session = createFoldTestSession();\n        var fold, oldFold;\n        var foldData = session.$foldData;\n\n        oldFold = foldData[0].folds[0];\n\n        fold = session.addFold(\"fold0\", new Range(0, 10, 0, 21));\n        assert.equal(foldData[0].folds.length, 1);\n        assert.equal(fold.subFolds.length, 1);\n        assert.equal(fold.subFolds[0], oldFold);\n\n        session.expandFold(fold);\n        assert.equal(foldData[0].folds.length, 1);\n        assert.equal(foldData[0].folds[0], oldFold);\n        assert.equal(fold.subFolds.length, 0);\n\n        fold = session.addFold(\"fold0\", new Range(0, 13, 2, 10));\n        assert.equal(foldData.length, 1);\n        assert.equal(fold.subFolds.length, 2);\n        assert.equal(fold.subFolds[0], oldFold);\n\n        session.expandFold(fold);\n        assert.equal(foldData.length, 2);\n        assert.equal(foldData[0].folds.length, 1);\n        assert.equal(foldData[0].folds[0], oldFold);\n        assert.equal(fold.subFolds.length, 0);\n\n        session.unfold(null, true);\n        fold = session.addFold(\"fold0\", new Range(0, 0, 0, 21));\n        session.addFold(\"fold0\", new Range(0, 1, 0, 5));\n        session.addFold(\"fold0\", new Range(0, 6, 0, 8));\n        assert.equal(fold.subFolds.length, 2);\n    },\n\n    \"test row cache\": function() {\n        var session = createFoldTestSession();\n\n        session.screenToDocumentPosition(2,3);\n        assertArray(session.$docRowCache, [1,3]);\n        assertArray(session.$screenRowCache, [1,2]);\n\n        session.screenToDocumentPosition(5,3);\n        assertArray(session.$docRowCache, [1,3,4]);\n        assertArray(session.$screenRowCache, [1,2,3]);\n\n        session.screenToDocumentPosition(0,3);\n        assertArray(session.$docRowCache, [1,3,4]);\n        assertArray(session.$screenRowCache, [1,2,3]);\n\n        var pos = session.screenToDocumentPosition(0,0);\n        assert.equal(pos.row, 0);\n        assertArray(session.$docRowCache, [1,3,4]);\n        assertArray(session.$screenRowCache, [1,2,3]);\n        \n        session.screenToDocumentPosition(1,0);\n        assertArray(session.$docRowCache, [1,3,4]);\n        assertArray(session.$screenRowCache, [1,2,3]);\n\n        session.$resetRowCache();\n        assertArray(session.$docRowCache, []);\n        assertArray(session.$screenRowCache, []);\n        \n        session.screenToDocumentPosition(1,3);\n        assertArray(session.$docRowCache, [1]);\n        assertArray(session.$screenRowCache, [1]);\n       \n        session.screenToDocumentPosition(5,3);\n        assertArray(session.$docRowCache, [1,3,4]);\n        assertArray(session.$screenRowCache, [1,2,3]);\n        \n        session = new EditSession(new Array(30).join(\"\\n\"));\n        session.documentToScreenPosition(2,0);\n        session.documentToScreenPosition(2,0);\n        assertArray(session.$docRowCache, [1,2]);\n        assertArray(session.$screenRowCache, [1,2]);\n    },\n\n    \"test annotations\": function() {\n        var session = new EditSession([]),\n            annotation = {row: 0, type: 'info', text: \"This is a test.\"};\n\n        session.clearAnnotations();\n        assertArray(session.getAnnotations(), []);\n        session.setAnnotations([annotation]);\n        assertArray(session.getAnnotations(), [annotation]);\n    },\n    \n    \"test: mode loading\" : async function(next) {\n        delete EditSession.prototype.$modes[\"ace/mode/javascript\"];\n        delete EditSession.prototype.$modes[\"ace/mode/css\"];\n        delete EditSession.prototype.$modes[\"ace/mode/sh\"];\n        require(\"./config\").setLoader(function(name, onLoad) {\n            if (name == \"ace/mode/javascript\") {\n                return onLoad(null, require(\"./mode/javascript\"));\n            }\n            if (name == \"ace/mode/sh\") {\n                return setTimeout(function() {\n                    return onLoad(null, require(\"./mode/sh\"));\n                });\n            }\n            if (name == \"ace/mode/css\") {\n                return setTimeout(function() {\n                    return onLoad(null, require(\"./mode/css\"));\n                });\n            }\n        });\n        var session = new EditSession([]);\n        \n        var onChangeModeCallCount = 0;\n        var originalOnChangeMode = session.$onChangeMode;\n\n        // Create spy\n        session.$onChangeMode = function(...arguments) {\n            onChangeModeCallCount++;\n            originalOnChangeMode.apply(this, arguments);\n        };\n\n        session.setMode(\"ace/mode/javascript\");   \n        assert.equal(session.$modeId, \"ace/mode/javascript\");\n\n        var modeChangeCallbacks = 0;\n        session.once(\"changeMode\", function() {\n            assert.equal(session.$modeId, \"ace/mode/sh\");\n            modeChangeCallbacks++;\n        });\n        session.setMode(\"ace/mode/sh\", function() {\n            assert.equal(session.$mode.$id, \"ace/mode/sh\");\n            modeChangeCallbacks++;\n        });\n        assert.equal(session.$modeId, \"ace/mode/sh\");\n        assert.equal(session.$mode.$id, \"ace/mode/javascript\");\n\n        await lang.sleep(0);\n        assert.equal(modeChangeCallbacks, 2);\n        session.setMode(\"ace/mode/javascript\");\n        assert.equal(session.$mode.$id, \"ace/mode/javascript\");\n        session.setMode(\"ace/mode/sh\");\n        assert.equal(session.$mode.$id, \"ace/mode/sh\");\n        session.setMode(\"ace/mode/css\");\n        assert.equal(session.$mode.$id, \"ace/mode/sh\");\n        // destory session to check if the last mode which is being loaded is aborted or not\n        session.destroy();\n\n        await lang.sleep(0);\n        // check if last setmode is aborted due to destroy\n        assert.equal(onChangeModeCallCount, 4);\n        session.$onChangeMode = originalOnChangeMode;\n        next();\n    },\n\n    \"test: sets destroyed flag when destroy called and tokenizer is never null\": function() {\n        var session = new EditSession([\"foo bar foo bar\"]);\n        assert.notEqual(session.bgTokenizer, null);\n        assert.equal(session.destroyed, false);\n\n        session.destroy();\n        assert.equal(session.destroyed, true);\n        assert.notEqual(session.bgTokenizer, null);\n    },\n\n    \"test: JSON serialization\": function() {\n        var session = new EditSession([\"Hello world!\"]);\n        session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n        session.setMode(\"ace/mode/javascript\");\n        session = EditSession.fromJSON(JSON.stringify(session));\n\n        assert.equal(session.getAnnotations().length, 1);\n        assert.equal(session.getMode().$id, \"ace/mode/javascript\");\n        assert.equal(session.getScrollLeft(), 0);\n        assert.equal(session.getScrollTop(), 0);\n        assert.equal(session.getValue(), \"Hello world!\");\n    },\n\n    \"test: JSON serialization preserves undo/redo history\": function() {\n        var session = new EditSession([\"Hello world!\"]);\n        session.setUndoManager(new UndoManager());\n        var document = session.getDocument();\n\n        insert(0, 12, \" test1\", session);\n        insert(0, 18, \" test2\", session);\n        insert(0, 24, \" test3\", session);\n\n        assert.equal(session.getValue(), \"Hello world! test1 test2 test3\");\n\n        session.getUndoManager().undo(session);\n        assert.equal(session.getValue(), \"Hello world! test1 test2\");\n\n        var serialized = JSON.stringify(session);\n        session = EditSession.fromJSON(serialized);\n\n        assert.equal(session.getValue(), \"Hello world! test1 test2\");\n\n        // Test undo stack works\n        session.getUndoManager().undo(session);\n        assert.equal(session.getValue(), \"Hello world! test1\");\n\n        session.getUndoManager().undo(session);\n        assert.equal(session.getValue(), \"Hello world!\");\n\n        // Test redo stack works\n        session.getUndoManager().redo(session);\n        assert.equal(session.getValue(), \"Hello world! test1\");\n\n        session.getUndoManager().redo(session);\n        assert.equal(session.getValue(), \"Hello world! test1 test2\");\n    },\n\n    \"test: operation handling : when session it not attached to an editor\": async function(done) {\n        const session = new EditSession(\"Hello world!\");\n        const beforeEndOperationSpy = [];\n        session.on(\"beforeEndOperation\", () => {\n            beforeEndOperationSpy.push(session.curOp);\n        });\n\n        // When both start and end operation are invoked by the consumer\n        session.startOperation({command: {name: \"inserting-both\"}});\n        session.insert({row: 0, column : 0}, \"both\");\n        session.endOperation();\n        assert.equal(beforeEndOperationSpy.length, 1);\n        assert.equal(beforeEndOperationSpy[0].command.name, \"inserting-both\");\n        assert.equal(beforeEndOperationSpy[0].docChanged, true);\n        assert.equal(beforeEndOperationSpy[0].selectionChanged, true);\n\n        // When only start operation is invoked\n        session.startOperation({command: {name: \"inserting-start\"}});\n        session.insert({row: 0, column : 0}, \"start\");\n\n        await lang.sleep(10);\n        assert.equal(beforeEndOperationSpy.length, 2);\n        assert.equal(beforeEndOperationSpy[1].command.name, \"inserting-start\");\n        assert.equal(beforeEndOperationSpy[1].docChanged, true);\n        assert.equal(beforeEndOperationSpy[1].selectionChanged, true);\n\n        // When only end operation is invoked\n        session.insert({row: 0, column : 0}, \"end\");\n        session.endOperation();\n        assert.equal(beforeEndOperationSpy.length, 3);\n        assert.deepEqual(beforeEndOperationSpy[2].command, {});\n        assert.equal(beforeEndOperationSpy[2].docChanged, true);\n        assert.equal(beforeEndOperationSpy[2].selectionChanged, true);\n\n        // When nothing is invoked\n        session.insert({row: 0, column : 0}, \"none\");\n\n        await lang.sleep(10);\n        assert.equal(beforeEndOperationSpy.length, 4);\n        assert.deepEqual(beforeEndOperationSpy[3].command, {});\n        assert.equal(beforeEndOperationSpy[3].docChanged, true);\n        assert.equal(beforeEndOperationSpy[3].selectionChanged, true);\n\n        done();\n    },\n\n    \"test: operation handling : when session is attached to an editor\": async function(done) {\n        const session = new EditSession(\"Hello world!\");\n        const editor = new Editor(new MockRenderer(), session);\n        const beforeEndOperationSpySession = [];\n        session.on(\"beforeEndOperation\", () => {\n            beforeEndOperationSpySession.push(session.curOp);\n        });\n        const beforeEndOperationSpyEditor = [];\n        editor.on(\"beforeEndOperation\", () => {\n            beforeEndOperationSpyEditor.push(editor.curOp);\n        });\n\n        // Imperative update from editor\n        editor.startOperation({command: {name: \"imperative-update\"}});\n        editor.insert(\"update\");\n        editor.endOperation();\n        for (const beforeEndOperationSpy of [beforeEndOperationSpySession, beforeEndOperationSpyEditor ]) {\n            assert.equal(beforeEndOperationSpy.length, 1);\n            assert.equal(beforeEndOperationSpy[0].command.name, \"imperative-update\");\n            assert.equal(beforeEndOperationSpy[0].docChanged, true);\n            assert.equal(beforeEndOperationSpy[0].selectionChanged, true);\n            assert.equal(!!beforeEndOperationSpy[0].selectionBefore, true);\n        }\n\n        // Imperative update from session\n        session.startOperation({command: {name: \"session-update\"}});\n        session.insert({row: 0, column : 0},\"update\");\n        session.endOperation();\n        for (const beforeEndOperationSpy of [beforeEndOperationSpySession, beforeEndOperationSpyEditor ]) {\n            assert.equal(beforeEndOperationSpy.length, 2);\n            assert.equal(beforeEndOperationSpy[1].command.name, \"session-update\");\n            assert.equal(beforeEndOperationSpy[1].docChanged, true);\n            assert.equal(beforeEndOperationSpy[1].selectionChanged, true);\n            assert.equal(!!beforeEndOperationSpy[1].selectionBefore, true);\n        }\n\n        // Command update\n        editor.execCommand(editor.commands.byName.indent);\n        for (const beforeEndOperationSpy of [beforeEndOperationSpySession, beforeEndOperationSpyEditor ]) {\n            assert.equal(beforeEndOperationSpy.length, 3);\n            assert.equal(beforeEndOperationSpy[2].command.name, \"indent\");\n            assert.equal(beforeEndOperationSpy[2].docChanged, true);\n            assert.equal(beforeEndOperationSpy[2].selectionChanged, true);\n            assert.equal(!!beforeEndOperationSpy[2].selectionBefore, true);\n        }\n\n        // Session cleanup logic\n        const newSession = new EditSession(\"Hello again!\");\n        editor.setSession(newSession);\n        const beforeEndOperationSpyNewSession = [];\n        newSession.on(\"beforeEndOperation\", () => {\n            beforeEndOperationSpyNewSession.push(newSession.curOp);\n        });\n        editor.execCommand(editor.commands.byName.indent);\n        assert.equal(beforeEndOperationSpyEditor.length, 4);\n        assert.equal(beforeEndOperationSpyNewSession.length, 1);\n        assert.equal(beforeEndOperationSpySession.length, 3);\n\n        // Imperative implicit update from editor\n        editor.insert(\"update\");\n\n        await lang.sleep(10);\n        assert.equal(beforeEndOperationSpyEditor.length, 5);\n        assert.equal(beforeEndOperationSpyNewSession.length, 2);\n        done();\n    }\n};\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"./virtual_renderer\").VirtualRenderer} VirtualRenderer\n * @typedef {import(\"./selection\").Selection} Selection\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.SearchOptions} SearchOptions\n */\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar useragent = require(\"./lib/useragent\");\nvar TextInput = require(\"./keyboard/textinput\").TextInput;\nvar MouseHandler = require(\"./mouse/mouse_handler\").MouseHandler;\nvar FoldHandler = require(\"./mouse/fold_handler\").FoldHandler;\nvar KeyBinding = require(\"./keyboard/keybinding\").KeyBinding;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Search = require(\"./search\").Search;\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar CommandManager = require(\"./commands/command_manager\").CommandManager;\nvar defaultCommands = require(\"./commands/default_commands\").commands;\nvar config = require(\"./config\");\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\nvar GutterKeyboardHandler = require(\"./keyboard/gutter_handler\").GutterKeyboardHandler;\nvar nls = require(\"./config\").nls;\n\nvar clipboard = require(\"./clipboard\");\nvar keys = require('./lib/keys');\n\nvar event = require(\"./lib/event\");\nvar HoverTooltip = require(\"./tooltip\").HoverTooltip;\n\n/**\n * The main entry point into the Ace functionality.\n *\n * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.\n *\n * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.\n **/\nclass Editor {\n    /**\n     * Creates a new `Editor` object.\n     *\n     * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything\n     * @param {EditSession} [session] The `EditSession` to refer to\n     * @param {Partial<import(\"../ace-internal\").Ace.EditorOptions>} [options] The default options\n     **/\n    constructor(renderer, session, options) {\n        /**@type {string}*/\n        this.id = \"editor\" + (++Editor.$uid);\n        /**@type{EditSession}*/this.session;\n        this.$toDestroy = [];\n\n        var container = renderer.getContainerElement();\n        /**@type {HTMLElement & {env?:any, value?:any}}*/\n        this.container = container;\n        /**@type {VirtualRenderer}*/\n        this.renderer = renderer;\n        this.commands = new CommandManager(useragent.isMac ? \"mac\" : \"win\", defaultCommands);\n        if (typeof document == \"object\") {\n            this.textInput = new TextInput(renderer.getTextAreaContainer(), this);\n            this.renderer.textarea = this.textInput.getElement();\n            // TODO detect touch event support\n            /**@type {MouseHandler}*/\n            this.$mouseHandler = new MouseHandler(this);\n            new FoldHandler(this);\n        }\n        /**@type {KeyBinding}*/\n        this.keyBinding = new KeyBinding(this);\n        /**@type {Search}*/\n        this.$search = new Search().set({\n            wrap: true\n        });\n\n        this.$historyTracker = this.$historyTracker.bind(this);\n        this.commands.on(\"exec\", this.$historyTracker);\n\n        this.$initOperationListeners();\n\n        this._$emitInputEvent = lang.delayedCall(function() {\n            this._signal(\"input\", {});\n            if (this.session && !this.session.destroyed)\n                this.session.bgTokenizer.scheduleStart();\n        }.bind(this));\n\n        this.on(\"change\", function(_, _self) {\n            _self._$emitInputEvent.schedule(31);\n        });\n\n        this.setSession(session || options && options.session || new EditSession(\"\"));\n        config.resetOptions(this);\n        if (options)\n            this.setOptions(options);\n        config._signal(\"editor\", this);\n    }\n\n    $initOperationListeners() {\n        this.commands.on(\"exec\", this.startOperation.bind(this), true);\n        this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n    }\n\n    startOperation(commandEvent) {\n        this.session.startOperation(commandEvent);\n    }\n\n    /**\n     * @arg e\n     */\n    endOperation(e) {\n        this.session.endOperation(e);\n    }\n\n    onStartOperation(commandEvent) {\n        this.curOp = this.session.curOp;\n        this.curOp.scrollTop = this.renderer.scrollTop;\n        this.prevOp = this.session.prevOp;\n\n        if (!commandEvent) {\n            this.previousCommand = null;\n        }\n    }\n\n    /**\n     * @arg e\n     */\n    onEndOperation(e) {\n        if (this.curOp && this.session) {\n            if (e && e.returnValue === false) {\n                this.curOp = null;\n                return;\n            }\n\n            this._signal(\"beforeEndOperation\");\n            if (!this.curOp) return;\n\n            var command = this.curOp.command;\n            var scrollIntoView = command && command.scrollIntoView;\n            if (scrollIntoView) {\n                switch (scrollIntoView) {\n                    case \"center-animate\":\n                        scrollIntoView = \"animate\";\n                    /* fall through */\n                    case \"center\":\n                        this.renderer.scrollCursorIntoView(null, 0.5);\n                        break;\n                    case \"animate\":\n                    case \"cursor\":\n                        this.renderer.scrollCursorIntoView();\n                        break;\n                    case \"selectionPart\":\n                        var range = this.selection.getRange();\n                        var config = this.renderer.layerConfig;\n                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {\n                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);\n                        }\n                        break;\n                    default:\n                        break;\n                }\n                if (scrollIntoView == \"animate\")\n                    this.renderer.animateScrolling(this.curOp.scrollTop);\n            }\n\n            this.$lastSel = this.session.selection.toJSON();\n            this.prevOp = this.curOp;\n            this.curOp = null;\n        }\n    }\n\n    /**\n     * @param e\n     */\n    $historyTracker(e) {\n        if (!this.$mergeUndoDeltas)\n            return;\n\n        var prev = this.prevOp;\n        var mergeableCommands = this.$mergeableCommands;\n        // previous command was the same\n        var shouldMerge = prev.command && (e.command.name == prev.command.name);\n        if (e.command.name == \"insertstring\") {\n            var text = e.args;\n            if (this.mergeNextCommand === undefined)\n                this.mergeNextCommand = true;\n\n            shouldMerge = shouldMerge\n                && this.mergeNextCommand // previous command allows to coalesce with\n                && (!/\\s/.test(text) || /\\s/.test(prev.args)); // previous insertion was of same type\n\n            this.mergeNextCommand = true;\n        } else {\n            shouldMerge = shouldMerge\n                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n        }\n\n        if (\n            this.$mergeUndoDeltas != \"always\"\n            && Date.now() - this.sequenceStartTime > 2000\n        ) {\n            shouldMerge = false; // the sequence is too long\n        }\n\n        if (shouldMerge)\n            this.session.mergeUndoDeltas = true;\n        else if (mergeableCommands.indexOf(e.command.name) !== -1)\n            this.sequenceStartTime = Date.now();\n    }\n\n    /**\n     * Sets a new key handler, such as \"vim\" or \"windows\".\n     * @param {String | import(\"../ace-internal\").Ace.KeyboardHandler | null} keyboardHandler The new key handler\n     * @param {() => void} [cb]\n     **/\n    setKeyboardHandler(keyboardHandler, cb) {\n        if (keyboardHandler && typeof keyboardHandler === \"string\" && keyboardHandler != \"ace\") {\n            this.$keybindingId = keyboardHandler;\n            var _self = this;\n            config.loadModule([\"keybinding\", keyboardHandler], function(module) {\n                if (_self.$keybindingId == keyboardHandler)\n                    _self.keyBinding.setKeyboardHandler(module && module.handler);\n                cb && cb();\n            });\n        } else {\n            this.$keybindingId = null;\n            // @ts-ignore\n            this.keyBinding.setKeyboardHandler(keyboardHandler);\n            cb && cb();\n        }\n    }\n\n    /**\n     * Returns the keyboard handler, such as \"vim\" or \"windows\".\n     * @returns {Object}\n     **/\n    getKeyboardHandler() {\n        return this.keyBinding.getKeyboardHandler();\n    }\n\n\n\n    /**\n     * Sets a new editsession to use. This method also emits the `'changeSession'` event.\n     * @param {EditSession|null} [session] The new session to use\n     **/\n    setSession(session) {\n        if (this.session == session)\n            return;\n\n        // make sure operationEnd events are not emitted to wrong session\n        if (this.curOp) this.endOperation();\n        this.curOp = {};\n\n        var oldSession = this.session;\n        if (oldSession) {\n            this.session.off(\"change\", this.$onDocumentChange);\n            this.session.off(\"changeMode\", this.$onChangeMode);\n            this.session.off(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n            this.session.off(\"changeTabSize\", this.$onChangeTabSize);\n            this.session.off(\"changeWrapLimit\", this.$onChangeWrapLimit);\n            this.session.off(\"changeWrapMode\", this.$onChangeWrapMode);\n            this.session.off(\"changeFold\", this.$onChangeFold);\n            this.session.off(\"changeFrontMarker\", this.$onChangeFrontMarker);\n            this.session.off(\"changeBackMarker\", this.$onChangeBackMarker);\n            this.session.off(\"changeBreakpoint\", this.$onChangeBreakpoint);\n            this.session.off(\"changeAnnotation\", this.$onChangeAnnotation);\n            this.session.off(\"changeOverwrite\", this.$onCursorChange);\n            this.session.off(\"changeScrollTop\", this.$onScrollTopChange);\n            this.session.off(\"changeScrollLeft\", this.$onScrollLeftChange);\n            this.session.off(\"startOperation\", this.$onStartOperation);\n            this.session.off(\"endOperation\", this.$onEndOperation);\n\n            var selection = this.session.getSelection();\n            selection.off(\"changeCursor\", this.$onCursorChange);\n            selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n\n        this.session = session;\n        if (session) {\n            this.$onDocumentChange = this.onDocumentChange.bind(this);\n            session.on(\"change\", this.$onDocumentChange);\n            this.renderer.setSession(session);\n\n            this.$onChangeMode = this.onChangeMode.bind(this);\n            session.on(\"changeMode\", this.$onChangeMode);\n\n            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n            session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n\n            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n            session.on(\"changeTabSize\", this.$onChangeTabSize);\n\n            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n            session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n\n            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n            session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n\n            this.$onChangeFold = this.onChangeFold.bind(this);\n            session.on(\"changeFold\", this.$onChangeFold);\n\n            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n            this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n\n            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n            this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n\n            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n            this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n\n            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n            this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n\n            this.$onCursorChange = this.onCursorChange.bind(this);\n            this.session.on(\"changeOverwrite\", this.$onCursorChange);\n\n            this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n            this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n\n            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n            this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n\n            this.selection = session.getSelection();\n            this.selection.on(\"changeCursor\", this.$onCursorChange);\n\n            this.$onSelectionChange = this.onSelectionChange.bind(this);\n            this.selection.on(\"changeSelection\", this.$onSelectionChange);\n\n            this.$onStartOperation = this.onStartOperation.bind(this);\n            this.session.on(\"startOperation\", this.$onStartOperation);\n            this.$onEndOperation = this.onEndOperation.bind(this);\n            this.session.on(\"endOperation\", this.$onEndOperation);\n\n            this.onChangeMode();\n\n            this.onCursorChange();\n\n            this.onScrollTopChange();\n            this.onScrollLeftChange();\n            this.onSelectionChange();\n            this.onChangeFrontMarker();\n            this.onChangeBackMarker();\n            this.onChangeBreakpoint();\n            this.onChangeAnnotation();\n            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();\n            this.renderer.updateFull();\n        } else {\n            this.selection = null;\n            this.renderer.setSession(session);\n        }\n\n        this._signal(\"changeSession\", {\n            session: session,\n            oldSession: oldSession\n        });\n\n        this.curOp = null;\n\n        oldSession && oldSession._signal(\"changeEditor\", {oldEditor: this});\n        if (oldSession) oldSession.$editor = null;\n        session && session._signal(\"changeEditor\", {editor: this});\n        if (session) session.$editor = this;\n\n        if (session && !session.destroyed)\n            session.bgTokenizer.scheduleStart();\n    }\n\n    /**\n     * Returns the current session being used.\n     * @returns {EditSession}\n     **/\n    getSession() {\n        return this.session;\n    }\n\n    /**\n     * Sets the current document to `val`.\n     * @param {String} val The new value to set for the document\n     * @param {Number} [cursorPos] Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end\n     *\n     * @returns {String} The current document value\n     * @related Document.setValue\n     **/\n    setValue(val, cursorPos) {\n        this.session.doc.setValue(val);\n\n        if (!cursorPos)\n            this.selectAll();\n        else if (cursorPos == 1)\n            this.navigateFileEnd();\n        else if (cursorPos == -1)\n            this.navigateFileStart();\n\n        return val;\n    }\n\n    /**\n     * Returns the current session's content.\n     *\n     * @returns {String}\n     * @related EditSession.getValue\n     **/\n    getValue() {\n        return this.session.getValue();\n    }\n\n    /**\n     *\n     * Returns the currently highlighted selection.\n     * @returns {Selection} The selection object\n     **/\n    getSelection() {\n        return this.selection;\n    }\n\n    /**\n     * {:VirtualRenderer.onResize}\n     * @param {Boolean} [force] If `true`, recomputes the size, even if the height and width haven't changed\n     * @related VirtualRenderer.onResize\n     **/\n    resize(force) {\n        this.renderer.onResize(force);\n    }\n\n    /**\n     * {:VirtualRenderer.setTheme}\n     * @param {string | import(\"../ace-internal\").Ace.Theme} theme The path to a theme\n     * @param {() => void} [cb] optional callback called when theme is loaded\n     **/\n    setTheme(theme, cb) {\n        this.renderer.setTheme(theme, cb);\n    }\n\n    /**\n     * {:VirtualRenderer.getTheme}\n     *\n     * @returns {String} The set theme\n     * @related VirtualRenderer.getTheme\n     **/\n    getTheme() {\n        return this.renderer.getTheme();\n    }\n\n    /**\n     * {:VirtualRenderer.setStyle}\n     * @param {String} style A class name\n     * @param {boolean} [incluude] pass false to remove the class name\n     * @related VirtualRenderer.setStyle\n     **/\n    setStyle(style, incluude) {\n        this.renderer.setStyle(style, incluude);\n    }\n\n    /**\n     * {:VirtualRenderer.unsetStyle}\n     * @related VirtualRenderer.unsetStyle\n     * @param {string} style\n     */\n    unsetStyle(style) {\n        this.renderer.unsetStyle(style);\n    }\n\n    /**\n     * Gets the current font size of the editor text.\n     * @return {string | number}\n     */\n    getFontSize() {\n        return this.getOption(\"fontSize\") ||\n            dom.computedStyle(this.container).fontSize;\n    }\n\n    /**\n     * Set a new font size (in pixels) for the editor text.\n     * @param {String | number} size A font size ( _e.g._ \"12px\")\n     **/\n    setFontSize(size) {\n        this.setOption(\"fontSize\", size);\n    }\n\n    $highlightBrackets() {\n        if (this.$highlightPending) {\n            return;\n        }\n\n        // perform highlight async to not block the browser during navigation\n        var self = this;\n        this.$highlightPending = true;\n        setTimeout(function () {\n            self.$highlightPending = false;\n            var session = self.session;\n            if (!session || session.destroyed) return;\n            if (session.$bracketHighlight) {\n                session.$bracketHighlight.markerIds.forEach(function(id) {\n                    session.removeMarker(id);\n                });\n                session.$bracketHighlight = null;\n            }\n            var pos = self.getCursorPosition();\n            var handler = self.getKeyboardHandler();\n            var isBackwards = handler && handler.$getDirectionForHighlight && handler.$getDirectionForHighlight(self);\n            var ranges = session.getMatchingBracketRanges(pos, isBackwards);\n\n            if (!ranges) {\n                var iterator = new TokenIterator(session, pos.row, pos.column);\n                var token = iterator.getCurrentToken();\n\n                if (token && /\\b(?:tag-open|tag-name)/.test(token.type)) {\n                    var tagNamesRanges = session.getMatchingTags(pos);\n                    if (tagNamesRanges) {\n                        ranges = [\n                            tagNamesRanges.openTagName.isEmpty() ? tagNamesRanges.openTag : tagNamesRanges.openTagName,\n                            tagNamesRanges.closeTagName.isEmpty() ? tagNamesRanges.closeTag : tagNamesRanges.closeTagName\n                        ];\n                    }\n                }\n            }\n            if (!ranges && session.$mode.getMatching)\n                ranges = session.$mode.getMatching(self.session);\n            if (!ranges) {\n                if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n                return;\n            }\n\n            var markerType = \"ace_bracket\";\n            if (!Array.isArray(ranges)) {\n                ranges = [ranges];\n            } else if (ranges.length == 1) {\n                markerType = \"ace_error_bracket\";\n            }\n\n            // show adjacent ranges as one\n            if (ranges.length == 2) {\n                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)\n                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];\n                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)\n                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];\n            }\n\n            session.$bracketHighlight = {\n                ranges: ranges,\n                markerIds: ranges.map(function(range) {\n                    return session.addMarker(range, markerType, \"text\");\n                })\n            };\n            if (self.getHighlightIndentGuides()) self.renderer.$textLayer.$highlightIndentGuide();\n        }, 50);\n    }\n\n    /**\n     *\n     * Brings the current `textInput` into focus.\n     **/\n    focus() {\n        this.textInput.focus();\n    }\n\n    /**\n     * Returns `true` if the current `textInput` is in focus.\n     * @return {Boolean}\n     **/\n    isFocused() {\n        return this.textInput.isFocused();\n    }\n\n    /**\n     *\n     * Blurs the current `textInput`.\n     **/\n    blur() {\n        this.textInput.blur();\n    }\n\n    /**\n     * Emitted once the editor comes into focus.\n     * @internal\n     **/\n    onFocus(e) {\n        if (this.$isFocused)\n            return;\n        this.$isFocused = true;\n        this.renderer.showCursor();\n        this.renderer.visualizeFocus();\n        this._emit(\"focus\", e);\n    }\n\n    /**\n     * Emitted once the editor has been blurred.\n     * @internal\n     **/\n    onBlur(e) {\n        if (!this.$isFocused)\n            return;\n        this.$isFocused = false;\n        this.renderer.hideCursor();\n        this.renderer.visualizeBlur();\n        this._emit(\"blur\", e);\n    }\n\n    /**\n     */\n    $cursorChange() {\n        this.renderer.updateCursor();\n        this.$highlightBrackets();\n        this.$updateHighlightActiveLine();\n    }\n\n    /**\n     * Emitted whenever the document is changed.\n     * @param {import(\"../ace-internal\").Ace.Delta} delta Contains a single property, `data`, which has the delta of changes\n     * @internal\n     **/\n    onDocumentChange(delta) {\n        // Rerender and emit \"change\" event.\n        var wrap = this.session.$useWrapMode;\n        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);\n        this.renderer.updateLines(delta.start.row, lastRow, wrap);\n\n        this._signal(\"change\", delta);\n\n        // Update cursor because tab characters can influence the cursor position.\n        this.$cursorChange();\n    }\n\n    /**\n     * @internal\n     */\n    onTokenizerUpdate(e) {\n        var rows = e.data;\n        this.renderer.updateLines(rows.first, rows.last);\n    }\n\n    /**\n     * @internal\n     */\n    onScrollTopChange() {\n        this.renderer.scrollToY(this.session.getScrollTop());\n    }\n\n    /**\n     * @internal\n     */\n    onScrollLeftChange() {\n        this.renderer.scrollToX(this.session.getScrollLeft());\n    }\n\n    /**\n     * Emitted when the selection changes.\n     * @internal\n     **/\n    onCursorChange() {\n        this.$cursorChange();\n        this._signal(\"changeSelection\");\n    }\n\n    /**\n     */\n    $updateHighlightActiveLine() {\n        var session = this.getSession();\n        /**@type {Point|false}*/\n        var highlight;\n        if (this.$highlightActiveLine) {\n            if (this.$selectionStyle != \"line\" || !this.selection.isMultiLine())\n                highlight = this.getCursorPosition();\n            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())\n                highlight = false;\n            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))\n                highlight = false;\n        }\n\n        if (session.$highlightLineMarker && !highlight) {\n            session.removeMarker(session.$highlightLineMarker.id);\n            session.$highlightLineMarker = null;\n        } else if (!session.$highlightLineMarker && highlight) {\n            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);\n            range.id = session.addMarker(range, \"ace_active-line\", \"screenLine\");\n            session.$highlightLineMarker = range;\n        } else if (highlight) {\n            session.$highlightLineMarker.start.row = highlight.row;\n            session.$highlightLineMarker.end.row = highlight.row;\n            session.$highlightLineMarker.start.column = highlight.column;\n            session._signal(\"changeBackMarker\");\n        }\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onSelectionChange(e) {\n        var session = this.session;\n\n        if (session.$selectionMarker) {\n            session.removeMarker(session.$selectionMarker);\n        }\n        session.$selectionMarker = null;\n\n        if (!this.selection.isEmpty()) {\n            var range = this.selection.getRange();\n            var style = this.getSelectionStyle();\n            session.$selectionMarker = session.addMarker(range, \"ace_selection\", style);\n        } else {\n            this.$updateHighlightActiveLine();\n        }\n\n        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n        this.session.highlight(re);\n\n        this._signal(\"changeSelection\");\n    }\n\n    $getSelectionHighLightRegexp() {\n        var session = this.session;\n\n        var selection = this.getSelectionRange();\n        if (selection.isEmpty() || selection.isMultiLine())\n            return;\n\n        var startColumn = selection.start.column;\n        var endColumn = selection.end.column;\n        var line = session.getLine(selection.start.row);\n\n        var needle = line.substring(startColumn, endColumn);\n        // maximum allowed size for regular expressions in 32000,\n        // but getting close to it has significant impact on the performance\n        if (needle.length > 5000 || !/[\\w\\d]/.test(needle))\n            return;\n\n        var re = this.$search.$assembleRegExp({\n            wholeWord: true,\n            caseSensitive: true,\n            needle: needle\n        });\n\n        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);\n        if (!re.test(wordWithBoundary))\n            return;\n\n        return re;\n    }\n\n    /**\n     * @internal\n     */\n    onChangeFrontMarker() {\n        this.renderer.updateFrontMarkers();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeBackMarker() {\n        this.renderer.updateBackMarkers();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeBreakpoint() {\n        this.renderer.updateBreakpoints();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeAnnotation() {\n        this.renderer.setAnnotations(this.session.getAnnotations());\n    }\n\n    /**\n     * @param e\n     * @internal\n     */\n    onChangeMode (e) {\n        this.renderer.updateText();\n        this._emit(\"changeMode\", e);\n    }\n\n    /**\n     * @internal\n     */\n    onChangeWrapLimit() {\n        this.renderer.updateFull();\n    }\n\n    /**\n     * @internal\n     */\n    onChangeWrapMode() {\n        this.renderer.onResize(true);\n    }\n\n\n    /**\n     * @internal\n     */\n    onChangeFold() {\n        // Update the active line marker as due to folding changes the current\n        // line range on the screen might have changed.\n        this.$updateHighlightActiveLine();\n        // TODO: This might be too much updating. Okay for now.\n        this.renderer.updateFull();\n    }\n\n\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getSelectedText() {\n        return this.session.getTextRange(this.getSelectionRange());\n    }\n\n\n    /**\n     * Returns the string of text currently highlighted.\n     * @returns {String}\n     **/\n    getCopyText () {\n        var text = this.getSelectedText();\n        var nl = this.session.doc.getNewLineCharacter();\n        var copyLine= false;\n        if (!text && this.$copyWithEmptySelection) {\n            copyLine = true;\n            var ranges = this.selection.getAllRanges();\n            for (var i = 0; i < ranges.length; i++) {\n                var range = ranges[i];\n                if (i && ranges[i - 1].start.row == range.start.row)\n                    continue;\n                text += this.session.getLine(range.start.row) + nl;\n            }\n        }\n        var e = {text: text};\n        this._signal(\"copy\", e);\n        clipboard.lineMode = copyLine ? e.text : false;\n        return e.text;\n    }\n\n    /**\n     * Called whenever a text \"copy\" happens.\n     * @internal\n     **/\n    onCopy() {\n        this.commands.exec(\"copy\", this);\n    }\n\n    /**\n     * Called whenever a text \"cut\" happens.\n     * @internal\n     **/\n    onCut() {\n        this.commands.exec(\"cut\", this);\n    }\n\n\n    /**\n     * Called whenever a text \"paste\" happens.\n     * @param {String} text The pasted text\n     * @param {ClipboardEvent} [event]\n     * @internal\n     **/\n    onPaste(text, event) {\n        var e = {text: text, event: event};\n        this.commands.exec(\"paste\", this, e);\n    }\n\n    /**\n     *\n     * @param {string | {text: string, event?: ClipboardEvent}} e\n     * @returns {boolean}\n     */\n    $handlePaste(e) {\n        if (typeof e == \"string\")\n            e = {text: e};\n        this._signal(\"paste\", e);\n        var text = e.text;\n\n        var lineMode = text === clipboard.lineMode;\n        var session = this.session;\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n            if (lineMode)\n                session.insert({ row: this.selection.lead.row, column: 0 }, text);\n            else\n                this.insert(text);\n        } else if (lineMode) {\n            this.selection.rangeList.ranges.forEach(function(range) {\n                session.insert({ row: range.start.row, column: 0 }, text);\n            });\n        } else {\n            var lines = text.split(/\\r\\n|\\r|\\n/);\n            var ranges = this.selection.rangeList.ranges;\n\n            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);\n            if (lines.length != ranges.length || isFullLine)\n                return this.commands.exec(\"insertstring\", this, text);\n\n            for (var i = ranges.length; i--;) {\n                var range = ranges[i];\n                if (!range.isEmpty())\n                    session.remove(range);\n\n                session.insert(range.start, lines[i]);\n            }\n        }\n    }\n\n    /**\n     *\n     * @param {string | string[] | import(\"../ace-internal\").Ace.Command} command\n     * @param [args]\n     * @return {boolean}\n     */\n    execCommand(command, args) {\n        return this.commands.exec(command, this, args);\n    }\n\n    /**\n     * Inserts `text` into wherever the cursor is pointing.\n     * @param {String} text The new text to add\n     * @param {boolean} [pasted]\n     **/\n    insert(text, pasted) {\n        var session = this.session;\n        var mode = session.getMode();\n        var cursor = this.getCursorPosition();\n\n        if (this.getBehavioursEnabled() && !pasted) {\n            // Get a transform if the current mode wants one.\n            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);\n            if (transform) {\n                if (text !== transform.text) {\n                    // keep automatic insertion in a separate delta, unless it is in multiselect mode\n                    if (!this.inVirtualSelectionMode) {\n                        this.session.mergeUndoDeltas = false;\n                        this.mergeNextCommand = false;\n                    }\n                }\n                text = transform.text;\n\n            }\n        }\n\n        if (text == \"\\t\")\n            text = this.session.getTabString();\n\n        // remove selected text\n        if (!this.selection.isEmpty()) {\n            var range = this.getSelectionRange();\n            cursor = this.session.remove(range);\n            this.clearSelection();\n        }\n        else if (this.session.getOverwrite() && text.indexOf(\"\\n\") == -1) {\n            var range = Range.fromPoints(cursor, cursor);\n            range.end.column += text.length;\n            this.session.remove(range);\n        }\n\n        if (text == \"\\n\" || text == \"\\r\\n\") {\n            var line = session.getLine(cursor.row);\n            if (cursor.column > line.search(/\\S|$/)) {\n                var d = line.substr(cursor.column).search(/\\S|$/);\n                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);\n            }\n        }\n        this.clearSelection();\n\n        var start = cursor.column;\n        var lineState = session.getState(cursor.row);\n        var line = session.getLine(cursor.row);\n        var shouldOutdent = mode.checkOutdent(lineState, line, text);\n        session.insert(cursor, text);\n\n        if (transform && transform.selection) {\n            if (transform.selection.length == 2) { // Transform relative to the current column\n                this.selection.setSelectionRange(\n                    new Range(cursor.row, start + transform.selection[0],\n                        cursor.row, start + transform.selection[1]));\n            } else { // Transform relative to the current row.\n                this.selection.setSelectionRange(\n                    new Range(cursor.row + transform.selection[0],\n                        transform.selection[1],\n                        cursor.row + transform.selection[2],\n                        transform.selection[3]));\n            }\n        }\n        if (this.$enableAutoIndent) {\n            if (session.getDocument().isNewLine(text)) {\n                var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n\n                session.insert({row: cursor.row+1, column: 0}, lineIndent);\n            }\n            if (shouldOutdent)\n                mode.autoOutdent(lineState, session, cursor.row);\n        }\n    }\n\n    autoIndent() {\n        var session = this.session;\n        var mode = session.getMode();\n\n        var ranges = this.selection.isEmpty()\n            ? [new Range(0, 0, session.doc.getLength() - 1, 0)]\n            : this.selection.getAllRanges();\n\n        /**@type{string|string[]}*/\n        var prevLineState = \"\";\n        var prevLine = \"\";\n        var lineIndent = \"\";\n        var tab = session.getTabString();\n        for (var i = 0; i < ranges.length; i++) {\n            var startRow = ranges[i].start.row;\n            var endRow = ranges[i].end.row;\n\n            for (var row = startRow; row <= endRow; row++) {\n                if (row > 0) {\n                    prevLineState = session.getState(row - 1);\n                    prevLine = session.getLine(row - 1);\n                    lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab);\n                }\n\n                var line = session.getLine(row);\n                var currIndent = mode.$getIndent(line);\n                if (lineIndent !== currIndent) {\n                    if (currIndent.length > 0) {\n                        var range = new Range(row, 0, row, currIndent.length);\n                        session.remove(range);\n                    }\n                    if (lineIndent.length > 0) {\n                        session.insert({row: row, column: 0}, lineIndent);\n                    }\n                }\n\n                mode.autoOutdent(prevLineState, session, row);\n            }\n        }\n    }\n\n    /**\n     *\n     * @param text\n     * @param composition\n     * @returns {*}\n     * @internal\n     */\n    onTextInput(text, composition) {\n        if (!composition)\n            return this.keyBinding.onTextInput(text);\n\n        this.startOperation({command: { name: \"insertstring\" }});\n        var applyComposition = this.applyComposition.bind(this, text, composition);\n        if (this.selection.rangeCount)\n            this.forEachSelection(applyComposition);\n        else\n            applyComposition();\n        this.endOperation();\n    }\n\n    /**\n     * @param {string} [text]\n     * @param {any} [composition]\n     */\n    applyComposition(text, composition) {\n        if (composition.extendLeft || composition.extendRight) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.extendLeft;\n            r.end.column += composition.extendRight;\n            if (r.start.column < 0) {\n                r.start.row--;\n                r.start.column += this.session.getLine(r.start.row).length + 1;\n            }\n            this.selection.setRange(r);\n            if (!text && !r.isEmpty())\n                this.remove();\n        }\n        if (text || !this.selection.isEmpty())\n            this.insert(text, true);\n        if (composition.restoreStart || composition.restoreEnd) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.restoreStart;\n            r.end.column -= composition.restoreEnd;\n            this.selection.setRange(r);\n        }\n    }\n\n    /**\n     * @internal\n     */\n    onCommandKey(e, hashId, keyCode) {\n        return this.keyBinding.onCommandKey(e, hashId, keyCode);\n    }\n\n    /**\n     * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n     * @param {Boolean} overwrite Defines whether or not to set overwrites\n     * @related EditSession.setOverwrite\n     **/\n    setOverwrite(overwrite) {\n        this.session.setOverwrite(overwrite);\n    }\n\n    /**\n     * Returns `true` if overwrites are enabled; `false` otherwise.\n     * @returns {Boolean}\n     * @related EditSession.getOverwrite\n     **/\n    getOverwrite() {\n        return this.session.getOverwrite();\n    }\n\n    /**\n     * Sets the value of overwrite to the opposite of whatever it currently is.\n     * @related EditSession.toggleOverwrite\n     **/\n    toggleOverwrite() {\n        this.session.toggleOverwrite();\n    }\n\n    /**\n     * Sets how fast the mouse scrolling should do.\n     * @param {Number} speed A value indicating the new speed (in milliseconds)\n     **/\n    setScrollSpeed(speed) {\n        this.setOption(\"scrollSpeed\", speed);\n    }\n\n    /**\n     * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).\n     * @returns {Number}\n     **/\n    getScrollSpeed() {\n        return this.getOption(\"scrollSpeed\");\n    }\n\n    /**\n     * Sets the delay (in milliseconds) of the mouse drag.\n     * @param {Number} dragDelay A value indicating the new delay\n     **/\n    setDragDelay(dragDelay) {\n        this.setOption(\"dragDelay\", dragDelay);\n    }\n\n    /**\n     * Returns the current mouse drag delay.\n     * @returns {Number}\n     **/\n    getDragDelay() {\n        return this.getOption(\"dragDelay\");\n    }\n\n\n    /**\n     * Draw selection markers spanning whole line, or only over selected text. Default value is \"line\"\n     * @param {\"fullLine\" | \"screenLine\" | \"text\" | \"line\"} val The new selection style \"line\"|\"text\"\n     **/\n    setSelectionStyle(val) {\n        this.setOption(\"selectionStyle\", val);\n    }\n\n    /**\n     * Returns the current selection style.\n     * @returns {import(\"../ace-internal\").Ace.EditorOptions[\"selectionStyle\"]}\n     **/\n    getSelectionStyle() {\n        return this.getOption(\"selectionStyle\");\n    }\n\n    /**\n     * Determines whether or not the current line should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the current line\n     **/\n    setHighlightActiveLine(shouldHighlight) {\n        this.setOption(\"highlightActiveLine\", shouldHighlight);\n    }\n    /**\n     * Returns `true` if current lines are always highlighted.\n     * @return {Boolean}\n     **/\n    getHighlightActiveLine() {\n        return this.getOption(\"highlightActiveLine\");\n    }\n\n    /**\n     * @param {boolean} shouldHighlight\n     */\n    setHighlightGutterLine(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    }\n\n    /**\n     * @returns {Boolean}\n     */\n    getHighlightGutterLine() {\n        return this.getOption(\"highlightGutterLine\");\n    }\n\n    /**\n     * Determines if the currently selected word should be highlighted.\n     * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word\n     **/\n    setHighlightSelectedWord(shouldHighlight) {\n        this.setOption(\"highlightSelectedWord\", shouldHighlight);\n    }\n\n    /**\n     * Returns `true` if currently highlighted words are to be highlighted.\n     * @returns {Boolean}\n     **/\n    getHighlightSelectedWord() {\n        return this.$highlightSelectedWord;\n    }\n\n    /**\n     * @param {boolean} shouldAnimate\n     */\n    setAnimatedScroll(shouldAnimate){\n        this.renderer.setAnimatedScroll(shouldAnimate);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getAnimatedScroll(){\n        return this.renderer.getAnimatedScroll();\n    }\n\n    /**\n     * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.\n     * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters\n     **/\n    setShowInvisibles(showInvisibles) {\n        this.renderer.setShowInvisibles(showInvisibles);\n    }\n\n    /**\n     * Returns `true` if invisible characters are being shown.\n     * @returns {Boolean}\n     **/\n    getShowInvisibles() {\n        return this.renderer.getShowInvisibles();\n    }\n\n    /**\n     * @param {boolean} display\n     */\n    setDisplayIndentGuides(display) {\n        this.renderer.setDisplayIndentGuides(display);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getDisplayIndentGuides() {\n        return this.renderer.getDisplayIndentGuides();\n    }\n\n    /**\n     * @param {boolean} highlight\n     */\n    setHighlightIndentGuides(highlight) {\n        this.renderer.setHighlightIndentGuides(highlight);\n    }\n\n    /**\n     * @return {boolean}\n     */\n    getHighlightIndentGuides() {\n        return this.renderer.getHighlightIndentGuides();\n    }\n\n    /**\n     * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.\n     * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin\n     *\n     **/\n    setShowPrintMargin(showPrintMargin) {\n        this.renderer.setShowPrintMargin(showPrintMargin);\n    }\n\n    /**\n     * Returns `true` if the print margin is being shown.\n     * @returns {Boolean}\n     **/\n    getShowPrintMargin() {\n        return this.renderer.getShowPrintMargin();\n    }\n\n    /**\n     * Sets the column defining where the print margin should be.\n     * @param {Number} showPrintMargin Specifies the new print margin\n     *\n     **/\n    setPrintMarginColumn(showPrintMargin) {\n        this.renderer.setPrintMarginColumn(showPrintMargin);\n    }\n\n    /**\n     * Returns the column number of where the print margin is.\n     * @returns {Number}\n     **/\n    getPrintMarginColumn() {\n        return this.renderer.getPrintMarginColumn();\n    }\n\n    /**\n     * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.\n     * @param {Boolean} readOnly Specifies whether the editor can be modified or not\n     **/\n    setReadOnly(readOnly) {\n        this.setOption(\"readOnly\", readOnly);\n    }\n\n    /**\n     * Returns `true` if the editor is set to read-only mode.\n     * @returns {Boolean}\n     **/\n    getReadOnly() {\n        return this.getOption(\"readOnly\");\n    }\n\n    /**\n     * Specifies whether to use behaviors or not. [\"Behaviors\" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}\n     * @param {Boolean} enabled Enables or disables behaviors\n     **/\n    setBehavioursEnabled(enabled) {\n        this.setOption(\"behavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}\n     * @returns {Boolean}\n     **/\n    getBehavioursEnabled() {\n        return this.getOption(\"behavioursEnabled\");\n    }\n\n    /**\n     * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets\n     * when such a character is typed in.\n     * @param {Boolean} enabled Enables or disables wrapping behaviors\n     **/\n    setWrapBehavioursEnabled(enabled) {\n        this.setOption(\"wrapBehavioursEnabled\", enabled);\n    }\n\n    /**\n     * Returns `true` if the wrapping behaviors are currently enabled.\n     * @returns {boolean}\n     **/\n    getWrapBehavioursEnabled() {\n        return this.getOption(\"wrapBehavioursEnabled\");\n    }\n\n    /**\n     * Indicates whether the fold widgets should be shown or not.\n     * @param {Boolean} show Specifies whether the fold widgets are shown\n     **/\n    setShowFoldWidgets(show) {\n        this.setOption(\"showFoldWidgets\", show);\n\n    }\n    /**\n     * Returns `true` if the fold widgets are shown.\n     * @return {Boolean}\n     **/\n    getShowFoldWidgets() {\n        return this.getOption(\"showFoldWidgets\");\n    }\n\n    /**\n     * @param {boolean} fade\n     */\n    setFadeFoldWidgets(fade) {\n        this.setOption(\"fadeFoldWidgets\", fade);\n    }\n\n    /**\n     * @returns {boolean}\n     */\n    getFadeFoldWidgets() {\n        return this.getOption(\"fadeFoldWidgets\");\n    }\n\n    /**\n     * Removes the current selection or one character.\n     * @param {'left' | 'right'} [dir] The direction of the deletion to occur, either \"left\" or \"right\"\n     **/\n    remove(dir) {\n        if (this.selection.isEmpty()){\n            if (dir == \"left\")\n                this.selection.selectLeft();\n            else\n                this.selection.selectRight();\n        }\n\n        var range = this.getSelectionRange();\n        if (this.getBehavioursEnabled()) {\n            var session = this.session;\n            var state = session.getState(range.start.row);\n            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);\n\n            if (range.end.column === 0) {\n                var text = session.getTextRange(range);\n                if (text[text.length - 1] == \"\\n\") {\n                    var line = session.getLine(range.end.row);\n                    if (/^\\s+$/.test(line)) {\n                        range.end.column = line.length;\n                    }\n                }\n            }\n            if (new_range)\n                // @ts-expect-error TODO: possible bug, new_range could be not a Range\n                range = new_range;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the right of the current selection.\n     **/\n    removeWordRight() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordRight();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes the word directly to the left of the current selection.\n     **/\n    removeWordLeft() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordLeft();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the left of the current selection, until the start of the line.\n     **/\n    removeToLineStart() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineStart();\n        if (this.selection.isEmpty())\n            this.selection.selectLeft();\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    }\n\n    /**\n     * Removes all the words to the right of the current selection, until the end of the line.\n     **/\n    removeToLineEnd() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineEnd();\n\n        var range = this.getSelectionRange();\n        if (range.start.column == range.end.column && range.start.row == range.end.row) {\n            range.end.column = 0;\n            range.end.row++;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    }\n\n    /**\n     * Splits the line at the current selection (by inserting an `'\\n'`).\n     **/\n    splitLine() {\n        if (!this.selection.isEmpty()) {\n            this.session.remove(this.getSelectionRange());\n            this.clearSelection();\n        }\n\n        var cursor = this.getCursorPosition();\n        this.insert(\"\\n\");\n        this.moveCursorToPosition(cursor);\n    }\n\n    /**\n     * Set the \"ghost\" text in provided position. \"Ghost\" text is a kind of\n     * preview text inside the editor which can be used to preview some code\n     * inline in the editor such as, for example, code completions.\n     *\n     * @param {String} text Text to be inserted as \"ghost\" text\n     * @param {Point} [position] Position to insert text to\n     */\n    setGhostText(text, position) {\n        this.renderer.setGhostText(text, position);\n    }\n\n    /**\n     * Removes \"ghost\" text currently displayed in the editor.\n     */\n    removeGhostText() {\n        this.renderer.removeGhostText();\n    }\n\n    /**\n     * Transposes current line.\n     **/\n    transposeLetters() {\n        if (!this.selection.isEmpty()) {\n            return;\n        }\n\n        var cursor = this.getCursorPosition();\n        var column = cursor.column;\n        if (column === 0)\n            return;\n\n        var line = this.session.getLine(cursor.row);\n        var swap, range;\n        if (column < line.length) {\n            swap = line.charAt(column) + line.charAt(column-1);\n            range = new Range(cursor.row, column-1, cursor.row, column+1);\n        }\n        else {\n            swap = line.charAt(column-1) + line.charAt(column-2);\n            range = new Range(cursor.row, column-2, cursor.row, column);\n        }\n        this.session.replace(range, swap);\n        this.session.selection.moveToPosition(range.end);\n    }\n\n    /**\n     * Converts the current selection entirely into lowercase.\n     **/\n    toLowerCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toLowerCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Converts the current selection entirely into uppercase.\n     **/\n    toUpperCase() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toUpperCase());\n        this.selection.setSelectionRange(originalRange);\n    }\n\n    /**\n     * Inserts an indentation into the current cursor position or indents the selected lines.\n     *\n     * @related EditSession.indentRows\n     **/\n    indent() {\n        var session = this.session;\n        var range = this.getSelectionRange();\n\n        if (range.start.row < range.end.row) {\n            var rows = this.$getSelectedRows();\n            session.indentRows(rows.first, rows.last, \"\\t\");\n            return;\n        } else if (range.start.column < range.end.column) {\n            var text = session.getTextRange(range);\n            if (!/^\\s+$/.test(text)) {\n                var rows = this.$getSelectedRows();\n                session.indentRows(rows.first, rows.last, \"\\t\");\n                return;\n            }\n        }\n\n        var line = session.getLine(range.start.row);\n        var position = range.start;\n        var size = session.getTabSize();\n        var column = session.documentToScreenColumn(position.row, position.column);\n\n        if (this.session.getUseSoftTabs()) {\n            var count = (size - column % size);\n            var indentString = lang.stringRepeat(\" \", count);\n        } else {\n            var count = column % size;\n            while (line[range.start.column - 1] == \" \" && count) {\n                range.start.column--;\n                count--;\n            }\n            this.selection.setSelectionRange(range);\n            indentString = \"\\t\";\n        }\n        return this.insert(indentString);\n    }\n\n    /**\n     * Indents the current line.\n     * @related EditSession.indentRows\n     **/\n    blockIndent() {\n        var rows = this.$getSelectedRows();\n        this.session.indentRows(rows.first, rows.last, \"\\t\");\n    }\n\n    /**\n     * Outdents the current line.\n     * @related EditSession.outdentRows\n     **/\n    blockOutdent() {\n        var selection = this.session.getSelection();\n        this.session.outdentRows(selection.getRange());\n    }\n\n    // TODO: move out of core when we have good mechanism for managing extensions\n    sortLines() {\n        var rows = this.$getSelectedRows();\n        var session = this.session;\n\n        var lines = [];\n        for (var i = rows.first; i <= rows.last; i++)\n            lines.push(session.getLine(i));\n\n        lines.sort(function(a, b) {\n            if (a.toLowerCase() < b.toLowerCase()) return -1;\n            if (a.toLowerCase() > b.toLowerCase()) return 1;\n            return 0;\n        });\n\n        var deleteRange = new Range(0, 0, 0, 0);\n        for (var i = rows.first; i <= rows.last; i++) {\n            var line = session.getLine(i);\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            deleteRange.end.column = line.length;\n            session.replace(deleteRange, lines[i-rows.first]);\n        }\n    }\n\n    /**\n     * Given the currently selected range, this function either comments all the lines, or uncomments all of them.\n     **/\n    toggleCommentLines() {\n        var state = this.session.getState(this.getCursorPosition().row);\n        var rows = this.$getSelectedRows();\n        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);\n    }\n\n    toggleBlockComment() {\n        var cursor = this.getCursorPosition();\n        var state = this.session.getState(cursor.row);\n        var range = this.getSelectionRange();\n        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);\n    }\n\n    /**\n     * Works like [[EditSession.getTokenAt]], except it returns a number.\n     * @returns {any}\n     **/\n    getNumberAt(row, column) {\n        var _numberRx = /[\\-]?[0-9]+(?:\\.[0-9]+)?/g;\n        _numberRx.lastIndex = 0;\n\n        var s = this.session.getLine(row);\n        while (_numberRx.lastIndex < column) {\n            var m = _numberRx.exec(s);\n            if(m.index <= column && m.index+m[0].length >= column){\n                var number = {\n                    value: m[0],\n                    start: m.index,\n                    end: m.index+m[0].length\n                };\n                return number;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * If the character before the cursor is a number, this functions changes its value by `amount`.\n     * @param {Number} amount The value to change the numeral by (can be negative to decrease value)\n     **/\n    modifyNumber(amount) {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n\n        // get the char before the cursor\n        var charRange = new Range(row, column-1, row, column);\n\n        var c = this.session.getTextRange(charRange);\n        // if the char is a digit\n        // @ts-ignore\n        if (!isNaN(parseFloat(c)) && isFinite(c)) {\n            // get the whole number the digit is part of\n            var nr = this.getNumberAt(row, column);\n            // if number found\n            if (nr) {\n                var fp = nr.value.indexOf(\".\") >= 0 ? nr.start + nr.value.indexOf(\".\") + 1 : nr.end;\n                var decimals = nr.start + nr.value.length - fp;\n\n                var t = parseFloat(nr.value);\n                t *= Math.pow(10, decimals);\n\n\n                if(fp !== nr.end && column < fp){\n                    amount *= Math.pow(10, nr.end - column - 1);\n                } else {\n                    amount *= Math.pow(10, nr.end - column);\n                }\n\n                t += amount;\n                t /= Math.pow(10, decimals);\n                var nnr = t.toFixed(decimals);\n\n                //update number\n                var replaceRange = new Range(row, nr.start, row, nr.end);\n                this.session.replace(replaceRange, nnr);\n\n                //reposition the cursor\n                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));\n\n            }\n        } else {\n            this.toggleWord();\n        }\n    }\n\n    /**\n     */\n    toggleWord() {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        this.selection.selectWord();\n        var currentState = this.getSelectedText();\n        var currWordStart = this.selection.getWordRange().start.column;\n        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\\s/);\n        var delta = column - currWordStart - 1;\n        if (delta < 0) delta = 0;\n        var curLength = 0, itLength = 0;\n        var that = this;\n        if (currentState.match(/[A-Za-z0-9_]+/)) {\n            wordParts.forEach(function (item, i) {\n                itLength = curLength + item.length;\n                if (delta >= curLength && delta <= itLength) {\n                    currentState = item;\n                    that.selection.clearSelection();\n                    that.moveCursorTo(row, curLength + currWordStart);\n                    that.selection.selectTo(row, itLength + currWordStart);\n                }\n                curLength = itLength;\n            });\n        }\n\n        var wordPairs = this.$toggleWordPairs;\n        var reg;\n        for (var i = 0; i < wordPairs.length; i++) {\n            var item = wordPairs[i];\n            for (var j = 0; j <= 1; j++) {\n                var negate = +!j;\n                var firstCondition = currentState.match(new RegExp('^\\\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\\\s?$', 'i'));\n                if (firstCondition) {\n                    var secondCondition = currentState.match(new RegExp('([_]|^|\\\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\\\s)', 'g'));\n                    if (secondCondition) {\n                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {\n                            var res = item[negate];\n                            if (result.toUpperCase() == result) {\n                                res = res.toUpperCase();\n                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {\n                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);\n                            }\n                            return res;\n                        });\n                        this.insert(reg);\n                        reg = \"\";\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Finds link at defined {row} and {column}\n     * @returns {String}\n     **/\n    findLinkAt(row, column) {\n        var line = this.session.getLine(row);\n        var wordParts = line.split(/((?:https?|ftp):\\/\\/[\\S]+)/);\n        var columnPosition = column;\n        if (columnPosition < 0) columnPosition = 0;\n        var previousPosition = 0, currentPosition = 0, match;\n        for (let item of wordParts) {\n            currentPosition = previousPosition + item.length;\n            if (columnPosition >= previousPosition && columnPosition <= currentPosition) {\n                if (item.match(/((?:https?|ftp):\\/\\/[\\S]+)/)) {\n                    match = item.replace(/[\\s:.,'\";}\\]]+$/, \"\");\n                    break;\n                }\n            }\n            previousPosition = currentPosition;\n        }\n        return match;\n    }\n\n    /**\n     * Open valid url under cursor in another tab\n     * @returns {Boolean}\n     **/\n    openLink() {\n        var cursor =  this.selection.getCursor();\n        var url = this.findLinkAt(cursor.row, cursor.column);\n        if (url)\n            window.open(url, '_blank');\n        return url != null;\n    }\n\n    /**\n     * Removes all the lines in the current selection\n     * @related EditSession.remove\n     **/\n    removeLines() {\n        var rows = this.$getSelectedRows();\n        this.session.removeFullLines(rows.first, rows.last);\n        this.clearSelection();\n    }\n\n    duplicateSelection() {\n        var sel = this.selection;\n        var doc = this.session;\n        var range = sel.getRange();\n        var reverse = sel.isBackwards();\n        if (range.isEmpty()) {\n            var row = range.start.row;\n            doc.duplicateLines(row, row);\n        } else {\n            var point = reverse ? range.start : range.end;\n            var endPoint = doc.insert(point, doc.getTextRange(range));\n            range.start = point;\n            range.end = endPoint;\n\n            sel.setSelectionRange(range, reverse);\n        }\n    }\n\n    /**\n     * Shifts all the selected lines down one row.\n     *\n     * @related EditSession.moveLinesUp\n     **/\n    moveLinesDown() {\n        this.$moveLines(1, false);\n    }\n\n    /**\n     * Shifts all the selected lines up one row.\n     * @related EditSession.moveLinesDown\n     **/\n    moveLinesUp() {\n        this.$moveLines(-1, false);\n    }\n\n    /**\n     * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n     * ```json\n     *    { row: newRowLocation, column: newColumnLocation }\n     * ```\n     * @param {Range} range The range of text you want moved within the document\n     * @param {Point} toPosition The location (row and column) where you want to move the text to\n     * @param {boolean} [copy]\n     *\n     * @returns {Range} The new range where the text was moved to.\n     * @related EditSession.moveText\n     **/\n    moveText(range, toPosition, copy) {\n        return this.session.moveText(range, toPosition, copy);\n    }\n\n    /**\n     * Copies all the selected lines up one row.\n     *\n     **/\n    copyLinesUp() {\n        this.$moveLines(-1, true);\n    }\n\n    /**\n     * Copies all the selected lines down one row.\n     * @related EditSession.duplicateLines\n     *\n     **/\n    copyLinesDown() {\n        this.$moveLines(1, true);\n    }\n\n    /**\n     * for internal use\n     * @ignore\n     *\n     **/\n    $moveLines(dir, copy) {\n        var rows, moved;\n        var selection = this.selection;\n        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {\n            var range = selection.toOrientedRange();\n            rows = this.$getSelectedRows(range);\n            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);\n            if (copy && dir == -1) moved = 0;\n            range.moveBy(moved, 0);\n            selection.fromOrientedRange(range);\n        } else {\n            var ranges = selection.rangeList.ranges;\n            // @ts-expect-error TODO: possible bug, no args in parameters\n            selection.rangeList.detach(this.session);\n            this.inVirtualSelectionMode = true;\n\n            var diff = 0;\n            var totalDiff = 0;\n            var l = ranges.length;\n            for (var i = 0; i < l; i++) {\n                var rangeIndex = i;\n                ranges[i].moveBy(diff, 0);\n                rows = this.$getSelectedRows(ranges[i]);\n                var first = rows.first;\n                var last = rows.last;\n                while (++i < l) {\n                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);\n                    var subRows = this.$getSelectedRows(ranges[i]);\n                    if (copy && subRows.first != last)\n                        break;\n                    else if (!copy && subRows.first > last + 1)\n                        break;\n                    last = subRows.last;\n                }\n                i--;\n                diff = this.session.$moveLines(first, last, copy ? 0 : dir);\n                if (copy && dir == -1) rangeIndex = i + 1;\n                while (rangeIndex <= i) {\n                    ranges[rangeIndex].moveBy(diff, 0);\n                    rangeIndex++;\n                }\n                if (!copy) diff = 0;\n                totalDiff += diff;\n            }\n\n            selection.fromOrientedRange(selection.ranges[0]);\n            selection.rangeList.attach(this.session);\n            this.inVirtualSelectionMode = false;\n        }\n    }\n\n    /**\n     * Returns an object indicating the currently selected rows. The object looks like this:\n     *\n     * ```json\n     * { first: range.start.row, last: range.end.row }\n     * ```\n     *\n     * @returns {Object}\n     **/\n    $getSelectedRows(range) {\n        range = (range || this.getSelectionRange()).collapseRows();\n\n        return {\n            first: this.session.getRowFoldStart(range.start.row),\n            last: this.session.getRowFoldEnd(range.end.row)\n        };\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionStart(compositionState) {\n        this.renderer.showComposition(compositionState);\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionUpdate(text) {\n        this.renderer.setCompositionText(text);\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionEnd() {\n        this.renderer.hideComposition();\n    }\n\n    /**\n     * {:VirtualRenderer.getFirstVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getFirstVisibleRow\n     **/\n    getFirstVisibleRow() {\n        return this.renderer.getFirstVisibleRow();\n    }\n\n    /**\n     * {:VirtualRenderer.getLastVisibleRow}\n     *\n     * @returns {Number}\n     * @related VirtualRenderer.getLastVisibleRow\n     **/\n    getLastVisibleRow() {\n        return this.renderer.getLastVisibleRow();\n    }\n\n    /**\n     * Indicates if the row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     * @returns {Boolean}\n     **/\n    isRowVisible(row) {\n        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());\n    }\n\n    /**\n     * Indicates if the entire row is currently visible on the screen.\n     * @param {Number} row The row to check\n     *\n     *\n     * @returns {Boolean}\n     **/\n    isRowFullyVisible(row) {\n        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());\n    }\n\n    /**\n     * Returns the number of currently visible rows.\n     * @returns {Number}\n     **/\n    $getVisibleRowCount() {\n        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;\n    }\n\n    $moveByPage(dir, select) {\n        var renderer = this.renderer;\n        var config = this.renderer.layerConfig;\n        var rows = dir * Math.floor(config.height / config.lineHeight);\n\n        if (select === true) {\n            this.selection.$moveSelection(function(){\n                this.moveCursorBy(rows, 0);\n            });\n        } else if (select === false) {\n            this.selection.moveCursorBy(rows, 0);\n            this.selection.clearSelection();\n        }\n\n        var scrollTop = renderer.scrollTop;\n\n        renderer.scrollBy(0, rows * config.lineHeight);\n        if (select != null)\n            renderer.scrollCursorIntoView(null, 0.5);\n\n        renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page down\" finishes.\n     **/\n    selectPageDown() {\n        this.$moveByPage(1, true);\n    }\n\n    /**\n     * Selects the text from the current position of the document until where a \"page up\" finishes.\n     **/\n    selectPageUp() {\n        this.$moveByPage(-1, true);\n    }\n\n    /**\n     * Shifts the document to wherever \"page down\" is, as well as moving the cursor position.\n     **/\n    gotoPageDown() {\n        this.$moveByPage(1, false);\n    }\n\n    /**\n     * Shifts the document to wherever \"page up\" is, as well as moving the cursor position.\n     **/\n    gotoPageUp() {\n        this.$moveByPage(-1, false);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page down\" is, without changing the cursor position.\n     **/\n    scrollPageDown() {\n        this.$moveByPage(1);\n    }\n\n    /**\n     * Scrolls the document to wherever \"page up\" is, without changing the cursor position.\n     **/\n    scrollPageUp() {\n        this.$moveByPage(-1);\n    }\n\n    /**\n     * Moves the editor to the specified row.\n     * @related VirtualRenderer.scrollToRow\n     * @param {number} row\n     */\n    scrollToRow(row) {\n        this.renderer.scrollToRow(row);\n    }\n\n    /**\n     * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).\n     * @param {Number} line The line to scroll to\n     * @param {Boolean} center If `true`\n     * @param {Boolean} animate If `true` animates scrolling\n     * @param {() => void} [callback] Function to be called when the animation has finished\n     *\n     * @related VirtualRenderer.scrollToLine\n     **/\n    scrollToLine(line, center, animate, callback) {\n        this.renderer.scrollToLine(line, center, animate, callback);\n    }\n\n    /**\n     * Attempts to center the current selection on the screen.\n     **/\n    centerSelection() {\n        var range = this.getSelectionRange();\n        var pos = {\n            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),\n            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)\n        };\n        this.renderer.alignCursor(pos, 0.5);\n    }\n\n    /**\n     * Gets the current position of the cursor.\n     * @returns {Point} An object that looks something like this:\n     *\n     * ```json\n     * { row: currRow, column: currCol }\n     * ```\n     *\n     * @related Selection.getCursor\n     **/\n    getCursorPosition() {\n        return this.selection.getCursor();\n    }\n\n    /**\n     * Returns the screen position of the cursor.\n     * @returns {Point}\n     * @related EditSession.documentToScreenPosition\n     **/\n    getCursorPositionScreen() {\n        return this.session.documentToScreenPosition(this.getCursorPosition());\n    }\n\n    /**\n     * {:Selection.getRange}\n     * @returns {Range}\n     * @related Selection.getRange\n     **/\n    getSelectionRange() {\n        return this.selection.getRange();\n    }\n\n    /**\n     * Selects all the text in editor.\n     * @related Selection.selectAll\n     **/\n    selectAll() {\n        this.selection.selectAll();\n    }\n\n    /**\n     * {:Selection.clearSelection}\n     * @related Selection.clearSelection\n     **/\n    clearSelection() {\n        this.selection.clearSelection();\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     * @related Selection.moveCursorTo\n     **/\n    moveCursorTo(row, column) {\n        this.selection.moveCursorTo(row, column);\n    }\n\n    /**\n     * Moves the cursor to the position indicated by `pos.row` and `pos.column`.\n     * @param {Point} pos An object with two properties, row and column\n     * @related Selection.moveCursorToPosition\n     **/\n    moveCursorToPosition(pos) {\n        this.selection.moveCursorToPosition(pos);\n    }\n\n    /**\n     * Moves the cursor's row and column to the next matching bracket or HTML tag.\n     * @param {boolean} [select]\n     * @param {boolean} [expand]\n     */\n    jumpToMatching(select, expand) {\n        var cursor = this.getCursorPosition();\n        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);\n        var prevToken = iterator.getCurrentToken();\n        var tokenCount = 0;\n        if (prevToken && prevToken.type.indexOf('tag-name') !== -1) {\n            prevToken = iterator.stepBackward();\n        }\n        var token = prevToken || iterator.stepForward();\n\n        if (!token) return;\n\n        //get next closing tag or bracket\n        var matchType;\n        var found = false;\n        var depth = {};\n        var i = cursor.column - token.start;\n        var bracketType;\n        var brackets = {\n            \")\": \"(\",\n            \"(\": \"(\",\n            \"]\": \"[\",\n            \"[\": \"[\",\n            \"{\": \"{\",\n            \"}\": \"{\"\n        };\n\n        do {\n            if (token.value.match(/[{}()\\[\\]]/g)) {\n                for (; i < token.value.length && !found; i++) {\n                    if (!brackets[token.value[i]]) {\n                        continue;\n                    }\n\n                    bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n\n                    if (isNaN(depth[bracketType])) {\n                        depth[bracketType] = 0;\n                    }\n\n                    switch (token.value[i]) {\n                        case '(':\n                        case '[':\n                        case '{':\n                            depth[bracketType]++;\n                            break;\n                        case ')':\n                        case ']':\n                        case '}':\n                            depth[bracketType]--;\n\n                            if (depth[bracketType] === -1) {\n                                matchType = 'bracket';\n                                found = true;\n                            }\n                            break;\n                    }\n                }\n            }\n            else if (token.type.indexOf('tag-name') !== -1) {\n                if (isNaN(depth[token.value])) {\n                    depth[token.value] = 0;\n                }\n\n                if (prevToken.value === '<' && tokenCount > 1) {\n                    depth[token.value]++;\n                }\n                else if (prevToken.value === '</') {\n                    depth[token.value]--;\n                }\n\n                if (depth[token.value] === -1) {\n                    matchType = 'tag';\n                    found = true;\n                }\n            }\n\n            if (!found) {\n                prevToken = token;\n                tokenCount++;\n                token = iterator.stepForward();\n                i = 0;\n            }\n        } while (token && !found);\n\n        //no match found\n        if (!matchType) return;\n\n        var range, pos;\n        if (matchType === 'bracket') {\n            range = this.session.getBracketRange(cursor);\n            if (!range) {\n                range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1,\n                    iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + i - 1\n                );\n                pos = range.start;\n                if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column)\n                    < 2) range = this.session.getBracketRange(pos);\n            }\n        }\n        else if (matchType === 'tag') {\n            if (!token || token.type.indexOf('tag-name') === -1) return;\n            range = new Range(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2,\n                iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() - 2\n            );\n\n            //find matching tag\n            if (range.compare(cursor.row, cursor.column) === 0) {\n                var tagsRanges = this.session.getMatchingTags(cursor);\n                if (tagsRanges) {\n                    if (tagsRanges.openTag.contains(cursor.row, cursor.column)) {\n                        range = tagsRanges.closeTag;\n                        pos = range.start;\n                    }\n                    else {\n                        range = tagsRanges.openTag;\n                        if (tagsRanges.closeTag.start.row === cursor.row && tagsRanges.closeTag.start.column\n                            === cursor.column) pos = range.end; else pos = range.start;\n                    }\n                }\n            }\n\n            //we found it\n            pos = pos || range.start;\n        }\n\n        pos = range && range.cursor || pos;\n        if (pos) {\n            if (select) {\n                if (range && expand) {\n                    this.selection.setRange(range);\n                }\n                else if (range && range.isEqual(this.getSelectionRange())) {\n                    this.clearSelection();\n                }\n                else {\n                    this.selection.selectTo(pos.row, pos.column);\n                }\n            }\n            else {\n                this.selection.moveTo(pos.row, pos.column);\n            }\n        }\n    }\n\n    /**\n     * Moves the cursor to the specified line number, and also into the indicated column.\n     * @param {Number} lineNumber The line number to go to\n     * @param {Number} [column] A column number to go to\n     * @param {Boolean} [animate] If `true` animates scolling\n     **/\n    gotoLine(lineNumber, column, animate) {\n        this.selection.clearSelection();\n        this.session.unfold({row: lineNumber - 1, column: column || 0});\n\n        // todo: find a way to automatically exit multiselect mode\n        this.exitMultiSelectMode && this.exitMultiSelectMode();\n        this.moveCursorTo(lineNumber - 1, column || 0);\n\n        if (!this.isRowFullyVisible(lineNumber - 1))\n            this.scrollToLine(lineNumber - 1, true, animate);\n    }\n\n    /**\n     * Moves the cursor to the specified row and column. Note that this does de-select the current selection.\n     * @param {Number} row The new row number\n     * @param {Number} column The new column number\n     *\n     * @related Editor.moveCursorTo\n     **/\n    navigateTo(row, column) {\n        this.selection.moveTo(row, column);\n    }\n\n    /**\n     * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateUp(times) {\n        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {\n            var selectionStart = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionStart);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(-times || -1, 0);\n    }\n\n    /**\n     * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateDown(times) {\n        if (this.selection.isMultiLine() && this.selection.isBackwards()) {\n            var selectionEnd = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionEnd);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(times || 1, 0);\n    }\n\n    /**\n     * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateLeft(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionStart = this.getSelectionRange().start;\n            this.moveCursorToPosition(selectionStart);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorLeft();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.\n     * @param {Number} [times] The number of times to change navigation\n     *\n     **/\n    navigateRight(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionEnd = this.getSelectionRange().end;\n            this.moveCursorToPosition(selectionEnd);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorRight();\n            }\n        }\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineStart() {\n        this.selection.moveCursorLineStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current line. Note that this does de-select the current selection.\n     **/\n    navigateLineEnd() {\n        this.selection.moveCursorLineEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the end of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileEnd() {\n        this.selection.moveCursorFileEnd();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the start of the current file. Note that this does de-select the current selection.\n     **/\n    navigateFileStart() {\n        this.selection.moveCursorFileStart();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordRight() {\n        this.selection.moveCursorWordRight();\n        this.clearSelection();\n    }\n\n    /**\n     *\n     * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.\n     **/\n    navigateWordLeft() {\n        this.selection.moveCursorWordLeft();\n        this.clearSelection();\n    }\n\n    /**\n     * Replaces the first occurrence of `options.needle` with the value in `replacement`.\n     * @param {String} [replacement] The text to replace with\n     * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n     * @return {number}\n     **/\n    replace(replacement, options) {\n        if (options)\n            this.$search.set(options);\n\n        var range = this.$search.find(this.session);\n        var replaced = 0;\n        if (!range)\n            return replaced;\n\n        if (this.$tryReplace(range, replacement)) {\n            replaced = 1;\n        }\n\n        this.selection.setSelectionRange(range);\n        this.renderer.scrollSelectionIntoView(range.start, range.end);\n\n        return replaced;\n    }\n\n    /**\n     * Replaces all occurrences of `options.needle` with the value in `replacement`.\n     * @param {String} [replacement] The text to replace with\n     * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n     * @return {number}\n     **/\n    replaceAll(replacement, options) {\n        if (options) {\n            this.$search.set(options);\n        }\n\n        var ranges = this.$search.findAll(this.session);\n        var replaced = 0;\n        if (!ranges.length)\n            return replaced;\n\n        var selection = this.getSelectionRange();\n        this.selection.moveTo(0, 0);\n\n        for (var i = ranges.length - 1; i >= 0; --i) {\n            if(this.$tryReplace(ranges[i], replacement)) {\n                replaced++;\n            }\n        }\n\n        this.selection.setSelectionRange(selection);\n\n        return replaced;\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.IRange} range\n     * @param {string} [replacement]\n     */\n    $tryReplace(range, replacement) {\n        var input = this.session.getTextRange(range);\n        replacement = this.$search.replace(input, replacement);\n        if (replacement !== null) {\n            range.end = this.session.replace(range, replacement);\n            return range;\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].\n     * @related Search.getOptions\n     * @returns {Partial<SearchOptions>}\n     **/\n    getLastSearchOptions() {\n        return this.$search.getOptions();\n    }\n\n    /**\n     * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].\n     * @param {String|RegExp|Object} needle The text to search for (optional)\n     * @param {Partial<SearchOptions>} [options] An object defining various search properties\n     * @param {Boolean} [animate] If `true` animate scrolling\n     * @related Search.find\n     **/\n    find(needle, options, animate) {\n        if (!options)\n            options = {};\n\n        if (typeof needle == \"string\" || needle instanceof RegExp)\n            options.needle = needle;\n        else if (typeof needle == \"object\")\n            oop.mixin(options, needle);\n\n        var range = this.selection.getRange();\n        if (options.needle == null) {\n            needle = this.session.getTextRange(range)\n                || this.$search.$options.needle;\n            if (!needle) {\n                range = this.session.getWordRange(range.start.row, range.start.column);\n                needle = this.session.getTextRange(range);\n            }\n            this.$search.set({needle: needle});\n        }\n\n        this.$search.set(options);\n        if (!options.start)\n            this.$search.set({start: range});\n\n        var newRange = this.$search.find(this.session);\n        if (options.preventScroll)\n            return newRange;\n        if (newRange) {\n            this.revealRange(newRange, animate);\n            return newRange;\n        }\n        // clear selection if nothing is found\n        if (options.backwards)\n            range.start = range.end;\n        else\n            range.end = range.start;\n        this.selection.setRange(range);\n    }\n\n    /**\n     * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].\n     * @param {Partial<SearchOptions>} [options] search options\n     * @param {Boolean} [animate] If `true` animate scrolling\n     *\n     * @related Editor.find\n     **/\n    findNext(options, animate) {\n        this.find({skipCurrent: true, backwards: false}, options, animate);\n    }\n\n    /**\n     * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].\n     * @param {Partial<SearchOptions>} [options] search options\n     * @param {Boolean} [animate] If `true` animate scrolling\n     *\n     * @related Editor.find\n     **/\n    findPrevious(options, animate) {\n        this.find(options, {skipCurrent: true, backwards: true}, animate);\n    }\n\n    /**\n     *\n     * @param {Range} range\n     * @param {boolean} [animate]\n     */\n    revealRange(range, animate) {\n        this.session.unfold(range);\n        this.selection.setSelectionRange(range);\n\n        var scrollTop = this.renderer.scrollTop;\n        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n        if (animate !== false)\n            this.renderer.animateScrolling(scrollTop);\n    }\n\n    /**\n     * {:UndoManager.undo}\n     * @related UndoManager.undo\n     **/\n    undo() {\n        this.session.getUndoManager().undo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     * {:UndoManager.redo}\n     * @related UndoManager.redo\n     **/\n    redo() {\n        this.session.getUndoManager().redo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    }\n\n    /**\n     *\n     * Cleans up the entire editor.\n     **/\n    destroy() {\n        /** true if editor is destroyed */\n        this.destroyed = true;\n        if (this.$toDestroy) {\n            this.$toDestroy.forEach(function(el) {\n                el.destroy();\n            });\n            this.$toDestroy = [];\n        }\n        if (this.$mouseHandler)\n            this.$mouseHandler.destroy();\n        this.renderer.destroy();\n        this._signal(\"destroy\", this);\n        if (this.session)\n            this.session.destroy();\n        if (this._$emitInputEvent)\n            this._$emitInputEvent.cancel();\n        this.removeAllListeners();\n\n    }\n\n    /**\n     * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element\n     * @param {Boolean} enable default true\n     **/\n    setAutoScrollEditorIntoView(enable) {\n        if (!enable)\n            return;\n        var rect;\n        var self = this;\n        var shouldScroll = false;\n        if (!this.$scrollAnchor)\n            this.$scrollAnchor = document.createElement(\"div\");\n        var scrollAnchor = this.$scrollAnchor;\n        scrollAnchor.style.cssText = \"position:absolute\";\n        this.container.insertBefore(scrollAnchor, this.container.firstChild);\n        var onChangeSelection = this.on(\"changeSelection\", function() {\n            shouldScroll = true;\n        });\n        // needed to not trigger sync reflow\n        var onBeforeRender = this.renderer.on(\"beforeRender\", function() {\n            if (shouldScroll)\n                rect = self.renderer.container.getBoundingClientRect();\n        });\n        var onAfterRender = this.renderer.on(\"afterRender\", function() {\n            if (shouldScroll && rect && (self.isFocused()\n                || self.searchBox && self.searchBox.isFocused())\n            ) {\n                var renderer = self.renderer;\n                var pos = renderer.$cursorLayer.$pixelPos;\n                var config = renderer.layerConfig;\n                var top = pos.top - config.offset;\n                if (pos.top >= 0 && top + rect.top < 0) {\n                    shouldScroll = true;\n                } else if (pos.top < config.height &&\n                    pos.top + rect.top + config.lineHeight > window.innerHeight) {\n                    shouldScroll = false;\n                } else {\n                    shouldScroll = null;\n                }\n                if (shouldScroll != null) {\n                    scrollAnchor.style.top = top + \"px\";\n                    scrollAnchor.style.left = pos.left + \"px\";\n                    scrollAnchor.style.height = config.lineHeight + \"px\";\n                    scrollAnchor.scrollIntoView(shouldScroll);\n                }\n                shouldScroll = rect = null;\n            }\n        });\n        this.setAutoScrollEditorIntoView = function(enable) {\n            if (enable)\n                return;\n            delete this.setAutoScrollEditorIntoView;\n            this.off(\"changeSelection\", onChangeSelection);\n            this.renderer.off(\"afterRender\", onAfterRender);\n            this.renderer.off(\"beforeRender\", onBeforeRender);\n        };\n    }\n\n    $resetCursorStyle() {\n        var style = this.$cursorStyle || \"ace\";\n        var cursorLayer = this.renderer.$cursorLayer;\n        if (!cursorLayer)\n            return;\n        cursorLayer.setSmoothBlinking(/smooth/.test(style));\n        cursorLayer.isBlinking = !this.$readOnly && style != \"wide\";\n        dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n    }\n\n    /**\n     * opens a prompt displaying message\n     **/\n    prompt(message, options, callback) {\n        var editor = this;\n        config.loadModule(\"ace/ext/prompt\", function (module) {\n            module.prompt(editor, message, options, callback);\n        });\n    }\n\n    get hoverTooltip() {\n        return this.$hoverTooltip || (this.$hoverTooltip = new HoverTooltip(this.container));\n    }\n    set hoverTooltip(value) {\n        if (this.$hoverTooltip) this.$hoverTooltip.destroy();\n            this.$hoverTooltip = value;\n    }\n}\n\nEditor.$uid = 0;\nEditor.prototype.curOp = null;\nEditor.prototype.prevOp = {};\n// TODO use property on commands instead of this\nEditor.prototype.$mergeableCommands = [\"backspace\", \"del\", \"insertstring\"];\nEditor.prototype.$toggleWordPairs = [\n    [\"first\", \"last\"],\n    [\"true\", \"false\"],\n    [\"yes\", \"no\"],\n    [\"width\", \"height\"],\n    [\"top\", \"bottom\"],\n    [\"right\", \"left\"],\n    [\"on\", \"off\"],\n    [\"x\", \"y\"],\n    [\"get\", \"set\"],\n    [\"max\", \"min\"],\n    [\"horizontal\", \"vertical\"],\n    [\"show\", \"hide\"],\n    [\"add\", \"remove\"],\n    [\"up\", \"down\"],\n    [\"before\", \"after\"],\n    [\"even\", \"odd\"],\n    [\"in\", \"out\"],\n    [\"inside\", \"outside\"],\n    [\"next\", \"previous\"],\n    [\"increase\", \"decrease\"],\n    [\"attach\", \"detach\"],\n    [\"&&\", \"||\"],\n    [\"==\", \"!=\"]\n];\n\noop.implement(Editor.prototype, EventEmitter);\n\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    selectionStyle: {\n        set: function(style) {\n            this.onSelectionChange();\n            this._signal(\"changeSelectionStyle\", {data: style});\n        },\n        initialValue: \"line\"\n    },\n    highlightActiveLine: {\n        set: function() {this.$updateHighlightActiveLine();},\n        initialValue: true\n    },\n    highlightSelectedWord: {\n        set: function(shouldHighlight) {this.$onSelectionChange();},\n        initialValue: true\n    },\n    readOnly: {\n        set: function(/**@type{boolean}*/readOnly) {\n            this.textInput.setReadOnly(readOnly);\n            if (this.destroyed) return;\n            this.$resetCursorStyle();\n            if (!this.$readOnlyCallback) {\n                this.$readOnlyCallback = (e) => {\n                    var shouldShow = false;\n                    if (e && e.type == \"keydown\") {\n                        if (e && e.key && !e.ctrlKey && !e.metaKey) {\n                            if (e.key == \" \") e.preventDefault();\n                            shouldShow = e.key.length == 1;\n                        }\n                        if (!shouldShow) return;\n                    } else if (e && e.type !== \"exec\") {\n                        shouldShow = true;\n                    }\n                    if (shouldShow) {\n                        var domNode = dom.createElement(\"div\");\n                        domNode.textContent = nls(\"editor.tooltip.disable-editing\", \"Editing is disabled\");\n                        if (!this.hoverTooltip.isOpen) {\n                            this.hoverTooltip.showForRange(this, this.getSelectionRange(), domNode);\n                        }\n                    } else if (this.hoverTooltip && this.hoverTooltip.isOpen) {\n                        this.hoverTooltip.hide();\n                    }\n                };\n            }\n            var textArea = this.textInput.getElement();\n            if (readOnly) {\n                event.addListener(textArea, \"keydown\", this.$readOnlyCallback, this);\n                this.commands.on(\"exec\", this.$readOnlyCallback);\n                this.commands.on(\"commandUnavailable\", this.$readOnlyCallback);\n            } else {\n                event.removeListener(textArea, \"keydown\", this.$readOnlyCallback);\n                this.commands.off(\"exec\", this.$readOnlyCallback);\n                this.commands.off(\"commandUnavailable\", this.$readOnlyCallback);\n            }\n        },\n        initialValue: false\n    },\n    copyWithEmptySelection: {\n        set: function(value) {\n            this.textInput.setCopyWithEmptySelection(value);\n        },\n        initialValue: false\n    },\n    cursorStyle: {\n        set: function(val) { this.$resetCursorStyle(); },\n        values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n        initialValue: \"ace\"\n    },\n    mergeUndoDeltas: {\n        values: [false, true, \"always\"],\n        initialValue: true\n    },\n    behavioursEnabled: {initialValue: true},\n    wrapBehavioursEnabled: {initialValue: true},\n    enableAutoIndent: {initialValue: true},\n    autoScrollEditorIntoView: {\n        set: function(val) {this.setAutoScrollEditorIntoView(val);}\n    },\n    keyboardHandler: {\n        set: function(val) { this.setKeyboardHandler(val); },\n        get: function() { return this.$keybindingId; },\n        handlesSet: true\n    },\n    value: {\n        set: function(val) { this.session.setValue(val); },\n        get: function() { return this.getValue(); },\n        handlesSet: true,\n        hidden: true\n    },\n    session: {\n        set: function(val) { this.setSession(val); },\n        get: function() { return this.session; },\n        handlesSet: true,\n        hidden: true\n    },\n\n    showLineNumbers: {\n        set: function(show) {\n            this.renderer.$gutterLayer.setShowLineNumbers(show);\n            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);\n            if (show && this.$relativeLineNumbers)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        },\n        initialValue: true\n    },\n    relativeLineNumbers: {\n        set: function(value) {\n            if (this.$showLineNumbers && value)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        }\n    },\n    placeholder: {\n        /**\n         * @param message\n         */\n        set: function(message) {\n            if (!this.$updatePlaceholder) {\n                this.$updatePlaceholder = function() {\n                    var hasValue = this.session && (this.renderer.$composition ||\n                         this.session.getLength() > 1 || this.session.getLine(0).length > 0);\n                    if (hasValue && this.renderer.placeholderNode) {\n                        this.renderer.off(\"afterRender\", this.$updatePlaceholder);\n                        dom.removeCssClass(this.container, \"ace_hasPlaceholder\");\n                        this.renderer.placeholderNode.remove();\n                        this.renderer.placeholderNode = null;\n                    } else if (!hasValue && !this.renderer.placeholderNode) {\n                        this.renderer.on(\"afterRender\", this.$updatePlaceholder);\n                        dom.addCssClass(this.container, \"ace_hasPlaceholder\");\n                        var el = dom.createElement(\"div\");\n                        el.className = \"ace_placeholder\";\n                        el.textContent = this.$placeholder || \"\";\n                        this.renderer.placeholderNode = el;\n                        this.renderer.content.appendChild(this.renderer.placeholderNode);\n                    } else if (!hasValue && this.renderer.placeholderNode) {\n                        this.renderer.placeholderNode.textContent = this.$placeholder || \"\";\n                    }\n                }.bind(this);\n                // @ts-ignore\n                this.on(\"input\", this.$updatePlaceholder);\n            }\n            this.$updatePlaceholder();\n        }\n    },\n    enableKeyboardAccessibility: {\n        set: function(value) {\n            var blurCommand = {\n                name: \"blurTextInput\",\n                description: \"Set focus to the editor content div to allow tabbing through the page\",\n                bindKey: \"Esc\",\n                exec: function(editor) {\n                    editor.blur();\n                    editor.renderer.scroller.focus();\n                },\n                readOnly: true\n            };\n\n            var focusOnEnterKeyup = function (e) {\n                if (e.target == this.renderer.scroller && e.keyCode === keys['enter']){\n                    e.preventDefault();\n                    var row = this.getCursorPosition().row;\n\n                    if (!this.isRowVisible(row))\n                        this.scrollToLine(row, true, true);\n\n                    this.focus();\n                }\n            };\n            /**@type {GutterKeyboardHandler}*/\n            var gutterKeyboardHandler;\n\n            // If keyboard a11y mode is enabled we:\n            // - Enable keyboard operability gutter.\n            // - Prevent tab-trapping.\n            // - Hide irrelevant elements from assistive technology.\n            // - On Windows, set more lines to the textarea.\n            // - set aria-label to the text input.\n            if (value){\n                this.renderer.enableKeyboardAccessibility = true;\n                this.renderer.keyboardFocusClassName = \"ace_keyboard-focus\";\n\n                this.textInput.getElement().setAttribute(\"tabindex\", -1);\n                // VoiceOver on Mac OS works best with single line in the textarea, the screen readers on\n                // Windows work best with multiple lines in the textarea.\n                this.textInput.setNumberOfExtraLines(useragent.isWin ? 3 : 0);\n                this.renderer.scroller.setAttribute(\"tabindex\", 0);\n                this.renderer.scroller.setAttribute(\"role\", \"group\");\n                this.renderer.scroller.setAttribute(\"aria-roledescription\", nls(\"editor.scroller.aria-roledescription\", \"editor\"));\n                this.renderer.scroller.classList.add(this.renderer.keyboardFocusClassName);\n                this.renderer.scroller.setAttribute(\"aria-label\",\n                    nls(\"editor.scroller.aria-label\", \"Editor content, press Enter to start editing, press Escape to exit\")\n                );\n\n                this.renderer.scroller.addEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.addCommand(blurCommand);\n\n                this.renderer.$gutter.setAttribute(\"tabindex\", 0);\n                this.renderer.$gutter.setAttribute(\"aria-hidden\", false);\n                this.renderer.$gutter.setAttribute(\"role\", \"group\");\n                this.renderer.$gutter.setAttribute(\"aria-roledescription\", nls(\"editor.gutter.aria-roledescription\", \"editor gutter\"));\n                this.renderer.$gutter.setAttribute(\"aria-label\",\n                    nls(\"editor.gutter.aria-label\", \"Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit\")\n                );\n                this.renderer.$gutter.classList.add(this.renderer.keyboardFocusClassName);\n\n                this.renderer.content.setAttribute(\"aria-hidden\", true);\n\n                if (!gutterKeyboardHandler)\n                    gutterKeyboardHandler = new GutterKeyboardHandler(this);\n\n                gutterKeyboardHandler.addListener();\n\n                this.textInput.setAriaOptions({\n                    setLabel: true\n                });\n            } else {\n                this.renderer.enableKeyboardAccessibility = false;\n\n                this.textInput.getElement().setAttribute(\"tabindex\", 0);\n                this.textInput.setNumberOfExtraLines(0);\n                this.renderer.scroller.setAttribute(\"tabindex\", -1);\n                this.renderer.scroller.removeAttribute(\"role\");\n                this.renderer.scroller.removeAttribute(\"aria-roledescription\");\n                this.renderer.scroller.classList.remove(this.renderer.keyboardFocusClassName);\n                this.renderer.scroller.removeAttribute(\"aria-label\");\n\n                this.renderer.scroller.removeEventListener(\"keyup\", focusOnEnterKeyup.bind(this));\n                this.commands.removeCommand(blurCommand);\n\n                this.renderer.content.removeAttribute(\"aria-hidden\");\n\n                this.renderer.$gutter.setAttribute(\"tabindex\", -1);\n                this.renderer.$gutter.setAttribute(\"aria-hidden\", true);\n                this.renderer.$gutter.removeAttribute(\"role\");\n                this.renderer.$gutter.removeAttribute(\"aria-roledescription\");\n                this.renderer.$gutter.removeAttribute(\"aria-label\");\n                this.renderer.$gutter.classList.remove(this.renderer.keyboardFocusClassName);\n\n                if (gutterKeyboardHandler)\n                    gutterKeyboardHandler.removeListener();\n            }\n        },\n        initialValue: false\n    },\n    textInputAriaLabel: {\n        set: function(val) { this.$textInputAriaLabel = val; },\n        initialValue: \"\"\n    },\n    enableMobileMenu: {\n        /**\n         * @param {boolean} val\n         */\n        set: function(val) { this.$enableMobileMenu = val; },\n        initialValue: true\n    },\n    customScrollbar: \"renderer\",\n    hScrollBarAlwaysVisible: \"renderer\",\n    vScrollBarAlwaysVisible: \"renderer\",\n    highlightGutterLine: \"renderer\",\n    animatedScroll: \"renderer\",\n    showInvisibles: \"renderer\",\n    showPrintMargin: \"renderer\",\n    printMarginColumn: \"renderer\",\n    printMargin: \"renderer\",\n    fadeFoldWidgets: \"renderer\",\n    showFoldWidgets: \"renderer\",\n    displayIndentGuides: \"renderer\",\n    highlightIndentGuides: \"renderer\",\n    showGutter: \"renderer\",\n    fontSize: \"renderer\",\n    fontFamily: \"renderer\",\n    maxLines: \"renderer\",\n    minLines: \"renderer\",\n    scrollPastEnd: \"renderer\",\n    fixedWidthGutter: \"renderer\",\n    theme: \"renderer\",\n    hasCssTransforms: \"renderer\",\n    maxPixelHeight: \"renderer\",\n    useTextareaForIME: \"renderer\",\n    useResizeObserver: \"renderer\",\n    useSvgGutterIcons: \"renderer\",\n    showFoldedAnnotations: \"renderer\",\n\n    scrollSpeed: \"$mouseHandler\",\n    dragDelay: \"$mouseHandler\",\n    dragEnabled: \"$mouseHandler\",\n    focusTimeout: \"$mouseHandler\",\n\n    firstLineNumber: \"session\",\n    overwrite: \"session\",\n    newLineMode: \"session\",\n    useWorker: \"session\",\n    useSoftTabs: \"session\",\n    navigateWithinSoftTabs: \"session\",\n    tabSize: \"session\",\n    wrap: \"session\",\n    indentedSoftWrap: \"session\",\n    foldStyle: \"session\",\n    mode: \"session\"\n});\n\n\nvar relativeNumberRenderer = {\n    getText: function(/**@type{EditSession}*/session, /**@type{number}*/row) {\n        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? \"\\xb7\" : \"\"))) + \"\";\n    },\n    getWidth: function(session, /**@type{number}*/lastLineNumber, config) {\n        return Math.max(\n            lastLineNumber.toString().length,\n            (config.lastRow + 1).toString().length,\n            2\n        ) * config.characterWidth;\n    },\n    update: function(e, /**@type{Editor}*/editor) {\n        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);\n    },\n    attach: function(/**@type{Editor}*/editor) {\n        editor.renderer.$gutterLayer.$renderer = this;\n        editor.on(\"changeSelection\", this.update);\n        this.update(null, editor);\n    },\n    detach: function(/**@type{Editor}*/editor) {\n        if (editor.renderer.$gutterLayer.$renderer == this)\n            editor.renderer.$gutterLayer.$renderer = null;\n        editor.off(\"changeSelection\", this.update);\n        this.update(null, editor);\n    }\n};\nexports.Editor = Editor;\n"
  },
  {
    "path": "src/editor_change_document_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar Text = require(\"./mode/text\").Mode;\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar CssMode = require(\"./mode/css\").Mode;\nvar HtmlMode = require(\"./mode/html\").Mode;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar assert = require(\"./test/assertions\");\nvar lang = require(\"./lib/lang\");\n\nmodule.exports = {\n\n    setUp : function() {\n        this.session1 = new EditSession([\"abc\", \"def\"]);\n        this.session2 = new EditSession([\"ghi\", \"jkl\"]);\n        \n        this.editor = new Editor(new MockRenderer());\n    },\n\n    \"test: change document\" : function() {\n        this.editor.setSession(this.session1);\n        assert.equal(this.editor.getSession(), this.session1);\n\n        this.editor.setSession(this.session2);\n        assert.equal(this.editor.getSession(), this.session2);\n    },\n\n    \"test: only changes to the new document should have effect\" : function() {\n        var called = false;\n        this.editor.onDocumentChange = function() {\n            called = true;\n        };\n\n        this.editor.setSession(this.session1);\n        this.editor.setSession(this.session2);\n\n        this.session1.duplicateLines(0, 0);\n        assert.notOk(called);\n\n        this.session2.duplicateLines(0, 0);\n        assert.ok(called);\n    },\n\n    \"test: should use cursor of new document\" : function() {\n        this.session1.getSelection().moveCursorTo(0, 1);\n        this.session2.getSelection().moveCursorTo(1, 0);\n\n        this.editor.setSession(this.session1);\n        assert.position(this.editor.getCursorPosition(), 0, 1);\n\n        this.editor.setSession(this.session2);\n        assert.position(this.editor.getCursorPosition(), 1, 0);\n    },\n\n    \"test: only changing the cursor of the new doc should not have an effect\" : function() {\n        this.editor.onCursorChange = function() {\n            called = true;\n        };\n\n        this.editor.setSession(this.session1);\n        this.editor.setSession(this.session2);\n        assert.position(this.editor.getCursorPosition(), 0, 0);\n\n        var called = false;\n        this.session1.getSelection().moveCursorTo(0, 1);\n        assert.position(this.editor.getCursorPosition(), 0, 0);\n        assert.notOk(called);\n\n        this.session2.getSelection().moveCursorTo(1, 1);\n        assert.position(this.editor.getCursorPosition(), 1, 1);\n        assert.ok(called);\n    },\n\n    \"test: should use selection of new document\" : function() {\n        this.session1.getSelection().selectTo(0, 1);\n        this.session2.getSelection().selectTo(1, 0);\n\n        this.editor.setSession(this.session1);\n        assert.position(this.editor.getSelection().getSelectionLead(), 0, 1);\n\n        this.editor.setSession(this.session2);\n        assert.position(this.editor.getSelection().getSelectionLead(), 1, 0);\n    },\n\n    \"test: only changing the selection of the new doc should not have an effect\" : function() {\n        this.editor.onSelectionChange = function() {\n            called = true;\n        };\n\n        this.editor.setSession(this.session1);\n        this.editor.setSession(this.session2);\n        assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);\n\n        var called = false;\n        this.session1.getSelection().selectTo(0, 1);\n        assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);\n        assert.notOk(called);\n\n        this.session2.getSelection().selectTo(1, 1);\n        assert.position(this.editor.getSelection().getSelectionLead(), 1, 1);\n        assert.ok(called);\n    },\n\n    \"test: should use mode of new document\" : function() {\n        this.editor.onChangeMode = function() {\n            called = true;\n        };\n        this.editor.setSession(this.session1);\n        this.editor.setSession(this.session2);\n\n        var called = false;\n        this.session1.setMode(new Text());\n        assert.notOk(called);\n\n        this.session2.setMode(new JavaScriptMode());\n        assert.ok(called);\n    },\n    \n    \"test: should use stop worker of old document\" : async function(next) {\n        var self = this;\n        \n        // 1. Open an editor and set the session to CssMode\n        self.editor.setSession(self.session1);\n        self.session1.setMode(new CssMode());\n        \n        // 2. Add a line or two of valid CSS.\n        self.session1.setValue(\"DIV { color: red; }\");\n        \n        // 3. Clear the session value.\n        self.session1.setValue(\"\");\n        \n        // 4. Set the session to HtmlMode\n        self.session1.setMode(new HtmlMode());\n\n        // 5. Try to type valid HTML\n        self.session1.insert({row: 0, column: 0}, \"<html></html>\");\n\n        await lang.sleep(600);\n        assert.equal(Object.keys(self.session1.getAnnotations()).length, 0);\n        next();\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor_commands_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar Editor = require(\"./editor\").Editor;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar HTMLMode = require(\"./mode/html\").Mode;\nvar assert = require(\"./test/assertions\");\nvar lang = require(\"./lib/lang\");\n\nrequire(\"./multi_select\");\n\nvar editor;\n\nvar exec = function(name, times, args) {\n    do {\n        editor.commands.exec(name, editor, args);\n    } while(times --> 1);\n};\n\n\nmodule.exports = {\n    \"test highlightmatching\": async function(done) {\n        editor = new Editor(new MockRenderer());\n        editor.session.setMode(new HTMLMode);\n        editor.setValue(\"<html><head></head> abcd</html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 3);\n        assert.equal(editor.$highlightPending, true);\n\n        await lang.sleep(51);\n        assert.equal(editor.$highlightPending, false);\n        assert.ok(editor.session.$bracketHighlight);\n        assert.equal(\n            editor.session.$bracketHighlight.ranges + \"\",\n            \"Range: [0/1] -> [0/5],Range: [0/26] -> [0/30]\"\n        );\n        exec(\"gotoend\", 1);\n        exec(\"gotoleft\", 3);\n        assert.equal(editor.$highlightPending, true);\n\n        await lang.sleep(51);\n        assert.equal(editor.$highlightPending, false);\n\n        editor.setValue(\"{}\");\n        exec(\"gotostart\", 1);\n\n        await lang.sleep(51);\n        assert.equal(editor.session.$bracketHighlight.ranges + \"\", 'Range: [0/0] -> [0/2]');\n        exec(\"gotoend\", 1);\n\n        await lang.sleep(51);\n        assert.equal(editor.session.$bracketHighlight.ranges + \"\", 'Range: [0/0] -> [0/2]');\n        done();\n    },\n    \"test modifyNumber\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.setValue(\"999\");\n        editor.execCommand(editor.commands.byName.modifyNumberUp);\n        assert.equal(editor.getValue(), \"1000\");\n\n        editor.setValue(\"999f\");\n        editor.execCommand(editor.commands.byName.modifyNumberUp);\n        assert.equal(editor.getValue(), \"999f\");\n\n        editor.setValue(\"1000\");\n        editor.execCommand(editor.commands.byName.modifyNumberDown);\n        assert.equal(editor.getValue(), \"999\");\n\n        editor.setValue(\"1000.1\");\n        editor.execCommand(editor.commands.byName.modifyNumberDown);\n        assert.equal(editor.getValue(), \"1000.0\");\n\n        editor.setValue(\"123.3\", 1);\n        exec(\"gotoleft\", 2);\n        editor.execCommand(editor.commands.byName.modifyNumberDown);\n        assert.equal(editor.getValue(), \"122.3\");\n    },\n    \"test duplicateSelection\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"123.3\", 1);\n        exec(\"selectleft\", 2);\n        editor.execCommand(editor.commands.byName.duplicateSelection);\n        assert.equal(editor.getValue(), \"123.3.3\");\n\n        editor.setValue(\"124.3\", 1);\n        exec(\"gotoleft\", 3);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.duplicateSelection);\n        assert.equal(editor.getValue(), \"124.4.3\");\n        editor.clearSelection();\n        editor.execCommand(editor.commands.byName.duplicateSelection);\n        assert.equal(editor.getValue(), \"124.4.3\\n124.4.3\");\n    },\n    \"test editor find\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"for for foo\", 1);\n        exec(\"gotoleft\", 8);\n        exec(\"selectleft\", 3);\n        editor.execCommand(editor.commands.byName.findnext);\n        assert.range(editor.selection.getRange(), 0, 4, 0, 7);\n\n        editor.setValue(\"for for for foo\", 1);\n        exec(\"gotoleft\", 8);\n        exec(\"selectleft\", 3);\n        editor.execCommand(editor.commands.byName.findprevious);\n        assert.range(editor.selection.getRange(), 0, 0, 0, 3);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 8);\n        editor.execCommand(editor.commands.byName.selectOrFindNext);\n        assert.range(editor.selection.getRange(), 0, 4, 0, 7);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 7);\n        exec(\"selectright\", 3);\n        editor.execCommand(editor.commands.byName.selectOrFindNext);\n        assert.range(editor.selection.getRange(), 0, 12, 0, 15);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 8);\n        editor.execCommand(editor.commands.byName.selectOrFindPrevious);\n        assert.range(editor.selection.getRange(), 0, 4, 0, 7);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 7);\n        exec(\"selectright\", 3);\n        editor.execCommand(editor.commands.byName.selectOrFindPrevious);\n        assert.range(editor.selection.getRange(), 0, 0, 0, 3);\n    },\n    \"test overwrite\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 7);\n        editor.execCommand(editor.commands.byName.overwrite);\n        exec(\"insertstring\", 1, \"b\");\n        assert.equal(editor.getValue(),\"foo for boo foo\");\n    },\n    \"test selections\": function() {\n        editor = new Editor(new MockRenderer(5));\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\", 1);\n        exec(\"gotoleft\", 7);\n        editor.execCommand(editor.commands.byName.selecttostart);\n        assert.range(editor.selection.getRange(), 0, 0, 1, 8);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\", 1);\n        exec(\"gotoleft\", 3);\n        editor.execCommand(editor.commands.byName.selectup);\n        assert.range(editor.selection.getRange(), 0, 6, 1, 6);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\", 1);\n        exec(\"gotoleft\", 9);\n        editor.execCommand(editor.commands.byName.selecttoend);\n        assert.range(editor.selection.getRange(), 1, 0, 1, 9);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 3);\n        editor.execCommand(editor.commands.byName.selectdown);\n        assert.range(editor.selection.getRange(), 0, 3, 1, 3);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\", 1);\n        exec(\"gotoleft\", 4);\n        editor.execCommand(editor.commands.byName.selecttolinestart);\n        assert.range(editor.selection.getRange(), 1, 0, 1, 5);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 7);\n        editor.execCommand(editor.commands.byName.selectwordright);\n        assert.range(editor.selection.getRange(), 0, 8, 0, 11);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 2);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.selecttolineend);\n        assert.range(editor.selection.getRange(), 0, 2, 0, 15);\n\n        // dublicate command\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 2);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.selectlineend);\n        assert.range(editor.selection.getRange(), 0, 2, 0, 15);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 2);\n        editor.execCommand(editor.commands.byName.selectlinestart);\n        assert.range(editor.selection.getRange(), 0, 0, 0, 13);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 3);\n        exec(\"selectright\", 3);\n        editor.execCommand(editor.commands.byName.invertSelection);\n        assert.range(editor.selection.getAllRanges()[0], 0, 0, 0, 3);\n        assert.range(editor.selection.getAllRanges()[1], 0, 6, 0, 15);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectright\", 3);\n        editor.execCommand(editor.commands.byName.invertSelection);\n        assert.range(editor.selection.getRange(), 0, 3, 0, 15);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.invertSelection);\n        assert.range(editor.selection.getRange(), 0, 0, 0, 15);\n\n        editor.setValue(\"foo for foo foo\");\n        editor.execCommand(editor.commands.byName.invertSelection);\n        assert.range(editor.selection.getRange(), 0, 15, 0, 15);\n\n        // ToDO: plenty of matching tests\n        editor.session.setMode(new HTMLMode);\n        editor.setValue(\"<html><head></head> abcd</html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 3);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 3, 0, 24);\n\n        editor.setValue(\"<html><div><div>abcd</div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 11);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 11, 0, 26);\n\n        editor.setValue(\"<html><div><div>abcd</div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 22);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 20, 0, 22);\n\n        editor.setValue(\"<html>abcd</div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 15);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 10, 0, 15);\n\n        editor.setValue(\"<html>abcd</div></div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 21);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 16, 0, 21);\n\n        editor.setValue(\"\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 3);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 0, 0, 0);\n\n        editor.session.setMode(new JavaScriptMode);\n        editor.setValue(\"if (state == 1) {alert(1);}\", -1);\n        exec(\"gotowordright\", 9);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 17, 0, 26);\n\n        editor.setValue(\"if (state == 1) {}\", 1);\n        exec(\"gotoleft\", 1);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 17, 0, 17);\n\n        editor.setValue(\"if (state == 1) {alert(1);}\", 1);\n        editor.selection.moveTo(0, 16);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 16, 0, 16);\n\n        editor.setValue(\"if (state == 1) {alert(1);}\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 16);\n        exec(\"selectright\", 10);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        assert.range(editor.selection.getRange(), 0, 16, 0, 17);\n\n        editor.setValue(\"<html>abcd</div></div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 6);\n        editor.execCommand(editor.commands.byName.selecttomatching);\n        // TODO: assert.range should return selection until the </html> instead of </div>\n\n        editor.setValue(\"<html>abcd</div>\\n</div></html>\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 6);\n        editor.execCommand(editor.commands.byName.expandtoline);\n        editor.execCommand(editor.commands.byName.expandtoline);\n        assert.range(editor.selection.getRange(), 0, 0, 1, 13);\n    },\n    \"test goto\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\", 1);\n        editor.execCommand(editor.commands.byName.golineup);\n        assert.position(editor.getCursorPosition(), 0, 9);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\\ndfsf\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectdown\", 1);\n        editor.execCommand(editor.commands.byName.golineup);\n        assert.position(editor.getCursorPosition(), 0, 0);\n\n        editor.setValue(\"foo for foo foo\\nfsdfsd232\\ndfsf\", 1);\n        exec(\"selectup\", 1);\n        editor.execCommand(editor.commands.byName.golinedown);\n        assert.position(editor.getCursorPosition(), 2, 4);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.gotoright);\n        assert.position(editor.getCursorPosition(), 0, 2);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        editor.execCommand(editor.commands.byName.gotowordleft);\n        assert.position(editor.getCursorPosition(), 0, 12);\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.gotowordright);\n        assert.position(editor.getCursorPosition(), 0, 3);\n    },\n    \"test cut/cut_or_delete\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectright\", 3);\n        editor.execCommand(editor.commands.byName.cut);\n        assert.equal(editor.getValue(), \" for foo foo\");\n\n        editor.setValue(\"foo for foo foo\\nfoo\", 1);\n        //exec(\"gotostart\", 1);\n        exec(\"selectall\", 1);\n        editor.execCommand(editor.commands.byName.cut);\n        assert.equal(editor.getValue(), \"\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.cut);\n        assert.equal(editor.getValue(), \"foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        editor.execCommand(editor.commands.byName.cut_or_delete);\n        assert.equal(editor.getValue(), \"foo for foo fo\");\n\n        editor.session.setMode(new JavaScriptMode);\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"selectleft\", 2);\n        assert.ok(editor.execCommand(\"cut_or_delete\") == false);\n    },\n    \"test sortlines\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"def\\nabd\\nacde\", 1);\n        exec(\"selectall\", 1);\n        editor.execCommand(editor.commands.byName.sortlines);\n        assert.equal(editor.getValue(), \"abd\\nacde\\ndef\");\n\n        editor.setValue(\"def\\nabd\\nabd\", 1);\n        exec(\"selectall\", 1);\n        editor.execCommand(editor.commands.byName.sortlines);\n        assert.equal(editor.getValue(), \"abd\\nabd\\ndef\");\n    },\n    \"test togglecomments/blockcomments\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.session.setMode(new JavaScriptMode);\n\n        editor.setValue(\"def\\nabd\\nabd\");\n        editor.execCommand(editor.commands.byName.togglecomment);\n        assert.equal(editor.getValue(), \"// def\\n// abd\\n// abd\");\n\n        editor.setValue(\"def\\nabd\\nabd\");\n        editor.execCommand(editor.commands.byName.toggleBlockComment);\n        assert.equal(editor.getValue(), \"/*def\\nabd\\nabd*/\");\n    },\n    \"test redo without undoManager\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.session.setValue(\"def\\nabd\\nabd\");\n        exec(\"selectall\", 1);\n        exec(\"backspace\", 1);\n        exec(\"undo\", 1);\n        assert.equal(editor.getValue(), \"\");\n        editor.execCommand(editor.commands.byName.redo);\n        assert.equal(editor.getValue(), \"\");\n    },\n    \"test redo\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.session.setUndoManager(new UndoManager());\n\n        editor.session.setValue(\"def\\nabd\\nabd\");\n        exec(\"selectall\", 1);\n        exec(\"backspace\", 1);\n        exec(\"undo\", 1);\n        assert.equal(editor.getValue(), \"def\\nabd\\nabd\");\n        editor.execCommand(editor.commands.byName.redo);\n        assert.equal(editor.getValue(), \"\");\n    },\n    \"test removetoline\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        editor.execCommand(editor.commands.byName.removetolinestart);\n        assert.equal(editor.getValue(), \"foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"selectleft\", 3);\n        editor.execCommand(editor.commands.byName.removetolinestart);\n        assert.equal(editor.getValue(), \"foo for foo \");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        editor.execCommand(editor.commands.byName.removetolinestarthard);\n        assert.equal(editor.getValue(), \"foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        exec(\"selectleft\", 3);\n        editor.execCommand(editor.commands.byName.removetolinestarthard);\n        assert.equal(editor.getValue(), \"foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 2);\n        editor.execCommand(editor.commands.byName.removetolineend);\n        assert.equal(editor.getValue(), \"fo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.removetolineend);\n        assert.equal(editor.getValue(), \"o for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 2);\n        editor.execCommand(editor.commands.byName.removetolineendhard);\n        assert.equal(editor.getValue(), \"fo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"gotoright\", 2);\n        exec(\"selectright\", 2);\n        editor.execCommand(editor.commands.byName.removetolineendhard);\n        assert.equal(editor.getValue(), \"fo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.removewordright);\n        assert.equal(editor.getValue(), \" for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectright\", 1);\n        editor.execCommand(editor.commands.byName.removewordright);\n        assert.equal(editor.getValue(), \"oo for foo foo\");\n    },\n    \"test indent/outdent\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.indent);\n        assert.equal(editor.getValue(),\"    foo for foo foo\");\n        // TODO: buggy behaviour with autocompletion. For example, when cursor after f in the middle of the word.\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        exec(\"selecttostart\", 1);\n        editor.execCommand(editor.commands.byName.indent);\n        assert.equal(editor.getValue(), \"    foo for foo foo\\n    foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\");\n        editor.execCommand(editor.commands.byName.indent);\n        assert.equal(editor.getValue(), \"    foo for foo foo\\n    foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        exec(\"selectleft\", 2);\n        editor.execCommand(editor.commands.byName.indent);\n        assert.equal(editor.getValue(), \"foo for foo foo\\n    foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"indent\", 1);\n        editor.execCommand(editor.commands.byName.outdent);\n        assert.equal(editor.getValue(), \"foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"indent\", 1);\n        editor.execCommand(editor.commands.byName.blockoutdent);\n        assert.equal(editor.getValue(), \"foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        editor.execCommand(editor.commands.byName.blockindent);\n        assert.equal(editor.getValue(),\"    foo for foo foo\");\n    },\n    \"test splitline\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"gotoleft\", 3);\n        editor.execCommand(editor.commands.byName.splitline);\n        assert.equal(editor.getValue(), \"foo for foo \\nfoo\");\n\n        editor.setValue(\"foo for foo foo\", 1);\n        exec(\"selectleft\", 3);\n        editor.execCommand(editor.commands.byName.splitline);\n        assert.equal(editor.getValue(), \"foo for foo \\n\");\n    },\n    \"test touppercase/tolowercase\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\");\n        editor.execCommand(editor.commands.byName.touppercase);\n        assert.equal(editor.getValue(), \"FOO FOR FOO FOO\");\n\n        editor.setValue(\"FOO for FOO FOO\");\n        editor.execCommand(editor.commands.byName.tolowercase);\n        assert.equal(editor.getValue(), \"foo for foo foo\");\n    },\n    \"test joinlines\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\");\n        editor.execCommand(editor.commands.byName.joinlines);\n        assert.equal(editor.getValue(), \"foo for foo foo foo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\\nfoo for foo foo\", 1);\n        editor.execCommand(editor.commands.byName.joinlines);\n        assert.equal(editor.getValue(), \"foo for foo foo\\nfoo for foo foo\\nfoo for foo foo\");\n\n        editor.setValue(\"foo for foo foo\\nfoo for foo foo\\nfoo for foo foo\", 1);\n        exec(\"gotostart\", 1);\n        exec(\"selectlineend\", 1);\n        editor.execCommand(editor.commands.byName.joinlines);\n        assert.equal(editor.getValue(), \"foo for foo foo foo for foo foo\\nfoo for foo foo\");\n    },\n    \"test findlink\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"foo for foo foo\\nhttps://www.google.com/\", 1);\n        var url = editor.findLinkAt(0, 1);\n        assert.equal(url, null);\n\n        url = editor.findLinkAt(1, 5);\n        assert.equal(url, \"https://www.google.com/\");\n    },\n    \"test handle events without deprecated keyCode property\": function() {\n        editor = new Editor(new MockRenderer());\n        var e = new CustomEvent(\"keydown\"); \n        e.code = \"KeyA\";\n        if (editor.commands.platform === \"mac\") {\n            e.metaKey = true;\n        } else {\n            e.ctrlKey = true;\n        }\n        editor.session.setValue(\"123\");\n        assert.equal(editor.getSelectedText(), \"\");\n        editor.textInput.getElement().dispatchEvent(e);\n        assert.equal(editor.getSelectedText(), \"123\");\n    },\n    \"test fold\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.session.setMode(new JavaScriptMode);\n        editor.session.setValue('\"string\"');\n        editor.execCommand(\"fold\");\n        assert.equal(editor.session.getFoldLine(0), undefined);\n        editor.session.setValue('\"string\\\\\\nsecondline\"');\n        editor.execCommand(\"fold\");\n        assert.equal(editor.session.getFoldLine(0).end.row, 1);\n        editor.execCommand(\"unfold\");\n        assert.equal(editor.session.getFoldLine(0), undefined);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor_highlight_selected_word_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar assert = require(\"./test/assertions\");\n\nvar lipsum = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. \" +\n             \"Mauris at arcu mi, eu lobortis mauris. Quisque ut libero eget \" +\n             \"diam congue vehicula. Quisque ut odio ut mi aliquam tincidunt. \" +\n             \"Duis lacinia aliquam lorem eget eleifend. Morbi eget felis mi. \" +\n             \"Duis quam ligula, consequat vitae convallis volutpat, blandit \" +\n             \"nec neque. Nulla facilisi. Etiam suscipit lorem ac justo \" +\n             \"sollicitudin tristique. Phasellus ut posuere nunc. Aliquam \" +\n             \"scelerisque mollis felis non gravida. Vestibulum lacus sem, \" +\n             \"posuere non bibendum id, luctus non dolor. Aenean id metus \" +\n             \"lorem, vel dapibus est. Donec gravida feugiat augue nec \" +\n             \"accumsan.Lorem ipsum dolor sit amet, consectetur adipiscing \" +\n             \"elit. Nulla vulputate, velit vitae tincidunt congue, nunc \" +\n             \"augue accumsan velit, eu consequat turpis lectus ac orci. \" +\n             \"Pellentesque ornare dolor feugiat dui auctor eu varius nulla \" +\n             \"fermentum. Sed aliquam odio at velit lacinia vel fermentum \" +\n             \"felis sodales. In dignissim magna eget nunc lobortis non \" +\n             \"fringilla nibh ullamcorper. Donec facilisis malesuada elit \" +\n             \"at egestas. Etiam bibendum, diam vitae tempor aliquet, dui \" +\n             \"libero vehicula odio, eget bibendum mauris velit eu lorem.\\n\" +\n             \"consectetur\";\n\nfunction callHighlighterUpdate(session, firstRow, lastRow) {\n    var rangeCount = 0;\n    var  mockMarkerLayer = { drawSingleLineMarker: function() {rangeCount++;} };\n    session.$searchHighlight.update([], mockMarkerLayer, session, {\n        firstRow: firstRow,\n        lastRow: lastRow\n    });\n    return rangeCount;\n}\n\nmodule.exports = {\n    setUp: function() {\n        this.session = new EditSession(lipsum);\n        this.editor = new Editor(new MockRenderer(), this.session);\n        this.selection = this.session.getSelection();\n        this.search = this.editor.$search;\n    },\n\n    \"test: highlight selected words by default\": function() {\n        assert.equal(this.editor.getHighlightSelectedWord(), true);\n    },\n\n    \"test: highlight a word\": function() {\n        this.editor.moveCursorTo(0, 9);\n        this.selection.selectWord();\n\n        var highlighter = this.editor.session.$searchHighlight;\n        assert.ok(highlighter != null);\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"ipsum\");\n        assert.equal(highlighter.cache.length, 0);\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 2);\n    },\n\n    \"test: highlight a word and clear highlight\": function() {\n        this.editor.moveCursorTo(0, 8);\n        this.selection.selectWord();\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"ipsum\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 2);\n\n        this.session.highlight(\"\");\n        assert.equal(this.session.$searchHighlight.cache.length, 0);\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 0);\n    },\n\n    \"test: highlight another word\": function() {\n        this.selection.moveCursorTo(0, 14);\n        this.selection.selectWord();\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"dolor\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 4);\n    },\n\n    \"test: no selection, no highlight\": function() {\n        this.selection.clearSelection();\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 0);\n    },\n\n    \"test: select a word, no highlight\": function() {\n        this.selection.moveCursorTo(0, 14);\n        this.selection.selectWord();\n\n        this.editor.setHighlightSelectedWord(false);\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"dolor\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 0);\n    },\n\n    \"test: select a word with no matches\": function() {\n        this.editor.setHighlightSelectedWord(true);\n\n        var currentOptions = this.search.getOptions();\n        var newOptions = {\n            wrap: true,\n            wholeWord: true,\n            caseSensitive: true,\n            needle: \"Mauris\"\n        };\n        this.search.set(newOptions);\n\n        var match = this.search.find(this.session);\n        assert.notEqual(match, null, \"found a match for 'Mauris'\");\n\n        this.search.set(currentOptions);\n\n        this.selection.setSelectionRange(match);\n\n        assert.equal(this.session.getTextRange(match), \"Mauris\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 1);\n    },\n\n    \"test: partial word selection 1\": function() {\n        this.selection.moveCursorTo(0, 14);\n        this.selection.selectWord();\n        this.selection.selectLeft();\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"dolo\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 0);\n    },\n\n    \"test: partial word selection 2\": function() {\n        this.selection.moveCursorTo(0, 13);\n        this.selection.selectWord();\n        this.selection.selectRight();\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"dolor \");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 3);\n    },\n\n    \"test: partial word selection 3\": function() {\n        var range = this.selection.getWordRange(0, 14);\n        range.start.column++;\n        this.selection.setRange(range);\n\n        var range = this.selection.getRange();\n        assert.equal(this.session.getTextRange(range), \"olor\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 0), 0);\n    },\n\n    \"test: select last word\": function() {\n        this.selection.moveCursorTo(0, 1);\n\n        var currentOptions = this.search.getOptions();\n        var newOptions = {\n            wrap: true,\n            wholeWord: true,\n            caseSensitive: true,\n            backwards: true,\n            needle: \"consectetur\"\n        };\n        this.search.set(newOptions);\n\n        var match = this.search.find(this.session);\n        assert.notEqual(match, null, \"found a match for 'consectetur'\");\n        assert.position(match.start, 1, 0);\n\n        this.search.set(currentOptions);\n\n        this.selection.setSelectionRange(match);\n\n        assert.equal(this.session.getTextRange(match), \"consectetur\");\n        assert.equal(callHighlighterUpdate(this.session, 0, 1), 3);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor_navigation_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar VirtualRenderer = require(\"./virtual_renderer\").VirtualRenderer;\nvar assert = require(\"./test/assertions\");\nvar keys = require('./lib/keys');\n\nfunction emit(keyCode) {\n    var data = {bubbles: true, keyCode};\n    var event = new KeyboardEvent(\"keyup\", data);\n\n    var el = document.activeElement;\n    el.dispatchEvent(event);\n}\n\nmodule.exports = {\n    createEditSession : function(rows, cols) {\n        var line = new Array(cols + 1).join(\"a\");\n        var text = new Array(rows).join(line + \"\\n\") + line;\n        return new EditSession(text);\n    },\n\n    \"test: navigate to end of file should scroll the last line into view\" : function() {\n        var doc = this.createEditSession(200, 10);\n        var editor = new Editor(new MockRenderer(), doc);\n\n        editor.execCommand(\"gotoend\");\n        var cursor = editor.getCursorPosition();\n\n        assert.ok(editor.getFirstVisibleRow() <= cursor.row);\n        assert.ok(editor.getLastVisibleRow() >= cursor.row);\n    },\n\n    \"test: navigate to start of file should scroll the first row into view\" : function() {\n        var doc = this.createEditSession(200, 10);\n        var editor = new Editor(new MockRenderer(), doc);\n\n        editor.moveCursorTo(editor.getLastVisibleRow() + 20);\n        editor.execCommand(\"gotostart\");\n\n        assert.equal(editor.getFirstVisibleRow(), 0);\n    },\n\n    \"test: goto hidden line should scroll the line into the middle of the viewport\" : function() {\n        var editor = new Editor(new MockRenderer(), this.createEditSession(200, 5));\n\n        editor.navigateTo(0, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(101);\n        assert.position(editor.getCursorPosition(), 100, 0);\n        assert.equal(editor.getFirstVisibleRow(), 89);\n\n        editor.navigateTo(100, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(11);\n        assert.position(editor.getCursorPosition(), 10, 0);\n        assert.equal(editor.getFirstVisibleRow(), 0);\n\n        editor.navigateTo(100, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(6);\n        assert.position(editor.getCursorPosition(), 5, 0);\n        assert.equal(0, editor.getFirstVisibleRow(), 0);\n\n        editor.navigateTo(100, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(1);\n        assert.position(editor.getCursorPosition(), 0, 0);\n        assert.equal(editor.getFirstVisibleRow(), 0);\n\n        editor.navigateTo(0, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(191);\n        assert.position(editor.getCursorPosition(), 190, 0);\n        assert.equal(editor.getFirstVisibleRow(), 179);\n\n        editor.navigateTo(0, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(196);\n        assert.position(editor.getCursorPosition(), 195, 0);\n        assert.equal(editor.getFirstVisibleRow(), 180);\n    },\n\n    \"test: goto visible line should only move the cursor and not scroll\": function() {\n        var editor = new Editor(new MockRenderer(), this.createEditSession(200, 5));\n\n        editor.navigateTo(0, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(12);\n        assert.position(editor.getCursorPosition(), 11, 0);\n        assert.equal(editor.getFirstVisibleRow(), 0);\n\n        editor.navigateTo(30, 0);\n        editor.renderer.scrollCursorIntoView();\n        editor.gotoLine(33);\n        assert.position(editor.getCursorPosition(), 32, 0);\n        assert.equal(editor.getFirstVisibleRow(), 30);\n    },\n\n    \"test: navigate from the end of a long line down to a short line and back should maintain the curser column\": function() {\n        var editor = new Editor(new MockRenderer(), new EditSession([\"123456\", \"1\"]));\n\n        editor.navigateTo(0, 6);\n        assert.position(editor.getCursorPosition(), 0, 6);\n\n        editor.navigateDown();\n        assert.position(editor.getCursorPosition(), 1, 1);\n\n        editor.navigateUp();\n        assert.position(editor.getCursorPosition(), 0, 6);\n    },\n\n    \"test: reset desired column on navigate left or right\": function() {\n        var editor = new Editor(new MockRenderer(), new EditSession([\"123456\", \"12\"]));\n\n        editor.navigateTo(0, 6);\n        assert.position(editor.getCursorPosition(), 0, 6);\n\n        editor.navigateDown();\n        assert.position(editor.getCursorPosition(), 1, 2);\n\n        editor.navigateLeft();\n        assert.position(editor.getCursorPosition(), 1, 1);\n\n        editor.navigateUp();\n        assert.position(editor.getCursorPosition(), 0, 1);\n    },\n\n    \"test: navigate within soft tabs based on setting\": function() {\n        var editor = new Editor(new MockRenderer(), new EditSession([\"        \"]));\n\n        editor.getSession().setUseSoftTabs(true);\n        editor.getSession().setTabSize(4);\n\n        editor.navigateTo(0, 0);\n        editor.navigateRight();\n        assert.position(editor.getCursorPosition(), 0, 4);\n\n        editor.navigateLeft();\n        assert.position(editor.getCursorPosition(), 0, 0);\n\n        editor.getSession().setNavigateWithinSoftTabs(true);\n\n        editor.navigateRight();\n        assert.position(editor.getCursorPosition(), 0, 1);\n\n        editor.navigateTo(0, 4);\n        editor.navigateLeft();\n        assert.position(editor.getCursorPosition(), 0, 3);\n    },\n    \n    \"test: typing text should update the desired column\": function() {\n        var editor = new Editor(new MockRenderer(), new EditSession([\"1234\", \"1234567890\"]));\n\n        editor.navigateTo(0, 3);\n        editor.insert(\"juhu\");\n        \n        editor.navigateDown();\n        assert.position(editor.getCursorPosition(), 1, 7);\n    },\n\n    \"test: should allow to toggle between keyboard trapping modes\": function() {\n        var editor = new Editor(new VirtualRenderer(), new EditSession([\"1234\", \"1234567890\"]));\n\n        // Should not trap focus\n        editor.setOption('enableKeyboardAccessibility', true);\n\n        // Focus on editor\n        editor.focus();\n\n        // Focus should be on textInput\n        assert.equal(document.activeElement, editor.textInput.getElement());\n        assert.notEqual(document.activeElement, editor.renderer.scroller);\n\n        editor.onCommandKey({}, 0, keys[\"escape\"]);\n \n        // Focus should be on the content div after pressing Esc\n        assert.equal(document.activeElement, editor.renderer.scroller);\n        assert.notEqual(document.activeElement, editor.textInput.getElement());\n\n        // Should trap focus\n        editor.setOption('enableKeyboardAccessibility', false);\n\n        // Focus on editor\n        editor.focus();\n\n        // Focus should be on textInput\n        assert.equal(document.activeElement, editor.textInput.getElement());\n        assert.notEqual(document.activeElement, editor.renderer.scroller);\n\n        editor.onCommandKey({}, 0, keys[\"escape\"]);\n \n        // Focus should still be on the textInput\n        assert.equal(document.activeElement, editor.textInput.getElement());\n        assert.notEqual(document.activeElement, editor.renderer.scroller);\n    },\n\n    \"test: should allow to focus on textInput using keyboard in non-trapping mode\": function() {\n        var editor = new Editor(new VirtualRenderer(), new EditSession([\"1234\", \"1234567890\"]));\n\n        // Set to not trap focus mode\n        editor.setOption('enableKeyboardAccessibility', true);\n\n        // Focus on editor\n        editor.renderer.scroller.focus();\n\n        // Focus should be on scroller\n        assert.equal(document.activeElement, editor.renderer.scroller);\n        assert.notEqual(document.activeElement, editor.textInput.getElement());\n\n        // Press enter to give focus to the textinput\n        emit(keys[\"enter\"]);\n\n        // Focus should be on the textinput\n        assert.equal(document.activeElement, editor.textInput.getElement());\n        assert.notEqual(document.activeElement, editor.renderer.scroller);        \n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor_options_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"./test/assertions\");\nvar sendKey = require(\"./test/user\").type;\nvar ace = require(\"./ace\");\nvar lang = require(\"./lib/lang\");\n\nvar editor;\n\nfunction mouse(type, pos, properties) {\n    var target = editor.renderer.getMouseEventTarget();\n    var event = new CustomEvent(\"mouse\" + type, {bubbles: true});\n\n    if (\"row\" in pos) {\n        var pagePos = editor.renderer.textToScreenCoordinates(pos.row, pos.column);\n        event.clientX = pagePos.pageX;\n        event.clientY = pagePos.pageY;\n    }\n    else {\n        target = pos;\n        var rect = target.getBoundingClientRect();\n        event.clientX = rect.left + rect.width / 2;\n        event.clientY = rect.top + rect.height / 2;\n    }\n    Object.assign(event, properties);\n    target.dispatchEvent(event);\n}\n\nmodule.exports = {\n    setUp: function () {\n        editor = ace.edit(null, {\n            value: \"999\"\n        });\n        document.body.appendChild(editor.container);\n        editor.container.style.height = \"200px\";\n        editor.container.style.width = \"300px\";\n        editor.focus();\n\n    },\n    tearDown: function () {\n        editor.destroy();\n        editor = null;\n    },\n    \"test readOnly Option\": async function (done) {\n        Array.from(document.querySelectorAll(\".ace_editor\")).forEach(function (el) {\n            if (el != editor.container)\n                el.remove();\n        });\n        var nodes = document.querySelectorAll(\".ace_tooltip\");\n        assert.equal(nodes.length, 1);\n\n        let readOnly = editor.getOption(\"readOnly\");\n        assert.equal(editor.$hoverTooltip, null);\n        assert.equal(readOnly, false);\n        editor.setOption(\"readOnly\", true);\n        readOnly = editor.getOption(\"readOnly\");\n        assert.equal(readOnly, true);\n        sendKey(\"a\");\n\n        await lang.sleep(6);\n        assert.equal(editor.getValue(), \"999\");\n        assert.ok(editor.hoverTooltip != null);\n\n        var nodes = document.querySelectorAll(\".ace_tooltip\");\n        assert.equal(nodes.length, 2);\n        assert.equal(editor.hoverTooltip.isOpen, true);\n\n        mouse(\"down\", editor.container, {button: 0});\n\n        await lang.sleep(6);\n        assert.equal(editor.hoverTooltip.isOpen, false);\n\n        editor.setOption(\"readOnly\", false);\n        sendKey(\"a\");\n\n        await lang.sleep(6);\n        assert.equal(editor.getValue(), \"a999\");\n        var nodes = document.querySelectorAll(\".ace_tooltip\");\n        assert.equal(nodes.length, 2);\n        editor.destroy();\n        editor.container.remove();\n        var nodes = document.querySelectorAll(\".ace_tooltip\");\n        assert.equal(nodes.length, 0);\n        done();\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/editor_text_edit_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar assert = require(\"./test/assertions\");\nvar whitespace = require(\"./ext/whitespace\");\n\nmodule.exports = {\n    \"test: delete line from the middle\" : function() {\n        var session = new EditSession([\"a\", \"b\", \"c\", \"d\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 1);\n        editor.removeLines();\n\n        assert.equal(session.toString(), \"a\\nc\\nd\");\n        assert.position(editor.getCursorPosition(), 1, 0);\n\n        editor.removeLines();\n\n        assert.equal(session.toString(), \"a\\nd\");\n        assert.position(editor.getCursorPosition(), 1, 0);\n\n        editor.removeLines();\n\n        assert.equal(session.toString(), \"a\");\n        assert.position(editor.getCursorPosition(), 0, 1);\n\n        editor.removeLines();\n\n        assert.equal(session.toString(), \"\");\n        assert.position(editor.getCursorPosition(), 0, 0);\n    },\n\n    \"test: delete multiple selected lines\" : function() {\n        var session = new EditSession([\"a\", \"b\", \"c\", \"d\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 1);\n        editor.getSelection().selectDown();\n\n        editor.removeLines();\n        assert.equal(session.toString(), \"a\\nd\");\n        assert.position(editor.getCursorPosition(), 1, 0);\n    },\n\n    \"test: delete first line\" : function() {\n        var session = new EditSession([\"a\", \"b\", \"c\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.removeLines();\n\n        assert.equal(session.toString(), \"b\\nc\");\n        assert.position(editor.getCursorPosition(), 0, 0);\n    },\n\n    \"test: delete last should also delete the new line of the previous line\" : function() {\n        var session = new EditSession([\"a\", \"b\", \"c\", \"\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(3, 0);\n\n        editor.removeLines();\n        assert.equal(session.toString(), \"a\\nb\\nc\");\n        assert.position(editor.getCursorPosition(), 2, 1);\n\n        editor.removeLines();\n        assert.equal(session.toString(), \"a\\nb\");\n        assert.position(editor.getCursorPosition(), 1, 1);\n    },\n\n    \"test: indent block\" : function() {\n        var session = new EditSession([\"a12345\", \"b12345\", \"c12345\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 3);\n        editor.getSelection().selectDown();\n\n        editor.indent();\n\n        assert.equal([\"a12345\", \"    b12345\", \"    c12345\"].join(\"\\n\"), session.toString());\n\n        assert.position(editor.getCursorPosition(), 2, 7);\n\n        var range = editor.getSelectionRange();\n        assert.position(range.start, 1, 7);\n        assert.position(range.end, 2, 7);\n        \n        session.setValue(\"   x\");\n        session.setOption(\"useSoftTabs\", false);\n        editor.selection.moveTo(0, 3);\n        editor.indent();\n        assert.equal(\"\\tx\", session.toString());\n    },\n\n    \"test: indent selected lines\" : function() {\n        var session = new EditSession([\"a12345\", \"b12345\", \"c12345\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 0);\n        editor.getSelection().selectDown();\n\n        editor.indent();\n        assert.equal([\"a12345\", \"    b12345\", \"c12345\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: no auto indent if cursor is before the {\" : function() {\n        var session = new EditSession(\"{\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 0);\n        editor.onTextInput(\"\\n\");\n        assert.equal([\"\", \"{\"].join(\"\\n\"), session.toString());\n    },\n    \n    \"test: outdent block\" : function() {\n        var session = new EditSession([\"        a12345\", \"    b12345\", \"        c12345\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 5);\n        editor.getSelection().selectDown();\n        editor.getSelection().selectDown();\n\n        editor.blockOutdent();\n        assert.equal(session.toString(), [\"    a12345\", \"b12345\", \"    c12345\"].join(\"\\n\"));\n\n        assert.position(editor.getCursorPosition(), 2, 1);\n\n        var range = editor.getSelectionRange();\n        assert.position(range.start, 0, 1);\n        assert.position(range.end, 2, 1);\n\n        editor.blockOutdent();\n        assert.equal(session.toString(), [\"a12345\", \"b12345\", \"c12345\"].join(\"\\n\"));\n\n        var range = editor.getSelectionRange();\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 2, 0);\n    },\n\n    \"test: outent without a selection should update cursor\" : function() {\n        var session = new EditSession(\"        12\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 3);\n        editor.blockOutdent(\"  \");\n\n        assert.equal(session.toString(), \"    12\");\n        assert.position(editor.getCursorPosition(), 0, 0);\n    },\n\n    \"test: comment lines should perserve selection\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\"].join(\"\\n\"), new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n        whitespace.detectIndentation(session);\n        \n        editor.moveCursorTo(0, 2);\n        editor.getSelection().selectDown();\n        editor.toggleCommentLines();\n\n        assert.equal([\"//   abc\", \"// cde\"].join(\"\\n\"), session.toString());\n\n        var selection = editor.getSelectionRange();\n        assert.position(selection.start, 0, 5);\n        assert.position(selection.end, 1, 5);\n    },\n\n    \"test: uncomment lines should perserve selection\" : function() {\n        var session = new EditSession([\"//   abc\", \"//cde\"].join(\"\\n\"), new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n        session.setTabSize(2);\n\n        editor.moveCursorTo(0, 1);\n        editor.getSelection().selectDown();\n        editor.getSelection().selectRight();\n        editor.getSelection().selectRight();\n\n        editor.toggleCommentLines();\n\n        assert.equal([\"  abc\", \"cde\"].join(\"\\n\"), session.toString());\n        assert.range(editor.getSelectionRange(), 0, 0, 1, 1);\n    },\n\n    \"test: toggle comment lines twice should return the original text\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\", \"fg\"], new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 0);\n        editor.getSelection().selectDown();\n        editor.getSelection().selectDown();\n\n        editor.toggleCommentLines();\n        editor.toggleCommentLines();\n\n        assert.equal([\"  abc\", \"cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n\n    \"test: comment lines - if the selection end is at the line start it should stay there\": function() {\n        //select down\n        var session = new EditSession([\"abc\", \"cde\"].join(\"\\n\"), new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 0);\n        editor.getSelection().selectDown();\n\n        editor.toggleCommentLines();\n        assert.range(editor.getSelectionRange(), 0, 3, 1, 0);\n\n        // select up\n        var session = new EditSession([\"abc\", \"cde\"].join(\"\\n\"), new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 0);\n        editor.getSelection().selectUp();\n\n        editor.toggleCommentLines();\n        assert.range(editor.getSelectionRange(), 0, 3, 1, 0);\n    },\n\n    \"test: move lines down should keep selection on moved lines\" : function() {\n        var session = new EditSession([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(0, 1);\n        editor.getSelection().selectDown();\n\n        editor.moveLinesDown();\n        assert.equal([\"33\", \"11\", \"22\", \"44\"].join(\"\\n\"), session.toString());\n        assert.position(editor.getCursorPosition(), 2, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 2, 1);\n\n        editor.moveLinesDown();\n        assert.equal([\"33\", \"44\", \"11\", \"22\"].join(\"\\n\"), session.toString());\n        assert.position(editor.getCursorPosition(), 3, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 3, 1);\n\n        // moving again should have no effect\n        editor.moveLinesDown();\n        assert.equal([\"33\", \"44\", \"11\", \"22\"].join(\"\\n\"), session.toString());\n        assert.position(editor.getCursorPosition(), 3, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 3, 1);\n    },\n\n    \"test: move lines up should keep selection on moved lines\" : function() {\n        var session = new EditSession([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(2, 1);\n        editor.getSelection().selectDown();\n\n        editor.moveLinesUp();\n        assert.equal(session.toString(), [\"11\", \"33\", \"44\", \"22\"].join(\"\\n\"));\n        assert.position(editor.getCursorPosition(), 2, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 2, 1);\n\n        editor.moveLinesUp();\n        assert.equal(session.toString(), [\"33\", \"44\", \"11\", \"22\"].join(\"\\n\"));\n        assert.position(editor.getCursorPosition(), 1, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 0, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 1, 1);\n    },\n\n    \"test: move line without active selection should not move cursor relative to the moved line\" : function() {\n        var session = new EditSession([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 1);\n        editor.clearSelection();\n\n        editor.moveLinesDown();\n        assert.equal([\"11\", \"33\", \"22\", \"44\"].join(\"\\n\"), session.toString());\n        assert.position(editor.getCursorPosition(), 2, 1);\n\n        editor.clearSelection();\n\n        editor.moveLinesUp();\n        assert.equal([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"), session.toString());\n        assert.position(editor.getCursorPosition(), 1, 1);\n    },\n\n    \"test: copy lines down should keep selection\" : function() {\n        var session = new EditSession([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 1);\n        editor.getSelection().selectDown();\n\n        editor.copyLinesDown();\n        assert.equal([\"11\", \"22\", \"33\", \"22\", \"33\", \"44\"].join(\"\\n\"), session.toString());\n\n        assert.position(editor.getCursorPosition(), 4, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 3, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 4, 1);\n    },\n\n    \"test: copy lines up should keep selection\" : function() {\n        var session = new EditSession([\"11\", \"22\", \"33\", \"44\"].join(\"\\n\"));\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.moveCursorTo(1, 1);\n        editor.getSelection().selectDown();\n\n        editor.copyLinesUp();\n        assert.equal([\"11\", \"22\", \"33\", \"22\", \"33\", \"44\"].join(\"\\n\"), session.toString());\n\n        assert.position(editor.getCursorPosition(), 2, 1);\n        assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);\n        assert.position(editor.getSelection().getSelectionLead(), 2, 1);\n    },\n\n    \"test: input a tab with soft tab should convert it to spaces\" : function() {\n        var session = new EditSession(\"\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        session.setTabSize(2);\n        session.setUseSoftTabs(true);\n\n        editor.onTextInput(\"\\t\");\n        assert.equal(session.toString(), \"  \");\n\n        session.setTabSize(5);\n        editor.onTextInput(\"\\t\");\n        assert.equal(session.toString(), \"       \");\n    },\n\n    \"test: input tab without soft tabs should keep the tab character\" : function() {\n        var session = new EditSession(\"\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        session.setUseSoftTabs(false);\n\n        editor.onTextInput(\"\\t\");\n        assert.equal(session.toString(), \"\\t\");\n    },\n\n    \"test: undo/redo for delete line\" : function() {\n        var session = new EditSession([\"111\", \"222\", \"333\"]);\n        var undoManager = new UndoManager();\n        session.setUndoManager(undoManager);\n\n        var initialText = session.toString();\n        var editor = new Editor(new MockRenderer(), session);\n\n        editor.removeLines();\n        var step1 = session.toString();\n        assert.equal(step1, \"222\\n333\");\n        session.$syncInformUndoManager();\n\n        editor.removeLines();\n        var step2 = session.toString();\n        assert.equal(step2, \"333\");\n        session.$syncInformUndoManager();\n\n        editor.removeLines();\n        var step3 = session.toString();\n        assert.equal(step3, \"\");\n        session.$syncInformUndoManager();\n\n        undoManager.undo();\n        session.$syncInformUndoManager();\n        assert.equal(session.toString(), step2);\n\n        undoManager.undo();\n        session.$syncInformUndoManager();\n        assert.equal(session.toString(), step1);\n\n        undoManager.undo();\n        session.$syncInformUndoManager();\n        assert.equal(session.toString(), initialText);\n\n        undoManager.undo();\n        session.$syncInformUndoManager();\n        assert.equal(session.toString(), initialText);\n    },\n\n    \"test: remove left should remove character left of the cursor\" : function() {\n        var session = new EditSession([\"123\", \"456\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 1);\n        editor.remove(\"left\");\n        assert.equal(session.toString(), \"123\\n56\");\n    },\n\n    \"test: remove left should remove line break if cursor is at line start\" : function() {\n        var session = new EditSession([\"123\", \"456\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.remove(\"left\");\n        assert.equal(session.toString(), \"123456\");\n    },\n\n    \"test: remove left should remove tabsize spaces if cursor is on a tab stop and preceeded by spaces\" : function() {\n        var session = new EditSession([\"123\", \"        456\"]);\n        session.setUseSoftTabs(true);\n        session.setTabSize(4);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 8);\n        editor.remove(\"left\");\n        assert.equal(session.toString(), \"123\\n    456\");\n    },\n    \n    \"test: transpose at line start should be a noop\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.transposeLetters();\n        \n        assert.equal(session.getValue(), [\"123\", \"4567\", \"89\"].join(\"\\n\"));\n    },\n    \n    \"test: transpose in line should swap the charaters before and after the cursor\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 2);\n        editor.transposeLetters();\n        \n        assert.equal(session.getValue(), [\"123\", \"4657\", \"89\"].join(\"\\n\"));\n    },\n    \n    \"test: transpose at line end should swap the last two characters\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 4);\n        editor.transposeLetters();\n        \n        assert.equal(session.getValue(), [\"123\", \"4576\", \"89\"].join(\"\\n\"));\n    },\n    \n    \"test: transpose with non empty selection should be a noop\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 1);\n        editor.getSelection().selectRight();\n        editor.transposeLetters();\n        \n        assert.equal(session.getValue(), [\"123\", \"4567\", \"89\"].join(\"\\n\"));\n    },\n    \n    \"test: transpose should move the cursor behind the last swapped character\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 2);\n        editor.transposeLetters();\n        assert.position(editor.getCursorPosition(), 1, 3);\n    },\n    \n    \"test: remove to line end\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 2);\n        editor.removeToLineEnd();\n        assert.equal(session.getValue(), [\"123\", \"45\", \"89\"].join(\"\\n\"));\n    },\n    \n    \"test: remove to line end at line end should remove the new line\": function() {\n        var session = new EditSession([\"123\", \"4567\", \"89\"]);\n        \n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 4);\n        editor.removeToLineEnd();\n        assert.position(editor.getCursorPosition(), 1, 4);\n        assert.equal(session.getValue(), [\"123\", \"456789\"].join(\"\\n\"));\n    },\n\n    \"test: transform selection to uppercase\": function() {\n        var session = new EditSession([\"ajax\", \"dot\", \"org\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.getSelection().selectLineEnd();\n        editor.toUpperCase();\n        assert.equal(session.getValue(), [\"ajax\", \"DOT\", \"org\"].join(\"\\n\"));\n    },\n\n    \"test: transform word to uppercase\": function() {\n        var session = new EditSession([\"ajax\", \"dot\", \"org\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.toUpperCase();\n        assert.equal(session.getValue(), [\"ajax\", \"DOT\", \"org\"].join(\"\\n\"));\n        assert.position(editor.getCursorPosition(), 1, 0);\n    },\n\n    \"test: transform selection to lowercase\": function() {\n        var session = new EditSession([\"AJAX\", \"DOT\", \"ORG\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.getSelection().selectLineEnd();\n        editor.toLowerCase();\n        assert.equal(session.getValue(), [\"AJAX\", \"dot\", \"ORG\"].join(\"\\n\"));\n    },\n\n    \"test: transform word to lowercase\": function() {\n        var session = new EditSession([\"AJAX\", \"DOT\", \"ORG\"]);\n\n        var editor = new Editor(new MockRenderer(), session);\n        editor.moveCursorTo(1, 0);\n        editor.toLowerCase();\n        assert.equal(session.getValue(), [\"AJAX\", \"dot\", \"ORG\"].join(\"\\n\"));\n        assert.position(editor.getCursorPosition(), 1, 0);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/ext/beautify.js",
    "content": "/**\n * ## Code beautification and formatting extension.\n *\n * **This extension is considered outdated.** For better formatting support with modern language servers\n * and advanced formatting capabilities, consider using [ace-linters](https://github.com/mkslanc/ace-linters)\n * which provides comprehensive language support including formatting, linting, and IntelliSense features.\n *\n * This legacy extension provides basic formatting for HTML, CSS, JavaScript, and PHP code with support for\n * proper indentation, whitespace management, line breaks, and bracket alignment. It handles various language\n * constructs including HTML tags, CSS selectors, JavaScript operators, control structures, and maintains\n * consistent code style throughout the document.\n *\n * @module\n */\n\n\n\"use strict\";\n\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\n\nfunction is(token, type) {\n    return token.type.lastIndexOf(type + \".xml\") > -1;\n}\n\n/**\n * List of HTML singleton (self-closing) tags that do not require additional indentation.\n * These tags are typically void elements that cannot have child content and are closed within themselves.\n *\n * @type {string[]}\n * @exports\n */\nexports.singletonTags = [\"area\", \"base\", \"br\", \"col\", \"command\", \"embed\", \"hr\", \"html\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\"];\n\n/**\n * List of HTML block-level tags that typically require line breaks after their opening and closing tags.\n * These tags represent structural elements that usually contain other content and are rendered as block-level elements.\n *\n * @type {string[]}\n */\nexports.blockTags = [\"article\", \"aside\", \"blockquote\", \"body\", \"div\", \"dl\", \"fieldset\", \"footer\", \"form\", \"head\", \"header\", \"html\", \"nav\", \"ol\", \"p\", \"script\", \"section\", \"style\", \"table\", \"tbody\", \"tfoot\", \"thead\", \"ul\"];\n\n/**\n * Configuration options for code formatting behavior.\n * Controls various formatting rules such as line break placement and spacing preferences.\n *\n * @type {{lineBreaksAfterCommasInCurlyBlock?: boolean}}\n */\nexports.formatOptions = {\n    lineBreaksAfterCommasInCurlyBlock: true\n};\n\n/**\n * Formats and beautifies code in the editor session with intelligent indentation, whitespace management, and bracket alignment.\n * Supports HTML, CSS, JavaScript, and PHP with configurable formatting options and language-specific rules.\n *\n * @param {import(\"../edit_session\").EditSession} session - The editor session containing the code to format\n */\n\nexports.beautify = function(session) {\n    var iterator = new TokenIterator(session, 0, 0);\n    var token = iterator.getCurrentToken();\n    var tabString = session.getTabString();\n    var singletonTags = exports.singletonTags;\n    var blockTags = exports.blockTags;\n    var formatOptions = exports.formatOptions || {};\n    var nextToken;\n    var breakBefore = false;\n    var spaceBefore = false;\n    var spaceAfter = false;\n    var code = \"\";\n    var value = \"\";\n    var tagName = \"\";\n    var depth = 0;\n    var lastDepth = 0;\n    var lastIndent = 0;\n    var indent = 0;\n    var unindent = 0;\n    var roundDepth = 0;\n    var curlyDepth = 0;\n    var row;\n    var curRow = 0;\n    var rowsToAdd = 0;\n    var rowTokens = [];\n    var abort = false;\n    var i;\n    var indentNextLine = false;\n    var inTag = false;\n    var inCSS = false;\n    var inBlock = false;\n    var levels = {0: 0};\n    var parents = [];\n    var caseBody = false;\n\n    var trimNext = function() {\n        if (nextToken && nextToken.value && nextToken.type !== 'string.regexp')\n            nextToken.value = nextToken.value.replace(/^\\s*/, \"\");\n    };\n    \n    var trimLine = function() {\n        var end = code.length - 1;\n\n        while (true) {\n            if (end == 0)\n                break;\n            if (code[end] !== \" \")\n                break;\n            \n            end = end - 1;\n        }\n\n        code = code.slice(0, end + 1);\n    };\n    \n    var trimCode = function() {\n        code = code.trimRight();\n        breakBefore = false;\n    };\n\n    while (token !== null) {\n        curRow = iterator.getCurrentTokenRow();\n        rowTokens = iterator.$rowTokens;\n        nextToken = iterator.stepForward();\n\n        if (typeof token !== \"undefined\") {\n            value = token.value;\n            unindent = 0;\n\n            // mode\n            inCSS = (tagName === \"style\" || session.$modeId === \"ace/mode/css\");\n\n            // in tag\n            if (is(token, \"tag-open\")) {\n                inTag = true;\n\n                // are we in a block tag\n                if (nextToken)\n                    inBlock = (blockTags.indexOf(nextToken.value) !== -1);\n\n                // html indentation\n                if (value === \"</\") {\n                    // line break before closing tag unless we just had one\n                    if (inBlock && !breakBefore && rowsToAdd < 1)\n                        rowsToAdd++;\n\n                    if (inCSS)\n                        rowsToAdd = 1;\n\n                    unindent = 1;\n                    inBlock = false;\n                }\n            } else if (is(token, \"tag-close\")) {\n                inTag = false;\n            // comments\n            } else if (is(token, \"comment.start\")) {\n                inBlock = true;\n            } else if (is(token, \"comment.end\")) {\n                inBlock = false;\n            }\n\n            // line break before }\n            if (!inTag && !rowsToAdd && token.type === \"paren.rparen\" && token.value.substr(0, 1) === \"}\") {\n                rowsToAdd++;\n            }\n\n            // add rows\n            if (curRow !== row) {\n                rowsToAdd = curRow;\n\n                if (row)\n                    rowsToAdd -= row;\n            }\n\n            if (rowsToAdd) {\n                trimCode();\n                for (; rowsToAdd > 0; rowsToAdd--)\n                    code += \"\\n\";\n\n                breakBefore = true;\n\n                // trim value if not in a comment or string\n                if (!is(token, \"comment\") && !token.type.match(/^(comment|string)$/))\n                   value = value.trimLeft();\n            }\n\n            if (value) {\n                // whitespace\n                if (token.type === \"keyword\" && value.match(/^(if|else|elseif|for|foreach|while|switch)$/)) {\n                    parents[depth] = value;\n\n                    trimNext();\n                    spaceAfter = true;\n\n                    // space before else, elseif\n                    if (value.match(/^(else|elseif)$/)) {\n                        if (code.match(/\\}[\\s]*$/)) {\n                            trimCode();\n                            spaceBefore = true;\n                        }\n                    }\n                // trim value after opening paren\n                } else if (token.type === \"paren.lparen\") {\n                    trimNext();\n\n                    // whitespace after {\n                    if (value.substr(-1) === \"{\") {\n                        spaceAfter = true;\n                        indentNextLine = false;\n\n                        if(!inTag)\n                            rowsToAdd = 1;\n                    }\n\n                    // ensure curly brace is preceeded by whitespace\n                    if (value.substr(0, 1) === \"{\") {\n                        spaceBefore = true;\n\n                        // collapse square and curly brackets together\n                        if (code.substr(-1) !== '[' && code.trimRight().substr(-1) === '[') {\n                            trimCode();\n                            spaceBefore = false;\n                        } else if (code.trimRight().substr(-1) === ')') {\n                            trimCode();\n                        } else {\n                            trimLine();\n                        }\n                    }\n                // remove space before closing paren\n                } else if (token.type === \"paren.rparen\") {\n                    unindent = 1;\n\n                    // ensure curly brace is preceeded by whitespace\n                    if (value.substr(0, 1) === \"}\") {\n                        if (parents[depth-1] === 'case')\n                            unindent++;\n\n                        if (code.trimRight().substr(-1) === '{') {\n                            trimCode();\n                        } else {\n                            spaceBefore = true;\n\n                            if (inCSS)\n                                rowsToAdd+=2;\n                        }\n                    }\n\n                    // collapse square and curly brackets together\n                    if (value.substr(0, 1) === \"]\") {\n                        if (code.substr(-1) !== '}' && code.trimRight().substr(-1) === '}') {\n                            spaceBefore = false;\n                            indent++;\n                            trimCode();\n                        }\n                    }\n\n                    // collapse round brackets together\n                    if (value.substr(0, 1) === \")\") {\n                        if (code.substr(-1) !== '(' && code.trimRight().substr(-1) === '(') {\n                            spaceBefore = false;\n                            indent++;\n                            trimCode();\n                        }\n                    }\n\n                    trimLine();\n                // add spaces around conditional operators\n                } else if ((token.type === \"keyword.operator\" || token.type === \"keyword\") && value.match(/^(=|==|===|!=|!==|&&|\\|\\||and|or|xor|\\+=|.=|>|>=|<|<=|=>)$/)) {\n                    trimCode();\n                    trimNext();\n                    spaceBefore = true;\n                    spaceAfter = true;\n                // remove space before semicolon\n                } else if (token.type === \"punctuation.operator\" && value === ';') {\n                    trimCode();\n                    trimNext();\n                    spaceAfter = true;\n\n                    if (inCSS)\n                        rowsToAdd++;\n                // space after colon or comma\n                } else if (token.type === \"punctuation.operator\" && value.match(/^(:|,)$/)) {\n                    trimCode();\n                    trimNext();\n\n                    // line break after commas in curly block\n                    if (value.match(/^(,)$/) && curlyDepth>0 && roundDepth===0 && formatOptions.lineBreaksAfterCommasInCurlyBlock) {\n                        rowsToAdd++;\n                    } else {\n                        spaceAfter = true;\n                        breakBefore = false;\n                    }\n                // ensure space before php closing tag\n                } else if (token.type === \"support.php_tag\" && value === \"?>\" && !breakBefore) {\n                    trimCode();\n                    spaceBefore = true;\n                // remove excess space before HTML attribute\n                } else if (is(token, \"attribute-name\") && code.substr(-1).match(/^\\s$/)) {\n                    spaceBefore = true;\n                // remove space around attribute equals\n                } else if (is(token, \"attribute-equals\")) {\n                    trimLine();\n                    trimNext();\n                // remove space before HTML closing tag\n                } else if (is(token, \"tag-close\")) {\n                    trimLine();\n                    if(value === \"/>\")\n                        spaceBefore = true;\n                } else if (token.type === \"keyword\" && value.match(/^(case|default)$/)) {\n                    if (caseBody)\n                        unindent = 1;\n                }\n\n                // add indent to code unless multiline string or comment\n                if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['\"@]$/))) {\n\n                    indent = lastIndent;\n\n                    if(depth > lastDepth) {\n                        indent++;\n\n                        for (i=depth; i > lastDepth; i--)\n                            levels[i] = indent;\n                    } else if(depth < lastDepth)\n                        indent = levels[depth];\n\n                    lastDepth = depth;\n                    lastIndent = indent;\n\n                    if(unindent)\n                        indent -= unindent;\n\n                    if (indentNextLine && !roundDepth) {\n                        indent++;\n                        indentNextLine = false;\n                    }\n\n                    for (i = 0; i < indent; i++)\n                        code += tabString;\n                }\n\n                if (token.type === \"keyword\" && value.match(/^(case|default)$/)) {\n                    if (caseBody === false) {\n                        parents[depth] = value;\n                        depth++;\n                        caseBody = true;\n                    }\n                } else if (token.type === \"keyword\" && value.match(/^(break)$/)) {\n                    if(parents[depth-1] && parents[depth-1].match(/^(case|default)$/)) {\n                        depth--;\n                        caseBody = false;\n                    }\n                }\n\n                // indent one line after if or else\n                if (token.type === \"paren.lparen\") {\n                    roundDepth += (value.match(/\\(/g) || []).length;\n                    curlyDepth += (value.match(/\\{/g) || []).length;\n                    depth += value.length;\n                }\n\n                if (token.type === \"keyword\" && value.match(/^(if|else|elseif|for|while)$/)) {\n                    indentNextLine = true;\n                    roundDepth = 0;\n                } else if (!roundDepth && value.trim() && token.type !== \"comment\")\n                    indentNextLine = false;\n\n                if (token.type === \"paren.rparen\") {\n                    roundDepth -= (value.match(/\\)/g) || []).length;\n                    curlyDepth -= (value.match(/\\}/g) || []).length;\n\n                    for (i = 0; i < value.length; i++) {\n                        depth--;\n                        if(value.substr(i, 1)==='}' && parents[depth]==='case') {\n                            depth--;\n                        }\n                    }\n                }\n                \n                if (token.type == \"text\")\n                    value = value.replace(/\\s+$/, \" \");\n\n                // add to code\n                if (spaceBefore && !breakBefore) {\n                    trimLine();\n                    if (code.substr(-1) !== \"\\n\")\n                        code += \" \";\n                }\n\n                code += value;\n\n                if (spaceAfter)\n                    code += \" \";\n\n                breakBefore = false;\n                spaceBefore = false;\n                spaceAfter = false;\n\n                // line break after block tag or doctype\n                if ((is(token, \"tag-close\") && (inBlock || blockTags.indexOf(tagName) !== -1)) || (is(token, \"doctype\") && value === \">\")) {\n                    // undo linebreak if tag is immediately closed\n                    if (inBlock && nextToken && nextToken.value === \"</\")\n                        rowsToAdd = -1;\n                    else\n                        rowsToAdd = 1;\n                }\n\n                // html indentation\n                if (nextToken && singletonTags.indexOf(nextToken.value) === -1) {\n                    if (is(token, \"tag-open\") && value === \"</\") {\n                        depth--;\n                    } else if (is(token, \"tag-open\") && value === \"<\") {\n                        depth++;\n                    } else if (is(token, \"tag-close\") && value === \"/>\"){\n                        depth--;\n                    }\n                }\n                \n                if (is(token, \"tag-name\")) {\n                    tagName = value;\n                }\n\n                row = curRow;\n            }\n        }\n\n        token = nextToken;\n    }\n\n    code = code.trim();\n    session.doc.setValue(code);\n};\n\n/**\n * Array of command definitions for the beautify extension.\n * Contains the main beautify command with keyboard shortcut and execution handler.\n *\n * @type {import(\"../../ace-internal\").Ace.Command[]}\n */\nexports.commands = [{\n    name: \"beautify\",\n    description: \"Format selection (Beautify)\",\n    exec: function(editor) {\n        exports.beautify(editor.session);\n    },\n    bindKey: \"Ctrl-Shift-B\"\n}];\n"
  },
  {
    "path": "src/ext/beautify_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar beautify = require(\"./beautify\");\nvar PHPMode = require(\"../mode/php\").Mode;\nvar CSSMode = require(\"../mode/css\").Mode;\n\n// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite\nmodule.exports = {\n    timeout: 10000,\n\n    \"test beautify first line empty\": function() {\n        var s = new EditSession([\n            \"\",\n            \"hello world\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"hello world\");\n    },\n\n    \"test beautify block tag indentation\": function() {\n        var s = new EditSession([\n            \"<div>\",\n            \"<h1>hello</h1>\",\n            \"world</div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div>\\n\"\n            + \"\\t<h1>hello</h1>\\n\"\n            + \"\\tworld\\n\"\n            + \"</div>\");\n    },\n\n    \"test beautify block tag line breaks and indentation\": function() {\n        var s = new EditSession([\n            \"<html><body><div></div></body></html>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<html>\\n\"\n            + \"<body>\\n\"\n            + \"\\t<div></div>\\n\"\n            + \"</body>\\n\"\n            + \"</html>\");\n    },\n\n    \"test beautify empty block tag\": function() {\n        var s = new EditSession([\n            \"\\t<div></div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div></div>\");\n    },\n\n    \"test beautify inline tag indentation\": function() {\n        var s = new EditSession([\n            \"<div>\",\n            \"<span>hello world</span>\",\n            \"</div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div>\\n\"\n            + \"\\t<span>hello world</span>\\n\"\n            + \"</div>\");\n    },\n\n    \"test beautify multiline inline tag indentation\": function() {\n        var s = new EditSession([\n            \"<div>\",\n            \"<span>\",\n            \"hello world\",\n            \"</span>\",\n            \"</div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div>\\n\"\n            + \"\\t<span>\\n\"\n            + \"\\t\\thello world\\n\"\n            + \"\\t</span>\\n\"\n            + \"</div>\");\n    },\n\n    \"test beautify singleton tag indentation\": function() {\n        var s = new EditSession([\n            \"<div>\",\n            \"hello<br>\",\n            \"world\",\n            \"</div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div>\\n\"\n            + \"\\thello<br>\\n\"\n            + \"\\tworld\\n\"\n            + \"</div>\");\n    },\n\n    \"test beautify unknown singleton indentation\": function() {\n        var s = new EditSession([\n            \"<div>\",\n            \"hello<single />\",\n            \"world\",\n            \"</div>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<div>\\n\"\n            + \"\\thello<single />\\n\"\n            + \"\\tworld\\n\"\n            + \"</div>\");\n    },\n\n    \"test beautify curly indentation\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"if ($foo===array()) {\",\n            \"$i++;\",\n            \"}\",\n            \"if (($foo ||\",\n            \"$bar)) {\",\n            \"true;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if ($foo === array()) {\\n\"\n            + \"\\t$i++;\\n\"\n            + \"}\\n\"\n            + \"if (($foo ||\\n\"\n            + \"\\t$bar)) {\\n\"\n            + \"\\ttrue;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify adding bracket whitespace\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"if(true){\",\n            \"\\t$i++;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if (true) {\\n\"\n            + \"\\t$i++;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify removing bracket whitespace\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"if ( true ) {\",\n            \"\\t$i++;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if (true) {\\n\"\n            + \"\\t$i++;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify adding keyword whitespace\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"if ($foo===true) {\",\n            \"\\t$i++;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if ($foo === true) {\\n\"\n            + \"\\t$i++;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify if without paren\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"if ($foo)\",\n            \"$i++;\",\n            \"if ($foo) $j++\",\n            \"print $i\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if ($foo)\\n\"\n            + \"\\t$i++;\\n\"\n            + \"if ($foo) $j++\\n\"\n            + \"print $i\");\n    },\n\n    \"test beautify switch indentation\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"switch ($i) {\",\n            \"case 1;\",\n            \"case 2;\",\n            \"print $foo;\",\n            \"break;\",\n            \"case 2;\",\n            \"print $bar;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"switch ($i) {\\n\"\n            + \"\\tcase 1;\\n\"\n            + \"\\tcase 2;\\n\"\n            + \"\\t\\tprint $foo;\\n\"\n            + \"\\t\\tbreak;\\n\"\n            + \"\\tcase 2;\\n\"\n            + \"\\t\\tprint $bar;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify multiline string\": function() {\n        var s = new EditSession([\n            \"<?php\",\n            \"\\tprint 'hello\",\n            \"\\t\\tworld'\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"print 'hello\\n\"\n            + \"\\t\\tworld'\");\n    },\n\n    \"test beautify remove spaces before semicolons\": function() {\n        var s = new EditSession([\n            \"<?php echo \\\"hello world\\\";?>\",\n            \"<?php\",\n            \"$foo = \\\"hello \\\" ;$bar = \\\"world\\\";\",\n            \"print $foo.$bar;\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php echo \\\"hello world\\\"; ?>\\n\"\n            + \"<?php\\n\"\n            + \"$foo = \\\"hello \\\"; $bar = \\\"world\\\";\\n\"\n            + \"print $foo.$bar;\");\n    },\n\n    \"test beautify tag whitepace\": function() {\n        var s = new EditSession([\n            \"<form   id=\\\"\\\"   action = \\\"\\\"   method=\\\"get\\\"  >\",\n            \"\\t<br   />\",\n            \"</form  >\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<form id=\\\"\\\" action=\\\"\\\" method=\\\"get\\\">\\n\"\n            + \"\\t<br />\\n\"\n            + \"</form>\");\n    },\n\n    \"test beautify css in php\": function() {\n        var s = new EditSession([\n            \"<style>h1{font-size: 20px;}p{font-size:14px; padding:10px;}</style>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<style>\\n\"\n            + \"\\th1 {\\n\"\n            + \"\\t\\tfont-size: 20px;\\n\"\n            + \"\\t}\\n\"\n            + \"\\n\"\n            + \"\\tp {\\n\"\n            + \"\\t\\tfont-size: 14px;\\n\"\n            + \"\\t\\tpadding: 10px;\\n\"\n            + \"\\t}\\n\"\n            + \"</style>\");\n    },\n    \n    \"test beautify css\": function() {\n        var s = new EditSession(\"\", new CSSMode());\n        s.setUseSoftTabs(true);\n        s.setValue(\".x    y:h{    animation: appear 1.5s ease-in-out     ease-in-out;     border:  solid    red;}\");\n        \n        beautify.beautify(s);\n        assert.equal(s.getValue(), \".x y:h {\\n\"\n            + \"    animation: appear 1.5s ease-in-out ease-in-out;\\n\"\n            + \"    border: solid red;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify comments\": function() {\n        var s = new EditSession([\n            \"<?php\\n\",\n            \"if(true) //break me\\n\",\n            \"{}\\n\",\n            \"?>\\n\",\n            \"<!--\\n\",\n            \"\\thello\\n\",\n            \"\\t\\tworld\\n\",\n            \"-->\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"if (true) //break me\\n\"\n            + \"{}\\n\"\n            + \"?>\\n\"\n            + \"<!--\\n\"\n            + \"\\thello\\n\"\n            + \"\\t\\tworld\\n\"\n            + \"-->\");\n    },\n\n    \"test beautify js array of objects\": function() {\n        var s = new EditSession([\n            \"<script>\\n\",\n            \"var foo = [\",\n            \"\\t{ \\n\",\n            \"\\t\\tbar: \\\"hello\\\", \\n\",\n            \"\\t\\tbar2: {}\\n\",\n            \"\\t},{\\n\",\n            \"\\t\\t\\\"bar\\\": true\\n\",\n            \"\\t}\\n\",\n            \"];\\n\",\n            \"</script>\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<script>\\n\"\n            + \"\\tvar foo = [{\\n\"\n            + \"\\t\\tbar: \\\"hello\\\",\\n\"\n            + \"\\t\\tbar2: {}\\n\"\n            + \"\\t}, {\\n\"\n            + \"\\t\\t\\\"bar\\\": true\\n\"\n            + \"\\t}];\\n\"\n            + \"</script>\");\n    },\n\n    \"test beautify js object\": function() {\n        var s = new EditSession([\n            '<script>{\"a\": \"1\", \"b\": \"2\"}</script>'\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<script>\\n\"\n            + \"\\t{\\n\"\n            + \"\\t\\t\\\"a\\\": \\\"1\\\",\\n\"\n            + \"\\t\\t\\\"b\\\": \\\"2\\\"\\n\"\n            + \"\\t}\\n\"\n            + \"</script>\");\n    },\n\n    \"test beautify php default behaviour with line breaks after comma\": function() {\n        var s = new EditSession([\n            \"<?php\\n\",\n            \"class Test {\",\n            \"public int $id, $num;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"class Test {\\n\"\n            + \"\\tpublic int $id,\\n\" \n            + \"\\t$num;\\n\"\n            + \"}\");\n    },\n\n    \"test beautify php with no line breaks after comma\": function() {\n        var s = new EditSession([\n            \"<?php\\n\",\n            \"class Test {\",\n            \"public int $id, $num;\",\n            \"}\"\n        ], new PHPMode());\n        s.setUseSoftTabs(false);\n\n        beautify.formatOptions.lineBreaksAfterCommasInCurlyBlock = false;\n        beautify.beautify(s);\n        assert.equal(s.getValue(), \"<?php\\n\"\n            + \"class Test {\\n\"\n            + \"\\tpublic int $id, $num;\\n\"\n            + \"}\");\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/code_lens.js",
    "content": "/**\n * ## Code Lens extension.\n *\n * Displaying contextual information and clickable commands above code lines. Supports registering custom providers,\n * rendering lens widgets with proper positioning and styling, and handling user interactions with lens commands.\n * @module\n */\n\n\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n * @typedef {import(\"../virtual_renderer\").VirtualRenderer & {$textLayer: import(\"../layer/text\").Text &{$lenses: HTMLElement[]}}} VirtualRenderer\n * @typedef {import(\"../../ace-internal\").Ace.CodeLenseCommand} CodeLenseCommand\n * @typedef {import(\"../../ace-internal\").Ace.CodeLense} CodeLense\n */\n\nvar event = require(\"../lib/event\");\nvar lang = require(\"../lib/lang\");\nvar dom = require(\"../lib/dom\");\n\n/**\n * Clears all code lens elements from the renderer\n * @param {VirtualRenderer} renderer The renderer to clear lens elements from\n */\nfunction clearLensElements(renderer) {\n    var textLayer = renderer.$textLayer;\n    /** @type {HTMLElement[]} */\n    var lensElements = textLayer.$lenses;\n    if (lensElements)\n        lensElements.forEach(function(el) {el.remove(); });\n    textLayer.$lenses = null;\n}\n\n/**\n * Renders code lens widgets based on changes to the editor\n * @param {number} changes Bitmask of change types\n * @param {VirtualRenderer} renderer The renderer to update\n */\nfunction renderWidgets(changes, renderer) {\n    var changed = changes & renderer.CHANGE_LINES\n        || changes & renderer.CHANGE_FULL\n        || changes & renderer.CHANGE_SCROLL\n        || changes & renderer.CHANGE_TEXT;\n    if (!changed)\n        return;\n\n    var session = renderer.session;\n    var lineWidgets = renderer.session.lineWidgets;\n    var textLayer = renderer.$textLayer;\n    var lensElements = textLayer.$lenses;\n    if (!lineWidgets) {\n        if (lensElements)\n            clearLensElements(renderer);\n        return;\n    }\n\n    var textCells = renderer.$textLayer.$lines.cells;\n    var config = renderer.layerConfig;\n    var padding = renderer.$padding;\n\n    if (!lensElements)\n        lensElements = textLayer.$lenses = [];\n\n\n    var index = 0;\n    for (var i = 0; i < textCells.length; i++) {\n        var row = textCells[i].row;\n        var widget = lineWidgets[row];\n        var lenses = widget && widget.lenses;\n\n        if (!lenses || !lenses.length) continue;\n\n        var lensContainer = lensElements[index];\n        if (!lensContainer) {\n            lensContainer = lensElements[index]\n                = dom.buildDom([\"div\", {class: \"ace_codeLens\"}], renderer.container);\n        }\n        lensContainer.style.height = config.lineHeight + \"px\";\n        index++;\n\n        for (var j = 0; j < lenses.length; j++) {\n            var el = lensContainer.childNodes[2 * j];\n            if (!el) {\n                if (j != 0) lensContainer.appendChild(dom.createTextNode(\"\\xa0|\\xa0\"));\n                el = dom.buildDom([\"a\"], lensContainer);\n            }\n            el.textContent = lenses[j].title;\n            /** @type {HTMLElement & { lensCommand : CodeLenseCommand}} */\n            (el).lensCommand = lenses[j];\n        }\n        while (lensContainer.childNodes.length > 2 * j - 1)\n            lensContainer.lastChild.remove();\n\n        var top = renderer.$cursorLayer.getPixelPosition({\n            row: row,\n            column: 0\n        }, true).top - config.lineHeight * widget.rowsAbove - config.offset;\n        lensContainer.style.top = top + \"px\";\n\n        var left = renderer.gutterWidth;\n        var indent = session.getLine(row).search(/\\S|$/);\n        if (indent == -1)\n            indent = 0;\n        left += indent * config.characterWidth;\n        lensContainer.style.paddingLeft = padding + left + \"px\";\n    }\n    while (index < lensElements.length)\n        lensElements.pop().remove();\n}\n\n/**\n * Clears all code lens widgets from the session\n * @param {EditSession} session The session to clear code lens widgets from\n */\nfunction clearCodeLensWidgets(session) {\n    if (!session.lineWidgets) return;\n    var widgetManager = session.widgetManager;\n    session.lineWidgets.forEach(function(widget) {\n        if (widget && widget.lenses)\n            widgetManager.removeLineWidget(widget);\n    });\n}\n\n/**\n * Sets code lenses for the given session\n * @param {EditSession} session The session to set code lenses for\n * @param {import(\"../../ace-internal\").Ace.CodeLense[]} lenses Array of code lenses to set\n * @return {number} The row of the first code lens or Number.MAX_VALUE if no lenses\n */\nexports.setLenses = function(session, lenses) {\n    var firstRow = Number.MAX_VALUE;\n\n    clearCodeLensWidgets(session);\n    lenses && lenses.forEach(function(lens) {\n        var row = lens.start.row;\n        var column = lens.start.column;\n        var widget = session.lineWidgets && session.lineWidgets[row];\n        if (!widget || !widget.lenses) {\n            widget = session.widgetManager.$registerLineWidget({\n                rowCount: 1,\n                rowsAbove: 1,\n                row: row,\n                column: column,\n                lenses: []\n            });\n        }\n        widget.lenses.push(lens.command);\n        if (row < firstRow)\n            firstRow = row;\n    });\n    session._emit(\"changeFold\", {data: {start: {row: firstRow}}});\n    return firstRow;\n};\n\n/**\n * Attaches code lens functionality to an editor\n * @param {import(\"../editor\").Editor} editor The editor to attach to\n */\nfunction attachToEditor(editor) {\n    editor.codeLensProviders = [];\n    editor.renderer.on(\"afterRender\", renderWidgets);\n    if (!editor.$codeLensClickHandler) {\n        editor.$codeLensClickHandler = function(e) {\n            /** @type {CodeLenseCommand} */\n            var command = e.target.lensCommand;\n            if (!command) return;\n            editor.execCommand(command.id, command.arguments);\n            editor._emit(\"codeLensClick\", e);\n        };\n        event.addListener(editor.container, \"click\", editor.$codeLensClickHandler, editor);\n    }\n    editor.$updateLenses = function() {\n        var session = editor.session;\n        if (!session) return;\n\n        var providersToWaitNum = editor.codeLensProviders.length;\n        var lenses = [];\n        editor.codeLensProviders.forEach(function(provider) {\n            provider.provideCodeLenses(session, function(err, payload) {\n                if (err) return;\n                payload.forEach(function(lens) {\n                    lenses.push(lens);\n                });\n                providersToWaitNum--;\n                if (providersToWaitNum == 0) {\n                    applyLenses();\n                }\n            });\n        });\n\n        function applyLenses() {\n            var cursor = session.selection.cursor;\n            var oldRow = session.documentToScreenRow(cursor);\n            var scrollTop = session.getScrollTop();\n            var firstRow = exports.setLenses(session, lenses);\n\n            var lastDelta = session.$undoManager && session.$undoManager.$lastDelta;\n            if (lastDelta && lastDelta.action == \"remove\" && lastDelta.lines.length > 1)\n                return;\n            var row = session.documentToScreenRow(cursor);\n            var lineHeight = editor.renderer.layerConfig.lineHeight;\n            var top = session.getScrollTop() + (row - oldRow) * lineHeight;\n            // special case for the lens on line 0, because it can't be scrolled into view with keyboard\n            if (firstRow == 0 && scrollTop < lineHeight /4 && scrollTop > -lineHeight/4) {\n                top = -lineHeight;\n            }\n            session.setScrollTop(top);\n        }\n    };\n    var updateLenses = lang.delayedCall(editor.$updateLenses);\n    editor.$updateLensesOnInput = function() {\n        updateLenses.delay(250);\n    };\n    editor.on(\"input\", editor.$updateLensesOnInput);\n}\n\n/**\n * Detaches code lens functionality from an editor\n * @param {import(\"../editor\").Editor} editor The editor to detach from\n */\nfunction detachFromEditor(editor) {\n    editor.off(\"input\", editor.$updateLensesOnInput);\n    editor.renderer.off(\"afterRender\", renderWidgets);\n    if (editor.$codeLensClickHandler)\n        editor.container.removeEventListener(\"click\", editor.$codeLensClickHandler);\n}\n\n/**\n * Registers a code lens provider with an editor\n * @param {import(\"../editor\").Editor} editor The editor to register the provider with\n * @param {import(\"../../ace-internal\").Ace.CodeLenseProvider} codeLensProvider The provider to register\n */\nexports.registerCodeLensProvider = function(editor, codeLensProvider) {\n    editor.setOption(\"enableCodeLens\", true);\n    editor.codeLensProviders.push(codeLensProvider);\n    editor.$updateLensesOnInput();\n};\n\n/**\n * Clears all code lenses from the session\n * @param {EditSession} session The session to clear code lenses from\n */\nexports.clear = function(session) {\n    exports.setLenses(session, null);\n};\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    enableCodeLens: {\n        set: function(val) {\n            if (val) {\n                attachToEditor(this);\n            } else {\n                detachFromEditor(this);\n            }\n        }\n    }\n});\n\ndom.importCssString(`\n.ace_codeLens {\n    position: absolute;\n    color: #aaa;\n    font-size: 88%;\n    background: inherit;\n    width: 100%;\n    display: flex;\n    align-items: flex-end;\n    pointer-events: none;\n}\n.ace_codeLens > a {\n    cursor: pointer;\n    pointer-events: auto;\n}\n.ace_codeLens > a:hover {\n    color: #0000ff;\n    text-decoration: underline;\n}\n.ace_dark > .ace_codeLens > a:hover {\n    color: #4e94ce;\n}\n`, \"codelense.css\", false);\n"
  },
  {
    "path": "src/ext/code_lens_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar ace = require(\"../ace\");\nvar codeLens = require(\"./code_lens\");\nvar assert = require(\"../test/assertions\");\nvar lang = require(\"../lib/lang\");\n\nrequire(\"./error_marker\");\n\nfunction click(node) {\n    node.dispatchEvent(new window.CustomEvent(\"click\", {bubbles: true}));\n}\n\nvar editor = null;\nmodule.exports = {\n    setUp: function() {\n        if (editor)\n            editor.destroy();\n        var el = document.createElement(\"div\");\n\n        el.style.left = \"20px\";\n        el.style.top = \"30px\";\n        el.style.width = \"300px\";\n        el.style.height = \"100px\";\n        document.body.appendChild(el);\n        editor = ace.edit(el);\n        editor.on(\"destroy\", function() {\n            document.body.removeChild(el);\n        });\n    },\n    tearDown: function() {\n        editor && editor.destroy();\n        editor = null;\n    },\n\n    \"test code lens\": function() {\n        editor.session.setValue(\"a\\nb|c\\nd\" + \"\\n\".repeat(100) + \"\\txxx\");\n\n        var commandId = \"codeLensAction\";\n        var called = null;\n        editor.commands.addCommand({\n            name: commandId,\n            exec: function(editor, args) {\n                called = args;\n            }\n        });\n\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: function(session, callback) {\n                callback(null, [{\n                    start: {\n                        row: 1\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"1\",\n                        arguments: \"line\"\n                    }\n                }, {\n                    start: {\n                        row: 1\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"2\",\n                        arguments: \"column\"\n                    }\n                }, {\n                    start: {\n                        row: session.getLength() - 1\n                    },\n                    command: {\n                        id: commandId,\n                        title: \"last\",\n                        arguments: \"last\"\n                    }\n                }]);\n            }\n        });\n        editor.$updateLenses();\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"1\\xa0|\\xa02\");\n        assert.equal(lens.childNodes.length, 3);\n        click(lens.childNodes[0]);\n        assert.equal(called, \"line\");\n        click(lens.childNodes[2]);\n        assert.equal(called, \"column\");\n\n        // Scroll down so that first lines go beyond the viewport\n        editor.gotoLine(10);\n        editor.renderer.$loop._flush();\n        lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.ok(!lens);\n\n        editor.gotoLine(200);\n        editor.renderer.$loop._flush();\n        lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"last\");\n\n        editor.setSession(ace.createEditSession(\"\\n\".repeat(100)));\n        editor.renderer.$loop._flush();\n        lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.ok(!lens);\n    },\n\n    \"test async code lens\": async function(next) {\n        editor.session.setValue(\"a\\nb\\nc\");\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: async function (session, callback) {\n                await lang.sleep(0);\n                callback(null, [\n                    {\n                        start: {row: 1},\n                        command: {title: \"code lens\"}\n                    }\n                ]);\n            }\n        });\n        editor.$updateLenses();\n        await lang.sleep(0);\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"code lens\");\n        next();\n    },\n\n    \"test multiple code lens providers\": async function(next) {\n        editor.session.setValue(\"a\\nb\\nc\\nd\");\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: function (session, callback) {\n                callback(null, [\n                    {\n                        start: {row: 1},\n                        command: {title: \"1\"}\n                    }\n                ]);\n            }\n        });\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: async function (session, callback) {\n                await lang.sleep(0);\n                callback(null, [\n                    {\n                        start: {row: 2},\n                        command: {title: \"2\"}\n                    }\n                ]);\n            }\n        });\n        editor.$updateLenses();\n        await lang.sleep(0);\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelectorAll(\".ace_codeLens\");\n        assert.equal(lens[0].textContent, \"1\");\n        assert.equal(lens[1].textContent, \"2\");\n        next();\n    },\n\n    \"test multiple code lens providers on the same line\": function() {\n        editor.session.setValue(\"a\\nb\\nc\");\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: function(session, callback) {\n                callback(null, [{\n                    start: { row: 1 },\n                    command: { title: \"1\" }\n                }]);\n            }\n        });\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: function(session, callback) {\n                callback(null, [{\n                    start: { row: 1 },\n                    command: { title: \"2\" }\n                }]);\n            }\n        });\n        editor.$updateLenses();\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"1\\xa0|\\xa02\");\n    },\n\n    \"test code lens behavior with multiple sessions\": function() {\n        editor.session.setValue(\"a\\nb\");\n        codeLens.registerCodeLensProvider(editor, {\n            provideCodeLenses: function(session, callback) {\n                callback(null, [{\n                    start: { row: 1 },\n                    command: { title: session.doc.$lines[0] }\n                }]);\n            }\n        });\n        editor.$updateLenses();\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"a\");\n\n        editor.setSession(ace.createEditSession(\"c\\nd\"));\n        editor.$updateLenses();\n        editor.renderer.$loop._flush();\n        var lens = editor.container.querySelector(\".ace_codeLens\");\n        assert.equal(lens.textContent, \"c\");\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/command_bar.js",
    "content": "/**\n * ## Command Bar extension.\n *\n * Provides an interactive command bar tooltip that displays above the editor's active line. The extension enables\n * clickable commands with keyboard shortcuts, icons, and various button types including standard buttons, checkboxes,\n * and text elements. Supports overflow handling with a secondary tooltip for additional commands when space is limited.\n * The tooltip can be configured to always show or display only on mouse hover over the active line.\n *\n * @module\n */\n\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n * @typedef {import(\"../../ace-internal\").Ace.TooltipCommand} TooltipCommand\n */\nvar Tooltip = require(\"../tooltip\").Tooltip;\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar lang = require(\"../lib/lang\");\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar useragent = require(\"../lib/useragent\");\n\nvar BUTTON_CLASS_NAME = 'command_bar_tooltip_button';\nvar VALUE_CLASS_NAME = 'command_bar_button_value';\nvar CAPTION_CLASS_NAME = 'command_bar_button_caption';\nvar KEYBINDING_CLASS_NAME = 'command_bar_keybinding';\nvar TOOLTIP_CLASS_NAME = 'command_bar_tooltip';\nvar MORE_OPTIONS_BUTTON_ID = 'MoreOptionsButton';\n\nvar defaultDelay = 100;\nvar defaultMaxElements = 4;\n\nvar minPosition = function (posA, posB) {\n    if (posB.row > posA.row) {\n        return posA;\n    } else if (posB.row === posA.row && posB.column > posA.column) {\n        return posA;\n    }\n    return posB;\n};\n\nvar keyDisplayMap = {\n    \"Ctrl\": { mac: \"^\"},\n    \"Option\": { mac: \"⌥\"},\n    \"Command\": { mac: \"⌘\"},\n    \"Cmd\": { mac: \"⌘\"},\n    \"Shift\": \"⇧\",\n    \"Left\": \"←\",\n    \"Right\": \"→\",\n    \"Up\": \"↑\",\n    \"Down\": \"↓\"\n};\n\n\n/**\n * Displays a command tooltip above the currently active line selection, with clickable elements.\n *\n * Internally it is a composite of two tooltips, one for the main tooltip and one for the \n * overflowing commands.\n * The commands are added sequentially in registration order.\n * When attached to an editor, it is either always shown or only when the active line is hovered\n * with mouse, depending on the alwaysShow property.\n */\nclass CommandBarTooltip {\n    /**\n     * @param {HTMLElement} parentNode\n     * @param {Partial<import(\"../../ace-internal\").Ace.CommandBarOptions>} [options]\n     */\n    constructor(parentNode, options) {\n        options = options || {};\n        this.parentNode = parentNode;\n        this.tooltip = new Tooltip(this.parentNode);\n        this.moreOptions = new Tooltip(this.parentNode);\n        this.maxElementsOnTooltip = options.maxElementsOnTooltip || defaultMaxElements;\n        this.$alwaysShow = options.alwaysShow || false;\n        this.eventListeners = {};\n        this.elements = {};\n        this.commands = {};\n\n        this.tooltipEl = dom.buildDom(['div', { class: TOOLTIP_CLASS_NAME }], this.tooltip.getElement());\n        this.moreOptionsEl = dom.buildDom(['div', { class: TOOLTIP_CLASS_NAME + \" tooltip_more_options\" }], this.moreOptions.getElement());\n\n        this.$showTooltipTimer = lang.delayedCall(this.$showTooltip.bind(this), options.showDelay || defaultDelay);\n        this.$hideTooltipTimer = lang.delayedCall(this.$hideTooltip.bind(this), options.hideDelay || defaultDelay);\n        this.$tooltipEnter = this.$tooltipEnter.bind(this);\n        this.$onMouseMove = this.$onMouseMove.bind(this);\n        this.$onChangeScroll = this.$onChangeScroll.bind(this);\n        this.$onEditorChangeSession = this.$onEditorChangeSession.bind(this);\n        this.$scheduleTooltipForHide = this.$scheduleTooltipForHide.bind(this);\n        this.$preventMouseEvent = this.$preventMouseEvent.bind(this);\n\n        for (var event of [\"mousedown\", \"mouseup\", \"click\"]) {\n            this.tooltip.getElement().addEventListener(event, this.$preventMouseEvent);\n            this.moreOptions.getElement().addEventListener(event, this.$preventMouseEvent);\n        }\n    }\n\n    /**\n     * Registers a command on the command bar tooltip.\n     * \n     * The commands are added in sequential order. If there is not enough space on the main\n     * toolbar, the remaining elements are added to the overflow menu.\n     * \n     * @param {string} id      \n     * @param {TooltipCommand} command\n     */\n    registerCommand(id, command) {\n        var registerForMainTooltip = Object.keys(this.commands).length < this.maxElementsOnTooltip;\n        if (!registerForMainTooltip && !this.elements[MORE_OPTIONS_BUTTON_ID]) {\n            this.$createCommand(MORE_OPTIONS_BUTTON_ID, {\n                name: \"···\",\n                exec: \n                /**\n                 * @this {CommandBarTooltip}\n                 */\n                function() {\n                    this.$shouldHideMoreOptions = false;\n                    this.$setMoreOptionsVisibility(!this.isMoreOptionsShown());\n                }.bind(this),\n                type: \"checkbox\",\n                getValue: function() {\n                    return this.isMoreOptionsShown();\n                }.bind(this),\n                enabled: true\n            }, true);\n        }\n        this.$createCommand(id, command, registerForMainTooltip);\n        if (this.isShown()) {\n            this.updatePosition();\n        }\n    }\n\n    isShown() {\n        return !!this.tooltip && this.tooltip.isOpen;\n    }\n\n    isMoreOptionsShown() {\n        return !!this.moreOptions && this.moreOptions.isOpen;\n    }\n\n    getAlwaysShow() {\n        return this.$alwaysShow;\n    }\n\n    /**\n     * Sets the display mode of the tooltip\n     * \n     * When true, the tooltip is always displayed while it is attached to an editor.\n     * When false, the tooltip is displayed only when the mouse hovers over the active editor line.\n     * \n     * @param {boolean} alwaysShow\n     */\n    setAlwaysShow(alwaysShow) {\n        this.$alwaysShow = alwaysShow;\n        this.$updateOnHoverHandlers(!this.$alwaysShow);\n        this._signal(\"alwaysShow\", this.$alwaysShow);\n    }\n\n    /**\n     * Attaches the clickable command bar tooltip to an editor\n     * \n     * Depending on the alwaysShow parameter it either displays the tooltip immediately,\n     * or subscribes to the necessary events to display the tooltip on hover.\n     * \n     * @param {Editor} editor\n     */\n    attach(editor) {\n        if (!editor || (this.isShown() && this.editor === editor)) {\n            return;\n        }\n\n        this.detach();\n\n        this.editor = editor;\n        this.editor.on(\"changeSession\", this.$onEditorChangeSession);\n        if (this.editor.session) {\n            this.editor.session.on(\"changeScrollLeft\", this.$onChangeScroll);\n            this.editor.session.on(\"changeScrollTop\", this.$onChangeScroll);\n        }\n\n        if (this.getAlwaysShow()) {\n            this.$showTooltip();\n        } else {\n            this.$updateOnHoverHandlers(true);\n        }\n    }\n\n    /**\n     * Updates the position of the command bar tooltip. It aligns itself above the active line in the editor.\n     */\n    updatePosition() {\n        if (!this.editor) {\n            return;\n        }\n        var renderer = this.editor.renderer;\n\n        var ranges;\n        if (this.editor.selection.getAllRanges) {\n            ranges = this.editor.selection.getAllRanges();\n        } else {\n            ranges = [this.editor.getSelectionRange()];\n        }\n        if (!ranges.length) {\n            return;\n        }\n        var minPos = minPosition(ranges[0].start, ranges[0].end);\n        for (var i = 0, range; range = ranges[i]; i++) {\n            minPos = minPosition(minPos, minPosition(range.start, range.end));\n        }\n\n        var pos = renderer.$cursorLayer.getPixelPosition(minPos, true);\n\n        var tooltipEl = this.tooltip.getElement();\n        var screenWidth = window.innerWidth;\n        var screenHeight = window.innerHeight;\n        var rect = this.editor.container.getBoundingClientRect();\n\n        pos.top += rect.top - renderer.layerConfig.offset;\n        pos.left += rect.left + renderer.gutterWidth - renderer.scrollLeft;\n\n        var cursorVisible = pos.top >= rect.top && pos.top <= rect.bottom &&\n            pos.left >= rect.left + renderer.gutterWidth && pos.left <= rect.right;\n\n        if (!cursorVisible && this.isShown()) {\n            this.$hideTooltip();\n            return;\n        } else if (cursorVisible && !this.isShown() && this.getAlwaysShow()) {\n            this.$showTooltip();\n            return;\n        }\n\n        var top = pos.top - tooltipEl.offsetHeight;\n        var left = Math.min(screenWidth - tooltipEl.offsetWidth, pos.left);\n\n        var tooltipFits = top >= 0 && top + tooltipEl.offsetHeight <= screenHeight &&\n            left >= 0 && left + tooltipEl.offsetWidth <= screenWidth;\n\n        if (!tooltipFits) {\n            this.$hideTooltip();\n            return;\n        }\n\n        this.tooltip.setPosition(left, top);\n\n        if (this.isMoreOptionsShown()) {\n            top = top + tooltipEl.offsetHeight;\n            left = this.elements[MORE_OPTIONS_BUTTON_ID].getBoundingClientRect().left;\n    \n            var moreOptionsEl = this.moreOptions.getElement();\n            var screenHeight = window.innerHeight;\n            if (top + moreOptionsEl.offsetHeight > screenHeight) {\n                top -= tooltipEl.offsetHeight + moreOptionsEl.offsetHeight;\n            }\n            if (left + moreOptionsEl.offsetWidth > screenWidth) {\n                left = screenWidth - moreOptionsEl.offsetWidth;\n            }\n            \n            this.moreOptions.setPosition(left, top);\n        }\n    }\n\n    /**\n     * Updates each command element in the tooltip. \n     * \n     * This is automatically called on certain events, but can be called manually as well.\n     */\n    update() {\n        Object.keys(this.elements).forEach(this.$updateElement.bind(this));\n    }\n\n    /**\n     * Detaches the tooltip from the editor.\n     */\n    detach() {\n        this.tooltip.hide();\n        this.moreOptions.hide();\n        this.$updateOnHoverHandlers(false);\n        if (this.editor) {\n            this.editor.off(\"changeSession\", this.$onEditorChangeSession);\n            if (this.editor.session) {\n                this.editor.session.off(\"changeScrollLeft\", this.$onChangeScroll);\n                this.editor.session.off(\"changeScrollTop\", this.$onChangeScroll);\n            }\n        }\n        this.$mouseInTooltip = false;\n        this.editor = null;\n    }\n\n    destroy() {\n        if (this.tooltip && this.moreOptions) {\n            this.detach();\n            this.tooltip.destroy();\n            this.moreOptions.destroy();\n        }\n        this.eventListeners = {};\n        this.commands = {};\n        this.elements = {};\n        this.tooltip = this.moreOptions = this.parentNode = null;\n    }\n\n    /**\n     * @param {string} id\n     * @param {TooltipCommand} command\n     * @param {boolean} forMainTooltip\n     */\n    $createCommand(id, command, forMainTooltip) {\n        var parentEl = forMainTooltip ? this.tooltipEl : this.moreOptionsEl;\n        var keyParts = [];\n        var bindKey = command.bindKey;\n        if (bindKey) {\n            if (typeof bindKey === 'object') {\n                bindKey = useragent.isMac ? bindKey.mac : bindKey.win;\n            }\n            bindKey = bindKey.split(\"|\")[0];\n            keyParts = bindKey.split(\"-\");\n            \n            keyParts = keyParts.map(function(key) {\n                if (keyDisplayMap[key]) {\n                    if (typeof keyDisplayMap[key] === 'string') {\n                        return keyDisplayMap[key];\n                    } else if (useragent.isMac && keyDisplayMap[key].mac) {\n                        return keyDisplayMap[key].mac;\n                    }\n                }\n                return key;\n            });\n        }\n\n        /**@type {any[]} */\n        var buttonNode;\n        if (forMainTooltip && command.iconCssClass) {\n            //Only support icon button for main tooltip, otherwise fall back to text button\n            buttonNode = [\n                'div',\n                {\n                     class: [\"ace_icon_svg\", command.iconCssClass].join(\" \"),\n                     \"aria-label\": command.name + \" (\" + command.bindKey + \")\"\n                }\n            ];\n        } else {\n            buttonNode = [\n                ['div', { class: VALUE_CLASS_NAME }],\n                ['div', { class: CAPTION_CLASS_NAME }, command.name]\n            ];\n            if (keyParts.length) {\n                buttonNode.push(\n                    [\n                        'div',\n                        { class: KEYBINDING_CLASS_NAME },\n                        keyParts.map(function(keyPart) {\n                            return ['div', keyPart];\n                        }) \n                    ]\n                );\n            }\n        }\n\n        // @ts-ignore\n        dom.buildDom(['div', { class: [BUTTON_CLASS_NAME, command.cssClass || \"\"].join(\" \"), ref: id }, buttonNode], parentEl, this.elements);\n        this.commands[id] = command;\n        \n        var eventListener =\n            /**\n             * @this {CommandBarTooltip}\n             */\n            function(e) {\n            if (this.editor) {\n                this.editor.focus();\n            }\n            // Internal variable to properly handle when the more options button is clicked\n            this.$shouldHideMoreOptions = this.isMoreOptionsShown();\n            if (!this.elements[id].disabled && command.exec) {\n                command.exec(this.editor);\n            }\n            if (this.$shouldHideMoreOptions) {\n                this.$setMoreOptionsVisibility(false);\n            }\n            this.update();\n            e.preventDefault();\n        }.bind(this);\n        this.eventListeners[id] = eventListener;\n        this.elements[id].addEventListener('click', eventListener.bind(this));\n        this.$updateElement(id);\n    }\n\n    /**\n     * @param {boolean} visible\n     */\n    $setMoreOptionsVisibility(visible) {\n        if (visible) {\n            this.moreOptions.setTheme(this.editor.renderer.theme);\n            this.moreOptions.setClassName(TOOLTIP_CLASS_NAME + \"_wrapper\");\n            this.moreOptions.show();\n            this.update();\n            this.updatePosition();\n        } else {\n            this.moreOptions.hide();\n        }\n    }\n\n    $onEditorChangeSession(e) {\n        if (e.oldSession) {\n            e.oldSession.off(\"changeScrollTop\", this.$onChangeScroll);\n            e.oldSession.off(\"changeScrollLeft\", this.$onChangeScroll);\n        }\n        this.detach();\n    }\n\n    $onChangeScroll() {\n        if (this.editor.renderer && (this.isShown() || this.getAlwaysShow())) {\n            this.editor.renderer.once(\"afterRender\", this.updatePosition.bind(this));\n        }\n    }\n\n    $onMouseMove(e) {\n        if (this.$mouseInTooltip) {\n            return;\n        }\n        var cursorPosition = this.editor.getCursorPosition();\n        var cursorScreenPosition = this.editor.renderer.textToScreenCoordinates(cursorPosition.row, cursorPosition.column);\n        var lineHeight = this.editor.renderer.lineHeight;\n        \n        var isInCurrentLine = e.clientY >= cursorScreenPosition.pageY && e.clientY < cursorScreenPosition.pageY + lineHeight;\n\n        if (isInCurrentLine) {\n            if (!this.isShown() && !this.$showTooltipTimer.isPending()) {\n                this.$showTooltipTimer.delay();\n            }\n            if (this.$hideTooltipTimer.isPending()) {\n                this.$hideTooltipTimer.cancel();\n            }\n        } else {\n            if (this.isShown() && !this.$hideTooltipTimer.isPending()) {\n                this.$hideTooltipTimer.delay();\n            }\n            if (this.$showTooltipTimer.isPending()) {\n                this.$showTooltipTimer.cancel();\n            }\n        }\n    }\n\n    $preventMouseEvent(e) {\n        if (this.editor) {\n            this.editor.focus();\n        }\n        e.preventDefault();\n    }\n    \n    $scheduleTooltipForHide() {\n        this.$mouseInTooltip = false;\n        this.$showTooltipTimer.cancel();\n        this.$hideTooltipTimer.delay();\n    }\n\n    $tooltipEnter() {\n        this.$mouseInTooltip = true;\n        if (this.$showTooltipTimer.isPending()) {\n            this.$showTooltipTimer.cancel();\n        }\n        if (this.$hideTooltipTimer.isPending()) {\n            this.$hideTooltipTimer.cancel();\n        }\n    }\n\n    /**\n     * @param {boolean} [enableHover]\n     */\n    $updateOnHoverHandlers(enableHover) {\n        var tooltipEl = this.tooltip.getElement();\n        var moreOptionsEl = this.moreOptions.getElement();\n        if (enableHover) {\n            if (this.editor) {\n                this.editor.on(\"mousemove\", this.$onMouseMove);\n                this.editor.renderer.getMouseEventTarget().addEventListener(\"mouseout\", this.$scheduleTooltipForHide, true);\n            }\n            tooltipEl.addEventListener('mouseenter', this.$tooltipEnter);\n            tooltipEl.addEventListener('mouseleave', this.$scheduleTooltipForHide);\n            moreOptionsEl.addEventListener('mouseenter', this.$tooltipEnter);\n            moreOptionsEl.addEventListener('mouseleave', this.$scheduleTooltipForHide);\n        } else {\n            if (this.editor) {\n                this.editor.off(\"mousemove\", this.$onMouseMove);\n                this.editor.renderer.getMouseEventTarget().removeEventListener(\"mouseout\", this.$scheduleTooltipForHide, true);\n            }\n            tooltipEl.removeEventListener('mouseenter', this.$tooltipEnter);\n            tooltipEl.removeEventListener('mouseleave', this.$scheduleTooltipForHide);\n            moreOptionsEl.removeEventListener('mouseenter', this.$tooltipEnter);\n            moreOptionsEl.removeEventListener('mouseleave', this.$scheduleTooltipForHide);\n        }\n    }\n\n    $showTooltip() {\n        if (this.isShown()) {\n            return;\n        }\n        this.tooltip.setTheme(this.editor.renderer.theme);\n        this.tooltip.setClassName(TOOLTIP_CLASS_NAME + \"_wrapper\");\n        this.tooltip.show();\n        this.update();\n        this.updatePosition();\n        this._signal(\"show\");\n    }\n    $hideTooltip() {\n        this.$mouseInTooltip = false;\n        if (!this.isShown()) {\n            return;\n        }\n        this.moreOptions.hide();\n        this.tooltip.hide();\n        this._signal(\"hide\");\n    }\n\n    /**\n     * @param {string} id\n     */\n    $updateElement(id) {\n        var command = this.commands[id];\n        if (!command) {\n            return;\n        }\n        var el = this.elements[id];\n        var commandEnabled = command.enabled;\n        \n        if (typeof commandEnabled === 'function') {\n            commandEnabled = commandEnabled(this.editor);\n        }\n\n        if (typeof command.getValue === 'function') {\n            var value = command.getValue(this.editor);\n            if (command.type === 'text') {\n                el.textContent = value;\n            } else if (command.type === 'checkbox') {\n                var domCssFn = value ? dom.addCssClass : dom.removeCssClass;\n                var isOnTooltip = el.parentElement === this.tooltipEl;\n                el.ariaChecked = value;\n                if (isOnTooltip) {\n                    domCssFn(el, \"ace_selected\");\n                } else {\n                    el = el.querySelector(\".\" + VALUE_CLASS_NAME);\n                    domCssFn(el, \"ace_checkmark\");\n                }\n            }\n        }\n\n        if (commandEnabled && el.disabled) {\n            dom.removeCssClass(el, \"ace_disabled\");\n            el.ariaDisabled = el.disabled = false;\n            el.removeAttribute(\"disabled\");\n        } else if (!commandEnabled && !el.disabled) {\n            dom.addCssClass(el, \"ace_disabled\");\n            el.ariaDisabled = el.disabled = true;\n            el.setAttribute(\"disabled\", \"\");\n        }\n    }\n}\n\noop.implement(CommandBarTooltip.prototype, EventEmitter);\n\ndom.importCssString(`\n.ace_tooltip.${TOOLTIP_CLASS_NAME}_wrapper {\n    padding: 0;\n}\n\n.ace_tooltip .${TOOLTIP_CLASS_NAME} {\n    padding: 1px 5px;\n    display: flex;\n    pointer-events: auto;\n}\n\n.ace_tooltip .${TOOLTIP_CLASS_NAME}.tooltip_more_options {\n    padding: 1px;\n    flex-direction: column;\n}\n\ndiv.${BUTTON_CLASS_NAME} {\n    display: inline-flex;\n    cursor: pointer;\n    margin: 1px;\n    border-radius: 2px;\n    padding: 2px 5px;\n    align-items: center;\n}\n\ndiv.${BUTTON_CLASS_NAME}.ace_selected,\ndiv.${BUTTON_CLASS_NAME}:hover:not(.ace_disabled) {\n    background-color: rgba(0, 0, 0, 0.1);\n}\n\ndiv.${BUTTON_CLASS_NAME}.ace_disabled {\n    color: #777;\n    pointer-events: none;\n}\n\ndiv.${BUTTON_CLASS_NAME} .ace_icon_svg {\n    height: 12px;\n    background-color: #000;\n}\n\ndiv.${BUTTON_CLASS_NAME}.ace_disabled .ace_icon_svg {\n    background-color: #777;\n}\n\n.${TOOLTIP_CLASS_NAME}.tooltip_more_options .${BUTTON_CLASS_NAME} {\n    display: flex;\n}\n\n.${TOOLTIP_CLASS_NAME}.${VALUE_CLASS_NAME} {\n    display: none;\n}\n\n.${TOOLTIP_CLASS_NAME}.tooltip_more_options .${VALUE_CLASS_NAME} {\n    display: inline-block;\n    width: 12px;\n}\n\n.${CAPTION_CLASS_NAME} {\n    display: inline-block;\n}\n\n.${KEYBINDING_CLASS_NAME} {\n    margin: 0 2px;\n    display: inline-block;\n    font-size: 8px;\n}\n\n.${TOOLTIP_CLASS_NAME}.tooltip_more_options .${KEYBINDING_CLASS_NAME} {\n    margin-left: auto;\n}\n\n.${KEYBINDING_CLASS_NAME} div {\n    display: inline-block;\n    min-width: 8px;\n    padding: 2px;\n    margin: 0 1px;\n    border-radius: 2px;\n    background-color: #ccc;\n    text-align: center;\n}\n\n.ace_dark.ace_tooltip .${TOOLTIP_CLASS_NAME} {\n    background-color: #373737;\n    color: #eee;\n}\n\n.ace_dark div.${BUTTON_CLASS_NAME}.ace_disabled {\n    color: #979797;\n}\n\n.ace_dark div.${BUTTON_CLASS_NAME}.ace_selected,\n.ace_dark div.${BUTTON_CLASS_NAME}:hover:not(.ace_disabled) {\n    background-color: rgba(255, 255, 255, 0.1);\n}\n\n.ace_dark div.${BUTTON_CLASS_NAME} .ace_icon_svg {\n    background-color: #eee;\n}\n\n.ace_dark div.${BUTTON_CLASS_NAME}.ace_disabled .ace_icon_svg {\n    background-color: #979797;\n}\n\n.ace_dark .${BUTTON_CLASS_NAME}.ace_disabled {\n    color: #979797;\n}\n\n.ace_dark .${KEYBINDING_CLASS_NAME} div {\n    background-color: #575757;\n}\n\n.ace_checkmark::before {\n    content: '✓';\n}\n`, \"commandbar.css\", false);\n\nexports.CommandBarTooltip = CommandBarTooltip;\nexports.TOOLTIP_CLASS_NAME = TOOLTIP_CLASS_NAME;\nexports.BUTTON_CLASS_NAME = BUTTON_CLASS_NAME;\n"
  },
  {
    "path": "src/ext/command_bar_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar TOOLTIP_CLASS_NAME = require(\"./command_bar\").TOOLTIP_CLASS_NAME;\nvar BUTTON_CLASS_NAME = require(\"./command_bar\").BUTTON_CLASS_NAME;\nvar CommandBarTooltip = require(\"./command_bar\").CommandBarTooltip;\nvar Editor = require(\"../ace\").Editor;\nvar EditSession = require(\"../ace\").EditSession;\nvar VirtualRenderer = require(\"../ace\").VirtualRenderer;\nvar assert = require(\"../test/assertions\");\nvar useragent = require(\"../lib/useragent\");\nvar lang = require(\"../lib/lang\");\n\nfunction simulateClick(node) {\n    node.dispatchEvent(new window.CustomEvent(\"click\", { bubbles: true }));\n}\n\nfunction simulateMouseEvent(type, opts, node) {\n    var target = node || editor.renderer.getMouseEventTarget();\n    var e = new window.CustomEvent(\"mouse\" + type, {bubbles: true, cancelable: true});\n    Object.defineProperties(e, Object.getOwnPropertyDescriptors(opts));\n    target.dispatchEvent(e);\n}\n\n\nvar editor;\nvar counters = {};\nvar commandBarTooltip;\nvar testValues = {};\nvar wrapperEl;\nvar editorPx = 500;\n\nfunction getActiveLinePosition() {\n    var cursorPosition = editor.getCursorPosition();\n    return editor.renderer.textToScreenCoordinates(cursorPosition.row, cursorPosition.column);\n}\n\n\nvar testFunction = function(name, defaultValue) {\n    return function(editor) {\n        if (!editor) {\n            return;\n        }\n        if (!counters[name]) {\n            counters[name] = 0;\n        }\n        counters[name]++;\n        return testValues[name] === undefined ? defaultValue : testValues[name];\n    };\n};\n\nvar commands = {\n    \"testCommand1\": {\n        name: \"testCommand1\",\n        bindKey: { win: \"Alt-K\", mac: \"Cmd-K\" },\n        exec: testFunction(\"testCommand1\"),\n        enabled: testFunction(\"testEnabled1\", true),\n        type: \"button\"\n    },\n    \"testCommand2\": {\n        name: \"testCommand2\",\n        bindKey: \"Ctrl-L\",\n        exec: testFunction(\"testCommand2\"),\n        enabled: testFunction(\"testEnabled2\", true),\n        type: \"button\"\n    }\n};\n\nvar createTooltip = function(options, additionalCommands) {\n    commandBarTooltip = new CommandBarTooltip(document.body, options);\n    Object.keys(commands).forEach(function(key) {\n        commandBarTooltip.registerCommand(key, commands[key]);\n    });\n    (additionalCommands || []).forEach(function(commandEntry) {\n        commandBarTooltip.registerCommand(commandEntry[0], commandEntry[1]);\n    });\n    commandBarTooltip.setAlwaysShow(true);\n    // Workaround: non-standard width and height hints for mock dom (which does not work well with flex elements)\n    // When running in the browser, these are ignored\n    commandBarTooltip.tooltip.getElement().style.widthHint = 150;\n    commandBarTooltip.tooltip.getElement().style.heightHint = editor.renderer.lineHeight * 2;\n    commandBarTooltip.moreOptions.getElement().style.widthHint = 150;\n    commandBarTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;commandBarTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;commandBarTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;commandBarTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;commandBarTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;\n};\n\nvar isElementVisible = function(elem) {\n    return !((elem.position !== \"fixed\" && elem.offsetParent === null) ||\n        window.getComputedStyle(elem).display === 'none' || elem.clientHeight === 0);\n};\n\nvar tooltipVisibilityCheck = function(tooltipVisible = false, moreOptionsVisible = false) {\n    moreOptionsVisible = tooltipVisible && moreOptionsVisible;\n    assert.strictEqual(commandBarTooltip.isShown(), tooltipVisible);\n    assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), moreOptionsVisible);\n    var tooltipDomElements = document.querySelectorAll(\".\" + TOOLTIP_CLASS_NAME);\n    assert.strictEqual(tooltipDomElements.length, 2);\n    assert.strictEqual(isElementVisible(tooltipDomElements[0]), tooltipVisible);\n    assert.strictEqual(isElementVisible(tooltipDomElements[1]), moreOptionsVisible);\n};\n\nmodule.exports = {\n    setUp: function() {\n        wrapperEl = document.createElement(\"div\");\n        wrapperEl.style.position = \"fixed\";\n        wrapperEl.style.left = \"400px\";\n        wrapperEl.style.top = \"100px\";\n        wrapperEl.style.width = editorPx + \"px\";\n        wrapperEl.style.height = editorPx + \"px\";\n        document.body.appendChild(wrapperEl);\n        var renderer = new VirtualRenderer(wrapperEl);\n        var session = new EditSession(\"abc123\\n\\nfunc\");\n        editor = new Editor(renderer, session);\n        counters = {};\n        testValues = {};\n        editor.getSelection().moveCursorFileEnd();\n        editor.renderer.$loop._flush();\n    },\n    \"test: displays command bar tooltip above cursor with commands immediately in 'always show' mode\": function() {\n        createTooltip();\n        tooltipVisibilityCheck(false, false);\n\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true, false);\n    },\n    \"test: commands are disabled when enable check is falsy\": function() {\n        createTooltip();\n        commandBarTooltip.attach(editor);\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        var disabledButtonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME + \".ace_disabled\"));\n        assert.strictEqual(buttonElements.length, 2);\n        assert.strictEqual(disabledButtonElements.length, 0);\n        assert.strictEqual(buttonElements.filter(function (button) { return !button.disabled; }).length, 2);\n        assert.strictEqual(counters[\"testEnabled1\"], 1);\n        assert.strictEqual(counters[\"testEnabled2\"], 1);\n\n        testValues.testEnabled2 = false;\n        commandBarTooltip.update();\n        buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        disabledButtonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME + \".ace_disabled\"));\n        assert.strictEqual(buttonElements.length, 2);\n        assert.strictEqual(disabledButtonElements.length, 1);\n        assert.strictEqual(disabledButtonElements.filter(function (button) { return button.disabled; }).length, 1);\n        assert.strictEqual(buttonElements.filter(function (button) { return !button.disabled; }).length, 1);\n        assert.strictEqual(counters[\"testEnabled1\"], 2);\n        assert.strictEqual(counters[\"testEnabled2\"], 2);\n    },\n    \"test: enabled commands are clickable\": function() {\n        createTooltip();\n        commandBarTooltip.attach(editor);\n        assert.strictEqual(commandBarTooltip.isShown(), true);\n        assert.strictEqual(counters[\"testCommand1\"], undefined);\n        assert.strictEqual(counters[\"testCommand2\"], undefined);\n        testValues.testEnabled2 = false;\n        commandBarTooltip.update();\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 2);\n        var disabledButtonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME + \".ace_disabled\"));\n        assert.strictEqual(disabledButtonElements.length, 1);\n        simulateClick(buttonElements[0]);\n        simulateClick(buttonElements[1]);\n        simulateClick(disabledButtonElements[0]);\n        assert.strictEqual(counters[\"testCommand1\"], 1);\n        assert.strictEqual(counters[\"testCommand2\"], undefined);\n    },\n    \"test: tooltip is displayed on hover with the tooltip delay\": async function(done) {\n        var delay = 10;\n        createTooltip({ showDelay: delay, hideDelay: delay, maxElementsOnTooltip: 1 });\n        commandBarTooltip.setAlwaysShow(false);\n        editor.getSelection().moveCursorTo(1, 1);\n        editor.renderer.$loop._flush();\n        var activeLinePos = getActiveLinePosition();\n        var mainTooltipEl = commandBarTooltip.tooltip.getElement();\n        var moreOptionsEl = commandBarTooltip.moreOptions.getElement();\n        var moveToActiveLineCursor = { clientX: activeLinePos.pageX + 1, clientY: activeLinePos.pageY + 1 };\n        var moveAway = { clientX: activeLinePos.pageX + 1, clientY: activeLinePos.pageY + 100 };\n        commandBarTooltip.attach(editor);\n        simulateMouseEvent(\"move\", moveToActiveLineCursor);\n        tooltipVisibilityCheck(false);\n\n        await lang.sleep(delay);\n        tooltipVisibilityCheck(true, false);\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n\n        var moreOptionsButton = buttonElements[1];\n\n        var moveToMoreOptionsButton = { clientX: moreOptionsButton.left + 1, clientY: moreOptionsButton.right + 1 };\n\n        simulateMouseEvent(\"move\", moveToMoreOptionsButton);\n        simulateMouseEvent(\"enter\", moveToMoreOptionsButton, mainTooltipEl);\n\n        simulateClick(moreOptionsButton);\n\n        tooltipVisibilityCheck(true, true);\n\n        var leaveMainTooltip = { clientX: mainTooltipEl.right + 10, clientY: mainTooltipEl.top - 10 };\n        simulateMouseEvent(\"move\", leaveMainTooltip);\n        simulateMouseEvent(\"leave\", leaveMainTooltip, mainTooltipEl);\n\n        await lang.sleep(delay / 2);\n        var moreOptionsRect = moreOptionsEl.getBoundingClientRect();\n        var enterMoreOptions = { clientX: moreOptionsRect.left + 1, clientY: moreOptionsRect.top + 1 };\n        simulateMouseEvent(\"move\", enterMoreOptions);\n        simulateMouseEvent(\"enter\", enterMoreOptions, moreOptionsEl);\n\n        await lang.sleep(delay);\n        tooltipVisibilityCheck(true, true);\n        var moreOptionsRect = moreOptionsEl.getBoundingClientRect();\n        var leaveWholeTooltip = { clientX: moreOptionsRect.right + 10, clientY: moreOptionsRect.top - 10 };\n        simulateMouseEvent(\"move\", leaveWholeTooltip);\n        simulateMouseEvent(\"leave\", leaveWholeTooltip, mainTooltipEl);\n\n        await lang.sleep(delay / 2);\n        simulateMouseEvent(\"move\", moveToActiveLineCursor);\n\n        await lang.sleep(delay);\n        tooltipVisibilityCheck(true, true);\n        simulateMouseEvent(\"move\", moveAway);\n\n        await lang.sleep(delay);\n        tooltipVisibilityCheck(false);\n        simulateMouseEvent(\"move\", moveToActiveLineCursor);\n\n        await lang.sleep(delay);\n        tooltipVisibilityCheck(true);\n        done();\n    },\n    \"test: tooltip supports checkbox buttons\": function() {\n        createTooltip();\n        testValues.testCheckboxValue1 = true;\n        commandBarTooltip.registerCommand(\"testCheckbox1\", {\n            name: \"testCheckbox1\",\n            bindKey: \"Alt-C\",\n            exec: function() {\n                testValues.testCheckboxValue1 = !testValues.testCheckboxValue1;\n            },\n            enabled: testFunction(\"testCheckboxEnabled1\", true),\n            getValue: testFunction(\"testCheckboxValue1\"),\n            type: \"checkbox\"\n        });\n\n        commandBarTooltip.attach(editor);\n        assert.strictEqual(commandBarTooltip.isShown(), true);\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n        var checkboxElement = buttonElements[2];\n        assert.strictEqual(checkboxElement.classList.contains(\"ace_selected\"), true);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"true\");\n\n        testValues.testCheckboxValue1 = false;\n        commandBarTooltip.update();\n        assert.strictEqual(checkboxElement.classList.contains(\"ace_selected\"), false);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"false\");\n\n        simulateClick(checkboxElement);\n        assert.strictEqual(checkboxElement.classList.contains(\"ace_selected\"), true);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"true\");\n    },\n    \"test: tooltip supports checkbox menu items\": function() {\n        createTooltip({ maxElementsOnTooltip: 2 });\n        testValues.testCheckboxValue1 = true;\n        commandBarTooltip.registerCommand(\"testCheckbox1\", {\n            name: \"testCheckbox1\",\n            bindKey: \"Alt-C\",\n            exec: function() {\n                testValues.testCheckboxValue1 = !testValues.testCheckboxValue1;\n            },\n            enabled: testFunction(\"testCheckboxEnabled1\", true),\n            getValue: testFunction(\"testCheckboxValue1\"),\n            type: \"checkbox\"\n        });\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        commandBarTooltip.attach(editor);\n        assert.strictEqual(commandBarTooltip.isShown(), true);\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 4);\n        var moreOptionsElement = buttonElements[2];\n        var checkboxElement = buttonElements[3];\n        assert.strictEqual(checkboxElement.parentElement, commandBarTooltip.moreOptionsEl);\n        assert.strictEqual(checkboxElement.firstChild.classList.contains(\"ace_checkmark\"), true);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"true\");\n\n        testValues.testCheckboxValue1 = false;\n        commandBarTooltip.update();\n        assert.strictEqual(checkboxElement.firstChild.classList.contains(\"ace_checkmark\"), false);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"false\");\n\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n        simulateClick(moreOptionsElement);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), true);\n        simulateClick(checkboxElement);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n\n        assert.strictEqual(checkboxElement.firstChild.classList.contains(\"ace_checkmark\"), true);\n        assert.strictEqual(checkboxElement.ariaChecked.toString(), \"true\");\n    },\n    \"test: tooltip supports icon buttons\": function() {\n        createTooltip();\n        commandBarTooltip.registerCommand(\"testIcon1\", {\n            name: \"testIcon1\",\n            bindKey: \"Alt-I\",\n            exec: testFunction(\"testIcon1\"),\n            enabled: testFunction(\"testIconEnabled1\", true),\n            iconCssClass: \"ace_info\",\n            type: \"button\"\n        });\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        commandBarTooltip.attach(editor);\n        assert.strictEqual(commandBarTooltip.isShown(), true);\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n        var iconButtonElement = buttonElements[2];\n        assert.strictEqual(iconButtonElement.firstChild.classList.contains(\"ace_info\"), true);\n        assert.strictEqual(iconButtonElement.firstChild.classList.contains(\"ace_icon_svg\"), true);\n        assert.strictEqual(counters[\"testIcon1\"], undefined);\n\n        simulateClick(iconButtonElement);\n\n        assert.strictEqual(counters[\"testIcon1\"], 1);\n    },\n    \"test: tooltip supports text elements\": function() {\n        createTooltip();\n        testValues.testTextValue1 = \"test\";\n        commandBarTooltip.registerCommand(\"testText1\", {\n            name: \"testText1\",\n            bindKey: \"Alt-I\",\n            enabled: testFunction(\"testTextEnabled1\", true),\n            getValue: testFunction(\"testTextValue1\"),\n            type: \"text\"\n        });\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        commandBarTooltip.attach(editor);\n        assert.strictEqual(commandBarTooltip.isShown(), true);\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n        var textButtonElement = buttonElements[2];\n        assert.strictEqual(textButtonElement.textContent, \"test\");\n        assert.strictEqual(counters[\"testText1\"], undefined);\n\n        simulateClick(textButtonElement);\n        assert.strictEqual(textButtonElement.textContent, \"test\");\n        assert.strictEqual(counters[\"testText1\"], undefined);\n\n        testValues.testTextValue1 = \"updatedTest\";\n        commandBarTooltip.update();\n        assert.strictEqual(textButtonElement.textContent, \"updatedTest\");\n        assert.strictEqual(counters[\"testText1\"], undefined);\n    },\n    \"test: tooltip creates more options menu for overflow options\": function() {\n        createTooltip({ maxElementsOnTooltip: 2 });\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 2);\n        assert.strictEqual(buttonElements[0].parentElement, commandBarTooltip.tooltipEl);\n        assert.strictEqual(buttonElements[1].parentElement, commandBarTooltip.tooltipEl);\n\n        commandBarTooltip.attach(editor);\n\n        commandBarTooltip.registerCommand(\"testText1\", {\n            name: \"testText1\",\n            enabled: testFunction(\"testTextEnabled1\", true),\n            getValue: testFunction(\"testTextValue1\"),\n            type: \"text\"\n        });\n\n        buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 4);\n        assert.strictEqual(buttonElements[2].parentElement, commandBarTooltip.tooltipEl);\n        assert.strictEqual(buttonElements[3].parentElement, commandBarTooltip.moreOptionsEl);\n\n        var moreOptionsButton = buttonElements[2];\n\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n        simulateClick(moreOptionsButton);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), true);\n        simulateClick(moreOptionsButton);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n        simulateClick(moreOptionsButton);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), true);\n        simulateClick(buttonElements[3]);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n    },\n    \"test: more options opens below main tooltip, above only if there is no space below\": function() {\n        createTooltip({ maxElementsOnTooltip: 1 });\n\n        wrapperEl.style.top = (window.innerHeight - editorPx) + \"px\";\n        wrapperEl.style.left = (window.innerWidth - editorPx) + \"px\";\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n\n        var moreOptionsButton = buttonElements[1];\n        var tooltipEl = commandBarTooltip.tooltip.getElement();\n        var moreOptionsEl = commandBarTooltip.moreOptions.getElement();\n        var charWidth = editor.renderer.$textLayer.getCharacterWidth();\n        var testString = \"\\n\".repeat(editorPx / editor.renderer.lineHeight + 3) +\n             \"b\".repeat(editorPx / charWidth);\n\n\n        editor.execCommand(\"insertstring\", testString);\n        editor.getSelection().moveCursorFileStart();\n        editor.renderer.scrollTo(0,0);\n        editor.renderer.$loop._flush();\n\n        commandBarTooltip.attach(editor);\n\n        tooltipVisibilityCheck(true);\n        simulateClick(moreOptionsButton);\n        tooltipVisibilityCheck(true, true);\n\n        assert.ok(tooltipEl.getBoundingClientRect().top < moreOptionsEl.getBoundingClientRect().top);\n\n        commandBarTooltip.detach();\n\n        editor.getSelection().moveCursorFileEnd();\n        editor.renderer.scrollCursorIntoView(editor.getCursorPosition());\n        editor.renderer.$loop._flush();\n\n        commandBarTooltip.attach(editor);\n\n        tooltipVisibilityCheck(true);\n        simulateClick(moreOptionsButton);\n        tooltipVisibilityCheck(true, true);\n\n        assert.ok(tooltipEl.getBoundingClientRect().top > moreOptionsEl.getBoundingClientRect().top);\n    },\n    \"test: keeps the editor in focus after the tooltip is clicked\": function() {\n        createTooltip({ maxElementsOnTooltip: 1 });\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        assert.strictEqual(buttonElements.length, 3);\n\n        var moreOptionsButton = buttonElements[1];\n        var tooltipEl = commandBarTooltip.tooltip.getElement();\n        var moreOptionsEl = commandBarTooltip.moreOptions.getElement();\n\n        commandBarTooltip.attach(editor);\n\n        tooltipVisibilityCheck(true);\n        simulateClick(tooltipEl);\n        assert.strictEqual(editor.isFocused(), true);\n        simulateClick(moreOptionsButton);\n        assert.strictEqual(editor.isFocused(), true);\n        tooltipVisibilityCheck(true, true);\n        simulateClick(moreOptionsEl);\n        assert.strictEqual(editor.isFocused(), true);\n        simulateClick(buttonElements[2]);\n        assert.strictEqual(editor.isFocused(), true);\n        \n        commandBarTooltip.detach();\n\n        assert.strictEqual(editor.isFocused(), true);\n    },\n    \"test: shows windows keybindings when available\": function() {\n        var origIsWin = useragent.isWin;\n        var origIsMac = useragent.isMac;\n        try {\n            useragent.isWin = true;\n            useragent.isMac = false;\n            createTooltip({ maxElementsOnTooltip: 1 });\n\n            commandBarTooltip.registerCommand(\"testButton3\", {\n                name: \"testButton\",\n                bindKey: { win: \"Shift-Right\", mac: \"Option-Right\" },\n                exec: testFunction(\"testButton3\"),\n                enabled: testFunction(\"testButtonEnabled3\", true),\n                type: \"button\"\n            });\n\n            var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n            assert.strictEqual(buttonElements.length, 4);\n\n            var extractTextContent = function(el) {\n                return el.textContent;\n            };\n\n            var keyBindings1 = Array.from(buttonElements[0].lastChild.childNodes).map(extractTextContent);\n            var keyBindings2 = Array.from(buttonElements[2].lastChild.childNodes).map(extractTextContent);\n            var keyBindings3 = Array.from(buttonElements[3].lastChild.childNodes).map(extractTextContent);\n            assert.deepEqual(keyBindings1, [\"Alt\", \"K\"]);\n            assert.deepEqual(keyBindings2, [\"Ctrl\", \"L\"]);\n            assert.deepEqual(keyBindings3, [\"⇧\", \"→\"]);\n        } finally {\n            useragent.isWin = origIsWin;\n            useragent.isMac = origIsMac;\n        }\n    },\n    \"test: shows mac keybindings when available\": function() {\n        var origIsWin = useragent.isWin;\n        var origIsMac = useragent.isMac;\n        try {\n            useragent.isWin = false;\n            useragent.isMac = true;\n            createTooltip({ maxElementsOnTooltip: 1 });\n\n            commandBarTooltip.registerCommand(\"testButton3\", {\n                name: \"testButton\",\n                bindKey: { win: \"Shift-Right\", mac: \"Option-Right\" },\n                exec: testFunction(\"testButton3\"),\n                enabled: testFunction(\"testButtonEnabled3\", true),\n                type: \"button\"\n            });\n\n            var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n            assert.strictEqual(buttonElements.length, 4);\n\n            var extractTextContent = function(el) {\n                return el.textContent;\n            };\n\n            var keyBindings1 = Array.from(buttonElements[0].lastChild.childNodes).map(extractTextContent);\n            var keyBindings2 = Array.from(buttonElements[2].lastChild.childNodes).map(extractTextContent);\n            var keyBindings3 = Array.from(buttonElements[3].lastChild.childNodes).map(extractTextContent);\n            assert.deepEqual(keyBindings1, [\"⌘\", \"K\"]);\n            assert.deepEqual(keyBindings2, [\"^\", \"L\"]);\n            assert.deepEqual(keyBindings3, [\"⌥\", \"→\"]);\n        } finally {\n            useragent.isWin = origIsWin;\n            useragent.isMac = origIsMac;\n        }\n    },\n    \"test: does not display if the editor cursor is not visible\": function() {\n        createTooltip();\n\n        var charWidth = editor.renderer.$textLayer.getCharacterWidth();\n\n        var testString = \"a\".repeat(100) +\n             \"\\n\".repeat(editorPx / editor.renderer.lineHeight + 3) +\n             \"b\".repeat(100);\n\n        editor.execCommand(\"insertstring\", testString);\n        editor.renderer.$loop._flush();\n\n        editor.getSelection().moveCursorFileStart();\n        editor.renderer.scrollTo(0,0);\n        editor.renderer.$loop._flush();\n\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        editor.renderer.scrollToLine(1);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(false);\n\n        editor.renderer.scrollToLine(0);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(true);\n\n        editor.renderer.scrollBy(charWidth * 2);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(false);\n\n        editor.renderer.scrollBy(-charWidth * 2);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(true);\n        commandBarTooltip.detach();\n\n        editor.getSelection().moveCursorFileEnd();\n        editor.renderer.scrollCursorIntoView(editor.getCursorPosition());\n        editor.renderer.$loop._flush();\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        editor.renderer.scrollToLine(editor.renderer.getScrollTopRow() - 2);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(false);\n\n        editor.renderer.scrollToLine(editor.renderer.getScrollTopRow() + 2);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(true);\n\n        editor.renderer.scrollBy(-charWidth * 10);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(false);\n\n        editor.renderer.scrollBy(charWidth * 10);\n        editor.renderer.$loop._flush();\n        tooltipVisibilityCheck(true);\n        commandBarTooltip.detach();\n    },\n    \"test: does not display if the tooltip does not fit into the screen\": async function() {\n        await lang.sleep(0);\n        createTooltip();\n\n        var testString = \"a\".repeat(100) +\n             \"\\n\".repeat(editorPx / editor.renderer.lineHeight + 3) +\n             \"b\".repeat(100);\n\n        editor.execCommand(\"insertstring\", testString);\n        editor.renderer.$loop._flush();\n\n        wrapperEl.style.top = \"10px\";\n\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        commandBarTooltip.detach();\n\n        tooltipVisibilityCheck(false);\n\n        editor.getSelection().moveCursorFileStart();\n        editor.renderer.scrollCursorIntoView(editor.getCursorPosition());\n        editor.renderer.$loop._flush();\n\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(false);\n    },\n    \"test: detaches when session changes\": function() {\n        createTooltip();\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        var currentSession = editor.getSession();\n        editor.setSession(null);\n        tooltipVisibilityCheck(false);\n\n        editor.setSession(currentSession);\n        tooltipVisibilityCheck(false);\n\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n    },\n    \"test: verify detach\": function() {\n        createTooltip();\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        commandBarTooltip.detach();\n        tooltipVisibilityCheck(false);\n\n        commandBarTooltip.detach();\n        tooltipVisibilityCheck(false);\n    },\n    \"test: verify destroy\": function() {\n        createTooltip();\n        commandBarTooltip.attach(editor);\n        tooltipVisibilityCheck(true);\n\n        commandBarTooltip.destroy();\n        assert.strictEqual(commandBarTooltip.isShown(), false);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n        var tooltipDomElements = document.querySelectorAll(\".\" + TOOLTIP_CLASS_NAME);\n        assert.strictEqual(tooltipDomElements.length, 0);\n\n        // Intentionally called twice\n        commandBarTooltip.destroy();\n        assert.strictEqual(commandBarTooltip.isShown(), false);\n        assert.strictEqual(commandBarTooltip.isMoreOptionsShown(), false);\n        tooltipDomElements = document.querySelectorAll(\".\" + TOOLTIP_CLASS_NAME);\n        assert.strictEqual(tooltipDomElements.length, 0);\n    },\n    tearDown: function() {\n        commandBarTooltip.destroy();\n        editor.destroy();\n        wrapperEl.parentElement.removeChild(wrapperEl);\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/diff/base_diff_view.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar dom = require(\"../../lib/dom\");\nvar config = require(\"../../config\");\nvar LineWidgets = require(\"../../line_widgets\").LineWidgets;\nvar ScrollDiffDecorator = require(\"./scroll_diff_decorator\").ScrollDiffDecorator;\n\n// @ts-ignore\nvar css = require(\"./styles-css.js\").cssText;\n\nvar Editor = require(\"../../editor\").Editor;\nvar Renderer = require(\"../../virtual_renderer\").VirtualRenderer;\nvar UndoManager = require(\"../../undomanager\").UndoManager;\nvar Decorator = require(\"../../layer/decorators\").Decorator;\n\nrequire(\"../../theme/textmate\");\n// enable multiselect\nrequire(\"../../multi_select\");\n\nvar EditSession = require(\"../../edit_session\").EditSession;\n\nvar MinimalGutterDiffDecorator = require(\"./gutter_decorator\").MinimalGutterDiffDecorator;\n\nvar dummyDiffProvider = {\n    compute: function(val1, val2, options) {\n        return [];\n    }\n};\n\ndom.importCssString(css, \"diffview.css\", false);\n\nclass BaseDiffView {\n    /**\n     * Constructs a new base DiffView instance.\n     * @param {boolean} [inlineDiffEditor] - Whether to use an inline diff editor.\n     * @param {HTMLElement} [container] - optional container element for the DiffView.\n     */\n    constructor(inlineDiffEditor, container) {\n        this.onChangeTheme = this.onChangeTheme.bind(this);\n        this.onInput = this.onInput.bind(this);\n        this.onChangeFold = this.onChangeFold.bind(this);\n        this.realign = this.realign.bind(this);\n        this.onSelect = this.onSelect.bind(this);\n        this.onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n        this.realignPending = false;\n\n        /**@type{{sessionA: EditSession, sessionB: EditSession, chunks: DiffChunk[]}}*/this.diffSession;\n        /**@type DiffChunk[]*/this.chunks;\n        this.inlineDiffEditor = inlineDiffEditor || false;\n        this.currentDiffIndex = 0;\n        this.diffProvider = dummyDiffProvider;\n\n        if (container) {\n            this.container = container;\n        }\n\n        this.$ignoreTrimWhitespace = false;\n        this.$maxDiffs = 5000;\n        this.$maxComputationTimeMs = 150;\n        this.$syncSelections = false;\n        this.$foldUnchangedOnInput = false;\n\n        this.markerB = new DiffHighlight(this, 1);\n        this.markerA = new DiffHighlight(this, -1);\n    }\n\n    /**\n     * @param {import(\"../diff\").DiffModel} [diffModel] - The model for the diff view.\n     */\n    $setupModels(diffModel) {\n        if (diffModel.diffProvider) {\n            this.setProvider(diffModel.diffProvider);\n        }\n        this.showSideA = diffModel.inline == undefined ? true : diffModel.inline === \"a\";\n        var diffEditorOptions = /**@type {Partial<import(\"../../../ace-internal\").Ace.EditorOptions>}*/({\n            scrollPastEnd: 0.5,\n            highlightActiveLine: false,\n            highlightGutterLine: false,\n            animatedScroll: true,\n            customScrollbar: true,\n            vScrollBarAlwaysVisible: true,\n            fadeFoldWidgets: true,\n            showFoldWidgets: true,\n            selectionStyle: \"text\",\n        });\n\n        this.savedOptionsA = diffModel.editorA && diffModel.editorA.getOptions(diffEditorOptions);\n        this.savedOptionsB = diffModel.editorB && diffModel.editorB.getOptions(diffEditorOptions);\n\n        if (!this.inlineDiffEditor || diffModel.inline === \"a\") {\n            this.editorA = diffModel.editorA || this.$setupModel(diffModel.sessionA, diffModel.valueA);\n            this.container && this.container.appendChild(this.editorA.container);\n            this.editorA.setOptions(diffEditorOptions);\n        }\n        if (!this.inlineDiffEditor || diffModel.inline === \"b\") {\n            this.editorB = diffModel.editorB || this.$setupModel(diffModel.sessionB, diffModel.valueB);\n            this.container && this.container.appendChild(this.editorB.container);\n            this.editorB.setOptions(diffEditorOptions);\n        }\n        \n        if (this.inlineDiffEditor) {\n            this.activeEditor = this.showSideA ? this.editorA : this.editorB;\n            this.otherSession = this.showSideA ? this.sessionB : this.sessionA;\n            var cloneOptions = this.activeEditor.getOptions();\n            cloneOptions.readOnly = true;\n            delete cloneOptions.mode;\n            this.otherEditor = new Editor(new Renderer(null), undefined, cloneOptions);\n            if (this.showSideA) {\n                this.editorB = this.otherEditor;\n            } else {\n                this.editorA = this.otherEditor;\n            }\n        }\n\n        this.setDiffSession({\n            sessionA: diffModel.sessionA || (diffModel.editorA ? diffModel.editorA.session : new EditSession(\n                diffModel.valueA || \"\")),\n            sessionB: diffModel.sessionB || (diffModel.editorB ? diffModel.editorB.session : new EditSession(\n                diffModel.valueB || \"\")),\n            chunks: []\n        });\n        \n        if (this.otherEditor && this.activeEditor) {\n            this.otherSession.setOption(\"wrap\", this.activeEditor.getOption(\"wrap\"));\n        }\n\n        this.setupScrollbars();\n    }\n\n    addGutterDecorators() { \n        if (!this.gutterDecoratorA)\n            this.gutterDecoratorA = new MinimalGutterDiffDecorator(this.editorA, -1);\n        if (!this.gutterDecoratorB)\n            this.gutterDecoratorB = new MinimalGutterDiffDecorator(this.editorB, 1);\n    }\n\n    /**\n     * @param {EditSession} [session]\n     * @param {string} [value]\n     */\n    $setupModel(session, value) {\n        var editor = new Editor(new Renderer(), session);\n        editor.session.setUndoManager(new UndoManager());\n        if (value != undefined) {\n            editor.setValue(value, -1);\n        }\n        return editor;\n    }\n\n    foldUnchanged() {\n        var chunks = this.chunks;\n        var placeholder = \"-\".repeat(120);\n        var prev = {\n            old: new Range(0, 0, 0, 0),\n            new: new Range(0, 0, 0, 0)\n        };\n        var foldsChanged = false;\n        for (var i = 0; i < chunks.length + 1; i++) {\n            let current = chunks[i] || {\n                old: new Range(this.sessionA.getLength(), 0, this.sessionA.getLength(), 0),\n                new: new Range(this.sessionB.getLength(), 0, this.sessionB.getLength(), 0)\n            };\n            var l = current.new.start.row - prev.new.end.row - 5;\n            if (l > 2) {\n                var s = prev.old.end.row + 2;\n                var fold1 = this.sessionA.addFold(placeholder, new Range(s, 0, s + l, Number.MAX_VALUE));\n                s = prev.new.end.row + 2;\n                var fold2 = this.sessionB.addFold(placeholder, new Range(s, 0, s + l, Number.MAX_VALUE));\n                if (fold1 || fold2) foldsChanged = true;\n                if (fold2 && fold1) {\n                    fold1[\"other\"] = fold2;\n                    fold2[\"other\"] = fold1;\n                }\n            }\n\n            prev = current;\n        }\n        return foldsChanged;\n    }\n\n    unfoldUnchanged() {\n        var folds = this.sessionA.getAllFolds();\n        for (var i = folds.length - 1; i >= 0; i--) {\n            var fold = folds[i];\n            if (fold.placeholder.length == 120) {\n                this.sessionA.removeFold(fold);\n            }\n        }\n    }\n\n    toggleFoldUnchanged() {\n        if (!this.foldUnchanged()) {\n            this.unfoldUnchanged();\n        }\n    }\n\n    /**\n     * @param {{ sessionA: any; sessionB: EditSession; chunks: DiffChunk[] }} session\n     */\n    setDiffSession(session) {\n        if (this.diffSession) {\n            this.$detachSessionsEventHandlers();\n            this.clearSelectionMarkers();\n        }\n        this.diffSession = session;\n        this.sessionA = this.sessionB = null;\n        if (this.diffSession) {\n            this.chunks = this.diffSession.chunks || [];\n            this.editorA && this.editorA.setSession(session.sessionA);\n            this.editorB && this.editorB.setSession(session.sessionB);\n            this.sessionA = this.diffSession.sessionA;\n            this.sessionB = this.diffSession.sessionB;\n            this.$attachSessionsEventHandlers();\n            this.initSelectionMarkers();\n        }\n\n        this.otherSession = this.showSideA ? this.sessionB : this.sessionA;\n    }\n\n    /**\n     * @abstract\n     */\n    $attachSessionsEventHandlers() {\n    }\n\n    /**\n     * @abstract\n     */\n    $detachSessionsEventHandlers() {\n    }\n\n    getDiffSession() {\n        return this.diffSession;\n    }\n\n    setTheme(theme) {\n        this.editorA && this.editorA.setTheme(theme);\n        this.editorB && this.editorB.setTheme(theme);\n    }\n\n    getTheme() {\n        return (this.editorA || this.editorB).getTheme();\n    }\n\n    onChangeTheme(e) {\n        var theme = e && e.theme || this.getTheme();\n\n        if (this.editorA && this.editorA.getTheme() !== theme) {\n            this.editorA.setTheme(theme);\n        }\n        if (this.editorB && this.editorB.getTheme() !== theme) {\n            this.editorB.setTheme(theme);\n        }\n    }\n\n    resize(force) {\n        this.editorA && this.editorA.resize(force);\n        this.editorB && this.editorB.resize(force);\n    }\n\n    scheduleOnInput() {\n        if (this.$onInputTimer) return;\n        this.$onInputTimer = setTimeout(() => {\n            this.$onInputTimer = null;\n            this.onInput();\n        });\n    }\n    onInput() {\n        if (this.$onInputTimer) clearTimeout(this.$onInputTimer);\n\n        var val1 = this.sessionA.doc.getAllLines();\n        var val2 = this.sessionB.doc.getAllLines();\n\n        this.selectionRangeA = null;\n        this.selectionRangeB = null;\n\n        var chunks = this.$diffLines(val1, val2);\n\n        this.diffSession.chunks = this.chunks = chunks;\n        this.gutterDecoratorA && this.gutterDecoratorA.setDecorations(chunks);\n        this.gutterDecoratorB && this.gutterDecoratorB.setDecorations(chunks);\n        // if we\"re dealing with too many chunks, fail silently\n        if (this.chunks && this.chunks.length > this.$maxDiffs) {\n            return;\n        }\n\n        this.align();\n\n        this.editorA && this.editorA.renderer.updateBackMarkers();\n        this.editorB && this.editorB.renderer.updateBackMarkers();\n\n        setTimeout(() => {\n            this.updateScrollBarDecorators();\n        }, 0);\n\n        if (this.$foldUnchangedOnInput) {\n            this.foldUnchanged();\n        }\n    }\n\n    setupScrollbars() {\n        /**\n         * @param {Renderer & {$scrollDecorator: ScrollDiffDecorator}} renderer\n         */\n        const setupScrollBar = (renderer) => {\n            setTimeout(() => {\n                this.$setScrollBarDecorators(renderer);\n                this.updateScrollBarDecorators();\n            }, 0);\n        };\n\n        if (this.inlineDiffEditor) {\n            setupScrollBar(this.activeEditor.renderer);\n        }\n        else {\n            setupScrollBar(this.editorA.renderer);\n            setupScrollBar(this.editorB.renderer);\n        }\n\n    }\n\n    $setScrollBarDecorators(renderer) {\n        if (renderer.$scrollDecorator) {\n            renderer.$scrollDecorator.destroy();\n        }\n        renderer.$scrollDecorator = new ScrollDiffDecorator(renderer.scrollBarV, renderer, this.inlineDiffEditor);\n        renderer.$scrollDecorator.setSessions(this.sessionA, this.sessionB);\n        renderer.scrollBarV.setVisible(true);\n        renderer.scrollBarV.element.style.bottom = renderer.scrollBarH.getHeight() + \"px\";\n    }\n\n    $resetDecorators(renderer) {\n        if (renderer.$scrollDecorator) {\n            renderer.$scrollDecorator.destroy();\n        }\n        renderer.$scrollDecorator = new Decorator(renderer.scrollBarV, renderer);\n    }\n\n    updateScrollBarDecorators() {\n        if (this.inlineDiffEditor) {\n            if (!this.activeEditor) {\n                return;\n            }\n            this.activeEditor.renderer.$scrollDecorator.$zones = [];\n        }\n        else {\n            if (!this.editorA || !this.editorB) {\n                return;\n            }\n            this.editorA.renderer.$scrollDecorator.$zones = [];\n            this.editorB.renderer.$scrollDecorator.$zones = [];\n        }\n\n        /**\n         * @param {DiffChunk} change\n         */\n        const updateDecorators = (editor, change) => {\n            if (!editor) {\n                return;\n            }\n            if (typeof editor.renderer.$scrollDecorator.addZone !== \"function\") {\n                return;\n            }\n            if (change.old.start.row != change.old.end.row) {\n                editor.renderer.$scrollDecorator.addZone(change.old.start.row, change.old.end.row - 1, \"delete\");\n            }\n            if (change.new.start.row != change.new.end.row) {\n                editor.renderer.$scrollDecorator.addZone(change.new.start.row, change.new.end.row - 1, \"insert\");\n            }\n        };\n\n        if (this.inlineDiffEditor) {\n            this.chunks && this.chunks.forEach((lineChange) => {\n                updateDecorators(this.activeEditor, lineChange);\n            });\n            this.activeEditor.renderer.$scrollDecorator.$updateDecorators(this.activeEditor.renderer.layerConfig);\n        }\n        else {\n            this.chunks && this.chunks.forEach((lineChange) => {\n                updateDecorators(this.editorA, lineChange);\n                updateDecorators(this.editorB, lineChange);\n            });\n\n            this.editorA.renderer.$scrollDecorator.$updateDecorators(this.editorA.renderer.layerConfig);\n            this.editorB.renderer.$scrollDecorator.$updateDecorators(this.editorB.renderer.layerConfig);\n        }\n    }\n\n    /**\n     *\n     * @param {string[]} val1\n     * @param {string[]} val2\n     * @return {DiffChunk[]}\n     */\n    $diffLines(val1, val2) {\n        return this.diffProvider.compute(val1, val2, {\n            ignoreTrimWhitespace: this.$ignoreTrimWhitespace,\n            maxComputationTimeMs: this.$maxComputationTimeMs\n        });\n    }\n\n    /**\n     * @param {import(\"./providers/default\").DiffProvider} provider\n     */\n    setProvider(provider) {\n        this.diffProvider = provider;\n    }\n\n    /**\n     * @param {EditSession} session\n     * @param {{ rowCount: number; rowsAbove: number; row: number; }} w\n     */\n    $addWidget(session, w) {\n        let lineWidget = session.lineWidgets[w.row];\n        if (lineWidget) {\n            w.rowsAbove += lineWidget.rowsAbove > w.rowsAbove ? lineWidget.rowsAbove : w.rowsAbove;\n            w.rowCount += lineWidget.rowCount;\n        }\n        session.lineWidgets[w.row] = w;\n        session.widgetManager.lineWidgets[w.row] = w;\n        session.$resetRowCache(w.row);\n        var fold = session.getFoldAt(w.row, 0);\n        if (fold) {\n            session.widgetManager.updateOnFold({\n                data: fold,\n                action: \"add\",\n            }, session);\n        }\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    $initWidgets(editor) {\n        var session = editor.session;\n        if (!session) return;\n        if (!session.widgetManager) {\n            session.widgetManager = new LineWidgets(session);\n            session.widgetManager.attach(editor);\n        }\n        session.lineWidgets = [];\n        session.widgetManager.lineWidgets = [];\n        session.$resetRowCache(0);\n    }\n\n    /**\n     * @param {import(\"../../../ace-internal\").Ace.Point} pos\n     * @param {EditSession} session\n     */\n    $screenRow(pos, session) {\n        var row = session.documentToScreenPosition(pos).row;\n        var afterEnd = pos.row - session.getLength() + 1;\n        if (afterEnd > 0) {\n            row += afterEnd;\n        }\n        return row;\n    }\n\n    /**\n     * scroll locking\n     * @abstract\n     **/\n    align() {}\n\n    onChangeWrapLimit(e, session) {}\n\n    onSelect(e, selection) {\n        this.searchHighlight(selection);\n        this.syncSelect(selection);\n    }\n\n    syncSelect(selection) {\n        if (this.$updatingSelection) return;\n        var isOld = selection.session === this.sessionA;\n        var selectionRange = selection.getRange();\n\n        var currSelectionRange = isOld ? this.selectionRangeA : this.selectionRangeB;\n        if (currSelectionRange && selectionRange.isEqual(currSelectionRange))\n            return;\n\n        if (isOld) {\n            this.selectionRangeA = selectionRange;\n        } else {\n            this.selectionRangeB = selectionRange;\n        }\n\n        this.$updatingSelection = true;\n        var newRange = this.transformRange(selectionRange, isOld);\n\n        if (this.$syncSelections) {\n            (isOld ? this.editorB : this.editorA).session.selection.setSelectionRange(newRange);\n        }\n        this.$updatingSelection = false;\n\n        if (isOld) {\n            this.selectionRangeA = selectionRange;\n            this.selectionRangeB = newRange;\n        } else {\n            this.selectionRangeA = newRange;\n            this.selectionRangeB = selectionRange;\n        }\n\n        this.updateSelectionMarker(this.syncSelectionMarkerA, this.sessionA, this.selectionRangeA);\n        this.updateSelectionMarker(this.syncSelectionMarkerB, this.sessionB, this.selectionRangeB);\n    }\n\n    updateSelectionMarker(marker, session, range) {\n        marker.setRange(range);\n        session._signal(\"changeFrontMarker\");\n    }\n\n    /**\n     * @param ev\n     * @param {EditSession} session\n     */\n    onChangeFold(ev, session) {\n        var fold = ev.data;\n        if (this.$syncingFold || !fold || !ev.action) return;\n        this.scheduleRealign();\n\n        const isOrig = session === this.sessionA;\n        const other = isOrig ? this.sessionB : this.sessionA;\n\n        if (ev.action === \"remove\") {\n            if (fold.other) {\n                fold.other.other = null;\n                other.removeFold(fold.other);\n            }\n            else if (fold.lineWidget) {\n                other.widgetManager.addLineWidget(fold.lineWidget);\n                fold.lineWidget = null;\n                if (other[\"$editor\"]) {\n                    other[\"$editor\"].renderer.updateBackMarkers();\n                }\n            }\n        }\n\n        if (ev.action === \"add\") {\n            const range = this.transformRange(fold.range, isOrig);\n            if (range.isEmpty()) {\n                const row = range.start.row + 1;\n                if (other.lineWidgets[row]) {\n                    fold.lineWidget = other.lineWidgets[row];\n                    other.widgetManager.removeLineWidget(fold.lineWidget);\n                    if (other[\"$editor\"]) {\n                        other[\"$editor\"].renderer.updateBackMarkers();\n                    }\n                }\n            }\n            else {\n                this.$syncingFold = true;\n\n                fold.other = other.addFold(fold.placeholder, range);\n                if (fold.other) {\n                    fold.other.other = fold;\n                }\n                this.$syncingFold = false;\n            }\n        }\n    }\n\n    scheduleRealign() {\n        if (!this.realignPending) {\n            this.realignPending = true;\n            this.editorA.renderer.on(\"beforeRender\", this.realign);\n            this.editorB.renderer.on(\"beforeRender\", this.realign);\n        }\n    }\n\n    realign() {\n        this.realignPending = true;\n        this.editorA.renderer.off(\"beforeRender\", this.realign);\n        this.editorB.renderer.off(\"beforeRender\", this.realign);\n        this.align();\n        this.realignPending = false;\n    }\n\n    detach() {\n        if (!this.editorA || !this.editorB) return;\n        if (this.savedOptionsA)\n            this.editorA.setOptions(this.savedOptionsA);\n        if (this.savedOptionsB)\n            this.editorB.setOptions(this.savedOptionsB);\n        this.editorA.renderer.off(\"beforeRender\", this.realign);\n        this.editorB.renderer.off(\"beforeRender\", this.realign);\n        this.$detachEventHandlers();\n        this.$removeLineWidgets(this.sessionA);\n        this.$removeLineWidgets(this.sessionB);\n        this.gutterDecoratorA && this.gutterDecoratorA.dispose();\n        this.gutterDecoratorB && this.gutterDecoratorB.dispose();\n        this.sessionA.selection.clearSelection();\n        this.sessionB.selection.clearSelection();\n\n        if (this.savedOptionsA && this.savedOptionsA.customScrollbar) {\n            this.$resetDecorators(this.editorA.renderer);\n        }\n        if (this.savedOptionsB &&this.savedOptionsB.customScrollbar) {\n            this.$resetDecorators(this.editorB.renderer);\n        }\n        clearTimeout(this.$onInputTimer);\n    }\n\n    $removeLineWidgets(session) {\n        // TODO remove only our widgets\n        // session.widgetManager.removeLineWidget\n        session.lineWidgets = [];\n        session.widgetManager.lineWidgets = [];\n        session._signal(\"changeFold\", {data: {start: {row: 0}}});\n    }\n\n    /**\n     * @abstract\n     */\n    $detachEventHandlers() {\n\n    }\n\n    destroy() {\n        this.detach();\n        this.editorA && this.editorA.destroy();\n        this.editorB && this.editorB.destroy();\n        this.editorA = this.editorB = null;\n    }\n\n    gotoNext(dir) {\n        var ace = this.activeEditor || this.editorA;\n        if (this.inlineDiffEditor) {\n            ace = this.editorA;\n        }\n        var sideA = ace == this.editorA;\n\n        var row = ace.selection.lead.row;\n        var i = this.findChunkIndex(this.chunks, row, sideA);\n        var chunk = this.chunks[i + dir] || this.chunks[i];\n\n        var scrollTop = ace.session.getScrollTop();\n        if (chunk) {\n            var range = chunk[sideA ? \"old\" : \"new\"];\n            var line = Math.max(range.start.row, range.end.row - 1);\n            ace.selection.setRange(new Range(line, 0, line, 0));\n        }\n        ace.renderer.scrollSelectionIntoView(ace.selection.lead, ace.selection.anchor, 0.5);\n        ace.renderer.animateScrolling(scrollTop);\n    }\n\n\n    firstDiffSelected() {\n        return this.currentDiffIndex <= 1;\n    }\n\n    lastDiffSelected() {\n        return this.currentDiffIndex > this.chunks.length - 1;\n    }\n\n    /**\n     * @param {Range} range\n     * @param {boolean} isOriginal\n     */\n    transformRange(range, isOriginal) {\n        return Range.fromPoints(this.transformPosition(range.start, isOriginal), this.transformPosition(range.end, isOriginal));\n    }\n\n    /**\n     * @param {import(\"ace-code\").Ace.Point} pos\n     * @param {boolean} isOriginal\n     * @return {import(\"ace-code\").Ace.Point}\n     */\n    transformPosition(pos, isOriginal) {\n        var chunkIndex = this.findChunkIndex(this.chunks, pos.row, isOriginal);\n\n        var chunk = this.chunks[chunkIndex];\n\n        var clonePos = this.sessionB.doc.clonePos;\n        var result = clonePos(pos);\n\n        var [from, to] = isOriginal ? [\"old\", \"new\"] : [\"new\", \"old\"];\n        var deltaChar = 0;\n        var ignoreIndent = false;\n\n        if (chunk) {\n            if (chunk[from].end.row <= pos.row) {\n                result.row -= chunk[from].end.row - chunk[to].end.row;\n            }\n            else if (chunk.charChanges) {\n                for (let i = 0; i < chunk.charChanges.length; i++) {\n                    let change = chunk.charChanges[i];\n\n                    let fromRange = change[from];\n                    let toRange = change[to];\n\n                    if (fromRange.end.row < pos.row) continue;\n\n                    if (fromRange.start.row > pos.row) break;\n\n                    if (fromRange.isMultiLine() && fromRange.contains(pos.row, pos.column)) {\n                        result.row = toRange.start.row + pos.row - fromRange.start.row;\n                        var maxRow = toRange.end.row;\n                        if (toRange.end.column === 0) maxRow--;\n\n                        if (result.row > maxRow) {\n                            result.row = maxRow;\n                            result.column = (isOriginal ? this.sessionB : this.sessionA).getLine(maxRow).length;\n                            ignoreIndent = true;\n                        }\n                        result.row = Math.min(result.row, maxRow);\n                    }\n                    else {\n                        result.row = toRange.start.row;\n                        if (fromRange.start.column > pos.column) break;\n                        ignoreIndent = true;\n\n                        if (!fromRange.isEmpty() && fromRange.contains(pos.row, pos.column)) {\n                            result.column = toRange.start.column;\n                            deltaChar = pos.column - fromRange.start.column;\n                            deltaChar = Math.min(deltaChar, toRange.end.column - toRange.start.column);\n                        }\n                        else {\n                            result = clonePos(toRange.end);\n                            deltaChar = pos.column - fromRange.end.column;\n                        }\n                    }\n                }\n            }\n            else if (chunk[from].start.row <= pos.row) {\n                result.row += chunk[to].start.row - chunk[from].start.row;\n                if (result.row >= chunk[to].end.row) {\n                    result.row = chunk[to].end.row - 1;\n                    result.column = (isOriginal ? this.sessionB : this.sessionA).getLine(result.row).length;\n                }\n            }\n        }\n\n\n        if (!ignoreIndent) { //TODO:\n            var [fromEditSession, toEditSession] = isOriginal ? [this.sessionA, this.sessionB] : [\n                this.sessionB, this.sessionA\n            ];\n            deltaChar -= this.$getDeltaIndent(fromEditSession, toEditSession, pos.row, result.row);\n        }\n\n        result.column += deltaChar;\n        return result;\n    }\n\n    /**\n     * @param {EditSession} fromEditSession\n     * @param {EditSession} toEditSession\n     * @param {number} fromLine\n     * @param {number} toLine\n     */\n    $getDeltaIndent(fromEditSession, toEditSession, fromLine, toLine) {\n        let origIndent = this.$getIndent(fromEditSession, fromLine);\n        let editIndent = this.$getIndent(toEditSession, toLine);\n        return origIndent - editIndent;\n    }\n\n    /**\n     * @param {EditSession} editSession\n     * @param {number} line\n     */\n    $getIndent(editSession, line) {\n        return editSession.getLine(line).match(/^\\s*/)[0].length;\n    }\n\n    printDiffs() {\n        this.chunks.forEach((diff) => {\n            console.log(diff.toString());\n        });\n    }\n\n    /**\n     *\n     * @param {DiffChunk[]} chunks\n     * @param {number} row\n     * @param {boolean} isOriginal\n     * @return {number}\n     */\n    findChunkIndex(chunks, row, isOriginal) {\n        for (var i = 0; i < chunks.length; i++) {\n            var ch = chunks[i];\n            var chunk = isOriginal ? ch.old : ch.new;\n            if (chunk.end.row < row) continue;\n            if (chunk.start.row > row) break;\n        }\n\n        this.currentDiffIndex = i;\n\n        return i - 1;\n    }\n\n    searchHighlight(selection) {\n        if (this.$syncSelections || this.inlineDiffEditor) {\n            return;\n        }\n        let currSession = selection.session;\n        let otherSession = currSession === this.sessionA\n            ? this.sessionB : this.sessionA;\n        otherSession.highlight(currSession.$searchHighlight.regExp);\n        otherSession._signal(\"changeBackMarker\");\n    }\n\n    initSelectionMarkers() {\n        this.syncSelectionMarkerA = new SyncSelectionMarker();\n        this.syncSelectionMarkerB = new SyncSelectionMarker();\n        this.sessionA.addDynamicMarker(this.syncSelectionMarkerA, true);\n        this.sessionB.addDynamicMarker(this.syncSelectionMarkerB, true);\n    }\n    clearSelectionMarkers() {\n        this.sessionA.removeMarker(this.syncSelectionMarkerA.id);\n        this.sessionB.removeMarker(this.syncSelectionMarkerB.id);\n    }\n}\n\n/*** options ***/\n\nconfig.defineOptions(BaseDiffView.prototype, \"DiffView\", {\n    showOtherLineNumbers: {\n        set: function(value) {\n            if (this.gutterLayer) {\n                this.gutterLayer.$renderer = value ?  null : emptyGutterRenderer;\n                this.editorA.renderer.updateFull();\n            }\n        },\n        initialValue: true\n    },\n    folding: {\n        set: function(value) {\n            this.editorA.setOption(\"showFoldWidgets\", value);\n            this.editorB.setOption(\"showFoldWidgets\", value);\n            if (!value) {\n                var posA = [];\n                var posB = [];\n                if (this.chunks) {\n                    this.chunks.forEach(x=>{\n                        posA.push(x.old.start, x.old.end);\n                        posB.push(x.new.start, x.new.end);\n                     });\n                }\n                this.sessionA.unfold(posA);\n                this.sessionB.unfold(posB);\n            }\n        }\n    },\n    syncSelections: {\n        set: function(value) {\n\n        },\n    },\n    ignoreTrimWhitespace: {\n        set: function(value) {\n            this.scheduleOnInput();\n        },\n    },\n    wrap: {\n        set: function(value) {\n            this.sessionA.setOption(\"wrap\", value);\n            this.sessionB.setOption(\"wrap\", value);\n        }\n    },\n    maxDiffs: {\n        value: 5000,\n    },\n    theme: {\n        set: function(value) {\n            this.setTheme(value);\n        },\n        get: function() {\n            return this.editorA.getTheme();\n        }\n    },\n});\n\nvar emptyGutterRenderer =  {\n    getText: function name(params) {\n        return \"\";\n    },\n    getWidth() {\n        return 0;\n    }\n};\n\nexports.BaseDiffView = BaseDiffView;\n\n\nclass DiffChunk {\n    /**\n     * @param {Range} originalRange\n     * @param {Range} modifiedRange\n     * @param {{originalStartLineNumber: number, originalStartColumn: number,\n     * originalEndLineNumber: number, originalEndColumn: number, modifiedStartLineNumber: number,\n     * modifiedStartColumn: number, modifiedEndLineNumber: number, modifiedEndColumn: number}[]} [charChanges]\n     */\n    constructor(originalRange, modifiedRange, charChanges) {\n        this.old = originalRange;\n        this.new = modifiedRange;\n        this.charChanges = charChanges && charChanges.map(m => new DiffChunk(\n            new Range(m.originalStartLineNumber, m.originalStartColumn,\n                m.originalEndLineNumber, m.originalEndColumn\n            ), new Range(m.modifiedStartLineNumber, m.modifiedStartColumn,\n                m.modifiedEndLineNumber, m.modifiedEndColumn\n            )));\n    }\n}\n\nclass DiffHighlight {\n    /**\n     * @param {import(\"./base_diff_view\").BaseDiffView} diffView\n     * @param type\n     */\n    constructor(diffView, type) {\n        /**@type{number}*/this.id;\n        this.diffView = diffView;\n        this.type = type;\n    }\n\n    update(html, markerLayer, session, config) {\n        let dir, operation, opOperation;\n        var diffView = this.diffView;\n        if (this.type === -1) {// original editor\n            dir = \"old\";\n            operation = \"delete\";\n            opOperation = \"insert\";\n        }\n        else { //modified editor\n            dir = \"new\";\n            operation = \"insert\";\n            opOperation = \"delete\";\n        }\n\n        var ignoreTrimWhitespace = diffView.$ignoreTrimWhitespace;\n        var lineChanges = diffView.chunks;\n\n        if (session.lineWidgets && !diffView.inlineDiffEditor) {\n            for (var row = config.firstRow; row <= config.lastRow; row++) {\n                var lineWidget = session.lineWidgets[row];\n                if (!lineWidget || lineWidget.hidden)\n                    continue;\n\n                let start = session.documentToScreenRow(row, 0);\n\n                if (lineWidget.rowsAbove > 0) {\n                    var range = new Range(start - lineWidget.rowsAbove, 0, start - 1, Number.MAX_VALUE);\n                    markerLayer.drawFullLineMarker(html, range, \"ace_diff aligned_diff\", config);\n                }\n                let end = start + lineWidget.rowCount - (lineWidget.rowsAbove || 0);\n                var range = new Range(start + 1, 0, end, Number.MAX_VALUE);\n                markerLayer.drawFullLineMarker(html, range, \"ace_diff aligned_diff\", config);\n            }\n        }\n\n        lineChanges.forEach((lineChange) => {\n            let startRow = lineChange[dir].start.row;\n            let endRow = lineChange[dir].end.row;\n            if (endRow < config.firstRow || startRow > config.lastRow)\n                return;\n            let range = new Range(startRow, 0, endRow - 1, 1 << 30);\n            if (startRow !== endRow) {\n                range = range.toScreenRange(session);\n\n                markerLayer.drawFullLineMarker(html, range, \"ace_diff \" + operation, config);\n            }\n\n            if (lineChange.charChanges) {\n                for (var i = 0; i < lineChange.charChanges.length; i++) {\n                    var changeRange = lineChange.charChanges[i][dir];\n                    if (changeRange.end.column == 0 && changeRange.end.row > changeRange.start.row && changeRange.end.row == lineChange[dir].end.row ) {\n                        changeRange.end.row --;\n                        changeRange.end.column = Number.MAX_VALUE;\n                    }\n                        \n                    if (ignoreTrimWhitespace) {\n                        for (let lineNumber = changeRange.start.row;\n                             lineNumber <= changeRange.end.row; lineNumber++) {\n                            let startColumn;\n                            let endColumn;\n                            let sessionLineStart = session.getLine(lineNumber).match(/^\\s*/)[0].length;\n                            let sessionLineEnd = session.getLine(lineNumber).length;\n\n                            if (lineNumber === changeRange.start.row) {\n                                startColumn = changeRange.start.column;\n                            }\n                            else {\n                                startColumn = sessionLineStart;\n                            }\n                            if (lineNumber === changeRange.end.row) {\n                                endColumn = changeRange.end.column;\n                            }\n                            else {\n                                endColumn = sessionLineEnd;\n                            }\n                            let range = new Range(lineNumber, startColumn, lineNumber, endColumn);\n                            var screenRange = range.toScreenRange(session);\n\n                            if (sessionLineStart === startColumn && sessionLineEnd === endColumn) {\n                                continue;\n                            }\n\n                            let cssClass = \"inline \" + operation;\n                            if (range.isEmpty() && startColumn !== 0) {\n                                cssClass = \"inline \" + opOperation + \" empty\";\n                            }\n\n                            markerLayer.drawSingleLineMarker(html, screenRange, \"ace_diff \" + cssClass, config);\n                        }\n                    }\n                    else {\n                        let range = new Range(changeRange.start.row, changeRange.start.column,\n                            changeRange.end.row, changeRange.end.column\n                        );\n                        var screenRange = range.toScreenRange(session);\n                        let cssClass = \"inline \" + operation;\n                        if (range.isEmpty() && changeRange.start.column !== 0) {\n                            cssClass = \"inline empty \" + opOperation;\n                        }\n\n                        if (screenRange.isMultiLine()) {\n                            markerLayer.drawTextMarker(html, screenRange, \"ace_diff \" + cssClass, config);\n                        }\n                        else {\n                            markerLayer.drawSingleLineMarker(html, screenRange, \"ace_diff \" + cssClass, config);\n                        }\n                    }\n                }\n            }\n        });\n    }\n}\n\nclass SyncSelectionMarker {\n    constructor() {\n        /**@type{number}*/this.id;\n        this.type = \"fullLine\";\n        this.clazz = \"ace_diff-active-line\";\n    }\n\n    update(html, markerLayer, session, config) {\n    }\n\n    /**\n     * @param {Range} range\n     */\n    setRange(range) {//TODO\n        var newRange = range.clone();\n        newRange.end.column++;\n\n        this.range = newRange;\n    }\n}\n\nexports.DiffChunk = DiffChunk;\nexports.DiffHighlight = DiffHighlight;"
  },
  {
    "path": "src/ext/diff/diff_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"../../test/assertions\");\nrequire(\"../../test/mockdom\");\n\nvar {InlineDiffView} = require(\"./inline_diff_view\");\nvar {SplitDiffView} = require(\"./split_diff_view\");\nvar {DiffProvider} = require(\"./providers/default\");\n\nvar ace = require(\"../../ace\");\nvar Range = require(\"../../range\").Range;\nvar editorA, editorB, diffView;\nconst {Decorator} = require(\"../../layer/decorators\");\nconst {ScrollDiffDecorator} = require(\"./scroll_diff_decorator\");\nvar lang = require(\"../../lib/lang\");\n\n\nvar DEBUG = false;\n\nfunction createEditor() {\n    var editor = ace.edit(null);\n    document.body.appendChild(editor.container);\n    setEditorPosition(editor);\n    return editor;\n}\nfunction setEditorPosition(editor) {\n    editor.container.style.height = \"200px\";\n    editor.container.style.width = \"300px\";\n    editor.container.style.position = \"absolute\";\n    editor.container.style.outline = \"solid\";\n}\n\nfunction getValueA(lines) {\n    return lines.map(function(v) {\n        return v[0];\n    }).filter(function(x) {\n        return x != null;\n    }).join(\"\\n\");\n}\nfunction getValueB(lines) {\n    return lines.map(function(v) {\n        return v.length == 2 ? v[1] : v[0];\n    }).filter(function(x) {\n        return x != null;\n    }).join(\"\\n\");\n}\nvar simpleDiff = [\n    [\"a\"],\n    [\"b\"],\n    [\"c\"],\n    [null, \"inserted1\"],\n    [null, \"inserted2\"],\n    [\"e\"],\n    [\"f\"],\n    [\"g\", \"edited g\"],\n    [\"h\"],\n    [\"i\"],\n];\nvar diffAtEnds = [\n    [null, \"only new\"],\n    [null, \"only new\"],\n    [\"a\"],\n    [\"b\"],\n    [\"c\"],\n    [\"d\"],\n    [\"e\"],\n    [\"f\"],\n    [\"g\"],\n    [\"h\"],\n    [\"i\"],\n    [\"j\"],\n    [\"k\"],\n    [\"only old\", null],\n    [\"only old2\", null],\n];\nvar longLinesDiff = [\n    [null, \"0\"],\n    [\"a\"],\n    [\"b\"],\n    [\"c\", \"edited c \".repeat(100)],\n    [\"e long \".repeat(100)],\n    [\"f\"],\n    [\"g \" + \"to delete \".repeat(100), \"edited g\"],\n    [\"h\"],\n    [\"i\"],\n];\nmodule.exports = {\n    setUpSuite: function() {\n        ace.config.setLoader(function(moduleName, cb) {\n            if (moduleName == \"ace/ext/error_marker\")\n                return cb(null, require(\"../error_marker\"));\n            if (moduleName == \"ace/theme/cloud_editor\")\n                return cb(null, require(\"../../theme/cloud_editor\"));\n        });\n        editorA = createEditor();\n        editorB = createEditor();\n        editorB.container.style.left = \"301px\";\n        editorA.focus();\n    },\n    tearDownSuite: function() {\n        if (DEBUG) return;\n        [editorA, editorB].forEach(function(editor) {\n            if (editor) {\n                editor.destroy();\n                editor.container.remove();\n                editor = null;\n            }\n        });\n    },\n    tearDown: function() {\n        if (DEBUG) return;\n        if (diffView) {\n            diffView.detach();\n            diffView = null;\n        }\n    },\n    \"test: clean detach\": function() {\n        var diffProvider = new DiffProvider();\n\n        editorA.session.setValue(getValueA(simpleDiff));\n        editorB.session.setValue(getValueB(simpleDiff));\n\n        assert.ok(!!editorA.session.widgetManager);\n        assert.ok(!!editorB.session.widgetManager);\n\n        var uid = 0;\n        var saved = {};\n        function saveEventRegistry(object) {\n            var id = object.id;\n            if (!id) {\n                id = object.id = \"unknown\" + (uid++);\n            }\n            var eventRegistry = {};\n            for (var key in object._eventRegistry) {\n                var handlers = object._eventRegistry[key];\n                eventRegistry[key] = handlers.slice(0);\n            }\n            saved[id] = {eventRegistry, object};\n            if (/session/.test(id)) {\n                saved[id].$frontMarkers = Object.keys(object.$frontMarkers);\n            }\n        }\n        function checkEventRegistry() {\n            for (var id in saved) {\n                var object = saved[id].object;\n                var eventRegistry = saved[id].eventRegistry;\n                for (var eventName in object._eventRegistry) {\n                    var handlers = object._eventRegistry[eventName];\n                    var savedHandlers = eventRegistry[eventName] || [];\n                    assert.notEqual(handlers, savedHandlers);\n                    assert.equal(handlers.length, savedHandlers.length, id + \":\" + eventName);\n                    for (var j = 0; j < handlers.length; j++) {\n                        assert.equal(handlers[j], eventRegistry[eventName][j], id + \":\" + eventName);\n                    }\n                }\n                if (saved[id].$frontMarkers) {\n                    var frontMarkers = Object.keys(object.$frontMarkers);\n                    assert.equal(frontMarkers + \"\", saved[id].$frontMarkers + \"\", id);\n                }\n            }\n        }\n        saveEventRegistry(editorA);\n        saveEventRegistry(editorB);\n        saveEventRegistry(editorA.session);\n        saveEventRegistry(editorB.session);\n        saveEventRegistry(editorA.renderer);\n        saveEventRegistry(editorB.renderer);\n\n        var diffView = new InlineDiffView({\n            editorA, editorB,\n            inline: \"a\",\n            diffProvider,\n        });\n        editorA.session.addFold(\"---\", new Range(0, 0, 2, 0));\n        diffView.onInput();\n        diffView.resize(true);\n        \n        assert.equal(editorA.session.$foldData.length, 1);\n        assert.equal(editorB.session.$foldData.length, 1);\n        \n        diffView.detach();\n        var sessionB = editorB.session;\n        sessionB.widgetManager.attach(editorB);\n        checkEventRegistry();\n\n        diffView = new SplitDiffView({editorA, editorB, diffProvider});\n        editorB.session.addFold(\"---\", new Range(5, 0, 7, 0));\n        editorB.renderer.$loop._flush();\n        editorA.renderer.$loop._flush();\n        assert.equal(editorA.session.$foldData.length, 2);\n        assert.equal(editorB.session.$foldData.length, 2);\n        \n        diffView.onInput();\n        diffView.resize(true);\n\n        diffView.setTheme(\"ace/theme/cloud_editor\");\n        assert.equal(diffView.editorA.getTheme(), \"ace/theme/cloud_editor\");\n        assert.equal(diffView.editorB.getTheme(), \"ace/theme/cloud_editor\");\n\n        diffView.editorB.setTheme(\"ace/theme/textmate\");\n        assert.equal(diffView.editorA.getTheme(), \"ace/theme/textmate\");\n        assert.equal(diffView.editorB.getTheme(), \"ace/theme/textmate\");\n\n        diffView.detach();\n        checkEventRegistry();\n\n\n        var diffView = new InlineDiffView({\n            editorB, valueA: editorA.getValue(),\n            inline: \"b\",\n            diffProvider,\n        });\n\n        diffView.onInput();\n        diffView.resize(true);\n\n        diffView.detach();\n        checkEventRegistry();\n\n    },\n    \"test: diff at ends\": function() {\n        var diffProvider = new DiffProvider();\n\n        var valueA = getValueA(diffAtEnds);\n        var valueB = getValueB(diffAtEnds);\n\n        diffView = new InlineDiffView({\n            valueA,\n            valueB,\n            inline: \"a\",\n            diffProvider,\n        }, document.body);\n        setEditorPosition(diffView.editorA);\n        diffView.onInput();\n        diffView.resize(true);\n        var lineHeight = diffView.editorA.renderer.lineHeight;\n        assert.ok(diffView.editorA.renderer.lineHeight > 0);\n        assert.equal(diffView.chunks.length, 2);\n        assert.equal(diffView.editorA.renderer.layerConfig.offset, 0);\n        diffView.sessionA.setScrollTop(lineHeight * 1.5);\n        diffView.resize(true);\n        assert.equal(diffView.editorA.renderer.layerConfig.offset, 0.5 * lineHeight);\n        diffView.detach();\n\n        diffView = new SplitDiffView({\n            valueA,\n            valueB,\n            diffProvider,\n        }, document.body);\n        setEditorPosition(diffView.editorA);\n        setEditorPosition(diffView.editorB);\n        diffView.onInput();\n        diffView.resize(true);\n        assert.equal(diffView.chunks.length, 2);\n\n        diffView.detach();\n\n        diffView = new InlineDiffView({\n            valueA,\n            valueB,\n            inline: \"b\",\n        }, document.body);\n        setEditorPosition(diffView.editorB);\n        diffView.onInput();\n        diffView.resize(true);\n        assert.equal(diffView.chunks.length, 0);\n        diffView.detach();\n    },\n    \"test scroll\": function() {\n        var diffProvider = new DiffProvider();\n\n        var valueA = getValueA(diffAtEnds);\n        var valueB = getValueB(diffAtEnds);\n\n        editorA.session.setValue(valueA);\n        editorB.session.setValue(valueB);\n\n        diffView = new SplitDiffView({\n            editorA, editorB,\n            diffProvider,\n        });\n\n\n        diffView.onInput();\n        diffView.resize(true);\n        assert.equal(diffView.chunks.length, 2);\n\n        diffView.setDiffSession({\n            sessionA: ace.createEditSession(valueA.repeat(20)),\n            sessionB: ace.createEditSession(valueB.repeat(20)),\n        });\n\n        diffView.onInput();\n        diffView.resize(true);\n        assert.equal(diffView.chunks.length, 21);\n        diffView.editorA.setOption(\"animatedScroll\", false);\n        diffView.editorB.setOption(\"animatedScroll\", false);\n\n        diffView.editorA.execCommand(\"gotoend\");\n        diffView.editorB.renderer.$loop._flush();\n        diffView.editorA.renderer.$loop._flush();\n\n        assert.ok(diffView.sessionB.$scrollTop > 100);\n        assert.ok(diffView.sessionA.$scrollTop == diffView.sessionB.$scrollTop);\n\n        diffView.toggleFoldUnchanged();\n        assert.equal(diffView.sessionA.$foldData.length, 20);\n        assert.equal(diffView.sessionA.$foldData.length, 20);\n        diffView.toggleFoldUnchanged();\n        assert.equal(diffView.sessionA.$foldData.length, 0);\n        assert.equal(diffView.sessionA.$foldData.length, 0);\n\n    },\n    \"test line widget at both sides of line\": function() {\n        var diffProvider = new DiffProvider();\n\n        editorA.session.setValue(\"a\\n\");\n        editorB.session.setValue(\"\\n\\na\\n\\n\");\n\n        diffView = new SplitDiffView({\n            editorA, editorB,\n            diffProvider,\n        });\n        diffView.onInput();\n        diffView.resize(true);\n        var markers = diffView.editorA.renderer.$markerBack.element.childNodes;\n        assert.equal(markers[0].className, \"ace_diff aligned_diff\");\n        assert.equal(markers[1].className, \"ace_diff aligned_diff\");\n        assert.equal(markers.length, 4);\n    },\n\n    \"test: toggle wrap\": function() {\n        var diffProvider = new DiffProvider();\n\n        editorA.session.setValue(getValueA(longLinesDiff));\n        editorB.session.setValue(getValueB(longLinesDiff));\n\n        diffView = new SplitDiffView({\n            editorA, editorB,\n            diffProvider,\n        });\n        diffView.onInput();\n        diffView.setOptions({\n            wrap: 20,\n            syncSelections: true,\n        });\n        diffView.resize(true);\n        diffView.gotoNext(1);\n        diffView.gotoNext(1);\n        var posA = diffView.sessionA.documentToScreenPosition(diffView.editorA.getCursorPosition());\n        var posB = diffView.sessionB.documentToScreenPosition(diffView.editorB.getCursorPosition());\n        assert.equal(posA.row, posB.row);\n    },\n\n    \"test: restore options\": function() {\n        var diffProvider = new DiffProvider();\n\n        editorA.session.setValue(getValueA(simpleDiff));\n        editorB.session.setValue(getValueB(simpleDiff));\n        editorA.setOption(\"customScrollbar\", true);\n\n        diffView = new InlineDiffView({\n            editorA, editorB,\n            inline: \"a\",\n            diffProvider,\n        });\n        diffView.onInput();\n        diffView.setOptions({\n            wrap: true,\n            folding: false,\n            showOtherLineNumbers: false,\n        });\n        diffView.resize(true);\n        assert.equal(diffView.chunks.length, 2);\n        assert.equal(editorA.getOption(\"wrap\"), \"free\");\n        assert.equal(diffView.editorB.getOption(\"wrap\"), \"free\");\n\n        assert.equal(editorA.getOption(\"fadeFoldWidgets\"), true);\n        assert.equal(diffView.editorB.getOption(\"fadeFoldWidgets\"), true);\n\n        assert.equal(diffView.editorA.getOption(\"showFoldWidgets\"), false);\n        assert.equal(diffView.editorB.getOption(\"showFoldWidgets\"), false);\n\n        assert.ok(!!diffView.editorB.renderer.$gutterLayer.$renderer);\n\n        assert.ok(editorA.renderer.$scrollDecorator instanceof ScrollDiffDecorator);\n\n        diffView.detach();\n\n        assert.equal(editorA.getOption(\"wrap\"), \"free\");\n        assert.equal(editorA.getOption(\"fadeFoldWidgets\"), false);\n        assert.equal(editorA.getOption(\"showFoldWidgets\"), true);\n\n        assert.equal(editorB.getOption(\"wrap\"), \"free\");\n        assert.equal(editorB.getOption(\"fadeFoldWidgets\"), false);\n        assert.equal(editorB.getOption(\"showFoldWidgets\"), true);\n        assert.ok(!editorB.renderer.$gutterLayer.$renderer);\n\n        assert.ok(editorA.renderer.$scrollDecorator instanceof Decorator);\n    },\n    \"test split diff scroll decorators\": async function(done) {\n        editorA.session.setValue([\"a\", \"b\", \"c\"].join(\"\\n\"));\n        editorB.session.setValue([\"a\", \"c\", \"X\"].join(\"\\n\"));\n\n        diffView = new SplitDiffView({ editorA, editorB });\n        diffView.setProvider(new DiffProvider());\n        diffView.onInput();\n\n\n        editorA.renderer.$loop._flush();\n        editorB.renderer.$loop._flush();\n\n        await lang.sleep(0);\n        assertDecoratorsPlacement(editorA, false);\n        done();\n    },\n    \"test inline diff scroll decorators\": async function(done) {\n        editorA.session.setValue([\"a\", \"b\", \"c\"].join(\"\\n\"));\n        editorB.session.setValue([\"a\", \"c\", \"X\"].join(\"\\n\"));\n\n        diffView = new InlineDiffView({ editorA, editorB, inline: \"a\" });\n        diffView.setProvider(new DiffProvider());\n        diffView.onInput();\n\n        editorA.renderer.$loop._flush();\n\n        await lang.sleep(0);\n        assertDecoratorsPlacement(editorA, true);\n        done();\n    },\n    \"test: second editor destroyed on detach in inline diff view\": function() {\n        editorA.setOption(\"wrap\", \"free\");\n        diffView = new InlineDiffView({ editorA, inline: \"a\" });\n\n        assert.equal(diffView.editorB.getOption(\"wrap\"), \"free\");\n\n        assert.ok(!diffView.otherEditor.destroyed);\n        diffView.detach();\n        assert.ok(diffView.otherEditor.destroyed);\n    },\n    \"test: wrap stays in sync\": function() {\n        editorA.setOption(\"wrap\", \"off\");\n        diffView = new InlineDiffView({ editorA, inline: \"a\" });\n\n        assert.equal(diffView.editorB.getOption(\"wrap\"), \"off\");\n        assert.equal(diffView.editorA.getOption(\"wrap\"), \"off\");\n\n        editorA.setOption(\"wrap\", \"free\");\n        assert.equal(diffView.editorB.getOption(\"wrap\"), \"free\");\n        assert.equal(diffView.editorA.getOption(\"wrap\"), \"free\");\n\n        diffView.detach();\n\n\n        editorB.setOption(\"wrap\", 40);\n        diffView = new InlineDiffView({ editorB, inline: \"b\" });\n\n        assert.equal(diffView.editorB.getOption(\"wrap\"), 40);\n        assert.equal(diffView.editorA.getOption(\"wrap\"), 40);\n\n        editorB.setOption(\"wrap\", \"free\");\n        assert.equal(diffView.editorB.getOption(\"wrap\"), \"free\");\n        assert.equal(diffView.editorA.getOption(\"wrap\"), \"free\");\n\n        editorB.setOption(\"wrap\", 50);\n        assert.equal(diffView.editorB.getOption(\"wrap\"), 50);\n        assert.equal(diffView.editorA.getOption(\"wrap\"), 50);\n\n        diffView.detach();\n    }\n};\n\nfunction findPointFillStyle(imageData, y) {\n    const data = imageData.slice(4 * y, 4 * (y + 1));\n    const a = Math.round(data[3] / 256 * 100);\n    if (a === 100) return \"rgb(\" + data.slice(0, 3).join(\",\") + \")\";\n    return \"rgba(\" + data.slice(0, 3).join(\",\") + \",\" + (a / 100) + \")\";\n}\n\nfunction assertDecoratorsPlacement(editor, inlineDiff) {\n    const decoA = editor.renderer.$scrollDecorator;\n    const ctxA = decoA.canvas.getContext(\"2d\");\n    const delRow = 1;\n    const offA = decoA.sessionA.documentToScreenRow(delRow, 0) * decoA.lineHeight;\n    const centerA = offA + decoA.lineHeight / 2;\n    const yA = Math.round(decoA.heightRatio * centerA);\n    let imgA = ctxA.getImageData(decoA.oneZoneWidth, 0, 1, decoA.canvasHeight).data;\n    assert.equal(findPointFillStyle(imgA, yA), decoA.colors.light.delete);\n\n    if (inlineDiff) {\n        //make sure that in inline diff, markers fills the whole line (except error decorators part)\n        imgA = ctxA.getImageData(decoA.canvasWidth - 1, 0, 1, decoA.canvasHeight).data;\n        assert.equal(findPointFillStyle(imgA, yA), decoA.colors.light.delete);\n    }\n\n    const xB = decoA.oneZoneWidth * 2;\n    const imgB = ctxA.getImageData(xB, 0, 1, decoA.canvasHeight).data;\n\n    const insRow = 2;\n    const offB = decoA.sessionB.documentToScreenRow(insRow, 0) * decoA.lineHeight;\n    const centerB = offB + decoA.lineHeight / 2;\n    const yB = Math.round(decoA.heightRatio * centerB);\n    assert.equal(findPointFillStyle(imgB, yB), decoA.colors.light.insert);\n}\n\nrequire(\"../../test/run\")(module);"
  },
  {
    "path": "src/ext/diff/gutter_decorator.js",
    "content": "var dom = require(\"../../lib/dom\");\n\nclass MinimalGutterDiffDecorator {\n    /**\n     * @param {import(\"../../editor\").Editor} editor\n     * @param {number} type\n     */\n    constructor(editor, type) {\n        this.gutterClass =\"ace_mini-diff_gutter-enabled\";\n        this.gutterCellsClasses = {\n            add: \"mini-diff-added\",\n            delete: \"mini-diff-deleted\",\n        };\n\n        this.editor = editor;\n        this.type = type;\n        this.chunks = [];\n        this.attachToEditor();\n    }\n\n    attachToEditor() {\n        this.renderGutters = this.renderGutters.bind(this);\n\n        dom.addCssClass(\n            this.editor.renderer.$gutterLayer.element,\n            this.gutterClass\n        );\n        this.editor.renderer.$gutterLayer.on(\n            \"afterRender\",\n            this.renderGutters\n        );\n    }\n\n    renderGutters(e, gutterLayer) {\n        const cells = this.editor.renderer.$gutterLayer.$lines.cells;\n        cells.forEach((cell) => {\n            cell.element.classList.remove(Object.values(this.gutterCellsClasses));\n        });\n        const dir = this.type === -1 ? \"old\" : \"new\";\n        const diffClass = this.type === -1 ? this.gutterCellsClasses.delete : this.gutterCellsClasses.add;\n        this.chunks.forEach((lineChange) => {\n            let startRow = lineChange[dir].start.row;\n            let endRow = lineChange[dir].end.row - 1;\n\n            cells.forEach((cell) => {\n                if (cell.row >= startRow && cell.row <= endRow) {\n                    cell.element.classList.add(diffClass);\n                }\n            });\n        });\n    }\n\n    setDecorations(changes) {\n        this.chunks = changes;\n        this.renderGutters();\n    }\n\n    dispose() {\n        dom.removeCssClass(\n            this.editor.renderer.$gutterLayer.element,\n            this.gutterClass\n        );\n        this.editor.renderer.$gutterLayer.off(\n            \"afterRender\",\n            this.renderGutters\n        );\n    }\n}\n\nexports.MinimalGutterDiffDecorator = MinimalGutterDiffDecorator;\n"
  },
  {
    "path": "src/ext/diff/inline_diff_view.js",
    "content": "\"use strict\";\n\n\nconst BaseDiffView = require(\"./base_diff_view\").BaseDiffView;\nconst Renderer = require(\"../../virtual_renderer\").VirtualRenderer;\nconst config = require(\"../../config\");\n\nclass InlineDiffView extends BaseDiffView {\n    /**\n     * Constructs a new inline DiffView instance.\n     * @param {import(\"../diff\").DiffModel} [diffModel] - The model for the diff view.\n     * @param {HTMLElement} [container] - optional container element for the DiffView.\n     */\n    constructor(diffModel, container) {\n        diffModel = diffModel || {};\n        diffModel.inline = diffModel.inline || \"a\";\n        super( true, container);\n        this.init(diffModel);\n    }\n\n    init(diffModel) {\n        this.onSelect = this.onSelect.bind(this);\n        this.onAfterRender = this.onAfterRender.bind(this);\n        \n\n        this.$setupModels(diffModel);\n        this.onChangeTheme();\n        config.resetOptions(this);\n        config[\"_signal\"](\"diffView\", this);\n\n        var padding = this.activeEditor.renderer.$padding;\n\n        this.addGutterDecorators();\n\n        this.otherEditor.renderer.setPadding(padding);\n        this.textLayer = this.otherEditor.renderer.$textLayer;\n        this.markerLayer = this.otherEditor.renderer.$markerBack;\n        this.gutterLayer = this.otherEditor.renderer.$gutterLayer;\n        this.cursorLayer = this.otherEditor.renderer.$cursorLayer;\n\n        this.otherEditor.renderer.$updateCachedSize = function() {\n        };\n\n        var textLayerElement = this.activeEditor.renderer.$textLayer.element;\n        textLayerElement.parentNode.insertBefore(\n            this.textLayer.element,\n            textLayerElement\n        );\n\n        var markerLayerElement = this.activeEditor.renderer.$markerBack.element;\n        markerLayerElement.parentNode.insertBefore(\n            this.markerLayer.element,\n            markerLayerElement.nextSibling\n        );\n\n        var gutterLayerElement = this.activeEditor.renderer.$gutterLayer.element;\n        gutterLayerElement.parentNode.insertBefore(\n            this.gutterLayer.element,\n            gutterLayerElement.nextSibling\n        );\n        gutterLayerElement.style.position = \"absolute\";\n        this.gutterLayer.element.style.position = \"absolute\";\n        this.gutterLayer.element.style.width = \"100%\";\n        this.gutterLayer.element.classList.add(\"ace_mini-diff_gutter_other\");\n        \n\n        this.gutterLayer.$updateGutterWidth = function() {};\n        this.initMouse();\n        this.initTextInput();\n        this.initTextLayer();\n        this.initRenderer();\n\n        this.$attachEventHandlers();\n        this.selectEditor(this.activeEditor);\n    }\n\n    initRenderer(restore) {\n        if (restore) {\n            delete this.activeEditor.renderer.$getLongestLine;\n        } else {\n            this.editorA.renderer.$getLongestLine =\n            this.editorB.renderer.$getLongestLine = () => {\n                var getLongestLine = Renderer.prototype.$getLongestLine;\n                return Math.max(\n                    getLongestLine.call(this.editorA.renderer),\n                    getLongestLine.call(this.editorB.renderer)\n                );\n            };\n        }\n    }\n\n    initTextLayer() {\n        var renderLine = this.textLayer.$renderLine;\n        var diffView = this;\n        this.otherEditor.renderer.$textLayer.$renderLine = function(parent, row, foldLIne) {\n            if (isVisibleRow(diffView.chunks, row)) {\n                renderLine.call(this, parent, row, foldLIne);\n            }\n        };\n        var side = this.showSideA ? \"new\" : \"old\";\n        function isVisibleRow(chunks, row) {\n            var min = 0;\n            var max = chunks.length - 1;\n            var result = -1;\n            while (min < max) {\n                var mid = Math.floor((min + max) / 2);\n                var chunkStart = chunks[mid][side].start.row;\n                if (chunkStart < row) {\n                    result = mid;\n                    min = mid + 1;\n                } else if (chunkStart > row) {\n                    max = mid - 1;\n                } else {\n                    result = mid;\n                    break;\n                }\n            }\n            if (chunks[result + 1] && chunks[result + 1][side].start.row <= row) {\n                result++;\n            }\n            var range = chunks[result] && chunks[result][side];\n            if (range && range.end.row > row) {\n                return true;\n            }\n            return false;\n        }\n    }\n\n    initTextInput(restore) {\n        if (restore) {\n            this.otherEditor.textInput = this.othertextInput;\n            this.otherEditor.container = this.otherEditorContainer;\n        } else {\n            this.othertextInput = this.otherEditor.textInput;\n            this.otherEditor.textInput = this.activeEditor.textInput;\n            this.otherEditorContainer = this.otherEditor.container;\n            this.otherEditor.container = this.activeEditor.container;\n        }\n    }\n\n    selectEditor(editor) {\n        if (editor == this.activeEditor) {\n            this.otherEditor.selection && this.otherEditor.selection.clearSelection();\n            this.activeEditor.textInput.setHost(this.activeEditor);\n            this.activeEditor.setStyle(\"ace_diff_other\", false);\n            this.cursorLayer.element.remove();\n            this.activeEditor.renderer.$cursorLayer.element.style.display = \"block\";\n            if (this.showSideA) {\n                this.sessionA.removeMarker(this.syncSelectionMarkerA.id);\n                this.sessionA.addDynamicMarker(this.syncSelectionMarkerA, true);\n            }\n            this.markerLayer.element.classList.add(\"ace_hidden_marker-layer\");\n            this.activeEditor.renderer.$markerBack.element.classList.remove(\"ace_hidden_marker-layer\");\n            this.removeBracketHighlight(this.otherEditor); \n        } else {\n            this.activeEditor.selection && this.activeEditor.selection.clearSelection();\n            this.activeEditor.textInput.setHost(this.otherEditor);\n            this.activeEditor.setStyle(\"ace_diff_other\");\n            this.activeEditor.renderer.$cursorLayer.element.parentNode.appendChild(\n                this.cursorLayer.element\n            );\n            this.activeEditor.renderer.$cursorLayer.element.style.display = \"none\";\n            if (this.activeEditor.$isFocused) {\n                this.otherEditor.onFocus();\n            }\n            if (this.showSideA) {\n                this.sessionA.removeMarker(this.syncSelectionMarkerA.id);\n            }\n            this.markerLayer.element.classList.remove(\"ace_hidden_marker-layer\");\n            this.activeEditor.renderer.$markerBack.element.classList.add(\"ace_hidden_marker-layer\");\n            this.removeBracketHighlight(this.activeEditor); \n        }\n    }\n\n    removeBracketHighlight(editor) {\n        var session = editor.session;\n        if (session && session.$bracketHighlight) {\n            session.$bracketHighlight.markerIds.forEach(function(id) {\n                session.removeMarker(id);\n            });\n            session.$bracketHighlight = null;\n        }\n    }\n\n    initMouse() {\n        this.otherEditor.renderer.$loop = this.activeEditor.renderer.$loop;\n        \n        this.otherEditor.renderer.scroller = {\n            getBoundingClientRect: () => {\n                return this.activeEditor.renderer.scroller.getBoundingClientRect();\n            },\n            style: this.activeEditor.renderer.scroller.style,\n        };\n        \n        var forwardEvent = (ev) => {\n            if (!ev.domEvent) return; \n            var screenPos = ev.editor.renderer.pixelToScreenCoordinates(ev.clientX, ev.clientY);\n            var sessionA = this.activeEditor.session;\n            var sessionB = this.otherEditor.session;\n            var posA = sessionA.screenToDocumentPosition(screenPos.row, screenPos.column, screenPos.offsetX); \n            var posB = sessionB.screenToDocumentPosition(screenPos.row, screenPos.column, screenPos.offsetX); \n        \n            var posAx = sessionA.documentToScreenPosition(posA); \n            var posBx = sessionB.documentToScreenPosition(posB); \n            \n            if (ev.editor == this.activeEditor) {\n                if (posBx.row == screenPos.row && posAx.row != screenPos.row) {\n                    if (ev.type == \"mousedown\") {\n                        this.selectEditor(this.otherEditor);\n                    }\n                    ev.propagationStopped = true;\n                    ev.defaultPrevented = true;\n                    this.otherEditor.$mouseHandler.onMouseEvent(ev.type, ev.domEvent);\n                } else if (ev.type == \"mousedown\") {\n                    this.selectEditor(this.activeEditor);\n                }\n            }\n        };\n        \n        \n        var events = [\n            \"mousedown\",\n            \"click\",\n            \"mouseup\",\n            \"dblclick\",\n            \"tripleclick\",\n            \"quadclick\",\n        ];\n        events.forEach((event) => {\n            this.activeEditor.on(event, forwardEvent, true);\n            this.activeEditor.on(\"gutter\" + event, forwardEvent, true);\n        });\n\n        var onFocus = (e) => {\n            this.activeEditor.onFocus(e);\n        };\n        var onBlur = (e) => {\n            this.activeEditor.onBlur(e);\n        };\n        this.otherEditor.on(\"focus\", onFocus);\n        this.otherEditor.on(\"blur\", onBlur);\n\n        this.onMouseDetach = () => {\n            events.forEach((event) => {\n                this.activeEditor.off(event, forwardEvent, true);\n                this.activeEditor.off(\"gutter\" + event, forwardEvent, true);\n            });\n            this.otherEditor.off(\"focus\", onFocus);\n            this.otherEditor.off(\"blur\", onBlur);\n        };\n    }\n\n    align() {\n        var diffView = this;\n\n        this.$initWidgets(diffView.editorA);\n        this.$initWidgets(diffView.editorB);\n\n        diffView.chunks.forEach(function (ch) {\n            var diff1 = diffView.$screenRow(ch.old.end, diffView.sessionA)\n                - diffView.$screenRow(ch.old.start, diffView.sessionA);\n            var diff2 = diffView.$screenRow(ch.new.end, diffView.sessionB)\n                - diffView.$screenRow(ch.new.start, diffView.sessionB);\n\n            diffView.$addWidget(diffView.sessionA, {\n                rowCount: diff2,\n                rowsAbove: ch.old.end.row === 0 ? diff2 : 0,\n                row: ch.old.end.row === 0 ? 0 : ch.old.end.row - 1\n            });\n            diffView.$addWidget(diffView.sessionB, {\n                rowCount: diff1,\n                rowsAbove: diff1,\n                row: ch.new.start.row,\n            });\n\n        });\n        diffView.sessionA[\"_emit\"](\"changeFold\", {data: {start: {row: 0}}});\n        diffView.sessionB[\"_emit\"](\"changeFold\", {data: {start: {row: 0}}});\n    }\n\n    onChangeWrapLimit(e, session) {\n        this.otherSession.setOption(\"wrap\", session.getOption(\"wrap\"));\n        this.otherSession.adjustWrapLimit(session.$wrapLimit);\n        this.scheduleRealign();\n        // todo, this is needed because editor.onChangeWrapMode\n        // calls resize(true) instead of waiting for the renderloop\n        this.activeEditor.renderer.updateFull();\n    }\n\n    $attachSessionsEventHandlers() {\n        this.$attachSessionEventHandlers(this.editorA, this.markerA);\n        this.$attachSessionEventHandlers(this.editorB, this.markerB);\n        var session = this.activeEditor.session;\n        session.on(\"changeWrapLimit\", this.onChangeWrapLimit);\n        session.on(\"changeWrapMode\", this.onChangeWrapLimit);\n    }\n\n    $attachSessionEventHandlers(editor, marker) {\n        editor.session.on(\"changeFold\", this.onChangeFold);\n        editor.session.addDynamicMarker(marker);\n        editor.selection.on(\"changeCursor\", this.onSelect);\n        editor.selection.on(\"changeSelection\", this.onSelect);\n    }\n\n    $detachSessionsEventHandlers() {\n        this.$detachSessionHandlers(this.editorA, this.markerA);\n        this.$detachSessionHandlers(this.editorB, this.markerB);\n        this.otherSession.bgTokenizer.lines.fill(undefined);\n        var session = this.activeEditor.session;\n        session.off(\"changeWrapLimit\", this.onChangeWrapLimit);\n        session.off(\"changeWrapMode\", this.onChangeWrapLimit);\n    }\n\n    $detachSessionHandlers(editor, marker) {\n        if (!editor.session) return;\n        editor.session.removeMarker(marker.id);\n        editor.selection.off(\"changeCursor\", this.onSelect);\n        editor.selection.off(\"changeSelection\", this.onSelect);\n        editor.session.off(\"changeFold\", this.onChangeFold);\n    }\n\n    $attachEventHandlers() {\n        this.activeEditor.on(\"input\", this.onInput);\n        this.activeEditor.renderer.on(\"afterRender\", this.onAfterRender);\n        this.otherSession.on(\"change\", this.onInput);\n    }\n\n    $detachEventHandlers() {\n        this.$detachSessionsEventHandlers();\n        this.activeEditor.off(\"input\", this.onInput);\n        this.activeEditor.renderer.off(\"afterRender\", this.onAfterRender);\n        this.otherSession.off(\"change\", this.onInput);\n\n        this.textLayer.element.textContent = \"\";\n        this.textLayer.element.remove();\n        this.gutterLayer.element.textContent = \"\";\n        this.gutterLayer.element.remove();\n        this.markerLayer.element.textContent = \"\";\n        this.markerLayer.element.remove();\n\n        this.onMouseDetach();\n\n        this.selectEditor(this.activeEditor);\n        this.clearSelectionMarkers();\n        this.otherEditor.setSession(null);\n        this.otherEditor.renderer.$loop = null;\n        this.initTextInput(true);\n        this.initRenderer(true);\n\n        this.otherEditor.destroy();\n    }\n\n    /**\n     * @param {number} changes\n     * @param {import(\"ace-code\").VirtualRenderer} renderer\n     */\n    onAfterRender(changes, renderer) {\n        var config = renderer.layerConfig;\n\n        var session = this.otherSession;\n        var cloneRenderer = this.otherEditor.renderer;\n\n        session.$scrollTop = renderer.scrollTop;\n        session.$scrollLeft = renderer.scrollLeft;\n\n        [\n            \"characterWidth\",\n            \"lineHeight\",\n            \"scrollTop\",\n            \"scrollLeft\",\n            \"scrollMargin\",\n            \"$padding\",\n            \"$size\",\n            \"layerConfig\",\n            \"$horizScroll\",\n            \"$vScroll\",\n        ]. forEach(function(prop) {\n            cloneRenderer[prop] = renderer[prop];\n        });\n\n        cloneRenderer.$computeLayerConfig();\n\n        var newConfig = cloneRenderer.layerConfig;\n        \n        this.gutterLayer.update(newConfig);\n\n        newConfig.firstRowScreen = config.firstRowScreen;\n        \n        cloneRenderer.$cursorLayer.config = newConfig;\n        cloneRenderer.$cursorLayer.update(newConfig);\n\n        if (changes & cloneRenderer.CHANGE_LINES\n            || changes & cloneRenderer.CHANGE_FULL\n            || changes & cloneRenderer.CHANGE_SCROLL\n            || changes & cloneRenderer.CHANGE_TEXT\n        )\n            this.textLayer.update(newConfig);\n\n        this.markerLayer.setMarkers(this.otherSession.getMarkers());\n        this.markerLayer.update(newConfig);\n    }\n\n    detach() {\n        super.detach();\n        this.otherEditor && this.otherEditor.destroy();\n    }\n}\n\nexports.InlineDiffView = InlineDiffView;\n"
  },
  {
    "path": "src/ext/diff/providers/default.js",
    "content": "'use strict';\n\nfunction equals(one, other, itemEquals = (a, b) => a === b) {\n  if (one === other) {\n    return true;\n  }\n  if (!one || !other) {\n    return false;\n  }\n  if (one.length !== other.length) {\n    return false;\n  }\n  for (let i = 0, len = one.length; i < len; i++) {\n    if (!itemEquals(one[i], other[i])) {\n      return false;\n    }\n  }\n  return true;\n}\nfunction* groupAdjacentBy(items, shouldBeGrouped) {\n  let currentGroup;\n  let last;\n  for (const item of items) {\n    if (last !== undefined && shouldBeGrouped(last, item)) {\n      currentGroup.push(item);\n    } else {\n      if (currentGroup) {\n        yield currentGroup;\n      }\n      currentGroup = [item];\n    }\n    last = item;\n  }\n  if (currentGroup) {\n    yield currentGroup;\n  }\n}\nfunction forEachAdjacent(arr, f) {\n  for (let i = 0; i <= arr.length; i++) {\n    f(i === 0 ? undefined : arr[i - 1], i === arr.length ? undefined : arr[i]);\n  }\n}\nfunction forEachWithNeighbors(arr, f) {\n  for (let i = 0; i < arr.length; i++) {\n    f(i === 0 ? undefined : arr[i - 1], arr[i], i + 1 === arr.length ? undefined : arr[i + 1]);\n  }\n}\nfunction pushMany(arr, items) {\n  for (const item of items) {\n    arr.push(item);\n  }\n}\nfunction compareBy(selector, comparator) {\n  return (a, b) => comparator(selector(a), selector(b));\n}\nconst numberComparator = (a, b) => a - b;\nfunction reverseOrder(comparator) {\n  return (a, b) => -comparator(a, b);\n}\n\nclass BugIndicatingError extends Error {\n  constructor(message) {\n    super(message || \"An unexpected bug occurred.\");\n    Object.setPrototypeOf(this, BugIndicatingError.prototype);\n  }\n}\n\nfunction assert(condition, message = \"unexpected state\") {\n  if (!condition) {\n    throw new BugIndicatingError(`Assertion Failed: ${message}`);\n  }\n}\nfunction assertFn(condition) {\n  condition();\n}\nfunction checkAdjacentItems(items, predicate) {\n  let i = 0;\n  while (i < items.length - 1) {\n    const a = items[i];\n    const b = items[i + 1];\n    if (!predicate(a, b)) {\n      return false;\n    }\n    i++;\n  }\n  return true;\n}\n\nclass OffsetRange {\n  constructor(start, endExclusive) {\n    this.start = start;\n    this.endExclusive = endExclusive;\n    if (start > endExclusive) {\n      throw new BugIndicatingError(`Invalid range: ${this.toString()}`);\n    }\n  }\n  static fromTo(start, endExclusive) {\n    return new OffsetRange(start, endExclusive);\n  }\n  static addRange(range, sortedRanges) {\n    let i = 0;\n    while (i < sortedRanges.length && sortedRanges[i].endExclusive < range.start) {\n      i++;\n    }\n    let j = i;\n    while (j < sortedRanges.length && sortedRanges[j].start <= range.endExclusive) {\n      j++;\n    }\n    if (i === j) {\n      sortedRanges.splice(i, 0, range);\n    } else {\n      const start = Math.min(range.start, sortedRanges[i].start);\n      const end = Math.max(range.endExclusive, sortedRanges[j - 1].endExclusive);\n      sortedRanges.splice(i, j - i, new OffsetRange(start, end));\n    }\n  }\n  static tryCreate(start, endExclusive) {\n    if (start > endExclusive) {\n      return undefined;\n    }\n    return new OffsetRange(start, endExclusive);\n  }\n  static ofLength(length) {\n    return new OffsetRange(0, length);\n  }\n  static ofStartAndLength(start, length) {\n    return new OffsetRange(start, start + length);\n  }\n  static emptyAt(offset) {\n    return new OffsetRange(offset, offset);\n  }\n  get isEmpty() {\n    return this.start === this.endExclusive;\n  }\n  delta(offset) {\n    return new OffsetRange(this.start + offset, this.endExclusive + offset);\n  }\n  deltaStart(offset) {\n    return new OffsetRange(this.start + offset, this.endExclusive);\n  }\n  deltaEnd(offset) {\n    return new OffsetRange(this.start, this.endExclusive + offset);\n  }\n  get length() {\n    return this.endExclusive - this.start;\n  }\n  toString() {\n    return `[${this.start}, ${this.endExclusive})`;\n  }\n  equals(other) {\n    return this.start === other.start && this.endExclusive === other.endExclusive;\n  }\n  containsRange(other) {\n    return this.start <= other.start && other.endExclusive <= this.endExclusive;\n  }\n  contains(offset) {\n    return this.start <= offset && offset < this.endExclusive;\n  }\n  /**\n   * for all numbers n: range1.contains(n) or range2.contains(n) => range1.join(range2).contains(n)\n   * The joined range is the smallest range that contains both ranges.\n   */\n  join(other) {\n    return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive));\n  }\n  /**\n   * for all numbers n: range1.contains(n) and range2.contains(n) <=> range1.intersect(range2).contains(n)\n   *\n   * The resulting range is empty if the ranges do not intersect, but touch.\n   * If the ranges don't even touch, the result is undefined.\n   */\n  intersect(other) {\n    const start = Math.max(this.start, other.start);\n    const end = Math.min(this.endExclusive, other.endExclusive);\n    if (start <= end) {\n      return new OffsetRange(start, end);\n    }\n    return undefined;\n  }\n  intersectionLength(range) {\n    const start = Math.max(this.start, range.start);\n    const end = Math.min(this.endExclusive, range.endExclusive);\n    return Math.max(0, end - start);\n  }\n  intersects(other) {\n    const start = Math.max(this.start, other.start);\n    const end = Math.min(this.endExclusive, other.endExclusive);\n    return start < end;\n  }\n  intersectsOrTouches(other) {\n    const start = Math.max(this.start, other.start);\n    const end = Math.min(this.endExclusive, other.endExclusive);\n    return start <= end;\n  }\n  isBefore(other) {\n    return this.endExclusive <= other.start;\n  }\n  isAfter(other) {\n    return this.start >= other.endExclusive;\n  }\n  slice(arr) {\n    return arr.slice(this.start, this.endExclusive);\n  }\n  substring(str) {\n    return str.substring(this.start, this.endExclusive);\n  }\n  /**\n   * Returns the given value if it is contained in this instance, otherwise the closest value that is contained.\n   * The range must not be empty.\n   */\n  clip(value) {\n    if (this.isEmpty) {\n      throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`);\n    }\n    return Math.max(this.start, Math.min(this.endExclusive - 1, value));\n  }\n  /**\n   * Returns `r := value + k * length` such that `r` is contained in this range.\n   * The range must not be empty.\n   *\n   * E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`.\n   */\n  clipCyclic(value) {\n    if (this.isEmpty) {\n      throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`);\n    }\n    if (value < this.start) {\n      return this.endExclusive - (this.start - value) % this.length;\n    }\n    if (value >= this.endExclusive) {\n      return this.start + (value - this.start) % this.length;\n    }\n    return value;\n  }\n  map(f) {\n    const result = [];\n    for (let i = this.start; i < this.endExclusive; i++) {\n      result.push(f(i));\n    }\n    return result;\n  }\n  forEach(f) {\n    for (let i = this.start; i < this.endExclusive; i++) {\n      f(i);\n    }\n  }\n}\n\nclass Position {\n  constructor(lineNumber, column) {\n    this.lineNumber = lineNumber;\n    this.column = column;\n  }\n  /**\n   * Test if this position equals other position\n   */\n  equals(other) {\n    return Position.equals(this, other);\n  }\n  /**\n   * Test if position `a` equals position `b`\n   */\n  static equals(a, b) {\n    if (!a && !b) {\n      return true;\n    }\n    return !!a && !!b && a.lineNumber === b.lineNumber && a.column === b.column;\n  }\n  /**\n   * Test if this position is before other position.\n   * If the two positions are equal, the result will be false.\n   */\n  isBefore(other) {\n    return Position.isBefore(this, other);\n  }\n  /**\n   * Test if position `a` is before position `b`.\n   * If the two positions are equal, the result will be false.\n   */\n  static isBefore(a, b) {\n    if (a.lineNumber < b.lineNumber) {\n      return true;\n    }\n    if (b.lineNumber < a.lineNumber) {\n      return false;\n    }\n    return a.column < b.column;\n  }\n  /**\n   * Test if this position is before other position.\n   * If the two positions are equal, the result will be true.\n   */\n  isBeforeOrEqual(other) {\n    return Position.isBeforeOrEqual(this, other);\n  }\n  /**\n   * Test if position `a` is before position `b`.\n   * If the two positions are equal, the result will be true.\n   */\n  static isBeforeOrEqual(a, b) {\n    if (a.lineNumber < b.lineNumber) {\n      return true;\n    }\n    if (b.lineNumber < a.lineNumber) {\n      return false;\n    }\n    return a.column <= b.column;\n  }\n}\n\nclass Range {\n  constructor(startLineNumber, startColumn, endLineNumber, endColumn) {\n    if (startLineNumber > endLineNumber || startLineNumber === endLineNumber && startColumn > endColumn) {\n      this.startLineNumber = endLineNumber;\n      this.startColumn = endColumn;\n      this.endLineNumber = startLineNumber;\n      this.endColumn = startColumn;\n    } else {\n      this.startLineNumber = startLineNumber;\n      this.startColumn = startColumn;\n      this.endLineNumber = endLineNumber;\n      this.endColumn = endColumn;\n    }\n  }\n  /**\n   * Test if this range is empty.\n   */\n  isEmpty() {\n    return Range.isEmpty(this);\n  }\n  /**\n   * Test if `range` is empty.\n   */\n  static isEmpty(range) {\n    return range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn;\n  }\n  /**\n   * Test if position is in this range. If the position is at the edges, will return true.\n   */\n  containsPosition(position) {\n    return Range.containsPosition(this, position);\n  }\n  /**\n   * Test if `position` is in `range`. If the position is at the edges, will return true.\n   */\n  static containsPosition(range, position) {\n    if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {\n      return false;\n    }\n    if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {\n      return false;\n    }\n    if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {\n      return false;\n    }\n    return true;\n  }\n  /**\n   * Test if range is in this range. If the range is equal to this range, will return true.\n   */\n  containsRange(range) {\n    return Range.containsRange(this, range);\n  }\n  /**\n   * Test if `otherRange` is in `range`. If the ranges are equal, will return true.\n   */\n  static containsRange(range, otherRange) {\n    if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {\n      return false;\n    }\n    if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {\n      return false;\n    }\n    if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {\n      return false;\n    }\n    if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {\n      return false;\n    }\n    return true;\n  }\n  /**\n   * Test if `range` is strictly in this range. `range` must start after and end before this range for the result to be true.\n   */\n  strictContainsRange(range) {\n    return Range.strictContainsRange(this, range);\n  }\n  /**\n   * Test if `otherRange` is strictly in `range` (must start after, and end before). If the ranges are equal, will return false.\n   */\n  static strictContainsRange(range, otherRange) {\n    if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {\n      return false;\n    }\n    if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {\n      return false;\n    }\n    if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn <= range.startColumn) {\n      return false;\n    }\n    if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn >= range.endColumn) {\n      return false;\n    }\n    return true;\n  }\n  /**\n   * A reunion of the two ranges.\n   * The smallest position will be used as the start point, and the largest one as the end point.\n   */\n  plusRange(range) {\n    return Range.plusRange(this, range);\n  }\n  /**\n   * A reunion of the two ranges.\n   * The smallest position will be used as the start point, and the largest one as the end point.\n   */\n  static plusRange(a, b) {\n    let startLineNumber;\n    let startColumn;\n    let endLineNumber;\n    let endColumn;\n    if (b.startLineNumber < a.startLineNumber) {\n      startLineNumber = b.startLineNumber;\n      startColumn = b.startColumn;\n    } else if (b.startLineNumber === a.startLineNumber) {\n      startLineNumber = b.startLineNumber;\n      startColumn = Math.min(b.startColumn, a.startColumn);\n    } else {\n      startLineNumber = a.startLineNumber;\n      startColumn = a.startColumn;\n    }\n    if (b.endLineNumber > a.endLineNumber) {\n      endLineNumber = b.endLineNumber;\n      endColumn = b.endColumn;\n    } else if (b.endLineNumber === a.endLineNumber) {\n      endLineNumber = b.endLineNumber;\n      endColumn = Math.max(b.endColumn, a.endColumn);\n    } else {\n      endLineNumber = a.endLineNumber;\n      endColumn = a.endColumn;\n    }\n    return new Range(startLineNumber, startColumn, endLineNumber, endColumn);\n  }\n  /**\n   * A intersection of the two ranges.\n   */\n  intersectRanges(range) {\n    return Range.intersectRanges(this, range);\n  }\n  /**\n   * A intersection of the two ranges.\n   */\n  static intersectRanges(a, b) {\n    let resultStartLineNumber = a.startLineNumber;\n    let resultStartColumn = a.startColumn;\n    let resultEndLineNumber = a.endLineNumber;\n    let resultEndColumn = a.endColumn;\n    const otherStartLineNumber = b.startLineNumber;\n    const otherStartColumn = b.startColumn;\n    const otherEndLineNumber = b.endLineNumber;\n    const otherEndColumn = b.endColumn;\n    if (resultStartLineNumber < otherStartLineNumber) {\n      resultStartLineNumber = otherStartLineNumber;\n      resultStartColumn = otherStartColumn;\n    } else if (resultStartLineNumber === otherStartLineNumber) {\n      resultStartColumn = Math.max(resultStartColumn, otherStartColumn);\n    }\n    if (resultEndLineNumber > otherEndLineNumber) {\n      resultEndLineNumber = otherEndLineNumber;\n      resultEndColumn = otherEndColumn;\n    } else if (resultEndLineNumber === otherEndLineNumber) {\n      resultEndColumn = Math.min(resultEndColumn, otherEndColumn);\n    }\n    if (resultStartLineNumber > resultEndLineNumber) {\n      return null;\n    }\n    if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {\n      return null;\n    }\n    return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);\n  }\n  /**\n   * Test if this range equals other.\n   */\n  equalsRange(other) {\n    return Range.equalsRange(this, other);\n  }\n  /**\n   * Test if range `a` equals `b`.\n   */\n  static equalsRange(a, b) {\n    if (!a && !b) {\n      return true;\n    }\n    return !!a && !!b && a.startLineNumber === b.startLineNumber && a.startColumn === b.startColumn && a.endLineNumber === b.endLineNumber && a.endColumn === b.endColumn;\n  }\n  /**\n   * Return the end position (which will be after or equal to the start position)\n   */\n  getEndPosition() {\n    return Range.getEndPosition(this);\n  }\n  /**\n   * Return the end position (which will be after or equal to the start position)\n   */\n  static getEndPosition(range) {\n    return new Position(range.endLineNumber, range.endColumn);\n  }\n  /**\n   * Return the start position (which will be before or equal to the end position)\n   */\n  getStartPosition() {\n    return Range.getStartPosition(this);\n  }\n  /**\n   * Return the start position (which will be before or equal to the end position)\n   */\n  static getStartPosition(range) {\n    return new Position(range.startLineNumber, range.startColumn);\n  }\n  /**\n   * Create a new empty range using this range's start position.\n   */\n  collapseToStart() {\n    return Range.collapseToStart(this);\n  }\n  /**\n   * Create a new empty range using this range's start position.\n   */\n  static collapseToStart(range) {\n    return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);\n  }\n  /**\n   * Create a new empty range using this range's end position.\n   */\n  collapseToEnd() {\n    return Range.collapseToEnd(this);\n  }\n  /**\n   * Create a new empty range using this range's end position.\n   */\n  static collapseToEnd(range) {\n    return new Range(range.endLineNumber, range.endColumn, range.endLineNumber, range.endColumn);\n  }\n  // ---\n  static fromPositions(start, end = start) {\n    return new Range(start.lineNumber, start.column, end.lineNumber, end.column);\n  }\n}\n\nfunction findLastMonotonous(array, predicate) {\n  const idx = findLastIdxMonotonous(array, predicate);\n  return idx === -1 ? undefined : array[idx];\n}\nfunction findLastIdxMonotonous(array, predicate, startIdx = 0, endIdxEx = array.length) {\n  let i = startIdx;\n  let j = endIdxEx;\n  while (i < j) {\n    const k = Math.floor((i + j) / 2);\n    if (predicate(array[k])) {\n      i = k + 1;\n    } else {\n      j = k;\n    }\n  }\n  return i - 1;\n}\nfunction findFirstMonotonous(array, predicate) {\n  const idx = findFirstIdxMonotonousOrArrLen(array, predicate);\n  return idx === array.length ? undefined : array[idx];\n}\nfunction findFirstIdxMonotonousOrArrLen(array, predicate, startIdx = 0, endIdxEx = array.length) {\n  let i = startIdx;\n  let j = endIdxEx;\n  while (i < j) {\n    const k = Math.floor((i + j) / 2);\n    if (predicate(array[k])) {\n      j = k;\n    } else {\n      i = k + 1;\n    }\n  }\n  return i;\n}\nclass MonotonousArray {\n  constructor(_array) {\n    this._array = _array;\n    this._findLastMonotonousLastIdx = 0;\n  }\n  static {\n    this.assertInvariants = false;\n  }\n  /**\n   * The predicate must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`!\n   * For subsequent calls, current predicate must be weaker than (or equal to) the previous predicate, i.e. more entries must be `true`.\n   */\n  findLastMonotonous(predicate) {\n    if (MonotonousArray.assertInvariants) {\n      if (this._prevFindLastPredicate) {\n        for (const item of this._array) {\n          if (this._prevFindLastPredicate(item) && !predicate(item)) {\n            throw new Error(\"MonotonousArray: current predicate must be weaker than (or equal to) the previous predicate.\");\n          }\n        }\n      }\n      this._prevFindLastPredicate = predicate;\n    }\n    const idx = findLastIdxMonotonous(this._array, predicate, this._findLastMonotonousLastIdx);\n    this._findLastMonotonousLastIdx = idx + 1;\n    return idx === -1 ? undefined : this._array[idx];\n  }\n}\n\nclass LineRange {\n  static fromRangeInclusive(range) {\n    return new LineRange(range.startLineNumber, range.endLineNumber + 1);\n  }\n  static join(lineRanges) {\n    if (lineRanges.length === 0) {\n      throw new BugIndicatingError(\"lineRanges cannot be empty\");\n    }\n    let startLineNumber = lineRanges[0].startLineNumber;\n    let endLineNumberExclusive = lineRanges[0].endLineNumberExclusive;\n    for (let i = 1; i < lineRanges.length; i++) {\n      startLineNumber = Math.min(startLineNumber, lineRanges[i].startLineNumber);\n      endLineNumberExclusive = Math.max(endLineNumberExclusive, lineRanges[i].endLineNumberExclusive);\n    }\n    return new LineRange(startLineNumber, endLineNumberExclusive);\n  }\n  static ofLength(startLineNumber, length) {\n    return new LineRange(startLineNumber, startLineNumber + length);\n  }\n  constructor(startLineNumber, endLineNumberExclusive) {\n    if (startLineNumber > endLineNumberExclusive) {\n      throw new BugIndicatingError(`startLineNumber ${startLineNumber} cannot be after endLineNumberExclusive ${endLineNumberExclusive}`);\n    }\n    this.startLineNumber = startLineNumber;\n    this.endLineNumberExclusive = endLineNumberExclusive;\n  }\n  /**\n   * Indicates if this line range is empty.\n   */\n  get isEmpty() {\n    return this.startLineNumber === this.endLineNumberExclusive;\n  }\n  /**\n   * Moves this line range by the given offset of line numbers.\n   */\n  delta(offset) {\n    return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset);\n  }\n  /**\n   * The number of lines this line range spans.\n   */\n  get length() {\n    return this.endLineNumberExclusive - this.startLineNumber;\n  }\n  /**\n   * Creates a line range that combines this and the given line range.\n   */\n  join(other) {\n    return new LineRange(\n      Math.min(this.startLineNumber, other.startLineNumber),\n      Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive)\n    );\n  }\n  /**\n   * The resulting range is empty if the ranges do not intersect, but touch.\n   * If the ranges don't even touch, the result is undefined.\n   */\n  intersect(other) {\n    const startLineNumber = Math.max(this.startLineNumber, other.startLineNumber);\n    const endLineNumberExclusive = Math.min(this.endLineNumberExclusive, other.endLineNumberExclusive);\n    if (startLineNumber <= endLineNumberExclusive) {\n      return new LineRange(startLineNumber, endLineNumberExclusive);\n    }\n    return undefined;\n  }\n  overlapOrTouch(other) {\n    return this.startLineNumber <= other.endLineNumberExclusive && other.startLineNumber <= this.endLineNumberExclusive;\n  }\n  toInclusiveRange() {\n    if (this.isEmpty) {\n      return null;\n    }\n    return new Range(this.startLineNumber, 1, this.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER);\n  }\n  /**\n   * Converts this 1-based line range to a 0-based offset range (subtracts 1!).\n   * @internal\n   */\n  toOffsetRange() {\n    return new OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1);\n  }\n}\nclass LineRangeSet {\n  constructor(_normalizedRanges = []) {\n    this._normalizedRanges = _normalizedRanges;\n  }\n  get ranges() {\n    return this._normalizedRanges;\n  }\n  addRange(range) {\n    if (range.length === 0) {\n      return;\n    }\n    const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, (r) => r.endLineNumberExclusive >= range.startLineNumber);\n    const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, (r) => r.startLineNumber <= range.endLineNumberExclusive) + 1;\n    if (joinRangeStartIdx === joinRangeEndIdxExclusive) {\n      this._normalizedRanges.splice(joinRangeStartIdx, 0, range);\n    } else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) {\n      const joinRange = this._normalizedRanges[joinRangeStartIdx];\n      this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range);\n    } else {\n      const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range);\n      this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange);\n    }\n  }\n  contains(lineNumber) {\n    const rangeThatStartsBeforeEnd = findLastMonotonous(this._normalizedRanges, (r) => r.startLineNumber <= lineNumber);\n    return !!rangeThatStartsBeforeEnd && rangeThatStartsBeforeEnd.endLineNumberExclusive > lineNumber;\n  }\n  /**\n   * Subtracts all ranges in this set from `range` and returns the result.\n   */\n  subtractFrom(range) {\n    const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, (r) => r.endLineNumberExclusive >= range.startLineNumber);\n    const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, (r) => r.startLineNumber <= range.endLineNumberExclusive) + 1;\n    if (joinRangeStartIdx === joinRangeEndIdxExclusive) {\n      return new LineRangeSet([range]);\n    }\n    const result = [];\n    let startLineNumber = range.startLineNumber;\n    for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) {\n      const r = this._normalizedRanges[i];\n      if (r.startLineNumber > startLineNumber) {\n        result.push(new LineRange(startLineNumber, r.startLineNumber));\n      }\n      startLineNumber = r.endLineNumberExclusive;\n    }\n    if (startLineNumber < range.endLineNumberExclusive) {\n      result.push(new LineRange(startLineNumber, range.endLineNumberExclusive));\n    }\n    return new LineRangeSet(result);\n  }\n  getIntersection(other) {\n    const result = [];\n    let i1 = 0;\n    let i2 = 0;\n    while (i1 < this._normalizedRanges.length && i2 < other._normalizedRanges.length) {\n      const r1 = this._normalizedRanges[i1];\n      const r2 = other._normalizedRanges[i2];\n      const i = r1.intersect(r2);\n      if (i && !i.isEmpty) {\n        result.push(i);\n      }\n      if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) {\n        i1++;\n      } else {\n        i2++;\n      }\n    }\n    return new LineRangeSet(result);\n  }\n  getWithDelta(value) {\n    return new LineRangeSet(this._normalizedRanges.map((r) => r.delta(value)));\n  }\n}\n\nclass TextLength {\n  constructor(lineCount, columnCount) {\n    this.lineCount = lineCount;\n    this.columnCount = columnCount;\n  }\n  static {\n    this.zero = new TextLength(0, 0);\n  }\n  toLineRange() {\n    return LineRange.ofLength(1, this.lineCount);\n  }\n  addToPosition(position) {\n    if (this.lineCount === 0) {\n      return new Position(position.lineNumber, position.column + this.columnCount);\n    } else {\n      return new Position(position.lineNumber + this.lineCount, this.columnCount + 1);\n    }\n  }\n}\n\n \nclass LineBasedText  {\n  constructor(_getLineContent, _lineCount) {\n    assert(_lineCount >= 1);\n    this._getLineContent = _getLineContent;\n    this._lineCount = _lineCount;\n  }\n  getValueOfRange(range) {\n    if (range.startLineNumber === range.endLineNumber) {\n      return this._getLineContent(range.startLineNumber).substring(range.startColumn - 1, range.endColumn - 1);\n    }\n    let result = this._getLineContent(range.startLineNumber).substring(range.startColumn - 1);\n    for (let i = range.startLineNumber + 1; i < range.endLineNumber; i++) {\n      result += \"\\n\" + this._getLineContent(i);\n    }\n    result += \"\\n\" + this._getLineContent(range.endLineNumber).substring(0, range.endColumn - 1);\n    return result;\n  }\n  getLineLength(lineNumber) {\n    return this._getLineContent(lineNumber).length;\n  }\n  get length() {\n    const lastLine = this._getLineContent(this._lineCount);\n    return new TextLength(this._lineCount - 1, lastLine.length);\n  }\n}\nclass ArrayText extends LineBasedText {\n  constructor(lines) {\n    super(\n      (lineNumber) => lines[lineNumber - 1],\n      lines.length\n    );\n  }\n}\n\nclass LinesDiff {\n  constructor(changes, moves, hitTimeout) {\n    this.changes = changes;\n    this.moves = moves;\n    this.hitTimeout = hitTimeout;\n  }\n}\nclass MovedText {\n  constructor(lineRangeMapping, changes) {\n    this.lineRangeMapping = lineRangeMapping;\n    this.changes = changes;\n  }\n}\n\nclass LineRangeMapping {\n  constructor(originalRange, modifiedRange) {\n    this.original = originalRange;\n    this.modified = modifiedRange;\n  }\n  join(other) {\n    return new LineRangeMapping(\n      this.original.join(other.original),\n      this.modified.join(other.modified)\n    );\n  }\n  get changedLineCount() {\n    return Math.max(this.original.length, this.modified.length);\n  }\n  /**\n   * This method assumes that the LineRangeMapping describes a valid diff!\n   * I.e. if one range is empty, the other range cannot be the entire document.\n   * It avoids various problems when the line range points to non-existing line-numbers.\n  */\n  toRangeMapping() {\n    const origInclusiveRange = this.original.toInclusiveRange();\n    const modInclusiveRange = this.modified.toInclusiveRange();\n    if (origInclusiveRange && modInclusiveRange) {\n      return new RangeMapping(origInclusiveRange, modInclusiveRange);\n    } else if (this.original.startLineNumber === 1 || this.modified.startLineNumber === 1) {\n      if (!(this.modified.startLineNumber === 1 && this.original.startLineNumber === 1)) {\n        throw new BugIndicatingError(\"not a valid diff\");\n      }\n      return new RangeMapping(\n        new Range(this.original.startLineNumber, 1, this.original.endLineNumberExclusive, 1),\n        new Range(this.modified.startLineNumber, 1, this.modified.endLineNumberExclusive, 1)\n      );\n    } else {\n      return new RangeMapping(\n        new Range(this.original.startLineNumber - 1, Number.MAX_SAFE_INTEGER, this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER),\n        new Range(this.modified.startLineNumber - 1, Number.MAX_SAFE_INTEGER, this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER)\n      );\n    }\n  }\n  /**\n   * This method assumes that the LineRangeMapping describes a valid diff!\n   * I.e. if one range is empty, the other range cannot be the entire document.\n   * It avoids various problems when the line range points to non-existing line-numbers.\n  */\n  toRangeMapping2(original, modified) {\n    if (isValidLineNumber(this.original.endLineNumberExclusive, original) && isValidLineNumber(this.modified.endLineNumberExclusive, modified)) {\n      return new RangeMapping(\n        new Range(this.original.startLineNumber, 1, this.original.endLineNumberExclusive, 1),\n        new Range(this.modified.startLineNumber, 1, this.modified.endLineNumberExclusive, 1)\n      );\n    }\n    if (!this.original.isEmpty && !this.modified.isEmpty) {\n      return new RangeMapping(\n        Range.fromPositions(\n          new Position(this.original.startLineNumber, 1),\n          normalizePosition(new Position(this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), original)\n        ),\n        Range.fromPositions(\n          new Position(this.modified.startLineNumber, 1),\n          normalizePosition(new Position(this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), modified)\n        )\n      );\n    }\n    if (this.original.startLineNumber > 1 && this.modified.startLineNumber > 1) {\n      return new RangeMapping(\n        Range.fromPositions(\n          normalizePosition(new Position(this.original.startLineNumber - 1, Number.MAX_SAFE_INTEGER), original),\n          normalizePosition(new Position(this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), original)\n        ),\n        Range.fromPositions(\n          normalizePosition(new Position(this.modified.startLineNumber - 1, Number.MAX_SAFE_INTEGER), modified),\n          normalizePosition(new Position(this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), modified)\n        )\n      );\n    }\n    throw new BugIndicatingError();\n  }\n}\nfunction normalizePosition(position, content) {\n  if (position.lineNumber < 1) {\n    return new Position(1, 1);\n  }\n  if (position.lineNumber > content.length) {\n    return new Position(content.length, content[content.length - 1].length + 1);\n  }\n  const line = content[position.lineNumber - 1];\n  if (position.column > line.length + 1) {\n    return new Position(position.lineNumber, line.length + 1);\n  }\n  return position;\n}\nfunction isValidLineNumber(lineNumber, lines) {\n  return lineNumber >= 1 && lineNumber <= lines.length;\n}\nclass DetailedLineRangeMapping extends LineRangeMapping {\n  static fromRangeMappings(rangeMappings) {\n    const originalRange = LineRange.join(rangeMappings.map((r) => LineRange.fromRangeInclusive(r.originalRange)));\n    const modifiedRange = LineRange.join(rangeMappings.map((r) => LineRange.fromRangeInclusive(r.modifiedRange)));\n    return new DetailedLineRangeMapping(originalRange, modifiedRange, rangeMappings);\n  }\n  constructor(originalRange, modifiedRange, innerChanges) {\n    super(originalRange, modifiedRange);\n    this.innerChanges = innerChanges;\n  }\n  flip() {\n    return new DetailedLineRangeMapping(this.modified, this.original, this.innerChanges?.map((c) => c.flip()));\n  }\n  withInnerChangesFromLineRanges() {\n    return new DetailedLineRangeMapping(this.original, this.modified, [this.toRangeMapping()]);\n  }\n}\nclass RangeMapping {\n  static join(rangeMappings) {\n    if (rangeMappings.length === 0) {\n      throw new BugIndicatingError(\"Cannot join an empty list of range mappings\");\n    }\n    let result = rangeMappings[0];\n    for (let i = 1; i < rangeMappings.length; i++) {\n      result = result.join(rangeMappings[i]);\n    }\n    return result;\n  }\n  static assertSorted(rangeMappings) {\n    for (let i = 1; i < rangeMappings.length; i++) {\n      const previous = rangeMappings[i - 1];\n      const current = rangeMappings[i];\n      if (!(previous.originalRange.getEndPosition().isBeforeOrEqual(current.originalRange.getStartPosition()) && previous.modifiedRange.getEndPosition().isBeforeOrEqual(current.modifiedRange.getStartPosition()))) {\n        throw new BugIndicatingError(\"Range mappings must be sorted\");\n      }\n    }\n  }\n  constructor(originalRange, modifiedRange) {\n    this.originalRange = originalRange;\n    this.modifiedRange = modifiedRange;\n  }\n  flip() {\n    return new RangeMapping(this.modifiedRange, this.originalRange);\n  }\n  /**\n   * Creates a single text edit that describes the change from the original to the modified text.\n  */\n  join(other) {\n    return new RangeMapping(\n      this.originalRange.plusRange(other.originalRange),\n      this.modifiedRange.plusRange(other.modifiedRange)\n    );\n  }\n}\nfunction lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines, dontAssertStartLine = false) {\n  const changes = [];\n  for (const g of groupAdjacentBy(\n    alignments.map((a) => getLineRangeMapping(a, originalLines, modifiedLines)),\n    (a1, a2) => a1.original.overlapOrTouch(a2.original) || a1.modified.overlapOrTouch(a2.modified)\n  )) {\n    const first = g[0];\n    const last = g[g.length - 1];\n    changes.push(new DetailedLineRangeMapping(\n      first.original.join(last.original),\n      first.modified.join(last.modified),\n      g.map((a) => a.innerChanges[0])\n    ));\n  }\n  assertFn(() => {\n    if (!dontAssertStartLine && changes.length > 0) {\n      if (changes[0].modified.startLineNumber !== changes[0].original.startLineNumber) {\n        return false;\n      }\n      if (modifiedLines.length.lineCount - changes[changes.length - 1].modified.endLineNumberExclusive !== originalLines.length.lineCount - changes[changes.length - 1].original.endLineNumberExclusive) {\n        return false;\n      }\n    }\n    return checkAdjacentItems(\n      changes,\n      (m1, m2) => m2.original.startLineNumber - m1.original.endLineNumberExclusive === m2.modified.startLineNumber - m1.modified.endLineNumberExclusive && // There has to be an unchanged line in between (otherwise both diffs should have been joined)\n      m1.original.endLineNumberExclusive < m2.original.startLineNumber && m1.modified.endLineNumberExclusive < m2.modified.startLineNumber\n    );\n  });\n  return changes;\n}\nfunction getLineRangeMapping(rangeMapping, originalLines, modifiedLines) {\n  let lineStartDelta = 0;\n  let lineEndDelta = 0;\n  if (rangeMapping.modifiedRange.endColumn === 1 && rangeMapping.originalRange.endColumn === 1 && rangeMapping.originalRange.startLineNumber + lineStartDelta <= rangeMapping.originalRange.endLineNumber && rangeMapping.modifiedRange.startLineNumber + lineStartDelta <= rangeMapping.modifiedRange.endLineNumber) {\n    lineEndDelta = -1;\n  }\n  if (rangeMapping.modifiedRange.startColumn - 1 >= modifiedLines.getLineLength(rangeMapping.modifiedRange.startLineNumber) && rangeMapping.originalRange.startColumn - 1 >= originalLines.getLineLength(rangeMapping.originalRange.startLineNumber) && rangeMapping.originalRange.startLineNumber <= rangeMapping.originalRange.endLineNumber + lineEndDelta && rangeMapping.modifiedRange.startLineNumber <= rangeMapping.modifiedRange.endLineNumber + lineEndDelta) {\n    lineStartDelta = 1;\n  }\n  const originalLineRange = new LineRange(\n    rangeMapping.originalRange.startLineNumber + lineStartDelta,\n    rangeMapping.originalRange.endLineNumber + 1 + lineEndDelta\n  );\n  const modifiedLineRange = new LineRange(\n    rangeMapping.modifiedRange.startLineNumber + lineStartDelta,\n    rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta\n  );\n  return new DetailedLineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);\n}\n\nclass DiffAlgorithmResult {\n  constructor(diffs, hitTimeout) {\n    this.diffs = diffs;\n    this.hitTimeout = hitTimeout;\n  }\n  static trivial(seq1, seq2) {\n    return new DiffAlgorithmResult([new SequenceDiff(OffsetRange.ofLength(seq1.length), OffsetRange.ofLength(seq2.length))], false);\n  }\n  static trivialTimedOut(seq1, seq2) {\n    return new DiffAlgorithmResult([new SequenceDiff(OffsetRange.ofLength(seq1.length), OffsetRange.ofLength(seq2.length))], true);\n  }\n}\nclass SequenceDiff {\n  constructor(seq1Range, seq2Range) {\n    this.seq1Range = seq1Range;\n    this.seq2Range = seq2Range;\n  }\n  static invert(sequenceDiffs, doc1Length) {\n    const result = [];\n    forEachAdjacent(sequenceDiffs, (a, b) => {\n      result.push(SequenceDiff.fromOffsetPairs(\n        a ? a.getEndExclusives() : OffsetPair.zero,\n        b ? b.getStarts() : new OffsetPair(doc1Length, (a ? a.seq2Range.endExclusive - a.seq1Range.endExclusive : 0) + doc1Length)\n      ));\n    });\n    return result;\n  }\n  static fromOffsetPairs(start, endExclusive) {\n    return new SequenceDiff(\n      new OffsetRange(start.offset1, endExclusive.offset1),\n      new OffsetRange(start.offset2, endExclusive.offset2)\n    );\n  }\n  static assertSorted(sequenceDiffs) {\n    let last = undefined;\n    for (const cur of sequenceDiffs) {\n      if (last) {\n        if (!(last.seq1Range.endExclusive <= cur.seq1Range.start && last.seq2Range.endExclusive <= cur.seq2Range.start)) {\n          throw new BugIndicatingError(\"Sequence diffs must be sorted\");\n        }\n      }\n      last = cur;\n    }\n  }\n  swap() {\n    return new SequenceDiff(this.seq2Range, this.seq1Range);\n  }\n  join(other) {\n    return new SequenceDiff(this.seq1Range.join(other.seq1Range), this.seq2Range.join(other.seq2Range));\n  }\n  delta(offset) {\n    if (offset === 0) {\n      return this;\n    }\n    return new SequenceDiff(this.seq1Range.delta(offset), this.seq2Range.delta(offset));\n  }\n  deltaStart(offset) {\n    if (offset === 0) {\n      return this;\n    }\n    return new SequenceDiff(this.seq1Range.deltaStart(offset), this.seq2Range.deltaStart(offset));\n  }\n  deltaEnd(offset) {\n    if (offset === 0) {\n      return this;\n    }\n    return new SequenceDiff(this.seq1Range.deltaEnd(offset), this.seq2Range.deltaEnd(offset));\n  }\n  intersect(other) {\n    const i1 = this.seq1Range.intersect(other.seq1Range);\n    const i2 = this.seq2Range.intersect(other.seq2Range);\n    if (!i1 || !i2) {\n      return undefined;\n    }\n    return new SequenceDiff(i1, i2);\n  }\n  getStarts() {\n    return new OffsetPair(this.seq1Range.start, this.seq2Range.start);\n  }\n  getEndExclusives() {\n    return new OffsetPair(this.seq1Range.endExclusive, this.seq2Range.endExclusive);\n  }\n}\nclass OffsetPair {\n  constructor(offset1, offset2) {\n    this.offset1 = offset1;\n    this.offset2 = offset2;\n  }\n  static {\n    this.zero = new OffsetPair(0, 0);\n  }\n  static {\n    this.max = new OffsetPair(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);\n  }\n  delta(offset) {\n    if (offset === 0) {\n      return this;\n    }\n    return new OffsetPair(this.offset1 + offset, this.offset2 + offset);\n  }\n  equals(other) {\n    return this.offset1 === other.offset1 && this.offset2 === other.offset2;\n  }\n}\nclass InfiniteTimeout {\n  static {\n    this.instance = new InfiniteTimeout();\n  }\n  isValid() {\n    return true;\n  }\n}\nclass DateTimeout {\n  constructor(timeout) {\n    this.timeout = timeout;\n    this.startTime = Date.now();\n    this.valid = true;\n    if (timeout <= 0) {\n      throw new BugIndicatingError(\"timeout must be positive\");\n    }\n  }\n  // Recommendation: Set a log-point `{this.disable()}` in the body\n  isValid() {\n    const valid = Date.now() - this.startTime < this.timeout;\n    if (!valid && this.valid) {\n      this.valid = false;\n    }\n    return this.valid;\n  }\n  disable() {\n    this.timeout = Number.MAX_SAFE_INTEGER;\n    this.isValid = () => true;\n    this.valid = true;\n  }\n}\n\nclass Array2D {\n  constructor(width, height) {\n    this.width = width;\n    this.height = height;\n    this.array = [];\n    this.array = new Array(width * height);\n  }\n  get(x, y) {\n    return this.array[x + y * this.width];\n  }\n  set(x, y, value) {\n    this.array[x + y * this.width] = value;\n  }\n}\nfunction isSpace(charCode) {\n  return charCode === 32 || charCode === 9;\n}\nclass LineRangeFragment {\n  constructor(range, lines, source) {\n    this.range = range;\n    this.lines = lines;\n    this.source = source;\n    this.histogram = [];\n    let counter = 0;\n    for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) {\n      const line = lines[i];\n      for (let j = 0; j < line.length; j++) {\n        counter++;\n        const chr = line[j];\n        const key2 = LineRangeFragment.getKey(chr);\n        this.histogram[key2] = (this.histogram[key2] || 0) + 1;\n      }\n      counter++;\n      const key = LineRangeFragment.getKey(\"\\n\");\n      this.histogram[key] = (this.histogram[key] || 0) + 1;\n    }\n    this.totalCount = counter;\n  }\n  static {\n    this.chrKeys = /* @__PURE__ */ new Map();\n  }\n  static getKey(chr) {\n    let key = this.chrKeys.get(chr);\n    if (key === undefined) {\n      key = this.chrKeys.size;\n      this.chrKeys.set(chr, key);\n    }\n    return key;\n  }\n  computeSimilarity(other) {\n    let sumDifferences = 0;\n    const maxLength = Math.max(this.histogram.length, other.histogram.length);\n    for (let i = 0; i < maxLength; i++) {\n      sumDifferences += Math.abs((this.histogram[i] ?? 0) - (other.histogram[i] ?? 0));\n    }\n    return 1 - sumDifferences / (this.totalCount + other.totalCount);\n  }\n}\n\nclass DynamicProgrammingDiffing {\n  compute(sequence1, sequence2, timeout = InfiniteTimeout.instance, equalityScore) {\n    if (sequence1.length === 0 || sequence2.length === 0) {\n      return DiffAlgorithmResult.trivial(sequence1, sequence2);\n    }\n    const lcsLengths = new Array2D(sequence1.length, sequence2.length);\n    const directions = new Array2D(sequence1.length, sequence2.length);\n    const lengths = new Array2D(sequence1.length, sequence2.length);\n    for (let s12 = 0; s12 < sequence1.length; s12++) {\n      for (let s22 = 0; s22 < sequence2.length; s22++) {\n        if (!timeout.isValid()) {\n          return DiffAlgorithmResult.trivialTimedOut(sequence1, sequence2);\n        }\n        const horizontalLen = s12 === 0 ? 0 : lcsLengths.get(s12 - 1, s22);\n        const verticalLen = s22 === 0 ? 0 : lcsLengths.get(s12, s22 - 1);\n        let extendedSeqScore;\n        if (sequence1.getElement(s12) === sequence2.getElement(s22)) {\n          if (s12 === 0 || s22 === 0) {\n            extendedSeqScore = 0;\n          } else {\n            extendedSeqScore = lcsLengths.get(s12 - 1, s22 - 1);\n          }\n          if (s12 > 0 && s22 > 0 && directions.get(s12 - 1, s22 - 1) === 3) {\n            extendedSeqScore += lengths.get(s12 - 1, s22 - 1);\n          }\n          extendedSeqScore += equalityScore ? equalityScore(s12, s22) : 1;\n        } else {\n          extendedSeqScore = -1;\n        }\n        const newValue = Math.max(horizontalLen, verticalLen, extendedSeqScore);\n        if (newValue === extendedSeqScore) {\n          const prevLen = s12 > 0 && s22 > 0 ? lengths.get(s12 - 1, s22 - 1) : 0;\n          lengths.set(s12, s22, prevLen + 1);\n          directions.set(s12, s22, 3);\n        } else if (newValue === horizontalLen) {\n          lengths.set(s12, s22, 0);\n          directions.set(s12, s22, 1);\n        } else if (newValue === verticalLen) {\n          lengths.set(s12, s22, 0);\n          directions.set(s12, s22, 2);\n        }\n        lcsLengths.set(s12, s22, newValue);\n      }\n    }\n    const result = [];\n    let lastAligningPosS1 = sequence1.length;\n    let lastAligningPosS2 = sequence2.length;\n    function reportDecreasingAligningPositions(s12, s22) {\n      if (s12 + 1 !== lastAligningPosS1 || s22 + 1 !== lastAligningPosS2) {\n        result.push(new SequenceDiff(\n          new OffsetRange(s12 + 1, lastAligningPosS1),\n          new OffsetRange(s22 + 1, lastAligningPosS2)\n        ));\n      }\n      lastAligningPosS1 = s12;\n      lastAligningPosS2 = s22;\n    }\n    let s1 = sequence1.length - 1;\n    let s2 = sequence2.length - 1;\n    while (s1 >= 0 && s2 >= 0) {\n      if (directions.get(s1, s2) === 3) {\n        reportDecreasingAligningPositions(s1, s2);\n        s1--;\n        s2--;\n      } else {\n        if (directions.get(s1, s2) === 1) {\n          s1--;\n        } else {\n          s2--;\n        }\n      }\n    }\n    reportDecreasingAligningPositions(-1, -1);\n    result.reverse();\n    return new DiffAlgorithmResult(result, false);\n  }\n}\n\nclass MyersDiffAlgorithm {\n  compute(seq1, seq2, timeout = InfiniteTimeout.instance) {\n    if (seq1.length === 0 || seq2.length === 0) {\n      return DiffAlgorithmResult.trivial(seq1, seq2);\n    }\n    const seqX = seq1;\n    const seqY = seq2;\n    function getXAfterSnake(x, y) {\n      while (x < seqX.length && y < seqY.length && seqX.getElement(x) === seqY.getElement(y)) {\n        x++;\n        y++;\n      }\n      return x;\n    }\n    let d = 0;\n    const V = new FastInt32Array();\n    V.set(0, getXAfterSnake(0, 0));\n    const paths = new FastArrayNegativeIndices();\n    paths.set(0, V.get(0) === 0 ? null : new SnakePath(null, 0, 0, V.get(0)));\n    let k = 0;\n    loop: while (true) {\n      d++;\n      if (!timeout.isValid()) {\n        return DiffAlgorithmResult.trivialTimedOut(seqX, seqY);\n      }\n      const lowerBound = -Math.min(d, seqY.length + d % 2);\n      const upperBound = Math.min(d, seqX.length + d % 2);\n      for (k = lowerBound; k <= upperBound; k += 2) {\n        const maxXofDLineTop = k === upperBound ? -1 : V.get(k + 1);\n        const maxXofDLineLeft = k === lowerBound ? -1 : V.get(k - 1) + 1;\n        const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seqX.length);\n        const y = x - k;\n        if (x > seqX.length || y > seqY.length) {\n          continue;\n        }\n        const newMaxX = getXAfterSnake(x, y);\n        V.set(k, newMaxX);\n        const lastPath = x === maxXofDLineTop ? paths.get(k + 1) : paths.get(k - 1);\n        paths.set(k, newMaxX !== x ? new SnakePath(lastPath, x, y, newMaxX - x) : lastPath);\n        if (V.get(k) === seqX.length && V.get(k) - k === seqY.length) {\n          break loop;\n        }\n      }\n    }\n    let path = paths.get(k);\n    const result = [];\n    let lastAligningPosS1 = seqX.length;\n    let lastAligningPosS2 = seqY.length;\n    while (true) {\n      const endX = path ? path.x + path.length : 0;\n      const endY = path ? path.y + path.length : 0;\n      if (endX !== lastAligningPosS1 || endY !== lastAligningPosS2) {\n        result.push(new SequenceDiff(\n          new OffsetRange(endX, lastAligningPosS1),\n          new OffsetRange(endY, lastAligningPosS2)\n        ));\n      }\n      if (!path) {\n        break;\n      }\n      lastAligningPosS1 = path.x;\n      lastAligningPosS2 = path.y;\n      path = path.prev;\n    }\n    result.reverse();\n    return new DiffAlgorithmResult(result, false);\n  }\n}\nclass SnakePath {\n  constructor(prev, x, y, length) {\n    this.prev = prev;\n    this.x = x;\n    this.y = y;\n    this.length = length;\n  }\n}\nclass FastInt32Array {\n  constructor() {\n    this.positiveArr = new Int32Array(10);\n    this.negativeArr = new Int32Array(10);\n  }\n  get(idx) {\n    if (idx < 0) {\n      idx = -idx - 1;\n      return this.negativeArr[idx];\n    } else {\n      return this.positiveArr[idx];\n    }\n  }\n  set(idx, value) {\n    if (idx < 0) {\n      idx = -idx - 1;\n      if (idx >= this.negativeArr.length) {\n        const arr = this.negativeArr;\n        this.negativeArr = new Int32Array(arr.length * 2);\n        this.negativeArr.set(arr);\n      }\n      this.negativeArr[idx] = value;\n    } else {\n      if (idx >= this.positiveArr.length) {\n        const arr = this.positiveArr;\n        this.positiveArr = new Int32Array(arr.length * 2);\n        this.positiveArr.set(arr);\n      }\n      this.positiveArr[idx] = value;\n    }\n  }\n}\nclass FastArrayNegativeIndices {\n  constructor() {\n    this.positiveArr = [];\n    this.negativeArr = [];\n  }\n  get(idx) {\n    if (idx < 0) {\n      idx = -idx - 1;\n      return this.negativeArr[idx];\n    } else {\n      return this.positiveArr[idx];\n    }\n  }\n  set(idx, value) {\n    if (idx < 0) {\n      idx = -idx - 1;\n      this.negativeArr[idx] = value;\n    } else {\n      this.positiveArr[idx] = value;\n    }\n  }\n}\n\nclass SetMap {\n  constructor() {\n    this.map = /* @__PURE__ */ new Map();\n  }\n  add(key, value) {\n    let values = this.map.get(key);\n    if (!values) {\n      values = /* @__PURE__ */ new Set();\n      this.map.set(key, values);\n    }\n    values.add(value);\n  }\n  forEach(key, fn) {\n    const values = this.map.get(key);\n    if (!values) {\n      return;\n    }\n    values.forEach(fn);\n  }\n  get(key) {\n    const values = this.map.get(key);\n    if (!values) {\n      return /* @__PURE__ */ new Set();\n    }\n    return values;\n  }\n}\n\nclass LinesSliceCharSequence {\n  constructor(lines, range, considerWhitespaceChanges) {\n    this.lines = lines;\n    this.range = range;\n    this.considerWhitespaceChanges = considerWhitespaceChanges;\n    this.elements = [];\n    this.firstElementOffsetByLineIdx = [];\n    this.lineStartOffsets = [];\n    this.trimmedWsLengthsByLineIdx = [];\n    this.firstElementOffsetByLineIdx.push(0);\n    for (let lineNumber = this.range.startLineNumber; lineNumber <= this.range.endLineNumber; lineNumber++) {\n      let line = lines[lineNumber - 1];\n      let lineStartOffset = 0;\n      if (lineNumber === this.range.startLineNumber && this.range.startColumn > 1) {\n        lineStartOffset = this.range.startColumn - 1;\n        line = line.substring(lineStartOffset);\n      }\n      this.lineStartOffsets.push(lineStartOffset);\n      let trimmedWsLength = 0;\n      if (!considerWhitespaceChanges) {\n        const trimmedStartLine = line.trimStart();\n        trimmedWsLength = line.length - trimmedStartLine.length;\n        line = trimmedStartLine.trimEnd();\n      }\n      this.trimmedWsLengthsByLineIdx.push(trimmedWsLength);\n      const lineLength = lineNumber === this.range.endLineNumber ? Math.min(this.range.endColumn - 1 - lineStartOffset - trimmedWsLength, line.length) : line.length;\n      for (let i = 0; i < lineLength; i++) {\n        this.elements.push(line.charCodeAt(i));\n      }\n      if (lineNumber < this.range.endLineNumber) {\n        this.elements.push(\"\\n\".charCodeAt(0));\n        this.firstElementOffsetByLineIdx.push(this.elements.length);\n      }\n    }\n  }\n  toString() {\n    return `Slice: \"${this.text}\"`;\n  }\n  get text() {\n    return this.getText(new OffsetRange(0, this.length));\n  }\n  getText(range) {\n    return this.elements.slice(range.start, range.endExclusive).map((e) => String.fromCharCode(e)).join(\"\");\n  }\n  getElement(offset) {\n    return this.elements[offset];\n  }\n  get length() {\n    return this.elements.length;\n  }\n  getBoundaryScore(length) {\n    const prevCategory = getCategory(length > 0 ? this.elements[length - 1] : -1);\n    const nextCategory = getCategory(length < this.elements.length ? this.elements[length] : -1);\n    if (prevCategory === 7 /* LineBreakCR */ && nextCategory === 8 /* LineBreakLF */) {\n      return 0;\n    }\n    if (prevCategory === 8 /* LineBreakLF */) {\n      return 150;\n    }\n    let score2 = 0;\n    if (prevCategory !== nextCategory) {\n      score2 += 10;\n      if (prevCategory === 0 /* WordLower */ && nextCategory === 1 /* WordUpper */) {\n        score2 += 1;\n      }\n    }\n    score2 += getCategoryBoundaryScore(prevCategory);\n    score2 += getCategoryBoundaryScore(nextCategory);\n    return score2;\n  }\n  translateOffset(offset, preference = \"right\") {\n    const i = findLastIdxMonotonous(this.firstElementOffsetByLineIdx, (value) => value <= offset);\n    const lineOffset = offset - this.firstElementOffsetByLineIdx[i];\n    return new Position(\n      this.range.startLineNumber + i,\n      1 + this.lineStartOffsets[i] + lineOffset + (lineOffset === 0 && preference === \"left\" ? 0 : this.trimmedWsLengthsByLineIdx[i])\n    );\n  }\n  translateRange(range) {\n    const pos1 = this.translateOffset(range.start, \"right\");\n    const pos2 = this.translateOffset(range.endExclusive, \"left\");\n    if (pos2.isBefore(pos1)) {\n      return Range.fromPositions(pos2, pos2);\n    }\n    return Range.fromPositions(pos1, pos2);\n  }\n  /**\n   * Finds the word that contains the character at the given offset\n   */\n  findWordContaining(offset) {\n    if (offset < 0 || offset >= this.elements.length) {\n      return undefined;\n    }\n    if (!isWordChar(this.elements[offset])) {\n      return undefined;\n    }\n    let start = offset;\n    while (start > 0 && isWordChar(this.elements[start - 1])) {\n      start--;\n    }\n    let end = offset;\n    while (end < this.elements.length && isWordChar(this.elements[end])) {\n      end++;\n    }\n    return new OffsetRange(start, end);\n  }\n  /** fooBar has the two sub-words foo and bar */\n  findSubWordContaining(offset) {\n    if (offset < 0 || offset >= this.elements.length) {\n      return undefined;\n    }\n    if (!isWordChar(this.elements[offset])) {\n      return undefined;\n    }\n    let start = offset;\n    while (start > 0 && isWordChar(this.elements[start - 1]) && !isUpperCase(this.elements[start])) {\n      start--;\n    }\n    let end = offset;\n    while (end < this.elements.length && isWordChar(this.elements[end]) && !isUpperCase(this.elements[end])) {\n      end++;\n    }\n    return new OffsetRange(start, end);\n  }\n  countLinesIn(range) {\n    return this.translateOffset(range.endExclusive).lineNumber - this.translateOffset(range.start).lineNumber;\n  }\n  isStronglyEqual(offset1, offset2) {\n    return this.elements[offset1] === this.elements[offset2];\n  }\n  extendToFullLines(range) {\n    const start = findLastMonotonous(this.firstElementOffsetByLineIdx, (x) => x <= range.start) ?? 0;\n    const end = findFirstMonotonous(this.firstElementOffsetByLineIdx, (x) => range.endExclusive <= x) ?? this.elements.length;\n    return new OffsetRange(start, end);\n  }\n}\nfunction isWordChar(charCode) {\n  return charCode >= 97 && charCode <= 122 || charCode >= 65 && charCode <= 90 || charCode >= 48 && charCode <= 57;\n}\nfunction isUpperCase(charCode) {\n  return charCode >= 65 && charCode <= 90;\n}\nconst score = {\n  [0 /* WordLower */]: 0,\n  [1 /* WordUpper */]: 0,\n  [2 /* WordNumber */]: 0,\n  [3 /* End */]: 10,\n  [4 /* Other */]: 2,\n  [5 /* Separator */]: 30,\n  [6 /* Space */]: 3,\n  [7 /* LineBreakCR */]: 10,\n  [8 /* LineBreakLF */]: 10\n};\nfunction getCategoryBoundaryScore(category) {\n  return score[category];\n}\nfunction getCategory(charCode) {\n  if (charCode === 10) {\n    return 8 /* LineBreakLF */;\n  } else if (charCode === 13) {\n    return 7 /* LineBreakCR */;\n  } else if (isSpace(charCode)) {\n    return 6 /* Space */;\n  } else if (charCode >= 97 && charCode <= 122) {\n    return 0 /* WordLower */;\n  } else if (charCode >= 65 && charCode <= 90) {\n    return 1 /* WordUpper */;\n  } else if (charCode >= 48 && charCode <= 57) {\n    return 2 /* WordNumber */;\n  } else if (charCode === -1) {\n    return 3 /* End */;\n  } else if (charCode === 44 || charCode === 59) {\n    return 5 /* Separator */;\n  } else {\n    return 4 /* Other */;\n  }\n}\n\nfunction computeMovedLines(changes, originalLines, modifiedLines, hashedOriginalLines, hashedModifiedLines, timeout) {\n  let { moves, excludedChanges } = computeMovesFromSimpleDeletionsToSimpleInsertions(changes, originalLines, modifiedLines, timeout);\n  if (!timeout.isValid()) {\n    return [];\n  }\n  const filteredChanges = changes.filter((c) => !excludedChanges.has(c));\n  const unchangedMoves = computeUnchangedMoves(filteredChanges, hashedOriginalLines, hashedModifiedLines, originalLines, modifiedLines, timeout);\n  pushMany(moves, unchangedMoves);\n  moves = joinCloseConsecutiveMoves(moves);\n  moves = moves.filter((current) => {\n    const lines = current.original.toOffsetRange().slice(originalLines).map((l) => l.trim());\n    const originalText = lines.join(\"\\n\");\n    return originalText.length >= 15 && countWhere(lines, (l) => l.length >= 2) >= 2;\n  });\n  moves = removeMovesInSameDiff(changes, moves);\n  return moves;\n}\nfunction countWhere(arr, predicate) {\n  let count = 0;\n  for (const t of arr) {\n    if (predicate(t)) {\n      count++;\n    }\n  }\n  return count;\n}\nfunction computeMovesFromSimpleDeletionsToSimpleInsertions(changes, originalLines, modifiedLines, timeout) {\n  const moves = [];\n  const deletions = changes.filter((c) => c.modified.isEmpty && c.original.length >= 3).map((d) => new LineRangeFragment(d.original, originalLines, d));\n  const insertions = new Set(changes.filter((c) => c.original.isEmpty && c.modified.length >= 3).map((d) => new LineRangeFragment(d.modified, modifiedLines, d)));\n  const excludedChanges = /* @__PURE__ */ new Set();\n  for (const deletion of deletions) {\n    let highestSimilarity = -1;\n    let best;\n    for (const insertion of insertions) {\n      const similarity = deletion.computeSimilarity(insertion);\n      if (similarity > highestSimilarity) {\n        highestSimilarity = similarity;\n        best = insertion;\n      }\n    }\n    if (highestSimilarity > 0.9 && best) {\n      insertions.delete(best);\n      moves.push(new LineRangeMapping(deletion.range, best.range));\n      excludedChanges.add(deletion.source);\n      excludedChanges.add(best.source);\n    }\n    if (!timeout.isValid()) {\n      return { moves, excludedChanges };\n    }\n  }\n  return { moves, excludedChanges };\n}\nfunction computeUnchangedMoves(changes, hashedOriginalLines, hashedModifiedLines, originalLines, modifiedLines, timeout) {\n  const moves = [];\n  const original3LineHashes = new SetMap();\n  for (const change of changes) {\n    for (let i = change.original.startLineNumber; i < change.original.endLineNumberExclusive - 2; i++) {\n      const key = `${hashedOriginalLines[i - 1]}:${hashedOriginalLines[i + 1 - 1]}:${hashedOriginalLines[i + 2 - 1]}`;\n      original3LineHashes.add(key, { range: new LineRange(i, i + 3) });\n    }\n  }\n  const possibleMappings = [];\n  changes.sort(compareBy((c) => c.modified.startLineNumber, numberComparator));\n  for (const change of changes) {\n    let lastMappings = [];\n    for (let i = change.modified.startLineNumber; i < change.modified.endLineNumberExclusive - 2; i++) {\n      const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`;\n      const currentModifiedRange = new LineRange(i, i + 3);\n      const nextMappings = [];\n      original3LineHashes.forEach(key, ({ range }) => {\n        for (const lastMapping of lastMappings) {\n          if (lastMapping.originalLineRange.endLineNumberExclusive + 1 === range.endLineNumberExclusive && lastMapping.modifiedLineRange.endLineNumberExclusive + 1 === currentModifiedRange.endLineNumberExclusive) {\n            lastMapping.originalLineRange = new LineRange(lastMapping.originalLineRange.startLineNumber, range.endLineNumberExclusive);\n            lastMapping.modifiedLineRange = new LineRange(lastMapping.modifiedLineRange.startLineNumber, currentModifiedRange.endLineNumberExclusive);\n            nextMappings.push(lastMapping);\n            return;\n          }\n        }\n        const mapping = {\n          modifiedLineRange: currentModifiedRange,\n          originalLineRange: range\n        };\n        possibleMappings.push(mapping);\n        nextMappings.push(mapping);\n      });\n      lastMappings = nextMappings;\n    }\n    if (!timeout.isValid()) {\n      return [];\n    }\n  }\n  possibleMappings.sort(reverseOrder(compareBy((m) => m.modifiedLineRange.length, numberComparator)));\n  const modifiedSet = new LineRangeSet();\n  const originalSet = new LineRangeSet();\n  for (const mapping of possibleMappings) {\n    const diffOrigToMod = mapping.modifiedLineRange.startLineNumber - mapping.originalLineRange.startLineNumber;\n    const modifiedSections = modifiedSet.subtractFrom(mapping.modifiedLineRange);\n    const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).getWithDelta(diffOrigToMod);\n    const modifiedIntersectedSections = modifiedSections.getIntersection(originalTranslatedSections);\n    for (const s of modifiedIntersectedSections.ranges) {\n      if (s.length < 3) {\n        continue;\n      }\n      const modifiedLineRange = s;\n      const originalLineRange = s.delta(-diffOrigToMod);\n      moves.push(new LineRangeMapping(originalLineRange, modifiedLineRange));\n      modifiedSet.addRange(modifiedLineRange);\n      originalSet.addRange(originalLineRange);\n    }\n  }\n  moves.sort(compareBy((m) => m.original.startLineNumber, numberComparator));\n  const monotonousChanges = new MonotonousArray(changes);\n  for (let i = 0; i < moves.length; i++) {\n    const move = moves[i];\n    const firstTouchingChangeOrig = monotonousChanges.findLastMonotonous((c) => c.original.startLineNumber <= move.original.startLineNumber);\n    const firstTouchingChangeMod = findLastMonotonous(changes, (c) => c.modified.startLineNumber <= move.modified.startLineNumber);\n    const linesAbove = Math.max(\n      move.original.startLineNumber - firstTouchingChangeOrig.original.startLineNumber,\n      move.modified.startLineNumber - firstTouchingChangeMod.modified.startLineNumber\n    );\n    const lastTouchingChangeOrig = monotonousChanges.findLastMonotonous((c) => c.original.startLineNumber < move.original.endLineNumberExclusive);\n    const lastTouchingChangeMod = findLastMonotonous(changes, (c) => c.modified.startLineNumber < move.modified.endLineNumberExclusive);\n    const linesBelow = Math.max(\n      lastTouchingChangeOrig.original.endLineNumberExclusive - move.original.endLineNumberExclusive,\n      lastTouchingChangeMod.modified.endLineNumberExclusive - move.modified.endLineNumberExclusive\n    );\n    let extendToTop;\n    for (extendToTop = 0; extendToTop < linesAbove; extendToTop++) {\n      const origLine = move.original.startLineNumber - extendToTop - 1;\n      const modLine = move.modified.startLineNumber - extendToTop - 1;\n      if (origLine > originalLines.length || modLine > modifiedLines.length) {\n        break;\n      }\n      if (modifiedSet.contains(modLine) || originalSet.contains(origLine)) {\n        break;\n      }\n      if (!areLinesSimilar(originalLines[origLine - 1], modifiedLines[modLine - 1], timeout)) {\n        break;\n      }\n    }\n    if (extendToTop > 0) {\n      originalSet.addRange(new LineRange(move.original.startLineNumber - extendToTop, move.original.startLineNumber));\n      modifiedSet.addRange(new LineRange(move.modified.startLineNumber - extendToTop, move.modified.startLineNumber));\n    }\n    let extendToBottom;\n    for (extendToBottom = 0; extendToBottom < linesBelow; extendToBottom++) {\n      const origLine = move.original.endLineNumberExclusive + extendToBottom;\n      const modLine = move.modified.endLineNumberExclusive + extendToBottom;\n      if (origLine > originalLines.length || modLine > modifiedLines.length) {\n        break;\n      }\n      if (modifiedSet.contains(modLine) || originalSet.contains(origLine)) {\n        break;\n      }\n      if (!areLinesSimilar(originalLines[origLine - 1], modifiedLines[modLine - 1], timeout)) {\n        break;\n      }\n    }\n    if (extendToBottom > 0) {\n      originalSet.addRange(new LineRange(move.original.endLineNumberExclusive, move.original.endLineNumberExclusive + extendToBottom));\n      modifiedSet.addRange(new LineRange(move.modified.endLineNumberExclusive, move.modified.endLineNumberExclusive + extendToBottom));\n    }\n    if (extendToTop > 0 || extendToBottom > 0) {\n      moves[i] = new LineRangeMapping(\n        new LineRange(move.original.startLineNumber - extendToTop, move.original.endLineNumberExclusive + extendToBottom),\n        new LineRange(move.modified.startLineNumber - extendToTop, move.modified.endLineNumberExclusive + extendToBottom)\n      );\n    }\n  }\n  return moves;\n}\nfunction areLinesSimilar(line1, line2, timeout) {\n  if (line1.trim() === line2.trim()) {\n    return true;\n  }\n  if (line1.length > 300 && line2.length > 300) {\n    return false;\n  }\n  const myersDiffingAlgorithm = new MyersDiffAlgorithm();\n  const result = myersDiffingAlgorithm.compute(\n    new LinesSliceCharSequence([line1], new Range(1, 1, 1, line1.length), false),\n    new LinesSliceCharSequence([line2], new Range(1, 1, 1, line2.length), false),\n    timeout\n  );\n  let commonNonSpaceCharCount = 0;\n  const inverted = SequenceDiff.invert(result.diffs, line1.length);\n  for (const seq of inverted) {\n    seq.seq1Range.forEach((idx) => {\n      if (!isSpace(line1.charCodeAt(idx))) {\n        commonNonSpaceCharCount++;\n      }\n    });\n  }\n  function countNonWsChars(str) {\n    let count = 0;\n    for (let i = 0; i < line1.length; i++) {\n      if (!isSpace(str.charCodeAt(i))) {\n        count++;\n      }\n    }\n    return count;\n  }\n  const longerLineLength = countNonWsChars(line1.length > line2.length ? line1 : line2);\n  const r = commonNonSpaceCharCount / longerLineLength > 0.6 && longerLineLength > 10;\n  return r;\n}\nfunction joinCloseConsecutiveMoves(moves) {\n  if (moves.length === 0) {\n    return moves;\n  }\n  moves.sort(compareBy((m) => m.original.startLineNumber, numberComparator));\n  const result = [moves[0]];\n  for (let i = 1; i < moves.length; i++) {\n    const last = result[result.length - 1];\n    const current = moves[i];\n    const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive;\n    const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive;\n    const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0;\n    if (currentMoveAfterLast && originalDist + modifiedDist <= 2) {\n      result[result.length - 1] = last.join(current);\n      continue;\n    }\n    result.push(current);\n  }\n  return result;\n}\nfunction removeMovesInSameDiff(changes, moves) {\n  const changesMonotonous = new MonotonousArray(changes);\n  moves = moves.filter((m) => {\n    const diffBeforeEndOfMoveOriginal = changesMonotonous.findLastMonotonous((c) => c.original.startLineNumber < m.original.endLineNumberExclusive) || new LineRangeMapping(new LineRange(1, 1), new LineRange(1, 1));\n    const diffBeforeEndOfMoveModified = findLastMonotonous(changes, (c) => c.modified.startLineNumber < m.modified.endLineNumberExclusive);\n    const differentDiffs = diffBeforeEndOfMoveOriginal !== diffBeforeEndOfMoveModified;\n    return differentDiffs;\n  });\n  return moves;\n}\n\nfunction optimizeSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n  let result = sequenceDiffs;\n  result = joinSequenceDiffsByShifting(sequence1, sequence2, result);\n  result = joinSequenceDiffsByShifting(sequence1, sequence2, result);\n  result = shiftSequenceDiffs(sequence1, sequence2, result);\n  return result;\n}\nfunction joinSequenceDiffsByShifting(sequence1, sequence2, sequenceDiffs) {\n  if (sequenceDiffs.length === 0) {\n    return sequenceDiffs;\n  }\n  const result = [];\n  result.push(sequenceDiffs[0]);\n  for (let i = 1; i < sequenceDiffs.length; i++) {\n    const prevResult = result[result.length - 1];\n    let cur = sequenceDiffs[i];\n    if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {\n      const length = cur.seq1Range.start - prevResult.seq1Range.endExclusive;\n      let d;\n      for (d = 1; d <= length; d++) {\n        if (sequence1.getElement(cur.seq1Range.start - d) !== sequence1.getElement(cur.seq1Range.endExclusive - d) || sequence2.getElement(cur.seq2Range.start - d) !== sequence2.getElement(cur.seq2Range.endExclusive - d)) {\n          break;\n        }\n      }\n      d--;\n      if (d === length) {\n        result[result.length - 1] = new SequenceDiff(\n          new OffsetRange(prevResult.seq1Range.start, cur.seq1Range.endExclusive - length),\n          new OffsetRange(prevResult.seq2Range.start, cur.seq2Range.endExclusive - length)\n        );\n        continue;\n      }\n      cur = cur.delta(-d);\n    }\n    result.push(cur);\n  }\n  const result2 = [];\n  for (let i = 0; i < result.length - 1; i++) {\n    const nextResult = result[i + 1];\n    let cur = result[i];\n    if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {\n      const length = nextResult.seq1Range.start - cur.seq1Range.endExclusive;\n      let d;\n      for (d = 0; d < length; d++) {\n        if (!sequence1.isStronglyEqual(cur.seq1Range.start + d, cur.seq1Range.endExclusive + d) || !sequence2.isStronglyEqual(cur.seq2Range.start + d, cur.seq2Range.endExclusive + d)) {\n          break;\n        }\n      }\n      if (d === length) {\n        result[i + 1] = new SequenceDiff(\n          new OffsetRange(cur.seq1Range.start + length, nextResult.seq1Range.endExclusive),\n          new OffsetRange(cur.seq2Range.start + length, nextResult.seq2Range.endExclusive)\n        );\n        continue;\n      }\n      if (d > 0) {\n        cur = cur.delta(d);\n      }\n    }\n    result2.push(cur);\n  }\n  if (result.length > 0) {\n    result2.push(result[result.length - 1]);\n  }\n  return result2;\n}\nfunction shiftSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n  if (!sequence1.getBoundaryScore || !sequence2.getBoundaryScore) {\n    return sequenceDiffs;\n  }\n  for (let i = 0; i < sequenceDiffs.length; i++) {\n    const prevDiff = i > 0 ? sequenceDiffs[i - 1] : undefined;\n    const diff = sequenceDiffs[i];\n    const nextDiff = i + 1 < sequenceDiffs.length ? sequenceDiffs[i + 1] : undefined;\n    const seq1ValidRange = new OffsetRange(prevDiff ? prevDiff.seq1Range.endExclusive + 1 : 0, nextDiff ? nextDiff.seq1Range.start - 1 : sequence1.length);\n    const seq2ValidRange = new OffsetRange(prevDiff ? prevDiff.seq2Range.endExclusive + 1 : 0, nextDiff ? nextDiff.seq2Range.start - 1 : sequence2.length);\n    if (diff.seq1Range.isEmpty) {\n      sequenceDiffs[i] = shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange);\n    } else if (diff.seq2Range.isEmpty) {\n      sequenceDiffs[i] = shiftDiffToBetterPosition(diff.swap(), sequence2, sequence1, seq2ValidRange, seq1ValidRange).swap();\n    }\n  }\n  return sequenceDiffs;\n}\nfunction shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange) {\n  const maxShiftLimit = 100;\n  let deltaBefore = 1;\n  while (diff.seq1Range.start - deltaBefore >= seq1ValidRange.start && diff.seq2Range.start - deltaBefore >= seq2ValidRange.start && sequence2.isStronglyEqual(diff.seq2Range.start - deltaBefore, diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit) {\n    deltaBefore++;\n  }\n  deltaBefore--;\n  let deltaAfter = 0;\n  while (diff.seq1Range.start + deltaAfter < seq1ValidRange.endExclusive && diff.seq2Range.endExclusive + deltaAfter < seq2ValidRange.endExclusive && sequence2.isStronglyEqual(diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit) {\n    deltaAfter++;\n  }\n  if (deltaBefore === 0 && deltaAfter === 0) {\n    return diff;\n  }\n  let bestDelta = 0;\n  let bestScore = -1;\n  for (let delta = -deltaBefore; delta <= deltaAfter; delta++) {\n    const seq2OffsetStart = diff.seq2Range.start + delta;\n    const seq2OffsetEndExclusive = diff.seq2Range.endExclusive + delta;\n    const seq1Offset = diff.seq1Range.start + delta;\n    const score = sequence1.getBoundaryScore(seq1Offset) + sequence2.getBoundaryScore(seq2OffsetStart) + sequence2.getBoundaryScore(seq2OffsetEndExclusive);\n    if (score > bestScore) {\n      bestScore = score;\n      bestDelta = delta;\n    }\n  }\n  return diff.delta(bestDelta);\n}\nfunction removeShortMatches(sequence1, sequence2, sequenceDiffs) {\n  const result = [];\n  for (const s of sequenceDiffs) {\n    const last = result[result.length - 1];\n    if (!last) {\n      result.push(s);\n      continue;\n    }\n    if (s.seq1Range.start - last.seq1Range.endExclusive <= 2 || s.seq2Range.start - last.seq2Range.endExclusive <= 2) {\n      result[result.length - 1] = new SequenceDiff(last.seq1Range.join(s.seq1Range), last.seq2Range.join(s.seq2Range));\n    } else {\n      result.push(s);\n    }\n  }\n  return result;\n}\nfunction extendDiffsToEntireWordIfAppropriate(sequence1, sequence2, sequenceDiffs, findParent, force = false) {\n  const equalMappings = SequenceDiff.invert(sequenceDiffs, sequence1.length);\n  const additional = [];\n  let lastPoint = new OffsetPair(0, 0);\n  function scanWord(pair, equalMapping) {\n    if (pair.offset1 < lastPoint.offset1 || pair.offset2 < lastPoint.offset2) {\n      return;\n    }\n    const w1 = findParent(sequence1, pair.offset1);\n    const w2 = findParent(sequence2, pair.offset2);\n    if (!w1 || !w2) {\n      return;\n    }\n    let w = new SequenceDiff(w1, w2);\n    const equalPart = w.intersect(equalMapping);\n    let equalChars1 = equalPart.seq1Range.length;\n    let equalChars2 = equalPart.seq2Range.length;\n    while (equalMappings.length > 0) {\n      const next = equalMappings[0];\n      const intersects = next.seq1Range.intersects(w.seq1Range) || next.seq2Range.intersects(w.seq2Range);\n      if (!intersects) {\n        break;\n      }\n      const v1 = findParent(sequence1, next.seq1Range.start);\n      const v2 = findParent(sequence2, next.seq2Range.start);\n      const v = new SequenceDiff(v1, v2);\n      const equalPart2 = v.intersect(next);\n      equalChars1 += equalPart2.seq1Range.length;\n      equalChars2 += equalPart2.seq2Range.length;\n      w = w.join(v);\n      if (w.seq1Range.endExclusive >= next.seq1Range.endExclusive) {\n        equalMappings.shift();\n      } else {\n        break;\n      }\n    }\n    if (force && equalChars1 + equalChars2 < w.seq1Range.length + w.seq2Range.length || equalChars1 + equalChars2 < (w.seq1Range.length + w.seq2Range.length) * 2 / 3) {\n      additional.push(w);\n    }\n    lastPoint = w.getEndExclusives();\n  }\n  while (equalMappings.length > 0) {\n    const next = equalMappings.shift();\n    if (next.seq1Range.isEmpty) {\n      continue;\n    }\n    scanWord(next.getStarts(), next);\n    scanWord(next.getEndExclusives().delta(-1), next);\n  }\n  const merged = mergeSequenceDiffs(sequenceDiffs, additional);\n  return merged;\n}\nfunction mergeSequenceDiffs(sequenceDiffs1, sequenceDiffs2) {\n  const result = [];\n  while (sequenceDiffs1.length > 0 || sequenceDiffs2.length > 0) {\n    const sd1 = sequenceDiffs1[0];\n    const sd2 = sequenceDiffs2[0];\n    let next;\n    if (sd1 && (!sd2 || sd1.seq1Range.start < sd2.seq1Range.start)) {\n      next = sequenceDiffs1.shift();\n    } else {\n      next = sequenceDiffs2.shift();\n    }\n    if (result.length > 0 && result[result.length - 1].seq1Range.endExclusive >= next.seq1Range.start) {\n      result[result.length - 1] = result[result.length - 1].join(next);\n    } else {\n      result.push(next);\n    }\n  }\n  return result;\n}\nfunction removeVeryShortMatchingLinesBetweenDiffs(sequence1, _sequence2, sequenceDiffs) {\n  let diffs = sequenceDiffs;\n  if (diffs.length === 0) {\n    return diffs;\n  }\n  let counter = 0;\n  let shouldRepeat;\n  do {\n    shouldRepeat = false;\n    const result = [\n      diffs[0]\n    ];\n    for (let i = 1; i < diffs.length; i++) {\n      let shouldJoinDiffs = function(before, after) {\n        const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);\n        const unchangedText = sequence1.getText(unchangedRange);\n        const unchangedTextWithoutWs = unchangedText.replace(/\\s/g, \"\");\n        if (unchangedTextWithoutWs.length <= 4 && (before.seq1Range.length + before.seq2Range.length > 5 || after.seq1Range.length + after.seq2Range.length > 5)) {\n          return true;\n        }\n        return false;\n      };\n      const cur = diffs[i];\n      const lastResult = result[result.length - 1];\n      const shouldJoin = shouldJoinDiffs(lastResult, cur);\n      if (shouldJoin) {\n        shouldRepeat = true;\n        result[result.length - 1] = result[result.length - 1].join(cur);\n      } else {\n        result.push(cur);\n      }\n    }\n    diffs = result;\n  } while (counter++ < 10 && shouldRepeat);\n  return diffs;\n}\nfunction removeVeryShortMatchingTextBetweenLongDiffs(sequence1, sequence2, sequenceDiffs) {\n  let diffs = sequenceDiffs;\n  if (diffs.length === 0) {\n    return diffs;\n  }\n  let counter = 0;\n  let shouldRepeat;\n  do {\n    shouldRepeat = false;\n    const result = [\n      diffs[0]\n    ];\n    for (let i = 1; i < diffs.length; i++) {\n      let shouldJoinDiffs = function(before, after) {\n        const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);\n        const unchangedLineCount = sequence1.countLinesIn(unchangedRange);\n        if (unchangedLineCount > 5 || unchangedRange.length > 500) {\n          return false;\n        }\n        const unchangedText = sequence1.getText(unchangedRange).trim();\n        if (unchangedText.length > 20 || unchangedText.split(/\\r\\n|\\r|\\n/).length > 1) {\n          return false;\n        }\n        const beforeLineCount1 = sequence1.countLinesIn(before.seq1Range);\n        const beforeSeq1Length = before.seq1Range.length;\n        const beforeLineCount2 = sequence2.countLinesIn(before.seq2Range);\n        const beforeSeq2Length = before.seq2Range.length;\n        const afterLineCount1 = sequence1.countLinesIn(after.seq1Range);\n        const afterSeq1Length = after.seq1Range.length;\n        const afterLineCount2 = sequence2.countLinesIn(after.seq2Range);\n        const afterSeq2Length = after.seq2Range.length;\n        const max = 2 * 40 + 50;\n        function cap(v) {\n          return Math.min(v, max);\n        }\n        if (Math.pow(Math.pow(cap(beforeLineCount1 * 40 + beforeSeq1Length), 1.5) + Math.pow(cap(beforeLineCount2 * 40 + beforeSeq2Length), 1.5), 1.5) + Math.pow(Math.pow(cap(afterLineCount1 * 40 + afterSeq1Length), 1.5) + Math.pow(cap(afterLineCount2 * 40 + afterSeq2Length), 1.5), 1.5) > (max ** 1.5) ** 1.5 * 1.3) {\n          return true;\n        }\n        return false;\n      };\n      const cur = diffs[i];\n      const lastResult = result[result.length - 1];\n      const shouldJoin = shouldJoinDiffs(lastResult, cur);\n      if (shouldJoin) {\n        shouldRepeat = true;\n        result[result.length - 1] = result[result.length - 1].join(cur);\n      } else {\n        result.push(cur);\n      }\n    }\n    diffs = result;\n  } while (counter++ < 10 && shouldRepeat);\n  const newDiffs = [];\n  forEachWithNeighbors(diffs, (prev, cur, next) => {\n    let newDiff = cur;\n    function shouldMarkAsChanged(text) {\n      return text.length > 0 && text.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100;\n    }\n    const fullRange1 = sequence1.extendToFullLines(cur.seq1Range);\n    const prefix = sequence1.getText(new OffsetRange(fullRange1.start, cur.seq1Range.start));\n    if (shouldMarkAsChanged(prefix)) {\n      newDiff = newDiff.deltaStart(-prefix.length);\n    }\n    const suffix = sequence1.getText(new OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive));\n    if (shouldMarkAsChanged(suffix)) {\n      newDiff = newDiff.deltaEnd(suffix.length);\n    }\n    const availableSpace = SequenceDiff.fromOffsetPairs(\n      prev ? prev.getEndExclusives() : OffsetPair.zero,\n      next ? next.getStarts() : OffsetPair.max\n    );\n    const result = newDiff.intersect(availableSpace);\n    if (newDiffs.length > 0 && result.getStarts().equals(newDiffs[newDiffs.length - 1].getEndExclusives())) {\n      newDiffs[newDiffs.length - 1] = newDiffs[newDiffs.length - 1].join(result);\n    } else {\n      newDiffs.push(result);\n    }\n  });\n  return newDiffs;\n}\n\nclass LineSequence {\n  constructor(trimmedHash, lines) {\n    this.trimmedHash = trimmedHash;\n    this.lines = lines;\n  }\n  getElement(offset) {\n    return this.trimmedHash[offset];\n  }\n  get length() {\n    return this.trimmedHash.length;\n  }\n  getBoundaryScore(length) {\n    const indentationBefore = length === 0 ? 0 : getIndentation(this.lines[length - 1]);\n    const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]);\n    return 1e3 - (indentationBefore + indentationAfter);\n  }\n  getText(range) {\n    return this.lines.slice(range.start, range.endExclusive).join(\"\\n\");\n  }\n  isStronglyEqual(offset1, offset2) {\n    return this.lines[offset1] === this.lines[offset2];\n  }\n}\nfunction getIndentation(str) {\n  let i = 0;\n  while (i < str.length && (str.charCodeAt(i) === 32 || str.charCodeAt(i) === 9)) {\n    i++;\n  }\n  return i;\n}\n\nclass DefaultLinesDiffComputer {\n  constructor() {\n    this.dynamicProgrammingDiffing = new DynamicProgrammingDiffing();\n    this.myersDiffingAlgorithm = new MyersDiffAlgorithm();\n  }\n  computeDiff(originalLines, modifiedLines, options) {\n    if (originalLines.length <= 1 && equals(originalLines, modifiedLines, (a, b) => a === b)) {\n      return new LinesDiff([], [], false);\n    }\n    if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) {\n      return new LinesDiff([\n        new DetailedLineRangeMapping(\n          new LineRange(1, originalLines.length + 1),\n          new LineRange(1, modifiedLines.length + 1),\n          [\n            new RangeMapping(\n              new Range(1, 1, originalLines.length, originalLines[originalLines.length - 1].length + 1),\n              new Range(1, 1, modifiedLines.length, modifiedLines[modifiedLines.length - 1].length + 1)\n            )\n          ]\n        )\n      ], [], false);\n    }\n    const timeout = options.maxComputationTimeMs === 0 ? InfiniteTimeout.instance : new DateTimeout(options.maxComputationTimeMs);\n    const considerWhitespaceChanges = !options.ignoreTrimWhitespace;\n    const perfectHashes = /* @__PURE__ */ new Map();\n    function getOrCreateHash(text) {\n      let hash = perfectHashes.get(text);\n      if (hash === undefined) {\n        hash = perfectHashes.size;\n        perfectHashes.set(text, hash);\n      }\n      return hash;\n    }\n    const originalLinesHashes = originalLines.map((l) => getOrCreateHash(l.trim()));\n    const modifiedLinesHashes = modifiedLines.map((l) => getOrCreateHash(l.trim()));\n    const sequence1 = new LineSequence(originalLinesHashes, originalLines);\n    const sequence2 = new LineSequence(modifiedLinesHashes, modifiedLines);\n    const lineAlignmentResult = (() => {\n      if (sequence1.length + sequence2.length < 1700) {\n        return this.dynamicProgrammingDiffing.compute(\n          sequence1,\n          sequence2,\n          timeout,\n          (offset1, offset2) => originalLines[offset1] === modifiedLines[offset2] ? modifiedLines[offset2].length === 0 ? 0.1 : 1 + Math.log(1 + modifiedLines[offset2].length) : 0.99\n        );\n      }\n      return this.myersDiffingAlgorithm.compute(\n        sequence1,\n        sequence2,\n        timeout\n      );\n    })();\n    let lineAlignments = lineAlignmentResult.diffs;\n    let hitTimeout = lineAlignmentResult.hitTimeout;\n    lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments);\n    lineAlignments = removeVeryShortMatchingLinesBetweenDiffs(sequence1, sequence2, lineAlignments);\n    const alignments = [];\n    const scanForWhitespaceChanges = (equalLinesCount) => {\n      if (!considerWhitespaceChanges) {\n        return;\n      }\n      for (let i = 0; i < equalLinesCount; i++) {\n        const seq1Offset = seq1LastStart + i;\n        const seq2Offset = seq2LastStart + i;\n        if (originalLines[seq1Offset] !== modifiedLines[seq2Offset]) {\n          const characterDiffs = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(\n            new OffsetRange(seq1Offset, seq1Offset + 1),\n            new OffsetRange(seq2Offset, seq2Offset + 1)\n          ), timeout, considerWhitespaceChanges, options);\n          for (const a of characterDiffs.mappings) {\n            alignments.push(a);\n          }\n          if (characterDiffs.hitTimeout) {\n            hitTimeout = true;\n          }\n        }\n      }\n    };\n    let seq1LastStart = 0;\n    let seq2LastStart = 0;\n    for (const diff of lineAlignments) {\n      assertFn(() => diff.seq1Range.start - seq1LastStart === diff.seq2Range.start - seq2LastStart);\n      const equalLinesCount = diff.seq1Range.start - seq1LastStart;\n      scanForWhitespaceChanges(equalLinesCount);\n      seq1LastStart = diff.seq1Range.endExclusive;\n      seq2LastStart = diff.seq2Range.endExclusive;\n      const characterDiffs = this.refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges, options);\n      if (characterDiffs.hitTimeout) {\n        hitTimeout = true;\n      }\n      for (const a of characterDiffs.mappings) {\n        alignments.push(a);\n      }\n    }\n    scanForWhitespaceChanges(originalLines.length - seq1LastStart);\n    const changes = lineRangeMappingFromRangeMappings(alignments, new ArrayText(originalLines), new ArrayText(modifiedLines));\n    let moves = [];\n    if (options.computeMoves) {\n      moves = this.computeMoves(changes, originalLines, modifiedLines, originalLinesHashes, modifiedLinesHashes, timeout, considerWhitespaceChanges, options);\n    }\n    assertFn(() => {\n      function validatePosition(pos, lines) {\n        if (pos.lineNumber < 1 || pos.lineNumber > lines.length) {\n          return false;\n        }\n        const line = lines[pos.lineNumber - 1];\n        if (pos.column < 1 || pos.column > line.length + 1) {\n          return false;\n        }\n        return true;\n      }\n      function validateRange(range, lines) {\n        if (range.startLineNumber < 1 || range.startLineNumber > lines.length + 1) {\n          return false;\n        }\n        if (range.endLineNumberExclusive < 1 || range.endLineNumberExclusive > lines.length + 1) {\n          return false;\n        }\n        return true;\n      }\n      for (const c of changes) {\n        if (!c.innerChanges) {\n          return false;\n        }\n        for (const ic of c.innerChanges) {\n          const valid = validatePosition(ic.modifiedRange.getStartPosition(), modifiedLines) && validatePosition(ic.modifiedRange.getEndPosition(), modifiedLines) && validatePosition(ic.originalRange.getStartPosition(), originalLines) && validatePosition(ic.originalRange.getEndPosition(), originalLines);\n          if (!valid) {\n            return false;\n          }\n        }\n        if (!validateRange(c.modified, modifiedLines) || !validateRange(c.original, originalLines)) {\n          return false;\n        }\n      }\n      return true;\n    });\n    return new LinesDiff(changes, moves, hitTimeout);\n  }\n  computeMoves(changes, originalLines, modifiedLines, hashedOriginalLines, hashedModifiedLines, timeout, considerWhitespaceChanges, options) {\n    const moves = computeMovedLines(\n      changes,\n      originalLines,\n      modifiedLines,\n      hashedOriginalLines,\n      hashedModifiedLines,\n      timeout\n    );\n    const movesWithDiffs = moves.map((m) => {\n      const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(\n        m.original.toOffsetRange(),\n        m.modified.toOffsetRange()\n      ), timeout, considerWhitespaceChanges, options);\n      const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, new ArrayText(originalLines), new ArrayText(modifiedLines), true);\n      return new MovedText(m, mappings);\n    });\n    return movesWithDiffs;\n  }\n  refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges, options) {\n    const lineRangeMapping = toLineRangeMapping(diff);\n    const rangeMapping = lineRangeMapping.toRangeMapping2(originalLines, modifiedLines);\n    const slice1 = new LinesSliceCharSequence(originalLines, rangeMapping.originalRange, considerWhitespaceChanges);\n    const slice2 = new LinesSliceCharSequence(modifiedLines, rangeMapping.modifiedRange, considerWhitespaceChanges);\n    const diffResult = slice1.length + slice2.length < 500 ? this.dynamicProgrammingDiffing.compute(slice1, slice2, timeout) : this.myersDiffingAlgorithm.compute(slice1, slice2, timeout);\n    let diffs = diffResult.diffs;\n    diffs = optimizeSequenceDiffs(slice1, slice2, diffs);\n    diffs = extendDiffsToEntireWordIfAppropriate(slice1, slice2, diffs, (seq, idx) => seq.findWordContaining(idx));\n    if (options.extendToSubwords) {\n      diffs = extendDiffsToEntireWordIfAppropriate(slice1, slice2, diffs, (seq, idx) => seq.findSubWordContaining(idx), true);\n    }\n    diffs = removeShortMatches(slice1, slice2, diffs);\n    diffs = removeVeryShortMatchingTextBetweenLongDiffs(slice1, slice2, diffs);\n    const result = diffs.map(\n      (d) => new RangeMapping(\n        slice1.translateRange(d.seq1Range),\n        slice2.translateRange(d.seq2Range)\n      )\n    );\n    return {\n      mappings: result,\n      hitTimeout: diffResult.hitTimeout\n    };\n  }\n}\nfunction toLineRangeMapping(sequenceDiff) {\n  return new LineRangeMapping(\n    new LineRange(sequenceDiff.seq1Range.start + 1, sequenceDiff.seq1Range.endExclusive + 1),\n    new LineRange(sequenceDiff.seq2Range.start + 1, sequenceDiff.seq2Range.endExclusive + 1)\n  );\n}\n\nfunction computeDiff(originalLines, modifiedLines, options) {\n  let diffComputer = new DefaultLinesDiffComputer();\n  var result = diffComputer.computeDiff(originalLines, modifiedLines, options);\n  return result?.changes.map((changes) => {\n    let originalStartLineNumber;\n    let originalEndLineNumber;\n    let modifiedStartLineNumber;\n    let modifiedEndLineNumber;\n    let innerChanges = changes.innerChanges;\n    originalStartLineNumber = changes.original.startLineNumber - 1;\n    originalEndLineNumber = changes.original.endLineNumberExclusive - 1;\n    modifiedStartLineNumber = changes.modified.startLineNumber - 1;\n    modifiedEndLineNumber = changes.modified.endLineNumberExclusive - 1;\n    return {\n      origStart: originalStartLineNumber,\n      origEnd: originalEndLineNumber,\n      editStart: modifiedStartLineNumber,\n      editEnd: modifiedEndLineNumber,\n      charChanges: innerChanges?.map((m) => ({\n        originalStartLineNumber: m.originalRange.startLineNumber - 1,\n        originalStartColumn: m.originalRange.startColumn - 1,\n        originalEndLineNumber: m.originalRange.endLineNumber - 1,\n        originalEndColumn: m.originalRange.endColumn - 1,\n        modifiedStartLineNumber: m.modifiedRange.startLineNumber - 1,\n        modifiedStartColumn: m.modifiedRange.startColumn - 1,\n        modifiedEndLineNumber: m.modifiedRange.endLineNumber - 1,\n        modifiedEndColumn: m.modifiedRange.endColumn - 1\n      }))\n    };\n  });\n}\n\nexports.computeDiff = computeDiff;\n\nvar AceRange = require(\"../../../range\").Range;\n\nvar {DiffChunk} = require(\"../base_diff_view\"); \n \n/**\n * VSCode’s computeDiff provider\n */\n\nclass DiffProvider {\n    compute(originalLines, modifiedLines, opts) {\n        if (!opts) opts = {};\n        if (!opts.maxComputationTimeMs) opts.maxComputationTimeMs = 500;\n        const chunks = computeDiff(originalLines, modifiedLines, opts) || [];\n        return chunks.map(\n            c => new DiffChunk(new AceRange(c.origStart, 0, c.origEnd, 0), new AceRange(c.editStart, 0, c.editEnd, 0),\n                c.charChanges\n            ));\n    }\n}\n\nexports.DiffProvider = DiffProvider;"
  },
  {
    "path": "src/ext/diff/scroll_diff_decorator.js",
    "content": "var Decorator = require(\"../../layer/decorators\").Decorator;\n\nclass ScrollDiffDecorator extends Decorator {\n    /**\n     * @param {import(\"../../../ace-internal\").Ace.VScrollbar} scrollbarV\n     * @param {import(\"../../virtual_renderer\").VirtualRenderer} renderer\n     * @param {boolean} [forInlineDiff]\n     */\n    constructor(scrollbarV, renderer, forInlineDiff) {\n        super(scrollbarV, renderer);\n\n        this.colors.dark[\"delete\"] = \"rgba(255, 18, 18, 1)\";\n        this.colors.dark[\"insert\"] = \"rgba(18, 136, 18, 1)\";\n        this.colors.light[\"delete\"] = \"rgb(255,51,51)\";\n        this.colors.light[\"insert\"] = \"rgb(32,133,72)\";\n\n        this.$zones = [];\n        this.$forInlineDiff = forInlineDiff;\n    }\n\n    /**\n     * @param {number} startRow\n     * @param {number} endRow\n     * @param {\"delete\"|\"insert\"} type\n     */\n    addZone(startRow, endRow, type) {\n        this.$zones.push({\n            startRow,\n            endRow,\n            type\n        });\n    }\n\n    /**\n     * @param {import(\"../../edit_session\").EditSession} sessionA\n     * @param {import(\"../../edit_session\").EditSession} sessionB\n     */\n    setSessions(sessionA, sessionB) {\n        this.sessionA = sessionA;\n        this.sessionB = sessionB;\n    }\n\n    $updateDecorators(config) {\n        if (typeof this.canvas.getContext !== \"function\") {\n            return;\n        }\n        super.$updateDecorators(config);\n        if (this.$zones.length > 0) {\n            var colors = (this.renderer.theme.isDark === true) ? this.colors.dark : this.colors.light;\n            var ctx = this.canvas.getContext(\"2d\");\n            this.$setDiffDecorators(ctx, colors);\n        }\n    }\n\n    /**\n     * @param {number} row\n     * @param {string} type\n     */\n    $transformPosition(row, type) {\n        if (type == \"delete\") {\n            return this.sessionA.documentToScreenRow(row, 0);\n        } else {\n            return this.sessionB.documentToScreenRow(row, 0);\n        }\n    }\n\n    $setDiffDecorators(ctx, colors) {\n        function compare(a, b) {\n            if (a.from === b.from) {\n                return a.to - b.to;\n            }\n            return a.from - b.from;\n        }\n\n        var zones = this.$zones;\n        if (zones) {\n            var resolvedZones = [];\n\n            const deleteZones = zones.filter(z => z.type === \"delete\");\n            const insertZones = zones.filter(z => z.type === \"insert\");\n\n            [deleteZones, insertZones].forEach((typeZones) => {\n                typeZones.forEach((zone, i) => {\n                    const offset1 = this.$transformPosition(zone.startRow, zone.type) * this.lineHeight;\n                    let offset2 = this.$transformPosition(zone.endRow, zone.type) * this.lineHeight + this.lineHeight;\n\n                    const y1 = Math.round(this.heightRatio * offset1);\n                    const y2 = Math.round(this.heightRatio * offset2);\n\n                    const padding = 1;\n\n                    let ycenter = Math.round((y1 + y2) / 2);\n                    let halfHeight = (y2 - ycenter);\n\n                    if (halfHeight < this.halfMinDecorationHeight) {\n                        halfHeight = this.halfMinDecorationHeight;\n                    }\n\n                    const previousZone = resolvedZones[resolvedZones.length - 1];\n\n                    if (i > 0 && previousZone && previousZone.type === zone.type && ycenter - halfHeight < previousZone.to + padding) {\n                        ycenter = resolvedZones[resolvedZones.length - 1].to + padding + halfHeight;\n                    }\n\n                    if (ycenter - halfHeight < 0) {\n                        ycenter = halfHeight;\n                    }\n                    if (ycenter + halfHeight > this.canvasHeight) {\n                        ycenter = this.canvasHeight - halfHeight;\n                    }\n\n                    resolvedZones.push({\n                        type: zone.type,\n                        from: ycenter - halfHeight,\n                        to: ycenter + halfHeight,\n                        color: colors[zone.type] || null\n                    });\n                });\n            });\n\n            resolvedZones = resolvedZones.sort(compare);\n\n            for (const zone of resolvedZones) {\n                ctx.fillStyle = zone.color || null;\n\n                const zoneFrom = zone.from;\n                const zoneTo = zone.to;\n                const zoneHeight = zoneTo - zoneFrom;\n                if (this.$forInlineDiff) {\n                    ctx.fillRect(this.oneZoneWidth, zoneFrom, 2 * this.oneZoneWidth, zoneHeight);\n                } else {\n                    if (zone.type == \"delete\") {\n                        ctx.fillRect(this.oneZoneWidth, zoneFrom, this.oneZoneWidth, zoneHeight);\n                    }\n                    else {\n                        ctx.fillRect(2 * this.oneZoneWidth, zoneFrom, this.oneZoneWidth, zoneHeight);\n                    }\n                }\n            }\n\n        }\n    }\n\n    setZoneWidth() {\n        this.oneZoneWidth = Math.round(this.canvasWidth / 3);\n    }\n}\n\nexports.ScrollDiffDecorator = ScrollDiffDecorator;"
  },
  {
    "path": "src/ext/diff/split_diff_view.js",
    "content": "\"use strict\";\n\nvar BaseDiffView = require(\"./base_diff_view\").BaseDiffView;\nvar config = require(\"../../config\");\n\nclass SplitDiffView extends BaseDiffView {\n    /**\n     * Constructs a new side by side DiffView instance.\n     *\n     * @param {import(\"../diff\").DiffModel} [diffModel] - The model for the diff view.\n     */\n    constructor(diffModel) {\n        diffModel = diffModel || {};\n        super();\n        this.init(diffModel);\n    }\n\n    init(diffModel) {\n        this.onChangeTheme = this.onChangeTheme.bind(this);\n        this.onMouseWheel = this.onMouseWheel.bind(this);\n        this.onScroll = this.onScroll.bind(this);\n\n        this.$setupModels(diffModel);\n\n        this.addGutterDecorators();\n\n        this.onChangeTheme();\n\n        config.resetOptions(this);\n        config[\"_signal\"](\"diffView\", this);\n\n        this.$attachEventHandlers();\n    }\n\n    onChangeWrapLimit() {\n        this.scheduleRealign();\n    }\n\n    /*** scroll locking ***/\n    align() {\n        var diffView = this;\n\n        this.$initWidgets(diffView.editorA);\n        this.$initWidgets(diffView.editorB);\n\n        diffView.chunks.forEach(function (ch) {\n            var diff1 = diffView.$screenRow(ch.old.start, diffView.sessionA);\n            var diff2 = diffView.$screenRow(ch.new.start, diffView.sessionB); \n\n            if (diff1 < diff2) {\n                diffView.$addWidget(diffView.sessionA, {\n                    rowCount: diff2 - diff1,\n                    rowsAbove: ch.old.start.row === 0 ? diff2 - diff1 : 0,\n                    row: ch.old.start.row === 0 ? 0 : ch.old.start.row - 1\n                });\n            }\n            else if (diff1 > diff2) {\n                diffView.$addWidget(diffView.sessionB, {\n                    rowCount: diff1 - diff2,\n                    rowsAbove: ch.new.start.row === 0 ? diff1 - diff2 : 0,\n                    row: ch.new.start.row === 0 ? 0 : ch.new.start.row - 1\n                });\n            }\n\n            var diff1 = diffView.$screenRow(ch.old.end, diffView.sessionA);\n            var diff2 = diffView.$screenRow(ch.new.end, diffView.sessionB); \n            if (diff1 < diff2) {\n                diffView.$addWidget(diffView.sessionA, {\n                    rowCount: diff2 - diff1,\n                    rowsAbove: ch.old.end.row === 0 ? diff2 - diff1 : 0,\n                    row: ch.old.end.row === 0 ? 0 : ch.old.end.row - 1\n                });\n            }\n            else if (diff1 > diff2) {\n                diffView.$addWidget(diffView.sessionB, {\n                    rowCount: diff1 - diff2,\n                    rowsAbove: ch.new.end.row === 0 ? diff1 - diff2 : 0,\n                    row: ch.new.end.row === 0 ? 0 : ch.new.end.row - 1\n                });\n            }\n        });\n        diffView.sessionA[\"_emit\"](\"changeFold\", {data: {start: {row: 0}}});\n        diffView.sessionB[\"_emit\"](\"changeFold\", {data: {start: {row: 0}}});\n    }\n\n    onScroll(e, session) {\n        this.syncScroll(this.sessionA === session ? this.editorA.renderer : this.editorB.renderer);\n    }\n\n    /**\n     * @param {import(\"../../virtual_renderer\").VirtualRenderer} renderer\n     */\n    syncScroll(renderer) {\n        if (this.$syncScroll == false) return;\n\n        var r1 = this.editorA.renderer;\n        var r2 = this.editorB.renderer;\n        var isOrig = renderer == r1;\n        if (r1[\"$scrollAnimation\"] && r2[\"$scrollAnimation\"]) return;\n\n        var now = Date.now();\n        if (this.scrollSetBy != renderer && now - this.scrollSetAt < 500) return;\n\n        var r = isOrig ? r1 : r2;\n        if (this.scrollSetBy != renderer) {\n            if (isOrig && this.scrollA == r.session.getScrollTop()) return; else if (!isOrig && this.scrollB\n                == r.session.getScrollTop()) return;\n        }\n        var rOther = isOrig ? r2 : r1;\n\n        var targetPos = r.session.getScrollTop();\n\n        this.$syncScroll = false;\n\n        if (isOrig) {\n            this.scrollA = r.session.getScrollTop();\n            this.scrollB = targetPos;\n        }\n        else {\n            this.scrollA = targetPos;\n            this.scrollB = r.session.getScrollTop();\n        }\n        this.scrollSetBy = renderer;\n        rOther.session.setScrollTop(targetPos);\n        this.$syncScroll = true;\n        this.scrollSetAt = now;\n    }\n\n    onMouseWheel(ev) {\n        if (ev.getAccelKey()) return;\n        if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {\n            ev.wheelX = ev.wheelY;\n            ev.wheelY = 0;\n        }\n\n        var editor = ev.editor;\n        var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);\n        if (!isScrolable) {\n            var other = editor == this.editorA ? this.editorB : this.editorA;\n            if (other.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed)) other.renderer.scrollBy(\n                ev.wheelX * ev.speed, ev.wheelY * ev.speed);\n            return ev.stop();\n        }\n    }\n\n    $attachSessionsEventHandlers() {\n        this.$attachSessionEventHandlers(this.editorA, this.markerA);\n        this.$attachSessionEventHandlers(this.editorB, this.markerB);\n    }\n\n    /**\n     * @param {import(\"../../editor\").Editor} editor\n     * @param {import(\"./base_diff_view\").DiffHighlight} marker\n     */\n    $attachSessionEventHandlers(editor, marker) {\n        editor.session.on(\"changeScrollTop\", this.onScroll);\n        editor.session.on(\"changeFold\", this.onChangeFold);\n        // @ts-expect-error\n        editor.session.addDynamicMarker(marker);\n        editor.selection.on(\"changeCursor\", this.onSelect);\n        editor.selection.on(\"changeSelection\", this.onSelect);\n\n        editor.session.on(\"changeWrapLimit\", this.onChangeWrapLimit);\n        editor.session.on(\"changeWrapMode\", this.onChangeWrapLimit);\n    }\n\n    $detachSessionsEventHandlers() {\n        this.$detachSessionHandlers(this.editorA, this.markerA);\n        this.$detachSessionHandlers(this.editorB, this.markerB);\n    }\n\n    /**\n     * @param {import(\"../../editor\").Editor} editor\n     * @param {import(\"./base_diff_view\").DiffHighlight} marker\n     */\n    $detachSessionHandlers(editor, marker) {\n        editor.session.off(\"changeScrollTop\", this.onScroll);\n        editor.session.off(\"changeFold\", this.onChangeFold);\n        editor.session.removeMarker(marker.id);\n        editor.selection.off(\"changeCursor\", this.onSelect);\n        editor.selection.off(\"changeSelection\", this.onSelect);\n\n        editor.session.off(\"changeWrapLimit\", this.onChangeWrapLimit);\n        editor.session.off(\"changeWrapMode\", this.onChangeWrapLimit);\n    }\n\n    $attachEventHandlers() {\n        this.editorA.renderer.on(\"themeChange\", this.onChangeTheme);\n        this.editorB.renderer.on(\"themeChange\", this.onChangeTheme);\n\n        this.editorA.on(\"mousewheel\", this.onMouseWheel);\n        this.editorB.on(\"mousewheel\", this.onMouseWheel);\n\n        this.editorA.on(\"input\", this.onInput);\n        this.editorB.on(\"input\", this.onInput);\n\n    }\n\n    $detachEventHandlers() {\n        this.$detachSessionsEventHandlers();\n        this.clearSelectionMarkers();\n        this.editorA.renderer.off(\"themeChange\", this.onChangeTheme);\n        this.editorB.renderer.off(\"themeChange\", this.onChangeTheme);\n        this.$detachEditorEventHandlers(this.editorA);\n        this.$detachEditorEventHandlers(this.editorB);\n    }\n\n    $detachEditorEventHandlers(editor) {\n        editor.off(\"mousewheel\", this.onMouseWheel);\n        editor.off(\"input\", this.onInput);\n    }\n}\n\n\nexports.SplitDiffView = SplitDiffView;\n"
  },
  {
    "path": "src/ext/diff/styles-css.js",
    "content": "exports.cssText = `\n/*\n * Line Markers\n */\n.ace_diff {\n    position: absolute;\n    z-index: 0;\n}\n.ace_diff.inline {\n    z-index: 20;\n}\n/*\n * Light Colors \n */\n.ace_diff.insert {\n    background-color: #EFFFF1;\n}\n.ace_diff.delete {\n    background-color: #FFF1F1;\n}\n.ace_diff.aligned_diff {\n    background: rgba(206, 194, 191, 0.26);\n    background: repeating-linear-gradient(\n                45deg,\n              rgba(122, 111, 108, 0.26),\n              rgba(122, 111, 108, 0.26) 5px,\n              rgba(0, 0, 0, 0) 5px,\n              rgba(0, 0, 0, 0) 10px \n    );\n}\n\n.ace_diff.insert.inline {\n    background-color:  rgb(74 251 74 / 18%); \n}\n.ace_diff.delete.inline {\n    background-color: rgb(251 74 74 / 15%);\n}\n\n.ace_diff.delete.inline.empty {\n    background-color: rgba(255, 128, 79, 0.7);\n    width: 2px !important;\n}\n\n.ace_diff.insert.inline.empty {\n    background-color: rgba(49, 230, 96, 0.7);\n    width: 2px !important;\n}\n\n.ace_diff-active-line {\n    border-bottom: 1px solid;\n    border-top: 1px solid;\n    background: transparent;\n    position: absolute;\n    box-sizing: border-box;\n    border-color: #9191ac;\n}\n\n.ace_dark .ace_diff-active-line {\n    background: transparent;\n    border-color: #75777a;\n}\n \n\n/* gutter changes */\n.ace_mini-diff_gutter-enabled > .ace_gutter-cell,\n.ace_mini-diff_gutter-enabled > .ace_gutter-cell_svg-icons {\n    padding-right: 13px;\n}\n\n.ace_mini-diff_gutter_other > .ace_gutter-cell,\n.ace_mini-diff_gutter_other > .ace_gutter-cell_svg-icons  {\n    display: none;\n}\n\n.ace_mini-diff_gutter_other {\n    pointer-events: none;\n}\n\n\n.ace_mini-diff_gutter-enabled > .mini-diff-added {\n    background-color: #EFFFF1;\n    border-left: 3px solid #2BB534;\n    padding-left: 16px;\n    display: block;\n}\n\n.ace_mini-diff_gutter-enabled > .mini-diff-deleted {\n    background-color: #FFF1F1;\n    border-left: 3px solid #EA7158;\n    padding-left: 16px;\n    display: block;\n}\n\n\n.ace_mini-diff_gutter-enabled > .mini-diff-added:after {\n    position: absolute;\n    right: 2px;\n    content: \"+\";\n    background-color: inherit;\n}\n\n.ace_mini-diff_gutter-enabled > .mini-diff-deleted:after {\n    position: absolute;\n    right: 2px;\n    content: \"-\";\n    background-color: inherit;\n}\n.ace_fade-fold-widgets:hover > .ace_folding-enabled > .mini-diff-added:after,\n.ace_fade-fold-widgets:hover > .ace_folding-enabled > .mini-diff-deleted:after {\n    display: none;\n}\n\n.ace_diff_other .ace_selection {\n    filter: drop-shadow(1px 2px 3px darkgray);\n}\n\n.ace_hidden_marker-layer .ace_bracket,\n.ace_hidden_marker-layer .ace_error_bracket {\n    display: none;\n}\n\n\n\n/*\n * Dark Colors \n */\n\n.ace_dark .ace_diff.insert {\n    background-color: #212E25;\n}\n.ace_dark .ace_diff.delete {\n    background-color: #3F2222;\n}\n\n.ace_dark .ace_mini-diff_gutter-enabled > .mini-diff-added {\n    background-color: #212E25;\n    border-left-color:#00802F;\n}\n\n.ace_dark .ace_mini-diff_gutter-enabled > .mini-diff-deleted {\n    background-color: #3F2222;\n    border-left-color: #9C3838;\n}\n\n`;\n"
  },
  {
    "path": "src/ext/diff.js",
    "content": "/**\n * ## Diff extension\n *\n * Provides side-by-side and inline diff view capabilities for comparing code differences between two versions.\n * Supports visual highlighting of additions, deletions, and modifications with customizable diff providers\n * and rendering options. Includes features for synchronized scrolling, line number alignment, and\n * various diff computation algorithms.\n *\n * **Components:**\n * - `InlineDiffView`: Single editor view showing changes inline with markers\n * - `SplitDiffView`: Side-by-side comparison view with two synchronized editors\n * - `DiffProvider`: Configurable algorithms for computing differences\n *\n * **Usage:**\n * ```javascript\n * const diffView = createDiffView({\n *   valueA: originalContent,\n *   valueB: modifiedContent,\n *   inline: false // or 'a'/'b' for inline view\n * });\n * ```\n *\n * @module\n */\n\nvar InlineDiffView = require(\"./diff/inline_diff_view\").InlineDiffView;\nvar SplitDiffView = require(\"./diff/split_diff_view\").SplitDiffView;\nvar DiffProvider = require(\"./diff/providers/default\").DiffProvider;\n\n/**\n * Interface representing a model for handling differences between two views or states.\n * @typedef {Object} DiffModel\n * @property {import(\"../editor\").Editor} [editorA] - The editor for the original view.\n * @property {import(\"../editor\").Editor} [editorB] - The editor for the edited view.\n * @property {import(\"../edit_session\").EditSession} [sessionA] - The edit session for the original view.\n * @property {import(\"../edit_session\").EditSession} [sessionB] - The edit session for the edited view.\n * @property {string} [valueA] - The original content.\n * @property {string} [valueB] - The modified content.\n * @property {\"a\"|\"b\"} [inline] - Whether to show the original view(\"a\") or modified view(\"b\") for inline diff view\n * @property {IDiffProvider} [diffProvider] - Provider for computing differences between original and modified content.\n */\n\n/**\n * @typedef {Object} DiffViewOptions\n * @property {boolean} [showOtherLineNumbers=true] - Whether to show line numbers in the other editor's gutter\n * @property {boolean} [folding] - Whether to enable code folding widgets\n * @property {boolean} [syncSelections] - Whether to synchronize selections between both editors\n * @property {boolean} [ignoreTrimWhitespace] - Whether to ignore trimmed whitespace when computing diffs\n * @property {boolean} [wrap] - Whether to enable word wrapping in both editors\n * @property {number} [maxDiffs=5000] - Maximum number of diffs to compute before failing silently\n * @property {string|import(\"../../ace-internal\").Ace.Theme} [theme] - Theme to apply to both editors\n */\n\n/**\n * @typedef {Object} IDiffProvider\n * @property {(originalLines: string[], modifiedLines: string[], opts?: any) => import(\"./diff/base_diff_view\").DiffChunk[]} compute - Computes differences between original and modified lines\n */\n\n\n/**\n * Creates a diff view for comparing code.\n * @param {DiffModel} [diffModel] model for the diff view\n * @param {DiffViewOptions} [options] options for the diff view\n * @returns {InlineDiffView|SplitDiffView} Configured diff view instance\n */\nfunction createDiffView(diffModel, options) {\n    diffModel = diffModel || {};\n    diffModel.diffProvider = diffModel.diffProvider || new DiffProvider(); //use default diff provider;\n    let diffView;\n    if (diffModel.inline) {\n        diffView = new InlineDiffView(diffModel);\n    }\n    else {\n        diffView = new SplitDiffView(diffModel);\n    }\n    if (options) {\n        diffView.setOptions(options);\n    }\n\n    return diffView;\n}\n\nexports.InlineDiffView = InlineDiffView;\nexports.SplitDiffView = SplitDiffView;\nexports.DiffProvider = DiffProvider;\nexports.createDiffView = createDiffView;\n"
  },
  {
    "path": "src/ext/diff_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"../test/assertions\");\nrequire(\"../test/mockdom\");\n\nvar {InlineDiffView} = require(\"./diff/inline_diff_view\");\nvar {SplitDiffView} = require(\"./diff/split_diff_view\");\nconst {createDiffView} = require(\"./diff\");\n\nvar diffView;\n\nmodule.exports = {\n    tearDown: function () {\n        if (diffView) {\n            diffView.destroy();\n            diffView = null;\n        }\n    },\n    \"test: diff wrapper test\": function () {\n        diffView = createDiffView({inline: \"a\"});\n        assert.ok(diffView instanceof InlineDiffView);\n        diffView.destroy();\n        diffView = createDiffView({});\n        assert.ok(diffView instanceof SplitDiffView);\n    },\n    \"test: diff setOptions\": function () {\n        diffView = createDiffView({}, {\n            maxDiffs: 1000,\n            ignoreTrimWhitespace: true\n        });\n        assert.ok(diffView.getOption(\"maxDiffs\"), 1000);\n        assert.ok(diffView.getOption(\"ignoreTrimWhitespace\"), true);\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/elastic_tabstops_lite.js",
    "content": "/**\n * ## Elastic Tabstops Lite extension.\n *\n * Automatically adjusts tab spacing to align content in tabular format by calculating optimal column widths\n * and maintaining consistent vertical alignment across multiple lines. Tracks content changes and dynamically\n * reprocesses affected rows to ensure proper formatting without manual intervention.\n *\n * **Enable:** `editor.setOption(\"useElasticTabstops\", true)`\n *  or configure it during editor initialization in the options object.\n * @module\n */\n\n\"use strict\";\nclass ElasticTabstopsLite {\n    /**\n     * @param {Editor} editor\n     */\n    constructor(editor) {\n        this.$editor = editor;\n        var self = this;\n        var changedRows = [];\n        var recordChanges = false;\n        this.onAfterExec = function() {\n            recordChanges = false;\n            self.processRows(changedRows);\n            changedRows = [];\n        };\n        this.onExec = function() {\n            recordChanges = true;\n        };\n        this.onChange = function(delta) {\n            if (recordChanges) {\n                if (changedRows.indexOf(delta.start.row) == -1)\n                    changedRows.push(delta.start.row);\n                if (delta.end.row != delta.start.row)\n                    changedRows.push(delta.end.row);\n            }\n        };\n    }\n\n    /**\n     * @param {number[]} rows\n     */\n    processRows(rows) {\n        this.$inChange = true;\n        var checkedRows = [];\n\n        for (var r = 0, rowCount = rows.length; r < rowCount; r++) {\n            var row = rows[r];\n\n            if (checkedRows.indexOf(row) > -1)\n                continue;\n\n            var cellWidthObj = this.$findCellWidthsForBlock(row);\n            var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths);\n            var rowIndex = cellWidthObj.firstRow;\n\n            for (var w = 0, l = cellWidths.length; w < l; w++) {\n                var widths = cellWidths[w];\n                checkedRows.push(rowIndex);\n                this.$adjustRow(rowIndex, widths);\n                rowIndex++;\n            }\n        }\n        this.$inChange = false;\n    }\n\n    /**\n     * @param {number} row\n     */\n    $findCellWidthsForBlock(row) {\n        var cellWidths = [], widths;\n\n        // starting row and backward\n        var rowIter = row;\n        while (rowIter >= 0) {\n            widths = this.$cellWidthsForRow(rowIter);\n            if (widths.length == 0)\n                break;\n\n            cellWidths.unshift(widths);\n            rowIter--;\n        }\n        var firstRow = rowIter + 1;\n\n        // forward (not including starting row)\n        rowIter = row;\n        var numRows = this.$editor.session.getLength();\n\n        while (rowIter < numRows - 1) {\n            rowIter++;\n\n            widths = this.$cellWidthsForRow(rowIter);\n            if (widths.length == 0)\n                break;\n\n            cellWidths.push(widths);\n        }\n\n        return { cellWidths: cellWidths, firstRow: firstRow };\n    }\n\n    /**\n     * @param {number} row\n     * @returns {number[]}\n     */\n    $cellWidthsForRow(row) {\n        var selectionColumns = this.$selectionColumnsForRow(row);\n        // todo: support multicursor\n\n        var tabs = [-1].concat(this.$tabsForRow(row));\n        var widths = tabs.map(function(el) { return 0; } ).slice(1);\n        var line = this.$editor.session.getLine(row);\n\n        for (var i = 0, len = tabs.length - 1; i < len; i++) {\n            var leftEdge = tabs[i]+1;\n            var rightEdge = tabs[i+1];\n\n            var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge);\n            var cell = line.substring(leftEdge, rightEdge);\n            widths[i] = Math.max(cell.replace(/\\s+$/g,'').length, rightmostSelection - leftEdge);\n        }\n\n        return widths;\n    }\n\n    /**\n     * @param {number} row\n     * @returns {number[]}\n     */\n    $selectionColumnsForRow(row) {\n        var selections = [], cursor = this.$editor.getCursorPosition();\n        if (this.$editor.session.getSelection().isEmpty()) {\n            // todo: support multicursor\n            if (row == cursor.row)\n                selections.push(cursor.column);\n        }\n\n        return selections;\n    }\n\n    /**\n     * @param {number[][]} cellWidths\n     */\n    $setBlockCellWidthsToMax(cellWidths) {\n        var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth;\n        var columnInfo = this.$izip_longest(cellWidths);\n\n        for (var c = 0, l = columnInfo.length; c < l; c++) {\n            var column = columnInfo[c];\n            if (!column.push) {\n                console.error(column);\n                continue;\n            }\n            // add an extra None to the end so that the end of the column automatically\n            // finishes a block\n            column.push(NaN);\n\n            for (var r = 0, s = column.length; r < s; r++) {\n                var width = column[r];\n                if (startingNewBlock) {\n                    blockStartRow = r;\n                    maxWidth = 0;\n                    startingNewBlock = false;\n                }\n                if (isNaN(width)) {\n                    // block ended\n                    blockEndRow = r;\n\n                    for (var j = blockStartRow; j < blockEndRow; j++) {\n                        cellWidths[j][c] = maxWidth;\n                    }\n                    startingNewBlock = true;\n                }\n\n                maxWidth = Math.max(maxWidth, width);\n            }\n        }\n\n        return cellWidths;\n    }\n\n    /**\n     * @param {number[]} selectionColumns\n     * @param {number} cellRightEdge\n     * @returns {number}\n     */\n    $rightmostSelectionInCell(selectionColumns, cellRightEdge) {\n        var rightmost = 0;\n\n        if (selectionColumns.length) {\n            var lengths = [];\n            for (var s = 0, length = selectionColumns.length; s < length; s++) {\n                if (selectionColumns[s] <= cellRightEdge)\n                    lengths.push(s);\n                else\n                    lengths.push(0);\n            }\n            rightmost = Math.max.apply(Math, lengths);\n        }\n\n        return rightmost;\n    }\n\n    /**\n     * @param {number} row\n     * @returns {number[]}\n     */\n    $tabsForRow(row) {\n        var rowTabs = [], line = this.$editor.session.getLine(row),\n            re = /\\t/g, match;\n\n        while ((match = re.exec(line)) != null) {\n            rowTabs.push(match.index);\n        }\n\n        return rowTabs;\n    }\n\n    /**\n     * @param {number} row\n     * @param {number[]} widths\n     */\n    $adjustRow(row, widths) {\n        var rowTabs = this.$tabsForRow(row);\n\n        if (rowTabs.length == 0)\n            return;\n\n        var bias = 0, location = -1;\n\n        // this always only contains two elements, so we're safe in the loop below\n        var expandedSet = this.$izip(widths, rowTabs);\n\n        for (var i = 0, l = expandedSet.length; i < l; i++) {\n            var w = expandedSet[i][0], it = expandedSet[i][1];\n            location += 1 + w;\n            it += bias;\n            var difference = location - it;\n\n            if (difference == 0)\n                continue;\n\n            var partialLine = this.$editor.session.getLine(row).substr(0, it );\n            var strippedPartialLine = partialLine.replace(/\\s*$/g, \"\");\n            var ispaces = partialLine.length - strippedPartialLine.length;\n\n            if (difference > 0) {\n                // put the spaces after the tab and then delete the tab, so any insertion\n                // points behave as expected\n                this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(\" \") + \"\\t\");\n                this.$editor.session.getDocument().removeInLine(row, it, it + 1);\n\n                bias += difference;\n            }\n\n            if (difference < 0 && ispaces >= -difference) {\n                this.$editor.session.getDocument().removeInLine(row, it + difference, it);\n                bias += difference;\n            }\n        }\n    }\n\n    /**\n     * The is a (naive) Python port--but works for these purposes\n     * @param {any[][]} iterables\n     */\n    $izip_longest(iterables) {\n        if (!iterables[0])\n            return [];\n        var longest = iterables[0].length;\n        var iterablesLength = iterables.length;\n\n        for (var i = 1; i < iterablesLength; i++) {\n            var iLength = iterables[i].length;\n            if (iLength > longest)\n                longest = iLength;\n        }\n\n        var expandedSet = [];\n\n        for (var l = 0; l < longest; l++) {\n            var set = [];\n            for (var i = 0; i < iterablesLength; i++) {\n                if (iterables[i][l] === \"\")\n                    set.push(NaN);\n                else\n                    set.push(iterables[i][l]);\n            }\n\n            expandedSet.push(set);\n        }\n\n\n        return expandedSet;\n    }\n\n    /**\n     * an even more (naive) Python port\n     * @param {string | any[]} widths\n     * @param {string | any[]} tabs\n     */\n    $izip(widths, tabs) {\n        // grab the shorter size\n        var size = widths.length >= tabs.length ? tabs.length : widths.length;\n\n        var expandedSet = [];\n        for (var i = 0; i < size; i++) {\n            var set = [ widths[i], tabs[i] ];\n            expandedSet.push(set);\n        }\n        return expandedSet;\n    }\n\n}\n\nexports.ElasticTabstopsLite = ElasticTabstopsLite;\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    useElasticTabstops: {\n        /**\n         * @param {boolean} val\n         * @this {Editor}\n         */\n        set: function(val) {\n            if (val) {\n                if (!this.elasticTabstops)\n                    this.elasticTabstops = new ElasticTabstopsLite(this);\n                this.commands.on(\"afterExec\", this.elasticTabstops.onAfterExec);\n                this.commands.on(\"exec\", this.elasticTabstops.onExec);\n                this.on(\"change\", this.elasticTabstops.onChange);\n            } else if (this.elasticTabstops) {\n                this.commands.removeListener(\"afterExec\", this.elasticTabstops.onAfterExec);\n                this.commands.removeListener(\"exec\", this.elasticTabstops.onExec);\n                this.removeListener(\"change\", this.elasticTabstops.onChange);\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "src/ext/emmet.js",
    "content": "/**\n * ## Emmet extension\n *\n * Providing HTML/CSS abbreviation expansion, code navigation, and text editing utilities with configurable options and\n * keyboard shortcuts for rapid web development workflow.\n *\n * **Enable:** `editor.setOption(\"enableEmmet\", true)`\n * or configure it during editor initialization in the options object.\n * @module\n */\n\"use strict\";\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar Editor = require(\"../editor\").Editor;\nvar snippetManager = require(\"../snippets\").snippetManager;\nvar Range = require(\"../range\").Range;\nvar config = require(\"../config\");\nvar emmet, emmetPath;\n\n/**\n * Implementation of {@link IEmmetEditor} interface for Ace\n */\n\nclass AceEmmetEditor {\n    /**\n     * @param {Editor} editor\n     */\n    setupContext(editor) {\n        this.ace = editor;\n        this.indentation = editor.session.getTabString();\n        if (!emmet)\n            emmet = window[\"emmet\"];\n        var resources = emmet.resources || emmet.require(\"resources\");\n        resources.setVariable(\"indentation\", this.indentation);\n        this.$syntax = null;\n        this.$syntax = this.getSyntax();\n    }\n    /**\n     * Returns character indexes of selected text: object with <code>start</code>\n     * and <code>end</code> properties. If there's no selection, should return\n     * object with <code>start</code> and <code>end</code> properties referring\n     * to current caret position\n     * @return {Object}\n     * @example\n     * var selection = editor.getSelectionRange();\n     * alert(selection.start + ', ' + selection.end);\n     */\n    getSelectionRange() {\n        // TODO should start be caret position instead?\n        var range = this.ace.getSelectionRange();\n        var doc = this.ace.session.doc;\n        return {\n            start: doc.positionToIndex(range.start),\n            end: doc.positionToIndex(range.end)\n        };\n    }\n\n    /**\n     * Creates selection from <code>start</code> to <code>end</code> character\n     * indexes. If <code>end</code> is ommited, this method should place caret\n     * and <code>start</code> index\n     * @param {Number} start\n     * @param {Number} [end]\n     * @example\n     * editor.createSelection(10, 40);\n     *\n     * //move caret to 15th character\n     * editor.createSelection(15);\n     */\n    createSelection(start, end) {\n        var doc = this.ace.session.doc;\n        this.ace.selection.setRange({\n            start: doc.indexToPosition(start),\n            end: doc.indexToPosition(end)\n        });\n    }\n\n    /**\n     * Returns current line's start and end indexes as object with <code>start</code>\n     * and <code>end</code> properties\n     * @return {Object}\n     * @example\n     * var range = editor.getCurrentLineRange();\n     * alert(range.start + ', ' + range.end);\n     */\n    getCurrentLineRange() {\n        var ace = this.ace;\n        var row = ace.getCursorPosition().row;\n        var lineLength = ace.session.getLine(row).length;\n        var index = ace.session.doc.positionToIndex({row: row, column: 0});\n        return {\n            start: index,\n            end: index + lineLength\n        };\n    }\n\n    /**\n     * Returns current caret position\n     * @return {Number|null}\n     */\n    getCaretPos(){\n        var pos = this.ace.getCursorPosition();\n        return this.ace.session.doc.positionToIndex(pos);\n    }\n\n    /**\n     * Set new caret position\n     * @param {Number} index Caret position\n     */\n    setCaretPos(index){\n        var pos = this.ace.session.doc.indexToPosition(index);\n        this.ace.selection.moveToPosition(pos);\n    }\n\n    /**\n     * Returns content of current line\n     * @return {String}\n     */\n    getCurrentLine() {\n        var row = this.ace.getCursorPosition().row;\n        return this.ace.session.getLine(row);\n    }\n\n    /**\n     * Replace editor's content or it's part (from <code>start</code> to\n     * <code>end</code> index). If <code>value</code> contains\n     * <code>caret_placeholder</code>, the editor will put caret into\n     * this position. If you skip <code>start</code> and <code>end</code>\n     * arguments, the whole target's content will be replaced with\n     * <code>value</code>.\n     *\n     * If you pass <code>start</code> argument only,\n     * the <code>value</code> will be placed at <code>start</code> string\n     * index of current content.\n     *\n     * If you pass <code>start</code> and <code>end</code> arguments,\n     * the corresponding substring of current target's content will be\n     * replaced with <code>value</code>.\n     * @param {String} value Content you want to paste\n     * @param {Number} [start] Start index of editor's content\n     * @param {Number} [end] End index of editor's content\n     * @param {Boolean} [noIndent] Do not auto indent <code>value</code>\n     */\n    replaceContent(value, start, end, noIndent) {\n        if (end == null)\n            end = start == null ? this.getContent().length : start;\n        if (start == null)\n            start = 0;        \n        \n        var editor = this.ace;\n        var doc = editor.session.doc;\n        var range = Range.fromPoints(doc.indexToPosition(start), doc.indexToPosition(end));\n        editor.session.remove(range);\n        \n        range.end = range.start;\n        //editor.selection.setRange(range);\n        \n        value = this.$updateTabstops(value);\n        snippetManager.insertSnippet(editor, value);\n    }\n\n    /**\n     * Returns editor's content\n     * @return {String}\n     */\n    getContent(){\n        return this.ace.getValue();\n    }\n\n    /**\n     * Returns current editor's syntax mode\n     * @return {String}\n     */\n    getSyntax() {\n        if (this.$syntax)\n            return this.$syntax;\n        var syntax = this.ace.session.$modeId.split(\"/\").pop();\n        if (syntax == \"html\" || syntax == \"php\") {\n            var cursor = this.ace.getCursorPosition();\n            /**@type {string | string[]} */\n            var state = this.ace.session.getState(cursor.row);\n            if (typeof state != \"string\")\n                state = state[0];\n            if (state) {\n                state = state.split(\"-\");\n                if (state.length > 1)\n                    syntax = state[0];\n                else if (syntax == \"php\")\n                    syntax = \"html\";\n            }\n        }\n        return syntax;\n    }\n\n    /**\n     * Returns current output profile name (@see emmet#setupProfile)\n     * @return {String}\n     */\n    getProfileName() {\n        var resources = emmet.resources || emmet.require(\"resources\");\n        switch (this.getSyntax()) {\n          case \"css\": return \"css\";\n          case \"xml\":\n          case \"xsl\":\n            return \"xml\";\n          case \"html\":\n            var profile = resources.getVariable(\"profile\");\n            // no forced profile, guess from content html or xhtml?\n            if (!profile)\n                profile = this.ace.session.getLines(0,2).join(\"\").search(/<!DOCTYPE[^>]+XHTML/i) != -1 ? \"xhtml\": \"html\";\n            return profile;\n          default:\n            var mode = this.ace.session.$mode;\n            return mode.emmetConfig && mode.emmetConfig.profile || \"xhtml\";\n        }\n    }\n\n    /**\n     * Ask user to enter something\n     * @param {String} title Dialog title\n     * @return {String} Entered data\n     * @since 0.65\n     */\n    prompt(title) {\n        return prompt(title); // eslint-disable-line no-alert\n    }\n\n    /**\n     * Returns current selection\n     * @return {String}\n     * @since 0.65\n     */\n    getSelection() {\n        return this.ace.session.getTextRange();\n    }\n\n    /**\n     * Returns current editor's file path\n     * @return {String}\n     * @since 0.65\n     */\n    getFilePath() {\n        return \"\";\n    }\n    \n    // update tabstops: make sure all caret placeholders are unique\n    // by default, abbreviation parser generates all unlinked (un-mirrored)\n    // tabstops as ${0}, so we have upgrade all caret tabstops with unique\n    // positions but make sure that all other tabstops are not linked accidentally\n    // based on https://github.com/sergeche/emmet-sublime/blob/master/editor.js#L119-L171\n    /**\n     * @param {string} value\n     */\n    $updateTabstops(value) {\n        var base = 1000;\n        var zeroBase = 0;\n        var lastZero = null;\n        var ts = emmet.tabStops || emmet.require('tabStops');\n        var resources = emmet.resources || emmet.require(\"resources\");\n        var settings = resources.getVocabulary(\"user\");\n        var tabstopOptions = {\n            tabstop: function(data) {\n                var group = parseInt(data.group, 10);\n                var isZero = group === 0;\n                if (isZero)\n                    group = ++zeroBase;\n                else\n                    group += base;\n\n                var placeholder = data.placeholder;\n                if (placeholder) {\n                    // recursively update nested tabstops\n                    placeholder = ts.processText(placeholder, tabstopOptions);\n                }\n\n                var result = '${' + group + (placeholder ? ':' + placeholder : '') + '}';\n\n                if (isZero) {\n                    lastZero = [data.start, result];\n                }\n\n                return result;\n            },\n            escape: function(ch) {\n                if (ch == '$') return '\\\\$';\n                if (ch == '\\\\') return '\\\\\\\\';\n                return ch;\n            }\n        };\n\n        value = ts.processText(value, tabstopOptions);\n\n        if (settings.variables['insert_final_tabstop'] && !/\\$\\{0\\}$/.test(value)) {\n            value += '${0}';\n        } else if (lastZero) {\n            var common = emmet.utils ? emmet.utils.common : emmet.require('utils');\n            value = common.replaceSubstring(value, '${0}', lastZero[0], lastZero[1]);\n        }\n        \n        return value;\n    }\n}\n\n\nvar keymap = {\n    expand_abbreviation: {\"mac\": \"ctrl+alt+e\", \"win\": \"alt+e\"},\n    match_pair_outward: {\"mac\": \"ctrl+d\", \"win\": \"ctrl+,\"},\n    match_pair_inward: {\"mac\": \"ctrl+j\", \"win\": \"ctrl+shift+0\"},\n    matching_pair: {\"mac\": \"ctrl+alt+j\", \"win\": \"alt+j\"},\n    next_edit_point: \"alt+right\",\n    prev_edit_point: \"alt+left\",\n    toggle_comment: {\"mac\": \"command+/\", \"win\": \"ctrl+/\"},\n    split_join_tag: {\"mac\": \"shift+command+'\", \"win\": \"shift+ctrl+`\"},\n    remove_tag: {\"mac\": \"command+'\", \"win\": \"shift+ctrl+;\"},\n    evaluate_math_expression: {\"mac\": \"shift+command+y\", \"win\": \"shift+ctrl+y\"},\n    increment_number_by_1: \"ctrl+up\",\n    decrement_number_by_1: \"ctrl+down\",\n    increment_number_by_01: \"alt+up\",\n    decrement_number_by_01: \"alt+down\",\n    increment_number_by_10: {\"mac\": \"alt+command+up\", \"win\": \"shift+alt+up\"},\n    decrement_number_by_10: {\"mac\": \"alt+command+down\", \"win\": \"shift+alt+down\"},\n    select_next_item: {\"mac\": \"shift+command+.\", \"win\": \"shift+ctrl+.\"},\n    select_previous_item: {\"mac\": \"shift+command+,\", \"win\": \"shift+ctrl+,\"},\n    reflect_css_value: {\"mac\": \"shift+command+r\", \"win\": \"shift+ctrl+r\"},\n\n    encode_decode_data_url: {\"mac\": \"shift+ctrl+d\", \"win\": \"ctrl+'\"},\n    // update_image_size: {\"mac\": \"shift+ctrl+i\", \"win\": \"ctrl+u\"},\n    // expand_as_you_type: \"ctrl+alt+enter\",\n    // wrap_as_you_type: {\"mac\": \"shift+ctrl+g\", \"win\": \"shift+ctrl+g\"},\n    expand_abbreviation_with_tab: \"Tab\",\n    wrap_with_abbreviation: {\"mac\": \"shift+ctrl+a\", \"win\": \"shift+ctrl+a\"}\n};\n\nvar editorProxy = new AceEmmetEditor();\nexports.commands = new HashHandler();\n\n/**\n * Runs an Emmet command on the given editor.\n *\n * @param {Editor} editor - The Ace editor instance to run the Emmet command on\n * @return {ReturnType<typeof setTimeout> | boolean} The result of the Emmet command execution\n */\nexports.runEmmetCommand = function runEmmetCommand(editor) {\n    if (this.action == \"expand_abbreviation_with_tab\") {\n        if (!editor.selection.isEmpty())\n            return false;\n        var pos = editor.selection.lead;\n        var token = editor.session.getTokenAt(pos.row, pos.column);\n        if (token && /\\btag\\b/.test(token.type))\n            return false;\n    }\n    try {\n        editorProxy.setupContext(editor);\n        var actions = emmet.actions || emmet.require(\"actions\");\n        \n        if (this.action == \"wrap_with_abbreviation\") {\n            // without setTimeout prompt doesn't work on firefox\n            return setTimeout(function() {\n                actions.run(\"wrap_with_abbreviation\", editorProxy);\n            }, 0);\n        }\n        \n        var result = actions.run(this.action, editorProxy);\n    } catch(e) {\n        if (!emmet) {\n            var loading = exports.load(runEmmetCommand.bind(this, editor));\n            if (this.action == \"expand_abbreviation_with_tab\")\n                return false;\n            return loading;\n        }\n        editor._signal(\"changeStatus\", typeof e == \"string\" ? e : e.message);\n        config.warn(e);\n        result = false;\n    }\n    return result;\n};\n\nfor (var command in keymap) {\n    exports.commands.addCommand({\n        name: \"emmet:\" + command,\n        action: command,\n        bindKey: keymap[command],\n        exec: exports.runEmmetCommand,\n        multiSelectAction: \"forEach\"\n    });\n}\n\n/**\n * Updates the keyboard handler for Emmet commands in the editor.\n *\n * @param {Editor} editor - The Ace editor instance\n * @param {boolean} [enabled] - Whether Emmet commands should be enabled\n */\nexports.updateCommands = function(editor, enabled) {\n    if (enabled) {\n        editor.keyBinding.addKeyboardHandler(exports.commands);\n    } else {\n        editor.keyBinding.removeKeyboardHandler(exports.commands);\n    }\n};\n\n/**\n * Determines if a given editor mode is supported by Emmet.\n *\n * @param {Object|string} mode - The editor mode to check for Emmet support\n * @returns {boolean} Whether the mode is supported by Emmet\n */\nexports.isSupportedMode = function(mode) {\n    if (!mode) return false;\n    if (mode.emmetConfig) return true;\n    var id = mode.$id || mode;\n    return /css|less|scss|sass|stylus|html|php|twig|ejs|handlebars/.test(id);\n};\n\n/**\n * Checks if an Emmet command is available for the current editor context.\n *\n * @param {Editor} editor - The current Ace editor instance\n * @param {string} command - The Emmet command to check availability for\n * @return {boolean} Whether the command is available in the current editor mode\n */\nexports.isAvailable = function(editor, command) {\n    if (/(evaluate_math_expression|expand_abbreviation)$/.test(command))\n        return true;\n    var mode = editor.session.$mode;\n    var isSupported = exports.isSupportedMode(mode);\n    if (isSupported && mode.$modes) {\n        // TODO refactor mode delegates to make this simpler\n        try {\n            editorProxy.setupContext(editor);\n            if (/js|php/.test(editorProxy.getSyntax()))\n                isSupported = false;\n        } catch(e) {}\n    }\n    return isSupported;\n};\n\nvar onChangeMode = function(e, target) {\n    var editor = target;\n    if (!editor)\n        return;\n    var enabled = exports.isSupportedMode(editor.session.$mode);\n    if (e.enableEmmet === false)\n        enabled = false;\n    if (enabled)\n        exports.load();\n    exports.updateCommands(editor, enabled);\n};\n\n/**\n * Loads the Emmet core module dynamically.\n *\n * @param {Function} [cb] - Optional callback function to be executed after module loading\n * @return {boolean} Whether the Emmet core module loading was initiated successfully\n */\nexports.load = function(cb) {\n    if (typeof emmetPath !== \"string\") {\n        config.warn(\"script for emmet-core is not loaded\");\n        return false;\n    }\n    config.loadModule(emmetPath, function() {\n        emmetPath = null;\n        cb && cb();\n    });\n    return true;\n};\n\nexports.AceEmmetEditor = AceEmmetEditor;\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    enableEmmet: {\n        set: function(val) {\n            this[val ? \"on\" : \"removeListener\"](\"changeMode\", onChangeMode);\n            onChangeMode({enableEmmet: !!val}, this);\n        },\n        value: true\n    }\n});\n\n/**\n * Sets the Emmet core module or path.\n *\n * @param {string|Object} e - Either the path to the Emmet core script or the Emmet core module itself\n * If a string is provided, it sets the path to load the Emmet core script.\n * If an object is provided, it directly sets the Emmet core module.\n */\nexports.setCore = function(e) {\n    if (typeof e == \"string\")\n       emmetPath = e;\n    else\n       emmet = e;\n};\n"
  },
  {
    "path": "src/ext/emmet_test.js",
    "content": "\"use strict\";\n\nrequire(\"../test/mockdom\");\nvar Mode = require(\"../mode/html\").Mode;\nvar ace = require(\"../ace\");\nvar assert = require(\"assert\");\nrequire(\"./emmet\");\n\nmodule.exports = {\n    \"test doesn't break tab when emmet is not loaded\": function() {\n        var editor = ace.edit(null, {\n            mode: new Mode(),\n            enableEmmet: true,\n            useSoftTabs: false\n        });\n        \n        window.emmet = null;\n        editor.onCommandKey({}, 0, 9);\n        assert.equal(editor.getValue(), \"\\t\");\n        \n        try {\n            var called = 0;\n            window.emmet = {\n                actions: {\n                    run: function() {\n                        called++;\n                    }\n                },\n                resources: {\n                    setVariable: function() {\n                        called++;\n                    }\n                }\n            };\n            editor.onCommandKey({}, 0, 9);\n            assert.equal(called, 2);\n        } finally {\n            window.emmet = null;\n        }\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/error_marker.js",
    "content": "/**\n * ## Error Marker extension\n *\n * Provides inline error display functionality for Ace editor. Creates visual error markers that appear as tooltips\n * below editor lines containing annotations (errors, warnings, info). Enables navigation between error locations with\n * keyboard shortcuts and displays context-sensitive messages with proper styling based on annotation severity.\n *\n * @module\n */\n\n\"use strict\";\nvar dom = require(\"../lib/dom\");\nvar Range = require(\"../range\").Range;\nvar nls = require(\"../config\").nls;\n\nfunction binarySearch(array, needle, comparator) {\n    var first = 0;\n    var last = array.length - 1;\n\n    while (first <= last) {\n        var mid = (first + last) >> 1;\n        var c = comparator(needle, array[mid]);\n        if (c > 0)\n            first = mid + 1;\n        else if (c < 0)\n            last = mid - 1;\n        else\n            return mid;\n    }\n\n    // Return the nearest lesser index, \"-1\" means \"0, \"-2\" means \"1\", etc.\n    return -(first + 1);\n}\n\n/**\n * @param {import(\"../edit_session\").EditSession} session\n * @param {number} row\n * @param {number} dir\n */\nfunction findAnnotations(session, row, dir) {\n    var annotations = session.getAnnotations().sort(Range.comparePoints);\n    if (!annotations.length)\n        return;\n    \n    var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);\n    if (i < 0)\n        i = -i - 1;\n    \n    if (i >= annotations.length)\n        i = dir > 0 ? 0 : annotations.length - 1;\n    else if (i === 0 && dir < 0)\n        i = annotations.length - 1;\n    \n    var annotation = annotations[i];\n    if (!annotation || !dir)\n        return;\n\n        if (annotation.row === row) {\n        do {\n            annotation = annotations[i += dir];\n        } while (annotation && annotation.row === row);\n        if (!annotation)\n            return annotations.slice();\n    }\n    \n    \n    var matched = [];\n    row = annotation.row;\n    do {\n        matched[dir < 0 ? \"unshift\" : \"push\"](annotation);\n        annotation = annotations[i += dir];\n    } while (annotation && annotation.row == row);\n    return matched.length && matched;\n}\n\n/**\n * Displays an error marker widget in the editor for annotations at the current cursor position.\n *\n * @param {import(\"../editor\").Editor} editor - The Ace editor instance\n * @param {number} dir - The direction of navigation through annotations (-1 or 1)\n */\nexports.showErrorMarker = function(editor, dir) {\n    var session = editor.session;\n    var pos = editor.getCursorPosition();\n    var row = pos.row;\n    var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) {\n        return w.type == \"errorMarker\";\n    })[0];\n    if (oldWidget) {\n        oldWidget.destroy();\n    } else {\n        row -= dir;\n    }\n    var annotations = findAnnotations(session, row, dir);\n    var gutterAnno;\n    if (annotations) {\n        var annotation = annotations[0];\n        pos.column = (annotation.pos && typeof annotation.column != \"number\"\n            ? annotation.pos.sc\n            : annotation.column) || 0;\n        pos.row = annotation.row;\n        gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];\n    } else if (oldWidget) {\n        return;\n    } else {\n        gutterAnno = {\n            displayText: [nls(\"error-marker.good-state\", \"Looks good!\")],\n            className: \"ace_ok\"\n        };\n    }\n    editor.session.unfold(pos.row);\n    editor.selection.moveToPosition(pos);\n    \n    var w = {\n        row: pos.row, \n        fixedWidth: true,\n        coverGutter: true,\n        el: dom.createElement(\"div\"),\n        type: \"errorMarker\"\n    };\n    var el = w.el.appendChild(dom.createElement(\"div\"));\n    var arrow = w.el.appendChild(dom.createElement(\"div\"));\n    arrow.className = \"error_widget_arrow \" + gutterAnno.className;\n    \n    var left = editor.renderer.$cursorLayer\n        .getPixelPosition(pos).left;\n    arrow.style.left = left + editor.renderer.gutterWidth - 5 + \"px\";\n    \n    w.el.className = \"error_widget_wrapper\";\n    el.className = \"error_widget \" + gutterAnno.className;\n    gutterAnno.displayText.forEach(function (annoTextLine, i) {\n        el.appendChild(dom.createTextNode(annoTextLine));\n        if (i < gutterAnno.displayText.length - 1) {\n            el.appendChild(dom.createElement(\"br\"));\n        }\n    });\n    \n    el.appendChild(dom.createElement(\"div\"));\n    \n    var kb = function(_, hashId, keyString) {\n        if (hashId === 0 && (keyString === \"esc\" || keyString === \"return\")) {\n            w.destroy();\n            return {command: \"null\"};\n        }\n    };\n    \n    w.destroy = function() {\n        if (editor.$mouseHandler.isMousePressed)\n            return;\n        // @ts-ignore\n        editor.keyBinding.removeKeyboardHandler(kb);\n        session.widgetManager.removeLineWidget(w);\n        editor.off(\"changeSelection\", w.destroy);\n        editor.off(\"changeSession\", w.destroy);\n        editor.off(\"mouseup\", w.destroy);\n        editor.off(\"change\", w.destroy);\n    };\n\n    // @ts-ignore\n    editor.keyBinding.addKeyboardHandler(kb);\n    editor.on(\"changeSelection\", w.destroy);\n    editor.on(\"changeSession\", w.destroy);\n    editor.on(\"mouseup\", w.destroy);\n    editor.on(\"change\", w.destroy);\n    \n    editor.session.widgetManager.addLineWidget(w);\n    \n    w.el.onmousedown = editor.focus.bind(editor);\n    \n    editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});\n};\n\n\ndom.importCssString(`\n    .error_widget_wrapper {\n        background: inherit;\n        color: inherit;\n        border:none\n    }\n    .error_widget {\n        border-top: solid 2px;\n        border-bottom: solid 2px;\n        margin: 5px 0;\n        padding: 10px 40px;\n        white-space: pre-wrap;\n    }\n    .error_widget.ace_error, .error_widget_arrow.ace_error{\n        border-color: #ff5a5a\n    }\n    .error_widget.ace_warning, .error_widget_arrow.ace_warning{\n        border-color: #F1D817\n    }\n    .error_widget.ace_info, .error_widget_arrow.ace_info{\n        border-color: #5a5a5a\n    }\n    .error_widget.ace_ok, .error_widget_arrow.ace_ok{\n        border-color: #5aaa5a\n    }\n    .error_widget_arrow {\n        position: absolute;\n        border: solid 5px;\n        border-top-color: transparent!important;\n        border-right-color: transparent!important;\n        border-left-color: transparent!important;\n        top: -5px;\n    }\n`, \"error_marker.css\", false);\n"
  },
  {
    "path": "src/ext/error_marker_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"./../test/assertions\");\nrequire(\"./../test/mockdom\");\nvar ace = require(\"../ace\");\nvar editor, changes;\n\nmodule.exports = {\n    setUp: function() {\n        ace.config.setLoader(function(moduleName, cb) {\n            if (moduleName == \"ace/ext/error_marker\")\n                return cb(null, require(\"../ext/error_marker\"));\n        });\n        if (!editor) {\n            editor = ace.edit(null);\n            document.body.appendChild(editor.container);\n            editor.container.style.height = \"200px\";\n            editor.container.style.width = \"300px\";\n            editor.container.style.position = \"absolute\";\n            editor.container.style.outline = \"solid\";\n            editor.on(\"change\", function(e) {\n                changes.push(e);\n            });\n        }\n        changes = [];\n        editor.focus();\n    },\n    tearDown: function() {\n        if (editor) {\n            editor.destroy();\n            editor.container.remove();\n            editor = null;\n        }\n    },\n    \"test: go to next error\": function() {\n        editor.session.setValue(\"1\\nerror 2 warning\\n3\\n4 info\\n5\\n6\\n\");\n        editor.execCommand(\"goToNextError\");\n        editor.resize(true);\n        assert.ok(/Looks good/.test(editor.container.innerHTML));\n        \n        editor.$search.$options.needle = /[a-z]+/gim;\n        var ranges = editor.$search.findAll(editor.session);\n        \n        editor.session.setAnnotations(ranges.map(function(r) {\n            var type = editor.session.getTextRange(r);\n            return {\n                row: r.start.row,\n                column: r.start.column,\n                text: type + \" \" + r,\n                type: type\n            };\n        }));\n        \n        editor.execCommand(\"goToNextError\");\n        editor.renderer.$loop._flush();\n        assert.ok(/error_widget\\s+ace_error/.test(editor.container.innerHTML));\n                \n        editor.execCommand(\"goToNextError\");\n        editor.renderer.$loop._flush();\n        assert.ok(/error_widget\\s+ace_info/.test(editor.container.innerHTML));\n        \n        editor.execCommand(\"goToPreviousError\");\n        editor.renderer.$loop._flush();\n        assert.ok(/error_widget\\s+ace_error/.test(editor.container.innerHTML));\n        \n        editor.execCommand(\"insertstring\", \"\\n\");\n        editor.renderer.$loop._flush();\n        assert.notOk(/error_widget/.test(editor.container.innerHTML));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/hardwrap.js",
    "content": "/**\n * ## Text hard wrapping extension for automatic line breaking and text formatting.\n *\n * Provides intelligent line wrapping functionality that breaks long lines at configurable column limits while\n * preserving indentation and optionally merging short adjacent lines. Supports both automatic wrapping during text\n * input and manual formatting of selected text ranges.\n *\n * **Enable:** `editor.setOption(\"hardWrap\", true)`\n * or configure it during editor initialization in the options object.\n * @module\n */\n\n\"use strict\";\n\nvar Range = require(\"../range\").Range;\n\n/**\n * Wraps lines at specified column limits and optionally merges short adjacent lines.\n *\n * Processes text within the specified row range, breaking lines that exceed the maximum column\n * width at appropriate word boundaries while preserving indentation. When merge is enabled,\n * combines short consecutive lines that can fit within the column limit. Automatically adjusts\n * the end row when new line breaks are inserted to ensure all affected content is processed.\n *\n * @param {import(\"../editor\").Editor} editor - The editor instance containing the text to wrap\n * @param {import(\"../../ace-internal\").Ace.HardWrapOptions} options - Configuration options for wrapping behavior\n */\n\nfunction hardWrap(editor, options) {\n    var max = options.column || editor.getOption(\"printMarginColumn\");\n    var allowMerge = options.allowMerge != false;\n       \n    var row = Math.min(options.startRow, options.endRow);\n    var endRow = Math.max(options.startRow, options.endRow);\n    \n    var session = editor.session;\n    \n    while (row <= endRow) {\n        var line = session.getLine(row);\n        if (line.length > max) {\n            var space = findSpace(line, max, 5);\n            if (space) {\n                var indentation = /^\\s*/.exec(line)[0];\n                session.replace(new Range(row,space.start,row,space.end), \"\\n\" + indentation);\n            }\n            endRow++;\n        } else if (allowMerge && /\\S/.test(line) && row != endRow) {\n            var nextLine = session.getLine(row + 1);\n            if (nextLine && /\\S/.test(nextLine)) {\n                var trimmedLine = line.replace(/\\s+$/, \"\");\n                var trimmedNextLine = nextLine.replace(/^\\s+/, \"\");\n                var mergedLine = trimmedLine + \" \" + trimmedNextLine;\n\n                var space = findSpace(mergedLine, max, 5);\n                if (space && space.start > trimmedLine.length || mergedLine.length < max) {\n                    var replaceRange = new Range(row,trimmedLine.length,row + 1,nextLine.length - trimmedNextLine.length);\n                    session.replace(replaceRange, \" \");\n                    row--;\n                    endRow--;\n                } else if (trimmedLine.length < line.length) {\n                    session.remove(new Range(row, trimmedLine.length, row, line.length));\n                }\n            }\n        }\n        row++;\n    }\n\n    /**\n     * @param {string} line\n     * @param {number} max\n     * @param {number} min\n     */\n    function findSpace(line, max, min) {\n        if (line.length < max)\n            return;\n        var before = line.slice(0, max);\n        var after = line.slice(max);\n        var spaceAfter = /^(?:(\\s+)|(\\S+)(\\s+))/.exec(after);\n        var spaceBefore = /(?:(\\s+)|(\\s+)(\\S+))$/.exec(before);\n        var start = 0;\n        var end = 0;\n        if (spaceBefore && !spaceBefore[2]) {\n            start = max - spaceBefore[1].length;\n            end = max;\n        }\n        if (spaceAfter && !spaceAfter[2]) {\n            if (!start)\n                start = max;\n            end = max + spaceAfter[1].length;\n        }\n        if (start) {\n            return {\n                start: start,\n                end: end\n            };\n        }\n        if (spaceBefore && spaceBefore[2] && spaceBefore.index > min) {\n            return {\n                start: spaceBefore.index,\n                end: spaceBefore.index + spaceBefore[2].length\n            };\n        }\n        if (spaceAfter && spaceAfter[2]) {\n            start =  max + spaceAfter[2].length;\n            return {\n                start: start,\n                end: start + spaceAfter[3].length\n            };\n        }\n    }\n\n}\n\nfunction wrapAfterInput(e) {\n    if (e.command.name == \"insertstring\" && /\\S/.test(e.args)) {\n        var editor = e.editor;\n        var cursor = editor.selection.cursor;\n        if (cursor.column <= editor.renderer.$printMarginColumn) return;\n        var lastDelta = editor.session.$undoManager.$lastDelta;\n\n        hardWrap(editor, {\n            startRow: cursor.row, endRow: cursor.row,\n            allowMerge: false\n        });\n        if (lastDelta != editor.session.$undoManager.$lastDelta) \n            editor.session.markUndoGroup();\n    }\n}\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    hardWrap: {\n        set: function(val) {\n            if (val) {\n                this.commands.on(\"afterExec\", wrapAfterInput);\n            } else {\n                this.commands.off(\"afterExec\", wrapAfterInput);\n            }\n        },\n        value: false\n    }\n});\n\nexports.hardWrap = hardWrap;\n"
  },
  {
    "path": "src/ext/hardwrap_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"./../test/assertions\");\nrequire(\"./../test/mockdom\");\nvar ace = require(\"../ace\");\nvar hardWrap = require(\"./hardwrap\").hardWrap;\nvar editor;\n\nmodule.exports = {\n    setUp: function() {\n        if (!editor) {\n            editor = ace.edit(null);\n        }\n        editor.focus();\n    },\n    tearDown: function() {\n        if (editor) {\n            editor.destroy();\n            editor.container.remove();\n            editor = null;\n        }\n    },\n    \"test: split lines\": function() {\n        editor.setValue(\"line 1 longword line 2\");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line 1\\nlongword\\nline 2\");\n        \n        editor.setValue(\"line1longword line 2\");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line1longword\\nline 2\");\n        \n        editor.setValue(\"line1longword    \");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line1longword\\n\");\n        \n        editor.setValue(\"line 1               line 2\");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line 1\\nline 2\");\n        \n        editor.setValue(\"line 1  line 2\");\n        hardWrap(editor, {column: 6, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line 1\\nline 2\");\n        \n        editor.setValue(\"line 1\");\n        hardWrap(editor, {column: 10, startRow: 0, endRow: 2});\n        assert.equal(editor.getValue(), \"line 1\");\n    },\n    \n    \"test: merge lines\": function() {\n        editor.setValue(\"line \\n \\t 1   \\nlongword\\nline \\n 2\");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 4});\n        assert.equal(editor.getValue(), \"line 1\\nlongword\\nline 2\");\n        \n        editor.setValue(\"line \\n 1 \\n longword \\n line \\n2 a longer line\");\n        hardWrap(editor, {column: 12, startRow: 0, endRow: 4, allowMerge: false});\n        assert.equal(editor.getValue(), \"line \\n 1 \\n longword \\n line \\n2 a longer\\nline\");\n    },\n\n    \"test: keep indentation\": function() {\n        var value = \"hello\\n    long long text\\n unchanged next line\";\n        editor.setValue(value);\n        hardWrap(editor, {column: 12, startRow: 1, endRow: 1});\n        assert.equal(editor.getValue(), \"hello\\n    long\\n    long\\n    text\\n unchanged next line\");\n        hardWrap(editor, {column: 80, startRow: 1, endRow: 3});\n        assert.equal(editor.getValue(), value);\n    },\n\n    \"test: wrap as you type\": function() {\n        editor.setValue(\"hello\\n    long long text\\n unchanged next line\", -1);\n        editor.execCommand(\"golinedown\");\n        editor.execCommand(\"gotolineend\");\n        editor.execCommand(\"insertstring\", \" \");\n        editor.execCommand(\"insertstring\", \"t\");\n        assert.equal(editor.session.getLine(1), \"    long long text t\");\n        editor.setOptions({printMargin: 12, hardWrap: true});\n        editor.execCommand(\"insertstring\", \" \");\n        assert.equal(editor.session.getLine(1), \"    long long text t \");\n        editor.execCommand(\"insertstring\", \"x\");\n        assert.equal(editor.getValue(), \"hello\\n    long\\n    long\\n    text t x\\n unchanged next line\");\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/inline_autocomplete.js",
    "content": "/**\n * ## Inline Autocomplete extension\n *\n * Provides lightweight, prefix-based autocompletion with inline ghost text rendering and an optional command bar tooltip.\n * Displays completion suggestions as ghost text directly in the editor with keyboard navigation and interactive controls.\n *\n * **Enable:** `editor.setOption(\"enableInlineAutocompletion\", true)`\n * or configure it during editor initialization in the options object.\n * @module\n */\n\n\"use strict\";\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar AceInline = require(\"../autocomplete/inline\").AceInline;\nvar FilteredList = require(\"../autocomplete\").FilteredList;\nvar CompletionProvider = require(\"../autocomplete\").CompletionProvider;\nvar Editor = require(\"../editor\").Editor;\nvar util = require(\"../autocomplete/util\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar CommandBarTooltip = require(\"./command_bar\").CommandBarTooltip;\nvar BUTTON_CLASS_NAME = require(\"./command_bar\").BUTTON_CLASS_NAME;\n\nvar snippetCompleter = require(\"./language_tools\").snippetCompleter;\nvar textCompleter = require(\"./language_tools\").textCompleter;\nvar keyWordCompleter = require(\"./language_tools\").keyWordCompleter;\n\nvar destroyCompleter = function(e, editor) {\n    editor.completer && editor.completer.destroy();\n};\n\n/**\n * This class controls the inline-only autocompletion components and their lifecycle.\n * This is more lightweight than the popup-based autocompletion, as it can only work with exact prefix matches.\n * There is an inline ghost text renderer and an optional command bar tooltip inside.\n */\nclass InlineAutocomplete {\n    /**\n     * @param {Editor} editor\n     */\n    constructor(editor) {\n        this.editor = editor;\n        this.keyboardHandler = new HashHandler(this.commands);\n        this.$index = -1;\n\n        this.blurListener = this.blurListener.bind(this);\n        this.changeListener = this.changeListener.bind(this);\n\n\n        this.changeTimer = lang.delayedCall(function() {\n            this.updateCompletions();\n        }.bind(this));\n    }\n\n    /**\n     * \n     * @return {AceInline}\n     */\n    getInlineRenderer() {\n        if (!this.inlineRenderer)\n            this.inlineRenderer = new AceInline();\n        return this.inlineRenderer;\n    }\n\n    /**\n     * @return {CommandBarTooltip}\n     */\n    getInlineTooltip() {\n        if (!this.inlineTooltip) {\n            this.inlineTooltip = InlineAutocomplete.createInlineTooltip(document.body || document.documentElement);\n        }\n        return this.inlineTooltip;\n    }\n\n\n    /**\n     * This function is the entry point to the class. This triggers the gathering of the autocompletion and displaying the results;\n     * @param {import(\"../../ace-internal\").Ace.CompletionOptions} options\n     */\n    show(options) {\n        this.activated = true;\n\n        if (this.editor.completer !== this) {\n            if (this.editor.completer)\n                this.editor.completer.detach();\n            this.editor.completer = this;\n        }\n\n        this.editor.on(\"changeSelection\", this.changeListener);\n        this.editor.on(\"blur\", this.blurListener);\n\n        this.updateCompletions(options);\n    }\n\n    $open() {\n        if (this.editor.textInput.setAriaOptions) {\n            this.editor.textInput.setAriaOptions({});\n        }\n\n        this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);\n        this.getInlineTooltip().attach(this.editor);\n\n        if (this.$index === -1) {\n            this.setIndex(0);\n        } else {\n            this.$showCompletion();\n        }\n        \n        this.changeTimer.cancel();\n    }\n    \n    insertMatch() {\n        var result = this.getCompletionProvider().insertByIndex(this.editor, this.$index);\n        this.detach();\n        return result;\n    }\n\n    changeListener(e) {\n        var cursor = this.editor.selection.lead;\n        if (cursor.row != this.base.row || cursor.column < this.base.column) {\n            this.detach();\n        }\n        if (this.activated)\n            this.changeTimer.schedule();\n        else\n            this.detach();\n    }\n\n    blurListener(e) {\n        this.detach();\n    }\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.InlineAutocompleteAction} where\n     */\n    goTo(where) {\n        if (!this.completions || !this.completions.filtered) {\n            return;\n        }\n        var completionLength = this.completions.filtered.length;\n        switch(where.toLowerCase()) {\n            case \"prev\":\n                this.setIndex((this.$index - 1 + completionLength) % completionLength);\n                break;\n            case \"next\":\n                this.setIndex((this.$index + 1 + completionLength) % completionLength);\n                break;\n            case \"first\":\n                this.setIndex(0);\n                break;\n            case \"last\":\n                this.setIndex(this.completions.filtered.length - 1);\n                break;\n        }\n    }\n\n    getLength() {\n        if (!this.completions || !this.completions.filtered) {\n            return 0;\n        }\n        return this.completions.filtered.length;\n    }\n\n    /**\n     * @param {number} [index]\n     * @returns {import(\"../../ace-internal\").Ace.Completion | undefined}\n     */\n    getData(index) {\n        if (index == undefined || index === null) {\n            return this.completions.filtered[this.$index];\n        } else {\n            return this.completions.filtered[index];\n        }\n    }\n\n    getIndex() {\n        return this.$index;\n    }\n\n    isOpen() {\n        return this.$index >= 0;\n    }\n\n    /**\n     * @param {number} value\n     */\n    setIndex(value) {\n        if (!this.completions || !this.completions.filtered) {\n            return;\n        }\n        var newIndex = Math.max(-1, Math.min(this.completions.filtered.length - 1, value));\n        if (newIndex !== this.$index) {\n            this.$index = newIndex;\n            this.$showCompletion();\n        }\n    }\n\n    /**\n     * @return {CompletionProvider}\n     */\n    getCompletionProvider(initialPosition) {\n        if (!this.completionProvider)\n            this.completionProvider = new CompletionProvider(initialPosition);\n        return this.completionProvider;\n    }\n\n    $showCompletion() {\n        if (!this.getInlineRenderer().show(this.editor, this.completions.filtered[this.$index], this.completions.filterText)) {\n            // Not able to show the completion, hide the previous one\n            this.getInlineRenderer().hide();\n        }\n        if (this.inlineTooltip && this.inlineTooltip.isShown()) {\n            this.inlineTooltip.update();\n        }\n    }\n\n    /**\n     * @return {any}\n     */\n    $updatePrefix() {\n        var pos = this.editor.getCursorPosition();\n        var prefix = this.editor.session.getTextRange({start: this.base, end: pos});\n        this.completions.setFilter(prefix);\n        if (!this.completions.filtered.length)\n            return this.detach();\n        if (this.completions.filtered.length == 1\n        && this.completions.filtered[0].value == prefix\n        && !this.completions.filtered[0].snippet)\n            return this.detach();\n        //@ts-expect-error TODO: potential wrong arguments\n        this.$open(this.editor, prefix);\n        return prefix;\n    }\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.CompletionOptions} [options]\n     */\n    updateCompletions(options) {\n        var prefix = \"\";\n        \n        if (options && options.matches) {\n            var pos = this.editor.getSelectionRange().start;\n            this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);\n            this.base.$insertRight = true;\n            this.completions = new FilteredList(options.matches);\n            //@ts-expect-error TODO: potential wrong arguments\n            return this.$open(this.editor, \"\");\n        }\n\n        if (this.base && this.completions) {\n            prefix = this.$updatePrefix();\n        }\n\n        var session = this.editor.getSession();\n        var pos = this.editor.getCursorPosition();\n        var prefix = util.getCompletionPrefix(this.editor);\n        this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);\n        this.base.$insertRight = true;\n\n        // @ts-ignore\n        var options = {\n            exactMatch: true,\n            ignoreCaption: true\n        };\n        this.getCompletionProvider({\n            prefix,\n            base: this.base,\n            pos\n            // @ts-ignore\n        }).provideCompletions(this.editor, options,\n            /**\n             * @this {InlineAutocomplete}\n             */\n            function(err, completions, finished) {\n                var filtered = completions.filtered;\n                var prefix = util.getCompletionPrefix(this.editor);\n\n                if (finished) {\n                    // No results\n                    if (!filtered.length)\n                        return this.detach();\n\n                    // One result equals to the prefix\n                    if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet)\n                        return this.detach();\n                }\n                this.completions = completions;\n                //@ts-expect-error TODO: potential wrong arguments\n                this.$open(this.editor, prefix);\n            }.bind(this));\n    }\n\n    detach() {\n        if (this.editor) {\n            this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);\n            this.editor.off(\"changeSelection\", this.changeListener);\n            this.editor.off(\"blur\", this.blurListener);\n        }\n        this.changeTimer.cancel();\n        if (this.inlineTooltip) {\n            this.inlineTooltip.detach();\n        }\n        \n        this.setIndex(-1);\n\n        if (this.completionProvider) {\n            this.completionProvider.detach();\n        }\n\n        if (this.inlineRenderer && this.inlineRenderer.isOpen()) {\n            this.inlineRenderer.hide();\n        }\n\n        if (this.base)\n            this.base.detach();\n        this.activated = false;\n        this.completionProvider = this.completions = this.base = null;\n    }\n\n    destroy() {\n        this.detach();\n        if (this.inlineRenderer)\n            this.inlineRenderer.destroy();\n        if (this.inlineTooltip)\n            this.inlineTooltip.destroy();\n        if (this.editor && this.editor.completer == this) {\n            this.editor.off(\"destroy\", destroyCompleter);\n            this.editor.completer = null;\n        }\n        this.inlineTooltip = this.editor = this.inlineRenderer = null;\n    }\n\n    updateDocTooltip(){\n    }\n\n}\n\n/**\n * \n * @type {{[key: string]: import(\"../../ace-internal\").Ace.Command}}\n */\nInlineAutocomplete.prototype.commands = {\n    \"Previous\": {\n        bindKey: \"Alt-[\",\n        name: \"Previous\",\n        exec: function(editor) {\n            editor.completer.goTo(\"prev\");\n        }\n    },\n    \"Next\": {\n        bindKey: \"Alt-]\",\n        name: \"Next\",\n        exec: function(editor) {\n            editor.completer.goTo(\"next\");\n        }\n    },\n    \"Accept\": {\n        bindKey: { win: \"Tab|Ctrl-Right\", mac: \"Tab|Cmd-Right\" },\n        name: \"Accept\",\n        exec: function(editor) {\n            return /**@type{InlineAutocomplete}*/(editor.completer).insertMatch();\n        }\n    },\n    \"Close\": {\n        bindKey: \"Esc\",\n        name: \"Close\",\n        exec: function(editor) {\n            editor.completer.detach();\n        }\n    }\n};\n\nInlineAutocomplete.for = function(editor) {\n    if (editor.completer instanceof InlineAutocomplete) {\n        return editor.completer;\n    }\n    if (editor.completer) {\n        editor.completer.destroy();\n        editor.completer = null;\n    }\n\n    editor.completer = new InlineAutocomplete(editor);\n    editor.once(\"destroy\", destroyCompleter);\n    return editor.completer;\n};\n\nInlineAutocomplete.startCommand = {\n    name: \"startInlineAutocomplete\",\n    exec: function(editor, options) {\n        var completer = InlineAutocomplete.for(editor);\n        completer.show(options);\n    },\n    bindKey: { win: \"Alt-C\", mac: \"Option-C\" }\n};\n\n\nvar completers = [snippetCompleter, textCompleter, keyWordCompleter];\n\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    enableInlineAutocompletion: {\n        /**\n         * @this{Editor}\n         * @param val\n         */\n        set: function(val) {\n            if (val) {\n                if (!this.completers)\n                    this.completers = Array.isArray(val)? val : completers;\n                this.commands.addCommand(InlineAutocomplete.startCommand);\n            } else {\n                this.commands.removeCommand(InlineAutocomplete.startCommand);\n            }\n        },\n        value: false\n    }\n});\n\n/**\n * Factory method to create a command bar tooltip for inline autocomplete.\n * \n * @param {HTMLElement} parentEl  The parent element where the tooltip HTML elements will be added.\n * @returns {CommandBarTooltip}   The command bar tooltip for inline autocomplete\n */\nInlineAutocomplete.createInlineTooltip = function(parentEl) {\n    /**@type {CommandBarTooltip}*/\n    var inlineTooltip = new CommandBarTooltip(parentEl);\n    inlineTooltip.registerCommand(\"Previous\",\n        // @ts-expect-error\n        Object.assign({}, InlineAutocomplete.prototype.commands[\"Previous\"], {\n            enabled: true,\n            type: \"button\",\n            iconCssClass: \"ace_arrow_rotated\"\n        })\n    );\n    inlineTooltip.registerCommand(\"Position\", {\n        enabled: false,\n        getValue: function (editor) {\n            return editor ? [/**@type{InlineAutocomplete}*/\n                (editor.completer).getIndex() + 1, /**@type{InlineAutocomplete}*/(editor.completer).getLength()\n            ].join(\"/\") : \"\";\n        },\n        type: \"text\",\n        cssClass: \"completion_position\"\n    });\n    inlineTooltip.registerCommand(\"Next\",\n        // @ts-expect-error\n        Object.assign({}, InlineAutocomplete.prototype.commands[\"Next\"], {\n            enabled: true,\n            type: \"button\",\n            iconCssClass: \"ace_arrow\"\n        })\n    );\n    inlineTooltip.registerCommand(\"Accept\",\n        // @ts-expect-error\n        Object.assign({}, InlineAutocomplete.prototype.commands[\"Accept\"], {\n            enabled: function(editor) {\n                return !!editor && editor.completer.getIndex() >= 0;\n            },\n            type: \"button\"\n        })\n    );\n    inlineTooltip.registerCommand(\"ShowTooltip\", {\n        name: \"Always Show Tooltip\",\n        exec: function() {\n            inlineTooltip.setAlwaysShow(!inlineTooltip.getAlwaysShow());\n        },\n        enabled: true,\n        getValue: function() {\n            return inlineTooltip.getAlwaysShow();\n        },\n        type: \"checkbox\"\n    });\n    return inlineTooltip;\n};\n\ndom.importCssString(`\n\n.ace_icon_svg.ace_arrow,\n.ace_icon_svg.ace_arrow_rotated {\n    -webkit-mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTUuODM3MDEgMTVMNC41ODc1MSAxMy43MTU1TDEwLjE0NjggOEw0LjU4NzUxIDIuMjg0NDZMNS44MzcwMSAxTDEyLjY0NjUgOEw1LjgzNzAxIDE1WiIgZmlsbD0iYmxhY2siLz48L3N2Zz4=\");\n}\n\n.ace_icon_svg.ace_arrow_rotated {\n    transform: rotate(180deg);\n}\n\ndiv.${BUTTON_CLASS_NAME}.completion_position {\n    padding: 0;\n}\n`, \"inlineautocomplete.css\", false);\n\nexports.InlineAutocomplete = InlineAutocomplete;\n"
  },
  {
    "path": "src/ext/inline_autocomplete_test.js",
    "content": "\nif (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar Editor = require(\"../editor\").Editor;\nvar EditSession = require(\"../edit_session\").EditSession;\nvar InlineAutocomplete = require(\"./inline_autocomplete\").InlineAutocomplete;\nconst { Autocomplete } = require(\"../autocomplete\");\nvar assert = require(\"../test/assertions\");\nvar BUTTON_CLASS_NAME = require(\"./command_bar\").BUTTON_CLASS_NAME;\nvar type = require(\"../test/user\").type;\nvar VirtualRenderer = require(\"../virtual_renderer\").VirtualRenderer;\n\nvar editor;\nvar autocomplete;\nvar inlineTooltip;\nvar wrapperEl;\n\nfunction simulateClick(node) {\n    node.dispatchEvent(new window.CustomEvent(\"click\", { bubbles: true }));\n}\n\n\nvar getAllLines = function() {\n    var text = Array.from(editor.renderer.$textLayer.element.childNodes).map(function (node) {\n        return node.textContent;\n    }).join(\"\\n\");\n    if (editor.renderer.$ghostTextWidget) {\n        return text + \"\\n\" + editor.renderer.$ghostTextWidget.el.innerHTML;\n    }\n    return text;\n};\n\nvar typeAndChange = function(...args) {\n    assert.equal(autocomplete.changeTimer.isPending(), null);\n    type(args);\n    assert.ok(autocomplete.changeTimer.isPending);\n    autocomplete.changeTimer.call();\n};\n\nvar completions = [\n    {\n        value: \"foo\"\n    },\n    {\n        value: \"foobar\"\n    },\n    {\n        value: \"function\"\n    },\n    {\n        value: \"fundraiser\"\n    },\n    {\n        snippet: \"function foo() {\\n    console.log('test');\\n}\",\n        caption: \"func\"\n    },\n    {\n        value: \"foobar2\"\n    }\n];\n\nvar mockCompleter = {\n    getCompletions: function(_1, _2, _3, _4, callback) {\n        callback(null, completions);\n    }\n};\n\nvar setupInlineTooltip = function() {\n    inlineTooltip = autocomplete.getInlineTooltip();\n    inlineTooltip.setAlwaysShow(true);\n    // Workaround: non-standard width and height hints for mock dom (mock dom does not work well with flex elements)\n    // When running in the browser, these are ignored\n    inlineTooltip.tooltip.getElement().style.widthHint = 150;\n    inlineTooltip.tooltip.getElement().style.heightHint = editor.renderer.lineHeight * 2;\n    inlineTooltip.moreOptions.getElement().style.widthHint = 150;\n    inlineTooltip.moreOptions.getElement().style.heightHint = editor.renderer.lineHeight * 2;\n};\n\nmodule.exports = {\n    setUp: function() {\n        wrapperEl = document.createElement(\"div\");\n        wrapperEl.style.position = \"fixed\";\n        wrapperEl.style.left = \"400px\";\n        wrapperEl.style.top = \"30px\";\n        wrapperEl.style.width = \"500px\";\n        wrapperEl.style.height = \"500px\";\n        document.body.appendChild(wrapperEl);\n        var renderer = new VirtualRenderer(wrapperEl);\n        var session = new EditSession(\"\");\n        editor = new Editor(renderer, session);\n        editor.setOption(\"enableInlineAutocompletion\", true);\n        editor.execCommand(\"insertstring\", \"f\");\n        editor.getSelection().moveCursorFileEnd();\n        editor.renderer.$loop._flush();\n        editor.completers = [mockCompleter];\n        autocomplete = InlineAutocomplete.for(editor);\n        setupInlineTooltip();\n        editor.focus();\n    },\n    \"test: autocomplete completion shows up\": function() {\n        autocomplete.show(editor);\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), \"foo\");\n    },\n    \"test: autocomplete start keybinding works\": function() {\n        type(\"Alt-C\");\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), \"foo\");\n        autocomplete.detach();\n\n        editor.setOption(\"enableInlineAutocompletion\", false);\n\n        type(\"Alt-C\");\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.strictEqual(autocomplete.getIndex(), -1);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), \"f\");\n    },\n    \"test: replaces different autocomplete implementation for the editor when opened\": function() {\n        var completer = Autocomplete.for(editor);\n        completer.showPopup(editor, {});\n        assert.strictEqual(editor.completer, completer);\n        assert.strictEqual(autocomplete.isOpen(), false);\n\n        autocomplete = InlineAutocomplete.for(editor);\n        autocomplete.show(editor);\n        assert.strictEqual(editor.completer.isOpen(), true);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(getAllLines(), \"foo\");\n    },\n    \"test: autocomplete tooltip is shown according to the selected option\": function() {\n        autocomplete.show(editor);\n        assert.strictEqual(inlineTooltip.isShown(), true);\n\n        autocomplete.detach();\n        assert.strictEqual(inlineTooltip.isShown(), false);\n    },\n    \"test: autocomplete keyboard navigation works\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.equal(getAllLines(), \"foo\");\n\n        type(\"Alt-]\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 1);\n        assert.strictEqual(autocomplete.getData().value, \"foobar\");\n        assert.equal(getAllLines(), \"foobar\");\n\n        type(\"Alt-[\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.equal(getAllLines(), \"foo\");\n    },\n    \"test: autocomplete tooltip navigation works\": function() {\n        autocomplete.show(editor);\n        assert.strictEqual(autocomplete.getInlineTooltip().isShown(), true);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n\n        var prevButton = buttonElements[0];\n        var nextButton = buttonElements[2];\n\n        simulateClick(prevButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 5);\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.strictEqual(getAllLines(), \"fundraiser\");\n\n        simulateClick(nextButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        simulateClick(nextButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 1);\n        assert.strictEqual(autocomplete.getData().value, \"foobar\");\n        assert.strictEqual(getAllLines(), \"foobar\");\n\n        autocomplete.setIndex(5);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.equal(getAllLines(), \"fundraiser\");\n\n        simulateClick(nextButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        simulateClick(prevButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 5);\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.strictEqual(getAllLines(), \"fundraiser\");\n\n        simulateClick(prevButton);\n\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 4);\n        assert.strictEqual(autocomplete.getData().value, \"function\");\n        assert.strictEqual(getAllLines(), \"function\");\n    },\n    \"test: verify goTo commands\": function() {\n        autocomplete.show(editor);\n        autocomplete.setIndex(1);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getData().value, \"foobar\");\n        assert.equal(getAllLines(), \"foobar\");\n\n        autocomplete.goTo(\"next\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 2);\n        assert.strictEqual(autocomplete.getData().value, \"foobar2\");\n        assert.strictEqual(getAllLines(), \"foobar2\");\n\n        autocomplete.goTo(\"prev\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 1);\n        assert.strictEqual(autocomplete.getData().value, \"foobar\");\n        assert.strictEqual(getAllLines(), \"foobar\");\n\n        autocomplete.goTo(\"last\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 5);\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.strictEqual(getAllLines(), \"fundraiser\");\n\n        autocomplete.goTo(\"next\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        autocomplete.setIndex(5);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.equal(getAllLines(), \"fundraiser\");\n\n        autocomplete.goTo(\"first\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(autocomplete.getData().value, \"foo\");\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        autocomplete.goTo(\"prev\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 5);\n        assert.strictEqual(autocomplete.getData().value, \"fundraiser\");\n        assert.strictEqual(getAllLines(), \"fundraiser\");\n    },\n    \"test: set index to negative value hides suggestions\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        autocomplete.setIndex(-1);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.strictEqual(getAllLines(), \"f\");\n    },\n    \"test: autocomplete can be closed\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), \"foo\");\n\n        type(\"Escape\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(getAllLines(), \"f\");\n    },\n    \"test: autocomplete can be accepted\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.ok(document.querySelectorAll(\".ace_ghost_text\").length > 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        type(\"Tab\");\n        editor.renderer.$loop._flush();\n        assert.equal(autocomplete.inlineCompleter, null);\n        assert.equal(autocomplete.inlineTooltip.isShown(), false);\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(editor.renderer.$ghostText, null);\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        assert.strictEqual(document.querySelectorAll(\".ace_ghost_text\").length, 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n    },\n    \"test: autocomplete can be accepted via tooltip\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(autocomplete.inlineTooltip.isShown(), true);\n        assert.ok(document.querySelectorAll(\".ace_ghost_text\").length > 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        var acceptButton = buttonElements[3];\n\n        simulateClick(acceptButton);\n\n        editor.renderer.$loop._flush();\n        assert.equal(autocomplete.inlineCompleter, null);\n        assert.equal(autocomplete.inlineTooltip.isShown(), false);\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(editor.renderer.$ghostText, null);\n        assert.equal(editor.renderer.$ghostTextWidget, null);\n        assert.strictEqual(document.querySelectorAll(\".ace_ghost_text\").length, 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n    },\n    \"test: incremental typing filters results\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), \"foo\");\n\n        typeAndChange(\"u\", \"n\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), `function foo() {\\n<div><span class=\"ace_ghost_text\">    console.log('test');</span></div><div><span class=\"ace_ghost_text\">}</span><span></span></div>`);\n\n        typeAndChange(\"d\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), \"fundraiser\");\n\n        typeAndChange(\"Backspace\", \"Backspace\", \"Backspace\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), \"foo\");\n\n        typeAndChange(\"r\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(getAllLines(), \"fr\");\n    },\n    \"test: tooltip stays open on incremental typing\": function() {\n        autocomplete.show(editor);\n        assert.strictEqual(inlineTooltip.isShown(), true);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.equal(getAllLines(), \"foo\");\n        typeAndChange(\"u\", \"n\");\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.isOpen(), true);\n        assert.strictEqual(inlineTooltip.isShown(), true);\n    },\n    \"test: can toggle tooltip display mode via tooltip button\": function() {\n        autocomplete.show(editor);\n        assert.strictEqual(inlineTooltip.isShown(), true);\n\n        var buttonElements = Array.from(document.querySelectorAll(\".\" + BUTTON_CLASS_NAME));\n        var moreOptionsButton = buttonElements[4];\n        var showTooltipToggle = buttonElements[5];\n        var showTooltipToggleCheckMark = showTooltipToggle.firstChild;\n\n        assert.strictEqual(showTooltipToggle.ariaChecked.toString(), \"true\");\n        assert.strictEqual(showTooltipToggleCheckMark.classList.contains(\"ace_checkmark\"), true);\n        assert.strictEqual(inlineTooltip.getAlwaysShow(), true);\n        assert.strictEqual(inlineTooltip.isMoreOptionsShown(), false);\n\n        simulateClick(moreOptionsButton);\n\n        assert.strictEqual(inlineTooltip.isShown(), true);\n        assert.strictEqual(showTooltipToggle.ariaChecked.toString(), \"true\");\n        assert.strictEqual(showTooltipToggleCheckMark.classList.contains(\"ace_checkmark\"), true);\n        assert.strictEqual(inlineTooltip.getAlwaysShow(), true);\n        assert.strictEqual(inlineTooltip.isMoreOptionsShown(), true);\n\n        simulateClick(showTooltipToggle);\n\n        assert.strictEqual(showTooltipToggle.ariaChecked.toString(), \"false\");\n        assert.strictEqual(showTooltipToggleCheckMark.classList.contains(\"ace_checkmark\"), false);\n        assert.strictEqual(inlineTooltip.getAlwaysShow(), false);\n        assert.strictEqual(inlineTooltip.isMoreOptionsShown(), false);\n    },\n    \"test: verify detach\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n\n        autocomplete.detach();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), -1);\n        assert.strictEqual(autocomplete.getLength(), 0);\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(autocomplete.base, null);\n        assert.equal(autocomplete.completions, null);\n        assert.equal(autocomplete.completionProvider, null);\n        assert.strictEqual(getAllLines(), \"f\");\n    },\n    \"test: verify destroy\": function() {\n        autocomplete.show(editor);\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), 0);\n        assert.strictEqual(getAllLines(), \"foo\");\n        assert.strictEqual(editor.completer, autocomplete);\n\n        autocomplete.destroy();\n        editor.renderer.$loop._flush();\n        assert.strictEqual(autocomplete.getIndex(), -1);\n        assert.strictEqual(autocomplete.getLength(), 0);\n        assert.strictEqual(autocomplete.isOpen(), false);\n        assert.equal(autocomplete.base, null);\n        assert.equal(autocomplete.completions, null);\n        assert.equal(autocomplete.completionProvider, null);\n        assert.equal(autocomplete.editor, null);\n        assert.equal(autocomplete.inlineTooltip, null);\n        assert.equal(autocomplete.inlineRenderer, null);\n        assert.strictEqual(editor.completer, null);\n        assert.strictEqual(getAllLines(), \"f\");\n\n        autocomplete.destroy();\n        editor.renderer.$loop._flush();\n    },\n\n    tearDown: function() {\n        autocomplete.destroy();\n        editor.destroy();\n        wrapperEl.parentElement.removeChild(wrapperEl);\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/keybinding_menu.js",
    "content": "/**\n * ## Show Keyboard Shortcuts extension\n *\n * Provides a keyboard shortcuts display overlay for the Ace editor. Creates an interactive menu that shows all available\n * keyboard shortcuts with their corresponding commands, organized in a searchable and navigable format. The menu\n * appears as an overlay page and can be triggered via keyboard shortcut (Ctrl-Alt-H/Cmd-Alt-H) or programmatically.\n *\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n * @module\n */\n\n/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/\n/*global define, require */\n\n\"use strict\";\n\nvar Editor = require(\"../editor\").Editor;\n\n/**\n * Generates a menu which displays the keyboard shortcuts.\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *  ☭ Hial Atropa!! ☭\n * @param {Editor} editor An instance of the ace editor.\n */\nfunction showKeyboardShortcuts(editor) {\n    // make sure the menu isn't open already.\n    if (!document.getElementById('kbshortcutmenu')) {\n        var overlayPage = require('./menu_tools/overlay_page').overlayPage;\n        var getEditorKeybordShortcuts = require('./menu_tools/get_editor_keyboard_shortcuts').getEditorKeybordShortcuts;\n        var kb = getEditorKeybordShortcuts(editor);\n        var el = document.createElement('div');\n        var commands = kb.reduce(function (previous, current) {\n            return previous + '<div class=\"ace_optionsMenuEntry\"><span class=\"ace_optionsMenuCommand\">'\n                + current.command + '</span> : '\n                + '<span class=\"ace_optionsMenuKey\">' + current.key + '</span></div>';\n        }, '');\n\n        el.id = 'kbshortcutmenu';\n        el.innerHTML = '<h1>Keyboard Shortcuts</h1>' + commands + '</div>';\n        overlayPage(editor, el);\n    }\n}\n\n/**\n * Initializes keyboard shortcut functionality for the editor.\n * Adds a method to show keyboard shortcuts and registers a command\n * to trigger the keyboard shortcuts display.\n *\n * @param {Editor} editor The Ace editor instance to initialize\n */\nmodule.exports.init = function (editor) {\n    Editor.prototype.showKeyboardShortcuts = function () {\n        showKeyboardShortcuts(this);\n    };\n    editor.commands.addCommands([{\n        name: \"showKeyboardShortcuts\",\n        bindKey: {\n            win: \"Ctrl-Alt-h\",\n            mac: \"Command-Alt-h\"\n        },\n        exec:\n            /**\n             * \n             * @param {Editor} editor\n             * @param [line]\n             */\n            function (editor, line) {\n            editor.showKeyboardShortcuts();\n        }\n    }]);\n};\n"
  },
  {
    "path": "src/ext/language_tools.js",
    "content": "/**\n * ## Language Tools extension for Ace Editor\n *\n * Provides autocompletion, snippets, and language intelligence features for the Ace code editor.\n * This extension integrates multiple completion providers including keyword completion, snippet expansion,\n * and text-based completion to enhance the coding experience with contextual suggestions and automated code generation.\n *\n * **Configuration Options:**\n * - `enableBasicAutocompletion`: Enable/disable basic completion functionality\n * - `enableLiveAutocompletion`: Enable/disable real-time completion suggestions\n * - `enableSnippets`: Enable/disable snippet expansion with Tab key\n * - `liveAutocompletionDelay`: Delay before showing live completion popup\n * - `liveAutocompletionThreshold`: Minimum prefix length to trigger completion\n *\n * **Usage:**\n * ```javascript\n * editor.setOptions({\n *   enableBasicAutocompletion: true,\n *   enableLiveAutocompletion: true,\n *   enableSnippets: true\n * });\n * ```\n *\n * @module\n */\n\n\"use strict\";\n/**@type{import(\"../snippets\").snippetManager & {files?: {[key: string]: any}}}*/\nvar snippetManager = require(\"../snippets\").snippetManager;\nvar Autocomplete = require(\"../autocomplete\").Autocomplete;\nvar config = require(\"../config\");\nvar lang = require(\"../lib/lang\");\nvar util = require(\"../autocomplete/util\");\n\nvar MarkerGroup = require(\"../marker_group\").MarkerGroup;\n\nvar textCompleter = require(\"../autocomplete/text_completer\");\n/**@type {import(\"../../ace-internal\").Ace.Completer}*/\nvar keyWordCompleter = {\n    getCompletions: function(editor, session, pos, prefix, callback) {\n        if (session.$mode.completer) {\n            return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback);\n        }\n        var state = editor.session.getState(pos.row);\n        var completions = session.$mode.getCompletions(state, session, pos, prefix);\n        completions = completions.map((el) => {\n            el.completerId = keyWordCompleter.id;\n            return el;\n        });\n        callback(null, completions);\n    },\n    id: \"keywordCompleter\"\n};\n\nvar transformSnippetTooltip = function(str) {\n    var record = {};\n    return str.replace(/\\${(\\d+)(:(.*?))?}/g, function(_, p1, p2, p3) {\n        return (record[p1] = p3 || '');\n    }).replace(/\\$(\\d+?)/g, function (_, p1) {\n        return record[p1];\n    });\n};\n/**@type {import(\"../../ace-internal\").Ace.Completer} */\nvar snippetCompleter = {\n    getCompletions: function(editor, session, pos, prefix, callback) {\n        var scopes = [];\n\n        // set scope to html-tag if we're inside an html tag\n        var token = session.getTokenAt(pos.row, pos.column);\n        if (token && token.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\\.xml$/))\n            scopes.push('html-tag');\n        else\n            scopes = snippetManager.getActiveScopes(editor);\n\n        var snippetMap = snippetManager.snippetMap;\n        var completions = [];\n        scopes.forEach(function(scope) {\n            var snippets = snippetMap[scope] || [];\n            for (var i = snippets.length; i--;) {\n                var s = snippets[i];\n                var caption = s.name || s.tabTrigger;\n                if (!caption)\n                    continue;\n                completions.push({\n                    caption: caption,\n                    snippet: s.content,\n                    meta: s.tabTrigger && !s.name ? s.tabTrigger + \"\\u21E5 \" : \"snippet\",\n                    completerId: snippetCompleter.id\n                });\n            }\n        }, this);\n        callback(null, completions);\n    },\n    getDocTooltip: function(item) {\n        if (item.snippet && !item.docHTML) {\n            item.docHTML = [\n                \"<b>\", lang.escapeHTML(item.caption), \"</b>\", \"<hr></hr>\",\n                lang.escapeHTML(transformSnippetTooltip(item.snippet))\n            ].join(\"\");\n        }\n    },\n    id: \"snippetCompleter\"\n};\n\nvar completers = [snippetCompleter, textCompleter, keyWordCompleter];\n/**\n * Replaces the default list of completers with a new set of completers.\n *\n * @param {import(\"../../ace-internal\").Ace.Completer[]} [val]\n *\n */\nexports.setCompleters = function(val) {\n    completers.length = 0;\n    if (val) completers.push.apply(completers, val);\n};\n/**\n * Adds a new completer to the list of available completers.\n *\n * @param {import(\"../../ace-internal\").Ace.Completer} completer - The completer object to be added to the completers array.\n */\nexports.addCompleter = function(completer) {\n    completers.push(completer);\n};\n\n// Exports existing completer so that user can construct his own set of completers.\nexports.textCompleter = textCompleter;\nexports.keyWordCompleter = keyWordCompleter;\nexports.snippetCompleter = snippetCompleter;\n\nvar expandSnippet = {\n    name: \"expandSnippet\",\n    exec: function(editor) {\n        return snippetManager.expandWithTab(editor);\n    },\n    bindKey: \"Tab\"\n};\n\nvar onChangeMode = function(e, editor) {\n    loadSnippetsForMode(editor.session.$mode);\n};\n\nvar loadSnippetsForMode = function(mode) {\n    if (typeof mode == \"string\")\n        mode = config.$modes[mode];\n    if (!mode)\n        return;\n    if (!snippetManager.files)\n        snippetManager.files = {};\n    \n    loadSnippetFile(mode.$id, mode.snippetFileId);\n    if (mode.modes)\n        mode.modes.forEach(loadSnippetsForMode);\n};\n\nvar loadSnippetFile = function(id, snippetFilePath) {\n    if (!snippetFilePath || !id || snippetManager.files[id])\n        return;\n    snippetManager.files[id] = {};\n    config.loadModule(snippetFilePath, function(m) {\n        if (!m) return;\n        snippetManager.files[id] = m;\n        if (!m.snippets && m.snippetText)\n            m.snippets = snippetManager.parseSnippetFile(m.snippetText);\n        snippetManager.register(m.snippets || [], m.scope);\n        if (m.includeScopes) {\n            snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes;\n            m.includeScopes.forEach(function(x) {\n                loadSnippetsForMode(\"ace/mode/\" + x);\n            });\n        }\n    });\n};\n\nvar doLiveAutocomplete = function(e) {\n    var editor = e.editor;\n    var hasCompleter = editor.completer && editor.completer.activated;\n\n    // We don't want to autocomplete with no prefix\n    if (e.command.name === \"backspace\") {\n        if (hasCompleter && !util.getCompletionPrefix(editor))\n            editor.completer.detach();\n    }\n    else if (e.command.name === \"insertstring\" && !hasCompleter) {\n        lastExecEvent = e;\n        var delay = e.editor.$liveAutocompletionDelay;\n        if (delay) {\n            liveAutocompleteTimer.delay(delay);\n        } else {\n            showLiveAutocomplete(e);\n        }\n    }\n};\n\nvar lastExecEvent;\nvar liveAutocompleteTimer = lang.delayedCall(function () {\n    showLiveAutocomplete(lastExecEvent);\n}, 0);\n\nvar showLiveAutocomplete = function(e) {\n    var editor = e.editor;\n    var prefix = util.getCompletionPrefix(editor);\n    // Only autocomplete if there's a prefix that can be matched or previous char is trigger character \n    var previousChar = e.args;\n    var triggerAutocomplete = util.triggerAutocomplete(editor, previousChar);\n    if (prefix && prefix.length >= editor.$liveAutocompletionThreshold || triggerAutocomplete) {\n        var completer = Autocomplete.for(editor);\n        // Set a flag for auto shown\n        completer.autoShown = true;\n        completer.showPopup(editor);\n    }\n};\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    enableBasicAutocompletion: {\n        /**\n         * @param val\n         * @this{Editor}\n         */\n        set: function(val) {\n            if (val) {\n                Autocomplete.for(this);\n\n                if (!this.completers)\n                    this.completers = Array.isArray(val)? val: completers;\n                this.commands.addCommand(Autocomplete.startCommand);\n            } else {\n                this.commands.removeCommand(Autocomplete.startCommand);\n            }\n        },\n        value: false\n    },\n    /**\n     * Enable live autocompletion\n     */\n    enableLiveAutocompletion: {\n        /**\n         * @param {boolean} val\n         * @this {Editor}\n         */\n        set: function(val) {\n            if (val) {\n                if (!this.completers)\n                    this.completers = Array.isArray(val)? val: completers;\n                // On each change automatically trigger the autocomplete\n                this.commands.on('afterExec', doLiveAutocomplete);\n            } else {\n                this.commands.off('afterExec', doLiveAutocomplete);\n            }\n        },\n        value: false\n    },\n    liveAutocompletionDelay: {\n        initialValue: 0\n    },\n    liveAutocompletionThreshold: {\n        initialValue: 0\n    },\n    enableSnippets: {\n        set: function(val) {\n            if (val) {\n                this.commands.addCommand(expandSnippet);\n                this.on(\"changeMode\", onChangeMode);\n                onChangeMode(null, this);\n            } else {\n                this.commands.removeCommand(expandSnippet);\n                this.off(\"changeMode\", onChangeMode);\n            }\n        },\n        value: false\n    }\n});\n\nexports.MarkerGroup = MarkerGroup;"
  },
  {
    "path": "src/ext/linking.js",
    "content": "/**\n * ## Interactive Linking Extension\n *\n * Enables clickable links and hover interactions in the editor when the Control key is pressed. Provides\n * keyboard-accelerated navigation by detecting tokens under the cursor and emitting custom events that can be handled\n * by external code to implement go-to-definition, symbol navigation, or other link-based functionality.\n *\n * **Enable:** `editor.setOption(\"enableLinking\", true)`\n * @module\n */\n\nvar Editor = require(\"../editor\").Editor;\n\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    enableLinking: {\n        set: function(val) {\n            if (val) {\n                this.on(\"click\", onClick);\n                this.on(\"mousemove\", onMouseMove);\n            } else {\n                this.off(\"click\", onClick);\n                this.off(\"mousemove\", onMouseMove);\n            }\n        },\n        value: false\n    }\n});\n\nexports.previousLinkingHover = false;\n\nfunction onMouseMove(e) {\n    var editor = e.editor;\n    var ctrl = e.getAccelKey();\n\n    if (ctrl) {\n        var editor = e.editor;\n        var docPos = e.getDocumentPosition();\n        var session = editor.session;\n        var token = session.getTokenAt(docPos.row, docPos.column);\n\n        if (exports.previousLinkingHover && exports.previousLinkingHover != token) {\n            editor._emit(\"linkHoverOut\");\n        }\n        editor._emit(\"linkHover\", {position: docPos, token: token});\n        exports.previousLinkingHover = token;\n    } else if (exports.previousLinkingHover) {\n        editor._emit(\"linkHoverOut\");\n        exports.previousLinkingHover = false;\n    }\n}\n\nfunction onClick(e) {\n    var ctrl = e.getAccelKey();\n    var button = e.getButton();\n\n    if (button == 0 && ctrl) {\n        var editor = e.editor;\n        var docPos = e.getDocumentPosition();\n        var session = editor.session;\n        var token = session.getTokenAt(docPos.row, docPos.column);\n\n        editor._emit(\"linkClick\", {position: docPos, token: token});\n    }\n}\n"
  },
  {
    "path": "src/ext/menu_tools/get_editor_keyboard_shortcuts.js",
    "content": "/**\n * ## Editor Keyboard Shortcuts Utility\n *\n * Provides functionality to extract and format keyboard shortcuts from an Ace editor instance. Analyzes all registered\n * command handlers and their key bindings to generate a list of available keyboard shortcuts for the\n * current platform. Returns formatted key combinations with proper modifier key representations and handles multiple\n * bindings per command with pipe-separated notation.\n *\n * **Usage:**\n * ```javascript\n * var getKbShortcuts = require('ace/ext/menu_tools/get_editor_keyboard_shortcuts');\n * var shortcuts = getKbShortcuts.getEditorKeybordShortcuts(editor);\n * console.log(shortcuts);\n * // [\n * //     {'command': 'selectall', 'key': 'Ctrl-A'},\n * //     {'command': 'copy', 'key': 'Ctrl-C|Ctrl-Insert'}\n * // ]\n * ```\n *\n * @module\n */\n\n/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/\n/*global define, require */\n\n\"use strict\";\n\n/** @type{any} */var keys = require(\"../../lib/keys\");\n\n/**\n * Gets a map of keyboard shortcuts to command names for the current platform.\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *  ☭ Hial Atropa!! ☭\n * @param {import(\"../../editor\").Editor} editor An editor instance.\n * @returns {Array} Returns an array of objects representing the keyboard\n *  shortcuts for the given editor.\n * @example\n * var getKbShortcuts = require('./get_keyboard_shortcuts');\n * console.log(getKbShortcuts(editor));\n * // [\n * //     {'command' : aCommand, 'key' : 'Control-d'},\n * //     {'command' : aCommand, 'key' : 'Control-d'}\n * // ]\n */\nmodule.exports.getEditorKeybordShortcuts = function(editor) {\n    var KEY_MODS = keys.KEY_MODS;\n    var keybindings = [];\n    var commandMap = {};\n    editor.keyBinding.$handlers.forEach(function(handler) {\n        var ckb = handler[\"commandKeyBinding\"];\n        for (var i in ckb) {\n            var key = i.replace(/(^|-)\\w/g, function(x) { return x.toUpperCase(); });\n            var commands = ckb[i];\n            if (!Array.isArray(commands))\n                commands = [commands];\n            commands.forEach(function(command) {\n                if (typeof command != \"string\")\n                    command  = command.name;\n                if (commandMap[command]) {\n                    commandMap[command].key += \"|\" + key;\n                } else {\n                    commandMap[command] = {key: key, command: command};\n                    keybindings.push(commandMap[command]);\n                }         \n            });\n        }\n    });\n    return keybindings;\n};\n"
  },
  {
    "path": "src/ext/menu_tools/overlay_page.js",
    "content": "/**\n * ## Overlay Page utility\n *\n * Provides modal overlay functionality for displaying editor extension interfaces. Creates a full-screen overlay with\n * configurable backdrop behavior, keyboard navigation (ESC to close), and focus management. Used by various extensions\n * to display menus, settings panels, and other interactive content over the editor interface.\n *\n * **Usage:**\n * ```javascript\n * var overlayPage = require('./overlay_page').overlayPage;\n * var contentElement = document.createElement('div');\n * contentElement.innerHTML = '<h1>Settings</h1>';\n *\n * var overlay = overlayPage(editor, contentElement, function() {\n *   console.log('Overlay closed');\n * });\n * ```\n *\n * @module\n */\n\n\n/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/\n/*global define, require */\n\n'use strict';\nvar dom = require(\"../../lib/dom\");\nvar cssText = require(\"./settings_menu.css\");\ndom.importCssString(cssText, \"settings_menu.css\", false);\n\n/**\n * Generates an overlay for displaying menus. The overlay is an absolutely\n *  positioned div.\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *  ☭ Hial Atropa!! ☭\n * @param {import(\"../../editor\").Editor} editor\n * @param {HTMLElement} contentElement Any element which may be presented inside\n *  a div.\n * @param {() => void} [callback]\n */\nmodule.exports.overlayPage = function overlayPage(editor, contentElement, callback) {\n    var closer = document.createElement('div');\n    var ignoreFocusOut = false;\n\n    function documentEscListener(e) {\n        if (e.keyCode === 27) {\n            close();\n        }\n    }\n\n    function close() {\n        if (!closer) return;\n        document.removeEventListener('keydown', documentEscListener);\n        closer.parentNode.removeChild(closer);\n        if (editor) {\n            editor.focus();\n        }\n        closer = null;\n        callback && callback();\n    }\n\n     /**\n     * Defines whether overlay is closed when user clicks outside of it.\n     * \n     * @param {Boolean} ignore      If set to true overlay stays open when focus moves to another part of the editor.\n     */\n    function setIgnoreFocusOut(ignore) {\n        ignoreFocusOut = ignore;\n        if (ignore) {\n            closer.style.pointerEvents = \"none\";\n            contentElement.style.pointerEvents = \"auto\";\n        }\n    }\n\n    closer.style.cssText = 'margin: 0; padding: 0; ' +\n        'position: fixed; top:0; bottom:0; left:0; right:0;' +\n        'z-index: 9990; ' +\n        (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');\n    closer.addEventListener('click', function(e) {\n        if (!ignoreFocusOut) {\n            close();\n        }\n    });\n    // click closer if esc key is pressed\n    document.addEventListener('keydown', documentEscListener);\n\n    contentElement.addEventListener('click', function (e) {\n        e.stopPropagation();\n    });\n\n    closer.appendChild(contentElement);\n    document.body.appendChild(closer);\n    if (editor) {\n        editor.blur();\n    }\n    return {\n        close: close,\n        setIgnoreFocusOut: setIgnoreFocusOut\n    };\n};\n"
  },
  {
    "path": "src/ext/menu_tools/settings_menu.css.js",
    "content": "module.exports = `#ace_settingsmenu, #kbshortcutmenu {\n    background-color: #F7F7F7;\n    color: black;\n    box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\n    padding: 1em 0.5em 2em 1em;\n    overflow: auto;\n    position: absolute;\n    margin: 0;\n    bottom: 0;\n    right: 0;\n    top: 0;\n    z-index: 9991;\n    cursor: default;\n}\n\n.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\n    box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\n    background-color: rgba(255, 255, 255, 0.6);\n    color: black;\n}\n\n.ace_optionsMenuEntry:hover {\n    background-color: rgba(100, 100, 100, 0.1);\n    transition: all 0.3s\n}\n\n.ace_closeButton {\n    background: rgba(245, 146, 146, 0.5);\n    border: 1px solid #F48A8A;\n    border-radius: 50%;\n    padding: 7px;\n    position: absolute;\n    right: -8px;\n    top: -8px;\n    z-index: 100000;\n}\n.ace_closeButton{\n    background: rgba(245, 146, 146, 0.9);\n}\n.ace_optionsMenuKey {\n    color: darkslateblue;\n    font-weight: bold;\n}\n.ace_optionsMenuCommand {\n    color: darkcyan;\n    font-weight: normal;\n}\n.ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\n    vertical-align: middle;\n}\n\n.ace_optionsMenuEntry button[ace_selected_button=true] {\n    background: #e7e7e7;\n    box-shadow: 1px 0px 2px 0px #adadad inset;\n    border-color: #adadad;\n}\n.ace_optionsMenuEntry button {\n    background: white;\n    border: 1px solid lightgray;\n    margin: 0px;\n}\n.ace_optionsMenuEntry button:hover{\n    background: #f0f0f0;\n}`;\n"
  },
  {
    "path": "src/ext/modelist.js",
    "content": "/**\n * ## File mode detection utility\n *\n * Provides automatic detection of editor syntax modes based on file paths and extensions. Maps file extensions to\n * appropriate Ace Editor syntax highlighting modes for over 100 programming languages and file formats including\n * JavaScript, TypeScript, HTML, CSS, Python, Java, C++, and many others. Supports complex extension patterns and\n * provides fallback mechanisms for unknown file types.\n *\n * @module\n */\n\n\"use strict\";\n\n/**\n * Represents an array to store various syntax modes.\n *\n * @type {Mode[]}\n */\nvar modes = [];\n/**\n * Suggests a mode based on the file extension present in the given path\n * @param {string} path The path to the file\n * @returns {Mode} Returns an object containing information about the\n *  suggested mode.\n */\nfunction getModeForPath(path) {\n    var mode = modesByName.text;\n    var fileName = path.split(/[\\/\\\\]/).pop();\n    for (var i = 0; i < modes.length; i++) {\n        if (modes[i].supportsFile(fileName)) {\n            mode = modes[i];\n            break;\n        }\n    }\n    return mode;\n}\n\nclass Mode {\n    /**\n     * @param {string} name\n     * @param {string} caption\n     * @param {string} extensions\n     */\n    constructor(name, caption, extensions) {\n        this.name = name;\n        this.caption = caption;\n        this.mode = \"ace/mode/\" + name;\n        this.extensions = extensions;\n        var re;\n        if (/\\^/.test(extensions)) {\n            re = extensions.replace(/\\|(\\^)?/g, function (a, b) {\n                return \"$|\" + (b ? \"^\" : \"^.*\\\\.\");\n            }) + \"$\";\n        }\n        else {\n            re = \"\\\\.(\" + extensions + \")$\";\n        }\n\n        this.extRe = new RegExp(re, \"gi\");\n    }\n\n    /**\n     * @param {string} filename\n     * @returns {RegExpMatchArray | null}\n     */\n    supportsFile(filename) {\n        return filename.match(this.extRe);\n    }\n}\n\n// todo firstlinematch\nvar supportedModes = {\n    ABAP:        [\"abap\"],\n    ABC:         [\"abc\"],\n    ActionScript:[\"as\"],\n    ADA:         [\"ada|adb\"],\n    Alda:        [\"alda\"],\n    Apache_Conf: [\"^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd\"],\n    Apex:        [\"apex|cls|trigger|tgr\"],\n    AQL:         [\"aql\"],\n    AsciiDoc:    [\"asciidoc|adoc\"],\n    ASL:         [\"dsl|asl|asl.json\"],\n    Assembly_ARM32:[\"s\"],\n    Assembly_x86:[\"asm|a\"],\n    Astro:       [\"astro\"],\n    AutoHotKey:  [\"ahk\"],\n    Basic:       [\"bas|bak\"],\n    BatchFile:   [\"bat|cmd\"],\n    BibTeX:      [\"bib\"],\n    C_Cpp:       [\"cpp|c|cc|cxx|h|hh|hpp|ino\"],\n    C9Search:    [\"c9search_results\"],\n    Cirru:       [\"cirru|cr\"],\n    Clojure:     [\"clj|cljs\"],\n    Clue:        [\"clue\"],\n    Cobol:       [\"CBL|COB\"],\n    coffee:      [\"coffee|cf|cson|^Cakefile\"],\n    ColdFusion:  [\"cfm|cfc\"],\n    Crystal:     [\"cr\"],\n    CSharp:      [\"cs\"],\n    Csound_Document: [\"csd\"],\n    Csound_Orchestra: [\"orc\"],\n    Csound_Score: [\"sco\"],\n    CSS:         [\"css\"],\n    CSV:         [\"csv\"],\n    Curly:       [\"curly\"],\n    Cuttlefish:  [\"conf\"],\n    D:           [\"d|di\"],\n    Dart:        [\"dart\"],\n    Diff:        [\"diff|patch\"],\n    Django:      [\"djt|html.djt|dj.html|djhtml\"],\n    Dockerfile:  [\"^Dockerfile\"],\n    Dot:         [\"dot\"],\n    Drools:      [\"drl\"],\n    Edifact:     [\"edi\"],\n    Eiffel:      [\"e|ge\"],\n    EJS:         [\"ejs\"],\n    Elixir:      [\"ex|exs\"],\n    Elm:         [\"elm\"],\n    Erlang:      [\"erl|hrl\"],\n    Flix:        [\"flix\"],\n    Forth:       [\"frt|fs|ldr|fth|4th\"],\n    Fortran:     [\"f|f90\"],\n    FSharp:      [\"fsi|fs|ml|mli|fsx|fsscript\"],\n    FSL:         [\"fsl\"],\n    FTL:         [\"ftl\"],\n    Gcode:       [\"gcode\"],\n    Gherkin:     [\"feature\"],\n    Gitignore:   [\"^.gitignore\"],\n    Glsl:        [\"glsl|frag|vert\"],\n    Gobstones:   [\"gbs\"],\n    golang:      [\"go\"],\n    GraphQLSchema: [\"gql\"],\n    Groovy:      [\"groovy\"],\n    HAML:        [\"haml\"],\n    Handlebars:  [\"hbs|handlebars|tpl|mustache\"],\n    Haskell:     [\"hs\"],\n    Haskell_Cabal: [\"cabal\"],\n    haXe:        [\"hx\"],\n    Hjson:       [\"hjson\"],\n    HTML: [\"html|htm|xhtml|we|wpy\"],\n    HTML_Elixir: [\"eex|html.eex\"],\n    HTML_Ruby:   [\"erb|rhtml|html.erb\"],\n    INI:         [\"ini|conf|cfg|prefs\"],\n    Io:          [\"io\"],\n    Ion:         [\"ion\"],\n    Jack:        [\"jack\"],\n    Jade:        [\"jade|pug\"],\n    Java:        [\"java\"],\n    JavaScript:  [\"js|jsm|cjs|mjs\"],\n    JEXL:        [\"jexl\"],\n    JSON:        [\"json\"],\n    JSON5:       [\"json5\"],\n    JSONiq:      [\"jq\"],\n    JSP:         [\"jsp\"],\n    JSSM:        [\"jssm|jssm_state\"],\n    JSX:         [\"jsx\"],\n    Julia:       [\"jl\"],\n    Kotlin:      [\"kt|kts\"],\n    LaTeX:       [\"tex|latex|ltx|bib\"],\n    Latte:       [\"latte\"],\n    LESS:        [\"less\"],\n    Liquid:      [\"liquid\"],\n    Lisp:        [\"lisp\"],\n    LiveScript:  [\"ls\"],\n    LogiQL:      [\"logic|lql\"],\n    Logtalk:     [\"lgt\"],\n    LSL:         [\"lsl\"],\n    Lua:         [\"lua\"],\n    LuaPage:     [\"lp\"],\n    Lucene:      [\"lucene\"],\n    Makefile:    [\"^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make\"],\n    Markdown:    [\"md|markdown\"],\n    Mask:        [\"mask\"],\n    MATLAB:      [\"matlab\"],\n    Maze:        [\"mz\"],\n    MediaWiki:   [\"wiki|mediawiki\"],\n    MEL:         [\"mel\"],\n    MIPS:        [\"s|asm\"],\n    MIXAL:       [\"mixal\"],\n    MUSHCode:    [\"mc|mush\"],\n    MySQL:       [\"mysql\"],\n    Nasal:       [\"nas\"],\n    Nginx:       [\"nginx|conf\"],\n    Nim:         [\"nim\"],\n    Nix:         [\"nix\"],\n    NSIS:        [\"nsi|nsh\"],\n    Nunjucks:    [\"nunjucks|nunjs|nj|njk\"],\n    ObjectiveC:  [\"m|mm\"],\n    OCaml:       [\"ml|mli\"],\n    Odin:        [\"odin\"],\n    PartiQL:     [\"partiql|pql\"],\n    Pascal:      [\"pas|p\"],\n    Perl:        [\"pl|pm\"],\n    pgSQL:       [\"pgsql\"],\n    PHP:         [\"php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module\"],\n    PHP_Laravel_blade: [\"blade.php\"],\n    Pig:         [\"pig\"],\n    PLSQL:       [\"plsql\"],\n    Powershell:  [\"ps1\"],\n    Praat:       [\"praat|praatscript|psc|proc\"],\n    Prisma:      [\"prisma\"],\n    Prolog:      [\"plg|prolog\"],\n    Properties:  [\"properties\"],\n    Protobuf:    [\"proto\"],\n    PRQL:        [\"prql\"],\n    Puppet:      [\"epp|pp\"],\n    Python:      [\"py\"],\n    QML:         [\"qml\"],\n    R:           [\"r\"],\n    Raku:        [\"raku|rakumod|rakutest|p6|pl6|pm6\"],\n    Razor:       [\"cshtml|asp\"],\n    RDoc:        [\"Rd\"],\n    Red:         [\"red|reds\"],\n    RHTML:       [\"Rhtml\"],\n    Robot:       [\"robot|resource\"],\n    RST:         [\"rst\"],\n    Ruby:        [\"rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile\"],\n    Rust:        [\"rs\"],\n    SaC:         [\"sac\"],\n    SASS:        [\"sass\"],\n    SCAD:        [\"scad\"],\n    Scala:       [\"scala|sbt\"],\n    Scheme:      [\"scm|sm|rkt|oak|scheme\"],\n    Scrypt:      [\"scrypt\"],\n    SCSS:        [\"scss\"],\n    SH:          [\"sh|bash|^.bashrc\"],\n    SJS:         [\"sjs\"],\n    Slim:        [\"slim|skim\"],\n    Smarty:      [\"smarty|tpl\"],\n    Smithy:      [\"smithy\"],\n    snippets:    [\"snippets\"],\n    Soy_Template:[\"soy\"],\n    Space:       [\"space\"],\n    SPARQL:      [\"rq\"],\n    SQL:         [\"sql\"],\n    SQLServer:   [\"sqlserver\"],\n    Stylus:      [\"styl|stylus\"],\n    SVG:         [\"svg\"],\n    Swift:       [\"swift\"],\n    Tcl:         [\"tcl\"],\n    Terraform:   [\"tf\", \"tfvars\", \"terragrunt\"],\n    Tex:         [\"tex\"],\n    Text:        [\"txt\"],\n    Textile:     [\"textile\"],\n    Toml:        [\"toml\"],\n    TSV:         [\"tsv\"],\n    TSX:         [\"tsx\"],\n    Turtle:      [\"ttl\"],\n    Twig:        [\"twig|swig\"],\n    Typescript:  [\"ts|mts|cts|typescript|str\"],\n    Vala:        [\"vala\"],\n    VBScript:    [\"vbs|vb\"],\n    Velocity:    [\"vm\"],\n    Verilog:     [\"v|vh|sv|svh\"],\n    VHDL:        [\"vhd|vhdl\"],\n    Visualforce: [\"vfp|component|page\"],\n    Vue: [\"vue\"],\n    Wollok:      [\"wlk|wpgm|wtest\"],\n    XML:         [\"xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml\"],\n    XQuery:      [\"xq\"],\n    YAML:        [\"yaml|yml\"],\n    Zeek:        [\"zeek|bro\"],\n    Zig:         [\"zig\"]\n};\n\nvar nameOverrides = {\n    ObjectiveC: \"Objective-C\",\n    CSharp: \"C#\",\n    golang: \"Go\",\n    C_Cpp: \"C and C++\",\n    Csound_Document: \"Csound Document\",\n    Csound_Orchestra: \"Csound\",\n    Csound_Score: \"Csound Score\",\n    coffee: \"CoffeeScript\",\n    HTML_Ruby: \"HTML (Ruby)\",\n    HTML_Elixir: \"HTML (Elixir)\",\n    FTL: \"FreeMarker\",\n    PHP_Laravel_blade: \"PHP (Blade Template)\",\n    Perl6: \"Perl 6\",\n    AutoHotKey: \"AutoHotkey / AutoIt\"\n};\n\n/**\n * An object that serves as a mapping of mode names to their corresponding mode data.\n * The keys of this object are mode names (as strings), and the values are expected\n * to represent data associated with each mode.\n *\n * This structure can be used for quick lookups of mode information by name.\n * @type {Record<string, Mode>}\n */\nvar modesByName = {};\nfor (var name in supportedModes) {\n    var data = supportedModes[name];\n    var displayName = (nameOverrides[name] || name).replace(/_/g, \" \");\n    var filename = name.toLowerCase();\n    var mode = new Mode(filename, displayName, data[0]);\n    modesByName[filename] = mode;\n    modes.push(mode);\n}\n\nexports.getModeForPath = getModeForPath;\nexports.modes = modes;\nexports.modesByName = modesByName;"
  },
  {
    "path": "src/ext/options.js",
    "content": "/**\n * ## Settings Menu extension\n *\n * Provides a settings panel for configuring editor options through an interactive UI.\n * Creates a tabular interface with grouped configuration options including themes, modes, keybindings,\n * font settings, display preferences, and advanced editor behaviors. Supports dynamic option rendering\n * with various input types (dropdowns, checkboxes, number inputs, button bars) and real-time updates.\n *\n * **Usage:**\n * ```javascript\n * var OptionPanel = require(\"ace/ext/settings_menu\").OptionPanel;\n * var panel = new OptionPanel(editor);\n * panel.render();\n * ```\n *\n * @module\n */\n\n\n\"use strict\";\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\n\nrequire(\"./menu_tools/overlay_page\");\n\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar config = require(\"../config\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar buildDom = dom.buildDom;\n\nvar modelist = require(\"./modelist\");\nvar themelist = require(\"./themelist\");\n\nvar themes = { Bright: [], Dark: [] };\nthemelist.themes.forEach(function(x) {\n    themes[x.isDark ? \"Dark\" : \"Bright\"].push({ caption: x.caption, value: x.theme });\n});\n\nvar modes = modelist.modes.map(function(x){ \n    return { caption: x.caption, value: x.mode }; \n});\n\n\n/**\n * Configuration object for grouping various options/settings into categorized groups.\n *\n * Organizes settings into two main categories: \"Main\" and \"More\",\n * each containing settings for configurable features of an application.\n */\nvar optionGroups = {\n    Main: {\n        Mode: {\n            path: \"mode\",\n            type: \"select\",\n            items: modes\n        },\n        Theme: {\n            path: \"theme\",\n            type: \"select\",\n            items: themes\n        },\n        \"Keybinding\": {\n            type: \"buttonBar\",\n            path: \"keyboardHandler\",\n            items: [\n                { caption : \"Ace\", value : null },\n                { caption : \"Vim\", value : \"ace/keyboard/vim\" },\n                { caption : \"Emacs\", value : \"ace/keyboard/emacs\" },\n                { caption : \"Sublime\", value : \"ace/keyboard/sublime\" },\n                { caption : \"VSCode\", value : \"ace/keyboard/vscode\" }\n            ]\n        },\n        \"Font Size\": {\n            path: \"fontSize\",\n            type: \"number\",\n            defaultValue: 12,\n            defaults: [\n                {caption: \"12px\", value: 12},\n                {caption: \"24px\", value: 24}\n            ]\n        },\n        \"Soft Wrap\": {\n            type: \"buttonBar\",\n            path: \"wrap\",\n            items: [\n               { caption : \"Off\",  value : \"off\" },\n               { caption : \"View\", value : \"free\" },\n               { caption : \"margin\", value : \"printMargin\" },\n               { caption : \"40\",   value : \"40\" }\n            ]\n        },\n        \"Cursor Style\": {\n            path: \"cursorStyle\",\n            items: [\n               { caption : \"Ace\",    value : \"ace\" },\n               { caption : \"Slim\",   value : \"slim\" },\n               { caption : \"Smooth\", value : \"smooth\" },\n               { caption : \"Smooth And Slim\", value : \"smooth slim\" },\n               { caption : \"Wide\",   value : \"wide\" }\n            ]\n        },\n        \"Folding\": {\n            path: \"foldStyle\",\n            items: [\n                { caption : \"Manual\", value : \"manual\" },\n                { caption : \"Mark begin\", value : \"markbegin\" },\n                { caption : \"Mark begin and end\", value : \"markbeginend\" }\n            ]\n        },\n        \"Soft Tabs\": [{\n            path: \"useSoftTabs\"\n        }, {\n            ariaLabel: \"Tab Size\",\n            path: \"tabSize\",\n            type: \"number\",\n            values: [2, 3, 4, 8, 16]\n        }],\n        \"Overscroll\": {\n            type: \"buttonBar\",\n            path: \"scrollPastEnd\",\n            items: [\n               { caption : \"None\",  value : 0 },\n               { caption : \"Half\",   value : 0.5 },\n               { caption : \"Full\",   value : 1 }\n            ]\n        }\n    },\n    More: {\n        \"Atomic soft tabs\": {\n            path: \"navigateWithinSoftTabs\"\n        },\n        \"Enable Behaviours\": {\n            path: \"behavioursEnabled\"\n        },\n        \"Wrap with quotes\": {\n            path: \"wrapBehavioursEnabled\"\n        },\n        \"Enable Auto Indent\": {\n            path: \"enableAutoIndent\"\n        },\n        \"Full Line Selection\": {\n            type: \"checkbox\",\n            values: \"text|line\",\n            path: \"selectionStyle\"\n        },\n        \"Highlight Active Line\": {\n            path: \"highlightActiveLine\"\n        },\n        \"Show Invisibles\": {\n            path: \"showInvisibles\"\n        },\n        \"Show Indent Guides\": {\n            path: \"displayIndentGuides\"\n        },\n        \"Highlight Indent Guides\": {\n            path: \"highlightIndentGuides\"\n        },\n        \"Persistent HScrollbar\": {\n            path: \"hScrollBarAlwaysVisible\"\n        },\n        \"Persistent VScrollbar\": {\n            path: \"vScrollBarAlwaysVisible\"\n        },\n        \"Animate scrolling\": {\n            path: \"animatedScroll\"\n        },\n        \"Show Gutter\": {\n            path: \"showGutter\"\n        },\n        \"Show Line Numbers\": {\n            path: \"showLineNumbers\"\n        },\n        \"Relative Line Numbers\": {\n            path: \"relativeLineNumbers\"\n        },\n        \"Fixed Gutter Width\": {\n            path: \"fixedWidthGutter\"\n        },\n        \"Show Print Margin\": [{\n            path: \"showPrintMargin\"\n        }, {\n            ariaLabel: \"Print Margin\",\n            type: \"number\",\n            path: \"printMarginColumn\"\n        }],\n        \"Indented Soft Wrap\": {\n            path: \"indentedSoftWrap\"\n        },\n        \"Highlight selected word\": {\n            path: \"highlightSelectedWord\"\n        },\n        \"Fade Fold Widgets\": {\n            path: \"fadeFoldWidgets\"\n        },\n        \"Use textarea for IME\": {\n            path: \"useTextareaForIME\"\n        },\n        \"Merge Undo Deltas\": {\n            path: \"mergeUndoDeltas\",\n            items: [\n               { caption : \"Always\",  value : \"always\" },\n               { caption : \"Never\",   value : \"false\" },\n               { caption : \"Timed\",   value : \"true\" }\n            ]\n        },\n        \"Elastic Tabstops\": {\n            path: \"useElasticTabstops\"\n        },\n        \"Incremental Search\": {\n            path: \"useIncrementalSearch\"\n        },\n        \"Read-only\": {\n            path: \"readOnly\"\n        },\n        \"Copy without selection\": {\n            path: \"copyWithEmptySelection\"\n        },\n        \"Live Autocompletion\": {\n            path: \"enableLiveAutocompletion\"\n        },\n        \"Custom scrollbar\": {\n            path: \"customScrollbar\"\n        },\n        \"Use SVG gutter icons\": {\n            path: \"useSvgGutterIcons\"\n        },\n        \"Annotations for folded lines\": {\n            path: \"showFoldedAnnotations\"\n        },\n        \"Keyboard Accessibility Mode\": {\n            path: \"enableKeyboardAccessibility\"\n        }\n    }\n};\n\n/**\n * Option panel component for configuring settings or options.\n * The panel is designed to integrate with an editor and render various UI controls based on provided configuration.\n */\nclass OptionPanel {\n    /**\n     * \n     * @param {Editor} editor\n     * @param {HTMLElement} [element]\n     */\n    constructor(editor, element) {\n        this.editor = editor;\n        this.container = element || document.createElement(\"div\");\n        this.groups = [];\n        this.options = {};\n    }\n    \n    add(config) {\n        if (config.Main)\n            oop.mixin(optionGroups.Main, config.Main);\n        if (config.More)\n            oop.mixin(optionGroups.More, config.More);\n    }\n\n  \n    render() {\n        this.container.innerHTML = \"\";\n        buildDom([\"table\", {role: \"presentation\", id: \"controls\"}, \n            this.renderOptionGroup(optionGroups.Main),\n            [\"tr\", null, [\"td\", {colspan: 2},\n                [\"table\", {role: \"presentation\", id: \"more-controls\"}, \n                    this.renderOptionGroup(optionGroups.More)\n                ]\n            ]],\n            [\"tr\", null, [\"td\", {colspan: 2}, \"version \" + config.version]]\n        ], this.container);\n    }\n    \n    renderOptionGroup(group) {\n        return Object.keys(group).map(function(key, i) {\n            var item = group[key];\n            if (!item.position)\n                item.position = i / 10000;\n            if (!item.label)\n                item.label = key;\n            return item;\n        }).sort(function(a, b) {\n            return a.position - b.position;\n        }).map(function(item) {\n            return this.renderOption(item.label, item);\n        }, this);\n    }\n\n    /**\n     * @param {string} key\n     * @param {Object} option\n     */\n    renderOptionControl(key, option) {\n        var self = this;\n        if (Array.isArray(option)) {\n            return option.map(function(x) {\n                return self.renderOptionControl(key, x);\n            });\n        }\n        /**@type {any}*/\n        var control;\n        \n        var value = self.getOption(option);\n        \n        if (option.values && option.type != \"checkbox\") {\n            if (typeof option.values == \"string\")\n                option.values = option.values.split(\"|\");\n            option.items = option.values.map(function(v) {\n                return { value: v, name: v };\n            });\n        }\n        \n        if (option.type == \"buttonBar\") {\n            control = [\"div\", {role: \"group\", \"aria-labelledby\": option.path + \"-label\"}, option.items.map(function(item) {\n                return [\"button\", { \n                    value: item.value, \n                    ace_selected_button: value == item.value, \n                    'aria-pressed': value == item.value, \n                    onclick: function() {\n                        self.setOption(option, item.value);\n                        var nodes = this.parentNode.querySelectorAll(\"[ace_selected_button]\");\n                        for (var i = 0; i < nodes.length; i++) {\n                            nodes[i].removeAttribute(\"ace_selected_button\");\n                            nodes[i].setAttribute(\"aria-pressed\", false);\n                        }\n                        this.setAttribute(\"ace_selected_button\", true);\n                        this.setAttribute(\"aria-pressed\", true);\n                    } \n                }, item.desc || item.caption || item.name];\n            })];\n        } else if (option.type == \"number\") {\n            control = [\"input\", {type: \"number\", value: value || option.defaultValue, style:\"width:3em\", oninput: function() {\n                self.setOption(option, parseInt(this.value));\n            }}];\n            if (option.ariaLabel) {\n                control[1][\"aria-label\"] = option.ariaLabel;\n            } else {\n                control[1].id = key;\n            }\n            if (option.defaults) {\n                control = [control, option.defaults.map(function(item) {\n                    return [\"button\", {onclick: function() {\n                        var input = this.parentNode.firstChild;\n                        input.value = item.value;\n                        input.oninput();\n                    }}, item.caption];\n                })];\n            }\n        } else if (option.items) {\n            var buildItems = function(items) {\n                return items.map(function(item) {\n                    return [\"option\", { value: item.value || item.name }, item.desc || item.caption || item.name];\n                });\n            };\n            \n            var items = Array.isArray(option.items) \n                ? buildItems(option.items)\n                : Object.keys(option.items).map(function(key) {\n                    return [\"optgroup\", {\"label\": key}, buildItems(option.items[key])];\n                });\n            control = [\"select\", { id: key, value: value, onchange: function() {\n                self.setOption(option, this.value);\n            } }, items];\n        } else {\n            if (typeof option.values == \"string\")\n                option.values = option.values.split(\"|\");\n            if (option.values) value = value == option.values[1];\n            control = [\"input\", { type: \"checkbox\", id: key, checked: value || null, onchange: function() {\n                var value = this.checked;\n                if (option.values) value = option.values[value ? 1 : 0];\n                self.setOption(option, value);\n            }}];\n            if (option.type == \"checkedNumber\") {\n                control = [control, []];\n            }\n        }\n        return control;\n    }\n\n    /**\n     * \n     * @param key\n     * @param option\n     */\n    renderOption(key, option) {\n        if (option.path && !option.onchange && !this.editor.$options[option.path])\n            return;\n        var path = Array.isArray(option) ? option[0].path : option.path;\n        this.options[path] = option;\n        var safeKey = \"-\" + path;\n        var safeId = path + \"-label\";\n        var control = this.renderOptionControl(safeKey, option);\n        return [\"tr\", {class: \"ace_optionsMenuEntry\"}, [\"td\",\n            [\"label\", {for: safeKey, id: safeId}, key]\n        ], [\"td\", control]];\n    }\n\n    /**\n     * @param {string | number | Object} option\n     * @param {string | number | boolean} value\n     */\n    setOption(option, value) {\n        if (typeof option == \"string\")\n            option = this.options[option];\n        if (value == \"false\") value = false;\n        if (value == \"true\") value = true;\n        if (value == \"null\") value = null;\n        if (value == \"undefined\") value = undefined;\n        if (typeof value == \"string\" && parseFloat(value).toString() == value)\n            value = parseFloat(value);\n        if (option.onchange)\n            option.onchange(value);\n        else if (option.path)\n            this.editor.setOption(option.path, value);\n        this._signal(\"setOption\", {name: option.path, value: value});\n    }\n    \n    getOption(option) {\n        if (option.getValue)\n            return option.getValue();\n        return this.editor.getOption(option.path);\n    }\n}\noop.implement(OptionPanel.prototype, EventEmitter);\n\nexports.OptionPanel = OptionPanel;\nexports.optionGroups = optionGroups;\n"
  },
  {
    "path": "src/ext/prompt.js",
    "content": "/**\n * ## User Input Prompt extension\n *\n * Provides customizable modal prompts for gathering user input with support for autocompletion, validation, and\n * specialized input types. Includes built-in prompt types for navigation (goto line), command palette, and mode\n * selection, with extensible architecture for custom prompt implementations.\n *\n * **Built-in Prompt Types:**\n * - `gotoLine`: Navigate to specific line numbers with selection support\n * - `commands`: Command palette with searchable editor commands and shortcuts\n * - `modes`: Language mode selector with filtering capabilities\n *\n * **Usage:**\n * ```javascript\n * // Basic prompt\n * prompt(editor, \"Default value\", {\n *   placeholder: \"Enter text...\",\n *   onAccept: (data) => console.log(data.value)\n * });\n *\n * // Built-in prompts\n * prompt.gotoLine(editor);\n * prompt.commands(editor);\n * prompt.modes(editor);\n * ```\n *\n * @module\n */\n\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\n\n\"use strict\";\n\nvar nls = require(\"../config\").nls;\nvar Range = require(\"../range\").Range;\nvar dom = require(\"../lib/dom\");\nvar FilteredList= require(\"../autocomplete\").FilteredList;\nvar AcePopup = require('../autocomplete/popup').AcePopup;\nvar $singleLineEditor = require('../autocomplete/popup').$singleLineEditor;\nvar UndoManager = require(\"../undomanager\").UndoManager;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar overlayPage = require(\"./menu_tools/overlay_page\").overlayPage;\nvar modelist = require(\"./modelist\");\nvar openPrompt;\n\n/**\n * @typedef PromptOptions\n * @property {String} name             Prompt name.\n * @property {String} $type            Use prompt of specific type (gotoLine|commands|modes or default if empty).\n * @property {[number, number]} selection  Defines which part of the predefined value should be highlighted.\n * @property {Boolean} hasDescription  Set to true if prompt has description below input box.\n * @property {String} prompt           Description below input box.\n * @property {String} placeholder      Placeholder for value.\n * @property {Object} $rules           Specific rules for input like password or regexp.\n * @property {Boolean} ignoreFocusOut  Set to true to keep the prompt open when focus moves to another part of the editor.\n * @property {Function} getCompletions Function for defining list of options for value.\n * @property {Function} getPrefix      Function for defining current value prefix.\n * @property {Function} onAccept       Function called when Enter is pressed.\n * @property {Function} onInput        Function called when input is added to prompt input box.\n * @property {Function} onCancel       Function called when Esc|Shift-Esc is pressed.\n * @property {Function} history        Function for defining history list.\n * @property {number} maxHistoryCount\n * @property {Function} addToHistory\n */\n\n/**\n * Prompt plugin is used for getting input from user.\n *\n * @param {Editor} editor                   Ouside editor related to this prompt. Will be blurred when prompt is open.\n * @param {String | Partial<PromptOptions>} message                  Predefined value of prompt input box.\n * @param {Partial<PromptOptions>} options                  Cusomizable options for this prompt.\n * @param {Function} [callback]               Function called after done.\n * */\nfunction prompt(editor, message, options, callback) {\n    if (typeof message == \"object\") {\n        // @ts-ignore\n        return prompt(editor, \"\", message, options);\n    }\n    if (openPrompt) {\n        var lastPrompt = openPrompt;\n        editor = lastPrompt.editor;\n        lastPrompt.close();\n        if (lastPrompt.name && lastPrompt.name == options.name)\n            return;\n    }\n    if (options.$type)\n       return prompt[options.$type](editor, callback);\n\n    var cmdLine = $singleLineEditor();\n    cmdLine.session.setUndoManager(new UndoManager());\n\n    /**@type {any}*/\n    var el = dom.buildDom([\"div\", {class: \"ace_prompt_container\" + (options.hasDescription ? \" input-box-with-description\" : \"\")}]);\n    var overlay = overlayPage(editor, el, done);\n    el.appendChild(cmdLine.container);\n\n    if (editor) {\n        editor.cmdLine = cmdLine;\n        cmdLine.setOption(\"fontSize\", editor.getOption(\"fontSize\"));\n    }\n    if (message) {\n        cmdLine.setValue(message, 1);\n    }\n    if (options.selection) {\n        cmdLine.selection.setRange({\n            start: cmdLine.session.doc.indexToPosition(options.selection[0]),\n            end: cmdLine.session.doc.indexToPosition(options.selection[1])\n        });\n    }\n\n    if (options.getCompletions) {\n        var popup = new AcePopup();\n        popup.renderer.setStyle(\"ace_autocomplete_inline\");\n        popup.container.style.display = \"block\";\n        popup.container.style.maxWidth = \"600px\";\n        popup.container.style.width = \"100%\";\n        popup.container.style.marginTop = \"3px\";\n        popup.renderer.setScrollMargin(2, 2, 0, 0);\n        popup.autoSelect = false;\n        popup.renderer.$maxLines = 15;\n        popup.setRow(-1);\n        popup.on(\"click\", function(e) {\n            var data = popup.getData(popup.getRow());\n            if (!data[\"error\"]) {\n                cmdLine.setValue(data.value || data[\"name\"] || data);\n                accept();\n                e.stop();\n            }\n        });\n        el.appendChild(popup.container);\n        updateCompletions();\n    }\n\n    if (options.$rules) {\n        var tokenizer = new Tokenizer(options.$rules);\n        cmdLine.session.bgTokenizer.setTokenizer(tokenizer);\n    }\n\n    if (options.placeholder) {\n        cmdLine.setOption(\"placeholder\", options.placeholder);\n    }\n\n    if (options.hasDescription) {\n        /**@type {any}*/\n        var promptTextContainer = dom.buildDom([\"div\", {class: \"ace_prompt_text_container\"}]);\n        dom.buildDom(options.prompt || \"Press 'Enter' to confirm or 'Escape' to cancel\", promptTextContainer);\n        el.appendChild(promptTextContainer);\n    }\n\n    overlay.setIgnoreFocusOut(options.ignoreFocusOut);\n\n    function accept() {\n        var val;\n        if (popup && popup.getCursorPosition().row > 0) {\n            val = valueFromRecentList();\n        } else {\n            val = cmdLine.getValue();\n        }\n        var curData = popup ? popup.getData(popup.getRow()) : val;\n        if (curData && !curData[\"error\"]) {\n            done();\n            options.onAccept && options.onAccept({\n                value: val,\n                item: curData\n            }, cmdLine);\n        }\n    }\n\n    var keys = {\n        \"Enter\": accept,\n        \"Esc|Shift-Esc\": function() {\n            options.onCancel && options.onCancel(cmdLine.getValue(), cmdLine);\n            done();\n        }\n    };\n\n    if (popup) {\n        Object.assign(keys, {\n            \"Up\": function(editor) { popup.goTo(\"up\"); valueFromRecentList();},\n            \"Down\": function(editor) { popup.goTo(\"down\"); valueFromRecentList();},\n            \"Ctrl-Up|Ctrl-Home\": function(editor) { popup.goTo(\"start\"); valueFromRecentList();},\n            \"Ctrl-Down|Ctrl-End\": function(editor) { popup.goTo(\"end\"); valueFromRecentList();},\n            \"Tab\": function(editor) {\n                popup.goTo(\"down\"); valueFromRecentList();\n            },\n            \"PageUp\": function(editor) { popup.gotoPageUp(); valueFromRecentList();},\n            \"PageDown\": function(editor) { popup.gotoPageDown(); valueFromRecentList();}\n        });\n    }\n\n    cmdLine.commands.bindKeys(keys);\n\n    function done() {\n        overlay.close();\n        callback && callback();\n        openPrompt = null;\n    }\n\n    cmdLine.on(\"input\", function() {\n        options.onInput && options.onInput();\n        updateCompletions();\n    });\n\n    function updateCompletions() {\n        if (options.getCompletions) {\n            var prefix;\n            if (options.getPrefix) {\n                prefix = options.getPrefix(cmdLine);\n            }\n\n            var completions = options.getCompletions(cmdLine);\n            popup.setData(completions, prefix);\n            popup.resize(true);\n        }\n    }\n\n    function valueFromRecentList() {\n        var current = popup.getData(popup.getRow());\n        if (current && !current[\"error\"])\n            return current.value || current.caption || current;\n    }\n\n    cmdLine.resize(true);\n    if (popup) {\n        popup.resize(true);\n    }\n    cmdLine.focus();\n\n    openPrompt = {\n        close: done,\n        name: options.name,\n        editor: editor\n    };\n}\n\n/**\n * Displays a \"Go to Line\" prompt for navigating to specific line and column positions with selection support.\n *\n * @param {Editor} editor - The editor instance to navigate within\n * @param {Function} [callback]\n */\nprompt.gotoLine = function(editor, callback) {\n    function stringifySelection(selection) {\n        if (!Array.isArray(selection))\n            selection = [selection];\n        return selection.map(function(r) {\n            var cursor = r.isBackwards ? r.start: r.end;\n            var anchor = r.isBackwards ? r.end: r.start;\n            var row = anchor.row;\n            var s = (row + 1) + \":\" + anchor.column;\n\n            if (anchor.row == cursor.row) {\n                if (anchor.column != cursor.column)\n                    s += \">\" + \":\" + cursor.column;\n            } else {\n                s += \">\" + (cursor.row + 1) + \":\" + cursor.column;\n            }\n            return s;\n        }).reverse().join(\", \");\n    }\n\n    prompt(editor, \":\" + stringifySelection(editor.selection.toJSON()), {\n        name: \"gotoLine\",\n        selection: [1, Number.MAX_VALUE],\n        onAccept: function(data) {\n            var value = data.value;\n            var _history = prompt.gotoLine[\"_history\"];\n            if (!_history)\n                prompt.gotoLine[\"_history\"] = _history = [];\n            if (_history.indexOf(value) != -1)\n                _history.splice(_history.indexOf(value), 1);\n            _history.unshift(value);\n            if (_history.length > 20) _history.length = 20;\n            \n            \n            var pos = editor.getCursorPosition();\n            var ranges = [];\n            value.replace(/^:/, \"\").split(/,/).map(function(str) {\n                var parts = str.split(/([<>:+-]|c?\\d+)|[^c\\d<>:+-]+/).filter(Boolean);\n                var i = 0;\n                function readPosition() {\n                    var c = parts[i++];\n                    if (!c) return;\n                    if (c[0] == \"c\") {\n                        var index = parseInt(c.slice(1)) || 0;\n                        return editor.session.doc.indexToPosition(index);\n                    }\n                    var row = pos.row;\n                    var column = 0;\n                    if (/\\d/.test(c)) {\n                        row = parseInt(c) - 1;\n                        c = parts[i++];\n                    }\n                    if (c == \":\") {\n                        c = parts[i++];\n                        if (/\\d/.test(c)) {\n                            column = parseInt(c) || 0;\n                        }\n                    }\n                    return {row: row, column: column};\n                }\n                pos = readPosition();\n                var range = Range.fromPoints(pos, pos);\n                if (parts[i] == \">\") {\n                    i++;\n                    range.end = readPosition();\n                }\n                else if (parts[i] == \"<\") {\n                    i++;\n                    range.start = readPosition();\n                }\n                ranges.unshift(range);\n            });\n            editor.selection.fromJSON(ranges);\n            var scrollTop = editor.renderer.scrollTop;\n            editor.renderer.scrollSelectionIntoView(\n                editor.selection.anchor, \n                editor.selection.cursor, \n                0.5\n            );\n            editor.renderer.animateScrolling(scrollTop);\n        },\n        history: function() {\n            if (!prompt.gotoLine[\"_history\"])\n                return [];\n            return prompt.gotoLine[\"_history\"];\n\n        },\n        getCompletions: function(cmdLine) {\n            var value = cmdLine.getValue();\n            var m = value.replace(/^:/, \"\").split(\":\");\n            var row = Math.min(parseInt(m[0]) || 1, editor.session.getLength()) - 1;\n            var line = editor.session.getLine(row);\n            var current = value + \"  \" + line;\n            return [current].concat(this.history());\n        },\n        $rules: {\n            start: [{\n                regex: /\\d+/,\n                token: \"string\"\n            }, {\n                regex: /[:,><+\\-c]/,\n                token: \"keyword\"\n            }]\n        }\n    });\n};\n\n/**\n * Displays a searchable command palette for executing editor commands with keyboard shortcuts and history.\n *\n * @param {Editor} editor - The editor instance to execute commands on\n * @param {Function} [callback]\n */\nprompt.commands = function(editor, callback) {\n    function normalizeName(name) {\n        return (name || \"\").replace(/^./, function(x) {\n            return x.toUpperCase(x);\n        }).replace(/[a-z][A-Z]/g, function(x) {\n            return x[0] + \" \" + x[1].toLowerCase(x);\n        });\n    }\n    function getEditorCommandsByName(excludeCommands) {\n        var commandsByName = [];\n        var commandMap = {};\n        editor.keyBinding.$handlers.forEach(function(handler) {\n            var platform = handler[\"platform\"];\n            var cbn = handler[\"byName\"];\n            for (var i in cbn) {\n                var key = cbn[i].bindKey;\n                if (typeof key !== \"string\") {\n                    key = key && key[platform] || \"\";\n                }\n                var commands = cbn[i];\n                var description = commands.description || normalizeName(commands.name);\n                if (!Array.isArray(commands))\n                    commands = [commands];\n                commands.forEach(function(command) {\n                    if (typeof command != \"string\")\n                        command = command.name;\n                    var needle = excludeCommands.find(function(el) {\n                        return el === command;\n                    });\n                    if (!needle) {\n                        if (commandMap[command]) {\n                            commandMap[command].key += \"|\" + key;\n                        } else {\n                            commandMap[command] = {key: key, command: command, description: description};\n                            commandsByName.push(commandMap[command]);\n                        }\n                    }\n                });\n            }\n        });\n        return commandsByName;\n    }\n    // exclude commands that can not be executed without args\n    var excludeCommandsList = [\"insertstring\", \"inserttext\", \"setIndentation\", \"paste\"];\n    var shortcutsArray = getEditorCommandsByName(excludeCommandsList);\n    shortcutsArray = shortcutsArray.map(function(item) {\n        return {value: item.description, meta: item.key, command: item.command};\n    });\n    prompt(editor, \"\",  {\n        name: \"commands\",\n        selection: [0, Number.MAX_VALUE],\n        maxHistoryCount: 5,\n        onAccept: function(data) {\n            if (data.item) {\n                var commandName = data.item.command;\n                this.addToHistory(data.item);\n\n                editor.execCommand(commandName);\n            }\n        },\n        addToHistory: function(item) {\n            var history = this.history();\n            history.unshift(item);\n            delete item.message;\n            for (var i = 1; i < history.length; i++) {\n                if (history[i][\"command\"] == item.command ) {\n                    history.splice(i, 1);\n                    break;\n                }\n            }\n            if (this.maxHistoryCount > 0 && history.length > this.maxHistoryCount) {\n                history.splice(history.length - 1, 1);\n            }\n            prompt.commands[\"history\"] = history;\n        },\n        history: function() {\n            return prompt.commands[\"history\"] || [];\n        },\n        getPrefix: function(cmdLine) {\n            var currentPos = cmdLine.getCursorPosition();\n            var filterValue = cmdLine.getValue();\n            return filterValue.substring(0, currentPos.column);\n        },\n        getCompletions: function(cmdLine) {\n            function getFilteredCompletions(commands, prefix) {\n                var resultCommands = JSON.parse(JSON.stringify(commands));\n\n                var filtered = new FilteredList(resultCommands);\n                return filtered.filterCompletions(resultCommands, prefix);\n            }\n\n            function getUniqueCommandList(commands, usedCommands) {\n                if (!usedCommands || !usedCommands.length) {\n                    return commands;\n                }\n                var excludeCommands = [];\n                usedCommands.forEach(function(item) {\n                    excludeCommands.push(item.command);\n                });\n\n                var resultCommands = [];\n\n                commands.forEach(function(item) {\n                    if (excludeCommands.indexOf(item.command) === -1) {\n                        resultCommands.push(item);\n                    }\n                });\n\n                return resultCommands;\n            }\n\n            var prefix = this.getPrefix(cmdLine);\n            var recentlyUsedCommands = getFilteredCompletions(this.history(), prefix);\n            var otherCommands = getUniqueCommandList(shortcutsArray, recentlyUsedCommands);\n            otherCommands = getFilteredCompletions(otherCommands, prefix);\n\n            if (recentlyUsedCommands.length && otherCommands.length) {\n                recentlyUsedCommands[0].message = nls(\"prompt.recently-used\", \"Recently used\");\n                otherCommands[0].message = nls(\"prompt.other-commands\", \"Other commands\");\n            }\n\n            var completions = recentlyUsedCommands.concat(otherCommands);\n            return completions.length > 0 ? completions : [{\n                value: nls(\"prompt.no-matching-commands\", \"No matching commands\"),\n                error: 1\n            }];\n        }\n    });\n};\n\n/**\n * Shows an interactive prompt containing all available syntax highlighting modes\n * that can be applied to the editor session. Users can type to filter through the modes list\n * and select one to change the editor's syntax highlighting mode. The prompt includes real-time\n * filtering based on mode names and captions.\n *\n * @param {Editor} editor - The editor instance to change the language mode for\n * @param {Function} [callback]\n */\n\nprompt.modes = function(editor, callback) {\n    /**@type {any[]}*/\n    var modesArray = modelist.modes;\n    modesArray = modesArray.map(function(item) {\n        return {value: item.caption, mode: item.name};\n    });\n    prompt(editor, \"\",  {\n        name: \"modes\",\n        selection: [0, Number.MAX_VALUE],\n        onAccept: function(data) {\n            if (data.item) {\n                var modeName = \"ace/mode/\" + data.item.mode;\n                editor.session.setMode(modeName);\n            }\n        },\n        getPrefix: function(cmdLine) {\n            var currentPos = cmdLine.getCursorPosition();\n            var filterValue = cmdLine.getValue();\n            return filterValue.substring(0, currentPos.column);\n        },\n        getCompletions: function(cmdLine) {\n            function getFilteredCompletions(modes, prefix) {\n                var resultCommands = JSON.parse(JSON.stringify(modes));\n\n                var filtered = new FilteredList(resultCommands);\n                return filtered.filterCompletions(resultCommands, prefix);\n            }\n\n            var prefix = this.getPrefix(cmdLine);\n            var completions = getFilteredCompletions(modesArray, prefix);\n            return completions.length > 0 ? completions : [{\n                \"caption\": \"No mode matching\",\n                \"value\": \"No mode matching\",\n                \"error\": 1\n            }];\n        }\n    });\n};\n\ndom.importCssString(`.ace_prompt_container {\n    max-width: 603px;\n    width: 100%;\n    margin: 20px auto;\n    padding: 3px;\n    background: white;\n    border-radius: 2px;\n    box-shadow: 0px 2px 3px 0px #555;\n}`, \"promtp.css\", false);\n\n\nexports.prompt = prompt;\n"
  },
  {
    "path": "src/ext/rtl.js",
    "content": "/**\n * ## Right-to-Left (RTL) text support extension\n *\n * Provides bidirectional text support enabling proper rendering and editing of RTL languages such as Arabic, Hebrew,\n * and Persian. Handles text direction detection, cursor positioning, and ensures correct visual behavior for mixed\n * LTR/RTL content. Includes keyboard shortcuts for manual text direction control and automatic\n * RLE (Right-to-Left Embedding) marker management.\n *\n * **Configuration Options:**\n * - `rtlText`: Enable automatic RTL text detection and handling\n * - `rtl`: Force RTL direction for the entire editor\n *\n * **Keyboard Shortcuts:**\n * - `Ctrl-Alt-Shift-L` (Win) / `Cmd-Alt-Shift-L` (Mac): Force left-to-right direction\n * - `Ctrl-Alt-Shift-R` (Win) / `Cmd-Alt-Shift-R` (Mac): Force right-to-left direction\n *\n * **Usage:**\n * ```javascript\n * editor.setOptions({\n *   rtlText: true,  // Enable automatic RTL detection\n *   rtl: false      // Or force RTL direction\n * });\n * ```\n *\n * @module\n */\n\n\n\"use strict\";\n\nvar commands = [{\n    name: \"leftToRight\",\n    bindKey: { win: \"Ctrl-Alt-Shift-L\", mac: \"Command-Alt-Shift-L\" },\n    exec: function(editor) {\n        editor.session.$bidiHandler.setRtlDirection(editor, false);\n    },\n    readOnly: true\n}, {\n    name: \"rightToLeft\",\n    bindKey: { win: \"Ctrl-Alt-Shift-R\",  mac: \"Command-Alt-Shift-R\" },\n    exec: function(editor) {\n        editor.session.$bidiHandler.setRtlDirection(editor, true);\n    },\n    readOnly: true\n}];\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    rtlText: {\n        set: function(val) {\n            if (val) {\n                this.on(\"change\", onChange);\n                this.on(\"changeSelection\", onChangeSelection);\n                this.renderer.on(\"afterRender\", updateLineDirection);\n                this.commands.on(\"exec\", onCommandEmitted);\n                this.commands.addCommands(commands);\n            } else {\n                this.off(\"change\", onChange);\n                this.off(\"changeSelection\", onChangeSelection);\n                this.renderer.off(\"afterRender\", updateLineDirection);\n                this.commands.off(\"exec\", onCommandEmitted);\n                this.commands.removeCommands(commands);\n                clearTextLayer(this.renderer);\n            }\n            this.renderer.updateFull();\n        }\n    },\n    rtl: {\n        set: function(val) {\n            this.session.$bidiHandler.$isRtl = val;\n            if (val) {\n                this.setOption(\"rtlText\", false);\n                this.renderer.on(\"afterRender\", updateLineDirection);\n                this.session.$bidiHandler.seenBidi = true;\n            } else {\n                this.renderer.off(\"afterRender\", updateLineDirection);\n                clearTextLayer(this.renderer);\n            }\n            this.renderer.updateFull();\n        }\n    }\n});\n\n/**\n * Whenever the selection is changed, prevent cursor (lead) to be positioned at\n * position 0 of right-to-left line in order to maintain the RLE marker at this position.\n * When cursor reaches position 0, either advance it to position 1 of current line (default) \n * or to last position of previous line (if it comes from position 1 as the result of commands\n * mentioned in 'onCommandEmitted' event handler).\n * This serves few purposes:\n * - ensures cursor visual movement as if RLE mark doesn't exist.\n * - prevents character insertion before RLE mark.\n * - prevents RLE mark removal when 'delete' is pressed when cursot stays at position 0.         \n * - ensures RLE mark removal on line merge, when 'delete' is pressed and cursor stays \n *   at last position of previous line and when 'backspace' is pressed and cursor  stays at\n *   first position of current line. This is achived by hacking range boundaries on 'remove' operation.\n * @param {any} e\n * @param {Editor} editor\n */\nfunction onChangeSelection(e, editor) {\n    var lead = editor.getSelection().lead;\n    if (editor.session.$bidiHandler.isRtlLine(lead.row)) {\n        if (lead.column === 0) {\n            if (editor.session.$bidiHandler.isMoveLeftOperation && lead.row > 0) {\n                editor.getSelection().moveCursorTo(lead.row - 1, editor.session.getLine(lead.row - 1).length);\n            } else {\n                if (editor.getSelection().isEmpty())\n                    lead.column += 1;\n                else\n                    lead.setPosition(lead.row, lead.column + 1);\n            }\n        }\n    }\n}\n\nfunction onCommandEmitted(commadEvent) {\n    commadEvent.editor.session.$bidiHandler.isMoveLeftOperation = /gotoleft|selectleft|backspace|removewordleft/.test(commadEvent.command.name);\n}\n\n/**\n * Whenever the document is changed make sure that line break operatin\n * on right-to-left line (like pressing Enter or pasting multi-line text)\n * produces new right-to-left lines\n * @param {import(\"../../ace-internal\").Ace.Delta} delta\n * @param {Editor} editor\n */\nfunction onChange(delta, editor) {\n    var session = editor.session;\n    session.$bidiHandler.currentRow = null;\n    if (session.$bidiHandler.isRtlLine(delta.start.row) && delta.action === 'insert' && delta.lines.length > 1) {\n        for (var row = delta.start.row; row < delta.end.row; row++) {\n            if (session.getLine(row + 1).charAt(0) !== session.$bidiHandler.RLE)\n                session.doc.$lines[row + 1] = session.$bidiHandler.RLE + session.getLine(row + 1);\n        }\n    }\n}\n\n/**\n * @param {any} e\n * @param {import(\"../virtual_renderer\").VirtualRenderer} renderer\n */\nfunction updateLineDirection(e, renderer) {\n    var session = renderer.session;\n    var $bidiHandler = session.$bidiHandler;\n    var cells = renderer.$textLayer.$lines.cells;\n    var width = renderer.layerConfig.width - renderer.layerConfig.padding + \"px\";\n    cells.forEach(function(cell) {\n        var style = cell.element.style;\n        if ($bidiHandler && $bidiHandler.isRtlLine(cell.row)) {\n            style.direction = \"rtl\";\n            style.textAlign = \"right\";\n            style.width = width;\n        } else {\n            style.direction = \"\";\n            style.textAlign = \"\";\n            style.width = \"\";\n        }\n    });\n}\n\n/**\n * @param {import(\"../virtual_renderer\").VirtualRenderer} renderer\n */\nfunction clearTextLayer(renderer) {\n    var lines = renderer.$textLayer.$lines;\n    lines.cells.forEach(clear);\n    lines.cellCache.forEach(clear);\n    function clear(cell) {\n        var style = cell.element.style;\n        style.direction = style.textAlign = style.width = \"\";\n    }\n}\n"
  },
  {
    "path": "src/ext/searchbox-css.js",
    "content": "module.exports = `\n\n/* ------------------------------------------------------------------------------------------\n * Editor Search Form\n * --------------------------------------------------------------------------------------- */\n.ace_search {\n    background-color: #ddd;\n    color: #666;\n    border: 1px solid #cbcbcb;\n    border-top: 0 none;\n    overflow: hidden;\n    margin: 0;\n    padding: 4px 6px 0 4px;\n    position: absolute;\n    top: 0;\n    z-index: 99;\n    white-space: normal;\n}\n.ace_search.left {\n    border-left: 0 none;\n    border-radius: 0px 0px 5px 0px;\n    left: 0;\n}\n.ace_search.right {\n    border-radius: 0px 0px 0px 5px;\n    border-right: 0 none;\n    right: 0;\n}\n\n.ace_search_form, .ace_replace_form {\n    margin: 0 20px 4px 0;\n    overflow: hidden;\n    line-height: 1.9;\n}\n.ace_replace_form {\n    margin-right: 0;\n}\n.ace_search_form.ace_nomatch {\n    outline: 1px solid red;\n}\n\n.ace_search_field {\n    border-radius: 3px 0 0 3px;\n    background-color: white;\n    color: black;\n    border: 1px solid #cbcbcb;\n    border-right: 0 none;\n    outline: 0;\n    padding: 0;\n    font-size: inherit;\n    margin: 0;\n    line-height: inherit;\n    padding: 0 6px;\n    min-width: 17em;\n    vertical-align: top;\n    min-height: 1.8em;\n    box-sizing: content-box;\n}\n.ace_searchbtn {\n    border: 1px solid #cbcbcb;\n    line-height: inherit;\n    display: inline-block;\n    padding: 0 6px;\n    background: #fff;\n    border-right: 0 none;\n    border-left: 1px solid #dcdcdc;\n    cursor: pointer;\n    margin: 0;\n    position: relative;\n    color: #666;\n}\n.ace_searchbtn:last-child {\n    border-radius: 0 3px 3px 0;\n    border-right: 1px solid #cbcbcb;\n}\n.ace_searchbtn:disabled {\n    background: none;\n    cursor: default;\n}\n.ace_searchbtn:hover {\n    background-color: #eef1f6;\n}\n.ace_searchbtn.prev, .ace_searchbtn.next {\n     padding: 0px 0.7em\n}\n.ace_searchbtn.prev:after, .ace_searchbtn.next:after {\n     content: \"\";\n     border: solid 2px #888;\n     width: 0.5em;\n     height: 0.5em;\n     border-width:  2px 0 0 2px;\n     display:inline-block;\n     transform: rotate(-45deg);\n}\n.ace_searchbtn.next:after {\n     border-width: 0 2px 2px 0 ;\n}\n.ace_searchbtn_close {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;\n    border-radius: 50%;\n    border: 0 none;\n    color: #656565;\n    cursor: pointer;\n    font: 16px/16px Arial;\n    padding: 0;\n    height: 14px;\n    width: 14px;\n    top: 9px;\n    right: 7px;\n    position: absolute;\n}\n.ace_searchbtn_close:hover {\n    background-color: #656565;\n    background-position: 50% 100%;\n    color: white;\n}\n\n.ace_button {\n    margin-left: 2px;\n    cursor: pointer;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -o-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n    overflow: hidden;\n    opacity: 0.7;\n    border: 1px solid rgba(100,100,100,0.23);\n    padding: 1px;\n    box-sizing:    border-box!important;\n    color: black;\n}\n\n.ace_button:hover {\n    background-color: #eee;\n    opacity:1;\n}\n.ace_button:active {\n    background-color: #ddd;\n}\n\n.ace_button.checked {\n    border-color: #3399ff;\n    opacity:1;\n}\n\n.ace_search_options{\n    margin-bottom: 3px;\n    text-align: right;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -o-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n    clear: both;\n}\n\n.ace_search_counter {\n    float: left;\n    font-family: arial;\n    padding: 0 8px;\n}`;\n"
  },
  {
    "path": "src/ext/searchbox.js",
    "content": "/**\n * ## Interactive search and replace UI extension for text editing\n *\n * Provides a floating search box interface with find/replace functionality including live search results, regex\n * support, case sensitivity options, whole word matching, and scoped selection searching. Features keyboard shortcuts\n * for quick access and navigation, with visual feedback for search matches and a counter showing current position\n * in results.\n *\n * **Key Features:**\n * - Real-time search with highlighted matches\n * - Find and replace with individual or bulk operations\n * - Advanced options: regex, case sensitivity, whole words, search in selection\n * - Keyboard navigation and shortcuts\n * - Visual match counter and no-match indicators\n *\n * **Usage:**\n * ```javascript\n * // Show search box\n * require(\"ace/ext/searchbox\").Search(editor);\n *\n * // Show with replace functionality\n * require(\"ace/ext/searchbox\").Search(editor, true);\n * ```\n *\n * @module\n */\n\n\n\"use strict\";\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar event = require(\"../lib/event\");\nvar searchboxCss = require(\"./searchbox-css\");\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar keyUtil = require(\"../lib/keys\");\nvar nls = require(\"../config\").nls;\n\nvar MAX_COUNT = 999;\n\ndom.importCssString(searchboxCss, \"ace_searchbox\", false);\n\nclass SearchBox {\n    /**\n     * @param {Editor} editor\n     * @param {never} [range]\n     * @param {never} [showReplaceForm]\n     */\n    constructor(editor, range, showReplaceForm) {\n        /**@type {HTMLInputElement}*/\n        this.activeInput;\n        /**@type {HTMLDivElement}*/\n        this.element = dom.buildDom([\"div\", {class:\"ace_search right\"},\n            [\"span\", {action: \"hide\", class: \"ace_searchbtn_close\"}],\n            [\"div\", {class: \"ace_search_form\"},\n                [\"input\", {class: \"ace_search_field\", placeholder: nls(\"search-box.find.placeholder\", \"Search for\"), spellcheck: \"false\"}],\n                [\"span\", {action: \"findPrev\", class: \"ace_searchbtn prev\"}, \"\\u200b\"],\n                [\"span\", {action: \"findNext\", class: \"ace_searchbtn next\"}, \"\\u200b\"],\n                [\"span\", {action: \"findAll\", class: \"ace_searchbtn\", title: \"Alt-Enter\"}, nls(\"search-box.find-all.text\", \"All\")]\n            ],\n            [\"div\", {class: \"ace_replace_form\"},\n                [\"input\", {class: \"ace_search_field\", placeholder: nls(\"search-box.replace.placeholder\", \"Replace with\"), spellcheck: \"false\"}],\n                [\"span\", {action: \"replaceAndFindNext\", class: \"ace_searchbtn\"}, nls(\"search-box.replace-next.text\", \"Replace\")],\n                [\"span\", {action: \"replaceAll\", class: \"ace_searchbtn\"}, nls(\"search-box.replace-all.text\", \"All\")]\n            ],\n            [\"div\", {class: \"ace_search_options\"},\n                [\"span\", {action: \"toggleReplace\", class: \"ace_button\", title: nls(\"search-box.toggle-replace.title\", \"Toggle Replace mode\"),\n                    style: \"float:left;margin-top:-2px;padding:0 5px;\"}, \"+\"],\n                [\"span\", {class: \"ace_search_counter\"}],\n                [\"span\", {action: \"toggleRegexpMode\", class: \"ace_button\", title: nls(\"search-box.toggle-regexp.title\", \"RegExp Search\")}, \".*\"],\n                [\"span\", {action: \"toggleCaseSensitive\", class: \"ace_button\", title: nls(\"search-box.toggle-case.title\", \"CaseSensitive Search\")}, \"Aa\"],\n                [\"span\", {action: \"toggleWholeWords\", class: \"ace_button\", title: nls(\"search-box.toggle-whole-word.title\", \"Whole Word Search\")}, \"\\\\b\"],\n                [\"span\", {action: \"searchInSelection\", class: \"ace_button\", title: nls(\"search-box.toggle-in-selection.title\", \"Search In Selection\")}, \"S\"]\n            ]\n        ]);\n\n        this.setSession = this.setSession.bind(this);\n        this.$onEditorInput = this.onEditorInput.bind(this);\n\n        this.$init();\n        this.setEditor(editor);\n        dom.importCssString(searchboxCss, \"ace_searchbox\", editor.container);\n        event.addListener(this.element, \"touchstart\", function(e) { e.stopPropagation(); }, editor);\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    setEditor(editor) {\n        editor.searchBox = this;\n        editor.renderer.scroller.appendChild(this.element);\n        /**@type {Editor}*/\n        this.editor = editor;\n    }\n\n    setSession(e) {\n        this.searchRange = null;\n        this.$syncOptions(true);\n    }\n\n    // Auto update \"updateCounter\" and \"ace_nomatch\"\n    onEditorInput() {\n        this.find(false, false, true);\n    }\n\n    /**\n     * @param {HTMLElement} sb\n     */\n    $initElements(sb) {\n        /**@type {HTMLElement}*/\n        this.searchBox = sb.querySelector(\".ace_search_form\");\n        /**@type {HTMLElement}*/\n        this.replaceBox = sb.querySelector(\".ace_replace_form\");\n        /**@type {HTMLInputElement}*/\n        this.searchOption = sb.querySelector(\"[action=searchInSelection]\");\n        /**@type {HTMLInputElement}*/\n        this.replaceOption = sb.querySelector(\"[action=toggleReplace]\");\n        /**@type {HTMLInputElement}*/\n        this.regExpOption = sb.querySelector(\"[action=toggleRegexpMode]\");\n        /**@type {HTMLInputElement}*/\n        this.caseSensitiveOption = sb.querySelector(\"[action=toggleCaseSensitive]\");\n        /**@type {HTMLInputElement}*/\n        this.wholeWordOption = sb.querySelector(\"[action=toggleWholeWords]\");\n        /**@type {HTMLInputElement}*/\n        this.searchInput = this.searchBox.querySelector(\".ace_search_field\");\n        /**@type {HTMLInputElement}*/\n        this.replaceInput = this.replaceBox.querySelector(\".ace_search_field\");\n        /**@type {HTMLElement}*/\n        this.searchCounter = sb.querySelector(\".ace_search_counter\");\n    }\n\n    $init() {\n        var sb = this.element;\n\n        this.$initElements(sb);\n\n        var _this = this;\n        event.addListener(sb, \"mousedown\", function(e) {\n            setTimeout(function(){\n                _this.activeInput.focus();\n            }, 0);\n            event.stopPropagation(e);\n        });\n        event.addListener(sb, \"click\", function(e) {\n            var t = e.target || e.srcElement;\n            var action = t.getAttribute(\"action\");\n            if (action && _this[action])\n                _this[action]();\n            else if (_this.$searchBarKb.commands[action])\n                _this.$searchBarKb.commands[action].exec(_this);\n            event.stopPropagation(e);\n        });\n\n        event.addCommandKeyListener(sb, function(e, hashId, keyCode) {\n            var keyString = keyUtil.keyCodeToString(keyCode);\n            var command = _this.$searchBarKb.findKeyCommand(hashId, keyString);\n            if (command && command.exec) {\n                command.exec(_this);\n                event.stopEvent(e);\n            }\n        });\n\n        /**\n         * @type {{schedule: (timeout?: number) => void}}\n         * @external\n        */\n        this.$onChange = lang.delayedCall(function() {\n            _this.find(false, false);\n        });\n\n        event.addListener(this.searchInput, \"input\", function() {\n            _this.$onChange.schedule(20);\n        });\n        event.addListener(this.searchInput, \"focus\", function() {\n            _this.activeInput = _this.searchInput;\n            _this.searchInput.value && _this.highlight();\n        });\n        event.addListener(this.replaceInput, \"focus\", function() {\n            _this.activeInput = _this.replaceInput;\n            _this.searchInput.value && _this.highlight();\n        });\n    }\n\n    setSearchRange(range) {\n        this.searchRange = range;\n        if (range) {\n            this.searchRangeMarker = this.editor.session.addMarker(range, \"ace_active-line\");\n        } else if (this.searchRangeMarker) {\n            this.editor.session.removeMarker(this.searchRangeMarker);\n            this.searchRangeMarker = null;\n        }\n    }\n\n    /**\n     * @param {boolean} [preventScroll]\n     * @external\n     */\n    $syncOptions(preventScroll) {\n        dom.setCssClass(this.replaceOption, \"checked\", this.searchRange);\n        dom.setCssClass(this.searchOption, \"checked\", this.searchOption.checked);\n        this.replaceOption.textContent = this.replaceOption.checked ? \"-\" : \"+\";\n        dom.setCssClass(this.regExpOption, \"checked\", this.regExpOption.checked);\n        dom.setCssClass(this.wholeWordOption, \"checked\", this.wholeWordOption.checked);\n        dom.setCssClass(this.caseSensitiveOption, \"checked\", this.caseSensitiveOption.checked);\n        var readOnly = this.editor.getReadOnly();\n        this.replaceOption.style.display = readOnly ? \"none\" : \"\";\n        this.replaceBox.style.display = this.replaceOption.checked && !readOnly ? \"\" : \"none\";\n        this.find(false, false, preventScroll);\n    }\n\n    /**\n     * @param {RegExp} [re]\n     */\n    highlight(re) {\n        this.editor.session.highlight(re || this.editor.$search.$options.re);\n        this.editor.renderer.updateBackMarkers();\n    }\n\n    /**\n     * @param {boolean} skipCurrent\n     * @param {boolean} backwards\n     * @param {any} [preventScroll]\n     */\n    find(skipCurrent, backwards, preventScroll) {\n        if (!this.editor.session) return;\n        var range = this.editor.find(this.searchInput.value, {\n            skipCurrent: skipCurrent,\n            backwards: backwards,\n            wrap: true,\n            regExp: this.regExpOption.checked,\n            caseSensitive: this.caseSensitiveOption.checked,\n            wholeWord: this.wholeWordOption.checked,\n            preventScroll: preventScroll,\n            range: this.searchRange\n        });\n        /**@type {any}*/\n        var noMatch = !range && this.searchInput.value;\n        dom.setCssClass(this.searchBox, \"ace_nomatch\", noMatch);\n        this.editor._emit(\"findSearchBox\", { match: !noMatch });\n        this.highlight();\n        this.updateCounter();\n    }\n    updateCounter() {\n        var editor = this.editor;\n        var regex = editor.$search.$options.re;\n        var supportsUnicodeFlag = regex.unicode;\n        var all = 0;\n        var before = 0;\n        if (regex) {\n            var value = this.searchRange\n                ? editor.session.getTextRange(this.searchRange)\n                : editor.getValue();\n\n            /**\n             * Convert all line ending variations to Unix-style = \\n\n             * Windows (\\r\\n), MacOS Classic (\\r), and Unix (\\n)\n             */\n            if (editor.$search.$isMultilineSearch(editor.getLastSearchOptions())) {\n                value = value.replace(/\\r\\n|\\r|\\n/g, \"\\n\");\n                editor.session.doc.$autoNewLine = \"\\n\";\n            }\n\n            var offset = editor.session.doc.positionToIndex(editor.selection.anchor);\n            if (this.searchRange)\n                offset -= editor.session.doc.positionToIndex(this.searchRange.start);\n\n            var last = regex.lastIndex = 0;\n            var m;\n            while ((m = regex.exec(value))) {\n                all++;\n                last = m.index;\n                if (last <= offset)\n                    before++;\n                if (all > MAX_COUNT)\n                    break;\n                if (!m[0]) {\n                    regex.lastIndex = last += lang.skipEmptyMatch(value, last, supportsUnicodeFlag);\n                    if (last >= value.length)\n                        break;\n                }\n            }\n        }\n        this.searchCounter.textContent = nls(\"search-box.search-counter\", \"$0 of $1\", [before , (all > MAX_COUNT ? MAX_COUNT + \"+\" : all)]);\n    }\n    findNext() {\n        this.find(true, false);\n    }\n    findPrev() {\n        this.find(true, true);\n    }\n    findAll(){\n        var range = this.editor.findAll(this.searchInput.value, {\n            regExp: this.regExpOption.checked,\n            caseSensitive: this.caseSensitiveOption.checked,\n            wholeWord: this.wholeWordOption.checked\n        });\n        /**@type {any}*/\n        var noMatch = !range && this.searchInput.value;\n        dom.setCssClass(this.searchBox, \"ace_nomatch\", noMatch);\n        this.editor._emit(\"findSearchBox\", { match: !noMatch });\n        this.highlight();\n        this.hide();\n    }\n    replace() {\n        if (!this.editor.getReadOnly())\n            this.editor.replace(this.replaceInput.value);\n    }\n    replaceAndFindNext() {\n        if (!this.editor.getReadOnly()) {\n            this.editor.replace(this.replaceInput.value);\n            this.findNext();\n        }\n    }\n    replaceAll() {\n        if (!this.editor.getReadOnly())\n            this.editor.replaceAll(this.replaceInput.value);\n    }\n\n    hide() {\n        this.active = false;\n        this.setSearchRange(null);\n        this.editor.off(\"changeSession\", this.setSession);\n        this.editor.off(\"input\", this.$onEditorInput);\n\n        this.element.style.display = \"none\";\n        this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb);\n        this.editor.focus();\n    }\n\n    /**\n     * @param {string} value\n     * @param {boolean} [isReplace]\n     */\n    show(value, isReplace) {\n        this.active = true;\n        this.editor.on(\"changeSession\", this.setSession);\n        this.editor.on(\"input\", this.$onEditorInput);\n        this.element.style.display = \"\";\n        this.replaceOption.checked = isReplace;\n\n        if (this.editor.$search.$options.regExp)\n            value = lang.escapeRegExp(value);\n\n        if (value != undefined)\n            this.searchInput.value = value;\n\n        this.searchInput.focus();\n        this.searchInput.select();\n\n        this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);\n\n        this.$syncOptions(true);\n    }\n\n    isFocused() {\n        var el = document.activeElement;\n        return el == this.searchInput || el == this.replaceInput;\n    }\n}\n\n//keybinding outside of the searchbox\nvar $searchBarKb = new HashHandler();\n$searchBarKb.bindKeys({\n    \"Ctrl-f|Command-f\": function(sb) {\n        var isReplace = sb.isReplace = !sb.isReplace;\n        sb.replaceBox.style.display = isReplace ? \"\" : \"none\";\n        sb.replaceOption.checked = false;\n        sb.$syncOptions();\n        sb.searchInput.focus();\n    },\n    \"Ctrl-H|Command-Option-F\": function(sb) {\n        if (sb.editor.getReadOnly())\n            return;\n        sb.replaceOption.checked = true;\n        sb.$syncOptions();\n        sb.replaceInput.focus();\n    },\n    \"Ctrl-G|Command-G\": function(sb) {\n        sb.findNext();\n    },\n    \"Ctrl-Shift-G|Command-Shift-G\": function(sb) {\n        sb.findPrev();\n    },\n    \"esc\": function(sb) {\n        setTimeout(function() { sb.hide();});\n    },\n    \"Return\": function(sb) {\n        if (sb.activeInput == sb.replaceInput)\n            sb.replace();\n        sb.findNext();\n    },\n    \"Shift-Return\": function(sb) {\n        if (sb.activeInput == sb.replaceInput)\n            sb.replace();\n        sb.findPrev();\n    },\n    \"Alt-Return\": function(sb) {\n        if (sb.activeInput == sb.replaceInput)\n            sb.replaceAll();\n        sb.findAll();\n    },\n    \"Tab\": function(sb) {\n        (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();\n    }\n});\n\n$searchBarKb.addCommands([{\n    name: \"toggleRegexpMode\",\n    bindKey: {win: \"Alt-R|Alt-/\", mac: \"Ctrl-Alt-R|Ctrl-Alt-/\"},\n    exec: function(sb) {\n        sb.regExpOption.checked = !sb.regExpOption.checked;\n        sb.$syncOptions();\n    }\n}, {\n    name: \"toggleCaseSensitive\",\n    bindKey: {win: \"Alt-C|Alt-I\", mac: \"Ctrl-Alt-R|Ctrl-Alt-I\"},\n    exec: function(sb) {\n        sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked;\n        sb.$syncOptions();\n    }\n}, {\n    name: \"toggleWholeWords\",\n    bindKey: {win: \"Alt-B|Alt-W\", mac: \"Ctrl-Alt-B|Ctrl-Alt-W\"},\n    exec: function(sb) {\n        sb.wholeWordOption.checked = !sb.wholeWordOption.checked;\n        sb.$syncOptions();\n    }\n}, {\n    name: \"toggleReplace\",\n    exec: function(sb) {\n        sb.replaceOption.checked = !sb.replaceOption.checked;\n        sb.$syncOptions();\n    }\n}, {\n    name: \"searchInSelection\",\n    exec: function(sb) {\n        sb.searchOption.checked = !sb.searchRange;\n        sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange());\n        sb.$syncOptions();\n    }\n}]);\n\n//keybinding outside of the searchbox\nvar $closeSearchBarKb = new HashHandler([{\n    bindKey: \"Esc\",\n    name: \"closeSearchBar\",\n    exec: function(editor) {\n        editor.searchBox.hide();\n    }\n}]);\n\nSearchBox.prototype.$searchBarKb = $searchBarKb;\nSearchBox.prototype.$closeSearchBarKb = $closeSearchBarKb;\n\nexports.SearchBox = SearchBox;\n\n/**\n * Shows the search box for the editor with optional replace functionality.\n *\n * @param {Editor} editor - The editor instance\n * @param {boolean} [isReplace] - Whether to show replace options\n */\nexports.Search = function(editor, isReplace) {\n    var sb = editor.searchBox || new SearchBox(editor);\n    var range = editor.session.selection.getRange();\n    var value = range.isMultiLine() ? \"\" : editor.session.getTextRange(range);\n    sb.show(value, isReplace);\n};\n\n\n/* ------------------------------------------------------------------------------------------\n * TODO\n * --------------------------------------------------------------------------------------- */\n/*\n- move search form to the left if it masks current word\n- include all options that search has. ex: regex\n- searchbox.searchbox is not that pretty. We should have just searchbox\n- disable prev button if it makes sense\n*/\n"
  },
  {
    "path": "src/ext/settings_menu.js",
    "content": "/**\n * ## Interactive Settings Menu Extension\n *\n * Provides settings interface for the Ace editor that displays dynamically generated configuration options based on\n * the current editor state. The menu appears as an overlay panel allowing users to modify editor options, themes,\n * modes, and other settings through an intuitive graphical interface.\n *\n * **Usage:**\n * ```javascript\n * editor.showSettingsMenu();\n * ```\n *\n * The extension automatically registers the `showSettingsMenu` command and method\n * on the editor instance when initialized.\n *\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *\n * @module\n */\n\n/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/\n/*global define, require */\n\n\"use strict\";\nvar OptionPanel = require(\"./options\").OptionPanel;\nvar overlayPage = require('./menu_tools/overlay_page').overlayPage;\n\n/**\n * This displays the settings menu if it is not already being shown.\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *  ☭ Hial Atropa!! ☭\n * @param {import(\"../editor\").Editor} editor An instance of the ace editor.\n */\nfunction showSettingsMenu(editor) {\n    // show if the menu isn't open already.\n    if (!document.getElementById('ace_settingsmenu')) {\n        var options = new OptionPanel(editor);\n        options.render();\n        options.container.id = \"ace_settingsmenu\";\n        overlayPage(editor, options.container);\n        // @ts-ignore\n        options.container.querySelector(\"select,input,button,checkbox\").focus();\n    }\n}\n\n/**\n * Initializes the settings menu extension. It adds the showSettingsMenu\n *  method to the given editor object and adds the showSettingsMenu command\n *  to the editor with appropriate keyboard shortcuts.\n */\nmodule.exports.init = function() {\n    var Editor = require(\"../editor\").Editor;\n    Editor.prototype.showSettingsMenu = function() {\n        showSettingsMenu(this);\n    };\n};\n"
  },
  {
    "path": "src/ext/simple_tokenizer.js",
    "content": "/**\n * ## Simple tokenizer extension\n *\n * Provides standalone tokenization functionality that can parse code content using Ace's highlight rules without\n * requiring a full editor instance. This is useful for generating syntax-highlighted tokens for external rendering,\n * static code generation, or testing tokenization rules. The tokenizer processes text line by line and returns\n * structured token data with CSS class names compatible with Ace themes.\n *\n * **Usage:**\n * ```javascript\n * const { tokenize } = require(\"ace/ext/simple_tokenizer\");\n * const { JsonHighlightRules } = require(\"ace/mode/json_highlight_rules\");\n *\n * const content = '{\"name\": \"value\"}';\n * const tokens = tokenize(content, new JsonHighlightRules());\n * // Returns: [[{className: \"ace_paren ace_lparen\", value: \"{\"}, ...]]\n * ```\n *\n * @module\n */\n\n\"use strict\";\nconst { Tokenizer } = require(\"../tokenizer\");\nconst isTextToken = require(\"../layer/text_util\").isTextToken;\n\nclass SimpleTokenizer {\n    /**\n     * @param {string} content \n     * @param {Tokenizer} tokenizer \n     */\n    constructor(content, tokenizer) {\n        this._lines = content.split(/\\r\\n|\\r|\\n/);\n        this._states = [];\n        this._tokenizer = tokenizer;\n    }   \n\n    /**\n     * @param {number} row \n     * @returns {import(\"../../ace-internal\").Ace.Token[]}\n     */\n    getTokens(row) {\n        const line = this._lines[row];\n        const previousState = this._states[row - 1];\n        \n        const data = this._tokenizer.getLineTokens(line, previousState);\n        this._states[row] = data.state;\n        return data.tokens;\n    }\n\n    /**\n     * @returns {number} \n     */\n    getLength() {\n        return this._lines.length;\n    }\n}\n\n/**\n * Parses provided content according to provided highlighting rules and return tokens. \n * Tokens either have the className set according to Ace themes or have no className if they are just pure text tokens.\n * Result is a list of list of tokens, where each line from the provided content is a separate list of tokens.\n * \n * @param {string} content to tokenize \n * @param {import(\"../../ace-internal\").Ace.HighlightRules} highlightRules defining the language grammar \n * @returns {import(\"../../ace-internal\").Ace.TokenizeResult} tokenization result containing a list of token for each of the lines from content\n */\nfunction tokenize(content, highlightRules) {\n    const tokenizer = new SimpleTokenizer(content, new Tokenizer(highlightRules.getRules()));\n    \n    let result = [];\n    for (let lineIndex = 0; lineIndex < tokenizer.getLength(); lineIndex++) {\n        const lineTokens = tokenizer.getTokens(lineIndex);\n        result.push(lineTokens.map((token) => ({\n            className: isTextToken(token.type) ? undefined : \"ace_\" + token.type.replace(/\\./g, \" ace_\"),\n            value: token.value\n        })));\n    }\n    return result;\n}\n\nexports.tokenize = tokenize;"
  },
  {
    "path": "src/ext/simple_tokenizer_test.js",
    "content": "\"use strict\";\n\nconst assert = require(\"../test/assertions\");\nconst tokenize = require(\"./simple_tokenizer\").tokenize;\n\nconst JsonHighlightRules = require(\"../mode/json_highlight_rules\").JsonHighlightRules;\nconst JavaScriptHighlightRules = require(\"../mode/javascript_highlight_rules\").JavaScriptHighlightRules;\n\nmodule.exports = {\n    \"test: can tokenize JSON\": function() {\n        const content = `{\n            \"name\": \"John\",\n            \"age\": 30,\n            \"car\": null\n        }`;\n        const result = tokenize(content, new JsonHighlightRules());\n\n        const expectedResult = [\n            [{ className: \"ace_paren ace_lparen\", value: \"{\" }],\n            [\n                {className: undefined, value: '            '},\n                { className: \"ace_variable\", value: '\"name\"' }, \n                { className: undefined, value: \": \" }, \n                { className: \"ace_string\", value: '\"John\"' }, \n                { className: \"ace_punctuation ace_operator\", value: \",\" } \n            ],\n            [\n                {className: undefined, value: '            '},\n                { className: \"ace_variable\", value: '\"age\"' }, \n                { className: undefined, value: \": \" }, \n                { className: \"ace_constant ace_numeric\", value: \"30\" }, \n                { className: \"ace_punctuation ace_operator\", value: \",\" } \n            ],\n            [\n                {className: undefined, value: '            '},\n                { className: \"ace_variable\", value: '\"car\"' }, \n                { className: undefined, value: \": null\" }\n            ],\n            [\n                {className: undefined, value: '        '},\n                { className: \"ace_paren ace_rparen\", value: \"}\" }\n            ]\n        ];\n\n        assert.deepEqual(result, expectedResult);\n    },\n\n    \"test: can tokenize Javascript\": function() {\n        const content = `console.log(\"content\")`;\n        const result = tokenize(content, new JavaScriptHighlightRules());\n\n        const expectedResult = [\n            [\n                {className: 'ace_storage ace_type', value: 'console'},\n                {className: 'ace_punctuation ace_operator', value: '.'},\n                {className: 'ace_support ace_function ace_firebug', value: 'log'},\n                {className: 'ace_paren ace_lparen', value: '('},\n                {className: 'ace_string', value: '\"content\"'},\n                {className: 'ace_paren ace_rparen', value: ')'}\n            ]\n        ];\n\n        assert.deepEqual(result, expectedResult);\n    }\n\n};\n"
  },
  {
    "path": "src/ext/spellcheck.js",
    "content": "/**\n * ## Browser spellcheck integration extension for native spelling correction\n *\n * Provides seamless integration with browser's native spellcheck functionality through context menu interactions.\n * Enables right-click spelling suggestions on misspelled words while preserving editor functionality and text input\n * handling. The extension bridges browser spellcheck capabilities with the editor's text manipulation system.\n *\n * **Enable:** `editor.setOption(\"spellcheck\", true)` (enabled by default)\n * or configure it during editor initialization in the options object.\n *\n * @module\n */\n\n\n\"use strict\";\nvar event = require(\"../lib/event\");\n\n/**\n * Handles context menu events for spellcheck integration by setting up a hidden input field\n * with the word at cursor position to trigger browser spellcheck suggestions.\n * @param {any} e - The context menu event\n */\n\nexports.contextMenuHandler = function(e){\n    var host = e.target;\n    var text = host.textInput.getElement();\n    if (!host.selection.isEmpty())\n        return;\n    var c = host.getCursorPosition();\n    var r = host.session.getWordRange(c.row, c.column);\n    var w = host.session.getTextRange(r);\n\n    host.session.tokenRe.lastIndex = 0;\n    if (!host.session.tokenRe.test(w))\n        return;\n    var PLACEHOLDER = \"\\x01\\x01\";\n    var value = w + \" \" + PLACEHOLDER;\n    text.value = value;\n    text.setSelectionRange(w.length, w.length + 1);\n    text.setSelectionRange(0, 0);\n    text.setSelectionRange(0, w.length);\n\n    var afterKeydown = false;\n    event.addListener(text, \"keydown\", function onKeydown() {\n        event.removeListener(text, \"keydown\", onKeydown);\n        afterKeydown = true;\n    });\n\n    host.textInput.setInputHandler(function(newVal) {\n        if (newVal == value)\n            return '';\n        if (newVal.lastIndexOf(value, 0) === 0)\n            return newVal.slice(value.length);\n        if (newVal.substr(text.selectionEnd) == value)\n            return newVal.slice(0, -value.length);\n        if (newVal.slice(-2) == PLACEHOLDER) {\n            var val = newVal.slice(0, -2);\n            if (val.slice(-1) == \" \") {\n                if (afterKeydown)\n                    return val.substring(0, text.selectionEnd);\n                val = val.slice(0, -1);\n                host.session.replace(r, val);\n                return \"\";\n            }\n        }\n\n        return newVal;\n    });\n};\n// todo support highlighting with typo.js\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    spellcheck: {\n        set: function(val) {\n            var text = this.textInput.getElement();\n            text.spellcheck = !!val;\n            if (!val)\n                this.removeListener(\"nativecontextmenu\", exports.contextMenuHandler);\n            else\n                this.on(\"nativecontextmenu\", exports.contextMenuHandler);\n        },\n        value: true\n    }\n});\n"
  },
  {
    "path": "src/ext/split.js",
    "content": "/**\n * ## Split editor container extension for multiple editor instances\n *\n * Provides functionality to create and manage multiple editor instances within a single container,\n * arranged either horizontally (beside) or vertically (below). Enables synchronized editing sessions\n * with shared configurations while maintaining independent cursor positions and selections.\n *\n * **Usage:**\n * ```javascript\n * var Split = require(\"ace/ext/split\").Split;\n * var split = new Split(container, theme, numberOfSplits);\n * split.setOrientation(split.BESIDE); // or split.BELOW\n * ```\n *\n * @experimental\n * @module\n */\n\n\"use strict\";\n\n/**\n * this is experimental, and subject to change, use at your own risk!\n */\nmodule.exports = require(\"../split\");\n"
  },
  {
    "path": "src/ext/static-css.js",
    "content": "module.exports = `.ace_static_highlight {\n    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'Source Code Pro', 'source-code-pro', 'Droid Sans Mono', monospace;\n    font-size: 12px;\n    white-space: pre-wrap\n}\n\n.ace_static_highlight .ace_gutter {\n    width: 2em;\n    text-align: right;\n    padding: 0 3px 0 0;\n    margin-right: 3px;\n    contain: none;\n}\n\n.ace_static_highlight.ace_show_gutter .ace_line {\n    padding-left: 2.6em;\n}\n\n.ace_static_highlight .ace_line { position: relative; }\n\n.ace_static_highlight .ace_gutter-cell {\n    -moz-user-select: -moz-none;\n    -khtml-user-select: none;\n    -webkit-user-select: none;\n    user-select: none;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    position: absolute;\n}\n\n\n.ace_static_highlight .ace_gutter-cell:before {\n    content: counter(ace_line, decimal);\n    counter-increment: ace_line;\n}\n.ace_static_highlight {\n    counter-reset: ace_line;\n}\n`;\n"
  },
  {
    "path": "src/ext/static_highlight.js",
    "content": "/**\n * ## Static syntax highlighting extension for code-to-HTML conversion\n *\n * Transforms code snippets into syntax-highlighted HTML with CSS styling without requiring a live editor instance.\n * Uses a simplified DOM implementation to generate standalone HTML output suitable for static content generation,\n * documentation, code export, and embedding highlighted code in web pages. Supports automatic language detection\n * from CSS classes and custom modes/themes.\n *\n * @module\n */\n\n\n\"use strict\";\n/**\n * @typedef {import(\"../../ace-internal\").Ace.SyntaxMode} SyntaxMode\n * @typedef {import(\"../../ace-internal\").Ace.Theme} Theme\n */\n\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar TextLayer = require(\"../layer/text\").Text;\nvar baseStyles = require(\"./static-css\");\nvar config = require(\"../config\");\nvar dom = require(\"../lib/dom\");\nvar escapeHTML = require(\"../lib/lang\").escapeHTML;\n\nclass Element {\n    /**\n     * @param {string} type\n     */\n    constructor(type) {\n        /** @type{string} */this.className;\n        this.type = type;\n        this.style = {};\n        this.textContent = \"\";\n    }\n\n    cloneNode() {\n        return this;\n    }\n\n    appendChild(child) {\n        this.textContent += child.toString();\n    }\n\n    toString() {\n        var stringBuilder = [];\n        if (this.type != \"fragment\") {\n            stringBuilder.push(\"<\", this.type);\n            if (this.className)\n                stringBuilder.push(\" class='\", this.className, \"'\");\n            var styleStr = [];\n            for (var key in this.style) {\n                styleStr.push(key, \":\", this.style[key]);\n            }\n            if (styleStr.length)\n                stringBuilder.push(\" style='\", styleStr.join(\"\"), \"'\");\n            stringBuilder.push(\">\");\n        }\n\n        if (this.textContent) {\n            stringBuilder.push(this.textContent);\n        }\n\n        if (this.type != \"fragment\") {\n            stringBuilder.push(\"</\", this.type, \">\");\n        }\n\n        return stringBuilder.join(\"\");\n    }\n}\n\n\nvar simpleDom = {\n    createTextNode: function(/** @type {string} */ textContent, /** @type {any} */ element) {\n        return escapeHTML(textContent);\n    },\n    createElement: function(/** @type {string} */ type) {\n        return new Element(type);\n    },\n    createFragment: function() {\n        return new Element(\"fragment\");\n    }\n};\n\n\n/**@type {any}*/\nvar SimpleTextLayer = function() {\n    this.config = {};\n    this.dom = simpleDom;\n};\nSimpleTextLayer.prototype = TextLayer.prototype;\n\n/**\n * Applies syntax highlighting to an HTML element containing code.\n *\n * Automatically detects the language from CSS class names (e.g., 'lang-javascript') or uses\n * the specified mode. Transforms the element's content into syntax-highlighted HTML with\n * CSS styling and preserves any existing child elements by repositioning them after highlighting.\n *\n * @param {HTMLElement} el - The HTML element containing code to highlight\n * @param {import(\"../../ace-internal\").Ace.StaticHighlightOptions} opts - Highlighting options\n * @param {function} [callback] - Optional callback executed after highlighting is complete\n * @returns {boolean} Returns false if no valid mode is found, otherwise true\n */\nvar highlight = function(el, opts, callback) {\n    var m = el.className.match(/lang-(\\w+)/);\n    var mode = opts.mode || m && (\"ace/mode/\" + m[1]);\n    if (!mode)\n        return false;\n    var theme = opts.theme || \"ace/theme/textmate\";\n\n    var data = \"\";\n    var nodes = [];\n\n    if (el.firstElementChild) {\n        var textLen = 0;\n        for (var i = 0; i < el.childNodes.length; i++) {\n            /**@type {any}*/\n            var ch = el.childNodes[i];\n            if (ch.nodeType == 3) {\n                textLen += ch.data.length;\n                data += ch.data;\n            } else {\n                nodes.push(textLen, ch);\n            }\n        }\n    } else {\n        data = el.textContent;\n        if (opts.trim)\n            data = data.trim();\n    }\n\n    highlight.render(data, mode, theme, opts.firstLineNumber, !opts.showGutter, function (highlighted) {\n        dom.importCssString(highlighted.css, \"ace_highlight\", true);\n        el.innerHTML = highlighted.html;\n        /**\n         * TODO: check if child exists\n         * @type {any}\n         */\n        var container = el.firstChild.firstChild;\n        for (var i = 0; i < nodes.length; i += 2) {\n            var pos = highlighted.session.doc.indexToPosition(nodes[i]);\n            var node = nodes[i + 1];\n            var lineEl = container.children[pos.row];\n            lineEl && lineEl.appendChild(node);\n        }\n        callback && callback();\n    });\n};\n\n/**\n * Transforms a given input code snippet into HTML using the given mode\n *\n * @param {string} input Code snippet\n * @param {string | SyntaxMode} mode String specifying the mode to load such as\n *  `ace/mode/javascript` or, a mode loaded from `/ace/mode`\n *  (use 'ServerSideHiglighter.getMode').\n * @param {string | Theme} theme String specifying the theme to load such as\n *  `ace/theme/twilight` or, a theme loaded from `/ace/theme`.\n * @param {number} lineStart A number indicating the first line number. Defaults\n *  to 1.\n * @param {boolean} disableGutter Specifies whether or not to disable the gutter.\n *  `true` disables the gutter, `false` enables the gutter. Defaults to `false`.\n * @param {function} [callback] When specifying the mode or theme as a string,\n *  this method has no return value and you must specify a callback function. The\n *  callback will receive the rendered object containing the properties `html`\n *  and `css`.\n * @returns {object} An object containing the properties `html` and `css`.\n */\nhighlight.render = function(input, mode, theme, lineStart, disableGutter, callback) {\n    var waiting = 1;\n    var modeCache = EditSession.prototype.$modes;\n\n    // if either the theme or the mode were specified as objects\n    // then we need to lazily load them.\n    if (typeof theme == \"string\") {\n        waiting++;\n        config.loadModule(['theme', theme], function(m) {\n            theme = m;\n            --waiting || done();\n        });\n    }\n    // allow setting mode options e.h {path: \"ace/mode/php\", inline:true}\n    var modeOptions;\n    if (mode && typeof mode === \"object\" && !mode.getTokenizer) {\n        modeOptions = mode;\n        mode = modeOptions.path;\n    }\n    if (typeof mode == \"string\") {\n        waiting++;\n        config.loadModule(['mode', mode], function(m) {\n            if (!modeCache[/**@type{string}*/(mode)] || modeOptions)\n                modeCache[/**@type{string}*/(mode)] = new m.Mode(modeOptions);\n            mode = modeCache[/**@type{string}*/(mode)];\n            --waiting || done();\n        });\n    }\n\n    // loads or passes the specified mode module then calls renderer\n    function done() {\n        var result = highlight.renderSync(input, mode, /**@type{Theme}*/(theme), lineStart, disableGutter);\n        return callback ? callback(result) : result;\n    }\n    return --waiting || done();\n};\n\n/**\n * Transforms a given input code snippet into HTML using the given mode\n * @param {string} input Code snippet\n * @param {SyntaxMode | string} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode')\n * @param {Theme} theme\n * @param {any} lineStart\n * @param {boolean} disableGutter\n * @returns {object} An object containing: html, css\n */\nhighlight.renderSync = function(input, mode, theme, lineStart, disableGutter) {\n    lineStart = parseInt(lineStart || 1, 10);\n\n    var session = new EditSession(\"\");\n    session.setUseWorker(false);\n    session.setMode(mode);\n\n    /**@type {TextLayer}*/\n    var textLayer = new SimpleTextLayer();\n    textLayer.setSession(session);\n    Object.keys(textLayer.$tabStrings).forEach(function(k) {\n        if (typeof textLayer.$tabStrings[k] == \"string\") {\n            var el = simpleDom.createFragment();\n            el.textContent = textLayer.$tabStrings[k];\n            textLayer.$tabStrings[k] = el;\n        }\n    });\n\n    session.setValue(input);\n    var length =  session.getLength();\n\n    var outerEl = simpleDom.createElement(\"div\");\n    outerEl.className = theme.cssClass;\n\n    var innerEl = simpleDom.createElement(\"div\");\n    innerEl.className = \"ace_static_highlight\" + (disableGutter ? \"\" : \" ace_show_gutter\");\n    innerEl.style[\"counter-reset\"] = \"ace_line \" + (lineStart - 1);\n\n    for (var ix = 0; ix < length; ix++) {\n        var lineEl = simpleDom.createElement(\"div\");\n        lineEl.className = \"ace_line\";\n\n        if (!disableGutter) {\n            var gutterEl = simpleDom.createElement(\"span\");\n            gutterEl.className =\"ace_gutter ace_gutter-cell\";\n            gutterEl.textContent = \"\"; /*(ix + lineStart) + */\n            lineEl.appendChild(gutterEl);\n        }\n        textLayer.$renderLine(lineEl, ix, false);\n        lineEl.textContent += \"\\n\";\n        innerEl.appendChild(lineEl);\n    }\n\n    //console.log(JSON.stringify(outerEl, null, 2));\n    //console.log(outerEl.toString());\n    outerEl.appendChild(innerEl);\n\n    return {\n        css: baseStyles + theme.cssText,\n        html: outerEl.toString(),\n        session: session\n    };\n};\n\nmodule.exports = highlight;\nmodule.exports.highlight = highlight;\n"
  },
  {
    "path": "src/ext/static_highlight_test.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar highlighter = require(\"./static_highlight\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar JavaScriptMode = require(\"../mode/javascript\").Mode;\nvar TextMode = require(\"../mode/text\").Mode;\nvar dom = require(\"../lib/dom\");\nvar config = require(\"../config\");\n\n// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite\nmodule.exports = {\n    \"test loading in node\": function(done) {\n        if (typeof process === \"undefined\") {\n            return done();\n        }\n        var req = require;\n        req(\"child_process\").execFile(process.execPath, [\"-p\", \"require('../ace').version\"], {\n            cwd: __dirname\n        }, function(err, stdout, stderr) {\n            assert.ok(!err, \"Failed to load ace in node: \" + err);\n            assert.equal(stdout.trim(), config.version);\n            done();\n        });\n    },\n\n    \"test simple snippet\": function() {\n        var theme = require(\"../theme/tomorrow\");\n        var snippet = [\n            \"/** this is a function\",\n            \"*\",\n            \"*/\",\n            \"\",\n            \"function hello (a, b, c) {\",\n            \"    console.log(a * b + c + 'sup$');\",\n            \"           //\",\n            \"\\t\\t\\t//\",\n            \"}\"\n        ].join(\"\\n\");\n        var mode = new JavaScriptMode();\n        var result = highlighter.render(snippet, mode, theme);\n        assert.equal(result.html, `<div class='ace-tomorrow'><div class='ace_static_highlight ace_show_gutter' style='counter-reset:ace_line 0'><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_comment ace_doc'>/**</span><span class='ace_comment ace_doc ace_body'> this is a function</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_comment ace_doc ace_body'>*</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_comment ace_doc'>*/</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_storage ace_type'>function</span> <span class='ace_entity ace_name ace_function'>hello</span> <span class='ace_paren ace_lparen'>(</span><span class='ace_variable ace_parameter'>a</span><span class='ace_punctuation ace_operator'>,</span> <span class='ace_variable ace_parameter'>b</span><span class='ace_punctuation ace_operator'>,</span> <span class='ace_variable ace_parameter'>c</span><span class='ace_paren ace_rparen'>)</span> <span class='ace_paren ace_lparen'>{</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span>    <span class='ace_storage ace_type'>console</span><span class='ace_punctuation ace_operator'>.</span><span class='ace_support ace_function ace_firebug'>log</span><span class='ace_paren ace_lparen'>(</span><span class='ace_identifier'>a</span> <span class='ace_keyword ace_operator'>*</span> <span class='ace_identifier'>b</span> <span class='ace_keyword ace_operator'>+</span> <span class='ace_identifier'>c</span> <span class='ace_keyword ace_operator'>+</span> <span class='ace_string'>&#39;sup$&#39;</span><span class='ace_paren ace_rparen'>)</span><span class='ace_punctuation ace_operator'>;</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_indent-guide'>    </span><span class='ace_indent-guide'>    </span>   <span class='ace_comment'>//</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_indent-guide'>    </span><span class='ace_indent-guide'>    </span>    <span class='ace_comment'>//</span>\n</div><div class='ace_line'><span class='ace_gutter ace_gutter-cell'></span><span class='ace_paren ace_rparen'>}</span>\n</div></div></div>`);\n        assert.ok(!!result.css);\n    },\n\n    \"test css from theme is used\": function() {\n        var theme = require(\"../theme/tomorrow\");\n        var snippet = [\n            \"/** this is a function\",\n            \"*\",\n            \"*/\",\n            \"function hello (a, b, c) {\",\n            \"    console.log(a * b + c + 'sup?');\",\n            \"}\"\n        ].join(\"\\n\");\n        var mode = new JavaScriptMode();\n\n        var result = highlighter.render(snippet, mode, theme);\n\n        assert.ok(result.css.indexOf(theme.cssText) !== -1);\n    },\n\n    \"test theme classname should be in output html\": function() {\n        var theme = require(\"../theme/tomorrow\");\n        var snippet = [\n            \"/** this is a function\",\n            \"*\",\n            \"*/\",\n            \"function hello (a, b, c) {\",\n            \"    console.log(a * b + c + 'sup?');\",\n            \"}\"\n        ].join(\"\\n\");\n        var mode = new JavaScriptMode();\n\n        var result = highlighter.render(snippet, mode, theme);\n        assert.equal(!!result.html.match(/<div class='ace-tomorrow'>/), true);\n    },\n    \n    \"test js string replace specials\": function() {\n        var theme = require(\"../theme/tomorrow\");\n        var snippet = \"$'$1$2$$$&\";\n        var mode = new TextMode();\n\n        var result = highlighter.render(snippet, mode, theme);\n        assert.ok(result.html.indexOf(\"</span>$&#39;$1$2$$$&#38;\\n</div>\") != -1);\n    },\n    \n    \"test html special chars\": function() {\n        var theme = require(\"../theme/tomorrow\");\n        var snippet = \"&<>'\\\"\";\n        var mode = new TextMode();\n\n        var result = highlighter.render(snippet, mode, theme);\n        assert.ok(result.html.indexOf(\"</span>&#38;&#60;>&#39;&#34;\\n</div>\") != -1);\n        \n        var mode = new JavaScriptMode();\n        var result = highlighter.render(\"/*\" + snippet, mode, theme);\n        assert.ok(result.html.indexOf(\"<span class='ace_comment'>/*&#38;&#60;>&#39;&#34;</span>\") != -1);\n    },\n    \n    \"test async highlight\": function(next) {\n        require(\"../test/mockdom\");\n        EditSession.prototype.$modes[\"./mode/javascript\"] = new JavaScriptMode();\n        var el = dom.buildDom([\"div\", {}, \"var a = 1\"]);\n        highlighter.highlight(el, {\n            theme: \"./theme/tomorrow\",\n            mode: \"./mode/javascript\"\n        }, function() {\n            assert.ok(/class=\"ace_storage ace_type\">var/.test(el.innerHTML));\n            next();\n        });\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/statusbar.js",
    "content": "/**\n * ## Status bar extension for displaying editor state information\n *\n * Provides a lightweight status indicator that displays real-time information about the editor state including\n * cursor position, selection details, recording status, and keyboard binding information. The status bar\n * automatically updates on editor events and renders as an inline element that can be embedded in any parent container.\n *\n * **Usage:**\n * ```javascript\n * var StatusBar = require(\"ace/ext/statusbar\").StatusBar;\n * var statusBar = new StatusBar(editor, parentElement);\n * ```\n *\n * @module\n */\n\n\n\"use strict\";\n/**\n *\n * @typedef {import(\"../editor\").Editor} Editor\n */\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\n\n/** simple statusbar **/\nclass StatusBar{\n    /**\n     * @param {Editor} editor\n     * @param {HTMLElement} parentNode\n     */\n    constructor(editor, parentNode) {\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_status-indicator\";\n        this.element.style.cssText = \"display: inline-block;\";\n        parentNode.appendChild(this.element);\n\n        var statusUpdate = lang.delayedCall(function(){\n            this.updateStatus(editor);\n        }.bind(this)).schedule.bind(null, 100);\n\n        editor.on(\"changeStatus\", statusUpdate);\n        editor.on(\"changeSelection\", statusUpdate);\n        editor.on(\"keyboardActivity\", statusUpdate);\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    updateStatus(editor) {\n        var status = [];\n        function add(str, separator) {\n            str && status.push(str, separator || \"|\");\n        }\n        // @ts-expect-error TODO: potential wrong argument\n        add(editor.keyBinding.getStatusText(editor));\n        if (editor.commands.recording)\n            add(\"REC\");\n        \n        var sel = editor.selection;\n        var c = sel.lead;\n        \n        if (!sel.isEmpty()) {\n            var r = editor.getSelectionRange();\n            add(\"(\" + (r.end.row - r.start.row) + \":\"  +(r.end.column - r.start.column) + \")\", \" \");\n        }\n        add(c.row + \":\" + c.column, \" \");        \n        if (sel.rangeCount)\n            add(\"[\" + sel.rangeCount + \"]\", \" \");\n        status.pop();\n        this.element.textContent = status.join(\"\");\n    }\n}\n\nexports.StatusBar = StatusBar;\n"
  },
  {
    "path": "src/ext/textarea.js",
    "content": "/**\n * ## Textarea transformation extension\n *\n * Transforms HTML textarea elements into fully-featured Ace editor instances while maintaining form compatibility\n * and providing an interactive settings panel. Handles automatic resizing, form submission integration, and\n * preserves the original textarea's styling properties. Includes a visual settings interface for configuring\n * editor options like themes, modes, keybindings, and display preferences through an overlay panel.\n *\n * **Usage:**\n * ```javascript\n * var ace = require(\"ace/ext/textarea\");\n * var editor = ace.transformTextarea(textareaElement, {\n *   mode: \"javascript\",\n *   theme: \"monokai\",\n *   wrap: true\n * });\n * ```\n *\n * @module\n */\n\n\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar UA = require(\"../lib/useragent\");\nvar ace = require(\"../ace\");\n\nmodule.exports = exports = ace;\n\n/**\n * @typedef {Object} TextAreaOptions\n * @property {string} [mode] - Programming language mode for syntax highlighting (e.g., \"javascript\", \"html\", \"css\")\n * @property {string} [theme] - Visual theme for the editor appearance (e.g., \"textmate\", \"monokai\", \"eclipse\")\n * @property {string|number} [wrap] - Line wrapping behavior - \"off\", \"free\", or specific column number like \"40\", \"80\"\n * @property {string} [fontSize] - Font size in CSS units (e.g., \"12px\", \"14px\", \"16px\")\n * @property {boolean|string} [showGutter] - Whether to display the line number gutter on the left side\n * @property {string} [keybindings] - Keyboard handler/bindings to use - \"ace\", \"vim\", or \"emacs\"\n * @property {boolean|string} [showPrintMargin] - Whether to show the print margin indicator line\n * @property {boolean|string} [useSoftTabs] - Whether to use soft tabs (spaces) instead of hard tabs\n * @property {boolean|string} [showInvisibles] - Whether to show invisible characters like spaces and tabs\n */\n\n/**\n * Returns the CSS property of element.\n *   1) If the CSS property is on the style object of the element, use it, OR\n *   2) Compute the CSS property\n *\n * If the property can't get computed, is 'auto' or 'intrinsic', the former\n * calculated property is used (this can happen in cases where the textarea\n * is hidden and has no dimension styles).\n * @param {HTMLElement} element\n * @param {HTMLElement} container\n * @param {string} property\n */\nvar getCSSProperty = function(element, container, property) {\n    var ret = element.style[property];\n\n    if (!ret) {\n        if (window.getComputedStyle) {\n            ret = window.getComputedStyle(element, '').getPropertyValue(property);\n        } else {\n            // @ts-ignore\n            ret = element.currentStyle[property];\n        }\n    }\n\n    if (!ret || ret == 'auto' || ret == 'intrinsic') {\n        ret = container.style[property];\n    }\n    return ret;\n};\n\n/**\n * @param {HTMLElement} elm\n * @param {Object} styles\n */\nfunction applyStyles(elm, styles) {\n    for (var style in styles) {\n        elm.style[style] = styles[style];\n    }\n}\n\nfunction setupContainer(element, getValue) {\n    if (element.type != 'textarea') {\n        throw new Error(\"Textarea required!\");\n    }\n\n    var parentNode = element.parentNode;\n\n    // This will hold the editor.\n    var container = document.createElement('div');\n\n    // To put Ace in the place of the textarea, we have to copy a few of the\n    // textarea's style attributes to the div container.\n    //\n    // The problem is that the properties have to get computed (they might be\n    // defined by a CSS file on the page - you can't access such rules that\n    // apply to an element via elm.style). Computed properties are converted to\n    // pixels although the dimension might be given as percentage. When the\n    // window resizes, the dimensions defined by percentages changes, so the\n    // properties have to get recomputed to get the new/true pixels.\n    var resizeEvent = function() {\n        var style = 'position:relative;';\n        [\n            'margin-top', 'margin-left', 'margin-right', 'margin-bottom'\n        ].forEach(function(item) {\n            style += item + ':' +\n                        getCSSProperty(element, container, item) + ';';\n        });\n\n        // Calculating the width/height of the textarea is somewhat tricky. To\n        // do it right, you have to include the paddings to the sides as well\n        // (eg. width = width + padding-left, -right).  This works well, as\n        // long as the width of the element is not set or given in pixels. In\n        // this case and after the textarea is hidden, getCSSProperty(element,\n        // container, 'width') will still return pixel value. If the element\n        // has realtiv dimensions (e.g. width='95<percent>')\n        // getCSSProperty(...) will return pixel values only as long as the\n        // textarea is visible. After it is hidden getCSSProperty will return\n        // the relative dimensions as they are set on the element (in the case\n        // of width, 95<percent>).\n        // Making the sum of pixel vaules (e.g. padding) and realtive values\n        // (e.g. <percent>) is not possible. As such the padding styles are\n        // ignored.\n\n        // The complete width is the width of the textarea + the padding\n        // to the left and right.\n        var width = getCSSProperty(element, container, 'width') || (element.clientWidth + \"px\");\n        var height = getCSSProperty(element, container, 'height')  || (element.clientHeight + \"px\");\n        style += 'height:' + height + ';width:' + width + ';';\n\n        // Set the display property to 'inline-block'.\n        style += 'display:inline-block;';\n        container.style.cssText = style;\n    };\n    event.addListener(window, 'resize', resizeEvent);\n\n    // Call the resizeEvent once, so that the size of the container is\n    // calculated.\n    resizeEvent();\n\n    // Insert the div container after the element.\n    parentNode.insertBefore(container, element.nextSibling);\n\n    // Override the forms onsubmit function. Set the innerHTML and value\n    // of the textarea before submitting.\n    while (parentNode !== document) {\n        if (parentNode.tagName.toUpperCase() === 'FORM') {\n            var oldSumit = parentNode.onsubmit;\n            // Override the onsubmit function of the form.\n            parentNode.onsubmit = function(evt) {\n                element.value = getValue();\n                // If there is a onsubmit function already, then call\n                // it with the current context and pass the event.\n                if (oldSumit) {\n                    oldSumit.call(this, evt);\n                }\n            };\n            break;\n        }\n        parentNode = parentNode.parentNode;\n    }\n    return container;\n}\n\n/**\n * Transforms a textarea element into an Ace editor instance.\n *\n * This function replaces the original textarea with an Ace editor,\n * preserving the textarea's initial value and focus state. It creates\n * a container with settings panel and provides full editor functionality.\n *\n * @param {HTMLTextAreaElement} element - The textarea element to transform\n * @param {TextAreaOptions} [options] - Optional configuration options for the editor\n * @returns {import(\"../editor\").Editor} The created Ace editor instance\n */\nexports.transformTextarea = function(element, options) {\n    var isFocused = element.autofocus || document.activeElement == element;\n    var session;\n    var container = setupContainer(element, function() {\n        return session.getValue();\n    });\n\n    // Hide the element.\n    element.style.display = 'none';\n    container.style.background = 'white';\n\n    //\n    var editorDiv = document.createElement(\"div\");\n    applyStyles(editorDiv, {\n        top: \"0px\",\n        left: \"0px\",\n        right: \"0px\",\n        bottom: \"0px\",\n        border: \"1px solid gray\",\n        position: \"absolute\"\n    });\n    container.appendChild(editorDiv);\n\n    var settingOpener = document.createElement(\"div\");\n    applyStyles(settingOpener, {\n        position: \"absolute\",\n        right: \"0px\",\n        bottom: \"0px\",\n        cursor: \"nw-resize\",\n        border: \"solid 9px\",\n        borderColor: \"lightblue gray gray #ceade6\",\n        zIndex: 101\n    });\n\n    var settingDiv = document.createElement(\"div\");\n    var settingDivStyles = {\n        top: \"0px\",\n        left: \"20%\",\n        right: \"0px\",\n        bottom: \"0px\",\n        position: \"absolute\",\n        padding: \"5px\",\n        zIndex: 100,\n        color: \"white\",\n        display: \"none\",\n        overflow: \"auto\",\n        fontSize: \"14px\",\n        boxShadow: \"-5px 2px 3px gray\"\n    };\n    if (!UA.isOldIE) {\n        settingDivStyles.backgroundColor = \"rgba(0, 0, 0, 0.6)\";\n    } else {\n        settingDivStyles.backgroundColor = \"#333\";\n    }\n\n    applyStyles(settingDiv, settingDivStyles);\n    container.appendChild(settingDiv);\n\n    options = options || exports.defaultOptions;\n    // Power up ace on the textarea:\n    var editor = ace.edit(editorDiv);\n    session = editor.getSession();\n\n    session.setValue(element.value || element.innerHTML);\n    if (isFocused)\n        editor.focus();\n\n    // Add the settingPanel opener to the editor's div.\n    container.appendChild(settingOpener);\n\n    // Create the API.\n    setupApi(editor, editorDiv, settingDiv, ace, options);\n\n    // Create the setting's panel.\n    setupSettingPanel(settingDiv, settingOpener, editor);\n\n    var state = \"\";\n    event.addListener(settingOpener, \"mousemove\", function(e) {\n        var rect = this.getBoundingClientRect();\n        var x = e.clientX - rect.left, y = e.clientY - rect.top;\n        if (x + y < (rect.width + rect.height)/2) {\n            this.style.cursor = \"pointer\";\n            state = \"toggle\";\n        } else {\n            state = \"resize\";\n            this.style.cursor = \"nw-resize\";\n        }\n    });\n\n    event.addListener(settingOpener, \"mousedown\", function(e) {\n        e.preventDefault();\n        if (state == \"toggle\") {\n            editor.setDisplaySettings();\n            return;\n        }\n        container.style.zIndex = \"100000\";\n        var rect = container.getBoundingClientRect();\n        var startX = rect.width  + rect.left - e.clientX;\n        var startY = rect.height  + rect.top - e.clientY;\n        event.capture(settingOpener, function(e) {\n            container.style.width = e.clientX - rect.left + startX + \"px\";\n            container.style.height = e.clientY - rect.top + startY + \"px\";\n            editor.resize();\n        }, function() {});\n    });\n\n    return editor;\n};\n\nfunction setupApi(editor, editorDiv, settingDiv, ace, options) {\n    function toBool(value) {\n        return value === \"true\" || value == true;\n    }\n\n    editor.setDisplaySettings = function(display) {\n        if (display == null)\n            display = settingDiv.style.display == \"none\";\n        if (display) {\n            settingDiv.style.display = \"block\";\n            settingDiv.hideButton.focus();\n            editor.on(\"focus\", function onFocus() {\n                editor.removeListener(\"focus\", onFocus);\n                settingDiv.style.display = \"none\";\n            });\n        } else {\n            editor.focus();\n        }\n    };\n\n    editor.$setOption = editor.setOption;\n    editor.$getOption = editor.getOption;\n    editor.setOption = function(key, value) {\n        switch (key) {\n            case \"mode\":\n                editor.$setOption(\"mode\", \"ace/mode/\" + value);\n            break;\n            case \"theme\":\n                editor.$setOption(\"theme\", \"ace/theme/\" + value);\n            break;\n            case \"keybindings\":\n                switch (value) {\n                    case \"vim\":\n                        editor.setKeyboardHandler(\"ace/keyboard/vim\");\n                        break;\n                    case \"emacs\":\n                        editor.setKeyboardHandler(\"ace/keyboard/emacs\");\n                        break;\n                    default:\n                        editor.setKeyboardHandler(null);\n                }\n            break;\n\n            case \"wrap\":\n            case \"fontSize\":\n                editor.$setOption(key, value);\n            break;\n            \n            default:\n                editor.$setOption(key, toBool(value));\n        }\n    };\n\n    editor.getOption = function(key) {\n        switch (key) {\n            case \"mode\":\n                return editor.$getOption(\"mode\").substr(\"ace/mode/\".length);\n            break;\n\n            case \"theme\":\n                return editor.$getOption(\"theme\").substr(\"ace/theme/\".length);\n            break;\n\n            case \"keybindings\":\n                var value = editor.getKeyboardHandler();\n                switch (value && value.$id) {\n                    case \"ace/keyboard/vim\":\n                        return \"vim\";\n                    case \"ace/keyboard/emacs\":\n                        return \"emacs\";\n                    default:\n                        return \"ace\";\n                }\n            break;\n\n            default:\n                return editor.$getOption(key);\n        }\n    };\n\n    editor.setOptions(options);\n    return editor;\n}\n\nfunction setupSettingPanel(settingDiv, settingOpener, editor) {\n    var BOOL = null;\n\n    var desc = {\n        mode:            \"Mode:\",\n        wrap:            \"Soft Wrap:\",\n        theme:           \"Theme:\",\n        fontSize:        \"Font Size:\",\n        showGutter:      \"Display Gutter:\",\n        keybindings:     \"Keyboard\",\n        showPrintMargin: \"Show Print Margin:\",\n        useSoftTabs:     \"Use Soft Tabs:\",\n        showInvisibles:  \"Show Invisibles\"\n    };\n\n    var optionValues = {\n        mode: {\n            text:       \"Plain\",\n            javascript: \"JavaScript\",\n            xml:        \"XML\",\n            html:       \"HTML\",\n            css:        \"CSS\",\n            scss:       \"SCSS\",\n            python:     \"Python\",\n            php:        \"PHP\",\n            java:       \"Java\",\n            ruby:       \"Ruby\",\n            c_cpp:      \"C/C++\",\n            coffee:     \"CoffeeScript\",\n            json:       \"json\",\n            perl:       \"Perl\",\n            clojure:    \"Clojure\",\n            ocaml:      \"OCaml\",\n            csharp:     \"C#\",\n            haxe:       \"haXe\",\n            svg:        \"SVG\",\n            textile:    \"Textile\",\n            groovy:     \"Groovy\",\n            liquid:     \"Liquid\",\n            Scala:      \"Scala\"\n        },\n        theme: {\n            clouds:           \"Clouds\",\n            clouds_midnight:  \"Clouds Midnight\",\n            cobalt:           \"Cobalt\",\n            crimson_editor:   \"Crimson Editor\",\n            dawn:             \"Dawn\",\n            gob:              \"Green on Black\",\n            eclipse:          \"Eclipse\",\n            idle_fingers:     \"Idle Fingers\",\n            kr_theme:         \"Kr Theme\",\n            merbivore:        \"Merbivore\",\n            merbivore_soft:   \"Merbivore Soft\",\n            mono_industrial:  \"Mono Industrial\",\n            monokai:          \"Monokai\",\n            pastel_on_dark:   \"Pastel On Dark\",\n            solarized_dark:   \"Solarized Dark\",\n            solarized_light:  \"Solarized Light\",\n            textmate:         \"Textmate\",\n            twilight:         \"Twilight\",\n            vibrant_ink:      \"Vibrant Ink\"\n        },\n        showGutter: BOOL,\n        fontSize: {\n            \"10px\": \"10px\",\n            \"11px\": \"11px\",\n            \"12px\": \"12px\",\n            \"14px\": \"14px\",\n            \"16px\": \"16px\"\n        },\n        wrap: {\n            off:    \"Off\",\n            40:     \"40\",\n            80:     \"80\",\n            free:   \"Free\"\n        },\n        keybindings: {\n            ace: \"ace\",\n            vim: \"vim\",\n            emacs: \"emacs\"\n        },\n        showPrintMargin:    BOOL,\n        useSoftTabs:        BOOL,\n        showInvisibles:     BOOL\n    };\n\n    var table = [];\n    table.push(\"<table><tr><th>Setting</th><th>Value</th></tr>\");\n\n    function renderOption(builder, option, obj, cValue) {\n        if (!obj) {\n            builder.push(\n                \"<input type='checkbox' title='\", option, \"' \",\n                    cValue + \"\" == \"true\" ? \"checked='true'\" : \"\",\n               \"'></input>\"\n            );\n            return;\n        }\n        builder.push(\"<select title='\" + option + \"'>\");\n        for (var value in obj) {\n            builder.push(\"<option value='\" + value + \"' \");\n\n            if (cValue == value) {\n                builder.push(\" selected \");\n            }\n\n            builder.push(\">\",\n                obj[value],\n                \"</option>\");\n        }\n        builder.push(\"</select>\");\n    }\n\n    for (var option in exports.defaultOptions) {\n        table.push(\"<tr><td>\", desc[option], \"</td>\");\n        table.push(\"<td>\");\n        renderOption(table, option, optionValues[option], editor.getOption(option));\n        table.push(\"</td></tr>\");\n    }\n    table.push(\"</table>\");\n    settingDiv.innerHTML = table.join(\"\");\n\n    var onChange = function(e) {\n        var select = e.currentTarget;\n        editor.setOption(select.title, select.value);\n    };\n    var onClick = function(e) {\n        var cb = e.currentTarget;\n        editor.setOption(cb.title, cb.checked);\n    };\n    var selects = settingDiv.getElementsByTagName(\"select\");\n    for (var i = 0; i < selects.length; i++)\n        selects[i].onchange = onChange;\n    var cbs = settingDiv.getElementsByTagName(\"input\");\n    for (var i = 0; i < cbs.length; i++)\n        cbs[i].onclick = onClick;\n\n\n    var button = document.createElement(\"input\");\n    button.type = \"button\";\n    button.value = \"Hide\";\n    event.addListener(button, \"click\", function() {\n        editor.setDisplaySettings(false);\n    });\n    settingDiv.appendChild(button);\n    settingDiv.hideButton = button;\n}\n\n/**\n * Default startup options.\n * @type {TextAreaOptions}\n */\nexports.defaultOptions = {\n    mode:               \"javascript\",\n    theme:              \"textmate\",\n    wrap:               \"off\",\n    fontSize:           \"12px\",\n    showGutter:         \"false\",\n    keybindings:        \"ace\",\n    showPrintMargin:    \"false\",\n    useSoftTabs:        \"true\",\n    showInvisibles:     \"false\"\n};\n"
  },
  {
    "path": "src/ext/themelist.js",
    "content": "/**\n * ## Theme enumeration utility\n *\n * Provides theme management for the Ace Editor by generating and organizing available themes into\n * categorized collections. Automatically maps theme data into structured objects containing theme metadata including\n * display captions, theme paths, brightness classification (dark/light), and normalized names. Exports both an\n * indexed theme collection and a complete themes array for easy integration with theme selection components\n * and configuration systems.\n *\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n * @module\n */\n/**\n * Generates a list of themes available when ace was built.\n * @fileOverview Generates a list of themes available when ace was built.\n * @author <a href=\"mailto:matthewkastor@gmail.com\">\n *  Matthew Christopher Kastor-Inare III </a><br />\n *  ☭ Hial Atropa!! ☭\n */\n\n\"use strict\";\n\n/**\n * @typedef {Object} Theme\n * @property {string} caption - The display caption of the theme.\n * @property {string} theme   - The path or identifier for the ACE theme.\n * @property {boolean} isDark - Indicates whether the theme is dark or light.\n * @property {string} name    - The normalized name used as the key.\n */\n\nvar themeData = [\n    [\"Chrome\"         ],\n    [\"Clouds\"         ],\n    [\"Crimson Editor\" ],\n    [\"Dawn\"           ],\n    [\"Dreamweaver\"    ],\n    [\"Eclipse\"        ],\n    [\"GitHub Light Default\" ],\n    [\"GitHub (Legacy)\"      ,\"github\"                  , \"light\"],\n    [\"IPlastic\"       ],\n    [\"Solarized Light\"],\n    [\"TextMate\"       ],\n    [\"Tomorrow\"       ],\n    [\"XCode\"          ],\n    [\"Kuroir\"],\n    [\"KatzenMilch\"],\n    [\"SQL Server\"           ,\"sqlserver\"               , \"light\"],\n    [\"CloudEditor\"          ,\"cloud_editor\"            , \"light\"],\n    [\"Ambiance\"             ,\"ambiance\"                ,  \"dark\"],\n    [\"Chaos\"                ,\"chaos\"                   ,  \"dark\"],\n    [\"Clouds Midnight\"      ,\"clouds_midnight\"         ,  \"dark\"],\n    [\"Dracula\"              ,\"\"                        ,  \"dark\"],\n    [\"Cobalt\"               ,\"cobalt\"                  ,  \"dark\"],\n    [\"Gruvbox\"              ,\"gruvbox\"                 ,  \"dark\"],\n    [\"Green on Black\"       ,\"gob\"                     ,  \"dark\"],\n    [\"idle Fingers\"         ,\"idle_fingers\"            ,  \"dark\"],\n    [\"krTheme\"              ,\"kr_theme\"                ,  \"dark\"],\n    [\"Merbivore\"            ,\"merbivore\"               ,  \"dark\"],\n    [\"Merbivore Soft\"       ,\"merbivore_soft\"          ,  \"dark\"],\n    [\"Mono Industrial\"      ,\"mono_industrial\"         ,  \"dark\"],\n    [\"Monokai\"              ,\"monokai\"                 ,  \"dark\"],\n    [\"Nord Dark\"            ,\"nord_dark\"               ,  \"dark\"],\n    [\"One Dark\"             ,\"one_dark\"                ,  \"dark\"],\n    [\"Pastel on dark\"       ,\"pastel_on_dark\"          ,  \"dark\"],\n    [\"Solarized Dark\"       ,\"solarized_dark\"          ,  \"dark\"],\n    [\"Terminal\"             ,\"terminal\"                ,  \"dark\"],\n    [\"Tomorrow Night\"       ,\"tomorrow_night\"          ,  \"dark\"],\n    [\"Tomorrow Night Blue\"  ,\"tomorrow_night_blue\"     ,  \"dark\"],\n    [\"Tomorrow Night Bright\",\"tomorrow_night_bright\"   ,  \"dark\"],\n    [\"Tomorrow Night 80s\"   ,\"tomorrow_night_eighties\" ,  \"dark\"],\n    [\"Twilight\"             ,\"twilight\"                ,  \"dark\"],\n    [\"Vibrant Ink\"          ,\"vibrant_ink\"             ,  \"dark\"],\n    [\"GitHub Dark\"          ,\"github_dark\"             ,  \"dark\"],\n    [\"CloudEditor Dark\"     ,\"cloud_editor_dark\"       ,  \"dark\"]\n];\n\n/**\n * @type {Object<string, Theme>}\n */\nexports.themesByName = {};\n\n/**\n * An array containing information about available themes.\n * @type {Theme[]}\n */\nexports.themes = themeData.map(function(data) {\n    var name = data[1] || data[0].replace(/ /g, \"_\").toLowerCase();\n    var theme = {\n        caption: data[0],\n        theme: \"ace/theme/\" + name,\n        isDark: data[2] == \"dark\",\n        name: name\n    };\n    exports.themesByName[name] = theme;\n    return theme;\n});\n"
  },
  {
    "path": "src/ext/whitespace.js",
    "content": "/**\n * ## Whitespace management and indentation utilities extension\n *\n * Provides whitespace handling capabilities including automatic indentation detection, trailing whitespace trimming,\n * and indentation format conversion. Analyzes code patterns to determine optimal tab settings and offers commands for\n * maintaining consistent code formatting across different indentation styles (spaces vs. tabs) and sizes.\n *\n * @module\n */\n\n\"use strict\";\n\n/**\n *\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n */\n\nvar lang = require(\"../lib/lang\");\n\n// based on http://www.freehackers.org/Indent_Finder\n/**\n * \n * @param {string[]} lines\n * @param [fallback]\n * @returns {{ch?: string, length?: number}}\n */\nexports.$detectIndentation = function(lines, fallback) {\n    var stats = [];\n    var changes = [];\n    var tabIndents = 0;\n    var prevSpaces = 0;\n    var max = Math.min(lines.length, 1000);\n    for (var i = 0; i < max; i++) {\n        var line = lines[i];\n        // ignore empty and comment lines\n        if (!/^\\s*[^*+\\-\\s]/.test(line))\n            continue;\n\n        if (line[0] == \"\\t\") {\n            tabIndents++;\n            prevSpaces = -Number.MAX_VALUE;\n        } else {\n            var spaces = line.match(/^ */)[0].length;\n            if (spaces && line[spaces] != \"\\t\") {\n                var diff = spaces - prevSpaces;\n                if (diff > 0 && !(prevSpaces%diff) && !(spaces%diff))\n                    changes[diff] = (changes[diff] || 0) + 1;\n    \n                stats[spaces] = (stats[spaces] || 0) + 1;\n            }\n            prevSpaces = spaces;\n        }\n        // ignore lines ending with backslash\n        while (i < max && line[line.length - 1] == \"\\\\\")\n            line = lines[i++];\n    }\n    \n    function getScore(indent) {\n        var score = 0;\n        for (var i = indent; i < stats.length; i += indent)\n            score += stats[i] || 0;\n        return score;\n    }\n\n    var changesTotal = changes.reduce(function(a,b){return a+b;}, 0);\n\n    var first = {score: 0, length: 0};\n    var spaceIndents = 0;\n    for (var i = 1; i < 12; i++) {\n        var score = getScore(i);\n        if (i == 1) {\n            spaceIndents = score;\n            score = stats[1] ? 0.9 : 0.8;\n            if (!stats.length)\n                score = 0;\n        } else\n            score /= spaceIndents;\n\n        if (changes[i])\n            score += changes[i] / changesTotal;\n\n        if (score > first.score)\n            first = {score: score, length: i};\n    }\n\n    if (first.score && first.score > 1.4)\n        var tabLength = first.length;\n\n    if (tabIndents > spaceIndents + 1) {\n        if (tabLength == 1 || spaceIndents < tabIndents / 4 || first.score < 1.8)\n            tabLength = undefined;\n        return {ch: \"\\t\", length: tabLength};\n    }\n    if (spaceIndents > tabIndents + 1)\n        return {ch: \" \", length: tabLength};\n};\n\n/**\n * Detects the indentation style of a document and configures the session accordingly.\n *\n * @param {EditSession} session The editing session to analyze and configure\n * @returns {{ch?: string, length?: number}|{}} An object containing detected indentation details (character and length)\n */\nexports.detectIndentation = function(session) {\n    var lines = session.getLines(0, 1000);\n    var indent = exports.$detectIndentation(lines) || {};\n\n    if (indent.ch)\n        session.setUseSoftTabs(indent.ch == \" \");\n\n    if (indent.length)\n        session.setTabSize(indent.length);\n    return indent;\n};\n\n/**\n * Removes trailing whitespace from all lines in the session.\n * @param {EditSession} session\n * @param {Object} options\n * @param {boolean} [options.trimEmpty] trim empty lines too\n * @param {boolean} [options.keepCursorPosition] do not trim whitespace before the cursor\n */\nexports.trimTrailingSpace = function(session, options) {\n    var doc = session.getDocument();\n    var lines = doc.getAllLines();\n    \n    var min = options && options.trimEmpty ? -1 : 0;\n    var cursors = [], ci = -1;\n    if (options && options.keepCursorPosition) {\n        if (session.selection.rangeCount) {\n            session.selection.rangeList.ranges.forEach(function(x, i, ranges) {\n               var next = ranges[i + 1];\n               if (next && next.cursor.row == x.cursor.row)\n                  return;\n              cursors.push(x.cursor);\n            });\n        } else {\n            cursors.push(session.selection.getCursor());\n        }\n        ci = 0;\n    }\n    var cursorRow = cursors[ci] && cursors[ci].row;\n\n    for (var i = 0, l=lines.length; i < l; i++) {\n        var line = lines[i];\n        var index = line.search(/\\s+$/);\n\n        if (i == cursorRow) {\n            if (index < cursors[ci].column && index > min)\n               index = cursors[ci].column;\n            ci++;\n            cursorRow = cursors[ci] ? cursors[ci].row : -1;\n        }\n\n        if (index > min)\n            doc.removeInLine(i, index, line.length);\n    }\n};\n\n/**\n * Converts indentation format throughout the session to use specified character and size.\n * @param {EditSession} session\n * @param {string} ch\n * @param {number} len\n */\nexports.convertIndentation = function(session, ch, len) {\n    var oldCh = session.getTabString()[0];\n    var oldLen = session.getTabSize();\n    if (!len) len = oldLen;\n    if (!ch) ch = oldCh;\n\n    var tab = ch == \"\\t\" ? ch: lang.stringRepeat(ch, len);\n\n    var doc = session.doc;\n    var lines = doc.getAllLines();\n\n    var cache = {};\n    var spaceCache = {};\n    for (var i = 0, l=lines.length; i < l; i++) {\n        var line = lines[i];\n        var match = line.match(/^\\s*/)[0];\n        if (match) {\n            var w = session.$getStringScreenWidth(match)[0];\n            var tabCount = Math.floor(w/oldLen);\n            var reminder = w%oldLen;\n            var toInsert = cache[tabCount] || (cache[tabCount] = lang.stringRepeat(tab, tabCount));\n            toInsert += spaceCache[reminder] || (spaceCache[reminder] = lang.stringRepeat(\" \", reminder));\n\n            if (toInsert != match) {\n                doc.removeInLine(i, 0, match.length);\n                doc.insertInLine({row: i, column: 0}, toInsert);\n            }\n        }\n    }\n    session.setTabSize(len);\n    session.setUseSoftTabs(ch == \" \");\n};\n\n/**\n * \n * @param {string} text\n * @returns {{}}\n */\nexports.$parseStringArg = function(text) {\n    var indent = {};\n    if (/t/.test(text))\n        indent.ch = \"\\t\";\n    else if (/s/.test(text))\n        indent.ch = \" \";\n    var m = text.match(/\\d+/);\n    if (m)\n        indent.length = parseInt(m[0], 10);\n    return indent;\n};\n\nexports.$parseArg = function(arg) {\n    if (!arg)\n        return {};\n    if (typeof arg == \"string\")\n        return exports.$parseStringArg(arg);\n    if (typeof arg.text == \"string\")\n        return exports.$parseStringArg(arg.text);\n    return arg;\n};\n\nexports.commands = [{\n    name: \"detectIndentation\",\n    description: \"Detect indentation from content\",\n    exec: function(editor) {\n        exports.detectIndentation(editor.session);\n        // todo show message?\n    }\n}, {\n    name: \"trimTrailingSpace\",\n    description: \"Trim trailing whitespace\",\n    exec: function(editor, args) {\n        exports.trimTrailingSpace(editor.session, args);\n    }\n}, {\n    name: \"convertIndentation\",\n    description: \"Convert indentation to ...\",\n    exec: function(editor, arg) {\n        var indent = exports.$parseArg(arg);\n        exports.convertIndentation(editor.session, indent.ch, indent.length);\n    }\n}, {\n    name: \"setIndentation\",\n    description: \"Set indentation\",\n    exec: function(editor, arg) {\n        var indent = exports.$parseArg(arg);\n        indent.length && editor.session.setTabSize(indent.length);\n        indent.ch && editor.session.setUseSoftTabs(indent.ch == \" \");\n    }\n}];\n"
  },
  {
    "path": "src/ext/whitespace_test.js",
    "content": "\"use strict\";\n\nrequire(\"../test/mockdom\");\nvar ace = require(\"../ace\");\nvar assert = require(\"assert\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar UndoManager = require(\"../undomanager\").UndoManager;\nvar whitespace = require(\"./whitespace\");\n\n// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite\nmodule.exports = {\n    timeout: 10000,\n\n    \"test tab detection\": function() {\n        var s = new EditSession([\n            \"define({\",\n            \"\\tfoo:1,\",\n            \"\\tbar:2,\",\n            \"\\tbaz:{,\",\n            \"\\t\\tx:3\",\n            \"\\t}\",\n            \"})\"\n        ]);\n         \n        var indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \"\\t\");\n        assert.equal(indent.length, undefined);\n        \n        s.insert({row: 0, column: 0}, \"  \");\n        indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \"\\t\");\n        assert.equal(indent.length, undefined);\n        s.doc.removeInLine(0, 0, 2);\n        \n        s.insert({row: 0, column: 0}, \"x\\n    y\\n        z\\n\");\n        indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \"\\t\");\n        assert.equal(indent.length, 4);\n        \n        s.setValue(\"\");\n        indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.ok(!indent);\n    },\n\n    \"test empty session\": function() {\n        var s = new EditSession([\n            \"define({\",\n            \"foo:1,\",\n            \"})\"\n        ]);\n        var indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.ok(!indent);\n        s.insert({row: 1, column: 0}, \"    x\\n    \");\n        \n        indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \" \");\n        assert.equal(indent.length, 4);\n    },\n    \n    \"!test one line\": function() {\n        var s = new EditSession([\n            \"define({\",\n            \"    foo:1,\",\n            \"})\"\n        ]);\n        var indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \" \");\n        assert.equal(indent.length, 4);\n    },\n    \n    \"test 1 width indents\": function() {\n        var s = new EditSession([\n            \"define({\",\n            \"    foo:1,\",\n            \"})\",\n            \"define({\",\n            \"    bar:1,\",\n            \"})\",\n            \"     t\",\n            \"      t\",\n            \"     t\",\n            \"      t\",\n            \"     t\",\n            \"      t\",\n            \"     t\",\n            \"      t\"\n        ]);\n        var indent = whitespace.$detectIndentation(s.doc.$lines);\n        // assert.equal(indent.ch, \" \");\n        // assert.equal(indent.length, 4);\n        \n        s = new EditSession([\n            \"{\",\n            \" foo:1,\",\n            \" bar: {\",\n            \"  baz:2\",\n            \" }\",\n            \"}\"\n        ]);\n        indent = whitespace.$detectIndentation(s.doc.$lines);\n        assert.equal(indent.ch, \" \");\n        assert.equal(indent.length, 1);\n    },\n\n    \"test trimTrailingSpace\": function() {\n        var session = new EditSession([\n            \"a\",\n            \"\\t b \\t\",\n            \"    \",\n            \"\\t\",\n            \"\\t\\tx\\t\\t\",\n            \" \",\n            \"   \"\n        ]);\n        session.setUndoManager(new UndoManager());\n        \n        function testOne(value, options) {\n            whitespace.trimTrailingSpace(session, options);\n            assert.equal(value, session.getValue());\n            session.markUndoGroup();\n            session.getUndoManager().undo();\n        }\n        \n        testOne(\"a\\n\\t b\\n    \\n\\t\\n\\t\\tx\\n \\n   \");\n        \n        testOne(\"a\\n\\t b\\n\\n\\n\\t\\tx\\n\\n\", {\n            trimEmpty: true\n        });\n        \n        session.selection.fromJSON([{\n            start: {row:2,column:3},\n            end: {row:4,column:4}\n        }]);\n        testOne(\"a\\n\\t b\\n\\n\\n\\t\\tx\\t\\n\\n\", {\n            keepCursorPosition: true,\n            trimEmpty: true\n        });\n        \n        session.selection.fromJSON([{\n            start: {row:2,column:3},\n            end: {row:4,column:4},\n            isBackwards: true\n        }]);\n        testOne(\"a\\n\\t b\\n   \\n\\n\\t\\tx\\n\\n\", {\n            keepCursorPosition: true,\n            trimEmpty: true\n        });\n        \n        session.selection.$initRangeList();\n        session.selection.fromJSON([{\n            start: {row:2, column:3},\n            end: {row:2,column:3}\n        }, {\n            start: {row:1, column:1},\n            end: {row:1, column:1}\n        }, {\n            start: {row:2,column:2},\n            end: {row:2,column:2}\n        }, {\n            start: {row:0,column:5},\n            end: {row:0,column:5},\n            isBackwards:false\n        }, {\n            start: {row:6,column:1},\n            end: {row:6,column:1},\n            isBackwards:false\n        }]);\n        testOne(\"a\\n\\t b\\n   \\n\\n\\t\\tx\\n\\n \", {\n            trimEmpty: true,\n            keepCursorPosition: true\n        });\n        \n        session.setValue(\"some text\");\n        session.selection.fromJSON([{\n            start: {row:0,column:4},\n            end: {row:0,column:4}\n        }]);\n        testOne(\"some text\", {\n            keepCursorPosition: true,\n            trimEmpty: true\n        });\n    },\n\n    \"test convertIndentation\": function() {\n        var value = \"\\ta\\n\\t\\tb\\n\\t\\t\\n\\t\\tc\";\n        var editor = ace.edit(null, {value: value});\n        editor.commands.addCommands(whitespace.commands);\n        editor.execCommand(\"detectIndentation\");\n        editor.execCommand(\"convertIndentation\", \"s8\");\n        assert.equal(editor.getValue(), value.replace(/\\t/g, \"        \"));\n        editor.execCommand(\"setIndentation\", \"s4\");\n        editor.execCommand(\"convertIndentation\", \"t1\");\n        assert.equal(editor.getValue(), value.replace(/\\t/g, \"\\t\\t\"));\n        editor.execCommand(\"convertIndentation\", {text: \"space\"});\n        editor.execCommand(\"trimTrailingSpace\", {trimEmpty: true});\n        assert.equal(editor.getValue(), value.replace(/\\t/g, \"  \").replace(/ *$/gm, \"\"));\n    }\n\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/ext/whitespaces_in_selection.js",
    "content": "/**\n * ## Show whitespaces in the current selection\n *\n * This extension adds a configuration option `showWhitespacesInSelection` to the editor\n * that highlights whitespaces within the current selection. When enabled, it adds a\n * marker to the selection that makes whitespaces visible.\n */\n\n\"use strict\";\n\nrequire(\"../layer/text_markers\");\nvar Editor = require(\"../editor\").Editor;\nvar config = require(\"../config\");\nvar dom = require(\"../lib/dom\");\n\ndom.importCssString(`\n.ace_whitespaces_in_selection {\n    color: rgba(0,0,0,0.29);\n}\n\n.ace_dark .ace_whitespaces_in_selection {\n    color: rgba(187, 181, 181, 0.5);\n}\n`, \"ace_whitespaces_in_selection\", false);\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    showWhitespacesInSelection: {\n        set: function(val) {\n            this.$showWhitespacesInSelection = val;\n\n            if (val) {\n                if (!this.$boundChangeSelectionForWhitespace) {\n                    this.$boundChangeSelectionForWhitespace = $onChangeSelectionForWhitespace.bind(this);\n                }\n                this.on(\"changeSelection\", this.$boundChangeSelectionForWhitespace);\n            } else {\n                this.off(\"changeSelection\", this.$boundChangeSelectionForWhitespace);\n\n                if (this.session && this.session.$invisibleMarkerId) {\n                    this.session.removeTextMarker(this.session.$invisibleMarkerId);\n                    this.session.$invisibleMarkerId = null;\n                }\n\n                this.$boundChangeSelectionForWhitespace = null;\n            }\n        },\n        get: function() {\n            return this.$showWhitespacesInSelection;\n        },\n        initialValue: false\n    }\n});\n\nfunction $onChangeSelectionForWhitespace() {\n    let invisibleMarkerId = this.session.$invisibleMarkerId;\n    if (invisibleMarkerId) {\n        this.session.removeTextMarker(invisibleMarkerId);\n        this.session.$invisibleMarkerId = null;\n    }\n\n    var currentRange = this.selection.getRange();\n    if (!currentRange.isEmpty()) {\n        this.session.$invisibleMarkerId = this.session.addTextMarker(\n            currentRange,\n            \"ace_whitespaces_in_selection\",\n            \"invisible\"\n        );\n    }\n}"
  },
  {
    "path": "src/ext/whitespaces_in_selection_test.js",
    "content": "\"use strict\";\n\nrequire(\"../test/mockdom\");\nvar assert = require(\"assert\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Editor = require(\"../editor\").Editor;\nvar MockRenderer = require(\"../test/mockrenderer\").MockRenderer;\nrequire(\"./whitespaces_in_selection\");\n\nmodule.exports = {\n    setUp: function() {\n        this.session = new EditSession(\"hello world\\n    with spaces\");\n        this.editor = new Editor(new MockRenderer(), this.session);\n    },\n\n    tearDown: function() {\n        this.session.destroy();\n    },\n\n    \"test: turning on extension\": function() {\n        assert.equal(this.editor.getOption(\"showWhitespacesInSelection\"), false);\n        this.editor.setOption(\"showWhitespacesInSelection\", true);\n        assert.equal(this.editor.getOption(\"showWhitespacesInSelection\"), true);\n\n        assert.ok(this.editor.$boundChangeSelectionForWhitespace);\n    },\n\n    \"test: turning off extension\": function() {\n        this.editor.setOption(\"showWhitespacesInSelection\", true);\n        assert.equal(this.editor.getOption(\"showWhitespacesInSelection\"), true);\n        this.editor.selection.setRange({start: {row: 0, column: 0}, end: {row: 0, column: 5}});\n\n        this.editor.setOption(\"showWhitespacesInSelection\", false);\n        assert.equal(this.editor.getOption(\"showWhitespacesInSelection\"), false);\n\n        assert.equal(this.editor.$boundChangeSelectionForWhitespace, null);\n    },\n\n    \"test: marker present after selection\": function() {\n        this.editor.setOption(\"showWhitespacesInSelection\", true);\n\n        this.editor.selection.setRange({start: {row: 0, column: 0}, end: {row: 0, column: 5}});\n\n        assert.ok(this.session.$invisibleMarkerId);\n\n        var markers = this.session.getTextMarkers();\n        assert.ok(markers[this.session.$invisibleMarkerId]);\n        assert.equal(markers[this.session.$invisibleMarkerId].className, \"ace_whitespaces_in_selection\");\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/incremental_search.js",
    "content": "\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar Search = require(\"./search\").Search;\nvar SearchHighlight = require(\"./search_highlight\").SearchHighlight;\nvar iSearchCommandModule = require(\"./commands/incremental_search_commands\");\nvar ISearchKbd = iSearchCommandModule.IncrementalSearchKeyboardHandler;\n\n// regexp handling\n\nfunction isRegExp(obj) {\n    return obj instanceof RegExp;\n}\n\n/**\n * @param {RegExp} re\n */\nfunction regExpToObject(re) {\n    var string = String(re),\n        start = string.indexOf('/'),\n        flagStart = string.lastIndexOf('/');\n    return {\n        expression: string.slice(start+1, flagStart),\n        flags: string.slice(flagStart+1)\n    };\n}\n\n/**\n * @param {string} string\n * @param {string} flags\n * @return {RegExp|string}\n */\nfunction stringToRegExp(string, flags) {\n    try {\n        return new RegExp(string, flags);\n    } catch (e) { return string; }\n}\n\nfunction objectToRegExp(obj) {\n    return stringToRegExp(obj.expression, obj.flags);\n}\n\n/**\n * Implements immediate searching while the user is typing. When incremental\n * search is activated, keystrokes into the editor will be used for composing\n * a search term. Immediately after every keystroke the search is updated:\n * - so-far-matching characters are highlighted\n * - the cursor is moved to the next match\n *\n **/\nclass IncrementalSearch extends Search {\n    /**\n     * Creates a new `IncrementalSearch` object.\n     **/\n    constructor() {\n        super();\n        this.$options = {wrap: false, skipCurrent: false};\n        this.$keyboardHandler = new ISearchKbd(this);\n    }\n\n    /**\n     * @param {boolean} backwards\n     */\n    activate(editor, backwards) {\n        this.$editor = editor;\n        this.$startPos = this.$currentPos = editor.getCursorPosition();\n        this.$options.needle = '';\n        this.$options.backwards = backwards;\n        editor.keyBinding.addKeyboardHandler(this.$keyboardHandler);\n        // we need to completely intercept paste, just registering an event handler does not work\n        this.$originalEditorOnPaste = editor.onPaste;\n        editor.onPaste = this.onPaste.bind(this);\n        this.$mousedownHandler = editor.on('mousedown', this.onMouseDown.bind(this));\n        this.selectionFix(editor);\n        this.statusMessage(true);\n    }\n\n    /**\n     * @param {boolean} [reset]\n     */\n    deactivate(reset) {\n        this.cancelSearch(reset);\n        var editor = this.$editor;\n        editor.keyBinding.removeKeyboardHandler(this.$keyboardHandler);\n        if (this.$mousedownHandler) {\n            editor.off('mousedown', this.$mousedownHandler);\n            delete this.$mousedownHandler;\n        }\n        editor.onPaste = this.$originalEditorOnPaste;\n        this.message('');\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    selectionFix(editor) {\n        // Fix selection bug: When clicked inside the editor\n        // editor.selection.$isEmpty is false even if the mouse click did not\n        // open a selection. This is interpreted by the move commands to\n        // extend the selection. To only extend the selection when there is\n        // one, we clear it here\n        if (editor.selection.isEmpty() && !editor.session.$emacsMark) {\n            editor.clearSelection();\n        }\n    }\n\n    /**\n     * @param {RegExp} regexp\n     */\n    highlight(regexp) {\n        var sess = this.$editor.session,\n            hl = sess.$isearchHighlight = sess.$isearchHighlight || sess.addDynamicMarker(\n                new SearchHighlight(null, \"ace_isearch-result\", \"text\"));\n        hl.setRegexp(regexp);\n        sess._emit(\"changeBackMarker\"); // force highlight layer redraw\n    }\n\n    /**\n     * @param {boolean} [reset]\n     */\n    cancelSearch(reset) {\n        var e = this.$editor;\n        this.$prevNeedle = this.$options.needle;\n        this.$options.needle = '';\n        if (reset) {\n            e.moveCursorToPosition(this.$startPos);\n            this.$currentPos = this.$startPos;\n        } else {\n            e.pushEmacsMark && e.pushEmacsMark(this.$startPos, false);\n        }\n        this.highlight(null);\n        return Range.fromPoints(this.$currentPos, this.$currentPos);\n    }\n\n    /**\n     * @param {boolean} moveToNext\n     * @param {Function} needleUpdateFunc\n     */\n    highlightAndFindWithNeedle(moveToNext, needleUpdateFunc) {\n        if (!this.$editor) return null;\n        var options = this.$options;\n\n        // get search term\n        if (needleUpdateFunc) {\n            options.needle = needleUpdateFunc.call(this, options.needle || '') || '';\n        }\n        if (options.needle.length === 0) {\n            this.statusMessage(true);\n            return this.cancelSearch(true);\n        }\n\n        // try to find the next occurrence and enable  highlighting marker\n        options.start = this.$currentPos;\n        var session = this.$editor.session,\n            found = this.find(session),\n            shouldSelect = this.$editor.emacsMark ?\n                !!this.$editor.emacsMark() : !this.$editor.selection.isEmpty();\n        if (found) {\n            if (options.backwards) found = Range.fromPoints(found.end, found.start);\n            this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end));\n            if (moveToNext) this.$currentPos = found.end;\n            // highlight after cursor move, so selection works properly\n            this.highlight(options.re);\n        }\n\n        this.statusMessage(found);\n\n        return found;\n    }\n\n    /**\n     * @param {string} s\n     */\n    addString(s) {\n        return this.highlightAndFindWithNeedle(false, function(needle) {\n            if (!isRegExp(needle))\n              return needle + s;\n            var reObj = regExpToObject(needle);\n            reObj.expression += s;\n            return objectToRegExp(reObj);\n        });\n    }\n\n    /**\n     * @param {any} c\n     */\n    removeChar(c) {\n        return this.highlightAndFindWithNeedle(false, function(needle) {\n            if (!isRegExp(needle))\n              return needle.substring(0, needle.length-1);\n            var reObj = regExpToObject(needle);\n            reObj.expression = reObj.expression.substring(0, reObj.expression.length-1);\n            return objectToRegExp(reObj);\n        });\n    }\n\n    next(options) {\n        // try to find the next occurrence of whatever we have searched for\n        // earlier.\n        // options = {[backwards: BOOL], [useCurrentOrPrevSearch: BOOL]}\n        options = options || {};\n        this.$options.backwards = !!options.backwards;\n        this.$currentPos = this.$editor.getCursorPosition();\n        return this.highlightAndFindWithNeedle(true, function(needle) {\n            return options.useCurrentOrPrevSearch && needle.length === 0 ?\n                this.$prevNeedle || '' : needle;\n        });\n    }\n\n    /**\n     * @internal\n     */\n    onMouseDown(evt) {\n        // when mouse interaction happens then we quit incremental search\n        this.deactivate();\n        return true;\n    }\n\n    /**\n     * @param {string} text\n     * @internal\n     */\n    onPaste(text) {\n        this.addString(text);\n    }\n\n    convertNeedleToRegExp() {\n        return this.highlightAndFindWithNeedle(false, function(needle) {\n            return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig');\n        });\n    }\n\n    convertNeedleToString() {\n        return this.highlightAndFindWithNeedle(false, function(needle) {\n            return isRegExp(needle) ? regExpToObject(needle).expression : needle;\n        });\n    }\n\n    statusMessage(found) {\n        var options = this.$options, msg = '';\n        msg += options.backwards ? 'reverse-' : '';\n        msg += 'isearch: ' + options.needle;\n        msg += found ? '' : ' (not found)';\n        this.message(msg);\n    }\n\n    message(msg) {\n        if (this.$editor.showCommandLine) {\n            this.$editor.showCommandLine(msg);\n            this.$editor.focus();\n        }\n    }\n\n}\n\nexports.IncrementalSearch = IncrementalSearch;\n\n\n/**\n *\n * Config settings for enabling/disabling [[IncrementalSearch `IncrementalSearch`]].\n *\n **/\n\nvar dom = require('./lib/dom');\ndom.importCssString(`\n.ace_marker-layer .ace_isearch-result {\n  position: absolute;\n  z-index: 6;\n  box-sizing: border-box;\n}\ndiv.ace_isearch-result {\n  border-radius: 4px;\n  background-color: rgba(255, 200, 0, 0.5);\n  box-shadow: 0 0 4px rgb(255, 200, 0);\n}\n.ace_dark div.ace_isearch-result {\n  background-color: rgb(100, 110, 160);\n  box-shadow: 0 0 4px rgb(80, 90, 140);\n}`, \"incremental-search-highlighting\", false);\n\n// support for default keyboard handler\nvar commands = require(\"./commands/command_manager\");\n(function() {\n    this.setupIncrementalSearch = function(editor, val) {\n        if (this.usesIncrementalSearch == val) return;\n        this.usesIncrementalSearch = val;\n        var iSearchCommands = iSearchCommandModule.iSearchStartCommands;\n        var method = val ? 'addCommands' : 'removeCommands';\n        this[method](iSearchCommands);\n    };\n}).call(commands.CommandManager.prototype);\n\n// incremental search config option\nvar Editor = require(\"./editor\").Editor;\nrequire(\"./config\").defineOptions(Editor.prototype, \"editor\", {\n    useIncrementalSearch: {\n        set: function(val) {\n            this.keyBinding.$handlers.forEach(function(handler) {\n                if (handler.setupIncrementalSearch) {\n                    handler.setupIncrementalSearch(this, val);\n                }\n            });\n            this._emit('incrementalSearchSettingChanged', {isEnabled: val});\n        }\n    }\n});\n"
  },
  {
    "path": "src/incremental_search_test.js",
    "content": "\"use strict\";\n\nvar emacs = require('./keyboard/emacs');\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar Range = require(\"./range\").Range;\nvar MultiSelect = require(\"./multi_select\").MultiSelect;\nvar assert = require(\"./test/assertions\");\nvar IncrementalSearch = require(\"./incremental_search\").IncrementalSearch;\n\nrequire(\"./multi_select\");\n\nvar editor, iSearch;\nfunction testRanges(str, ranges) {\n    ranges = ranges || editor.selection.getAllRanges();\n    assert.equal(ranges + \"\", str + \"\");\n}\n\n// force \"rerender\"\nfunction callHighlighterUpdate() {\n    var session = editor.session,\n        ranges = [],\n        mockMarkerLayer = {\n            drawSingleLineMarker: function(_, markerRanges) {\n                ranges = ranges.concat(markerRanges);\n            }\n        };\n    session.$isearchHighlight.update([], mockMarkerLayer, session, {\n        firstRow: 0, lastRow: session.getRowLength()});\n    return ranges;\n}\n\nmodule.exports = {\n\n    name: \"ACE incremental_search.js\",\n\n    setUp: function() {\n        var session = new EditSession([\"abc123\", \"xyz124\"]);\n        editor = new Editor(new MockRenderer(), session);\n        new MultiSelect(editor);\n        iSearch = new IncrementalSearch();\n    },\n\n    \"test: keyboard handler setup\" : function() {\n        iSearch.activate(editor);\n        assert.equal(editor.getKeyboardHandler(), iSearch.$keyboardHandler);\n        iSearch.deactivate();\n        assert.notEqual(editor.getKeyboardHandler(), iSearch.$keyboardHandler);\n    },\n\n    \"test: isearch highlight setup\" : function() {\n        var sess = editor.session;\n        iSearch.activate(editor);\n        iSearch.highlight('foo');\n        var highl = sess.$isearchHighlight.id;\n        assert.ok(sess.$isearchHighlight, 'session has no isearch highlighter');\n        assert.equal(sess.getMarkers()[highl.id], highl.id, 'isearch highlight not in markers');\n        iSearch.deactivate();\n        iSearch.activate(editor);\n        iSearch.highlight('bar');\n        var highl2 = sess.$isearchHighlight.id;\n        assert.equal(highl2, highl, 'multiple isearch highlights');\n    },\n\n    \"test: find simple text incrementally\" : function() {\n        iSearch.activate(editor);\n        var range = iSearch.addString('1'), // \"1\"\n            highlightRanges = callHighlighterUpdate();\n        testRanges(\"Range: [0/3] -> [0/4]\", [range]);\n        testRanges(\"Range: [0/3] -> [0/4],Range: [1/3] -> [1/4]\", highlightRanges);\n\n        range = iSearch.addString('2'); // \"12\"\n        highlightRanges = callHighlighterUpdate();\n        testRanges(\"Range: [0/3] -> [0/5]\", [range]);\n        testRanges(\"Range: [0/3] -> [0/5],Range: [1/3] -> [1/5]\", highlightRanges);\n\n        range = iSearch.addString('3'); // \"123\"\n        highlightRanges = callHighlighterUpdate();\n        testRanges(\"Range: [0/3] -> [0/6]\", [range]);\n        testRanges(\"Range: [0/3] -> [0/6]\", highlightRanges);\n\n        range = iSearch.removeChar(); // \"12\"\n        highlightRanges = callHighlighterUpdate();\n        testRanges(\"Range: [0/3] -> [0/5]\", [range]);\n        testRanges(\"Range: [0/3] -> [0/5],Range: [1/3] -> [1/5]\", highlightRanges);\n    },\n\n    \"test: forward / backward\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        var range = iSearch.next();\n        testRanges(\"Range: [1/3] -> [1/5]\", [range]);\n\n        range = iSearch.next(); // nothing to find\n        testRanges(\"\", [range]);\n\n        range = iSearch.next({backwards: true}); // backwards\n        testRanges(\"Range: [1/5] -> [1/3]\", [range]);\n    },\n\n    \"test: cancelSearch\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        var range = iSearch.cancelSearch(true);\n        testRanges(\"Range: [0/0] -> [0/0]\", [range]);\n\n        iSearch.addString('1'); range = iSearch.addString('2');\n        testRanges(\"Range: [0/3] -> [0/5]\", [range]);\n    },\n\n    \"test: failing search keeps pos\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        var range = iSearch.addString('x');\n        testRanges(\"\", [range]);\n        assert.position(editor.getCursorPosition(), 0, 5);\n    },\n\n    \"test: backwards search\" : function() {\n        editor.moveCursorTo(1,0);\n        iSearch.activate(editor, true);\n        iSearch.addString('1'); var range = iSearch.addString('2');\n        testRanges(\"Range: [0/5] -> [0/3]\", [range]);\n        assert.position(editor.getCursorPosition(), 0, 3);\n    },\n\n    \"test: forwards then backwards, same result, reoriented range\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); var range = iSearch.addString('2');\n        testRanges(\"Range: [0/3] -> [0/5]\", [range]);\n        assert.position(editor.getCursorPosition(), 0, 5);\n\n        range = iSearch.next({backwards: true});\n        testRanges(\"Range: [0/5] -> [0/3]\", [range]);\n        assert.position(editor.getCursorPosition(), 0, 3);\n    },\n\n    \"test: reuse prev search via option\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        assert.position(editor.getCursorPosition(), 0, 5);\n        iSearch.deactivate();\n\n        iSearch.activate(editor);\n        iSearch.next({backwards: false, useCurrentOrPrevSearch: true});\n        assert.position(editor.getCursorPosition(), 1, 5);\n    },\n\n    \"test: don't extend selection range if selection is empty\" : function() {\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        testRanges(\"Range: [0/5] -> [0/5]\", [editor.getSelectionRange()]);\n    },\n\n    \"test: extend selection range if selection exists\" : function() {\n        iSearch.activate(editor);\n        editor.selection.selectTo(0, 1);\n        iSearch.addString('1'); iSearch.addString('2');\n        testRanges(\"Range: [0/0] -> [0/5]\", [editor.getSelectionRange()]);\n    },\n\n    \"test: extend selection in emacs mark mode\" : function() {\n        var emacs = require('./keyboard/emacs');\n        editor.keyBinding.addKeyboardHandler(emacs.handler);\n        emacs.handler.commands.setMark.exec(editor);\n        iSearch.activate(editor);\n        iSearch.addString('1'); iSearch.addString('2');\n        testRanges(\"Range: [0/0] -> [0/5]\", [editor.getSelectionRange()]);\n    }\n\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/keyboard/emacs.js",
    "content": "\"use strict\";\n\nvar dom = require(\"../lib/dom\");\nrequire(\"../incremental_search\");\nvar iSearchCommandModule = require(\"../commands/incremental_search_commands\");\n\n\nvar HashHandler = require(\"./hash_handler\").HashHandler;\nexports.handler = new HashHandler();\n\nexports.handler.isEmacs = true;\nexports.handler.$id = \"ace/keyboard/emacs\";\n\n\ndom.importCssString(`\n.emacs-mode .ace_cursor{\n    border: 1px rgba(50,250,50,0.8) solid!important;\n    box-sizing: border-box!important;\n    background-color: rgba(0,250,0,0.9);\n    opacity: 0.5;\n}\n.emacs-mode .ace_hidden-cursors .ace_cursor{\n    opacity: 1;\n    background-color: transparent;\n}\n.emacs-mode .ace_overwrite-cursors .ace_cursor {\n    opacity: 1;\n    background-color: transparent;\n    border-width: 0 0 2px 2px !important;\n}\n.emacs-mode .ace_text-layer {\n    z-index: 4\n}\n.emacs-mode .ace_cursor-layer {\n    z-index: 2\n}`, 'emacsMode', false\n);\nvar $formerLongWords;\nvar $formerLineStart;\n\nexports.handler.attach = function(editor) {\n    // in emacs, gotowordleft/right should not count a space as a word..\n    $formerLongWords = editor.session.$selectLongWords;\n    editor.session.$selectLongWords = true;\n    // CTRL-A should go to actual beginning of line\n    $formerLineStart = editor.session.$useEmacsStyleLineStart;\n    editor.session.$useEmacsStyleLineStart = true;\n\n    editor.session.$emacsMark = null; // the active mark\n    editor.session.$emacsMarkRing = editor.session.$emacsMarkRing || [];\n\n    editor.emacsMark = function() {\n        return this.session.$emacsMark;\n    };\n\n    editor.setEmacsMark = function(p) {\n        // to deactivate pass in a falsy value\n        this.session.$emacsMark = p;\n    };\n\n    editor.pushEmacsMark = function(p, activate) {\n        var prevMark = this.session.$emacsMark;\n        if (prevMark)\n            pushUnique(this.session.$emacsMarkRing, prevMark);\n        if (!p || activate) this.setEmacsMark(p);\n        else pushUnique(this.session.$emacsMarkRing, p);\n    };\n\n    editor.popEmacsMark = function() {\n        var mark = this.emacsMark();\n        if (mark) { this.setEmacsMark(null); return mark; }\n        return this.session.$emacsMarkRing.pop();\n    };\n\n    editor.getLastEmacsMark = function(p) {\n        return this.session.$emacsMark || this.session.$emacsMarkRing.slice(-1)[0];\n    };\n\n    editor.emacsMarkForSelection = function(replacement) {\n        // find the mark in $emacsMarkRing corresponding to the current\n        // selection\n        var sel = this.selection,\n            multiRangeLength = this.multiSelect ?\n                this.multiSelect.getAllRanges().length : 1,\n            selIndex = sel.index || 0,\n            markRing = this.session.$emacsMarkRing,\n            markIndex = markRing.length - (multiRangeLength - selIndex),\n            lastMark = markRing[markIndex] || sel.anchor;\n        if (replacement) {\n            markRing.splice(markIndex, 1,\n                \"row\" in replacement && \"column\" in replacement ?\n                    replacement : undefined);\n        }\n        return lastMark;\n    };\n\n    editor.on(\"click\", $resetMarkMode);\n    editor.on(\"changeSession\", $kbSessionChange);\n    editor.renderer.$blockCursor = true;\n    editor.setStyle(\"emacs-mode\");\n    editor.commands.addCommands(commands);\n    exports.handler.platform = editor.commands.platform;\n    editor.$emacsModeHandler = this;\n    editor.on('copy', this.onCopy);\n    editor.on('paste', this.onPaste);\n};\n\nfunction pushUnique(ring, mark) {\n    var last = ring[ring.length - 1];\n    if (last && last.row === mark.row && last.column === mark.column) {\n        return;\n    }\n    ring.push(mark);\n}\n\nexports.handler.detach = function(editor) {\n    editor.renderer.$blockCursor = false;\n    editor.session.$selectLongWords = $formerLongWords;\n    editor.session.$useEmacsStyleLineStart = $formerLineStart;\n    editor.off(\"click\", $resetMarkMode);\n    editor.off(\"changeSession\", $kbSessionChange);\n    editor.unsetStyle(\"emacs-mode\");\n    editor.commands.removeCommands(commands);\n    editor.off('copy', this.onCopy);\n    editor.off('paste', this.onPaste);\n    editor.$emacsModeHandler = null;\n};\n\nvar $kbSessionChange = function(e) {\n    if (e.oldSession) {\n        e.oldSession.$selectLongWords = $formerLongWords;\n        e.oldSession.$useEmacsStyleLineStart = $formerLineStart;\n    }\n\n    $formerLongWords = e.session.$selectLongWords;\n    e.session.$selectLongWords = true;\n    $formerLineStart = e.session.$useEmacsStyleLineStart;\n    e.session.$useEmacsStyleLineStart = true;\n\n    if (!e.session.hasOwnProperty('$emacsMark'))\n        e.session.$emacsMark = null;\n    if (!e.session.hasOwnProperty('$emacsMarkRing'))\n        e.session.$emacsMarkRing = [];\n};\n\nvar $resetMarkMode = function(e) {\n    e.editor.session.$emacsMark = null;\n};\n\nvar keys = require(\"../lib/keys\").KEY_MODS;\nvar eMods = {C: \"ctrl\", S: \"shift\", M: \"alt\", CMD: \"command\"};\nvar combinations = [\"C-S-M-CMD\",\n                    \"S-M-CMD\", \"C-M-CMD\", \"C-S-CMD\", \"C-S-M\",\n                    \"M-CMD\", \"S-CMD\", \"S-M\", \"C-CMD\", \"C-M\", \"C-S\",\n                    \"CMD\", \"M\", \"S\", \"C\"];\ncombinations.forEach(function(c) {\n    var hashId = 0;\n    c.split(\"-\").forEach(function(c) {\n        hashId = hashId | keys[eMods[c]];\n    });\n    eMods[hashId] = c.toLowerCase() + \"-\";\n});\n\nexports.handler.onCopy = function(e, editor) {\n    if (editor.$handlesEmacsOnCopy) return;\n    editor.$handlesEmacsOnCopy = true;\n    exports.handler.commands.killRingSave.exec(editor);\n    editor.$handlesEmacsOnCopy = false;\n};\n\nexports.handler.onPaste = function(e, editor) {\n    editor.pushEmacsMark(editor.getCursorPosition());\n};\n\nexports.handler.bindKey = function(key, command) {\n    if (typeof key == \"object\")\n        key = key[this.platform];\n    if (!key)\n        return;\n\n    var ckb = this.commandKeyBinding;\n    key.split(\"|\").forEach(function(keyPart) {\n        keyPart = keyPart.toLowerCase();\n        ckb[keyPart] = command;\n        // register all partial key combos as null commands\n        // to be able to activate key combos with arbitrary length\n        // Example: if keyPart is \"C-c C-l t\" then \"C-c C-l t\" will\n        // get command assigned and \"C-c\" and \"C-c C-l\" will get\n        // a null command assigned in this.commandKeyBinding. For\n        // the lookup logic see handleKeyboard()\n        var keyParts = keyPart.split(\" \").slice(0,-1);\n        keyParts.reduce(function(keyMapKeys, keyPart, i) {\n            var prefix = keyMapKeys[i-1] ? keyMapKeys[i-1] + ' ' : '';\n            return keyMapKeys.concat([prefix + keyPart]);\n        }, []).forEach(function(keyPart) {\n            if (!ckb[keyPart]) ckb[keyPart] = \"null\";\n        });\n    }, this);\n};\n\nexports.handler.getStatusText = function(editor, data) {\n  var str = \"\";\n  if (data.count)\n    str += data.count;\n  if (data.keyChain)\n    str += \" \" + data.keyChain;\n  return str;\n};\n\nexports.handler.handleKeyboard = function(data, hashId, key, keyCode) {\n    // if keyCode == -1 a non-printable key was pressed, such as just\n    // control. Handling those is currently not supported in this handler\n    if (keyCode === -1) return undefined;\n\n    var editor = data.editor;\n    editor._signal(\"changeStatus\");\n    // insertstring data.count times\n    if (hashId == -1) {\n        editor.pushEmacsMark();\n        if (data.count) {\n            var str = new Array(data.count + 1).join(key);\n            data.count = null;\n            return {command: \"insertstring\", args: str};\n        }\n    }\n\n    var modifier = eMods[hashId];\n\n    // CTRL + number / universalArgument for setting data.count\n    if (modifier == \"c-\" || data.count) {\n        var count = parseInt(key[key.length - 1]);\n        if (typeof count === 'number' && !isNaN(count)) {\n            data.count = Math.max(data.count, 0) || 0;\n            data.count = 10 * data.count + count;\n            return {command: \"null\"};\n        }\n    }\n\n    // this.commandKeyBinding maps key specs like \"c-p\" (for CTRL + P) to\n    // command objects, for lookup key needs to include the modifier\n    if (modifier) key = modifier + key;\n\n    // Key combos like CTRL+X H build up the data.keyChain\n    if (data.keyChain) key = data.keyChain += \" \" + key;\n\n    // Key combo prefixes get stored as \"null\" (String!) in this\n    // this.commandKeyBinding. When encountered no command is invoked but we\n    // buld up data.keyChain\n    var command = this.commandKeyBinding[key];\n    data.keyChain = command == \"null\" ? key : \"\";\n\n    // there really is no command\n    if (!command) return undefined;\n\n    // we pass b/c of key combo or universalArgument\n    if (command === \"null\") return {command: \"null\"};\n\n    if (command === \"universalArgument\") {\n        // if no number pressed emacs repeats action 4 times.\n        // minus sign is needed to allow next keypress to replace it\n        data.count = -4;\n        return {command: \"null\"};\n    }\n\n    // lookup command\n    // TODO extract special handling of markmode\n    // TODO special case command.command is really unnecessary, remove\n    var args;\n    if (typeof command !== \"string\") {\n        args = command.args;\n        if (command.command) command = command.command;\n        if (command === \"goorselect\") {\n            command = editor.emacsMark() ? args[1] : args[0];\n            args = null;\n        }\n    }\n\n    if (typeof command === \"string\") {\n        if (command === \"insertstring\" ||\n            command === \"splitline\" ||\n            command === \"togglecomment\") {\n            editor.pushEmacsMark();\n        }\n        command = this.commands[command] || editor.commands.commands[command];\n        if (!command) return undefined;\n    }\n\n    if (!command.readOnly && !command.isYank)\n        data.lastCommand = null;\n\n    if (!command.readOnly && editor.emacsMark())\n        editor.setEmacsMark(null);\n        \n    if (data.count) {\n        var count = data.count;\n        data.count = 0;\n        if (!command || !command.handlesCount) {\n            return {\n                args: args,\n                command: {\n                    exec: function(editor, args) {\n                        for (var i = 0; i < count; i++)\n                            command.exec(editor, args);\n                    },\n                    multiSelectAction: command.multiSelectAction\n                }\n            };\n        } else {\n            if (!args) args = {};\n            if (typeof args === 'object') args.count = count;\n        }\n    }\n\n    return {command: command, args: args};\n};\n\nexports.emacsKeys = {\n    // movement\n    \"Up|C-p\"      : {command: \"goorselect\", args: [\"golineup\",\"selectup\"]},\n    \"Down|C-n\"    : {command: \"goorselect\", args: [\"golinedown\",\"selectdown\"]},\n    \"Left|C-b\"    : {command: \"goorselect\", args: [\"gotoleft\",\"selectleft\"]},\n    \"Right|C-f\"   : {command: \"goorselect\", args: [\"gotoright\",\"selectright\"]},\n    \"C-Left|M-b\"  : {command: \"goorselect\", args: [\"gotowordleft\",\"selectwordleft\"]},\n    \"C-Right|M-f\" : {command: \"goorselect\", args: [\"gotowordright\",\"selectwordright\"]},\n    \"Home|C-a\"    : {command: \"goorselect\", args: [\"gotolinestart\",\"selecttolinestart\"]},\n    \"End|C-e\"     : {command: \"goorselect\", args: [\"gotolineend\",\"selecttolineend\"]},\n    \"C-Home|S-M-,\": {command: \"goorselect\", args: [\"gotostart\",\"selecttostart\"]},\n    \"C-End|S-M-.\" : {command: \"goorselect\", args: [\"gotoend\",\"selecttoend\"]},\n\n    // selection\n    \"S-Up|S-C-p\"      : \"selectup\",\n    \"S-Down|S-C-n\"    : \"selectdown\",\n    \"S-Left|S-C-b\"    : \"selectleft\",\n    \"S-Right|S-C-f\"   : \"selectright\",\n    \"S-C-Left|S-M-b\"  : \"selectwordleft\",\n    \"S-C-Right|S-M-f\" : \"selectwordright\",\n    \"S-Home|S-C-a\"    : \"selecttolinestart\",\n    \"S-End|S-C-e\"     : \"selecttolineend\",\n    \"S-C-Home\"        : \"selecttostart\",\n    \"S-C-End\"         : \"selecttoend\",\n\n    \"C-l\" : \"recenterTopBottom\",\n    \"M-s\" : \"centerselection\",\n    \"M-g\": \"gotoline\",\n    \"C-x C-p\": \"selectall\",\n\n    // todo fix these\n    \"C-Down\": {command: \"goorselect\", args: [\"gotopagedown\",\"selectpagedown\"]},\n    \"C-Up\": {command: \"goorselect\", args: [\"gotopageup\",\"selectpageup\"]},\n    \"PageDown|C-v\": {command: \"goorselect\", args: [\"gotopagedown\",\"selectpagedown\"]},\n    \"PageUp|M-v\": {command: \"goorselect\", args: [\"gotopageup\",\"selectpageup\"]},\n    \"S-C-Down\": \"selectpagedown\",\n    \"S-C-Up\": \"selectpageup\",\n\n    \"C-s\": \"iSearch\",\n    \"C-r\": \"iSearchBackwards\",\n\n    \"M-C-s\": \"findnext\",\n    \"M-C-r\": \"findprevious\",\n    \"S-M-5\": \"replace\",\n\n    // basic editing\n    \"Backspace\": \"backspace\",\n    \"Delete|C-d\": \"del\",\n    \"Return|C-m\": {command: \"insertstring\", args: \"\\n\"}, // \"newline\"\n    \"C-o\": \"splitline\",\n\n    \"M-d|C-Delete\": {command: \"killWord\", args: \"right\"},\n    \"C-Backspace|M-Backspace|M-Delete\": {command: \"killWord\", args: \"left\"},\n    \"C-k\": \"killLine\",\n\n    \"C-y|S-Delete\": \"yank\",\n    \"M-y\": \"yankRotate\",\n    \"C-g\": \"keyboardQuit\",\n\n    \"C-w|C-S-W\": \"killRegion\",\n    \"M-w\": \"killRingSave\",\n    \"C-Space\": \"setMark\",\n    \"C-x C-x\": \"exchangePointAndMark\",\n\n    \"C-t\": \"transposeletters\",\n    \"M-u\": \"touppercase\",    // Doesn't work\n    \"M-l\": \"tolowercase\",\n    \"M-/\": \"autocomplete\",   // Doesn't work\n    \"C-u\": \"universalArgument\",\n\n    \"M-;\": \"togglecomment\",\n\n    \"C-/|C-x u|S-C--|C-z\": \"undo\",\n    \"S-C-/|S-C-x u|C--|S-C-z\": \"redo\", // infinite undo?\n    // vertical editing\n    \"C-x r\":  \"selectRectangularRegion\",\n    \"M-x\": {command: \"focusCommandLine\", args: \"M-x \"}\n    // todo\n    // \"C-x C-t\" \"M-t\" \"M-c\" \"F11\" \"C-M- \"M-q\"\n};\n\n\nexports.handler.bindKeys(exports.emacsKeys);\n\nexports.handler.addCommands({\n    recenterTopBottom: function(editor) {\n        var renderer = editor.renderer;\n        var pos = renderer.$cursorLayer.getPixelPosition();\n        var h = renderer.$size.scrollerHeight - renderer.lineHeight;\n        var scrollTop = renderer.scrollTop;\n        if (Math.abs(pos.top - scrollTop) < 2) {\n            scrollTop = pos.top - h;\n        } else if (Math.abs(pos.top - scrollTop - h * 0.5) < 2) {\n            scrollTop = pos.top;\n        } else {\n            scrollTop = pos.top - h * 0.5;\n        }\n        editor.session.setScrollTop(scrollTop);\n    },\n    selectRectangularRegion:  function(editor) {\n        editor.multiSelect.toggleBlockSelection();\n    },\n    setMark:  {\n        exec: function(editor, args) {\n            // Sets mark-mode and clears current selection.\n            // When mark is set, keyboard cursor movement commands become\n            // selection modification commands. That is,\n            // \"goto\" commands become \"select\" commands.\n            // Any insertion or mouse click resets mark-mode.\n            // setMark twice in a row at the same place resets markmode.\n            // in multi select mode, ea selection is handled individually\n\n            if (args && args.count) {\n                if (editor.inMultiSelectMode) editor.forEachSelection(moveToMark);\n                else moveToMark();\n                moveToMark();\n                return;\n            }\n\n            var mark = editor.emacsMark(),\n                ranges = editor.selection.getAllRanges(),\n                rangePositions = ranges.map(function(r) { return {row: r.start.row, column: r.start.column}; }),\n                transientMarkModeActive = true,\n                hasNoSelection = ranges.every(function(range) { return range.isEmpty(); });\n            // if transientMarkModeActive then mark behavior is a little\n            // different. Deactivate the mark when setMark is run with active\n            // mark\n            if (transientMarkModeActive && (mark || !hasNoSelection)) {\n                if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)});\n                else editor.clearSelection();\n                if (mark) editor.pushEmacsMark(null);\n                return;\n            }\n\n            if (!mark) {\n                rangePositions.forEach(function(pos) { editor.pushEmacsMark(pos); });\n                editor.setEmacsMark(rangePositions[rangePositions.length-1]);\n                return;\n            }\n\n            // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n            function moveToMark() {\n                var mark = editor.popEmacsMark();\n                mark && editor.moveCursorToPosition(mark);\n            }\n\n        },\n        readOnly: true,\n        handlesCount: true\n    },\n    exchangePointAndMark: {\n        exec: function exchangePointAndMark$exec(editor, args) {\n            var sel = editor.selection;\n            if (!args.count && !sel.isEmpty()) { // just invert selection\n                sel.setSelectionRange(sel.getRange(), !sel.isBackwards());\n                return;\n            }\n\n            if (args.count) { // replace mark and point\n                var pos = {row: sel.lead.row, column: sel.lead.column};\n                sel.clearSelection();\n                sel.moveCursorToPosition(editor.emacsMarkForSelection(pos));\n            } else { // create selection to last mark\n                sel.selectToPosition(editor.emacsMarkForSelection());\n            }\n        },\n        readOnly: true,\n        handlesCount: true,\n        multiSelectAction: \"forEach\"\n    },\n    killWord: {\n        exec: function(editor, dir) {\n            editor.clearSelection();\n            if (dir == \"left\")\n                editor.selection.selectWordLeft();\n            else\n                editor.selection.selectWordRight();\n\n            var range = editor.getSelectionRange();\n            var text = editor.session.getTextRange(range);\n            exports.killRing.add(text);\n\n            editor.session.remove(range);\n            editor.clearSelection();\n        },\n        multiSelectAction: \"forEach\"\n    },\n    killLine: function(editor) {\n        editor.pushEmacsMark(null);\n        // don't delete the selection if it's before the cursor\n        editor.clearSelection();\n        var range = editor.getSelectionRange();\n        var line = editor.session.getLine(range.start.row);\n        range.end.column = line.length;\n        line = line.substr(range.start.column);\n        \n        var foldLine = editor.session.getFoldLine(range.start.row);\n        if (foldLine && range.end.row != foldLine.end.row) {\n            range.end.row = foldLine.end.row;\n            line = \"x\";\n        }\n        // remove EOL if only whitespace remains after the cursor\n        if (/^\\s*$/.test(line)) {\n            range.end.row++;\n            line = editor.session.getLine(range.end.row);\n            range.end.column = /^\\s*$/.test(line) ? line.length : 0;\n        }\n        var text = editor.session.getTextRange(range);\n        if (editor.prevOp.command == this)\n            exports.killRing.append(text);\n        else\n            exports.killRing.add(text);\n\n        editor.session.remove(range);\n        editor.clearSelection();\n    },\n    yank: function(editor) {\n        editor.onPaste(exports.killRing.get() || '');\n        editor.keyBinding.$data.lastCommand = \"yank\";\n    },\n    yankRotate: function(editor) {\n        if (editor.keyBinding.$data.lastCommand != \"yank\")\n            return;\n        editor.undo();\n        editor.session.$emacsMarkRing.pop(); // also undo recording mark\n        editor.onPaste(exports.killRing.rotate());\n        editor.keyBinding.$data.lastCommand = \"yank\";\n    },\n    killRegion: {\n        exec: function(editor) {\n            exports.killRing.add(editor.getCopyText());\n            editor.commands.byName.cut.exec(editor);\n            editor.setEmacsMark(null);\n        },\n        readOnly: true,\n        multiSelectAction: \"forEach\"\n    },\n    killRingSave: {\n        exec: function(editor) {\n            // copy text and deselect. will save marks for starts of the\n            // selection(s)\n\n            editor.$handlesEmacsOnCopy = true;\n            var marks = editor.session.$emacsMarkRing.slice(),\n                deselectedMarks = [];\n            exports.killRing.add(editor.getCopyText());\n\n            setTimeout(function() {\n                function deselect() {\n                    var sel = editor.selection, range = sel.getRange(),\n                        pos = sel.isBackwards() ? range.end : range.start;\n                    deselectedMarks.push({row: pos.row, column: pos.column});\n                    sel.clearSelection();\n                }\n                editor.$handlesEmacsOnCopy = false;\n                if (editor.inMultiSelectMode) editor.forEachSelection({exec: deselect});\n                else deselect();\n                editor.setEmacsMark(null);\n                editor.session.$emacsMarkRing = marks.concat(deselectedMarks.reverse());\n            }, 0);\n        },\n        readOnly: true\n    },\n    keyboardQuit: function(editor) {\n        editor.selection.clearSelection();\n        editor.setEmacsMark(null);\n        editor.keyBinding.$data.count = null;\n    },\n    focusCommandLine: function(editor, arg) {\n        if (editor.showCommandLine)\n            editor.showCommandLine(arg);\n    }\n});\n\nexports.handler.addCommands(iSearchCommandModule.iSearchStartCommands);\n\nvar commands = exports.handler.commands;\ncommands.yank.isYank = true;\ncommands.yankRotate.isYank = true;\n\nexports.killRing = {\n    $data: [],\n    add: function(str) {\n        str && this.$data.push(str);\n        if (this.$data.length > 30)\n            this.$data.shift();\n    },\n    append: function(str) {\n        var idx = this.$data.length - 1;\n        var text = this.$data[idx] || \"\";\n        if (str) text += str;\n        if (text) this.$data[idx] = text;\n    },\n    get: function(n) {\n        n = n || 1;\n        return this.$data.slice(this.$data.length-n, this.$data.length).reverse().join('\\n');\n    },\n    pop: function() {\n        if (this.$data.length > 1)\n            this.$data.pop();\n        return this.get();\n    },\n    rotate: function() {\n        this.$data.unshift(this.$data.pop());\n        return this.get();\n    }\n};\n"
  },
  {
    "path": "src/keyboard/emacs_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"../multi_select\");\nvar {type} = require(\"../test/user\");\n\nvar EditSession = require(\"./../edit_session\").EditSession,\n    Editor = require(\"../editor\").Editor,\n    Range = require(\"./../range\").Range,\n    VirtualRenderer = require(\"./../virtual_renderer\").VirtualRenderer,\n    emacs = require('./emacs'),\n    assert = require(\"./../test/assertions\"),\n    editor, sel;\n\nfunction initEditor(docString) {\n    var doc = new EditSession(docString.split(\"\\n\"));\n    editor = new Editor(new VirtualRenderer(), doc);\n    editor.setKeyboardHandler(emacs.handler);\n    sel = editor.selection;\n    document.body.appendChild(editor.container);\n    editor.focus();\n}\n\nfunction print(obj) {\n    return JSON.stringify(obj, null, 2);\n}\n\nfunction pluck(arr, what) {\n    return arr.map(function(ea) { return ea[what]; });\n}\n\nmodule.exports = {\n    tearDown: function() {\n        editor.container.remove();\n        editor.destroy();\n    },\n    \"test: detach removes emacs commands from command manager\": function() {\n        initEditor('');\n        assert.ok(!!editor.commands.byName[\"keyboardQuit\"], 'setup error: emacs commands not installed');\n        editor.keyBinding.removeKeyboardHandler(editor.getKeyboardHandler());\n        assert.ok(!editor.commands.byName[\"keyboardQuit\"], 'emacs commands not removed');\n    },\n\n    \"test: keyboardQuit clears selection\": function() {\n        initEditor('foo');\n        editor.selectAll();\n        type('Ctrl-g');\n        assert.ok(editor.selection.isEmpty(), 'selection non-empty');\n    },\n\n    \"test: exchangePointAndMark without mark set\": function() {\n        initEditor('foo');\n        sel.setRange(Range.fromPoints({row: 0, column: 1}, {row: 0, column: 3}));\n        type('Ctrl-x', 'Ctrl-x');\n        assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition()));\n    },\n\n    \"test: exchangePointAndMark with mark set\": function() {\n        initEditor('foo');\n        // push marks\n        editor.selection.moveTo(0, 1);\n        type('Ctrl-Space', 'Ctrl-Space');\n        editor.selection.moveTo(0, 2);\n        type('Ctrl-Space', 'Ctrl-Space');\n        editor.selection.moveTo(0, 0);\n        // exchange point and mark with argument\n        type('Ctrl-4', 'Ctrl-x', 'Ctrl-x');\n        assert.deepEqual({row: 0, column: 2}, editor.getCursorPosition(), print(editor.getCursorPosition()));\n        assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 0}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing));\n    },\n\n    \"test: exchangePointAndMark with selection\": function() {\n        initEditor('foo');\n        editor.pushEmacsMark({row: 0, column: 1});\n        editor.pushEmacsMark({row: 0, column: 2});\n        sel.setRange(Range.fromPoints({row: 0, column: 0}, {row: 0, column: 1}), true);\n        editor.execCommand('exchangePointAndMark');\n        assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition()));\n        assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 2}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing));\n    },\n\n    \"test: exchangePointAndMark with multi selection\": function() {\n        initEditor('foo\\nhello world\\n123');\n        var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}],\n                      [{row: 1, column: 0}, {row: 1, column: 5}],\n                      [{row: 1, column: 6}, {row: 1, column: 11}]];\n        ranges.forEach(function(r) {\n            sel.addRange(Range.fromPoints(r[0], r[1]));\n        });\n        assert.equal(\"foo\\nhello\\nworld\", editor.getSelectedText());\n        editor.execCommand('exchangePointAndMark');\n        assert.equal(\"foo\\nhello\\nworld\", editor.getSelectedText());\n        assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), \"selections dir not inverted\");\n    },\n\n    \"test: exchangePointAndMark with multi cursors\": function() {\n        initEditor('foo\\nhello world\\n123');\n        var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}],\n                      [{row: 1, column: 0}, {row: 1, column: 5}],\n                      [{row: 1, column: 6}, {row: 1, column: 11}]];\n        // move cursors to the start of each range and set a mark to its end\n        // without selecting anything\n        ranges.forEach(function(r) {\n            editor.pushEmacsMark(r[1]);\n            sel.addRange(Range.fromPoints(r[0], r[0]));\n        });\n        assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), print(sel.getAllRanges()));\n        editor.execCommand('exchangePointAndMark');\n        assert.deepEqual(pluck(ranges, 1), pluck(sel.getAllRanges(), 'cursor'), \"not inverted: \" + print(sel.getAllRanges()));\n    },\n\n    \"test: setMark with multi cursors\": function() {\n        initEditor('foo\\nhello world\\n123');\n        var positions = [{row: 0, column: 0},\n                         {row: 1, column: 0},\n                         {row: 1, column: 6}];\n        positions.forEach(function(p) { sel.addRange(Range.fromPoints(p,p)); });\n        editor.execCommand('setMark');\n        assert.deepEqual(positions, editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing));\n    },\n    \n    \"test: killLine\": function() {\n        initEditor(\"foo  \\n Hello world\\n  \\n  123\");\n        sel.setRange(new Range(0, 0, 0, 2));\n        editor.endOperation();\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo\\n Hello world\\n  \\n  123\");\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo Hello world\\n  \\n  123\");\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo\\n  \\n  123\");\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo\\n  123\");\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo  123\");\n        type(\"Ctrl-k\");\n        assert.equal(editor.getValue(),\"fo\");\n        type(\"Ctrl-k\");\n        type(\"Ctrl-y\");\n        assert.equal(editor.getValue(),\"foo  \\n Hello world\\n  \\n  123\");\n    }\n\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/gutter_handler.js",
    "content": "\"use strict\";\n\nvar keys = require('../lib/keys');\n\nclass GutterKeyboardHandler {\n    constructor(editor) {\n        this.editor = editor;\n        this.gutterLayer = editor.renderer.$gutterLayer;\n        this.element = editor.renderer.$gutter;\n        this.lines = editor.renderer.$gutterLayer.$lines;\n\n        this.activeRowIndex = null;\n        this.activeLane = null;\n\n        this.annotationTooltip = this.editor.$mouseHandler.$tooltip;\n    }\n\n    addListener() {\n        this.element.addEventListener(\"keydown\", this.$onGutterKeyDown.bind(this));\n        this.element.addEventListener(\"focusout\", this.$blurGutter.bind(this));\n        this.editor.on(\"mousewheel\", this.$blurGutter.bind(this));\n    }\n\n    removeListener() {\n        this.element.removeEventListener(\"keydown\", this.$onGutterKeyDown.bind(this));\n        this.element.removeEventListener(\"focusout\", this.$blurGutter.bind(this));\n        this.editor.off(\"mousewheel\", this.$blurGutter.bind(this));\n    }\n\n    $onGutterKeyDown(e) {\n        // if the tooltip is open, we only want to respond to commands to close it (like a modal)\n        if (this.annotationTooltip.isOpen) {\n            e.preventDefault();\n\n            if (e.keyCode === keys[\"escape\"])\n                this.annotationTooltip.hide();\n\n            return;\n        }\n\n        // If focus is on the gutter element, set focus to nearest gutter icon on enter press.\n        if (e.target === this.element) {\n            if (e.keyCode != keys[\"enter\"]) {return;}\n            e.preventDefault();\n\n            // Scroll if the cursor is not currently within the viewport.\n            var row = this.editor.getCursorPosition().row;       \n            if (!this.editor.isRowVisible(row))\n                this.editor.scrollToLine(row, true, true);\n\n            // After scrolling is completed, find the nearest gutter icon and set focus to it.\n            setTimeout(\n                /** @this {GutterKeyboardHandler} */\n                function () {\n                    var index = this.$rowToRowIndex(this.gutterLayer.$cursorCell.row);\n                    var nearestFoldLaneWidgetIndex = this.$findNearestFoldLaneWidget(index);\n                    var nearestAnnotationIndex = this.$findNearestAnnotation(index);\n\n                    if (nearestFoldLaneWidgetIndex === null && nearestAnnotationIndex === null) return;\n\n                    var futureActiveRowIndex = this.$findClosestNumber(nearestFoldLaneWidgetIndex, nearestAnnotationIndex, index);\n\n                    if (futureActiveRowIndex === nearestFoldLaneWidgetIndex) {\n                        this.activeLane = \"fold\";\n                        this.activeRowIndex = nearestFoldLaneWidgetIndex;\n                        if(this.$isCustomWidgetVisible(nearestFoldLaneWidgetIndex)){\n                            this.$focusCustomWidget(this.activeRowIndex);\n                            return;\n                        }\n                        else {\n                            this.$focusFoldWidget(this.activeRowIndex);\n                            return;\n                        }\n                    }\n                    else {\n                        this.activeRowIndex = nearestAnnotationIndex;\n                        this.activeLane = \"annotation\";\n                        this.$focusAnnotation(this.activeRowIndex);\n                        return;\n                    }\n                }.bind(this), 10);\n            return;\n        } \n\n        // After here, foucs is on a gutter icon and we want to interact with them.\n        this.$handleGutterKeyboardInteraction(e);\n\n        // Wait until folding is completed and then signal gutterkeydown to the editor.\n        setTimeout(function() {\n            // Signal to the editor that a key is pressed inside the gutter.\n            this.editor._signal(\"gutterkeydown\", new GutterKeyboardEvent(e, this));\n        }.bind(this), 10);\n    }\n\n    $handleGutterKeyboardInteraction(e) {\n        // Prevent tabbing when interacting with the gutter icons.\n        if (e.keyCode === keys[\"tab\"]){\n            e.preventDefault();\n            return;\n        } \n\n        // If focus is on a gutter icon, set focus to gutter on escape press.\n        if (e.keyCode === keys[\"escape\"]) {\n            e.preventDefault();\n            this.$blurGutter();\n            this.element.focus();\n            this.lane = null;\n            return;\n        }\n\n        if (e.keyCode === keys[\"up\"]) {\n            e.preventDefault();\n  \n            switch (this.activeLane){\n                case \"fold\":\n                    this.$moveFoldWidgetUp();\n                    break;\n                \n                case \"annotation\":\n                    this.$moveAnnotationUp();\n                    break;\n            }\n            return;\n        }\n\n        if (e.keyCode === keys[\"down\"]) {\n            e.preventDefault();\n\n            switch (this.activeLane){\n                case \"fold\":\n                    this.$moveFoldWidgetDown();\n                    break;\n                \n                case \"annotation\":\n                    this.$moveAnnotationDown();\n                    break;\n            }\n            return;\n        }\n\n        // Try to switch from fold widgets to annotations.\n        if (e.keyCode === keys[\"left\"]){\n            e.preventDefault();\n            this.$switchLane(\"annotation\");\n            return;\n        }\n\n        // Try to switch from annotations to fold widgets.\n        if (e.keyCode === keys[\"right\"]){\n            e.preventDefault();\n            this.$switchLane(\"fold\");\n            return;\n        }\n\n        if (e.keyCode === keys[\"enter\"] || e.keyCode === keys[\"space\"]){\n            e.preventDefault();\n\n            switch (this.activeLane) {\n                case \"fold\":\n                    var row = this.$rowIndexToRow(this.activeRowIndex);\n                    var customWidget = this.editor.session.$gutterCustomWidgets[row];\n                    if (customWidget) {\n                        if (customWidget.callbacks && customWidget.callbacks.onClick) {\n                            customWidget.callbacks.onClick(e, row);\n                        }\n                    }\n                    else if (this.gutterLayer.session.foldWidgets[row] === 'start') {\n                        this.editor.session.onFoldWidgetClick(this.$rowIndexToRow(this.activeRowIndex), e);\n                        // After folding, check that the right fold widget is still in focus.\n                        // If not (e.g. folding close to bottom of doc), put right widget in focus.\n                        setTimeout(\n                            /** @this {GutterKeyboardHandler} */\n                            function () {\n                                if (this.$rowIndexToRow(this.activeRowIndex) !== row) {\n                                    this.$blurFoldWidget(this.activeRowIndex);\n                                    this.activeRowIndex = this.$rowToRowIndex(row);\n                                    this.$focusFoldWidget(this.activeRowIndex);\n                                }\n                        }.bind(this), 10);\n                        break;\n                    } else if (this.gutterLayer.session.foldWidgets[this.$rowIndexToRow(this.activeRowIndex)] === 'end') {\n                        /* TO DO: deal with 'end' fold widgets */\n                        break;\n                    }\n                    return; \n                \n                case \"annotation\":\n                    this.annotationTooltip.showTooltip(this.$rowIndexToRow(this.activeRowIndex));\n                    this.annotationTooltip.$fromKeyboard = true;\n                    break;\n            }\n            return;\n        }   \n    }\n\n    $blurGutter() {\n        if (this.activeRowIndex !== null){\n            switch (this.activeLane){\n                case \"fold\":\n                    this.$blurFoldWidget(this.activeRowIndex);\n                    this.$blurCustomWidget(this.activeRowIndex);\n                    break;\n\n                case \"annotation\":\n                    this.$blurAnnotation(this.activeRowIndex);\n                    break;\n            }\n        }\n\n        if (this.annotationTooltip.isOpen)\n            this.annotationTooltip.hide();\n\n        return;\n    }\n\n    $isFoldWidgetVisible(index) {\n        var isRowFullyVisible = this.editor.isRowFullyVisible(this.$rowIndexToRow(index));\n        var isIconVisible = this.$getFoldWidget(index).style.display !== \"none\";\n        return isRowFullyVisible && isIconVisible;\n    }\n\n    $isCustomWidgetVisible(index) {\n        var isRowFullyVisible = this.editor.isRowFullyVisible(this.$rowIndexToRow(index));\n        var isIconVisible = !!this.$getCustomWidget(index);\n        return isRowFullyVisible && isIconVisible;\n    }\n\n    $isAnnotationVisible(index) {\n        var isRowFullyVisible = this.editor.isRowFullyVisible(this.$rowIndexToRow(index));\n        var isIconVisible = this.$getAnnotation(index).style.display !== \"none\";\n        return isRowFullyVisible && isIconVisible;\n    }\n\n    $getFoldWidget(index) {\n        var cell = this.lines.get(index);\n        var element = cell.element;\n        return element.childNodes[1];\n    }\n\n    $getCustomWidget(index) {\n        var cell = this.lines.get(index);\n        var element = cell.element;\n        return element.childNodes[3];\n    }\n\n    $getAnnotation(index) {\n        var cell = this.lines.get(index);\n        var element = cell.element;\n        return element.childNodes[2];\n    }\n\n    // Given an index, find the nearest index with a widget in fold lane\n    $findNearestFoldLaneWidget(index) {\n        // If custom widget exists at index, return index\n        if (this.$isCustomWidgetVisible(index))\n            return index;\n\n        // If fold widget exists at index, return index.\n        if (this.$isFoldWidgetVisible(index))\n            return index;\n\n        // else, find the nearest index with widget within viewport.\n        var i = 0;\n        while (index - i > 0 || index + i < this.lines.getLength() - 1){\n            i++;\n            if (index - i >= 0 && this.$isCustomWidgetVisible(index - i))\n                return index - i;\n\n            if (index + i <= this.lines.getLength() - 1 && this.$isCustomWidgetVisible(index + i))\n                return index + i;\n\n            if (index - i >= 0 && this.$isFoldWidgetVisible(index - i))\n                return index - i;\n\n            if (index + i <= this.lines.getLength() - 1 && this.$isFoldWidgetVisible(index + i))\n                return index + i;\n        }\n\n        // If there are no widgets within the viewport, return null.\n        return null;\n    }\n\n    // Given an index, find the nearest index with an annotation.\n    $findNearestAnnotation(index) {\n        // If annotation exists at index, return index.\n        if (this.$isAnnotationVisible(index))\n            return index;\n\n        // else, find the nearest index with annotation within viewport.\n        var i = 0;\n        while (index - i > 0 || index + i < this.lines.getLength() - 1){\n            i++;\n\n            if (index - i >= 0 && this.$isAnnotationVisible(index - i))\n                return index - i;\n\n            if (index + i <= this.lines.getLength() - 1 && this.$isAnnotationVisible(index + i))\n                return index + i;\n        }\n\n        // If there are no annotations within the viewport, return null.\n        return null;\n    }\n\n    $focusFoldWidget(index) {\n        if (index == null)\n            return;\n\n        var foldWidget = this.$getFoldWidget(index);\n\n        foldWidget.classList.add(this.editor.renderer.keyboardFocusClassName);\n        foldWidget.focus();\n    }\n\n    $focusCustomWidget(index) {\n        if (index == null)\n            return;\n\n        var customWidget = this.$getCustomWidget(index);\n        if (customWidget) {\n            customWidget.classList.add(this.editor.renderer.keyboardFocusClassName);\n            customWidget.focus();\n        }\n    }\n\n    $focusAnnotation(index) {\n        if (index == null)\n            return;\n\n        var annotation = this.$getAnnotation(index);\n\n        annotation.classList.add(this.editor.renderer.keyboardFocusClassName);\n        annotation.focus();\n    }\n\n    $blurFoldWidget(index) {\n        var foldWidget = this.$getFoldWidget(index);\n\n        foldWidget.classList.remove(this.editor.renderer.keyboardFocusClassName);\n        foldWidget.blur();\n    }\n\n    $blurCustomWidget(index) {\n        var customWidget = this.$getCustomWidget(index);\n        if (customWidget) {\n            customWidget.classList.remove(this.editor.renderer.keyboardFocusClassName);\n            customWidget.blur();\n        }\n    }\n\n    $blurAnnotation(index) {\n        var annotation = this.$getAnnotation(index);\n\n        annotation.classList.remove(this.editor.renderer.keyboardFocusClassName);\n        annotation.blur();\n    }\n\n    $moveFoldWidgetUp() {\n        var index = this.activeRowIndex;\n\n        while (index > 0){\n            index--;\n\n            if (this.$isFoldWidgetVisible(index) || this.$isCustomWidgetVisible(index)){\n                this.$blurFoldWidget(this.activeRowIndex);\n                this.$blurCustomWidget(this.activeRowIndex);\n                this.activeRowIndex = index;\n                if (this.$isFoldWidgetVisible(index)) {\n                    this.$focusFoldWidget(this.activeRowIndex);\n                }\n                else {\n                    this.$focusCustomWidget(this.activeRowIndex);\n                }\n                return;\n            }\n        }\n        return;\n    }\n\n    $moveFoldWidgetDown() {\n        var index = this.activeRowIndex;\n\n        while (index < this.lines.getLength() - 1){\n            index++;\n\n            if (this.$isFoldWidgetVisible(index) || this.$isCustomWidgetVisible(index)){\n                this.$blurFoldWidget(this.activeRowIndex);\n                this.$blurCustomWidget(this.activeRowIndex);\n                this.activeRowIndex = index;\n                if (this.$isFoldWidgetVisible(index)) {\n                    this.$focusFoldWidget(this.activeRowIndex);\n                }\n                else {\n                    this.$focusCustomWidget(this.activeRowIndex);\n                }\n                return;\n            }\n        }\n        return;\n    }\n\n    $moveAnnotationUp() {\n        var index = this.activeRowIndex;\n\n        while (index > 0){\n            index--;\n\n            if (this.$isAnnotationVisible(index)){\n                this.$blurAnnotation(this.activeRowIndex);\n                this.activeRowIndex = index;\n                this.$focusAnnotation(this.activeRowIndex);\n                return;\n            }\n        }\n        return;\n    }\n\n    $moveAnnotationDown() {\n        var index = this.activeRowIndex;\n\n        while (index < this.lines.getLength() - 1){\n            index++;\n\n            if (this.$isAnnotationVisible(index)){\n                this.$blurAnnotation(this.activeRowIndex);\n                this.activeRowIndex = index;\n                this.$focusAnnotation(this.activeRowIndex);\n                return;\n            }\n        }\n        return;\n    }\n\n    $findClosestNumber(num1, num2, target) {\n        if (num1 === null) return num2;\n        if (num2 === null) return num1;\n        \n        return (Math.abs(target - num1) <= Math.abs(target - num2)) ? num1 : num2;\n    }\n\n    $switchLane(desinationLane){\n        switch (desinationLane) {\n            case \"annotation\":\n                if (this.activeLane === \"annotation\") {break;}\n                var annotationIndex = this.$findNearestAnnotation(this.activeRowIndex);\n                if (annotationIndex == null) {break;}\n\n                this.activeLane = \"annotation\";\n\n                this.$blurFoldWidget(this.activeRowIndex);\n                this.$blurCustomWidget(this.activeRowIndex);\n                this.activeRowIndex = annotationIndex;\n                this.$focusAnnotation(this.activeRowIndex);\n\n                break;\n\n            case \"fold\": \n            if (this.activeLane === \"fold\") {break;}\n            var foldLaneWidgetIndex = this.$findNearestFoldLaneWidget(this.activeRowIndex);\n            if (foldLaneWidgetIndex === null) {break;}\n\n            this.activeLane = \"fold\";\n\n            this.$blurAnnotation(this.activeRowIndex);\n\n            this.activeRowIndex = foldLaneWidgetIndex;\n\n            if (this.$isCustomWidgetVisible(foldLaneWidgetIndex)) {\n                this.$focusCustomWidget(this.activeRowIndex);\n            }\n            else {\n                this.$focusFoldWidget(this.activeRowIndex);\n            }\n                break;\n        }\n        return;\n    }\n\n    // Convert row index (viewport space) to row (document space).\n    $rowIndexToRow(index) {\n        var cell = this.lines.get(index);\n        if (cell)\n            return cell.row;\n\n        return null;\n    }\n\n    // Convert row (document space) to row index (viewport space).\n    $rowToRowIndex(row) {\n        for (var i = 0; i < this.lines.getLength(); i++){\n            var cell = this.lines.get(i);\n            if (cell.row == row)\n                return i;\n        }\n\n        return null;\n    }\n}\n\nexports.GutterKeyboardHandler = GutterKeyboardHandler;\n\n/*\n * Custom Ace gutter keyboard event\n */\nclass GutterKeyboardEvent {\n    constructor(domEvent, gutterKeyboardHandler) {\n        this.gutterKeyboardHandler = gutterKeyboardHandler;\n        this.domEvent = domEvent;\n    }\n\n    /**\n     * Returns the key that was presssed.\n     * \n     * @return {string} the key that was pressed.\n     */\n    getKey() {\n        return keys.keyCodeToString(this.domEvent.keyCode);\n    }\n\n    /**\n     * Returns the row in the gutter that was focused after the keyboard event was handled.\n     * \n     * @return {number} the key that was pressed.\n     */\n    getRow() {\n        return this.gutterKeyboardHandler.$rowIndexToRow(this.gutterKeyboardHandler.activeRowIndex);\n    }\n\n    /**\n     * Returns whether focus is on the annotation lane after the keyboard event was handled.\n     * \n     * @return {boolean} true if focus was on the annotation lane after the keyboard event.\n     */\n    isInAnnotationLane() {\n        return this.gutterKeyboardHandler.activeLane === \"annotation\";\n    }\n\n    /**\n     * Returns whether focus is on the fold lane after the keyboard event was handled.\n     * \n     * @return {boolean} true if focus was on the fold lane after the keyboard event.\n     */\n    isInFoldLane() {\n        return this.gutterKeyboardHandler.activeLane === \"fold\";\n    }\n}\n\nexports.GutterKeyboardEvent = GutterKeyboardEvent;\n"
  },
  {
    "path": "src/keyboard/gutter_handler_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n \nrequire(\"../multi_select\");\nrequire(\"../theme/textmate\");\nvar user = require(\"../test/user\");\nvar Editor = require(\"../editor\").Editor;\nvar Mode = require(\"../mode/java\").Mode;\nvar VirtualRenderer = require(\"../virtual_renderer\").VirtualRenderer;\nvar assert = require(\"../test/assertions\");\nvar lang = require(\"../lib/lang\");\n\nfunction findVisibleTooltip() {\n    const tooltips = document.body.querySelectorAll(\".ace_gutter-tooltip\");\n    for (let i = 0; i < tooltips.length; i++) {\n        if (window.getComputedStyle(tooltips[i]).display === \"block\") {\n            return tooltips[i];\n        }\n    }\n    return null;\n}\n\nmodule.exports = {\n    setUp : function() {\n        this.editor = new Editor(new VirtualRenderer());\n        this.editor.container.style.position = \"absolute\";\n        this.editor.container.style.height = \"500px\";\n        this.editor.container.style.width = \"500px\";\n        this.editor.container.style.left = \"50px\";\n        this.editor.container.style.top = \"10px\";\n        document.body.appendChild(this.editor.container);\n    },\n    \"test: keyboard code folding: basic functionality\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the fold widget.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[1]);\n\n        // Click the fold widget.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check that code is folded.\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"52\");\n\n        // After escape focus should be back to the gutter.\n        user.type(\"Escape\");\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n    \"test: keyboard code folding: multiple folds\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\\n x {\" + \"\\n\".repeat(5) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n  \n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        assert.equal(lines.cells[2].element.textContent, \"3\");\n\n        // Focus on the fold widgets.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[1]);\n\n        // Click the first fold widget.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check that code is folded.\n        editor.renderer.$loop._flush();\n        assert.equal(lines.cells[2].element.textContent, \"8\");\n\n        // Move to the next fold widget.\n        user.type(\"Down\");\n        assert.equal(document.activeElement, lines.cells[3].element.childNodes[1]);\n        assert.equal(lines.cells[4].element.textContent, \"10\");\n\n        // Click the fold widget.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check that code is folded.\n        assert.equal(lines.cells[4].element.textContent, \"15\");\n\n        // Move back up one fold widget.\n        user.type(\"Up\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[1]);\n\n        done();\n    },\n    \"test: keyboard annotation: basic functionality\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        user.type(\"Left\");\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[2]);\n\n        // Click annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check annotation is rendered.\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n\n        // Press escape to dismiss the tooltip.\n        user.type(\"Escape\");\n\n        // After escape again focus should be back to the gutter.\n        user.type(\"Escape\");\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n    \"test: keyboard annotation: multiple annotations\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([\n            {row: 1, column: 0, text: \"error test\", type: \"error\"},\n            {row: 2, column: 0, text: \"warning test\", type: \"warning\"}\n        ]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        user.type(\"Left\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[2]);\n\n        // Click annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check annotation is rendered.\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n\n        // Press escape to dismiss the tooltip.\n        user.type(\"Escape\");\n\n        // Press down to move to next annotation.\n        user.type(\"Down\");\n        assert.equal(document.activeElement, lines.cells[2].element.childNodes[2]);\n\n        // Click annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check annotation is rendered.\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/warning test/.test(tooltip.textContent));\n\n        // Press escape to dismiss the tooltip.\n        user.type(\"Escape\");\n\n        // Move back up one annotation.\n        user.type(\"Up\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[2]);\n\n        // Move back to the folds, focus should be on the fold on line 1.\n        user.type(\"Right\");\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[1]);\n\n        done();\n    },\n    \"test: keyboard annotation: no folds\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, text: \"error test\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on gutter interaction.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Focus should be on the annotation directly.\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[2]);\n        done();\n    },\n    \"test: aria attributes mode with getFoldWidgetRange\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(5) + \"}\";\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n\n        assert.equal(toggler.getAttribute(\"aria-label\"), \"Toggle code folding, rows 1 through 6\");\n        assert.equal(toggler.getAttribute(\"aria-expanded\"), \"true\");\n        assert.equal(toggler.getAttribute(\"title\"), \"Fold code\");\n\n        editor.session.$toggleFoldWidget(0, {});\n        editor.renderer.$loop._flush();\n\n        assert.equal(toggler.getAttribute(\"aria-label\"), \"Toggle code folding, rows 1 through 6\");\n        assert.equal(toggler.getAttribute(\"aria-expanded\"), \"false\");\n        assert.equal(toggler.getAttribute(\"title\"), \"Unfold code\");    \n    },\n    \"test: aria attributes mode without getFoldWidgetRange\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(5) + \"}\";\n        var mode = new Mode();\n        mode.foldingRules.getFoldWidgetRange = function(session, foldStyle, row) {\n            return null;\n        };\n        editor.session.setMode(mode);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n\n        assert.equal(toggler.getAttribute(\"aria-label\"), \"Toggle code folding, row 1\");\n        assert.equal(toggler.getAttribute(\"aria-expanded\"), \"true\");\n        assert.equal(toggler.getAttribute(\"title\"), \"Fold code\"); \n    },\n    \"test: should signal keyboard event\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n\n        var row, isAnnotation, isFold, key;\n        editor.on(\"gutterkeydown\", function(event) {\n            row = event.getRow();\n            isAnnotation = event.isInAnnotationLane();\n            isFold = event.isInFoldLane();\n            key = event.getKey();\n        });\n\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        user.type(\"Left\");\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[2]);\n\n        await lang.sleep(20);\n        assert.equal(row, 0);\n        assert.equal(isAnnotation, true);\n        assert.equal(isFold, false);\n        assert.equal(key, \"left\");\n        done();\n    },\n    \"test: switching lanes with the custom widget should work\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([\n            {row: 1, column: 0, text: \"error test\", type: \"error\"},\n            {row: 2, column: 0, text: \"warning test\", type: \"warning\"}\n        ]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        editor.renderer.$gutterLayer.$addCustomWidget(1, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\",\n        });\n\n        // Focus on the annotation.\n        user.type(\"Enter\");\n        await lang.sleep(20);\n        user.type(\"Left\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[2]);\n\n        // Click annotation.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        // Check annotation is rendered.\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n\n        // Press escape to dismiss the tooltip.\n        user.type(\"Escape\");\n\n        // Switch lane move to custom widget\n        user.type(\"Right\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[3]);\n\n        // Move back to the annotations, focus should be on the annotation on line 1.\n        user.type(\"Left\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[2]);\n        done();\n    },\n    \"test: moving up and down to custom widget and checking onclick callback as well\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\\n x {\" + \"\\n\".repeat(5) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n  \n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        assert.equal(lines.cells[2].element.textContent, \"3\");\n\n        let firstCallbackCalledCount=0;\n        const firstCallback = (e) =>{ \n            firstCallbackCalledCount++;\n            e.stopPropagation();\n        };\n\n        editor.renderer.$gutterLayer.$addCustomWidget(2, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\",\n            callbacks: {\n                onClick: firstCallback\n            }\n        });\n\n        // Focus on the fold widgets.\n        user.type(\"Enter\");\n\n        await lang.sleep(20);\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[1]);\n\n        // Move down to the custom widget.\n        user.type(\"Down\");\n        assert.equal(document.activeElement, lines.cells[2].element.childNodes[3]);\n\n        user.type(\"Enter\");\n        assert.equal(firstCallbackCalledCount, 1);\n\n        // Move up to the previous fold widget.\n        user.type(\"Up\");\n        assert.equal(document.activeElement, lines.cells[1].element.childNodes[1]);\n        done();\n    },\n    \"test: add several custom widgets\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(5) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.execCommand(\"toggleFoldWidget\");\n        editor.renderer.$loop._flush();\n\n        \n        editor.renderer.$gutterLayer.$addCustomWidget(100, {\n            className: \"widget1\",\n        });\n        editor.renderer.$gutterLayer.$addCustomWidget(4, {\n            className: \"widget2\",\n        });\n        editor.renderer.$loop._flush();\n        \n        assert.ok(!editor.container.querySelector(\".widget1\"));\n        assert.ok(editor.container.querySelector(\".widget2\"));\n\n        editor.navigateTo(100, 0);\n        editor.renderer.scrollCursorIntoView();\n\n        editor.renderer.$loop._flush();\n        assert.ok(editor.container.querySelector(\".widget1\"));\n        assert.ok(!editor.container.querySelector(\".widget2\"));\n\n    },\n    \n    tearDown : function() {\n        this.editor.destroy();\n        document.body.removeChild(this.editor.container);\n    }\n    \n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/hash_handler.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"../../ace-internal\").Ace.Command} Command\n * @typedef {import(\"../../ace-internal\").Ace.CommandLike} CommandLike\n*/\n\n/** @type {any} */var keyUtil = require(\"../lib/keys\");\nvar useragent = require(\"../lib/useragent\");\nvar KEY_MODS = keyUtil.KEY_MODS;\n\n/**\n * @typedef {\"win\" | \"mac\"} Platform\n */\n\nclass MultiHashHandler {\n    /**\n     * @param {Record<string, CommandLike> | Command[]} [config]\n     * @param {Platform} [platform]\n     */\n    constructor(config, platform) {\n        this.$init(config, platform, false);\n    }\n\n    /**\n     * @param {Record<string, CommandLike> | Command[]} config\n     * @param {Platform} [platform]\n     * @param {boolean} [$singleCommand]\n     */\n    $init(config, platform, $singleCommand) {\n        this.platform = platform || (useragent.isMac ? \"mac\" : \"win\");\n        /**@type {Record<string, Command>}*/\n        this.commands = {};\n        this.commandKeyBinding = {};\n        this.addCommands(config);\n        this.$singleCommand = $singleCommand;\n    }\n\n    /**\n     * @param {Command} command\n     */\n    addCommand(command) {\n        if (this.commands[command.name])\n            this.removeCommand(command);\n\n        this.commands[command.name] = command;\n\n        if (command.bindKey)\n            this._buildKeyHash(command);\n    }\n\n    /**\n     * @param {Command | string} command\n     * @param {boolean} [keepCommand]\n     */\n    removeCommand(command, keepCommand) {\n        var name = command && (typeof command === 'string' ? command : command.name);\n        command = this.commands[name];\n        if (!keepCommand)\n            delete this.commands[name];\n\n        // exhaustive search is brute force but since removeCommand is\n        // not a performance critical operation this should be OK\n        var ckb = this.commandKeyBinding;\n        for (var keyId in ckb) {\n            var cmdGroup = ckb[keyId];\n            if (cmdGroup == command) {\n                delete ckb[keyId];\n            } else if (Array.isArray(cmdGroup)) {\n                var i = cmdGroup.indexOf(command);\n                if (i != -1) {\n                    cmdGroup.splice(i, 1);\n                    if (cmdGroup.length == 1)\n                        ckb[keyId] = cmdGroup[0];\n                }\n            }\n        }\n    }\n\n    /**\n     * @param {string | { win?: string; mac?: string; position?:number}} key\n     * @param {CommandLike | string} command\n     * @param {number} [position]\n     */\n    bindKey(key, command, position) {\n        if (typeof key == \"object\" && key) {\n            if (position == undefined)\n                position = key.position;\n            key = key[this.platform];\n        }\n        if (!key)\n            return;\n        if (typeof command == \"function\")\n            return this.addCommand({exec: command, bindKey: key, name: command.name || /**@type{string}*/(key)});\n        \n        /**@type{string}*/(key).split(\"|\").forEach(function(keyPart) {\n            var chain = \"\";\n            if (keyPart.indexOf(\" \") != -1) {\n                var parts = keyPart.split(/\\s+/);\n                keyPart = parts.pop();\n                parts.forEach(function(keyPart) {\n                    var binding = this.parseKeys(keyPart);\n                    var id = KEY_MODS[binding.hashId] + binding.key;\n                    chain += (chain ? \" \" : \"\") + id;\n                    this._addCommandToBinding(chain, \"chainKeys\");\n                }, this);\n                chain += \" \";\n            }\n            var binding = this.parseKeys(keyPart);\n            var id = KEY_MODS[binding.hashId] + binding.key;\n            this._addCommandToBinding(chain + id, command, position);\n        }, this);\n    }\n\n    /**\n     * @param {string} keyId\n     * @param {any} command\n     * @param {number} position\n     */\n    _addCommandToBinding(keyId, command, position) {\n        var ckb = this.commandKeyBinding, i;\n        if (!command) {\n            delete ckb[keyId];\n        } else if (!ckb[keyId] || this.$singleCommand) {\n            ckb[keyId] = command;\n        } else {\n            if (!Array.isArray(ckb[keyId])) {\n                ckb[keyId] = [ckb[keyId]];\n            } else if ((i = ckb[keyId].indexOf(command)) != -1) {\n                ckb[keyId].splice(i, 1);\n            }\n            \n            if (typeof position != \"number\") {\n                position = getPosition(command);\n            }\n\n            var commands = ckb[keyId];\n            for (i = 0; i < commands.length; i++) {\n                var other = commands[i];\n                var otherPos = getPosition(other);\n                if (otherPos > position)\n                    break;\n            }\n            commands.splice(i, 0, command);\n        }\n    }\n\n    /**\n     * @param {Record<string, CommandLike> | Command[]} [commands]\n     */\n    addCommands(commands) {\n        commands && Object.keys(commands).forEach(function(name) {\n            var command = commands[name];\n            if (!command)\n                return;\n            \n            if (typeof command === \"string\")\n                return this.bindKey(command, name);\n\n            if (typeof command === \"function\")\n                command = { exec: command };\n\n            if (typeof command !== \"object\")\n                return;\n\n            if (!command.name)\n                command.name = name;\n\n            this.addCommand(command);\n        }, this);\n    }\n\n    /**\n     * @param {Record<string, CommandLike | string>} commands\n     */\n    removeCommands(commands) {\n        Object.keys(commands).forEach(function(name) {\n            this.removeCommand(commands[name]);\n        }, this);\n    }\n\n    /**\n     * @param {Record<string, CommandLike | string>} keyList\n     */\n    bindKeys(keyList) {\n        Object.keys(keyList).forEach(function(key) {\n            this.bindKey(key, keyList[key]);\n        }, this);\n    }\n\n    _buildKeyHash(command) {\n        this.bindKey(command.bindKey, command);\n    }\n\n    /**\n     * Accepts keys in the form ctrl+Enter or ctrl-Enter\n     * keys without modifiers or shift only\n     * @param {string} keys\n     * @returns {{key: string, hashId: number} | false}\n     */\n    parseKeys(keys) {\n        var parts = keys.toLowerCase().split(/[\\-\\+]([\\-\\+])?/).filter(function(x){return x;});\n        var key = parts.pop();\n\n        var keyCode = keyUtil[key];\n        if (keyUtil.FUNCTION_KEYS[keyCode])\n            key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();\n        else if (!parts.length)\n            return {key: key, hashId: -1};\n        else if (parts.length == 1 && parts[0] == \"shift\")\n            return {key: key.toUpperCase(), hashId: -1};\n\n        var hashId = 0;\n        for (var i = parts.length; i--;) {\n            var modifier = keyUtil.KEY_MODS[parts[i]];\n            if (modifier == null) {\n                if (typeof console != \"undefined\")\n                    console.error(\"invalid modifier \" + parts[i] + \" in \" + keys);\n                return false;\n            }\n            hashId |= modifier;\n        }\n        return {key: key, hashId: hashId};\n    }\n\n    /**\n     * @param {number} hashId\n     * @param {string} keyString\n     * @returns {Command}\n     */\n    findKeyCommand(hashId, keyString) {\n        var key = KEY_MODS[hashId] + keyString;\n        return this.commandKeyBinding[key];\n    }\n\n    /**\n     * @param {any} data\n     * @param {number} hashId\n     * @param {string} keyString\n     * @param {number} keyCode\n     * @returns {{command: string} | void}\n     */\n    handleKeyboard(data, hashId, keyString, keyCode) {\n        if (keyCode < 0) return;\n        var key = KEY_MODS[hashId] + keyString;\n        var command = this.commandKeyBinding[key];\n        if (data.$keyChain) {\n            data.$keyChain += \" \" + key;\n            command = this.commandKeyBinding[data.$keyChain] || command;\n        }\n        \n        if (command) {\n            if (command == \"chainKeys\" || command[command.length - 1] == \"chainKeys\") {\n                data.$keyChain = data.$keyChain || key;\n                return {command: \"null\"};\n            }\n        }\n        \n        if (data.$keyChain) {\n            if ((!hashId || hashId == 4) && keyString.length == 1)\n                data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input\n            else if (hashId == -1 || keyCode > 0)\n                data.$keyChain = \"\"; // reset keyChain\n        }\n        return {command: command};\n    }\n\n    /**\n     * @param {any} [editor]\n     * @param {any} [data]\n     * @returns {string}\n     */\n    getStatusText(editor, data) {\n        return data.$keyChain || \"\";\n    }\n\n}\n\nfunction getPosition(command) {\n    return typeof command == \"object\" && command.bindKey\n        && command.bindKey.position \n        || (command.isDefault ? -100 : 0);\n}\n\nclass HashHandler extends MultiHashHandler {\n    /**\n     * @param {Record<string, CommandLike> | Command[]} [config]\n     * @param {Platform} [platform]\n     */\n    constructor(config, platform) {\n        super(config, platform);\n        this.$singleCommand = true;\n    }\n}\n\nHashHandler.call = function(thisArg, config, platform) {\n    MultiHashHandler.prototype.$init.call(thisArg, config, platform, true);\n};\nMultiHashHandler.call = function(thisArg, config, platform) {\n    MultiHashHandler.prototype.$init.call(thisArg, config, platform, false);\n};\n\nexports.HashHandler = HashHandler;\nexports.MultiHashHandler = MultiHashHandler;\n"
  },
  {
    "path": "src/keyboard/keybinding.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n * @typedef {import(\"../../ace-internal\").Ace.KeyboardHandler} KeyboardHandler\n */\nvar keyUtil  = require(\"../lib/keys\");\nvar event = require(\"../lib/event\");\n\n\nclass KeyBinding {\n    /**\n     * @param {Editor} editor\n     */\n    constructor(editor) {\n        this.$editor = editor;\n        this.$data = {editor: editor};\n        /**@type {(KeyboardHandler)[]}*/\n        this.$handlers = [];\n        this.setDefaultHandler(editor.commands);\n    }\n\n    /**\n     * @param {KeyboardHandler} kb\n     */\n    setDefaultHandler(kb) {\n        this.removeKeyboardHandler(this.$defaultHandler);\n        this.$defaultHandler = kb;\n        this.addKeyboardHandler(kb, 0);\n    }\n\n    /**\n     * @param {KeyboardHandler} kb\n     */\n    setKeyboardHandler(kb) {\n        var h = this.$handlers;\n        if (h[h.length - 1] == kb)\n            return;\n\n        while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)\n            this.removeKeyboardHandler(h[h.length - 1]);\n\n        this.addKeyboardHandler(kb, 1);\n    }\n\n    /**\n     * @param {KeyboardHandler & {attach?: (editor: any) => void, detach?: (editor: any) => void;}} [kb]\n     * @param {number} [pos]\n     */\n    addKeyboardHandler(kb, pos) {\n        if (!kb)\n            return;\n        // @ts-ignore\n        if (typeof kb == \"function\" && !kb.handleKeyboard)\n            // @ts-ignore\n            kb.handleKeyboard = kb;\n        var i = this.$handlers.indexOf(kb);\n        if (i != -1)\n            this.$handlers.splice(i, 1);\n\n        if (pos == undefined)\n            this.$handlers.push(kb);\n        else\n            this.$handlers.splice(pos, 0, kb);\n\n        if (i == -1 && kb.attach)\n            kb.attach(this.$editor);\n    }\n\n    /**\n     * @param {KeyboardHandler & {attach?: (editor: any) => void, detach?: (editor: any) => void;}} kb\n     * @returns {boolean}\n     */\n    removeKeyboardHandler(kb) {\n        var i = this.$handlers.indexOf(kb);\n        if (i == -1)\n            return false;\n        this.$handlers.splice(i, 1);\n        kb.detach && kb.detach(this.$editor);\n        return true;\n    }\n\n    /**\n     * @return {KeyboardHandler}\n     */\n    getKeyboardHandler() {\n        return this.$handlers[this.$handlers.length - 1];\n    }\n\n    getStatusText() {\n        var data = this.$data;\n        var editor = data.editor;\n        return this.$handlers.map(function(h) {\n            return h.getStatusText && h.getStatusText(editor, data) || \"\";\n        }).filter(Boolean).join(\" \");\n    }\n\n    $callKeyboardHandlers(hashId, keyString, keyCode, e) {\n        var toExecute;\n        var success = false;\n        var commands = this.$editor.commands;\n\n        for (var i = this.$handlers.length; i--;) {\n            toExecute = this.$handlers[i].handleKeyboard(\n                // @ts-expect-error TODO: could be wrong arguments amount\n                this.$data, hashId, keyString, keyCode, e\n            );\n            if (!toExecute || !toExecute.command)\n                continue;\n\n            // allow keyboardHandler to consume keys\n            if (toExecute.command == \"null\") {\n                success = true;\n            } else {\n                // @ts-expect-error //TODO: potential wrong arguments amount\n                success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);\n            }\n            // do not stop input events to not break repeating\n            if (success && e && hashId != -1 &&\n                toExecute[\"passEvent\"] != true && toExecute.command[\"passEvent\"] != true\n            ) {\n                event.stopEvent(e);\n            }\n            if (success)\n                break;\n        }\n\n        if (!success && hashId == -1) {\n            toExecute = {command: \"insertstring\"};\n            success = commands.exec(\"insertstring\", this.$editor, keyString);\n        }\n\n        if (success && this.$editor._signal)\n            this.$editor._signal(\"keyboardActivity\", toExecute);\n\n        return success;\n    }\n\n    /**\n     * @param {any} e\n     * @param {number} hashId\n     * @param {number} keyCode\n     * @return {boolean}\n     * @internal\n     */\n    onCommandKey(e, hashId, keyCode) {\n        var keyString = keyUtil.keyCodeToString(keyCode);\n        return this.$callKeyboardHandlers(hashId, keyString, keyCode, e);\n    }\n\n    /**\n     * @param {string} text\n     * @return {boolean}\n     * @internal\n     */\n    onTextInput(text) {\n        return this.$callKeyboardHandlers(-1, text);\n    }\n\n}\n\nexports.KeyBinding = KeyBinding;\n"
  },
  {
    "path": "src/keyboard/keybinding_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"./../edit_session\").EditSession,\n    Editor = require(\"../editor\").Editor,\n    MockRenderer = require(\"./../test/mockrenderer\").MockRenderer,\n    assert = require(\"./../test/assertions\"),\n    HashHandler = require('./hash_handler').HashHandler,\n    keys = require('../lib/keys'),\n    editor;\n\nfunction initEditor(docString) {\n    var doc = new EditSession(docString.split(\"\\n\"));\n    editor = new Editor(new MockRenderer(), doc);\n}\n\nmodule.exports = {\n\n    \"test: adding a new keyboard handler does not remove the default handler\": function() {\n        initEditor('abc');\n        var handler = new HashHandler({'del': 'f1'});\n        editor.keyBinding.setKeyboardHandler(handler);\n        editor.onCommandKey({}, 0, keys['f1']);\n        assert.equal('bc', editor.getValue(), \"binding of new handler\");\n        editor.onCommandKey({}, 0, keys['delete']);\n        assert.equal('c', editor.getValue(), \"bindings of the old handler should still work\");\n    }\n\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/sublime.js",
    "content": "\"use strict\";\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\n\nfunction moveBySubWords(editor, direction, extend) {\n    var selection = editor.selection;\n    var row = selection.lead.row;\n    var column = selection.lead.column;\n\n    var line = editor.session.getLine(row);\n    if (!line[column + direction]) {\n        var method = (extend ? \"selectWord\" : \"moveCursorShortWord\")\n            + (direction == 1 ? \"Right\" : \"Left\");\n        return editor.selection[method]();\n    }\n    if (direction == -1) column--;\n    while (line[column]) {\n        var type = getType(line[column]) + getType(line[column + direction]);\n        column += direction;\n        if (direction == 1) {\n            if (type == \"WW\" && getType(line[column + 1]) == \"w\")\n                break;\n        }\n        else {\n            if (type == \"wW\") {\n                if (getType(line[column - 1]) == \"W\") {\n                    column -= 1;\n                    break;\n                } else {\n                    continue;\n                }\n            }\n            if (type == \"Ww\")\n                break;\n        }\n        if (/w[s_oW]|_[sWo]|o[s_wW]|s[W]|W[so]/.test(type))\n            break;\n    }\n    if (direction == -1) column++;\n    if (extend)\n        editor.selection.moveCursorTo(row, column);\n    else\n        editor.selection.moveTo(row, column);\n    \n    function getType(x) {\n        if (!x) return \"-\";\n        if (/\\s/.test(x)) return \"s\";\n        if (x == \"_\") return \"_\";\n        if (x.toUpperCase() == x && x.toLowerCase() != x) return \"W\";\n        if (x.toUpperCase() != x && x.toLowerCase() == x) return \"w\";\n        return \"o\";\n    }\n}\n\nexports.handler = new HashHandler();\n \nexports.handler.addCommands([{\n    name: \"find_all_under\",\n    exec: function(editor) {\n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        editor.findAll();\n    },\n    readOnly: true\n}, {\n    name: \"find_under\",\n    exec: function(editor) {\n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        editor.findNext();\n    },\n    readOnly: true\n}, {\n    name: \"find_under_prev\",\n    exec: function(editor) {\n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        editor.findPrevious();\n    },\n    readOnly: true\n}, {\n    name: \"find_under_expand\",\n    exec: function(editor) {\n        editor.selectMore(1, false, true);\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"find_under_expand_skip\",\n    exec: function(editor) {\n        editor.selectMore(1, true, true);\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"delete_to_hard_bol\",\n    exec: function(editor) {\n        var pos = editor.selection.getCursor();\n        editor.session.remove({\n            start: { row: pos.row, column: 0 },\n            end: pos\n        });\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"delete_to_hard_eol\",\n    exec: function(editor) {\n        var pos = editor.selection.getCursor();\n        editor.session.remove({\n            start: pos,\n            end: { row: pos.row, column: Infinity }\n        });\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"moveToWordStartLeft\",\n    exec: function(editor) {\n        editor.selection.moveCursorLongWordLeft();\n        editor.clearSelection();\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"moveToWordEndRight\",\n    exec: function(editor) {\n        editor.selection.moveCursorLongWordRight();\n        editor.clearSelection();\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"selectToWordStartLeft\",\n    exec: function(editor) {\n        var sel = editor.selection;\n        sel.$moveSelection(sel.moveCursorLongWordLeft);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"selectToWordEndRight\",\n    exec: function(editor) {\n        var sel = editor.selection;\n        sel.$moveSelection(sel.moveCursorLongWordRight);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"selectSubWordRight\",\n    exec: function(editor) {\n        moveBySubWords(editor, 1, true);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectSubWordLeft\",\n    exec: function(editor) {\n        moveBySubWords(editor, -1, true);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"moveSubWordRight\",\n    exec: function(editor) {\n        moveBySubWords(editor, 1);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"moveSubWordLeft\",\n    exec: function(editor) {\n        moveBySubWords(editor, -1);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}]);\n\n\n[{\n    bindKey: { mac: \"cmd-k cmd-backspace|cmd-backspace\", win: \"ctrl-shift-backspace|ctrl-k ctrl-backspace\" },\n    name: \"removetolinestarthard\"\n}, {\n    bindKey: { mac: \"cmd-k cmd-k|cmd-delete|ctrl-k\", win: \"ctrl-shift-delete|ctrl-k ctrl-k\" },\n    name: \"removetolineendhard\"\n}, {\n    bindKey: { mac: \"cmd-shift-d\", win: \"ctrl-shift-d\" },\n    name: \"duplicateSelection\"\n}, {\n    bindKey: { mac: \"cmd-l\", win: \"ctrl-l\" },\n    name: \"expandtoline\"\n}, \n{\n    bindKey: {mac: \"cmd-shift-a\", win: \"ctrl-shift-a\"},\n    name: \"expandSelection\",\n    args: {to: \"tag\"}\n}, {\n    bindKey: {mac: \"cmd-shift-j\", win: \"ctrl-shift-j\"},\n    name: \"expandSelection\",\n    args: {to: \"indentation\"}\n}, {\n    bindKey: {mac: \"ctrl-shift-m\", win: \"ctrl-shift-m\"},\n    name: \"expandSelection\",\n    args: {to: \"brackets\"}\n}, {\n    bindKey: {mac: \"cmd-shift-space\", win: \"ctrl-shift-space\"},\n    name: \"expandSelection\",\n    args: {to: \"scope\"}\n},\n{\n    bindKey: { mac: \"ctrl-cmd-g\", win: \"alt-f3\" },\n    name: \"find_all_under\"\n}, {\n    bindKey: { mac: \"alt-cmd-g\", win: \"ctrl-f3\" },\n    name: \"find_under\"\n}, {\n    bindKey: { mac: \"shift-alt-cmd-g\", win: \"ctrl-shift-f3\" },\n    name: \"find_under_prev\"\n}, {\n    bindKey: { mac: \"cmd-g\", win: \"f3\" },\n    name: \"findnext\"\n}, {\n    bindKey: { mac: \"shift-cmd-g\", win: \"shift-f3\" },\n    name: \"findprevious\"\n}, {\n    bindKey: { mac: \"cmd-d\", win: \"ctrl-d\" },\n    name: \"find_under_expand\"\n}, {\n    bindKey: { mac: \"cmd-k cmd-d\", win: \"ctrl-k ctrl-d\" },\n    name: \"find_under_expand_skip\"\n}, \n\n/* fold */\n{\n    bindKey: { mac: \"cmd-alt-[\", win: \"ctrl-shift-[\" },\n    name: \"toggleFoldWidget\"\n}, {\n    bindKey: { mac: \"cmd-alt-]\", win: \"ctrl-shift-]\" },\n    name: \"unfold\"\n}, {\n    bindKey: { mac: \"cmd-k cmd-0|cmd-k cmd-j\", win: \"ctrl-k ctrl-0|ctrl-k ctrl-j\" },\n    name: \"unfoldall\"\n}, {\n    bindKey: { mac: \"cmd-k cmd-1\", win: \"ctrl-k ctrl-1\" },\n    name: \"foldOther\",\n    args: { level: 1 }\n},\n \n\n/* move */\n{\n    bindKey: { win: \"ctrl-left\", mac: \"alt-left\" },\n    name: \"moveToWordStartLeft\"\n}, {\n    bindKey: { win: \"ctrl-right\", mac: \"alt-right\" },\n    name: \"moveToWordEndRight\"\n}, {\n    bindKey: { win: \"ctrl-shift-left\", mac: \"alt-shift-left\" },\n    name: \"selectToWordStartLeft\"\n}, {\n    bindKey: { win: \"ctrl-shift-right\", mac: \"alt-shift-right\" },\n    name: \"selectToWordEndRight\"\n}, \n\n// subwords\n{\n    bindKey: {mac: \"ctrl-alt-shift-right|ctrl-shift-right\", win: \"alt-shift-right\"},\n    name: \"selectSubWordRight\"\n}, {\n    bindKey: {mac: \"ctrl-alt-shift-left|ctrl-shift-left\", win: \"alt-shift-left\"},\n    name: \"selectSubWordLeft\"\n}, {\n    bindKey: {mac: \"ctrl-alt-right|ctrl-right\", win: \"alt-right\"},\n    name: \"moveSubWordRight\"\n}, {\n    bindKey: {mac: \"ctrl-alt-left|ctrl-left\", win: \"alt-left\"},\n    name: \"moveSubWordLeft\"\n}, \n{\n    bindKey: { mac: \"ctrl-m\", win: \"ctrl-m\" },\n    name: \"jumptomatching\",\n    args: { to: \"brackets\" }\n}, \n{\n    bindKey: { mac: \"ctrl-f6\", win: \"ctrl-f6\" },\n    name: \"goToNextError\"\n}, {\n    bindKey: { mac: \"ctrl-shift-f6\", win: \"ctrl-shift-f6\" },\n    name: \"goToPreviousError\"\n},\n\n{\n    bindKey: { mac: \"ctrl-o\" },\n    name: \"splitline\"\n}, \n{\n    bindKey: {mac: \"ctrl-shift-w\", win: \"alt-shift-w\"},\n    name: \"surrowndWithTag\"\n},{\n    bindKey: {mac: \"cmd-alt-.\", win: \"alt-.\"},\n    name: \"close_tag\"\n}, \n{\n    bindKey: { mac: \"cmd-j\", win: \"ctrl-j\" },\n    name: \"joinlines\"\n}, \n\n{\n    bindKey: {mac: \"ctrl--\", win: \"alt--\"},\n    name: \"jumpBack\"\n}, {\n    bindKey: {mac: \"ctrl-shift--\", win: \"alt-shift--\"},\n    name: \"jumpForward\"\n}, \n\n{\n    bindKey: { mac: \"cmd-k cmd-l\", win: \"ctrl-k ctrl-l\" },\n    name: \"tolowercase\"\n}, {\n    bindKey: { mac: \"cmd-k cmd-u\", win: \"ctrl-k ctrl-u\" },\n    name: \"touppercase\"\n}, \n\n{\n    bindKey: {mac: \"cmd-shift-v\", win: \"ctrl-shift-v\"},\n    name: \"paste_and_indent\"\n}, {\n    bindKey: {mac: \"cmd-k cmd-v|cmd-alt-v\", win: \"ctrl-k ctrl-v\"},\n    name: \"paste_from_history\"\n}, \n\n{\n    bindKey: { mac: \"cmd-shift-enter\", win: \"ctrl-shift-enter\" },\n    name: \"addLineBefore\"\n}, {\n    bindKey: { mac: \"cmd-enter\", win: \"ctrl-enter\" },\n    name: \"addLineAfter\"\n}, {\n    bindKey: { mac: \"ctrl-shift-k\", win: \"ctrl-shift-k\" },\n    name: \"removeline\"\n}, {\n    bindKey: { mac: \"ctrl-alt-up\", win: \"ctrl-up\" },\n    name: \"scrollup\"\n}, {\n    bindKey: { mac: \"ctrl-alt-down\", win: \"ctrl-down\" },\n    name: \"scrolldown\"\n}, {\n    bindKey: { mac: \"cmd-a\", win: \"ctrl-a\" },\n    name: \"selectall\"\n}, {\n    bindKey: { linux: \"alt-shift-down\", mac: \"ctrl-shift-down\", win: \"ctrl-alt-down\" },\n    name: \"addCursorBelow\"\n}, {\n    bindKey: { linux: \"alt-shift-up\", mac: \"ctrl-shift-up\", win: \"ctrl-alt-up\" },\n    name: \"addCursorAbove\"\n},\n\n\n{\n    bindKey: { mac: \"cmd-k cmd-c|ctrl-l\", win: \"ctrl-k ctrl-c\" },\n    name: \"centerselection\"\n}, \n\n{\n    bindKey: { mac: \"f5\", win: \"f9\" },\n    name: \"sortlines\"\n}, \n{\n    bindKey: {mac: \"ctrl-f5\", win: \"ctrl-f9\"},\n    name: \"sortlines\",\n    args: {caseSensitive: true}\n},\n{\n    bindKey: { mac: \"cmd-shift-l\", win: \"ctrl-shift-l\" },\n    name: \"splitSelectionIntoLines\"\n}, {\n    bindKey: { mac: \"ctrl-cmd-down\", win: \"ctrl-shift-down\" },\n    name: \"movelinesdown\"\n}, {\n    bindKey: { mac: \"ctrl-cmd-up\", win: \"ctrl-shift-up\" },\n    name: \"movelinesup\"\n}, {\n    bindKey: { mac: \"alt-down\", win: \"alt-down\" },\n    name: \"modifyNumberDown\"\n}, {\n    bindKey: { mac: \"alt-up\", win: \"alt-up\" },\n    name: \"modifyNumberUp\"\n}, {\n    bindKey: { mac: \"cmd-/\", win: \"ctrl-/\" },\n    name: \"togglecomment\"\n}, {\n    bindKey: { mac: \"cmd-alt-/\", win: \"ctrl-shift-/\" },\n    name: \"toggleBlockComment\"\n},\n\n\n{\n    bindKey: { linux: \"ctrl-alt-q\", mac: \"ctrl-q\", win: \"ctrl-q\" },\n    name: \"togglerecording\"\n}, {\n    bindKey: { linux: \"ctrl-alt-shift-q\", mac: \"ctrl-shift-q\", win: \"ctrl-shift-q\" },\n    name: \"replaymacro\"\n}, \n\n{\n    bindKey: { mac: \"ctrl-t\", win: \"ctrl-t\" },\n    name: \"transpose\"\n}\n\n].forEach(function(binding) {\n    var command = exports.handler.commands[binding.name];\n    if (command)\n        command.bindKey = binding.bindKey;\n    exports.handler.bindKey(binding.bindKey, command || binding.name);\n});\n"
  },
  {
    "path": "src/keyboard/sublime_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"../multi_select\");\n\nvar EditSession = require(\"./../edit_session\").EditSession;\nvar Editor = require(\"../editor\").Editor;\nvar Range = require(\"./../range\").Range;\nvar MockRenderer = require(\"./../test/mockrenderer\").MockRenderer;\nvar assert = require(\"./../test/assertions\");\nvar handler = require(\"./sublime\").handler;\nvar editor;\n\nfunction initEditor(docString) {\n    var doc = new EditSession(docString.split(\"\\n\"));\n    editor = new Editor(new MockRenderer(), doc);\n    editor.setKeyboardHandler(handler);\n}\n\nmodule.exports = {\n\n    \"test: move by subwords\": function() {\n        initEditor(\"\\n   abcDefGHKLmn_op ++ xyz$\\nt\");\n        \n        [0, 3, 6, 9, 12, 15, 18, 21, 25, 26, 0, 1, 1].forEach(function(col) {\n            assert.equal(editor.selection.lead.column, col);\n            editor.execCommand(handler.commands.moveSubWordRight);\n        });\n        [1, 0, 26, 25, 22, 19, 16, 12, 9, 6, 3, 0, 0].forEach(function(col) {\n            assert.equal(editor.selection.lead.column, col);\n            editor.execCommand(handler.commands.moveSubWordLeft);\n        });\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/textarea.js",
    "content": "\"use strict\";\n\nvar HashHandler = require(\"./hash_handler\").HashHandler;\nexports.handler = new HashHandler();\n\n[{\n    bindKey: \"Shift-Tab|Tab\",\n    command: \"passKeysToBrowser\"\n}, {\n    bindKey: {win: \"Ctrl-L\", mac: \"Cmd-L\"},\n    command: \"passKeysToBrowser\"\n}, {\n    bindKey: {win: \"Ctrl-G\", mac: \"Cmd-G\"},\n    command: \"gotoline\"\n}, {\n    bindKey: {win: \"Ctrl-T|Ctrl-Shift-T|Ctrl-K\", mac: \"Cmd-T|Cmd-Shift-T\"},\n    // TODO can't used shared passKeysToBrowser command since passEvent from it is ignored\n    command: {\n        name: \"passKeysToBrowser\",\n        exec: function() {},\n        passEvent: true,\n        readOnly: true\n    }\n}, {\n    bindKey: {win: \"Ctrl-G\", mac: \"Cmd-G\"},\n    command: \"passKeysToBrowser\"\n}, {\n    bindKey: {win: \"Ctrl-G\", mac: \"Cmd-G\"},\n    command: \"passKeysToBrowser\"\n}, {\n    command: \"golineup\",\n    bindKey: {win: null, mac: \"Ctrl-P\"}\n}, {\n    command: \"golinedown\",\n    bindKey: {win: null, mac: \"Ctrl-N\"}\n}, {\n    command: \"gotoleft\",    \n    bindKey: {win: null, mac: \"Ctrl-B\"}\n}, {\n    command: \"gotoright\",\n    bindKey: {win: null, mac: \"Ctrl-F\"}\n}, {\n    command: \"gotolineend\",\n    bindKey: {win: null, mac: \"Ctrl-E\"}\n}, {\n    command: \"gotolinestart\",\n    bindKey: {win: null, mac: \"Ctrl-A\"}\n}\n].forEach(function(k) {\n    var bindKey = k.bindKey;\n    if (typeof bindKey == \"object\")\n        bindKey = bindKey[exports.handler.platform];\n    exports.handler.bindKey(bindKey, k.command);\n});\nexports.handler[\"$id\"] = \"ace/keyboard/textarea\";\n"
  },
  {
    "path": "src/keyboard/textinput.js",
    "content": "\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar nls = require(\"../config\").nls;\nvar useragent = require(\"../lib/useragent\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar clipboard = require(\"../clipboard\");\nvar BROKEN_SETDATA = useragent.isChrome < 18;\nvar USE_IE_MIME_TYPE =  useragent.isIE;\nvar HAS_FOCUS_ARGS = useragent.isChrome > 63;\nvar MAX_LINE_LENGTH = 400;\n\n/**\n *\n * @type {{[key: string]: any}}\n */\nvar KEYS = require(\"../lib/keys\");\nvar MODS = KEYS.KEY_MODS;\nvar isIOS = useragent.isIOS;\nvar valueResetRegex = isIOS ? /\\s/ : /\\n/;\nvar isMobile = useragent.isMobile;\n\nclass TextInput {\n    /**\n     * @param {HTMLElement} parentNode\n     * @param {import(\"../editor\").Editor} host\n     */\n    constructor(parentNode, host) {\n        this.host = host;\n        /**@type {HTMLTextAreaElement & {msGetInputContext?: () => {compositionStartOffset: number}, getInputContext?: () => {compositionStartOffset: number}}}*/\n        this.text = dom.createElement(\"textarea\");\n        this.text.className = \"ace_text-input\";\n\n        this.text.setAttribute(\"wrap\", \"off\");\n        this.text.setAttribute(\"autocomplete\", \"off\");\n        this.text.setAttribute(\"autocorrect\", \"off\");\n        this.text.setAttribute(\"autocapitalize\", \"off\");\n        this.text.setAttribute(\"spellcheck\", \"false\");\n\n        this.text.style.opacity = \"0\";\n        parentNode.insertBefore(this.text, parentNode.firstChild);\n\n        /**@type{boolean|string}*/this.copied = false;\n        this.pasted = false;\n        /**@type {(boolean|Object) & {context?: any, useTextareaForIME?: boolean, selectionStart?: number, markerRange?: any}}} */\n        this.inComposition = false;\n        this.sendingText = false;\n        this.tempStyle = '';\n\n        if (!isMobile) this.text.style.fontSize = \"1px\";\n\n        this.commandMode = false;\n        this.ignoreFocusEvents = false;\n\n        this.lastValue = \"\";\n        this.lastSelectionStart = 0;\n        this.lastSelectionEnd = 0;\n        this.lastRestoreEnd = 0;\n        this.rowStart = Number.MAX_SAFE_INTEGER;\n        this.rowEnd = Number.MIN_SAFE_INTEGER;\n        this.numberOfExtraLines = 0;\n\n        // FOCUS\n        // ie9 throws error if document.activeElement is accessed too soon\n        try {\n            this.$isFocused = document.activeElement === this.text;\n        } catch (e) {\n        }\n\n        this.cancelComposition = this.cancelComposition.bind(this);\n\n        this.setAriaOptions({role: \"textbox\"});\n\n        event.addListener(this.text, \"blur\", (e) => {\n            if (this.ignoreFocusEvents) return;\n            host.onBlur(e);\n            this.$isFocused = false;\n        }, host);\n        event.addListener(this.text, \"focus\", (e) => {\n            if (this.ignoreFocusEvents) return;\n            this.$isFocused = true;\n            if (useragent.isEdge) {\n                // on edge focus event is fired even if document itself is not focused\n                try {\n                    if (!document.hasFocus()) return;\n                } catch (e) {\n                }\n            }\n            host.onFocus(e);\n            if (useragent.isEdge) setTimeout(this.resetSelection.bind(this)); else this.resetSelection();\n        }, host);\n\n        /**@type {boolean | string}*/this.$focusScroll = false;\n\n        host.on(\"beforeEndOperation\", () => {\n            var curOp = host.curOp;\n            var commandName = curOp && curOp.command && curOp.command.name;\n            if (commandName == \"insertstring\") return;\n            var isUserAction = commandName && (curOp.docChanged || curOp.selectionChanged);\n            if (this.inComposition && isUserAction) {\n                // exit composition from commands other than insertstring\n                this.lastValue = this.text.value = \"\";\n                this.onCompositionEnd();\n            }\n            // sync value of textarea\n            this.resetSelection();\n        });\n\n        // if cursor changes position, we need to update the label with the correct row\n        host.on(\"changeSelection\", this.setAriaLabel.bind(this));\n\n        this.resetSelection = isIOS ? this.$resetSelectionIOS : this.$resetSelection;\n\n        if (this.$isFocused) host.onFocus();\n\n        this.inputHandler = null;\n        this.afterContextMenu = false;\n\n        event.addCommandKeyListener(this.text, (e, hashId, keyCode) => {\n            // ignore command events during composition as they will\n            // either be handled by ime itself or fired again after ime end\n            if (this.inComposition) return;\n            return host.onCommandKey(e, hashId, keyCode);\n        }, host);\n\n        event.addListener(this.text, \"select\", this.onSelect.bind(this), host);\n        event.addListener(this.text, \"input\", this.onInput.bind(this), host);\n\n        event.addListener(this.text, \"cut\", this.onCut.bind(this), host);\n        event.addListener(this.text, \"copy\", this.onCopy.bind(this), host);\n        event.addListener(this.text, \"paste\", this.onPaste.bind(this), host);\n\n\n        // Opera has no clipboard events\n        if (!('oncut' in this.text) || !('oncopy' in this.text) || !('onpaste' in this.text)) {\n            event.addListener(parentNode, \"keydown\", (e) => {\n                if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) return;\n\n                switch (e.keyCode) {\n                    case 67:\n                        this.onCopy(e);\n                        break;\n                    case 86:\n                        this.onPaste(e);\n                        break;\n                    case 88:\n                        this.onCut(e);\n                        break;\n                }\n            }, host);\n        }\n\n        this.syncComposition = lang.delayedCall(this.onCompositionUpdate.bind(this), 50).schedule.bind(null, null); //TODO: check this\n\n        event.addListener(this.text, \"compositionstart\", this.onCompositionStart.bind(this), host);\n        event.addListener(this.text, \"compositionupdate\", this.onCompositionUpdate.bind(this), host);\n        event.addListener(this.text, \"keyup\", this.onKeyup.bind(this), host);\n        event.addListener(this.text, \"keydown\", this.syncComposition.bind(this), host);\n        event.addListener(this.text, \"compositionend\", this.onCompositionEnd.bind(this), host);\n\n        this.closeTimeout;\n\n        event.addListener(this.text, \"mouseup\", this.$onContextMenu.bind(this), host);\n        event.addListener(this.text, \"mousedown\", (e) => {\n            e.preventDefault();\n            this.onContextMenuClose();\n        }, host);\n        event.addListener(host.renderer.scroller, \"contextmenu\", this.$onContextMenu.bind(this), host);\n        event.addListener(this.text, \"contextmenu\", this.$onContextMenu.bind(this), host);\n\n        if (isIOS) this.addIosSelectionHandler(parentNode, host, this.text);\n    }\n\n    /**\n     * @internal\n     * @param {HTMLElement} parentNode\n     * @param {import(\"../editor\").Editor} host\n     * @param {HTMLTextAreaElement} text\n     */\n    addIosSelectionHandler(parentNode, host, text) {\n        var typingResetTimeout = null;\n        var typing = false;\n\n        text.addEventListener(\"keydown\", function (e) {\n            if (typingResetTimeout) clearTimeout(typingResetTimeout);\n            typing = true;\n        }, true);\n\n        text.addEventListener(\"keyup\", function (e) {\n            typingResetTimeout = setTimeout(function () {\n                typing = false;\n            }, 100);\n        }, true);\n\n        // IOS doesn't fire events for arrow keys, but this unique hack changes everything!\n        var detectArrowKeys = (e) => {\n            if (document.activeElement !== text) return;\n            if (typing || this.inComposition || host.$mouseHandler.isMousePressed) return;\n\n            if (this.copied) {\n                return;\n            }\n            var selectionStart = text.selectionStart;\n            var selectionEnd = text.selectionEnd;\n\n            var key = null;\n            var modifier = 0;\n            // console.log(selectionStart, selectionEnd);\n            if (selectionStart == 0) {\n                key = KEYS.up;\n            }\n            else if (selectionStart == 1) {\n                key = KEYS.home;\n            }\n            else if (selectionEnd > this.lastSelectionEnd && this.lastValue[selectionEnd] == \"\\n\") {\n                key = KEYS.end;\n            }\n            else if (selectionStart < this.lastSelectionStart && this.lastValue[selectionStart - 1] == \" \") {\n                key = KEYS.left;\n                modifier = MODS.option;\n            }\n            else if (selectionStart < this.lastSelectionStart || (selectionStart == this.lastSelectionStart\n                && this.lastSelectionEnd != this.lastSelectionStart && selectionStart == selectionEnd)) {\n                key = KEYS.left;\n            }\n            else if (selectionEnd > this.lastSelectionEnd && this.lastValue.slice(0, selectionEnd).split(\n                \"\\n\").length > 2) {\n                key = KEYS.down;\n            }\n            else if (selectionEnd > this.lastSelectionEnd && this.lastValue[selectionEnd - 1] == \" \") {\n                key = KEYS.right;\n                modifier = MODS.option;\n            }\n            else if (selectionEnd > this.lastSelectionEnd || (selectionEnd == this.lastSelectionEnd\n                && this.lastSelectionEnd != this.lastSelectionStart && selectionStart == selectionEnd)) {\n                key = KEYS.right;\n            }\n\n            if (selectionStart !== selectionEnd) modifier |= MODS.shift;\n\n            if (key) {\n                var result = host.onCommandKey({}, modifier, key);\n                if (!result && host.commands) {\n                    key = KEYS.keyCodeToString(key);\n                    var command = host.commands.findKeyCommand(modifier, key);\n                    if (command) host.execCommand(command);\n                }\n                this.lastSelectionStart = selectionStart;\n                this.lastSelectionEnd = selectionEnd;\n                this.resetSelection(\"\");\n            }\n        };\n        // On iOS, \"selectionchange\" can only be attached to the document object...\n        document.addEventListener(\"selectionchange\", detectArrowKeys);\n        host.on(\"destroy\", function () {\n            document.removeEventListener(\"selectionchange\", detectArrowKeys);\n        });\n    }\n\n    onContextMenuClose() {\n        clearTimeout(this.closeTimeout);\n        this.closeTimeout = setTimeout(() => {\n            if (this.tempStyle) {\n                this.text.style.cssText = this.tempStyle;\n                this.tempStyle = '';\n            }\n            this.host.renderer.$isMousePressed = false;\n            if (this.host.renderer.$keepTextAreaAtCursor) this.host.renderer.$moveTextAreaToCursor();\n        }, 0);\n    }\n\n    $onContextMenu(e) {\n        this.host.textInput.onContextMenu(e);\n        this.onContextMenuClose();\n    }\n\n    /**\n     * @internal\n     * @param e\n     */\n    onKeyup(e) {\n        // workaround for a bug in ie where pressing esc silently moves selection out of textarea\n        if (e.keyCode == 27 && this.text.value.length < this.text.selectionStart) {\n            if (!this.inComposition) this.lastValue = this.text.value;\n            this.lastSelectionStart = this.lastSelectionEnd = -1;\n            this.resetSelection();\n        }\n        this.syncComposition();\n    }\n\n    // COMPOSITION\n\n    /**\n     * @internal\n     */\n    cancelComposition() {\n        // force end composition\n        this.ignoreFocusEvents = true;\n        this.text.blur();\n        this.text.focus();\n        this.ignoreFocusEvents = false;\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionStart(e) {\n        if (this.inComposition || !this.host.onCompositionStart || this.host.$readOnly) return;\n\n        this.inComposition = {};\n\n        if (this.commandMode) return;\n\n        if (e.data) this.inComposition.useTextareaForIME = false;\n\n        setTimeout(this.onCompositionUpdate.bind(this), 0);\n        this.host._signal(\"compositionStart\");\n        this.host.on(\"mousedown\", this.cancelComposition); //TODO:\n\n        var range = this.host.getSelectionRange();\n        range.end.row = range.start.row;\n        range.end.column = range.start.column;\n        this.inComposition.markerRange = range;\n        this.inComposition.selectionStart = this.lastSelectionStart;\n        this.host.onCompositionStart(this.inComposition);\n\n        if (this.inComposition.useTextareaForIME) {\n            this.lastValue = this.text.value = \"\";\n            this.lastSelectionStart = 0;\n            this.lastSelectionEnd = 0;\n        }\n        else {\n            if (this.text.msGetInputContext) this.inComposition.context = this.text.msGetInputContext();\n            if (this.text.getInputContext) this.inComposition.context = this.text.getInputContext();\n        }\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionUpdate() {\n        if (!this.inComposition || !this.host.onCompositionUpdate || this.host.$readOnly) return;\n        if (this.commandMode) return this.cancelComposition();\n\n        if (this.inComposition.useTextareaForIME) {\n            this.host.onCompositionUpdate(this.text.value);\n        }\n        else {\n            var data = this.text.value;\n            this.sendText(data);\n            if (this.inComposition.markerRange) {\n                if (this.inComposition.context) {\n                    this.inComposition.markerRange.start.column = this.inComposition.selectionStart = this.inComposition.context.compositionStartOffset;\n                }\n                this.inComposition.markerRange.end.column = this.inComposition.markerRange.start.column\n                    + this.lastSelectionEnd - this.inComposition.selectionStart + this.lastRestoreEnd;\n            }\n        }\n    }\n\n    /**\n     * @internal\n     */\n    onCompositionEnd(e) {\n        if (!this.host.onCompositionEnd || this.host.$readOnly) return;\n        this.inComposition = false;\n        this.host.onCompositionEnd();\n        this.host.off(\"mousedown\", this.cancelComposition);\n        // note that resetting value of textarea at this point doesn't always work\n        // because textarea value can be silently restored\n        if (e) this.onInput();\n    }\n\n    /**\n     * @internal\n     */\n    onCut(e) {\n        this.doCopy(e, true);\n    }\n\n    /**\n     * @internal\n     */\n    onCopy(e) {\n        this.doCopy(e, false);\n    }\n\n    /**\n     * @internal\n     */\n    onPaste(e) {\n        var data = this.handleClipboardData(e);\n        if (clipboard.pasteCancelled()) return;\n        if (typeof data == \"string\") {\n            if (data) this.host.onPaste(data, e);\n            if (useragent.isIE) setTimeout(this.resetSelection);\n            event.preventDefault(e);\n        }\n        else {\n            this.text.value = \"\";\n            this.pasted = true;\n        }\n    }\n\n    /**\n     * @internal\n     * @param {ClipboardEvent} e\n     * @param {boolean} isCut\n     */\n    doCopy(e, isCut) {\n        var data = this.host.getCopyText();\n        if (!data) return event.preventDefault(e);\n\n        if (this.handleClipboardData(e, data)) {\n            if (isIOS) {\n                this.resetSelection(data);\n                this.copied = data;\n                setTimeout(() => {\n                    this.copied = false;\n                }, 10);\n            }\n            isCut ? this.host.onCut() : this.host.onCopy();\n            event.preventDefault(e);\n        }\n        else {\n            this.copied = true;\n            this.text.value = data;\n            this.text.select();\n            setTimeout(() => {\n                this.copied = false;\n                this.resetSelection();\n                isCut ? this.host.onCut() : this.host.onCopy();\n            });\n        }\n    }\n\n    /**\n     *\n     * @internal\n     * @param {ClipboardEvent} e\n     * @param {string} [data]\n     * @param {boolean} [forceIEMime]\n     */\n    handleClipboardData(e, data, forceIEMime) {\n        var clipboardData = e.clipboardData || window[\"clipboardData\"];\n        if (!clipboardData || BROKEN_SETDATA) return;\n        // using \"Text\" doesn't work on old webkit but ie needs it\n        var mime = USE_IE_MIME_TYPE || forceIEMime ? \"Text\" : \"text/plain\";\n        try {\n            if (data) {\n                // Safari 5 has clipboardData object, but does not handle setData()\n                return clipboardData.setData(mime, data) !== false;\n            }\n            else {\n                return clipboardData.getData(mime);\n            }\n        } catch (e) {\n            if (!forceIEMime) return this.handleClipboardData(e, data, true);\n        }\n    }\n\n    /**\n     * @internal\n     * @param e\n     */\n    onInput(e) {\n        if (this.inComposition) return this.onCompositionUpdate();\n        if (e && e.inputType) {\n            if (e.inputType == \"historyUndo\") return this.host.execCommand(\"undo\");\n            if (e.inputType == \"historyRedo\") return this.host.execCommand(\"redo\");\n        }\n        var data = this.text.value;\n        var inserted = this.sendText(data, true);\n        if (data.length > MAX_LINE_LENGTH + 100 || valueResetRegex.test(inserted) || isMobile && this.lastSelectionStart\n            < 1 && this.lastSelectionStart == this.lastSelectionEnd) {\n            this.resetSelection();\n        }\n    }\n\n    /**\n     * @internal\n     * @param {string} value\n     * @param {boolean} [fromInput]\n     * @return {string}\n     */\n    sendText(value, fromInput) {\n        if (this.afterContextMenu) this.afterContextMenu = false;\n        if (this.pasted) {\n            this.resetSelection();\n            if (value) this.host.onPaste(value);\n            this.pasted = false;\n            return \"\";\n        }\n        else {\n            var selectionStart = this.text.selectionStart;\n            var selectionEnd = this.text.selectionEnd;\n\n            var extendLeft = this.lastSelectionStart;\n            var extendRight = this.lastValue.length - this.lastSelectionEnd;\n\n            var inserted = value;\n            var restoreStart = value.length - selectionStart;\n            var restoreEnd = value.length - selectionEnd;\n\n            var i = 0;\n            while (extendLeft > 0 && this.lastValue[i] == value[i]) {\n                i++;\n                extendLeft--;\n            }\n            inserted = inserted.slice(i);\n            i = 1;\n            while (extendRight > 0 && this.lastValue.length - i > this.lastSelectionStart - 1\n            && this.lastValue[this.lastValue.length - i] == value[value.length - i]) {\n                i++;\n                extendRight--;\n            }\n            restoreStart -= i - 1;\n            restoreEnd -= i - 1;\n            var endIndex = inserted.length - i + 1;\n            if (endIndex < 0) {\n                extendLeft = -endIndex;\n                endIndex = 0;\n            }\n            inserted = inserted.slice(0, endIndex);\n\n            // composition update can be called without any change\n            if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd) return \"\";\n            this.sendingText = true;\n\n            // some android keyboards converts two spaces into sentence end, which is not useful for code\n            var shouldReset = false;\n            if (useragent.isAndroid && inserted == \". \") {\n                inserted = \"  \";\n                shouldReset = true;\n            }\n\n            if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || this.commandMode) {\n                this.host.onTextInput(inserted);\n            }\n            else {\n                this.host.onTextInput(inserted, {\n                    extendLeft: extendLeft,\n                    extendRight: extendRight,\n                    restoreStart: restoreStart,\n                    restoreEnd: restoreEnd\n                });\n            }\n            this.sendingText = false;\n\n            this.lastValue = value;\n            this.lastSelectionStart = selectionStart;\n            this.lastSelectionEnd = selectionEnd;\n            this.lastRestoreEnd = restoreEnd;\n            return shouldReset ? \"\\n\" : inserted;\n        }\n    }\n\n    /**\n     * @internal\n     * @param e\n     */\n    onSelect(e) {\n        if (this.inComposition) return;\n\n        var isAllSelected = (text) => {\n            return text.selectionStart === 0 && text.selectionEnd >= this.lastValue.length && text.value\n                === this.lastValue && this.lastValue && text.selectionEnd !== this.lastSelectionEnd;\n        };\n\n        if (this.copied) {\n            this.copied = false;\n        }\n        else if (isAllSelected(this.text)) {\n            this.host.selectAll();\n            this.resetSelection();\n        }\n        else if (isMobile && this.text.selectionStart != this.lastSelectionStart) {\n            this.resetSelection();\n        }\n    }\n\n    $resetSelectionIOS(value) {\n        if (!this.$isFocused || (this.copied && !value) || this.sendingText) return;\n        if (!value) value = \"\";\n        var newValue = \"\\n ab\" + value + \"cde fg\\n\";\n        if (newValue != this.text.value) this.text.value = this.lastValue = newValue;\n\n        var selectionStart = 4;\n        var selectionEnd = 4 + (value.length || (this.host.selection.isEmpty() ? 0 : 1));\n\n        if (this.lastSelectionStart != selectionStart || this.lastSelectionEnd != selectionEnd) {\n            this.text.setSelectionRange(selectionStart, selectionEnd);\n        }\n        this.lastSelectionStart = selectionStart;\n        this.lastSelectionEnd = selectionEnd;\n    }\n\n    $resetSelection() {\n        if (this.inComposition || this.sendingText) return;\n        // modifying selection of blured textarea can focus it (chrome mac/linux)\n        if (!this.$isFocused && !this.afterContextMenu) return;\n        // see https://github.com/ajaxorg/ace/issues/2114\n        // this prevents infinite recursion on safari 8\n        this.inComposition = true;\n\n        var selectionStart = 0;\n        var selectionEnd = 0;\n        var line = \"\";\n\n        // Convert from row,column position to the linear position with respect to the current\n        // block of lines in the textarea.\n        var positionToSelection = (row, column) => {\n            var selection = column;\n\n            for (var i = 1; i <= row - this.rowStart && i < 2 * this.numberOfExtraLines + 1; i++) {\n                selection += this.host.session.getLine(row - i).length + 1;\n            }\n            return selection;\n        };\n\n        if (this.host.session) {\n            var selection = this.host.selection;\n            var range = selection.getRange();\n            var row = selection.cursor.row;\n\n            // We keep 2*numberOfExtraLines + 1 lines in the textarea, if the new active row\n            // is within the current block of lines in the textarea we do nothing. If the new row\n            // is one row above or below the current block, move up or down to the next block of lines.\n            // If the new row is further than 1 row away from the current block grab a new block centered\n            // around the new row.\n            if (row === this.rowEnd + 1) {\n                this.rowStart = this.rowEnd + 1;\n                this.rowEnd = this.rowStart + 2 * this.numberOfExtraLines;\n            }\n            else if (row === this.rowStart - 1) {\n                this.rowEnd = this.rowStart - 1;\n                this.rowStart = this.rowEnd - 2 * this.numberOfExtraLines;\n            }\n            else if (row < this.rowStart - 1 || row > this.rowEnd + 1) {\n                this.rowStart = row > this.numberOfExtraLines ? row - this.numberOfExtraLines : 0;\n                this.rowEnd = row > this.numberOfExtraLines ? row + this.numberOfExtraLines : 2\n                    * this.numberOfExtraLines;\n            }\n\n            var lines = [];\n\n            for (var i = this.rowStart; i <= this.rowEnd; i++) {\n                lines.push(this.host.session.getLine(i));\n            }\n\n            line = lines.join('\\n');\n\n            selectionStart = positionToSelection(range.start.row, range.start.column);\n            selectionEnd = positionToSelection(range.end.row, range.end.column);\n\n            if (range.start.row < this.rowStart) {\n                var prevLine = this.host.session.getLine(this.rowStart - 1);\n                selectionStart = range.start.row < this.rowStart - 1 ? 0 : selectionStart;\n                selectionEnd += prevLine.length + 1;\n                line = prevLine + \"\\n\" + line;\n            }\n            else if (range.end.row > this.rowEnd) {\n                var nextLine = this.host.session.getLine(this.rowEnd + 1);\n                selectionEnd = range.end.row > this.rowEnd + 1 ? nextLine.length : range.end.column;\n                selectionEnd += line.length + 1;\n                line = line + \"\\n\" + nextLine;\n            }\n            else if (isMobile && row > 0) {\n                line = \"\\n\" + line;\n                selectionEnd += 1;\n                selectionStart += 1;\n            }\n\n            if (line.length > MAX_LINE_LENGTH) {\n                if (selectionStart < MAX_LINE_LENGTH && selectionEnd < MAX_LINE_LENGTH) {\n                    line = line.slice(0, MAX_LINE_LENGTH);\n                }\n                else {\n                    line = \"\\n\";\n                    if (selectionStart == selectionEnd) {\n                        selectionStart = selectionEnd = 0;\n                    }\n                    else {\n                        selectionStart = 0;\n                        selectionEnd = 1;\n                    }\n                }\n            }\n\n            var newValue = line + \"\\n\\n\";\n            if (newValue != this.lastValue) {\n                this.text.value = this.lastValue = newValue;\n                this.lastSelectionStart = this.lastSelectionEnd = newValue.length;\n            }\n        }\n\n        // contextmenu on mac may change the selection\n        if (this.afterContextMenu) {\n            this.lastSelectionStart = this.text.selectionStart;\n            this.lastSelectionEnd = this.text.selectionEnd;\n        }\n        // on firefox this throws if textarea is hidden\n        if (this.lastSelectionEnd != selectionEnd || this.lastSelectionStart != selectionStart || this.text.selectionEnd\n            != this.lastSelectionEnd // on ie edge selectionEnd changes silently after the initialization\n        ) {\n            try {\n                this.text.setSelectionRange(selectionStart, selectionEnd);\n                this.lastSelectionStart = selectionStart;\n                this.lastSelectionEnd = selectionEnd;\n            } catch (e) {\n            }\n        }\n        this.inComposition = false;\n    }\n\n    /**\n     * @param {import(\"../editor\").Editor} newHost\n     */\n    setHost(newHost) {\n        this.host = newHost;\n    }\n\n    /**\n     * Sets the number of extra lines in the textarea to improve screen reader compatibility.\n     * Extra lines can help screen readers perform better when reading text.\n     *\n     * @param {number} number - The number of extra lines to add. Must be non-negative.\n     */\n    setNumberOfExtraLines(number) {\n        this.rowStart = Number.MAX_SAFE_INTEGER;\n        this.rowEnd = Number.MIN_SAFE_INTEGER;\n\n        if (number < 0) {\n            this.numberOfExtraLines = 0;\n            return;\n        }\n\n        this.numberOfExtraLines = number;\n    }\n\n\n    setAriaLabel() {\n        var ariaLabel = \"\";\n        if (this.host.$textInputAriaLabel) {\n            ariaLabel += `${this.host.$textInputAriaLabel}, `;\n        }\n        if (this.host.session) {\n            var row = this.host.session.selection.cursor.row;\n            ariaLabel += nls(\"text-input.aria-label\", \"Cursor at row $0\", [row + 1]);\n        }\n        this.text.setAttribute(\"aria-label\", ariaLabel);\n    }\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.TextInputAriaOptions} options\n     */\n    setAriaOptions(options) {\n        if (options.activeDescendant) {\n            this.text.setAttribute(\"aria-haspopup\", \"true\");\n            this.text.setAttribute(\"aria-autocomplete\", options.inline ? \"both\" : \"list\");\n            this.text.setAttribute(\"aria-activedescendant\", options.activeDescendant);\n        }\n        else {\n            this.text.setAttribute(\"aria-haspopup\", \"false\");\n            this.text.setAttribute(\"aria-autocomplete\", \"both\");\n            this.text.removeAttribute(\"aria-activedescendant\");\n        }\n        if (options.role) {\n            this.text.setAttribute(\"role\", options.role);\n        }\n        if (options.setLabel) {\n            this.text.setAttribute(\"aria-roledescription\", nls(\"text-input.aria-roledescription\", \"editor\"));\n            this.setAriaLabel();\n        }\n    }\n\n    focus() {\n        // On focusing on the textarea, read active row number to assistive tech.\n        this.setAriaOptions({\n            setLabel: this.host.renderer.enableKeyboardAccessibility\n        });\n\n        if (this.tempStyle || HAS_FOCUS_ARGS || this.$focusScroll == \"browser\") return this.text.focus(\n            {preventScroll: true});\n\n        var top = this.text.style.top;\n        this.text.style.position = \"fixed\";\n        this.text.style.top = \"0px\";\n        try {\n            var isTransformed = this.text.getBoundingClientRect().top != 0;\n        } catch (e) {\n            // getBoundingClientRect on IE throws error if element is not in the dom tree\n            return;\n        }\n        var ancestors = [];\n        if (isTransformed) {\n            var t = this.text.parentElement;\n            while (t && t.nodeType == 1) {\n                ancestors.push(t);\n                t.setAttribute(\"ace_nocontext\", \"true\");\n                if (!t.parentElement && t.getRootNode) t = t.getRootNode()[\"host\"]; else t = t.parentElement;\n            }\n        }\n        this.text.focus({preventScroll: true});\n        if (isTransformed) {\n            ancestors.forEach(function (p) {\n                p.removeAttribute(\"ace_nocontext\");\n            });\n        }\n        setTimeout(() => {\n            this.text.style.position = \"\";\n            if (this.text.style.top == \"0px\") this.text.style.top = top;\n        }, 0);\n    }\n\n    blur() {\n        this.text.blur();\n    }\n\n    isFocused() {\n        return this.$isFocused;\n    }\n\n    setInputHandler(cb) {\n        this.inputHandler = cb;\n    }\n\n    getInputHandler() {\n        return this.inputHandler;\n    }\n\n    getElement() {\n        return this.text;\n    }\n\n    /**\n     * allows to ignore composition (used by vim keyboard handler in the normal mode)\n     * this is useful on mac, where with some keyboard layouts (e.g swedish) ^ starts composition\n     * @param {boolean} value\n     */\n    setCommandMode(value) {\n        this.commandMode = value;\n        this.text.readOnly = false;\n    }\n\n    setReadOnly(readOnly) {\n        if (!this.commandMode) this.text.readOnly = readOnly;\n    }\n\n    setCopyWithEmptySelection(value) {\n    }\n\n    onContextMenu(e) {\n        this.afterContextMenu = true;\n        this.resetSelection();\n        this.host._emit(\"nativecontextmenu\", {\n            target: this.host,\n            domEvent: e\n        });\n        this.moveToMouse(e, true);\n    }\n\n    /**\n     * @param e\n     * @param {boolean} bringToFront\n     */\n    moveToMouse(e, bringToFront) {\n        if (!this.tempStyle) this.tempStyle = this.text.style.cssText;\n        this.text.style.cssText = (bringToFront ? \"z-index:100000;\" : \"\") + (useragent.isIE ? \"opacity:0.1;\" : \"\")\n            + \"text-indent: -\" + (this.lastSelectionStart + this.lastSelectionEnd) * this.host.renderer.characterWidth\n            * 0.5 + \"px;\";\n\n        var rect = this.host.container.getBoundingClientRect();\n        var style = dom.computedStyle(this.host.container);\n        var top = rect.top + (parseInt(style.borderTopWidth) || 0);\n        var left = rect.left + (parseInt(style.borderLeftWidth) || 0);\n        var maxTop = rect.bottom - top - this.text.clientHeight - 2;\n        var move = (e) => {\n            dom.translate(this.text, e.clientX - left - 2, Math.min(e.clientY - top - 2, maxTop));\n        };\n        move(e);\n\n        if (e.type != \"mousedown\") return;\n\n        this.host.renderer.$isMousePressed = true;\n\n        clearTimeout(this.closeTimeout);\n        // on windows context menu is opened after mouseup\n        if (useragent.isWin) event.capture(this.host.container, move, this.onContextMenuClose.bind(this));\n    }\n\n    destroy() {\n        if (this.text.parentElement) this.text.parentElement.removeChild(this.text);\n    }\n}\n\nexports.TextInput = TextInput;\nexports.$setUserAgentForTests = function (_isMobile, _isIOS) {\n    isMobile = _isMobile;\n    isIOS = _isIOS;\n};\n"
  },
  {
    "path": "src/keyboard/textinput_test.js",
    "content": "/*global CustomEvent*/\n \n\"use strict\";\n\nrequire(\"../test/mockdom\");\nvar assert = require(\"../test/assertions\");\nvar clipboard = require(\"../clipboard\");\nvar setUserAgentForTests = require(\"./textinput\").$setUserAgentForTests;\nvar ace = require(\"../ace\");\nvar editor, changes, textarea, copiedValue;\n\nvar MouseEvent = function(type, opts) {\n    var e = document.createEvent(\"MouseEvents\");\n    e.initMouseEvent(\"mouse\" + type,\n        true, true, window,\n        opts.detail,\n        opts.x, opts.y, opts.x, opts.y,\n        opts.ctrl, opts.alt, opts.shift, opts.meta,\n        opts.button || 0, opts.relatedTarget);\n    return e;\n};\n\nfunction sendEvent(type, data) {\n    if (!data) \n        data = {};\n    if (typeof data == \"function\")\n        return data();\n    \n    var event = new CustomEvent(type);\n    if (/cut|copy|paste/.test(type)) {\n        event.clipboardData = {\n            getData: function() { return copiedValue; },\n            setData: function(mime, text) { copiedValue = text; }\n        };\n    }\n    for (var i in data.key || {})\n        event[i] = data.key[i];\n    data.modifier && data.modifier.split(\"-\").map(function(m) {\n        if (m) event[m + \"Key\"] = true;\n    });\n    if (data.data)\n        event.data = data.data;\n    \n    if (/input|select|composition/.test(type) || data.key && /Esc/.test(data.key.key)) {\n        if (data.value != null)\n            textarea.value = data.value;\n        if (data.range)\n            textarea.setSelectionRange(data.range[0], data.range[1]);\n    }\n    textarea.dispatchEvent(event); \n    if (data.value != null)\n        assert.equal(textarea.value, data.value);\n    \n    if (data.range != null) {\n        assert.equal(textarea.selectionStart, data.range[0]);\n        assert.equal(textarea.selectionEnd, data.range[1]);\n        if (/\\n\\n$/.test(textarea.value) && (!data.key || data.key.keyCode != 27)) {\n            assert.ok(textarea.selectionEnd < textarea.value.length);\n        }\n    }\n    editor.resize(true);\n}\n\nmodule.exports = {\n    setUp: function() {\n        if (editor) this.tearDown();\n        \n        setUserAgentForTests(false, false);\n        editor = ace.edit(null);\n        document.body.appendChild(editor.container);\n        editor.container.style.height = \"200px\";\n        editor.container.style.width = \"300px\";\n        editor.container.style.position = \"absolute\";\n        editor.container.style.outline = \"solid\";\n        editor.resize(true);\n        editor.on(\"change\", function(e) {\n            changes.push(e);\n        });\n        editor.setOption(\"useTextareaForIME\", true);\n        textarea = editor.textInput.getElement();\n        changes = [];\n        editor.focus();\n    },\n    tearDown: function() {\n        if (editor) {\n            editor.destroy();\n            editor.container.remove();\n            editor = textarea = null;\n        }\n    },\n    \n    \"test: simple text input\": function() {\n        [\n            { _: \"input\", range: [1,1], value: \"a\\n\\n\"},\n            { _: \"input\", range: [2,2], value: \"aa\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"aaa\\n\\n\"},\n            { _: \"keydown\", range: [0,0], value: \"aaa\\n\\n\", key: { code: \"Home\", key: \"Home\", keyCode: 36}},\n            { _: \"input\", range: [1,1], value: \"aaaa\\n\\n\"},\n            { _: \"input\", range: [2,2], value: \"aaaaa\\n\\n\"},\n            { _: \"keydown\", range: [1,2], value: \"aaaaa\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"input\", range: [2,2], value: \"aaaaa\\n\\n\"}\n        ].forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        editor.resize(true);\n        assert.equal(changes.filter(function(d) { return d.action == \"insert\"; }).length, 6);\n        assert.equal(changes.filter(function(d) { return d.action == \"remove\"; }).length, 1);\n    },\n    \n    \"test: mobile text deletion\": function() {\n        editor.setValue(\"x      x\", -1);\n        editor.execCommand(\"gotoright\", {times: 4});\n        editor.resize(true);\n        [\n            { _: \"keydown\", range: [4,4], value: \"x      x\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"x     x\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"x     x\\n\\n\"},\n            { _: \"keydown\", range: [3,3], value: \"x     x\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"x    x\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"x    x\\n\\n\"}\n        ].forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        editor.resize(true);\n        assert.equal(editor.getValue(), \"x    x\");\n    },\n    \n    \"test: mobile text deletion at the line start\": function() {\n        setUserAgentForTests(true, false);\n        editor.destroy();\n        editor = ace.edit(editor.container);\n        textarea = editor.textInput.getElement();\n        editor.resize(true);\n        editor.focus();\n        editor.setValue(\"\\nxy\", 1);\n        editor.execCommand(\"gotoleft\");\n        editor.resize(true);\n        [\n            { _: \"keydown\", range: [2,2], value: \"\\nxy\\n\\n\"},\n            { _: \"input\", range: [1,1], value: \"\\ny\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"\\ny\\n\\n\"},\n            { _: \"keydown\", range: [1,1], value: \"\\ny\\n\\n\"},\n            { _: \"input\", range: [0,0], value: \"y\\n\\n\"},\n            { _: \"keyup\", range: [0,0], value: \"y\\n\\n\"}\n        ].forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        editor.resize(true);\n        assert.equal(editor.getValue(), \"y\");\n    },\n    \n    \"test: composition with visible textarea\": function() {\n        var data = [\n            // select ll\n            { _: \"keydown\", range: [4,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}},\n            { _: \"keydown\", range: [4,4], value: \"hello\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [3,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            // start composition\n            { _: \"keydown\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"KeyK\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionstart\", range: [0,0], value: \"\"},\n            { _: \"compositionupdate\", range: [0,0], value: \"\"},\n            { _: \"input\", range: [1,1], value: \"ｋ\"},\n            { _: \"keyup\", range: [1,1], value: \"ｋ\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"KeyI\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,1], value: \"ｋ\"},\n            { _: \"input\", range: [1,1], value: \"き\"},\n            { _: \"keyup\", range: [1,1], value: \"き\", key: { code: \"KeyI\", key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [1,1], value: \"き\", key: { code: \"KeyM\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,1], value: \"き\"},\n            { _: \"input\", range: [2,2], value: \"きｍ\"},\n            { _: \"keyup\", range: [2,2], value: \"きｍ\", key: { code: \"KeyM\", key: \"m\", keyCode: 77}},\n            { _: \"keydown\", range: [2,2], value: \"きｍ\", key: { code: \"KeyO\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,2], value: \"きｍ\"},\n            { _: \"input\", range: [2,2], value: \"きも\"},\n            { _: \"keyup\", range: [2,2], value: \"きも\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            { _: \"keydown\", range: [2,2], value: \"きも\", key: { code: \"KeyN\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,2], value: \"きも\"},\n            { _: \"input\", range: [3,3], value: \"きもｎ\"},\n            { _: \"keyup\", range: [3,3], value: \"きもｎ\", key: { code: \"KeyN\", key: \"n\", keyCode: 78}},\n            { _: \"keydown\", range: [3,3], value: \"きもｎ\", key: { code: \"KeyO\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,3], value: \"きもｎ\"},\n            { _: \"input\", range: [3,3], value: \"きもの\"},\n            { _: \"keyup\", range: [3,3], value: \"きもの\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            { _: \"keydown\", range: [3,3], value: \"きもの\", key: { code: \"Enter\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,3], value: \"きもの\"},\n            { _: \"input\", range: [3,3], value: \"きもの\"},\n            function() {\n                assert.ok(editor.renderer.$composition);\n                assert.ok(Math.abs(parseFloat(textarea.style.width) - editor.renderer.characterWidth * 6) < 1);\n                assert.ok(Math.abs(parseFloat(textarea.style.height) - (editor.renderer.lineHeight)) < 1);\n                assert.ok(Math.abs(parseFloat(textarea.style.top)) < 1);\n                assert.ok(/ace_composition/.test(textarea.className));\n            },\n            { _: \"compositionend\", range: [3,3], value: \"きもの\"},\n            { _: \"keydown\", range: [3,3], value: \"きもの\", key: { code: \"KeyK\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionstart\", range: [0,0], value: \"\"},\n            { _: \"compositionupdate\", range: [0,0], value: \"\"},\n            { _: \"input\", range: [1,1], value: \"ｋ\"},\n            { _: \"keyup\", range: [1,1], value: \"ｋ\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"Enter\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [0,1], value: \"ｋ\"},\n            { _: \"input\", range: [1,1], value: \"ｋ\"},\n            { _: \"compositionend\", range: [1,1], value: \"ｋ\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"Enter\", key: \"Enter\", keyCode: 13}},\n            { _: \"keypress\", range: [1,1], value: \"ｋ\", key: { code: \"Enter\", key: \"Enter\", keyCode: 13}},\n            { _: \"input\", range: [0,0], value: \"o\\n\\n\"},\n            { _: \"select\", range: [0,0], value: \"o\\n\\n\"},\n            { _: \"keyup\", range: [0,0], value: \"o\\n\\n\", key: { code: \"Enter\", key: \"Enter\", keyCode: 13}},\n            { _: \"keydown\", range: [0,0], value: \"o\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"input\", range: [1,1], value: \"　o\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"　o\\n\\n\", key: { code: \"Space\", key: \" \", keyCode: 32}},\n            { _: \"keydown\", range: [1,1], value: \"　o\\n\\n\", key: { code: \"KeyK\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionstart\", range: [0,0], value: \"\"},\n            { _: \"compositionupdate\", range: [0,0], value: \"\"},\n            { _: \"input\", range: [1,1], value: \"ｋ\"},\n            { _: \"keyup\", range: [1,1], value: \"ｋ\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [1,1], value: \"ｋ\", key: { code: \"KeyZ\", key: \"Process\", keyCode: 229}, modifier: \"ctrl-\"},\n            { _: \"compositionupdate\", range: [0,1], value: \"ｋ\"},\n            { _: \"input\", range: [0,0], value: \"\"},\n            { _: \"compositionend\", range: [0,0], value: \"\"},\n            { _: \"keyup\", range: [0,0], value: \"\", key: { code: \"KeyZ\", key: \"z\", keyCode: 90}, modifier: \"ctrl-\"},\n            { _: \"keyup\", range: [0,0], value: \"\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}}\n        ];\n        \n        editor.setValue(\"hello\", 1);\n        editor.setOption(\"useTextareaForIME\", true);\n        data.forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        assert.ok(!editor.renderer.$composition);\n        assert.notOk(/ace_composition/.test(textarea.className));\n    },\n    \n    \"test: composition with hidden textarea\": function() {\n        var data = [\n            { _: \"keydown\", range: [4,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}},\n            { _: \"select\", range: [4,4], value: \"hello\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}},\n            { _: \"keydown\", range: [4,4], value: \"hello\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [3,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"select\", range: [3,4], value: \"hello\\n\\n\"},\n            { _: \"keyup\", range: [3,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"select\", range: [2,4], value: \"hello\\n\\n\"},\n            { _: \"keyup\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"ArrowLeft\", key: \"ArrowLeft\", keyCode: 37}, modifier: \"shift-\"},\n            { _: \"keyup\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}},\n            { _: \"keydown\", range: [2,4], value: \"hello\\n\\n\", key: { code: \"KeyK\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionstart\", range: [2,4], value: \"hello\\n\\n\"},\n            { _: \"compositionupdate\", range: [2,4], value: \"hello\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"heｋo\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"heｋo\\n\\n\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [3,3], value: \"heｋo\\n\\n\", key: { code: \"KeyI\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,3], value: \"heｋo\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"heきo\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"heきo\\n\\n\", key: { code: \"KeyI\", key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [3,3], value: \"heきo\\n\\n\", key: { code: \"KeyM\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,3], value: \"heきo\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"heきｍo\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"heきｍo\\n\\n\", key: { code: \"KeyM\", key: \"m\", keyCode: 77}},\n            { _: \"keydown\", range: [4,4], value: \"heきｍo\\n\\n\", key: { code: \"KeyO\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,4], value: \"heきｍo\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"heきもo\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"heきもo\\n\\n\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            { _: \"keydown\", range: [4,4], value: \"heきもo\\n\\n\", key: { code: \"KeyN\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,4], value: \"heきもo\\n\\n\"},\n            { _: \"input\", range: [5,5], value: \"heきもｎo\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"heきもｎo\\n\\n\", key: { code: \"KeyN\", key: \"n\", keyCode: 78}},\n            { _: \"keydown\", range: [5,5], value: \"heきもｎo\\n\\n\", key: { code: \"KeyO\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,5], value: \"heきもｎo\\n\\n\"},\n            { _: \"input\", range: [5,5], value: \"heきものo\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"heきものo\\n\\n\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            { _: \"keydown\", range: [5,5], value: \"heきものo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,5], value: \"heきものo\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"he着物o\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"he着物o\\n\\n\", key: { code: \"Space\", key: \" \", keyCode: 32}},\n            { _: \"keydown\", range: [4,4], value: \"he着物o\\n\\n\", key: { code: \"Enter\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,4], value: \"he着物o\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"he着物o\\n\\n\"},\n            function() {\n                assert.ok(editor.renderer.$composition);\n                assert.ok(textarea.style.fontSize, \"1px\");\n                assert.notOk(/ace_composition/.test(textarea.className));\n                assert.ok(/composition_marker/.test(editor.renderer.$markerBack.element.innerHTML));\n                assert.notOk(/ace_composition/.test(textarea.className));\n                assert.equal(textarea.style.height, \"1px\");\n                assert.equal(textarea.style.top, editor.renderer.lineHeight + 2 + \"px\");\n            },\n            { _: \"compositionend\", range: [4,4], value: \"he着物o\\n\\n\"},\n            { _: \"keydown\", range: [4,4], value: \"he着物o\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"input\", range: [5,5], value: \"he着物　o\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"he着物　o\\n\\n\", key: { code: \"Space\", key: \" \", keyCode: 32}},\n            { _: \"keydown\", range: [5,5], value: \"he着物　o\\n\\n\", key: { code: \"KeyK\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionstart\", range: [5,5], value: \"he着物　o\\n\\n\"},\n            { _: \"compositionupdate\", range: [5,5], value: \"he着物　o\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"he着物　ｋo\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"he着物　ｋo\\n\\n\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [6,6], value: \"he着物　ｋo\\n\\n\", key: { code: \"KeyA\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,6], value: \"he着物　ｋo\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"he着物　かo\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"he着物　かo\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [6,6], value: \"he着物　かo\\n\\n\", key: { code: \"KeyT\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,6], value: \"he着物　かo\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"he着物　かｔo\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"he着物　かｔo\\n\\n\", key: { code: \"KeyT\", key: \"t\", keyCode: 84}},\n            { _: \"keydown\", range: [7,7], value: \"he着物　かｔo\\n\\n\", key: { code: \"KeyA\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,7], value: \"he着物　かｔo\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"he着物　かたo\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"he着物　かたo\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [7,7], value: \"he着物　かたo\\n\\n\", key: { code: \"KeyN\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,7], value: \"he着物　かたo\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　かたｎo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　かたｎo\\n\\n\", key: { code: \"KeyN\", key: \"n\", keyCode: 78}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　かたｎo\\n\\n\", key: { code: \"KeyA\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　かたｎo\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　かたなo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　かたなo\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　かたなo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　かたなo\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"he着物　刀o\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"he着物　刀o\\n\\n\", key: { code: \"Space\", key: \" \", keyCode: 32}},\n            { _: \"keydown\", range: [6,6], value: \"he着物　刀o\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,6], value: \"he着物　刀o\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　過多なo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　過多なo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　過多なo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　過多なo\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　夥多なo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　夥多なo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　夥多なo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　夥多なo\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　かたなo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　かたなo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　かたなo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　かたなo\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"he着物　カタナo\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"he着物　カタナo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"keydown\", range: [8,8], value: \"he着物　カタナo\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,8], value: \"he着物　カタナo\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"he着物　刀o\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"he着物　刀o\\n\\n\", key: { code: \"Space\", key: \"Process\", keyCode: 229}},\n            { _: \"keydown\", range: [6,6], value: \"he着物　刀o\\n\\n\", key: { code: \"Enter\", key: \"Process\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,6], value: \"he着物　刀o\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"he着物　刀o\\n\\n\"},\n            { _: \"compositionend\", range: [6,6], value: \"he着物　刀o\\n\\n\"}\n        ];\n        editor.setValue(\"hello\", 1);\n        editor.setOption(\"useTextareaForIME\", false);\n        data.forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        assert.ok(!editor.renderer.$composition);\n        assert.notOk(/ace_composition/.test(textarea.className));\n    },\n    \n    \"test: korean composition\": function() {\n        var data = [\n            { _: \"input\", range: [1,1], value: \"ㅁ\\n\\n\", key: { key: \"a\", keyCode: 229}},\n            { _: \"compositionstart\", range: [1,1], value: \"ㅁ\\n\\n\"},\n            { _: \"select\", range: [0,1], value: \"ㅁ\\n\\n\"},\n            { _: \"compositionupdate\", range: [0,1], value: \"ㅁ\\n\\n\"},\n            { _: \"input\", range: [0,1], value: \"ㅁ\\n\\n\"},\n            { _: \"keyup\", range: [0,1], value: \"ㅁ\\n\\n\", key: { key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [0,1], value: \"ㅁ\\n\\n\", key: { key: \"p\", keyCode: 229}},\n            { _: \"select\", range: [0,1], value: \"메\\n\\n\"},\n            { _: \"compositionupdate\", range: [0,1], value: \"메\\n\\n\"},\n            function() {\n                assert.equal(editor.getValue(), \"메\");\n            },\n            { _: \"input\", range: [0,1], value: \"메\\n\\n\"},\n            { _: \"keyup\", range: [0,1], value: \"메\\n\\n\", key: { key: \"p\", keyCode: 80}},\n            { _: \"keydown\", range: [0,1], value: \"메\\n\\n\", key: { key: \"t\", keyCode: 229}},\n            { _: \"select\", range: [0,1], value: \"멧\\n\\n\"},\n            { _: \"compositionupdate\", range: [0,1], value: \"멧\\n\\n\"},\n            function() {\n                assert.equal(editor.getValue(), \"멧\");\n            },\n            { _: \"input\", range: [0,1], value: \"멧\\n\\n\"},\n            { _: \"keyup\", range: [0,1], value: \"멧\\n\\n\", key: { key: \"t\", keyCode: 84}},\n            { _: \"keydown\", range: [0,1], value: \"멧\\n\\n\", key: { key: \"a\", keyCode: 229}},\n            { _: \"compositionend\", range: [2,2], value: \"멧ㅁ\\n\\n\"},\n            { _: \"compositionstart\", range: [2,2], value: \"멧ㅁ\\n\\n\"},\n            { _: \"select\", range: [1,2], value: \"멧ㅁ\\n\\n\"},\n            { _: \"compositionupdate\", range: [1,2], value: \"멧ㅁ\\n\\n\"},\n            { _: \"input\", range: [1,2], value: \"멧ㅁ\\n\\n\"},\n            { _: \"keyup\", range: [1,2], value: \"멧ㅁ\\n\\n\", key: { key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [1,2], value: \"멧ㅁ\\n\\n\", key: { key: \"t\", keyCode: 229}},\n            { _: \"compositionend\", range: [3,3], value: \"멧ㅁㅅ\\n\\n\"},\n            { _: \"compositionstart\", range: [3,3], value: \"멧ㅁㅅ\\n\\n\"},\n            { _: \"select\", range: [2,3], value: \"멧ㅁㅅ\\n\\n\"},\n            { _: \"compositionupdate\", range: [2,3], value: \"멧ㅁㅅ\\n\\n\"},\n            { _: \"input\", range: [2,3], value: \"멧ㅁㅅ\\n\\n\"},\n            { _: \"keyup\", range: [2,3], value: \"멧ㅁㅅ\\n\\n\", key: { key: \"t\", keyCode: 84}},\n            { _: \"keydown\", range: [2,3], value: \"멧ㅁㅅ\\n\\n\", key: { key: \"p\", keyCode: 229}},\n            { _: \"select\", range: [2,3], value: \"멧ㅁ세\\n\\n\"},\n            { _: \"compositionupdate\", range: [2,3], value: \"멧ㅁ세\\n\\n\"},\n            { _: \"input\", range: [2,3], value: \"멧ㅁ세\\n\\n\"},\n            { _: \"keyup\", range: [2,3], value: \"멧ㅁ세\\n\\n\", key: { key: \"p\", keyCode: 80}},\n            { _: \"keydown\", range: [2,3], value: \"멧ㅁ세\\n\\n\", key: { key: \"a\", keyCode: 229}},\n            { _: \"select\", range: [2,3], value: \"멧ㅁ셈\\n\\n\"},\n            { _: \"compositionupdate\", range: [2,3], value: \"멧ㅁ셈\\n\\n\"},\n            function() {\n                assert.equal(editor.getValue(), \"멧ㅁ셈\");\n            },\n            { _: \"input\", range: [2,3], value: \"멧ㅁ셈\\n\\n\"},\n            { _: \"keyup\", range: [2,3], value: \"멧ㅁ셈\\n\\n\", key: { key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [2,3], value: \"멧ㅁ셈\\n\\n\", key: { key: \"a\", keyCode: 229}},\n            { _: \"compositionend\", range: [4,4], value: \"멧ㅁ셈ㅁ\\n\\n\"}\n        ];\n        editor.setValue(\"\", 1);\n        editor.setOption(\"useTextareaForIME\", false);\n        data.forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        assert.ok(!editor.renderer.$composition);\n        assert.notOk(/ace_composition/.test(textarea.className));\n        assert.equal(editor.getValue(), \"멧ㅁ셈ㅁ\");\n    },\n    \n    \"test: selection synchronization\": function() {\n        editor.session.setValue(\"juhu\\nkinners\\n\");\n        [\n            { _: \"keydown\", range: [1,1], value: \"juhu\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}},\n            { _: \"keydown\", range: [2,2], value: \"juhu\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}},\n            { _: \"keydown\", range: [2,2], value: \"juhu\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,3], value: \"juhu\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,4], value: \"juhu\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,5], value: \"juhu\\nkinners\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,6], value: \"juhu\\nkinners\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,7], value: \"juhu\\nkinners\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,8], value: \"juhu\\nkinners\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [0,8], value: \"kinners\\n\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [0,0], value: \"\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}},\n            { _: \"keydown\", range: [0,0], value: \"\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [3,8], value: \"kinners\\n\\n\\n\", key: { code: \"ArrowUp\", key: \"ArrowUp\", keyCode: 38}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [3,12], value: \"juhu\\nkinners\\n\\n\", key: { code: \"ArrowUp\", key: \"ArrowUp\", keyCode: 38}, modifier: \"shift-\"}\n        ].forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        // test overflow\n        editor.session.setValue(\"0123456789\".repeat(80));\n        editor.execCommand(\"gotoright\");\n        editor.execCommand(\"selectright\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"402,1,2\");\n        editor.execCommand(\"gotolineend\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"3,0,0\");\n        editor.execCommand(\"selectleft\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"3,0,1\");\n    },\n    \n    \"test: selection synchronization with extra lines enabled\": function() {\n        editor.textInput.setNumberOfExtraLines(1);\n        editor.session.setValue(\"line1\\nline2\\nline3\\nline4\\nline5\\nline6\\n\");\n        [\n            { _: \"keydown\", range: [1,1], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}},\n            { _: \"keydown\", range: [2,2], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}},\n            { _: \"keydown\", range: [2,2], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,3], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,4], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,5], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,6], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,7], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,8], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,14], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [2,2], value: \"line4\\nline5\\nline6\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}},\n            { _: \"keydown\", range: [2,2], value: \"line4\\nline5\\nline6\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [14,20], value: \"line1\\nline2\\nline3\\nline4\\n\\n\", key: { code: \"ArrowUp\", key: \"ArrowUp\", keyCode: 38}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [8,8], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowUp\", key: \"ArrowUp\", keyCode: 38}},\n            { _: \"keydown\", range: [14,14], value: \"line1\\nline2\\nline3\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}},\n            { _: \"keydown\", range: [2,8], value: \"line3\\nline4\\nline5\\nline6\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}, modifier: \"shift-\"}\n        ].forEach(function(data) {\n            sendEvent(data._, data);\n        });\n        // test overflow\n        editor.session.setValue(\"0123456789\".repeat(80));\n        editor.execCommand(\"gotoright\");\n        editor.execCommand(\"selectright\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"402,1,2\");\n        editor.execCommand(\"gotolineend\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"3,0,0\");\n        editor.execCommand(\"selectleft\");\n        assert.equal([textarea.value.length, textarea.selectionStart, textarea.selectionEnd].join(\",\"), \"3,0,1\");\n    },\n    \n    \"test: chinese ime on ie\": function() {\n        editor.setOption(\"useTextareaForIME\", false);\n        [\n            { _: \"keydown\", range: [0,0], value: \"\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keyup\", range: [0,0], value: \"\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [0,0], value: \"\\n\\n\", key: { key: \"k\", keyCode: 229}},\n            { _: \"compositionstart\", range: [0,0], value: \"\\n\\n\"},\n            { _: \"compositionupdate\", range: [1,1], value: \"k\\n\\n\"},\n            { _: \"input\", range: [1,1], value: \"k\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"k\\n\\n\", key: { key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [1,1], value: \"k\\n\\n\", key: { key: \"i\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [2,2], value: \"ki\\n\\n\"},\n            { _: \"input\", range: [2,2], value: \"ki\\n\\n\"},\n            { _: \"keyup\", range: [2,2], value: \"ki\\n\\n\", key: { key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [2,2], value: \"ki\\n\\n\", key: { key: \"i\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [3,3], value: \"kii\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"kii\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"kii\\n\\n\", key: { key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [3,3], value: \"kii\\n\\n\", key: { key: \"i\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [4,4], value: \"kiii\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"kiii\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"kiii\\n\\n\", key: { key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [4,4], value: \"kiii\\n\\n\", key: { key: \"2\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [4,4], value: \"开iii\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"开iii\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"开iii\\n\\n\", key: { key: \"2\", keyCode: 98}},\n            { _: \"keydown\", range: [4,4], value: \"开iii\\n\\n\", key: { key: \"Backspace\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [3,3], value: \"开ii\\n\\n\"},\n            { _: \"input\", range: [3,3], value: \"开ii\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"开ii\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [3,3], value: \"开ii\\n\\n\", key: { key: \"r\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [4,4], value: \"开iir\\n\\n\"},\n            { _: \"input\", range: [4,4], value: \"开iir\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"开iir\\n\\n\", key: { key: \"r\", keyCode: 82}},\n            { _: \"keydown\", range: [4,4], value: \"开iir\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"input\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Spacebar\", keyCode: 229}},\n            { _: \"compositionend\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Spacebar\", keyCode: 32}},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Spacebar\", keyCode: 32}},\n            { _: \"keydown\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"i\", keyCode: 229}},\n            { _: \"compositionstart\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"compositionupdate\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"i\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [7,7], value: \"开iirdii\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"开iirdii\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"开iirdii\\n\\n\", key: { key: \"i\", keyCode: 73}},\n            { _: \"keydown\", range: [7,7], value: \"开iirdii\\n\\n\", key: { key: \"Backspace\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"r\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [7,7], value: \"开iirdir\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"开iirdir\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"开iirdir\\n\\n\", key: { key: \"r\", keyCode: 82}},\n            { _: \"keydown\", range: [7,7], value: \"开iirdir\\n\\n\", key: { key: \"e\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [8,8], value: \"开iirdire\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"开iirdire\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"开iirdire\\n\\n\", key: { key: \"e\", keyCode: 69}},\n            { _: \"keydown\", range: [8,8], value: \"开iirdire\\n\\n\", key: { key: \"Backspace\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [7,7], value: \"开iirdir\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"开iirdir\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"开iirdir\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [7,7], value: \"开iirdir\\n\\n\", key: { key: \"Backspace\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"开iirdi\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [6,6], value: \"开iirdi\\n\\n\", key: { key: \"Backspace\", keyCode: 229}},\n            { _: \"compositionend\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"input\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionstart\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"compositionupdate\", range: [6,6], value: \"开iirdd\\n\\n\"},\n            { _: \"input\", range: [6,6], value: \"开iirdd\\n\\n\"},\n            { _: \"keyup\", range: [6,6], value: \"开iirdd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [6,6], value: \"开iirdd\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [7,7], value: \"开iirddd\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"开iirddd\\n\\n\"},\n            { _: \"keyup\", range: [7,7], value: \"开iirddd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [7,7], value: \"开iirddd\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [8,8], value: \"开iirdddd\\n\\n\"},\n            { _: \"input\", range: [8,8], value: \"开iirdddd\\n\\n\"},\n            { _: \"keyup\", range: [8,8], value: \"开iirdddd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [8,8], value: \"开iirdddd\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [9,9], value: \"开iirddddd\\n\\n\"},\n            { _: \"input\", range: [9,9], value: \"开iirddddd\\n\\n\"},\n            { _: \"keyup\", range: [9,9], value: \"开iirddddd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [9,9], value: \"开iirddddd\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [10,10], value: \"开iirdddddd\\n\\n\"},\n            { _: \"input\", range: [10,10], value: \"开iirdddddd\\n\\n\"},\n            { _: \"keyup\", range: [10,10], value: \"开iirdddddd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [10,10], value: \"开iirdddddd\\n\\n\", key: { key: \"d\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [11,11], value: \"开iird大大dddd\\n\\n\"},\n            { _: \"input\", range: [11,11], value: \"开iird大大dddd\\n\\n\"},\n            { _: \"keyup\", range: [11,11], value: \"开iird大大dddd\\n\\n\", key: { key: \"d\", keyCode: 68}},\n            { _: \"keydown\", range: [11,11], value: \"开iird大大dddd\\n\\n\", key: { key: \"1\", keyCode: 229}},\n            { _: \"compositionupdate\", range: [11,11], value: \"开iird大大得到当地\\n\\n\"},\n            { _: \"input\", range: [11,11], value: \"开iird大大得到当地\\n\\n\"},\n            { _: \"keyup\", range: [11,11], value: \"开iird大大得到当地\\n\\n\", key: { key: \"1\", keyCode: 97}},\n            { _: \"keydown\", range: [11,11], value: \"开iird大大得到当地\\n\\n\", key: { key: \"Esc\", keyCode: 229}},\n            function() {\n                assert.equal(editor.getValue(), \"开iird大大得到当地\");\n            },\n            { _: \"compositionend\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"input\", range: [5,5], value: \"开iird\\n\\n\"},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Esc\", keyCode: 27}},\n            { _: \"keyup\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Esc\", keyCode: 27}},\n            { _: \"keydown\", range: [5,5], value: \"开iird\\n\\n\", key: { key: \"Esc\", keyCode: 27}},\n            { _: \"keypress\", range: [2,2], value: \"\\n\\n\", key: { key: \"Esc\", keyCode: 27}}/*,\n            { _: \"keyup\", range: [4,4], value: \"\\n\\n\", key: { key: \"Esc\", keyCode: 27}},\n            { _: \"keydown\", range: [4,4], value: \"\\n\\n\", key: { key: \"4\", keyCode: 229}},\n            { _: \"compositionstart\", range: [4,4], value: \"\\n\\n\"},\n            { _: \"compositionend\", range: [1,1], value: \"4\\n\\n\"},\n            { _: \"input\", range: [1,1], value: \"4\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"4\\n\\n\", key: { key: \"4\", keyCode: 100}},\n            { _: \"keyup\", range: [1,1], value: \"4\\n\\n\", key: { key: \"4\", keyCode: 100}},*/\n\n        ].forEach(function(data, i) {\n            sendEvent(data._, data);\n        });\n        assert.equal(editor.getValue(), \"开iird\");\n    },\n    \n    \"test: backspace during composition\": function() {\n        editor.setValue(\"lxx\\n\", 1);\n        editor.execCommand(\"golineup\");\n        editor.selection.moveTo(0, 1);\n        editor.setOption(\"useTextareaForIME\", true);\n\n        [\n            { _: \"keydown\", range: [0,0], value: \"xx\\n\\n\", key: { code: \"Backspace\", key: \"Backspace\", keyCode: 8}},\n            function() {\n                assert.equal(editor.getValue(), \"xx\\n\");\n            },\n            { _: \"keydown\", range: [0,0], value: \"xx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keypress\", range: [0,0], value: \"xx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 97}},\n            { _: \"input\", data: \"a\", inputType: \"insertText\", range: [1,1], value: \"axx\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"axx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [1,1], value: \"axx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keypress\", range: [1,1], value: \"axx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 97}},\n            { _: \"input\", data: \"a\", inputType: \"insertText\", range: [2,2], value: \"aaxx\\n\\n\"},\n            { _: \"keyup\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}, modifier: \"alt-\"},\n            { _: \"keydown\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"KeyI\", key: \"Dead\", keyCode: 73}, modifier: \"alt-\"},\n            { _: \"compositionstart\", data: \"\", range: [0,0], value: \"\"},\n            function() {\n                editor.textInput.getElement().value = \"ˆ\";\n            },\n            { _: \"compositionupdate\", data: \"ˆ\", range: [0,0], value: \"\"},\n            { _: \"input\", data: \"ˆ\", inputType: \"insertCompositionText\", range: [1,1], value: \"ˆ\"},\n            { _: \"keyup\", range: [1,1], value: \"ˆ\", key: { code: \"KeyI\", key: \"ˆ\", keyCode: 73}, modifier: \"alt-\"},\n            { _: \"keyup\", range: [1,1], value: \"ˆ\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}},\n            { _: \"keydown\", range: [1,1], value: \"ˆ\", key: { code: \"Backspace\", key: \"Backspace\", keyCode: 8}},\n            { _: \"compositionend\", data: \"ˆ\", range: [1,1], value: \"ˆ\"},\n            { _: \"input\", data: \"ˆ\", inputType: \"insertCompositionText\", range: [1,1], value: \"ˆ\"},\n            { _: \"keydown\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"Backspace\", key: \"Backspace\", keyCode: 8}},\n            { _: \"keyup\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"Backspace\", key: \"Backspace\", keyCode: 8}},\n            { _: \"keydown\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}, modifier: \"alt-\"},\n            { _: \"keydown\", range: [2,2], value: \"aaxx\\n\\n\", key: { code: \"KeyI\", key: \"Dead\", keyCode: 73}, modifier: \"alt-\"},\n            { _: \"compositionstart\", data: \"\", range: [0,0], value: \"\"},\n            { _: \"compositionupdate\", data: \"ˆ\", range: [0,0], value: \"\"},\n            function() {\n                editor.textInput.getElement().value = \"ˆ\";\n            },\n            { _: \"input\", data: \"ˆ\", inputType: \"insertCompositionText\", range: [1,1], value: \"ˆ\"},\n            { _: \"keyup\", range: [1,1], value: \"ˆ\", key: { code: \"KeyI\", key: \"ˆ\", keyCode: 73}, modifier: \"alt-\"},\n            { _: \"keyup\", range: [1,1], value: \"ˆ\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}},\n            { _: \"keydown\", range: [1,1], value: \"ˆ\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keyup\", range: [1,1], value: \"ˆ\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}},\n            { _: \"keydown\", range: [1,1], value: \"ˆ\", key: { code: \"Delete\", key: \"Delete\", keyCode: 46}},\n            { _: \"compositionend\", data: \"ˆ\", range: [1,1], value: \"ˆ\"},\n            { _: \"input\", data: \"ˆ\", inputType: \"insertCompositionText\", range: [1,1], value: \"ˆ\"},\n            { _: \"keydown\", range: [3,3], value: \"aaˆx\\n\\n\", key: { code: \"Delete\", key: \"Delete\", keyCode: 46}},\n            { _: \"select\", range: [3,3], value: \"aaˆx\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"aaˆx\\n\\n\", key: { code: \"Delete\", key: \"Delete\", keyCode: 46}}\n        ].forEach(function(data, i) {\n            sendEvent(data._, data);\n        });\n        assert.equal(editor.getValue(), \"aaˆx\\n\");\n    },\n\n    \"test: mac pressAndHold on firefox\": function() {\n        editor.setOption(\"useTextareaForIME\", true);\n        [\n            { _: \"keydown\", range: [0,0], value: \"\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keypress\", range: [0,0], value: \"\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 97}},\n            { _: \"input\", inputType: \"insertText\", range: [1,1], value: \"a\\n\\n\"},\n            { _: \"keydown\", range: [1,1], value: \"a\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keyup\", range: [1,1], value: \"a\\n\\n\", key: { code: \"KeyA\", key: \"a\", keyCode: 65}},\n            { _: \"keydown\", range: [1,1], value: \"a\\n\\n\", key: { code: \"Digit1\", key: \"1\", keyCode: 49}},\n            { _: \"keyup\", range: [1,1], value: \"a\\n\\n\", key: { code: \"Digit1\", key: \"1\", keyCode: 49}},\n            { _: \"compositionstart\", data: \"a\", range: [0,1], value: \"a\\n\\n\"},\n            { _: \"compositionupdate\", range: [0,1], value: \"a\\n\\n\"},\n            { _: \"compositionend\", range: [1,1], value: \"à\\n\\n\"},\n            { _: \"input\", inputType: \"insertCompositionText\", range: [1,1], value: \"à\\n\\n\"}\n        ].forEach(function(data, i) {\n            sendEvent(data._, data);\n        });\n        assert.equal(editor.getValue(), \"à\");\n    },\n    \n    \"test: contextmenu\": function() {\n        var value = \"juhu\\nkinners\\n\";\n        editor.setValue(value);\n        editor.execCommand(\"gotoright\");\n        editor.resize(true);\n        var target = editor.renderer.getMouseEventTarget();\n        \n        // select all\n        textarea.setSelectionRange(0, 1000);\n        textarea.dispatchEvent(new CustomEvent(\"select\"));\n        assert.ok(editor.getSelectedText(), value);\n        \n        // delete\n        target.dispatchEvent(MouseEvent(\"down\", {x: 0, y: 0, button: 2}));\n        target.dispatchEvent(new CustomEvent(\"contextmenu\"));\n        textarea.value = textarea.value.slice(textarea.selectionEnd);\n        textarea.setSelectionRange(0, 0);\n        textarea.dispatchEvent(new CustomEvent(\"input\"));        \n        assert.equal(editor.getValue(), \"\");\n    },\n    \n    \"test clipboard\": function() {\n        copiedValue = \"x\";\n        sendEvent(\"paste\");\n        assert.equal(editor.getValue(), \"x\");\n        copiedValue = \"--\";\n        sendEvent(\"copy\");\n        assert.equal(copiedValue, \"--\");\n        editor.setOption(\"copyWithEmptySelection\", true);\n        sendEvent(\"copy\");\n        assert.equal(copiedValue, \"x\\n\");\n        editor.setValue(\"1\\n2\", -1);\n        sendEvent(\"paste\");\n        assert.equal(editor.getValue(), \"x\\n1\\n2\");\n        textarea.select();\n        sendEvent(\"select\");\n        sendEvent(\"cut\");\n        assert.equal(copiedValue, \"x\\n1\\n2\");\n        editor.setValue(\"0\", 1);\n        sendEvent(\"paste\");\n        assert.equal(editor.getValue(), \"0x\\n1\\n2\");\n        editor.setValue(\"\");\n        clipboard.cancel();\n        sendEvent(\"paste\");\n        assert.equal(editor.getValue(), \"\");\n    },\n    \n    \"test inputType undo\": function() {\n        editor.execCommand(\"insertstring\", \"x\");\n        assert.equal(editor.getValue(), \"x\");\n        sendEvent(\"input\", {key: {inputType: \"historyUndo\"}});\n        assert.equal(editor.getValue(), \"\");\n        sendEvent(\"input\", {key: {inputType: \"historyRedo\"}});\n        assert.equal(editor.getValue(), \"x\");\n    },\n\n    \"test: text input aria label without extra label set\": function() {\n        editor.setValue(\"x      x\", -1);\n        editor.setOption('enableKeyboardAccessibility', true);\n        editor.renderer.$loop._flush();\n\n        let text = editor.container.querySelector(\".ace_text-input\"); \n        assert.equal(text.getAttribute(\"aria-label\"), \"Cursor at row 1\");\n    },\n\n    \"test: text input aria label updated on focus\": function() {\n        editor.setValue(\"x      x\\ny      y\", -1);\n        editor.setOption('enableKeyboardAccessibility', true);\n        editor.renderer.$loop._flush();\n\n        let text = editor.container.querySelector(\".ace_text-input\"); \n        assert.equal(text.getAttribute(\"aria-label\"), \"Cursor at row 1\");\n\n        editor.focus();\n        sendEvent(\"keydown\", {key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}});\n        editor.renderer.$loop._flush();\n\n        editor.blur();\n        editor.focus();\n        assert.equal(text.getAttribute(\"aria-label\"), \"Cursor at row 2\");\n    },\n\n    \"test: text input aria label with extra label set\": function() {\n        editor.setValue(\"x      x\", -1);\n        editor.setOption('textInputAriaLabel', \"super cool editor\");\n        editor.setOption('enableKeyboardAccessibility', true);\n        editor.renderer.$loop._flush();\n\n        let text = editor.container.querySelector(\".ace_text-input\"); \n        assert.equal(text.getAttribute(\"aria-label\"), \"super cool editor, Cursor at row 1\");\n    },\n\n    \"test: text input aria label updated on cursor move\": function() {\n        editor.setValue(\"line1\\nline2\\nline3\", -1);\n        editor.setOption('enableKeyboardAccessibility', true);\n        editor.renderer.$loop._flush();\n\n        let text = editor.container.querySelector(\".ace_text-input\");\n        assert.equal(text.getAttribute(\"aria-label\"), \"Cursor at row 1\");\n\n        editor.focus();\n        sendEvent(\"keydown\", {key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}});\n        sendEvent(\"keydown\", {key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}});\n        sendEvent(\"keydown\", {key: { code: \"ArrowRight\", key: \"ArrowRight\", keyCode: 39}});\n        editor.renderer.$loop._flush();\n\n        assert.equal(text.getAttribute(\"aria-label\"), \"Cursor at row 3\");\n    },\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/vim.js",
    "content": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/5/LICENSE\n\n/**\n * Supported keybindings:\n *   Too many to list. Refer to defaultKeymap below.\n *\n * Supported Ex commands:\n *   Refer to defaultExCommandMap below.\n *\n * Registers: unnamed, -, ., :, /, _, a-z, A-Z, 0-9\n *   (Does not respect the special case for number registers when delete\n *    operator is made with these commands: %, (, ),  , /, ?, n, N, {, } )\n *   TODO: Implement the remaining registers.\n *\n * Marks: a-z, A-Z, and 0-9\n *   TODO: Implement the remaining special marks. They have more complex\n *       behavior.\n *\n * Events:\n *  'vim-mode-change' - raised on the editor anytime the current mode changes,\n *                      Event object: {mode: \"visual\", subMode: \"linewise\"}\n *\n * Code structure:\n *  1. Default keymap\n *  2. Variable declarations and short basic helpers\n *  3. Instance (External API) implementation\n *  4. Internal state tracking objects (input state, counter) implementation\n *     and instantiation\n *  5. Key handler (the main command dispatcher) implementation\n *  6. Motion, operator, and action implementations\n *  7. Helper functions for the key handler, motions, operators, and actions\n *  8. Set up Vim to work as a keymap for CodeMirror.\n *  9. Ex command implementations.\n */\n\n  'use strict';\n\n  function log() {\n    var d = \"\";\n    function format(p) {\n      if (typeof p != \"object\")\n        return p + \"\";\n      if (\"line\" in p) {\n        return p.line + \":\" + p.ch;\n      }\n      if (\"anchor\" in p) {\n        return format(p.anchor) + \"->\" + format(p.head);\n      }\n      if (Array.isArray(p))\n        return \"[\" + p.map(function(x) {\n          return format(x);\n        }) + \"]\";\n      return JSON.stringify(p);\n    }\n    for (var i = 0; i < arguments.length; i++) {\n      var p = arguments[i];\n      var f = format(p);\n      d += f + \"  \";\n    }\n    console.log(d);\n  }\n  var Range = require(\"../range\").Range;\n  var EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n  var domLib = require(\"../lib/dom\");\n  var oop = require(\"../lib/oop\");\n  var KEYS = require(\"../lib/keys\");\n  var event = require(\"../lib/event\");\n  var Search = require(\"../search\").Search;\n  var useragent = require(\"../lib/useragent\");\n  var SearchHighlight = require(\"../search_highlight\").SearchHighlight;\n  var multiSelectCommands = require(\"../commands/multi_select_commands\");\n  var TextModeTokenRe = require(\"../mode/text\").Mode.prototype.tokenRe;\n  var hardWrap = require(\"../ext/hardwrap\").hardWrap;\n  require(\"../multi_select\");\n\n  var CodeMirror = function(ace) {\n    this.ace = ace;\n    this.state = {};\n    this.marks = {};\n    this.options = {};\n    this.$uid = 0;\n    this.onChange = this.onChange.bind(this);\n    this.onSelectionChange = this.onSelectionChange.bind(this);\n    this.onBeforeEndOperation = this.onBeforeEndOperation.bind(this);\n    this.ace.on('change', this.onChange);\n    this.ace.on('changeSelection', this.onSelectionChange);\n    this.ace.on('beforeEndOperation', this.onBeforeEndOperation);\n  };\n  CodeMirror.Pos = function(line, ch) {\n    if (!(this instanceof Pos)) return new Pos(line, ch);\n    this.line = line; this.ch = ch;\n  };\n  CodeMirror.defineOption = function(name, val, setter) {};\n  CodeMirror.commands = {\n    redo: function(cm) { cm.ace.redo(); },\n    undo: function(cm) { cm.ace.undo(); },\n    newlineAndIndent: function(cm) { cm.ace.insert(\"\\n\"); },\n    goLineLeft: function(cm) { cm.ace.selection.moveCursorLineStart(); },\n    goLineRight: function(cm) { cm.ace.selection.moveCursorLineEnd(); }\n  };\n  CodeMirror.keyMap = {};\n  CodeMirror.addClass = CodeMirror.rmClass = function() {};\n  CodeMirror.e_stop = CodeMirror.e_preventDefault = event.stopEvent;\n  CodeMirror.keyName = function(e) {\n    var key = (KEYS[e.keyCode] || e.key || \"\");\n    if (key.length == 1) key = key.toUpperCase();\n    key = event.getModifierString(e).replace(/(^|-)\\w/g, function(m) {\n      return m.toUpperCase();\n    }) + key;\n    return key;\n  };\n  CodeMirror.keyMap['default'] = function(key) {\n    return function(cm) {\n      var cmd = cm.ace.commands.commandKeyBinding[key.toLowerCase()];\n      return cmd && cm.ace.execCommand(cmd) !== false;\n    };\n  };\n  CodeMirror.lookupKey = function lookupKey(key, map, handle) {\n    if (!map) map = \"default\";\n    if (typeof map == \"string\")\n      map = CodeMirror.keyMap[map] ||  CodeMirror.keyMap['default'];\n    var found = typeof map == \"function\" ? map(key) : map[key];\n    if (found === false) return \"nothing\";\n    if (found === \"...\") return \"multi\";\n    if (found != null && handle(found)) return \"handled\";\n\n    if (map.fallthrough) {\n      if (!Array.isArray(map.fallthrough))\n        return lookupKey(key, map.fallthrough, handle);\n      for (var i = 0; i < map.fallthrough.length; i++) {\n        var result = lookupKey(key, map.fallthrough[i], handle);\n        if (result) return result;\n      }\n    }\n  };\n\n\n  CodeMirror.findMatchingTag = function (cm, head) {\n    return cm.findMatchingTag(head);\n  }\n\n  CodeMirror.findEnclosingTag = function (cm, head) {\n\n  };\n\n  CodeMirror.signal = function(o, name, e) { return o._signal(name, e) };\n  CodeMirror.on = event.addListener;\n  CodeMirror.off = event.removeListener;\n  CodeMirror.isWordChar = function(ch) {\n    if (ch < \"\\x7f\") return /^\\w$/.test(ch);\n    TextModeTokenRe.lastIndex = 0;\n    return TextModeTokenRe.test(ch);\n  };\n\n(function() {\n  oop.implement(CodeMirror.prototype, EventEmitter);\n\n  this.destroy = function() {\n    this.ace.off('change', this.onChange);\n    this.ace.off('changeSelection', this.onSelectionChange);\n    this.ace.off('beforeEndOperation', this.onBeforeEndOperation);\n    this.removeOverlay();\n  };\n  this.virtualSelectionMode = function() {\n    return this.ace.inVirtualSelectionMode && this.ace.selection.index;\n  };\n  this.onChange = function(delta) {\n    if (this.$lineHandleChanges) {\n      this.$lineHandleChanges.push(delta);\n    }\n    var change = { text: delta.action[0] == 'i' ? delta.lines : [] };\n    var curOp = this.curOp = this.curOp || {};\n    if (!curOp.changeHandlers)\n      curOp.changeHandlers = this._eventRegistry[\"change\"] && this._eventRegistry[\"change\"].slice();\n    if (!curOp.lastChange) {\n      curOp.lastChange = curOp.change = change;\n    } else {\n      curOp.lastChange.next = curOp.lastChange = change;\n    }\n    this.$updateMarkers(delta);\n  };\n  this.onSelectionChange = function() {\n    var curOp = this.curOp = this.curOp || {};\n    if (!curOp.cursorActivityHandlers)\n      curOp.cursorActivityHandlers = this._eventRegistry[\"cursorActivity\"] && this._eventRegistry[\"cursorActivity\"].slice();\n    this.curOp.cursorActivity = true;\n    if (this.ace.inMultiSelectMode) {\n      this.ace.keyBinding.removeKeyboardHandler(multiSelectCommands.keyboardHandler);\n    }\n  };\n  this.operation = function(fn, force) {\n    if (!force && this.curOp || force && this.curOp && this.curOp.force) {\n      return fn();\n    }\n    if (force || !this.ace.curOp) {\n      if (this.curOp)\n        this.onBeforeEndOperation();\n    }\n    if (!this.ace.curOp) {\n      var prevOp = this.ace.prevOp;\n      this.ace.startOperation({\n        command: { name: \"vim\",  scrollIntoView: \"cursor\" }\n      });\n    }\n    var curOp = this.curOp = this.curOp || {};\n    this.curOp.force = force;\n    var result = fn();\n    if (this.ace.curOp && this.ace.curOp.command.name == \"vim\") {\n      if (this.state.dialog)\n        this.ace.curOp.command.scrollIntoView = this.ace.curOp.vimDialogScroll;\n      this.ace.endOperation();\n      if (!curOp.cursorActivity && !curOp.lastChange && prevOp)\n        this.ace.prevOp = prevOp;\n    }\n    if (force || !this.ace.curOp) {\n      if (this.curOp)\n        this.onBeforeEndOperation();\n    }\n    return result;\n  };\n  this.onBeforeEndOperation = function() {\n    var op = this.curOp;\n    if (op) {\n      if (op.change) { this.signal(\"change\", op.change, op); }\n      if (op && op.cursorActivity) { this.signal(\"cursorActivity\", null, op); }\n      this.curOp = null;\n    }\n  };\n\n  this.signal = function(eventName, e, handlers) {\n    var listeners = handlers ? handlers[eventName + \"Handlers\"]\n        : (this._eventRegistry || {})[eventName];\n    if (!listeners)\n        return;\n    listeners = listeners.slice();\n    for (var i=0; i<listeners.length; i++)\n        listeners[i](this, e);\n  };\n  this.firstLine = function() { return 0; };\n  this.lastLine = function() { return this.ace.session.getLength() - 1; };\n  this.lineCount = function() { return this.ace.session.getLength(); };\n  this.setCursor = function(line, ch) {\n    if (typeof line === 'object') {\n      ch = line.ch;\n      line = line.line;\n    }\n    var shouldScroll = !this.curOp && !this.ace.inVirtualSelectionMode;\n    if (!this.ace.inVirtualSelectionMode)\n      this.ace.exitMultiSelectMode();\n    this.ace.session.unfold({row: line, column: ch});\n    this.ace.selection.moveTo(line, ch);\n    if (shouldScroll) {\n      this.ace.renderer.scrollCursorIntoView();\n      this.ace.endOperation();\n    }\n  };\n  this.getCursor = function(p) {\n    var sel = this.ace.selection;\n    var pos = p == 'anchor' ? (sel.isEmpty() ? sel.lead : sel.anchor) :\n        p == 'head' || !p ? sel.lead : sel.getRange()[p];\n    return toCmPos(pos);\n  };\n  this.listSelections = function(p) {\n    var ranges = this.ace.multiSelect.rangeList.ranges;\n    if (!ranges.length || this.ace.inVirtualSelectionMode)\n      return [{anchor: this.getCursor('anchor'), head: this.getCursor('head')}];\n    return ranges.map(function(r) {\n      return {\n        anchor: this.clipPos(toCmPos(r.cursor == r.end ? r.start : r.end)),\n        head: this.clipPos(toCmPos(r.cursor))\n      };\n    }, this);\n  };\n  this.setSelections = function(p, primIndex) {\n    var sel = this.ace.multiSelect;\n    var ranges = p.map(function(x) {\n      var anchor = toAcePos(x.anchor);\n      var head = toAcePos(x.head);\n      var r = Range.comparePoints(anchor, head) < 0\n        ? new Range.fromPoints(anchor, head)\n        : new Range.fromPoints(head, anchor);\n      r.cursor = Range.comparePoints(r.start, head) ? r.end : r.start;\n      return r;\n    });\n\n    if (this.ace.inVirtualSelectionMode) {\n      this.ace.selection.fromOrientedRange(ranges[0]);\n      return;\n    }\n    if (!primIndex) {\n        ranges = ranges.reverse();\n    } else if (ranges[primIndex]) {\n       ranges.push(ranges.splice(primIndex, 1)[0]);\n    }\n    sel.toSingleRange(ranges[0].clone());\n    var session = this.ace.session;\n    for (var i = 0; i < ranges.length; i++) {\n      var range = session.$clipRangeToDocument(ranges[i]); // todo why ace doesn't do this?\n      sel.addRange(range);\n    }\n  };\n  this.setSelection = function(a, h, options) {\n    var sel = this.ace.selection;\n    sel.moveTo(a.line, a.ch);\n    sel.selectTo(h.line, h.ch);\n    if (options && options.origin == '*mouse') {\n      this.onBeforeEndOperation();\n    }\n  };\n  this.somethingSelected = function(p) {\n    return !this.ace.selection.isEmpty();\n  };\n  this.clipPos = function(p) {\n    var pos = this.ace.session.$clipPositionToDocument(p.line, p.ch);\n    return toCmPos(pos);\n  };\n  this.foldCode = function(pos) {\n    this.ace.session.$toggleFoldWidget(pos.line, {});\n  };\n  this.markText = function(cursor) {\n    // only used for fat-cursor, not needed\n    return {clear: function() {}, find: function() {}};\n  };\n  this.$updateMarkers = function(delta) {\n    var isInsert = delta.action == \"insert\";\n    var start = delta.start;\n    var end = delta.end;\n    var rowShift = (end.row - start.row) * (isInsert ? 1 : -1);\n    var colShift = (end.column - start.column) * (isInsert ? 1 : -1);\n    if (isInsert) end = start;\n\n    for (var i in this.marks) {\n      var point = this.marks[i];\n      var cmp = Range.comparePoints(point, start);\n      if (cmp < 0) {\n        continue; // delta starts after the range\n      }\n      if (cmp === 0) {\n        if (isInsert) {\n          if (!point.$insertRight) {\n            cmp = 1;\n          }\n          else if (point.bias == 1) {\n            cmp = 1;\n          } else {\n            point.bias = -1;\n            continue;\n          }\n        }\n      }\n      var cmp2 = isInsert ? cmp : Range.comparePoints(point, end);\n      if (cmp2 > 0) {\n        point.row += rowShift;\n        point.column += point.row == end.row ? colShift : 0;\n        continue;\n      }\n      if (!isInsert && cmp2 <= 0) {\n        point.row = start.row;\n        point.column = start.column;\n        if (cmp2 === 0)\n          point.bias = 1;\n      }\n    }\n  };\n  var Marker = function(cm, id, row, column) {\n    this.cm = cm;\n    this.id = id;\n    this.row = row;\n    this.column = column;\n    cm.marks[this.id] = this;\n  };\n  Marker.prototype.clear = function() { delete this.cm.marks[this.id] };\n  Marker.prototype.find = function() { return toCmPos(this) };\n  this.setBookmark = function(cursor, options) {\n    var bm = new Marker(this, this.$uid++, cursor.line, cursor.ch);\n    if (!options || !options.insertLeft)\n      bm.$insertRight = true;\n    this.marks[bm.id] = bm;\n    return bm;\n  };\n  this.moveH = function(increment, unit) {\n    if (unit == 'char') {\n      var sel = this.ace.selection;\n      sel.clearSelection();\n      sel.moveCursorBy(0, increment);\n    }\n  };\n  this.findPosV = function(start, amount, unit, goalColumn) {\n    if (unit == 'page') {\n      var renderer = this.ace.renderer;\n      var config = renderer.layerConfig;\n      amount = amount * Math.floor(config.height / config.lineHeight);\n      unit = 'line';\n    }\n    if (unit == 'line') {\n      var screenPos = this.ace.session.documentToScreenPosition(start.line, start.ch);\n      if (goalColumn != null)\n        screenPos.column = goalColumn;\n      screenPos.row += amount;\n      // not what codemirror does but vim mode needs only this\n      screenPos.row = Math.min(Math.max(0, screenPos.row), this.ace.session.getScreenLength() - 1);\n      var pos = this.ace.session.screenToDocumentPosition(screenPos.row, screenPos.column);\n      return toCmPos(pos);\n    } else {\n      debugger;\n    }\n  };\n  this.charCoords = function(pos, mode) {\n    if (mode == 'div' || !mode) {\n      var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch);\n      return {left: sc.column, top: sc.row};\n    }if (mode == 'local') {\n      var renderer = this.ace.renderer;\n      var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch);\n      var lh = renderer.layerConfig.lineHeight;\n      var cw = renderer.layerConfig.characterWidth;\n      var top = lh * sc.row;\n      return {left: sc.column * cw, top: top, bottom: top + lh};\n    }\n  };\n  this.coordsChar = function(pos, mode) {\n    var renderer = this.ace.renderer;\n    if (mode == 'local') {\n      var row = Math.max(0, Math.floor(pos.top / renderer.lineHeight));\n      var col = Math.max(0, Math.floor(pos.left / renderer.characterWidth));\n      var ch = renderer.session.screenToDocumentPosition(row, col);\n      return toCmPos(ch);\n    } else if (mode == 'div') {\n      throw \"not implemented\";\n    }\n  };\n  this.getSearchCursor = function(query, pos, caseFold) {\n    var caseSensitive = false;\n    var isRegexp = false;\n    if (query instanceof RegExp && !query.global) {\n      caseSensitive = !query.ignoreCase;\n      query = query.source;\n      isRegexp = true;\n    }\n    if (query == \"\\\\n\") { query = \"\\n\"; isRegexp = false; }\n    var search = new Search();\n    if (pos.ch == undefined) pos.ch = Number.MAX_VALUE;\n    var acePos = {row: pos.line, column: pos.ch};\n    var cm = this;\n    var last = null;\n    return {\n      findNext: function() { return this.find(false) },\n      findPrevious: function() {return this.find(true) },\n      find: function(back) {\n        search.setOptions({\n          needle: query,\n          caseSensitive: caseSensitive,\n          wrap: false,\n          backwards: back,\n          regExp: isRegexp,\n          start: last || acePos\n        });\n        var range = search.find(cm.ace.session);\n        last = range;\n        return last && [!last.isEmpty()];\n      },\n      from: function() { return last && toCmPos(last.start) },\n      to: function() { return last && toCmPos(last.end) },\n      replace: function(text) {\n        if (last) {\n          last.end = cm.ace.session.doc.replace(last, text);\n        }\n      }\n    };\n  };\n  this.scrollTo = function(x, y) {\n    var renderer = this.ace.renderer;\n    var config = renderer.layerConfig;\n    var maxHeight = config.maxHeight;\n    maxHeight -= (renderer.$size.scrollerHeight - renderer.lineHeight) * renderer.$scrollPastEnd;\n    if (y != null) this.ace.session.setScrollTop(Math.max(0, Math.min(y, maxHeight)));\n    if (x != null) this.ace.session.setScrollLeft(Math.max(0, Math.min(x, config.width)));\n  };\n  this.scrollInfo = function() { return 0; };\n  this.scrollIntoView = function(pos, margin) {\n    if (pos) {\n      var renderer = this.ace.renderer;\n      var viewMargin = { \"top\": 0, \"bottom\": margin };\n      renderer.scrollCursorIntoView(toAcePos(pos),\n        (renderer.lineHeight * 2) / renderer.$size.scrollerHeight, viewMargin);\n    }\n  };\n  this.getLine = function(row) { return this.ace.session.getLine(row) };\n  this.getRange = function(s, e) {\n    return this.ace.session.getTextRange(new Range(s.line, s.ch, e.line, e.ch));\n  };\n  this.replaceRange = function(text, s, e) {\n    if (!e) e = s;\n    // workaround for session.replace not handling negative rows\n    var range = new Range(s.line, s.ch, e.line, e.ch);\n    this.ace.session.$clipRangeToDocument(range);\n    return this.ace.session.replace(range, text);\n  };\n  this.replaceSelection =\n  this.replaceSelections = function(p) {\n    var strings = Array.isArray(p) && p;\n    var sel = this.ace.selection;\n    if (this.ace.inVirtualSelectionMode) {\n      this.ace.session.replace(sel.getRange(), strings ? p[0] || \"\": p );\n      return;\n    }\n    sel.inVirtualSelectionMode = true;\n    var ranges = sel.rangeList.ranges;\n    if (!ranges.length) ranges = [this.ace.multiSelect.getRange()];\n    for (var i = ranges.length; i--;)\n       this.ace.session.replace(ranges[i], strings ? p[i] || \"\" : p);\n    sel.inVirtualSelectionMode = false;\n  };\n  this.getSelection = function() {\n    return this.ace.getSelectedText();\n  };\n  this.getSelections = function() {\n    return this.listSelections().map(function(x) {\n      return this.getRange(x.anchor, x.head);\n    }, this);\n  };\n  this.getInputField = function() {\n    return this.ace.textInput.getElement();\n  };\n  this.getWrapperElement = function() {\n    return this.ace.container;\n  };\n  var optMap = {\n    indentWithTabs: \"useSoftTabs\",\n    indentUnit: \"tabSize\",\n    tabSize: \"tabSize\",\n    firstLineNumber: \"firstLineNumber\",\n    readOnly: \"readOnly\"\n  };\n  this.setOption = function(name, val) {\n    this.state[name] = val;\n    switch (name) {\n      case 'indentWithTabs':\n        name = optMap[name];\n        val = !val;\n      break;\n      case 'keyMap':\n        this.state.$keyMap = val;\n        return;\n      break;\n      default:\n        name = optMap[name];\n    }\n    if (name)\n      this.ace.setOption(name, val);\n  };\n  this.getOption = function(name) {\n    var val;\n    var aceOpt = optMap[name];\n    if (aceOpt)\n      val = this.ace.getOption(aceOpt);\n    switch (name) {\n      case 'indentWithTabs':\n        name = optMap[name];\n        return !val;\n      case 'keyMap':\n        return this.state.$keyMap || 'vim';\n    }\n    return aceOpt ? val : this.state[name];\n  };\n  this.toggleOverwrite = function(on) {\n    this.state.overwrite = on;\n    return this.ace.setOverwrite(on);\n  };\n  this.addOverlay = function(o) {\n    if (!this.$searchHighlight || !this.$searchHighlight.session) {\n      var highlight = new SearchHighlight(null, \"ace_highlight-marker\", \"text\");\n      var marker = this.ace.session.addDynamicMarker(highlight);\n      highlight.id = marker.id;\n      highlight.session = this.ace.session;\n      highlight.destroy = function(o) {\n        highlight.session.off(\"change\", highlight.updateOnChange);\n        highlight.session.off(\"changeEditor\", highlight.destroy);\n        highlight.session.removeMarker(highlight.id);\n        highlight.session = null;\n      };\n      highlight.updateOnChange = function(delta) {\n        var row = delta.start.row;\n        if (row == delta.end.row) highlight.cache[row] = undefined;\n        else highlight.cache.splice(row, highlight.cache.length);\n      };\n      highlight.session.on(\"changeEditor\", highlight.destroy);\n      highlight.session.on(\"change\", highlight.updateOnChange);\n    }\n    var re = new RegExp(o.query.source, \"gmi\");\n    this.$searchHighlight = o.highlight = highlight;\n    this.$searchHighlight.setRegexp(re);\n    this.ace.renderer.updateBackMarkers();\n  };\n  this.removeOverlay = function(o) {\n    if (this.$searchHighlight && this.$searchHighlight.session) {\n      this.$searchHighlight.destroy();\n    }\n  };\n  this.getScrollInfo = function() {\n    var renderer = this.ace.renderer;\n    var config = renderer.layerConfig;\n    return {\n      left: renderer.scrollLeft,\n      top: renderer.scrollTop,\n      height: config.maxHeight,\n      width: config.width,\n      clientHeight: config.height,\n      clientWidth: config.width\n    };\n  };\n  this.getValue = function() {\n    return this.ace.getValue();\n  };\n  this.setValue = function(v) {\n    return this.ace.setValue(v, -1);\n  };\n  this.getTokenTypeAt = function(pos) {\n    var token = this.ace.session.getTokenAt(pos.line, pos.ch);\n    return token && /comment|string/.test(token.type) ? \"string\" : \"\";\n  };\n  this.findMatchingBracket = function(pos) {\n    var m = this.ace.session.findMatchingBracket(toAcePos(pos));\n    return {to: m && toCmPos(m)};\n  };\n  this.findMatchingTag = function (pos) {\n    var m = this.ace.session.getMatchingTags(toAcePos(pos));\n    if (!m) return;\n    return {\n      open: {\n        from: toCmPos(m.openTag.start),\n        to: toCmPos(m.openTag.end)\n      },\n      close: {\n        from: toCmPos(m.closeTag.start),\n        to: toCmPos(m.closeTag.end)\n      }\n    };\n  };\n  this.indentLine = function(line, method) {\n    if (method === true)\n        this.ace.session.indentRows(line, line, \"\\t\");\n    else if (method === false)\n        this.ace.session.outdentRows(new Range(line, 0, line, 0));\n  };\n  this.indexFromPos = function(pos) {\n    return this.ace.session.doc.positionToIndex(toAcePos(pos));\n  };\n  this.posFromIndex = function(index) {\n    return toCmPos(this.ace.session.doc.indexToPosition(index));\n  };\n  this.focus = function(index) {\n    return this.ace.textInput.focus();\n  };\n  this.blur = function(index) {\n    return this.ace.blur();\n  };\n  this.defaultTextHeight = function(index) {\n    return this.ace.renderer.layerConfig.lineHeight;\n  };\n  this.scanForBracket = function(pos, dir, _, options) {\n    var re = options.bracketRegex.source;\n    var tokenRe = /paren|text|operator|tag/;\n    if (dir == 1) {\n      var m = this.ace.session.$findClosingBracket(re.slice(1, 2), toAcePos(pos), tokenRe);\n    } else {\n      var m = this.ace.session.$findOpeningBracket(re.slice(-2, -1), {row: pos.line, column: pos.ch + 1}, tokenRe);\n      if (!m && options.bracketRegex && options.bracketRegex.test(this.getLine(pos.line)[pos.ch - 1])) {\n          m = {row: pos.line, column: pos.ch - 1};\n      }\n    }\n    return m && {pos: toCmPos(m)};\n  };\n  this.refresh = function() {\n    return this.ace.resize(true);\n  };\n  this.getMode = function() {\n    return { name : this.getOption(\"mode\") };\n  };\n  this.execCommand = function(name) {\n    if (CodeMirror.commands.hasOwnProperty(name)) return CodeMirror.commands[name](this);\n    if (name == \"indentAuto\") return this.ace.execCommand(\"autoindent\");\n    console.log(name + \" is not implemented\");\n  };\n  this.getLineNumber = function(handle) {\n    var deltas = this.$lineHandleChanges;\n    if (!deltas)\n        return null;\n    var row = handle.row;\n    for (var i = 0; i < deltas.length; i++) {\n        var delta = deltas[i];\n        if (delta.start.row != delta.end.row) {\n            if (delta.action[0] == \"i\") {\n                if (delta.start.row < row)\n                    row += delta.end.row - delta.start.row;\n            }  else {\n                if (delta.start.row < row) {\n                    if (row < delta.end.row || row == delta.end.row && delta.start.column > 0) {\n                        return null;\n                    }\n                    row -= delta.end.row - delta.start.row;\n                }\n            }\n        }\n    }\n    return row;\n  };\n  this.getLineHandle = function(row) {\n    if (!this.$lineHandleChanges)\n      this.$lineHandleChanges = [];\n    return {text: this.ace.session.getLine(row), row: row};\n  };\n  this.releaseLineHandles = function() {\n    this.$lineHandleChanges = undefined;\n  };\n  this.getLastEditEnd = function() {\n    var undoManager = this.ace.session.$undoManager;\n    if (undoManager && undoManager.$lastDelta)\n      return toCmPos(undoManager.$lastDelta.end);\n  };\n}).call(CodeMirror.prototype);\n  function toAcePos(cmPos) {\n    return {row: cmPos.line, column: cmPos.ch};\n  }\n  function toCmPos(acePos) {\n    return new Pos(acePos.row, acePos.column);\n  }\n\n  var StringStream = CodeMirror.StringStream = function(string, tabSize) {\n    this.pos = this.start = 0;\n    this.string = string;\n    this.tabSize = tabSize || 8;\n    this.lastColumnPos = this.lastColumnValue = 0;\n    this.lineStart = 0;\n  };\n\n  StringStream.prototype = {\n    eol: function() {return this.pos >= this.string.length;},\n    sol: function() {return this.pos == this.lineStart;},\n    peek: function() {return this.string.charAt(this.pos) || undefined;},\n    next: function() {\n      if (this.pos < this.string.length)\n        return this.string.charAt(this.pos++);\n    },\n    eat: function(match) {\n      var ch = this.string.charAt(this.pos);\n      if (typeof match == \"string\") var ok = ch == match;\n      else var ok = ch && (match.test ? match.test(ch) : match(ch));\n      if (ok) {++this.pos; return ch;}\n    },\n    eatWhile: function(match) {\n      var start = this.pos;\n      while (this.eat(match)){}\n      return this.pos > start;\n    },\n    eatSpace: function() {\n      var start = this.pos;\n      while (/[\\s\\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;\n      return this.pos > start;\n    },\n    skipToEnd: function() {this.pos = this.string.length;},\n    skipTo: function(ch) {\n      var found = this.string.indexOf(ch, this.pos);\n      if (found > -1) {this.pos = found; return true;}\n    },\n    backUp: function(n) {this.pos -= n;},\n    column: function() {\n      throw \"not implemented\";\n    },\n    indentation: function() {\n      throw \"not implemented\";\n    },\n    match: function(pattern, consume, caseInsensitive) {\n      if (typeof pattern == \"string\") {\n        var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};\n        var substr = this.string.substr(this.pos, pattern.length);\n        if (cased(substr) == cased(pattern)) {\n          if (consume !== false) this.pos += pattern.length;\n          return true;\n        }\n      } else {\n        var match = this.string.slice(this.pos).match(pattern);\n        if (match && match.index > 0) return null;\n        if (match && consume !== false) this.pos += match[0].length;\n        return match;\n      }\n    },\n    current: function(){return this.string.slice(this.start, this.pos);},\n    hideFirstChars: function(n, inner) {\n      this.lineStart += n;\n      try { return inner(); }\n      finally { this.lineStart -= n; }\n    }\n  };\n\n// todo replace with showCommandLine\nCodeMirror.defineExtension = function(name, fn) {\n  CodeMirror.prototype[name] = fn;\n};\ndomLib.importCssString(`.normal-mode .ace_cursor{\n    border: none;\n    background-color: rgba(255,0,0,0.5);\n}\n.normal-mode .ace_hidden-cursors .ace_cursor{\n  background-color: transparent;\n  border: 1px solid red;\n  opacity: 0.7\n}\n.ace_dialog {\n  position: absolute;\n  left: 0; right: 0;\n  background: inherit;\n  z-index: 15;\n  padding: .1em .8em;\n  overflow: hidden;\n  color: inherit;\n}\n.ace_dialog-top {\n  border-bottom: 1px solid #444;\n  top: 0;\n}\n.ace_dialog-bottom {\n  border-top: 1px solid #444;\n  bottom: 0;\n}\n.ace_dialog input {\n  border: none;\n  outline: none;\n  background: transparent;\n  width: 20em;\n  color: inherit;\n  font-family: monospace;\n}`, \"vimMode\", false);\n(function() {\n  function dialogDiv(cm, template, bottom) {\n    var wrap = cm.ace.container;\n    var dialog;\n    dialog = wrap.appendChild(document.createElement(\"div\"));\n    if (bottom)\n      dialog.className = \"ace_dialog ace_dialog-bottom\";\n    else\n      dialog.className = \"ace_dialog ace_dialog-top\";\n\n    if (typeof template == \"string\") {\n      dialog.innerHTML = template;\n    } else { // Assuming it's a detached DOM element.\n      dialog.appendChild(template);\n    }\n    return dialog;\n  }\n\n  function closeNotification(cm, newVal) {\n    if (cm.state.currentNotificationClose)\n      cm.state.currentNotificationClose();\n    cm.state.currentNotificationClose = newVal;\n  }\n\n  CodeMirror.defineExtension(\"openDialog\", function(template, callback, options) {\n    if (this.virtualSelectionMode()) return;\n    if (!options) options = {};\n\n    closeNotification(this, null);\n\n    var dialog = dialogDiv(this, template, options.bottom);\n    var closed = false, me = this;\n    this.state.dialog = dialog;\n    function close(newVal) {\n      if (typeof newVal == 'string') {\n        inp.value = newVal;\n      } else {\n        if (closed) return;\n\n        if (newVal && newVal.type == \"blur\") {\n          if (document.activeElement === inp)\n            return;\n        }\n\n        if (me.state.dialog == dialog) {\n          me.state.dialog = null;\n          me.focus();\n        }\n        closed = true;\n        dialog.remove();\n\n        if (options.onClose) options.onClose(dialog);\n\n        // ace_patch{\n        var cm = me;\n        if (cm.state.vim) {\n          cm.state.vim.status = null;\n          cm.ace._signal(\"changeStatus\");\n          cm.ace.renderer.$loop.schedule(cm.ace.renderer.CHANGE_CURSOR);\n        }\n        // ace_patch}\n      }\n    }\n\n    var inp = dialog.getElementsByTagName(\"input\")[0], button;\n    if (inp) {\n      if (options.value) {\n        inp.value = options.value;\n        if (options.selectValueOnOpen !== false) inp.select();\n      }\n\n      if (options.onInput)\n        CodeMirror.on(inp, \"input\", function(e) { options.onInput(e, inp.value, close);});\n      if (options.onKeyUp)\n        CodeMirror.on(inp, \"keyup\", function(e) {options.onKeyUp(e, inp.value, close);});\n\n      CodeMirror.on(inp, \"keydown\", function(e) {\n        if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }\n        if (e.keyCode == 13) callback(inp.value);\n        if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {\n          CodeMirror.e_stop(e);\n          close();\n        }\n      });\n\n      if (options.closeOnBlur !== false) CodeMirror.on(inp, \"blur\", close);\n\n      inp.focus();\n    } else if (button = dialog.getElementsByTagName(\"button\")[0]) {\n      CodeMirror.on(button, \"click\", function() {\n        close();\n        me.focus();\n      });\n\n      if (options.closeOnBlur !== false) CodeMirror.on(button, \"blur\", close);\n\n      button.focus();\n    }\n    return close;\n  });\n\n  CodeMirror.defineExtension(\"openNotification\", function(template, options) {\n    if (this.virtualSelectionMode()) return;\n    closeNotification(this, close);\n    var dialog = dialogDiv(this, template, options && options.bottom);\n    var closed = false, doneTimer;\n    var duration = options && typeof options.duration !== \"undefined\" ? options.duration : 5000;\n\n    function close() {\n      if (closed) return;\n      closed = true;\n      clearTimeout(doneTimer);\n      dialog.remove();\n    }\n\n    CodeMirror.on(dialog, 'click', function(e) {\n      CodeMirror.e_preventDefault(e);\n      close();\n    });\n\n    if (duration)\n      doneTimer = setTimeout(close, duration);\n\n    return close;\n  });\n})();\n\n\n  var Pos = CodeMirror.Pos;\n\n  function updateSelectionForSurrogateCharacters(cm, curStart, curEnd) {\n    // start and character position when no selection \n    // is the same in visual mode, and differs in 1 character in normal mode\n    if (curStart.line === curEnd.line && curStart.ch >= curEnd.ch - 1) {\n      var text = cm.getLine(curStart.line);\n      var charCode = text.charCodeAt(curStart.ch);\n      if (0xD800 <= charCode && charCode <= 0xD8FF) {\n        curEnd.ch += 1;\n      }\n    }\n\n    return {start: curStart, end: curEnd};\n  }\n\n  var defaultKeymap = [\n    // Key to key mapping. This goes first to make it possible to override\n    // existing mappings.\n    { keys: '<Left>', type: 'keyToKey', toKeys: 'h' },\n    { keys: '<Right>', type: 'keyToKey', toKeys: 'l' },\n    { keys: '<Up>', type: 'keyToKey', toKeys: 'k' },\n    { keys: '<Down>', type: 'keyToKey', toKeys: 'j' },\n    { keys: 'g<Up>', type: 'keyToKey', toKeys: 'gk' },\n    { keys: 'g<Down>', type: 'keyToKey', toKeys: 'gj' },\n    { keys: '<Space>', type: 'keyToKey', toKeys: 'l' },\n    { keys: '<BS>', type: 'keyToKey', toKeys: 'h'},\n    { keys: '<Del>', type: 'keyToKey', toKeys: 'x' },\n    { keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' },\n    { keys: '<C-BS>', type: 'keyToKey', toKeys: 'B' },\n    { keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' },\n    { keys: '<S-BS>', type: 'keyToKey', toKeys: 'b' },\n    { keys: '<C-n>', type: 'keyToKey', toKeys: 'j' },\n    { keys: '<C-p>', type: 'keyToKey', toKeys: 'k' },\n    { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>' },\n    { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>' },\n    { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },\n    { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },\n    { keys: '<C-Esc>', type: 'keyToKey', toKeys: '<Esc>' }, // ipad keyboard sends C-Esc instead of C-[\n    { keys: '<C-Esc>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },\n    { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' },\n    { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'},\n    { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' },\n    { keys: 'S', type: 'keyToKey', toKeys: 'VdO', context: 'visual' },\n    { keys: '<Home>', type: 'keyToKey', toKeys: '0' },\n    { keys: '<End>', type: 'keyToKey', toKeys: '$' },\n    { keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },\n    { keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },\n    { keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },\n    { keys: '<Ins>', type: 'keyToKey', toKeys: 'i', context: 'normal'},\n    { keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },\n    // Motions\n    { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},\n    { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }},\n    { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }},\n    { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }},\n    { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }},\n    { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }},\n    { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }},\n    { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }},\n    { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }},\n    { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }},\n    { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }},\n    { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }},\n    { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }},\n    { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }},\n    { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }},\n    { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }},\n    { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }},\n    { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }},\n    { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }},\n    { keys: '(', type: 'motion', motion: 'moveBySentence', motionArgs: { forward: false }},\n    { keys: ')', type: 'motion', motion: 'moveBySentence', motionArgs: { forward: true }},\n    { keys: '<C-f>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }},\n    { keys: '<C-b>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }},\n    { keys: '<C-d>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }},\n    { keys: '<C-u>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }},\n    { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},\n    { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},\n    {keys: \"g$\", type: \"motion\", motion: \"moveToEndOfDisplayLine\"},\n    {keys: \"g^\", type: \"motion\", motion: \"moveToStartOfDisplayLine\"},\n    {keys: \"g0\", type: \"motion\", motion: \"moveToStartOfDisplayLine\"},\n    { keys: '0', type: 'motion', motion: 'moveToStartOfLine' },\n    { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' },\n    { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }},\n    { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }},\n    { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }},\n    { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }},\n    { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }},\n    { keys: 'f<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }},\n    { keys: 'F<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }},\n    { keys: 't<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }},\n    { keys: 'T<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }},\n    { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }},\n    { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }},\n    { keys: '\\'<register>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}},\n    { keys: '`<register>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}},\n    { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } },\n    { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } },\n    { keys: ']\\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } },\n    { keys: '[\\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } },\n    // the next two aren't motions but must come before more general motion declarations\n    { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}},\n    { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}},\n    { keys: ']<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}},\n    { keys: '[<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}},\n    { keys: '|', type: 'motion', motion: 'moveToColumn'},\n    { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'},\n    { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'},\n    // Operators\n    { keys: 'd', type: 'operator', operator: 'delete' },\n    { keys: 'y', type: 'operator', operator: 'yank' },\n    { keys: 'c', type: 'operator', operator: 'change' },\n    { keys: '=', type: 'operator', operator: 'indentAuto' },\n    { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }},\n    { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }},\n    { keys: 'g~', type: 'operator', operator: 'changeCase' },\n    { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true },\n    { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true },\n    { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }},\n    { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }},\n    { keys: 'gn', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: true }},\n    { keys: 'gN', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: false }},\n    { keys: 'gq', type: 'operator', operator: 'hardWrap' },\n    { keys: 'gw', type: 'operator', operator: 'hardWrap', operatorArgs: {keepCursor: true}},\n    // Operator-Motion dual commands\n    { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},\n    { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},\n    { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},\n    { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'},\n    { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'expandToLine', motionArgs: { linewise: true }, context: 'normal'},\n    { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'},\n    { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},\n    { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'},\n    { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'},\n    { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'},\n    { keys: '<C-u>', type: 'operatorMotion', operator: 'delete', motion: 'moveToStartOfLine', context: 'insert' },\n    { keys: '<C-w>', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' },\n    //ignore C-w in normal mode\n    { keys: '<C-w>', type: 'idle', context: 'normal' },\n    // Actions\n    { keys: '<C-i>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }},\n    { keys: '<C-o>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }},\n    { keys: '<C-e>', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }},\n    { keys: '<C-y>', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }},\n    { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' },\n    { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },\n    { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },\n    { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },\n    { keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' },\n    { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },\n    { keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' },\n    { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },\n    { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },\n    { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },\n    { keys: 'v', type: 'action', action: 'toggleVisualMode' },\n    { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }},\n    { keys: '<C-v>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},\n    { keys: '<C-q>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},\n    { keys: 'gv', type: 'action', action: 'reselectLastSelection' },\n    { keys: 'J', type: 'action', action: 'joinLines', isEdit: true },\n    { keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true },\n    { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},\n    { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},\n    { keys: 'r<character>', type: 'action', action: 'replace', isEdit: true },\n    { keys: '@<register>', type: 'action', action: 'replayMacro' },\n    { keys: 'q<register>', type: 'action', action: 'enterMacroRecordMode' },\n    // Handle Replace-mode as a special case of insert mode.\n    { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }, context: 'normal'},\n    { keys: 'R', type: 'operator', operator: 'change', operatorArgs: { linewise: true, fullLine: true }, context: 'visual', exitVisualBlock: true},\n    { keys: 'u', type: 'action', action: 'undo', context: 'normal' },\n    { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true },\n    { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true },\n    { keys: '<C-r>', type: 'action', action: 'redo' },\n    { keys: 'm<register>', type: 'action', action: 'setMark' },\n    { keys: '\"<register>', type: 'action', action: 'setRegister' },\n    { keys: '<C-r><register>', type: 'action', action: 'insertRegister', context: 'insert', isEdit: true },\n    { keys: '<C-o>', type: 'action', action: 'oneNormalCommand', context: 'insert' },\n    { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }},\n    { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n    { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }},\n    { keys: 'z<CR>', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n    { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }},\n    { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n    { keys: '.', type: 'action', action: 'repeatLastEdit' },\n    { keys: '<C-a>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}},\n    { keys: '<C-x>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}},\n    { keys: '<C-t>', type: 'action', action: 'indent', actionArgs: { indentRight: true }, context: 'insert' },\n    { keys: '<C-d>', type: 'action', action: 'indent', actionArgs: { indentRight: false }, context: 'insert' },\n    // Text object motions\n    { keys: 'a<register>', type: 'motion', motion: 'textObjectManipulation' },\n    { keys: 'i<register>', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }},\n    // Search\n    { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }},\n    { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }},\n    { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},\n    { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},\n    { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }},\n    { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }},\n    // Ex command\n    { keys: ':', type: 'ex' }\n  ];\n  var defaultKeymapLength = defaultKeymap.length;\n\n  /**\n   * Ex commands\n   * Care must be taken when adding to the default Ex command map. For any\n   * pair of commands that have a shared prefix, at least one of their\n   * shortNames must not match the prefix of the other command.\n   */\n  var defaultExCommandMap = [\n    { name: 'colorscheme', shortName: 'colo' },\n    { name: 'map' },\n    { name: 'imap', shortName: 'im' },\n    { name: 'nmap', shortName: 'nm' },\n    { name: 'vmap', shortName: 'vm' },\n    { name: 'omap', shortName: 'om' },\n    { name: 'noremap', shortName: 'no' },\n    { name: 'nnoremap', shortName: 'nn' },\n    { name: 'vnoremap', shortName: 'vn' },\n    { name: 'inoremap', shortName: 'ino' },\n    { name: 'onoremap', shortName: 'ono' },\n    { name: 'unmap' },\n    { name: 'mapclear', shortName: 'mapc' },\n    { name: 'nmapclear', shortName: 'nmapc' },\n    { name: 'vmapclear', shortName: 'vmapc' },\n    { name: 'imapclear', shortName: 'imapc' },\n    { name: 'omapclear', shortName: 'omapc' },\n    { name: 'write', shortName: 'w' },\n    { name: 'undo', shortName: 'u' },\n    { name: 'redo', shortName: 'red' },\n    { name: 'set', shortName: 'se' },\n    { name: 'setlocal', shortName: 'setl' },\n    { name: 'setglobal', shortName: 'setg' },\n    { name: 'sort', shortName: 'sor' },\n    { name: 'substitute', shortName: 's', possiblyAsync: true },\n    { name: 'startinsert', shortName: 'start' },\n    { name: 'nohlsearch', shortName: 'noh' },\n    { name: 'yank', shortName: 'y' },\n    { name: 'delmarks', shortName: 'delm' },\n    { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },\n    { name: 'vglobal', shortName: 'v' },\n    { name: 'delete', shortName: 'd' },\n    { name: 'join', shortName: 'j' },\n    { name: 'normal', shortName: 'norm' },\n    { name: 'global', shortName: 'g' }\n  ];\n\n  /**\n   * Langmap\n   * Determines how to interpret keystrokes in Normal and Visual mode.\n   * Useful for people who use a different keyboard layout than QWERTY\n   */\n  var langmap = parseLangmap('');\n\n    function enterVimMode(cm) {\n      cm.setOption('disableInput', true);\n      cm.setOption('showCursorWhenSelecting', false);\n      CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n      cm.on('cursorActivity', onCursorActivity);\n      maybeInitVimState(cm);\n      CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));\n    }\n\n    function leaveVimMode(cm) {\n      cm.setOption('disableInput', false);\n      cm.off('cursorActivity', onCursorActivity);\n      CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));\n      cm.state.vim = null;\n      if (highlightTimeout) clearTimeout(highlightTimeout);\n    }\n\n    function getOnPasteFn(cm) {\n      var vim = cm.state.vim;\n      if (!vim.onPasteFn) {\n        vim.onPasteFn = function() {\n          if (!vim.insertMode) {\n            cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));\n            actions.enterInsertMode(cm, {}, vim);\n          }\n        };\n      }\n      return vim.onPasteFn;\n    }\n\n    var numberRegex = /[\\d]/;\n    var wordCharTest = [CodeMirror.isWordChar, function(ch) {\n      return ch && !CodeMirror.isWordChar(ch) && !/\\s/.test(ch);\n    }], bigWordCharTest = [function(ch) {\n      return /\\S/.test(ch);\n    }];\n    var validMarks = ['<', '>'];\n    var validRegisters = ['-', '\"', '.', ':', '_', '/', '+'];\n    var latinCharRegex = /^\\w$/\n    var upperCaseChars;\n    try { upperCaseChars = new RegExp(\"^[\\\\p{Lu}]$\", \"u\"); }\n    catch (_) { upperCaseChars = /^[A-Z]$/; }\n\n    function isLine(cm, line) {\n      return line >= cm.firstLine() && line <= cm.lastLine();\n    }\n    function isLowerCase(k) {\n      return (/^[a-z]$/).test(k);\n    }\n    function isMatchableSymbol(k) {\n      return '()[]{}'.indexOf(k) != -1;\n    }\n    function isNumber(k) {\n      return numberRegex.test(k);\n    }\n    function isUpperCase(k) {\n      return upperCaseChars.test(k);\n    }\n    function isWhiteSpaceString(k) {\n      return (/^\\s*$/).test(k);\n    }\n    function isEndOfSentenceSymbol(k) {\n      return '.?!'.indexOf(k) != -1;\n    }\n    function inArray(val, arr) {\n      for (var i = 0; i < arr.length; i++) {\n        if (arr[i] == val) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    var options = {};\n    function defineOption(name, defaultValue, type, aliases, callback) {\n      if (defaultValue === undefined && !callback) {\n        throw Error('defaultValue is required unless callback is provided');\n      }\n      if (!type) { type = 'string'; }\n      options[name] = {\n        type: type,\n        defaultValue: defaultValue,\n        callback: callback\n      };\n      if (aliases) {\n        for (var i = 0; i < aliases.length; i++) {\n          options[aliases[i]] = options[name];\n        }\n      }\n      if (defaultValue) {\n        setOption(name, defaultValue);\n      }\n    }\n\n    function setOption(name, value, cm, cfg) {\n      var option = options[name];\n      cfg = cfg || {};\n      var scope = cfg.scope;\n      if (!option) {\n        return new Error('Unknown option: ' + name);\n      }\n      if (option.type == 'boolean') {\n        if (value && value !== true) {\n          return new Error('Invalid argument: ' + name + '=' + value);\n        } else if (value !== false) {\n          // Boolean options are set to true if value is not defined.\n          value = true;\n        }\n      }\n      if (option.callback) {\n        if (scope !== 'local') {\n          option.callback(value, undefined);\n        }\n        if (scope !== 'global' && cm) {\n          option.callback(value, cm);\n        }\n      } else {\n        if (scope !== 'local') {\n          option.value = option.type == 'boolean' ? !!value : value;\n        }\n        if (scope !== 'global' && cm) {\n          cm.state.vim.options[name] = {value: value};\n        }\n      }\n    }\n\n    function getOption(name, cm, cfg) {\n      var option = options[name];\n      cfg = cfg || {};\n      var scope = cfg.scope;\n      if (!option) {\n        return new Error('Unknown option: ' + name);\n      }\n      if (option.callback) {\n        var local = cm && option.callback(undefined, cm);\n        if (scope !== 'global' && local !== undefined) {\n          return local;\n        }\n        if (scope !== 'local') {\n          return option.callback();\n        }\n        return;\n      } else {\n        var local = (scope !== 'global') && (cm && cm.state.vim.options[name]);\n        return (local || (scope !== 'local') && option || {}).value;\n      }\n    }\n\n    defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) {\n      // Option is local. Do nothing for global.\n      if (cm === undefined) {\n        return;\n      }\n      // The 'filetype' option proxies to the CodeMirror 'mode' option.\n      if (name === undefined) {\n        var mode = cm.getOption('mode');\n        return mode == 'null' ? '' : mode;\n      } else {\n        var mode = name == '' ? 'null' : name;\n        cm.setOption('mode', mode);\n      }\n    });\n    defineOption('textwidth', 80, 'number', ['tw'], function(width, cm) {\n      // Option is local. Do nothing for global.\n      if (cm === undefined) {\n        return;\n      }\n      // The 'filetype' option proxies to the CodeMirror 'mode' option.\n      if (width === undefined) {\n        var value = cm.getOption('textwidth');\n        return value;\n      } else {\n        var column = Math.round(width);\n        if (column > 1) {\n          cm.setOption('textwidth', column);\n        }\n      }\n    });\n\n    var createCircularJumpList = function() {\n      var size = 100;\n      var pointer = -1;\n      var head = 0;\n      var tail = 0;\n      var buffer = new Array(size);\n      function add(cm, oldCur, newCur) {\n        var current = pointer % size;\n        var curMark = buffer[current];\n        function useNextSlot(cursor) {\n          var next = ++pointer % size;\n          var trashMark = buffer[next];\n          if (trashMark) {\n            trashMark.clear();\n          }\n          buffer[next] = cm.setBookmark(cursor);\n        }\n        if (curMark) {\n          var markPos = curMark.find();\n          // avoid recording redundant cursor position\n          if (markPos && !cursorEqual(markPos, oldCur)) {\n            useNextSlot(oldCur);\n          }\n        } else {\n          useNextSlot(oldCur);\n        }\n        useNextSlot(newCur);\n        head = pointer;\n        tail = pointer - size + 1;\n        if (tail < 0) {\n          tail = 0;\n        }\n      }\n      function move(cm, offset) {\n        pointer += offset;\n        if (pointer > head) {\n          pointer = head;\n        } else if (pointer < tail) {\n          pointer = tail;\n        }\n        var mark = buffer[(size + pointer) % size];\n        // skip marks that are temporarily removed from text buffer\n        if (mark && !mark.find()) {\n          var inc = offset > 0 ? 1 : -1;\n          var newCur;\n          var oldCur = cm.getCursor();\n          do {\n            pointer += inc;\n            mark = buffer[(size + pointer) % size];\n            // skip marks that are the same as current position\n            if (mark &&\n                (newCur = mark.find()) &&\n                !cursorEqual(oldCur, newCur)) {\n              break;\n            }\n          } while (pointer < head && pointer > tail);\n        }\n        return mark;\n      }\n      function find(cm, offset) {\n        var oldPointer = pointer;\n        var mark = move(cm, offset);\n        pointer = oldPointer;\n        return mark && mark.find();\n      }\n      return {\n        cachedCursor: undefined, //used for # and * jumps\n        add: add,\n        find: find,\n        move: move\n      };\n    };\n\n    // Returns an object to track the changes associated insert mode.  It\n    // clones the object that is passed in, or creates an empty object one if\n    // none is provided.\n    var createInsertModeChanges = function(c) {\n      if (c) {\n        // Copy construction\n        return {\n          changes: c.changes,\n          expectCursorActivityForChange: c.expectCursorActivityForChange\n        };\n      }\n      return {\n        // Change list\n        changes: [],\n        // Set to true on change, false on cursorActivity.\n        expectCursorActivityForChange: false\n      };\n    };\n\n    function MacroModeState() {\n      this.latestRegister = undefined;\n      this.isPlaying = false;\n      this.isRecording = false;\n      this.replaySearchQueries = [];\n      this.onRecordingDone = undefined;\n      this.lastInsertModeChanges = createInsertModeChanges();\n    }\n    MacroModeState.prototype = {\n      exitMacroRecordMode: function() {\n        var macroModeState = vimGlobalState.macroModeState;\n        if (macroModeState.onRecordingDone) {\n          macroModeState.onRecordingDone(); // close dialog\n        }\n        macroModeState.onRecordingDone = undefined;\n        macroModeState.isRecording = false;\n      },\n      enterMacroRecordMode: function(cm, registerName) {\n        var register =\n            vimGlobalState.registerController.getRegister(registerName);\n        if (register) {\n          register.clear();\n          this.latestRegister = registerName;\n          if (cm.openDialog) {\n            var template = dom('span', {class: 'cm-vim-message'}, 'recording @' + registerName);\n            this.onRecordingDone = cm.openDialog(template, null, {bottom:true});\n          }\n          this.isRecording = true;\n        }\n      }\n    };\n\n    function maybeInitVimState(cm) {\n      if (!cm.state.vim) {\n        // Store instance state in the CodeMirror object.\n        cm.state.vim = {\n          inputState: new InputState(),\n          // Vim's input state that triggered the last edit, used to repeat\n          // motions and operators with '.'.\n          lastEditInputState: undefined,\n          // Vim's action command before the last edit, used to repeat actions\n          // with '.' and insert mode repeat.\n          lastEditActionCommand: undefined,\n          // When using jk for navigation, if you move from a longer line to a\n          // shorter line, the cursor may clip to the end of the shorter line.\n          // If j is pressed again and cursor goes to the next line, the\n          // cursor should go back to its horizontal position on the longer\n          // line if it can. This is to keep track of the horizontal position.\n          lastHPos: -1,\n          // Doing the same with screen-position for gj/gk\n          lastHSPos: -1,\n          // The last motion command run. Cleared if a non-motion command gets\n          // executed in between.\n          lastMotion: null,\n          marks: {},\n          insertMode: false,\n          insertModeReturn: false,\n          // Repeat count for changes made in insert mode, triggered by key\n          // sequences like 3,i. Only exists when insertMode is true.\n          insertModeRepeat: undefined,\n          visualMode: false,\n          // If we are in visual line mode. No effect if visualMode is false.\n          visualLine: false,\n          visualBlock: false,\n          lastSelection: null,\n          lastPastedText: null,\n          sel: {},\n          // Buffer-local/window-local values of vim options.\n          options: {},\n          // Whether the next character should be interpreted literally\n          // Necassary for correct implementation of f<character>, r<character> etc.\n          // in terms of langmaps.\n          expectLiteralNext: false\n        };\n      }\n      return cm.state.vim;\n    }\n    var vimGlobalState;\n    function resetVimGlobalState() {\n      vimGlobalState = {\n        // The current search query.\n        searchQuery: null,\n        // Whether we are searching backwards.\n        searchIsReversed: false,\n        // Replace part of the last substituted pattern\n        lastSubstituteReplacePart: undefined,\n        jumpList: createCircularJumpList(),\n        macroModeState: new MacroModeState,\n        // Recording latest f, t, F or T motion command.\n        lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''},\n        registerController: new RegisterController({}),\n        // search history buffer\n        searchHistoryController: new HistoryController(),\n        // ex Command history buffer\n        exCommandHistoryController : new HistoryController()\n      };\n      for (var optionName in options) {\n        var option = options[optionName];\n        option.value = option.defaultValue;\n      }\n    }\n\n    var lastInsertModeKeyTimer;\n    var vimApi = {\n      enterVimMode: enterVimMode,\n      leaveVimMode: leaveVimMode,\n      buildKeyMap: function() {\n        // TODO: Convert keymap into dictionary format for fast lookup.\n      },\n      // Testing hook, though it might be useful to expose the register\n      // controller anyway.\n      getRegisterController: function() {\n        return vimGlobalState.registerController;\n      },\n      // Testing hook.\n      resetVimGlobalState_: resetVimGlobalState,\n\n      // Testing hook.\n      getVimGlobalState_: function() {\n        return vimGlobalState;\n      },\n\n      // Testing hook.\n      maybeInitVimState_: maybeInitVimState,\n\n      suppressErrorLogging: false,\n\n      InsertModeKey: InsertModeKey,\n      map: function(lhs, rhs, ctx) {\n        // Add user defined key bindings.\n        exCommandDispatcher.map(lhs, rhs, ctx);\n      },\n      unmap: function(lhs, ctx) {\n        return exCommandDispatcher.unmap(lhs, ctx);\n      },\n      // Non-recursive map function.\n      // NOTE: This will not create mappings to key maps that aren't present\n      // in the default key map. See TODO at bottom of function.\n      noremap: function(lhs, rhs, ctx) {\n        exCommandDispatcher.map(lhs, rhs, ctx, true);\n      },\n      // Remove all user-defined mappings for the provided context.\n      mapclear: function(ctx) {\n        // Partition the existing keymap into user-defined and true defaults.\n        var actualLength = defaultKeymap.length,\n            origLength = defaultKeymapLength;\n        var userKeymap = defaultKeymap.slice(0, actualLength - origLength);\n        defaultKeymap = defaultKeymap.slice(actualLength - origLength);\n        if (ctx) {\n          // If a specific context is being cleared, we need to keep mappings\n          // from all other contexts.\n          for (var i = userKeymap.length - 1; i >= 0; i--) {\n            var mapping = userKeymap[i];\n            if (ctx !== mapping.context) {\n              if (mapping.context) {\n                this._mapCommand(mapping);\n              } else {\n                // `mapping` applies to all contexts so create keymap copies\n                // for each context except the one being cleared.\n                var contexts = ['normal', 'insert', 'visual'];\n                for (var j in contexts) {\n                  if (contexts[j] !== ctx) {\n                    var newMapping = {};\n                    for (var key in mapping) {\n                      newMapping[key] = mapping[key];\n                    }\n                    newMapping.context = contexts[j];\n                    this._mapCommand(newMapping);\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      langmap: updateLangmap,\n      vimKeyFromEvent: vimKeyFromEvent,\n      // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace\n      // them, or somehow make them work with the existing CodeMirror setOption/getOption API.\n      setOption: setOption,\n      getOption: getOption,\n      defineOption: defineOption,\n      defineEx: function(name, prefix, func){\n        if (!prefix) {\n          prefix = name;\n        } else if (name.indexOf(prefix) !== 0) {\n          throw new Error('(Vim.defineEx) \"'+prefix+'\" is not a prefix of \"'+name+'\", command not registered');\n        }\n        exCommands[name]=func;\n        exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};\n      },\n      handleKey: function (cm, key, origin) {\n        var command = this.findKey(cm, key, origin);\n        if (typeof command === 'function') {\n          return command();\n        }\n      },\n      multiSelectHandleKey: multiSelectHandleKey,\n\n      /**\n       * This is the outermost function called by CodeMirror, after keys have\n       * been mapped to their Vim equivalents.\n       *\n       * Finds a command based on the key (and cached keys if there is a\n       * multi-key sequence). Returns `undefined` if no key is matched, a noop\n       * function if a partial match is found (multi-key), and a function to\n       * execute the bound command if a a key is matched. The function always\n       * returns true.\n       */\n      findKey: function(cm, key, origin) {\n        var vim = maybeInitVimState(cm);\n\n        function handleMacroRecording() {\n          var macroModeState = vimGlobalState.macroModeState;\n          if (macroModeState.isRecording) {\n            if (key == 'q') {\n              macroModeState.exitMacroRecordMode();\n              clearInputState(cm);\n              return true;\n            }\n            if (origin != 'mapping') {\n              logKey(macroModeState, key);\n            }\n          }\n        }\n        function handleEsc() {\n          if (key == '<Esc>') {\n            if (vim.visualMode) {\n              // Get back to normal mode.\n              exitVisualMode(cm);\n            } else if (vim.insertMode) {\n              // Get back to normal mode.\n              exitInsertMode(cm);\n            } else {\n              // We're already in normal mode. Let '<Esc>' be handled normally.\n              return;\n            }\n            clearInputState(cm);\n            return true;\n          }\n        }\n\n        function handleKeyInsertMode() {\n          if (handleEsc()) { return true; }\n          vim.inputState.keyBuffer.push(key);\n          var keys = vim.inputState.keyBuffer.join(\"\");\n          var keysAreChars = key.length == 1;\n          var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert');\n          var changeQueue = vim.inputState.changeQueue;\n\n          if (match.type == 'none') { clearInputState(cm); return false; }\n          else if (match.type == 'partial') {\n            if (match.expectLiteralNext) vim.expectLiteralNext = true;\n            if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }\n            lastInsertModeKeyTimer = keysAreChars && window.setTimeout(\n              function() { if (vim.insertMode && vim.inputState.keyBuffer.length) { clearInputState(cm); } },\n              getOption('insertModeEscKeysTimeout'));\n            if (keysAreChars) {\n              var selections = cm.listSelections();\n              if (!changeQueue || changeQueue.removed.length != selections.length)\n                changeQueue = vim.inputState.changeQueue = new ChangeQueue;\n              changeQueue.inserted += key;\n              for (var i = 0; i < selections.length; i++) {\n                var from = cursorMin(selections[i].anchor, selections[i].head);\n                var to = cursorMax(selections[i].anchor, selections[i].head);\n                var text = cm.getRange(from, cm.state.overwrite ? offsetCursor(to, 0, 1) : to);\n                changeQueue.removed[i] = (changeQueue.removed[i] || \"\") + text;\n              }\n            }\n            return !keysAreChars;\n          }\n          vim.expectLiteralNext = false;\n\n          if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }\n          if (match.command && changeQueue) {\n            var selections = cm.listSelections();\n            for (var i = 0; i < selections.length; i++) {\n              var here = selections[i].head;\n              cm.replaceRange(changeQueue.removed[i] || \"\", \n                offsetCursor(here, 0, -changeQueue.inserted.length), here, '+input');\n            }\n            vimGlobalState.macroModeState.lastInsertModeChanges.changes.pop();\n          }\n          if (!match.command) clearInputState(cm);\n          return match.command;\n        }\n\n        function handleKeyNonInsertMode() {\n          if (handleMacroRecording() || handleEsc()) { return true; }\n\n          vim.inputState.keyBuffer.push(key);\n          var keys = vim.inputState.keyBuffer.join(\"\");\n          if (/^[1-9]\\d*$/.test(keys)) { return true; }\n\n          var keysMatcher = /^(\\d*)(.*)$/.exec(keys);\n          if (!keysMatcher) { clearInputState(cm); return false; }\n          var context = vim.visualMode ? 'visual' :\n                                         'normal';\n          var mainKey = keysMatcher[2] || keysMatcher[1];\n          if (vim.inputState.operatorShortcut && vim.inputState.operatorShortcut.slice(-1) == mainKey) {\n            // multikey operators act linewise by repeating only the last character\n            mainKey = vim.inputState.operatorShortcut;\n          }\n          var match = commandDispatcher.matchCommand(mainKey, defaultKeymap, vim.inputState, context);\n          if (match.type == 'none') { clearInputState(cm); return false; }\n          else if (match.type == 'partial') {\n            if (match.expectLiteralNext) vim.expectLiteralNext = true;\n            return true;\n          }\n          else if (match.type == 'clear') { clearInputState(cm); return true; }\n          vim.expectLiteralNext = false;\n\n          vim.inputState.keyBuffer.length = 0;\n          keysMatcher = /^(\\d*)(.*)$/.exec(keys);\n          if (keysMatcher[1] && keysMatcher[1] != '0') {\n            vim.inputState.pushRepeatDigit(keysMatcher[1]);\n          }\n          return match.command;\n        }\n\n        var command;\n        if (vim.insertMode) { command = handleKeyInsertMode(); }\n        else { command = handleKeyNonInsertMode(); }\n        if (command === false) {\n          return !vim.insertMode && key.length === 1 ? function() { return true; } : undefined;\n        } else if (command === true) {\n          // TODO: Look into using CodeMirror's multi-key handling.\n          // Return no-op since we are caching the key. Counts as handled, but\n          // don't want act on it just yet.\n          return function() { return true; };\n        } else {\n          return function() {\n            if ((command.operator || command.isEdit) && cm.getOption('readOnly'))\n              return; // ace_patch\n            return cm.operation(function() {\n              cm.curOp.isVimOp = true;\n              try {\n                if (command.type == 'keyToKey') {\n                  doKeyToKey(cm, command.toKeys, command);\n                } else {\n                  commandDispatcher.processCommand(cm, vim, command);\n                }\n              } catch (e) {\n                // clear VIM state in case it's in a bad state.\n                cm.state.vim = undefined;\n                maybeInitVimState(cm);\n                if (!vimApi.suppressErrorLogging) {\n                  console['log'](e);\n                }\n                throw e;\n              }\n              return true;\n            });\n          };\n        }\n      },\n      handleEx: function(cm, input) {\n        exCommandDispatcher.processCommand(cm, input);\n      },\n\n      defineMotion: defineMotion,\n      defineAction: defineAction,\n      defineOperator: defineOperator,\n      mapCommand: mapCommand,\n      _mapCommand: _mapCommand,\n\n      defineRegister: defineRegister,\n\n      exitVisualMode: exitVisualMode,\n      exitInsertMode: exitInsertMode\n    };\n\n    var keyToKeyStack = [];\n    var noremap = false;\n    var virtualPrompt;\n    function sendKeyToPrompt(key) {\n      if (key[0] == \"<\") {\n        var lowerKey = key.toLowerCase().slice(1, -1);\n        var parts = lowerKey.split('-');\n        lowerKey = parts.pop() || '';\n        if (lowerKey == 'lt') key = '<';\n        else if (lowerKey == 'space') key = ' ';\n        else if (lowerKey == 'cr') key = '\\n';\n        else if (vimToCmKeyMap[lowerKey]) {\n          var value = virtualPrompt.value;\n          var event =  {\n            key: vimToCmKeyMap[lowerKey],\n            target: {\n              value: value,\n              selectionEnd: value.length,\n              selectionStart: value.length\n            }\n          }\n          if (virtualPrompt.onKeyDown) {\n            virtualPrompt.onKeyDown(event, virtualPrompt.value, close);\n          }\n          if (virtualPrompt && virtualPrompt.onKeyUp) {\n            virtualPrompt.onKeyUp(event, virtualPrompt.value, close);\n          }\n          return;\n        }\n      }\n      if (key == '\\n') {\n        var prompt = virtualPrompt;\n        virtualPrompt = null;\n        prompt.onClose && prompt.onClose(prompt.value);\n      } else {\n        virtualPrompt.value = (virtualPrompt.value || '') + key;\n      }\n\n      function close(value) {\n        if (typeof value == 'string') { virtualPrompt.value = value; }\n        else { virtualPrompt = null; }\n      }\n    }\n    function doKeyToKey(cm, keys, fromKey) {\n      var noremapBefore = noremap;\n      // prevent infinite recursion.\n      if (fromKey) {\n        if (keyToKeyStack.indexOf(fromKey) != -1) return;\n        keyToKeyStack.push(fromKey);\n        noremap = fromKey.noremap != false;\n      }\n\n      try {\n        var vim = maybeInitVimState(cm);\n        var keyRe = /<(?:[CSMA]-)*\\w+>|./gi;\n\n        var match;\n        // Pull off one command key, which is either a single character\n        // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.\n        while ((match = keyRe.exec(keys))) {\n          var key = match[0];\n          var wasInsert = vim.insertMode;\n          if (virtualPrompt) {\n            sendKeyToPrompt(key);\n            continue;\n          }\n\n          var result = vimApi.handleKey(cm, key, 'mapping');\n\n          if (!result && wasInsert && vim.insertMode) {\n            if (key[0] == \"<\") {\n              var lowerKey = key.toLowerCase().slice(1, -1);\n              var parts = lowerKey.split('-');\n              lowerKey = parts.pop() || '';\n              if (lowerKey == 'lt') key = '<';\n              else if (lowerKey == 'space') key = ' ';\n              else if (lowerKey == 'cr') key = '\\n';\n              else if (vimToCmKeyMap.hasOwnProperty(lowerKey)) {\n                // todo support codemirror keys in insertmode vimToCmKeyMap\n                key = vimToCmKeyMap[lowerKey];\n                sendCmKey(cm, key);\n                continue;\n              } else {\n                key = key[0];\n                keyRe.lastIndex = match.index + 1;\n              }\n            }\n            cm.replaceSelection(key);\n          }\n        }\n      } finally {\n        keyToKeyStack.pop();\n        noremap = keyToKeyStack.length ? noremapBefore : false;\n        if (!keyToKeyStack.length && virtualPrompt) {\n          var promptOptions = virtualPrompt;\n          virtualPrompt = null;\n          showPrompt(cm, promptOptions);\n        }\n      }\n    }\n\n    var specialKey = {\n      Return: 'CR', Backspace: 'BS', 'Delete': 'Del', Escape: 'Esc', Insert: 'Ins',\n      ArrowLeft: 'Left', ArrowRight: 'Right', ArrowUp: 'Up', ArrowDown: 'Down',\n      Enter: 'CR', ' ': 'Space'\n    };\n    var ignoredKeys = { Shift: 1, Alt: 1, Command: 1, Control: 1,\n      CapsLock: 1, AltGraph: 1, Dead: 1, Unidentified: 1 };\n\n    var vimToCmKeyMap = {};\n    'Left|Right|Up|Down|End|Home'.split('|').concat(Object.keys(specialKey)).forEach(function(x) {\n      vimToCmKeyMap[(specialKey[x] || '').toLowerCase()]\n         = vimToCmKeyMap[x.toLowerCase()] = x;\n    });\n\n    function vimKeyFromEvent(e, vim) {\n      var key = e.key;\n      if (ignoredKeys[key]) return;\n      if (key.length > 1 && key[0] == \"n\") {\n        key = key.replace(\"Numpad\", \"\");\n      }\n      key = specialKey[key] || key;\n\n      var name = '';\n      if (e.ctrlKey) { name += 'C-'; }\n      if (e.altKey) { name += 'A-'; }\n      if (e.metaKey) { name += 'M-'; }\n      // on mac many characters are entered as option- combos\n      // (e.g. on swiss keyboard { is option-8)\n      // so we ignore lonely A- modifier for keypress event on mac\n      if (CodeMirror.isMac && e.altKey && !e.metaKey && !e.ctrlKey) {\n        name = name.slice(2);\n      }\n      if ((name || key.length > 1) && e.shiftKey) { name += 'S-'; }\n  \n      if (vim && !vim.expectLiteralNext && key.length == 1) {\n        if (langmap.keymap && key in langmap.keymap) {\n          if (langmap.remapCtrl != false || !name)\n            key = langmap.keymap[key];\n        } else if (key.charCodeAt(0) > 255) {\n          var code = e.code && e.code.slice(-1) || \"\";\n          if (!e.shiftKey) code = code.toLowerCase();\n          if (code) key = code;\n        }\n      }\n\n      name += key;\n      if (name.length > 1) { name = '<' + name + '>'; }\n      return name;\n    };\n\n    // langmap support\n    function updateLangmap(langmapString, remapCtrl) {\n      if (langmap.string !== langmapString) {\n        langmap = parseLangmap(langmapString);\n      }\n      langmap.remapCtrl = remapCtrl;\n    }\n    function parseLangmap(langmapString) {\n      // From :help langmap\n      /*\n        The 'langmap' option is a list of parts, separated with commas.  Each\n            part can be in one of two forms:\n            1.  A list of pairs.  Each pair is a \"from\" character immediately\n                followed by the \"to\" character.  Examples: \"aA\", \"aAbBcC\".\n            2.  A list of \"from\" characters, a semi-colon and a list of \"to\"\n                characters.  Example: \"abc;ABC\"\n      */\n\n      let keymap = {};\n      if (!langmapString) return { keymap: keymap, string: '' };\n\n      function getEscaped(list) {\n        return list.split(/\\\\?(.)/).filter(Boolean);\n      }\n      langmapString.split(/((?:[^\\\\,]|\\\\.)+),/).map(part => {\n        if (!part) return;\n        const semicolon = part.split(/((?:[^\\\\;]|\\\\.)+);/);\n        if (semicolon.length == 3) {\n          const from = getEscaped(semicolon[1]);\n          const to = getEscaped(semicolon[2]);\n          if (from.length !== to.length) return; // skip over malformed part\n          for (let i = 0; i < from.length; ++i) keymap[from[i]] = to[i];\n        } else if (semicolon.length == 1) {\n          const pairs = getEscaped(part);\n          if (pairs.length % 2 !== 0) return; // skip over malformed part\n          for (let i = 0; i < pairs.length; i += 2) keymap[pairs[i]] = pairs[i + 1];\n        }\n      });\n\n      return { keymap: keymap, string: langmapString };\n    }\n\n    defineOption('langmap', undefined, 'string', ['lmap'], function(name, cm) {\n      // The 'filetype' option proxies to the CodeMirror 'mode' option.\n      if (name === undefined) {\n        return langmap.string;\n      } else {\n        updateLangmap(name);\n      }\n    });\n\n    // Represents the current input state.\n    function InputState() {\n      this.prefixRepeat = [];\n      this.motionRepeat = [];\n\n      this.operator = null;\n      this.operatorArgs = null;\n      this.motion = null;\n      this.motionArgs = null;\n      this.keyBuffer = []; // For matching multi-key commands.\n      this.registerName = null; // Defaults to the unnamed register.\n      this.changeQueue = null; // For restoring text used by insert mode keybindings\n    }\n    InputState.prototype.pushRepeatDigit = function(n) {\n      if (!this.operator) {\n        this.prefixRepeat = this.prefixRepeat.concat(n);\n      } else {\n        this.motionRepeat = this.motionRepeat.concat(n);\n      }\n    };\n    InputState.prototype.getRepeat = function() {\n      var repeat = 0;\n      if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) {\n        repeat = 1;\n        if (this.prefixRepeat.length > 0) {\n          repeat *= parseInt(this.prefixRepeat.join(''), 10);\n        }\n        if (this.motionRepeat.length > 0) {\n          repeat *= parseInt(this.motionRepeat.join(''), 10);\n        }\n      }\n      return repeat;\n    };\n\n    function clearInputState(cm, reason) {\n      cm.state.vim.inputState = new InputState();\n      cm.state.vim.expectLiteralNext = false;\n      CodeMirror.signal(cm, 'vim-command-done', reason);\n    }\n\n    function ChangeQueue() {\n      this.removed = [];\n      this.inserted = \"\";\n    }\n\n    /*\n     * Register stores information about copy and paste registers.  Besides\n     * text, a register must store whether it is linewise (i.e., when it is\n     * pasted, should it insert itself into a new line, or should the text be\n     * inserted at the cursor position.)\n     */\n    function Register(text, linewise, blockwise) {\n      this.clear();\n      this.keyBuffer = [text || ''];\n      this.insertModeChanges = [];\n      this.searchQueries = [];\n      this.linewise = !!linewise;\n      this.blockwise = !!blockwise;\n    }\n    Register.prototype = {\n      setText: function(text, linewise, blockwise) {\n        this.keyBuffer = [text || ''];\n        this.linewise = !!linewise;\n        this.blockwise = !!blockwise;\n      },\n      pushText: function(text, linewise) {\n        // if this register has ever been set to linewise, use linewise.\n        if (linewise) {\n          if (!this.linewise) {\n            this.keyBuffer.push('\\n');\n          }\n          this.linewise = true;\n        }\n        this.keyBuffer.push(text);\n      },\n      pushInsertModeChanges: function(changes) {\n        this.insertModeChanges.push(createInsertModeChanges(changes));\n      },\n      pushSearchQuery: function(query) {\n        this.searchQueries.push(query);\n      },\n      clear: function() {\n        this.keyBuffer = [];\n        this.insertModeChanges = [];\n        this.searchQueries = [];\n        this.linewise = false;\n      },\n      toString: function() {\n        return this.keyBuffer.join('');\n      }\n    };\n\n    /**\n     * Defines an external register.\n     *\n     * The name should be a single character that will be used to reference the register.\n     * The register should support setText, pushText, clear, and toString(). See Register\n     * for a reference implementation.\n     */\n    function defineRegister(name, register) {\n      var registers = vimGlobalState.registerController.registers;\n      if (!name || name.length != 1) {\n        throw Error('Register name must be 1 character');\n      }\n      // ace_patch\n      registers[name] = register;\n      validRegisters.push(name);\n    }\n\n    /*\n     * vim registers allow you to keep many independent copy and paste buffers.\n     * See http://usevim.com/2012/04/13/registers/ for an introduction.\n     *\n     * RegisterController keeps the state of all the registers.  An initial\n     * state may be passed in.  The unnamed register '\"' will always be\n     * overridden.\n     */\n    function RegisterController(registers) {\n      this.registers = registers;\n      this.unnamedRegister = registers['\"'] = new Register();\n      registers['.'] = new Register();\n      registers[':'] = new Register();\n      registers['/'] = new Register();\n      registers['+'] = new Register();\n    }\n    RegisterController.prototype = {\n      pushText: function(registerName, operator, text, linewise, blockwise) {\n        // The black hole register, \"_, means delete/yank to nowhere.\n        if (registerName === '_') return;\n        if (linewise && text.charAt(text.length - 1) !== '\\n'){\n          text += '\\n';\n        }\n        // Lowercase and uppercase registers refer to the same register.\n        // Uppercase just means append.\n        var register = this.isValidRegister(registerName) ?\n            this.getRegister(registerName) : null;\n        // if no register/an invalid register was specified, things go to the\n        // default registers\n        if (!register) {\n          switch (operator) {\n            case 'yank':\n              // The 0 register contains the text from the most recent yank.\n              this.registers['0'] = new Register(text, linewise, blockwise);\n              break;\n            case 'delete':\n            case 'change':\n              if (text.indexOf('\\n') == -1) {\n                // Delete less than 1 line. Update the small delete register.\n                this.registers['-'] = new Register(text, linewise);\n              } else {\n                // Shift down the contents of the numbered registers and put the\n                // deleted text into register 1.\n                this.shiftNumericRegisters_();\n                this.registers['1'] = new Register(text, linewise);\n              }\n              break;\n          }\n          // Make sure the unnamed register is set to what just happened\n          this.unnamedRegister.setText(text, linewise, blockwise);\n          return;\n        }\n\n        // If we've gotten to this point, we've actually specified a register\n        var append = isUpperCase(registerName);\n        if (append) {\n          register.pushText(text, linewise);\n        } else {\n          register.setText(text, linewise, blockwise);\n        }\n        if (registerName === '+' && typeof navigator !== 'undefined' &&\n          typeof navigator.clipboard !== 'undefined' &&\n          typeof navigator.clipboard.readText === 'function') {\n          navigator.clipboard.writeText(text);\n        }\n        // The unnamed register always has the same value as the last used\n        // register.\n        this.unnamedRegister.setText(register.toString(), linewise);\n      },\n      // Gets the register named @name.  If one of @name doesn't already exist,\n      // create it.  If @name is invalid, return the unnamedRegister.\n      getRegister: function(name) {\n        if (!this.isValidRegister(name)) {\n          return this.unnamedRegister;\n        }\n        name = name.toLowerCase();\n        if (!this.registers[name]) {\n          this.registers[name] = new Register();\n        }\n        return this.registers[name];\n      },\n      isValidRegister: function(name) {\n        return name && (inArray(name, validRegisters) || latinCharRegex.test(name));\n      },\n      shiftNumericRegisters_: function() {\n        for (var i = 9; i >= 2; i--) {\n          this.registers[i] = this.getRegister('' + (i - 1));\n        }\n      }\n    };\n    function HistoryController() {\n        this.historyBuffer = [];\n        this.iterator = 0;\n        this.initialPrefix = null;\n    }\n    HistoryController.prototype = {\n      // the input argument here acts a user entered prefix for a small time\n      // until we start autocompletion in which case it is the autocompleted.\n      nextMatch: function (input, up) {\n        var historyBuffer = this.historyBuffer;\n        var dir = up ? -1 : 1;\n        if (this.initialPrefix === null) this.initialPrefix = input;\n        for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) {\n          var element = historyBuffer[i];\n          for (var j = 0; j <= element.length; j++) {\n            if (this.initialPrefix == element.substring(0, j)) {\n              this.iterator = i;\n              return element;\n            }\n          }\n        }\n        // should return the user input in case we reach the end of buffer.\n        if (i >= historyBuffer.length) {\n          this.iterator = historyBuffer.length;\n          return this.initialPrefix;\n        }\n        // return the last autocompleted query or exCommand as it is.\n        if (i < 0 ) return input;\n      },\n      pushInput: function(input) {\n        var index = this.historyBuffer.indexOf(input);\n        if (index > -1) this.historyBuffer.splice(index, 1);\n        if (input.length) this.historyBuffer.push(input);\n      },\n      reset: function() {\n        this.initialPrefix = null;\n        this.iterator = this.historyBuffer.length;\n      }\n    };\n    var commandDispatcher = {\n      matchCommand: function(keys, keyMap, inputState, context) {\n        var matches = commandMatches(keys, keyMap, context, inputState);\n        if (!matches.full && !matches.partial) {\n          return {type: 'none'};\n        } else if (!matches.full && matches.partial) {\n          return {\n            type: 'partial',\n            expectLiteralNext: matches.partial.length == 1 && matches.partial[0].keys.slice(-11) == '<character>' // langmap literal logic\n          };\n        }\n\n        var bestMatch;\n        for (var i = 0; i < matches.full.length; i++) {\n          var match = matches.full[i];\n          if (!bestMatch) {\n            bestMatch = match;\n          }\n        }\n        if (bestMatch.keys.slice(-11) == '<character>' || bestMatch.keys.slice(-10) == '<register>') {\n          var character = lastChar(keys);\n          if (!character || character.length > 1) return {type: 'clear'};\n          inputState.selectedCharacter = character;\n        }\n        return {type: 'full', command: bestMatch};\n      },\n      processCommand: function(cm, vim, command) {\n        vim.inputState.repeatOverride = command.repeatOverride;\n        switch (command.type) {\n          case 'motion':\n            this.processMotion(cm, vim, command);\n            break;\n          case 'operator':\n            this.processOperator(cm, vim, command);\n            break;\n          case 'operatorMotion':\n            this.processOperatorMotion(cm, vim, command);\n            break;\n          case 'action':\n            this.processAction(cm, vim, command);\n            break;\n          case 'search':\n            this.processSearch(cm, vim, command);\n            break;\n          case 'ex':\n          case 'keyToEx':\n            this.processEx(cm, vim, command);\n            break;\n          default:\n            break;\n        }\n      },\n      processMotion: function(cm, vim, command) {\n        vim.inputState.motion = command.motion;\n        vim.inputState.motionArgs = copyArgs(command.motionArgs);\n        this.evalInput(cm, vim);\n      },\n      processOperator: function(cm, vim, command) {\n        var inputState = vim.inputState;\n        if (inputState.operator) {\n          if (inputState.operator == command.operator) {\n            // Typing an operator twice like 'dd' makes the operator operate\n            // linewise\n            inputState.motion = 'expandToLine';\n            inputState.motionArgs = { linewise: true };\n            this.evalInput(cm, vim);\n            return;\n          } else {\n            // 2 different operators in a row doesn't make sense.\n            clearInputState(cm);\n          }\n        }\n        inputState.operator = command.operator;\n        inputState.operatorArgs = copyArgs(command.operatorArgs);\n        if (command.keys.length > 1) {\n          inputState.operatorShortcut = command.keys;\n        }\n        if (command.exitVisualBlock) {\n            vim.visualBlock = false;\n            updateCmSelection(cm);\n        }\n        if (vim.visualMode) {\n          // Operating on a selection in visual mode. We don't need a motion.\n          this.evalInput(cm, vim);\n        }\n      },\n      processOperatorMotion: function(cm, vim, command) {\n        var visualMode = vim.visualMode;\n        var operatorMotionArgs = copyArgs(command.operatorMotionArgs);\n        if (operatorMotionArgs) {\n          // Operator motions may have special behavior in visual mode.\n          if (visualMode && operatorMotionArgs.visualLine) {\n            vim.visualLine = true;\n          }\n        }\n        this.processOperator(cm, vim, command);\n        if (!visualMode) {\n          this.processMotion(cm, vim, command);\n        }\n      },\n      processAction: function(cm, vim, command) {\n        var inputState = vim.inputState;\n        var repeat = inputState.getRepeat();\n        var repeatIsExplicit = !!repeat;\n        var actionArgs = copyArgs(command.actionArgs) || {};\n        if (inputState.selectedCharacter) {\n          actionArgs.selectedCharacter = inputState.selectedCharacter;\n        }\n        // Actions may or may not have motions and operators. Do these first.\n        if (command.operator) {\n          this.processOperator(cm, vim, command);\n        }\n        if (command.motion) {\n          this.processMotion(cm, vim, command);\n        }\n        if (command.motion || command.operator) {\n          this.evalInput(cm, vim);\n        }\n        actionArgs.repeat = repeat || 1;\n        actionArgs.repeatIsExplicit = repeatIsExplicit;\n        actionArgs.registerName = inputState.registerName;\n        clearInputState(cm);\n        vim.lastMotion = null;\n        if (command.isEdit) {\n          this.recordLastEdit(vim, inputState, command);\n        }\n        actions[command.action](cm, actionArgs, vim);\n      },\n      processSearch: function(cm, vim, command) {\n        if (!cm.getSearchCursor) {\n          // Search depends on SearchCursor.\n          return;\n        }\n        var forward = command.searchArgs.forward;\n        var wholeWordOnly = command.searchArgs.wholeWordOnly;\n        getSearchState(cm).setReversed(!forward);\n        var promptPrefix = (forward) ? '/' : '?';\n        var originalQuery = getSearchState(cm).getQuery();\n        var originalScrollPos = cm.getScrollInfo();\n        function handleQuery(query, ignoreCase, smartCase) {\n          vimGlobalState.searchHistoryController.pushInput(query);\n          vimGlobalState.searchHistoryController.reset();\n          try {\n            updateSearchQuery(cm, query, ignoreCase, smartCase);\n          } catch (e) {\n            showConfirm(cm, 'Invalid regex: ' + query);\n            clearInputState(cm);\n            return;\n          }\n          commandDispatcher.processMotion(cm, vim, {\n            type: 'motion',\n            motion: 'findNext',\n            motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist }\n          });\n        }\n        function onPromptClose(query) {\n          //ace_patch cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n          handleQuery(query, true /** ignoreCase */, true /** smartCase */);\n          var macroModeState = vimGlobalState.macroModeState;\n          if (macroModeState.isRecording) {\n            logSearchQuery(macroModeState, query);\n          }\n        }\n        function onPromptKeyUp(e, query, close) {\n          var keyName = vimKeyFromEvent(e), up, offset;\n          if (keyName == '<Up>' || keyName == '<Down>') {\n            up = keyName == '<Up>' ? true : false;\n            offset = e.target ? e.target.selectionEnd : 0;\n            query = vimGlobalState.searchHistoryController.nextMatch(query, up) || '';\n            close(query);\n            if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);\n          } else if (keyName && keyName != '<Left>' && keyName != '<Right>') {\n            vimGlobalState.searchHistoryController.reset();\n          }\n          var parsedQuery;\n          try {\n            parsedQuery = updateSearchQuery(cm, query,\n                true /** ignoreCase */, true /** smartCase */);\n          } catch (e) {\n            // Swallow bad regexes for incremental search.\n          }\n          if (parsedQuery) {\n            cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30);\n          } else {\n            clearSearchHighlight(cm);\n            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n          }\n        }\n        function onPromptKeyDown(e, query, close) {\n          var keyName = vimKeyFromEvent(e);\n          if (keyName == '<Esc>' || keyName == '<C-c>' || keyName == '<C-[>' ||\n              (keyName == '<BS>' && query == '')) {\n            vimGlobalState.searchHistoryController.pushInput(query);\n            vimGlobalState.searchHistoryController.reset();\n            updateSearchQuery(cm, originalQuery);\n            clearSearchHighlight(cm);\n            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n            CodeMirror.e_stop(e);\n            clearInputState(cm);\n            close();\n            cm.focus();\n          } else if (keyName == '<Up>' || keyName == '<Down>') {\n            CodeMirror.e_stop(e);\n          } else if (keyName == '<C-u>') {\n            // Ctrl-U clears input.\n            CodeMirror.e_stop(e);\n            close('');\n          }\n        }\n        switch (command.searchArgs.querySrc) {\n          case 'prompt':\n            var macroModeState = vimGlobalState.macroModeState;\n            if (macroModeState.isPlaying) {\n              var query = macroModeState.replaySearchQueries.shift();\n              handleQuery(query, true /** ignoreCase */, false /** smartCase */);\n            } else {\n              showPrompt(cm, {\n                  onClose: onPromptClose,\n                  prefix: promptPrefix,\n                  desc: '(JavaScript regexp)',\n                  onKeyUp: onPromptKeyUp,\n                  onKeyDown: onPromptKeyDown\n              });\n            }\n            break;\n          case 'wordUnderCursor':\n            var word = expandWordUnderCursor(cm, {noSymbol: true});\n            var isKeyword = true;\n            if (!word) {\n              word = expandWordUnderCursor(cm, {noSymbol: false});\n              isKeyword = false;\n            }\n            if (!word) {\n              showConfirm(cm, 'No word under cursor');\n              clearInputState(cm);\n              return;\n            }\n            var query = cm.getLine(word.start.line).substring(word.start.ch,\n                word.end.ch);\n            if (isKeyword && wholeWordOnly) {\n                query = '\\\\b' + query + '\\\\b';\n            } else {\n              query = escapeRegex(query);\n            }\n\n            // cachedCursor is used to save the old position of the cursor\n            // when * or # causes vim to seek for the nearest word and shift\n            // the cursor before entering the motion.\n            vimGlobalState.jumpList.cachedCursor = cm.getCursor();\n            cm.setCursor(word.start);\n\n            handleQuery(query, true /** ignoreCase */, false /** smartCase */);\n            break;\n        }\n      },\n      processEx: function(cm, vim, command) {\n        function onPromptClose(input) {\n          // Give the prompt some time to close so that if processCommand shows\n          // an error, the elements don't overlap.\n          vimGlobalState.exCommandHistoryController.pushInput(input);\n          vimGlobalState.exCommandHistoryController.reset();\n          exCommandDispatcher.processCommand(cm, input);\n          if (cm.state.vim) clearInputState(cm);\n        }\n        function onPromptKeyDown(e, input, close) {\n          var keyName = vimKeyFromEvent(e), up, offset;\n          if (keyName == '<Esc>' || keyName == '<C-c>' || keyName == '<C-[>' ||\n              (keyName == '<BS>' && input == '')) {\n            vimGlobalState.exCommandHistoryController.pushInput(input);\n            vimGlobalState.exCommandHistoryController.reset();\n            CodeMirror.e_stop(e);\n            clearInputState(cm);\n            close();\n            cm.focus();\n          }\n          if (keyName == '<Up>' || keyName == '<Down>') {\n            CodeMirror.e_stop(e);\n            up = keyName == '<Up>' ? true : false;\n            offset = e.target ? e.target.selectionEnd : 0;\n            input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || '';\n            close(input);\n            if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);\n          } else if (keyName == '<C-u>') {\n            // Ctrl-U clears input.\n            CodeMirror.e_stop(e);\n            close('');\n          } else if (keyName && keyName != '<Left>' && keyName != '<Right>') {\n              vimGlobalState.exCommandHistoryController.reset();\n          }\n        }\n        if (command.type == 'keyToEx') {\n          // Handle user defined Ex to Ex mappings\n          exCommandDispatcher.processCommand(cm, command.exArgs.input);\n        } else {\n          if (vim.visualMode) {\n            showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\\'<,\\'>',\n                onKeyDown: onPromptKeyDown, selectValueOnOpen: false});\n          } else {\n            showPrompt(cm, { onClose: onPromptClose, prefix: ':',\n                onKeyDown: onPromptKeyDown});\n          }\n        }\n      },\n      evalInput: function(cm, vim) {\n        // If the motion command is set, execute both the operator and motion.\n        // Otherwise return.\n        var inputState = vim.inputState;\n        var motion = inputState.motion;\n        var motionArgs = inputState.motionArgs || {};\n        var operator = inputState.operator;\n        var operatorArgs = inputState.operatorArgs || {};\n        var registerName = inputState.registerName;\n        var sel = vim.sel;\n        // TODO: Make sure cm and vim selections are identical outside visual mode.\n        var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head'));\n        var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor'));\n        var oldHead = copyCursor(origHead);\n        var oldAnchor = copyCursor(origAnchor);\n        var newHead, newAnchor;\n        var repeat;\n        if (operator) {\n          this.recordLastEdit(vim, inputState);\n        }\n        if (inputState.repeatOverride !== undefined) {\n          // If repeatOverride is specified, that takes precedence over the\n          // input state's repeat. Used by Ex mode and can be user defined.\n          repeat = inputState.repeatOverride;\n        } else {\n          repeat = inputState.getRepeat();\n        }\n        if (repeat > 0 && motionArgs.explicitRepeat) {\n          motionArgs.repeatIsExplicit = true;\n        } else if (motionArgs.noRepeat ||\n            (!motionArgs.explicitRepeat && repeat === 0)) {\n          repeat = 1;\n          motionArgs.repeatIsExplicit = false;\n        }\n        if (inputState.selectedCharacter) {\n          // If there is a character input, stick it in all of the arg arrays.\n          motionArgs.selectedCharacter = operatorArgs.selectedCharacter =\n              inputState.selectedCharacter;\n        }\n        motionArgs.repeat = repeat;\n        clearInputState(cm);\n        if (motion) {\n          var motionResult = motions[motion](cm, origHead, motionArgs, vim, inputState);\n          vim.lastMotion = motions[motion];\n          if (!motionResult) {\n            return;\n          }\n          if (motionArgs.toJumplist) {\n            if (!operator && cm.ace.curOp != null)\n              cm.ace.curOp.command.scrollIntoView = \"center-animate\"; // ace_patch\n            var jumpList = vimGlobalState.jumpList;\n            // if the current motion is # or *, use cachedCursor\n            var cachedCursor = jumpList.cachedCursor;\n            if (cachedCursor) {\n              recordJumpPosition(cm, cachedCursor, motionResult);\n              delete jumpList.cachedCursor;\n            } else {\n              recordJumpPosition(cm, origHead, motionResult);\n            }\n          }\n          if (motionResult instanceof Array) {\n            newAnchor = motionResult[0];\n            newHead = motionResult[1];\n          } else {\n            newHead = motionResult;\n          }\n          // TODO: Handle null returns from motion commands better.\n          if (!newHead) {\n            newHead = copyCursor(origHead);\n          }\n          if (vim.visualMode) {\n            if (!(vim.visualBlock && newHead.ch === Infinity)) {\n              newHead = clipCursorToContent(cm, newHead, oldHead);\n            }\n            if (newAnchor) {\n              newAnchor = clipCursorToContent(cm, newAnchor);\n            }\n            newAnchor = newAnchor || oldAnchor;\n            sel.anchor = newAnchor;\n            sel.head = newHead;\n            updateCmSelection(cm);\n            updateMark(cm, vim, '<',\n                cursorIsBefore(newAnchor, newHead) ? newAnchor\n                    : newHead);\n            updateMark(cm, vim, '>',\n                cursorIsBefore(newAnchor, newHead) ? newHead\n                    : newAnchor);\n          } else if (!operator) {\n            if (cm.ace.curOp)\n              cm.ace.curOp.vimDialogScroll = \"center-animate\"; // ace_patch\n            newHead = clipCursorToContent(cm, newHead, oldHead);\n            cm.setCursor(newHead.line, newHead.ch);\n          }\n        }\n        if (operator) {\n          if (operatorArgs.lastSel) {\n            // Replaying a visual mode operation\n            newAnchor = oldAnchor;\n            var lastSel = operatorArgs.lastSel;\n            var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line);\n            var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch);\n            if (lastSel.visualLine) {\n              // Linewise Visual mode: The same number of lines.\n              newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch);\n            } else if (lastSel.visualBlock) {\n              // Blockwise Visual mode: The same number of lines and columns.\n              newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset);\n            } else if (lastSel.head.line == lastSel.anchor.line) {\n              // Normal Visual mode within one line: The same number of characters.\n              newHead = new Pos(oldAnchor.line, oldAnchor.ch + chOffset);\n            } else {\n              // Normal Visual mode with several lines: The same number of lines, in the\n              // last line the same number of characters as in the last line the last time.\n              newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch);\n            }\n            vim.visualMode = true;\n            vim.visualLine = lastSel.visualLine;\n            vim.visualBlock = lastSel.visualBlock;\n            sel = vim.sel = {\n              anchor: newAnchor,\n              head: newHead\n            };\n            updateCmSelection(cm);\n          } else if (vim.visualMode) {\n            operatorArgs.lastSel = {\n              anchor: copyCursor(sel.anchor),\n              head: copyCursor(sel.head),\n              visualBlock: vim.visualBlock,\n              visualLine: vim.visualLine\n            };\n          }\n          var curStart, curEnd, linewise, mode;\n          var cmSel;\n          if (vim.visualMode) {\n            // Init visual op\n            curStart = cursorMin(sel.head, sel.anchor);\n            curEnd = cursorMax(sel.head, sel.anchor);\n            linewise = vim.visualLine || operatorArgs.linewise;\n            mode = vim.visualBlock ? 'block' :\n                   linewise ? 'line' :\n                   'char';\n            var newPositions = updateSelectionForSurrogateCharacters(cm, curStart, curEnd);\n            cmSel = makeCmSelection(cm, {\n              anchor: newPositions.start,\n              head: newPositions.end\n            }, mode);\n            if (linewise) {\n              var ranges = cmSel.ranges;\n              if (mode == 'block') {\n                // Linewise operators in visual block mode extend to end of line\n                for (var i = 0; i < ranges.length; i++) {\n                  ranges[i].head.ch = lineLength(cm, ranges[i].head.line);\n                }\n              } else if (mode == 'line') {\n                ranges[0].head = new Pos(ranges[0].head.line + 1, 0);\n              }\n            }\n          } else {\n            // Init motion op\n            curStart = copyCursor(newAnchor || oldAnchor);\n            curEnd = copyCursor(newHead || oldHead);\n            if (cursorIsBefore(curEnd, curStart)) {\n              var tmp = curStart;\n              curStart = curEnd;\n              curEnd = tmp;\n            }\n            linewise = motionArgs.linewise || operatorArgs.linewise;\n            if (linewise) {\n              // Expand selection to entire line.\n              expandSelectionToLine(cm, curStart, curEnd);\n            } else if (motionArgs.forward) {\n              // Clip to trailing newlines only if the motion goes forward.\n              clipToLine(cm, curStart, curEnd);\n            }\n            mode = 'char';\n            var exclusive = !motionArgs.inclusive || linewise;\n            var newPositions = updateSelectionForSurrogateCharacters(cm, curStart, curEnd);\n            cmSel = makeCmSelection(cm, {\n              anchor: newPositions.start,\n              head: newPositions.end\n            }, mode, exclusive);\n          }\n          cm.setSelections(cmSel.ranges, cmSel.primary);\n          vim.lastMotion = null;\n          operatorArgs.repeat = repeat; // For indent in visual mode.\n          operatorArgs.registerName = registerName;\n          // Keep track of linewise as it affects how paste and change behave.\n          operatorArgs.linewise = linewise;\n          var operatorMoveTo = operators[operator](\n            cm, operatorArgs, cmSel.ranges, oldAnchor, newHead);\n          if (vim.visualMode) {\n            exitVisualMode(cm, operatorMoveTo != null);\n          }\n          if (operatorMoveTo) {\n            cm.setCursor(operatorMoveTo);\n          }\n        }\n      },\n      recordLastEdit: function(vim, inputState, actionCommand) {\n        var macroModeState = vimGlobalState.macroModeState;\n        if (macroModeState.isPlaying) { return; }\n        vim.lastEditInputState = inputState;\n        vim.lastEditActionCommand = actionCommand;\n        macroModeState.lastInsertModeChanges.changes = [];\n        macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;\n        macroModeState.lastInsertModeChanges.visualBlock = vim.visualBlock ? vim.sel.head.line - vim.sel.anchor.line : 0;\n      }\n    };\n\n    /**\n     * typedef {Object{line:number,ch:number}} Cursor An object containing the\n     *     position of the cursor.\n     */\n    // All of the functions below return Cursor objects.\n    var motions = {\n      moveToTopLine: function(cm, _head, motionArgs) {\n        var line = getUserVisibleLines(cm).top + motionArgs.repeat -1;\n        return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n      },\n      moveToMiddleLine: function(cm) {\n        var range = getUserVisibleLines(cm);\n        var line = Math.floor((range.top + range.bottom) * 0.5);\n        return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n      },\n      moveToBottomLine: function(cm, _head, motionArgs) {\n        var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1;\n        return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n      },\n      expandToLine: function(_cm, head, motionArgs) {\n        // Expands forward to end of line, and then to next line if repeat is\n        // >1. Does not handle backward motion!\n        var cur = head;\n        return new Pos(cur.line + motionArgs.repeat - 1, Infinity);\n      },\n      findNext: function(cm, _head, motionArgs) {\n        var state = getSearchState(cm);\n        var query = state.getQuery();\n        if (!query) {\n          return;\n        }\n        var prev = !motionArgs.forward;\n        // If search is initiated with ? instead of /, negate direction.\n        prev = (state.isReversed()) ? !prev : prev;\n        highlightSearchMatches(cm, query);\n        return findNext(cm, prev/** prev */, query, motionArgs.repeat);\n      },\n      /**\n       * Find and select the next occurrence of the search query. If the cursor is currently\n       * within a match, then find and select the current match. Otherwise, find the next occurrence in the\n       * appropriate direction.\n       *\n       * This differs from `findNext` in the following ways:\n       *\n       * 1. Instead of only returning the \"from\", this returns a \"from\", \"to\" range.\n       * 2. If the cursor is currently inside a search match, this selects the current match\n       *    instead of the next match.\n       * 3. If there is no associated operator, this will turn on visual mode.\n       */\n      findAndSelectNextInclusive: function(cm, _head, motionArgs, vim, prevInputState) {\n        var state = getSearchState(cm);\n        var query = state.getQuery();\n\n        if (!query) {\n          return;\n        }\n\n        var prev = !motionArgs.forward;\n        prev = (state.isReversed()) ? !prev : prev;\n\n        // next: [from, to] | null\n        var next = findNextFromAndToInclusive(cm, prev, query, motionArgs.repeat, vim);\n\n        // No matches.\n        if (!next) {\n          return;\n        }\n\n        // If there's an operator that will be executed, return the selection.\n        if (prevInputState.operator) {\n          return next;\n        }\n\n        // At this point, we know that there is no accompanying operator -- let's\n        // deal with visual mode in order to select an appropriate match.\n\n        var from = next[0];\n        // For whatever reason, when we use the \"to\" as returned by searchcursor.js directly,\n        // the resulting selection is extended by 1 char. Let's shrink it so that only the\n        // match is selected.\n        var to = new Pos(next[1].line, next[1].ch - 1);\n\n        if (vim.visualMode) {\n          // If we were in visualLine or visualBlock mode, get out of it.\n          if (vim.visualLine || vim.visualBlock) {\n            vim.visualLine = false;\n            vim.visualBlock = false;\n            CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: \"\"});\n          }\n\n          // If we're currently in visual mode, we should extend the selection to include\n          // the search result.\n          var anchor = vim.sel.anchor;\n          if (anchor) {\n            if (state.isReversed()) {\n              if (motionArgs.forward) {\n                return [anchor, from];\n              }\n\n              return [anchor, to];\n            } else {\n              if (motionArgs.forward) {\n                return [anchor, to];\n              }\n\n              return [anchor, from];\n            }\n          }\n        } else {\n          // Let's turn visual mode on.\n          vim.visualMode = true;\n          vim.visualLine = false;\n          vim.visualBlock = false;\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: \"\"});\n        }\n\n        return prev ? [to, from] : [from, to];\n      },\n      goToMark: function(cm, _head, motionArgs, vim) {\n        var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);\n        if (pos) {\n          return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos;\n        }\n        return null;\n      },\n      moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) {\n        if (vim.visualBlock && motionArgs.sameLine) {\n          var sel = vim.sel;\n          return [\n            clipCursorToContent(cm, new Pos(sel.anchor.line, sel.head.ch)),\n            clipCursorToContent(cm, new Pos(sel.head.line, sel.anchor.ch))\n          ];\n        } else {\n          return ([vim.sel.head, vim.sel.anchor]);\n        }\n      },\n      jumpToMark: function(cm, head, motionArgs, vim) {\n        var best = head;\n        for (var i = 0; i < motionArgs.repeat; i++) {\n          var cursor = best;\n          for (var key in vim.marks) {\n            if (!isLowerCase(key)) {\n              continue;\n            }\n            var mark = vim.marks[key].find();\n            var isWrongDirection = (motionArgs.forward) ?\n              cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark);\n\n            if (isWrongDirection) {\n              continue;\n            }\n            if (motionArgs.linewise && (mark.line == cursor.line)) {\n              continue;\n            }\n\n            var equal = cursorEqual(cursor, best);\n            var between = (motionArgs.forward) ?\n              cursorIsBetween(cursor, mark, best) :\n              cursorIsBetween(best, mark, cursor);\n\n            if (equal || between) {\n              best = mark;\n            }\n          }\n        }\n\n        if (motionArgs.linewise) {\n          // Vim places the cursor on the first non-whitespace character of\n          // the line if there is one, else it places the cursor at the end\n          // of the line, regardless of whether a mark was found.\n          best = new Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));\n        }\n        return best;\n      },\n      moveByCharacters: function(_cm, head, motionArgs) {\n        var cur = head;\n        var repeat = motionArgs.repeat;\n        var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat;\n        return new Pos(cur.line, ch);\n      },\n      moveByLines: function(cm, head, motionArgs, vim) {\n        var cur = head;\n        var endCh = cur.ch;\n        // Depending what our last motion was, we may want to do different\n        // things. If our last motion was moving vertically, we want to\n        // preserve the HPos from our last horizontal move.  If our last motion\n        // was going to the end of a line, moving vertically we should go to\n        // the end of the line, etc.\n        switch (vim.lastMotion) {\n          case this.moveByLines:\n          case this.moveByDisplayLines:\n          case this.moveByScroll:\n          case this.moveToColumn:\n          case this.moveToEol:\n            endCh = vim.lastHPos;\n            break;\n          default:\n            vim.lastHPos = endCh;\n        }\n        var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0);\n        var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;\n        var first = cm.firstLine();\n        var last = cm.lastLine();\n        // Vim go to line begin or line end when cursor at first/last line and\n        // move to previous/next line is triggered.\n        if (line < first && cur.line == first){\n          return this.moveToStartOfLine(cm, head, motionArgs, vim);\n        } else if (line > last && cur.line == last){\n            return moveToEol(cm, head, motionArgs, vim, true);\n        }\n        // ace_patch{\n        var fold = cm.ace.session.getFoldLine(line);\n        if (fold) {\n          if (motionArgs.forward) {\n            if (line > fold.start.row)\n              line = fold.end.row + 1;\n          } else {\n            line = fold.start.row;\n          }\n        }\n        // ace_patch}\n        if (motionArgs.toFirstChar){\n          endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));\n          vim.lastHPos = endCh;\n        }\n        vim.lastHSPos = cm.charCoords(new Pos(line, endCh),'div').left;\n        return new Pos(line, endCh);\n      },\n      moveByDisplayLines: function(cm, head, motionArgs, vim) {\n        var cur = head;\n        switch (vim.lastMotion) {\n          case this.moveByDisplayLines:\n          case this.moveByScroll:\n          case this.moveByLines:\n          case this.moveToColumn:\n          case this.moveToEol:\n            break;\n          default:\n            vim.lastHSPos = cm.charCoords(cur,'div').left;\n        }\n        var repeat = motionArgs.repeat;\n        var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos);\n        if (res.hitSide) {\n          if (motionArgs.forward) {\n            var lastCharCoords = cm.charCoords(res, 'div');\n            var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos };\n            var res = cm.coordsChar(goalCoords, 'div');\n          } else {\n            var resCoords = cm.charCoords(new Pos(cm.firstLine(), 0), 'div');\n            resCoords.left = vim.lastHSPos;\n            res = cm.coordsChar(resCoords, 'div');\n          }\n        }\n        vim.lastHPos = res.ch;\n        return res;\n      },\n      moveByPage: function(cm, head, motionArgs) {\n        // CodeMirror only exposes functions that move the cursor page down, so\n        // doing this bad hack to move the cursor and move it back. evalInput\n        // will move the cursor to where it should be in the end.\n        var curStart = head;\n        var repeat = motionArgs.repeat;\n        return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page');\n      },\n      moveByParagraph: function(cm, head, motionArgs) {\n        var dir = motionArgs.forward ? 1 : -1;\n        return findParagraph(cm, head, motionArgs.repeat, dir);\n      },\n      moveBySentence: function(cm, head, motionArgs) {\n        var dir = motionArgs.forward ? 1 : -1;\n        return findSentence(cm, head, motionArgs.repeat, dir);\n      },\n      moveByScroll: function(cm, head, motionArgs, vim) {\n        var scrollbox = cm.getScrollInfo();\n        var curEnd = null;\n        var repeat = motionArgs.repeat;\n        if (!repeat) {\n          repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight());\n        }\n        var orig = cm.charCoords(head, 'local');\n        motionArgs.repeat = repeat;\n        curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim);\n        if (!curEnd) {\n          return null;\n        }\n        var dest = cm.charCoords(curEnd, 'local');\n        cm.scrollTo(null, scrollbox.top + dest.top - orig.top);\n        return curEnd;\n      },\n      moveByWords: function(cm, head, motionArgs) {\n        return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward,\n            !!motionArgs.wordEnd, !!motionArgs.bigWord);\n      },\n      moveTillCharacter: function(cm, head, motionArgs) {\n        var repeat = motionArgs.repeat;\n        var curEnd = moveToCharacter(cm, repeat, motionArgs.forward,\n            motionArgs.selectedCharacter, head);\n        var increment = motionArgs.forward ? -1 : 1;\n        recordLastCharacterSearch(increment, motionArgs);\n        if (!curEnd) return null;\n        curEnd.ch += increment;\n        return curEnd;\n      },\n      moveToCharacter: function(cm, head, motionArgs) {\n        var repeat = motionArgs.repeat;\n        recordLastCharacterSearch(0, motionArgs);\n        return moveToCharacter(cm, repeat, motionArgs.forward,\n            motionArgs.selectedCharacter, head) || head;\n      },\n      moveToSymbol: function(cm, head, motionArgs) {\n        var repeat = motionArgs.repeat;\n        return findSymbol(cm, repeat, motionArgs.forward,\n            motionArgs.selectedCharacter) || head;\n      },\n      moveToColumn: function(cm, head, motionArgs, vim) {\n        var repeat = motionArgs.repeat;\n        // repeat is equivalent to which column we want to move to!\n        vim.lastHPos = repeat - 1;\n        vim.lastHSPos = cm.charCoords(head,'div').left;\n        return moveToColumn(cm, repeat);\n      },\n      moveToEol: function(cm, head, motionArgs, vim) {\n        return moveToEol(cm, head, motionArgs, vim, false);\n      },\n      moveToFirstNonWhiteSpaceCharacter: function(cm, head) {\n        // Go to the start of the line where the text begins, or the end for\n        // whitespace-only lines\n        var cursor = head;\n        return new Pos(cursor.line,\n                   findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line)));\n      },\n      moveToMatchedSymbol: function(cm, head) {\n        var cursor = head;\n        var line = cursor.line;\n        var ch = cursor.ch;\n        var lineText = cm.getLine(line);\n        var symbol;\n        for (; ch < lineText.length; ch++) {\n          symbol = lineText.charAt(ch);\n          if (symbol && isMatchableSymbol(symbol)) {\n            var style = cm.getTokenTypeAt(new Pos(line, ch + 1));\n            if (style !== \"string\" && style !== \"comment\") {\n              break;\n            }\n          }\n        }\n        if (ch < lineText.length) {\n          // Only include angle brackets in analysis if they are being matched.\n          var re = /[<>]/.test(lineText[ch]) ? /[(){}[\\]<>]/ : /[(){}[\\]]/; //ace_patch?\n          var matched = cm.findMatchingBracket(new Pos(line, ch+1), {bracketRegex: re});\n          return matched.to;\n        } else {\n          return cursor;\n        }\n      },\n      moveToStartOfLine: function(_cm, head) {\n        return new Pos(head.line, 0);\n      },\n      moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) {\n        var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine();\n        if (motionArgs.repeatIsExplicit) {\n          lineNum = motionArgs.repeat - cm.getOption('firstLineNumber');\n        }\n        return new Pos(lineNum,\n                   findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));\n      },\n      moveToStartOfDisplayLine: function(cm) {\n        cm.execCommand(\"goLineLeft\");\n        return cm.getCursor();\n      },\n      moveToEndOfDisplayLine: function(cm) {\n        cm.execCommand(\"goLineRight\");\n        var head = cm.getCursor();\n        if (head.sticky == \"before\") head.ch--;\n        return head;\n      },\n      textObjectManipulation: function(cm, head, motionArgs, vim) {\n        // TODO: lots of possible exceptions that can be thrown here. Try da(\n        //     outside of a () block.\n        var mirroredPairs = {'(': ')', ')': '(',\n                             '{': '}', '}': '{',\n                             '[': ']', ']': '[',\n                             '<': '>', '>': '<'};\n        var selfPaired = {'\\'': true, '\"': true, '`': true};\n\n        var character = motionArgs.selectedCharacter;\n        // 'b' refers to  '()' block.\n        // 'B' refers to  '{}' block.\n        if (character == 'b') {\n          character = '(';\n        } else if (character == 'B') {\n          character = '{';\n        }\n\n        // Inclusive is the difference between a and i\n        // TODO: Instead of using the additional text object map to perform text\n        //     object operations, merge the map into the defaultKeyMap and use\n        //     motionArgs to define behavior. Define separate entries for 'aw',\n        //     'iw', 'a[', 'i[', etc.\n        var inclusive = !motionArgs.textObjectInner;\n\n        var tmp, move;\n        if (mirroredPairs[character]) {\n          move = true;\n          tmp = selectCompanionObject(cm, head, character, inclusive);\n          if (!tmp) {\n            var sc = cm.getSearchCursor(new RegExp(\"\\\\\" + character, \"g\"), head)\n            if (sc.find()) {\n              tmp = selectCompanionObject(cm, sc.from(), character, inclusive);\n            }\n          }\n        } else if (selfPaired[character]) {\n          move = true;\n          tmp = findBeginningAndEnd(cm, head, character, inclusive);\n        } else if (character === 'W' || character === 'w') {\n          var repeat = motionArgs.repeat || 1;\n          while (repeat-- > 0) {\n            var repeated = expandWordUnderCursor(cm, {\n              inclusive,\n              innerWord: !inclusive,\n              bigWord: character === 'W',\n              noSymbol: character === 'W',\n              multiline: true\n            }, tmp && tmp.end);\n            if (repeated) {\n              if (!tmp) tmp = repeated;\n              tmp.end = repeated.end;\n            }\n          }\n        } else if (character === 'p') {\n          tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive);\n          motionArgs.linewise = true;\n          if (vim.visualMode) {\n            if (!vim.visualLine) { vim.visualLine = true; }\n          } else {\n            var operatorArgs = vim.inputState.operatorArgs;\n            if (operatorArgs) { operatorArgs.linewise = true; }\n            tmp.end.line--;\n          }\n        } else if (character === 't') {\n          tmp = expandTagUnderCursor(cm, head, inclusive);\n        } else if (character === 's') {\n          // account for cursor on end of sentence symbol\n          var content = cm.getLine(head.line);\n          if (head.ch > 0 && isEndOfSentenceSymbol(content[head.ch])) {\n            head.ch -= 1;\n          }\n          var end = getSentence(cm, head, motionArgs.repeat, 1, inclusive)\n          var start = getSentence(cm, head, motionArgs.repeat, -1, inclusive)\n          // closer vim behaviour, 'a' only takes the space after the sentence if there is one before and after\n          if (isWhiteSpaceString(cm.getLine(start.line)[start.ch])\n              && isWhiteSpaceString(cm.getLine(end.line)[end.ch -1])) {\n            start = {line: start.line, ch: start.ch + 1}\n          }\n          tmp = {start: start, end: end};\n        }\n\n        if (!tmp) {\n          // No valid text object, don't move.\n          return null;\n        }\n\n        if (!cm.state.vim.visualMode) {\n          return [tmp.start, tmp.end];\n        } else {\n          return expandSelection(cm, tmp.start, tmp.end, move);\n        }\n      },\n\n      repeatLastCharacterSearch: function(cm, head, motionArgs) {\n        var lastSearch = vimGlobalState.lastCharacterSearch;\n        var repeat = motionArgs.repeat;\n        var forward = motionArgs.forward === lastSearch.forward;\n        var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);\n        cm.moveH(-increment, 'char');\n        motionArgs.inclusive = forward ? true : false;\n        var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter);\n        if (!curEnd) {\n          cm.moveH(increment, 'char');\n          return head;\n        }\n        curEnd.ch += increment;\n        return curEnd;\n      }\n    };\n\n    function defineMotion(name, fn) {\n      motions[name] = fn;\n    }\n\n    function fillArray(val, times) {\n      var arr = [];\n      for (var i = 0; i < times; i++) {\n        arr.push(val);\n      }\n      return arr;\n    }\n    /**\n     * An operator acts on a text selection. It receives the list of selections\n     * as input. The corresponding CodeMirror selection is guaranteed to\n    * match the input selection.\n     */\n    var operators = {\n      change: function(cm, args, ranges) {\n        var finalHead, text;\n        var vim = cm.state.vim;\n        var anchor = ranges[0].anchor,\n            head = ranges[0].head;\n        if (!vim.visualMode) {\n          text = cm.getRange(anchor, head);\n          var lastState = vim.lastEditInputState || {};\n          if (lastState.motion == \"moveByWords\" && !isWhiteSpaceString(text)) {\n            // Exclude trailing whitespace if the range is not all whitespace.\n            var match = (/\\s+$/).exec(text);\n            if (match && lastState.motionArgs && lastState.motionArgs.forward) {\n              head = offsetCursor(head, 0, - match[0].length);\n              text = text.slice(0, - match[0].length);\n            }\n          }\n          if (args.linewise) {\n            anchor = new Pos(anchor.line, findFirstNonWhiteSpaceCharacter(cm.getLine(anchor.line)));\n            if (head.line > anchor.line) {\n              head = new Pos(head.line - 1, Number.MAX_VALUE)\n            }\n          }\n          cm.replaceRange('', anchor, head);\n          finalHead = anchor;\n        } else if (args.fullLine) {\n            head.ch = Number.MAX_VALUE;\n            head.line--;\n            cm.setSelection(anchor, head)\n            text = cm.getSelection();\n            cm.replaceSelection(\"\");\n            finalHead = anchor;\n        } else {\n          text = cm.getSelection();\n          var replacement = fillArray('', ranges.length);\n          cm.replaceSelections(replacement);\n          finalHead = cursorMin(ranges[0].head, ranges[0].anchor);\n        }\n        vimGlobalState.registerController.pushText(\n            args.registerName, 'change', text,\n            args.linewise, ranges.length > 1);\n        actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim);\n      },\n      // delete is a javascript keyword.\n      'delete': function(cm, args, ranges) {\n        var finalHead, text;\n        var vim = cm.state.vim;\n        if (!vim.visualBlock) {\n          var anchor = ranges[0].anchor,\n              head = ranges[0].head;\n          if (args.linewise &&\n              head.line != cm.firstLine() &&\n              anchor.line == cm.lastLine() &&\n              anchor.line == head.line - 1) {\n            // Special case for dd on last line (and first line).\n            if (anchor.line == cm.firstLine()) {\n              anchor.ch = 0;\n            } else {\n              anchor = new Pos(anchor.line - 1, lineLength(cm, anchor.line - 1));\n            }\n          }\n          text = cm.getRange(anchor, head);\n          cm.replaceRange('', anchor, head);\n          finalHead = anchor;\n          if (args.linewise) {\n            finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor);\n          }\n        } else {\n          text = cm.getSelection();\n          var replacement = fillArray('', ranges.length);\n          cm.replaceSelections(replacement);\n          finalHead = cursorMin(ranges[0].head, ranges[0].anchor);\n        }\n        vimGlobalState.registerController.pushText(\n            args.registerName, 'delete', text,\n            args.linewise, vim.visualBlock);\n        return clipCursorToContent(cm, finalHead);\n      },\n      indent: function(cm, args, ranges) {\n        var vim = cm.state.vim;\n        // In visual mode, n> shifts the selection right n times, instead of\n        // shifting n lines right once.\n        var repeat = (vim.visualMode) ? args.repeat : 1;\n        if (vim.visualBlock) {\n          var tabSize = cm.getOption('tabSize');\n          var indent = cm.getOption('indentWithTabs') ? '\\t' : ' '.repeat(tabSize);\n          var cursor;\n          for (var i = ranges.length - 1; i >= 0; i--) {\n            cursor = cursorMin(ranges[i].anchor, ranges[i].head);\n            if (args.indentRight) {\n              cm.replaceRange(indent.repeat(repeat), cursor, cursor);\n            } else {\n              var text = cm.getLine(cursor.line);\n              var end = 0;\n              for (var j = 0; j < repeat; j++) {\n                var ch = text[cursor.ch + end];\n                if (ch == '\\t') {\n                  end++;\n                } else if (ch == ' ') {\n                  end++;\n                  for (var k = 1; k < indent.length; k++) {\n                    ch = text[cursor.ch + end];\n                    if (ch !== ' ') break;\n                    end++;\n                  }\n                } else {\n                  break\n                }\n              }\n              cm.replaceRange('', cursor, offsetCursor(cursor, 0, end));\n            }\n          }\n          return cursor;\n        } else if (cm.indentMore) {\n          for (var j = 0; j < repeat; j++) {\n            if (args.indentRight) cm.indentMore();\n            else cm.indentLess();\n          }\n        } else {\n          var startLine = ranges[0].anchor.line;\n          var endLine = vim.visualBlock ?\n            ranges[ranges.length - 1].anchor.line :\n            ranges[0].head.line;\n          if (args.linewise) {\n            // The only way to delete a newline is to delete until the start of\n            // the next line, so in linewise mode evalInput will include the next\n            // line. We don't want this in indent, so we go back a line.\n            endLine--;\n          }\n          for (var i = startLine; i <= endLine; i++) {\n            for (var j = 0; j < repeat; j++) {\n              cm.indentLine(i, args.indentRight);\n            }\n          }\n        }\n        return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);\n      },\n      indentAuto: function(cm, _args, ranges) {\n        cm.execCommand(\"indentAuto\");\n        return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);\n      },\n      hardWrap: function(cm, operatorArgs, ranges, oldAnchor, newHead) {\n        if (!cm.hardWrap) return;\n        var from = ranges[0].anchor.line;\n        var to = ranges[0].head.line;\n        if (operatorArgs.linewise) to--;\n        var endRow = cm.hardWrap({from: from, to: to});\n        if (endRow > from && operatorArgs.linewise) endRow--;\n        return operatorArgs.keepCursor ? oldAnchor : new Pos(endRow, 0);\n      },\n      changeCase: function(cm, args, ranges, oldAnchor, newHead) {\n        var selections = cm.getSelections();\n        var swapped = [];\n        var toLower = args.toLower;\n        for (var j = 0; j < selections.length; j++) {\n          var toSwap = selections[j];\n          var text = '';\n          if (toLower === true) {\n            text = toSwap.toLowerCase();\n          } else if (toLower === false) {\n            text = toSwap.toUpperCase();\n          } else {\n            for (var i = 0; i < toSwap.length; i++) {\n              var character = toSwap.charAt(i);\n              text += isUpperCase(character) ? character.toLowerCase() :\n                  character.toUpperCase();\n            }\n          }\n          swapped.push(text);\n        }\n        cm.replaceSelections(swapped);\n        if (args.shouldMoveCursor){\n          return newHead;\n        } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) {\n          return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor);\n        } else if (args.linewise){\n          return oldAnchor;\n        } else {\n          return cursorMin(ranges[0].anchor, ranges[0].head);\n        }\n      },\n      yank: function(cm, args, ranges, oldAnchor) {\n        var vim = cm.state.vim;\n        var text = cm.getSelection();\n        var endPos = vim.visualMode\n          ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor)\n          : oldAnchor;\n        vimGlobalState.registerController.pushText(\n            args.registerName, 'yank',\n            text, args.linewise, vim.visualBlock);\n        return endPos;\n      }\n    };\n\n    function defineOperator(name, fn) {\n      operators[name] = fn;\n    }\n\n    var actions = {\n      jumpListWalk: function(cm, actionArgs, vim) {\n        if (vim.visualMode) {\n          return;\n        }\n        var repeat = actionArgs.repeat;\n        var forward = actionArgs.forward;\n        var jumpList = vimGlobalState.jumpList;\n\n        var mark = jumpList.move(cm, forward ? repeat : -repeat);\n        var markPos = mark ? mark.find() : undefined;\n        markPos = markPos ? markPos : cm.getCursor();\n        cm.setCursor(markPos);\n        cm.ace.curOp.command.scrollIntoView = \"center-animate\"; // ace_patch\n      },\n      scroll: function(cm, actionArgs, vim) {\n        if (vim.visualMode) {\n          return;\n        }\n        var repeat = actionArgs.repeat || 1;\n        var lineHeight = cm.defaultTextHeight();\n        var top = cm.getScrollInfo().top;\n        var delta = lineHeight * repeat;\n        var newPos = actionArgs.forward ? top + delta : top - delta;\n        var cursor = copyCursor(cm.getCursor());\n        var cursorCoords = cm.charCoords(cursor, 'local');\n        if (actionArgs.forward) {\n          if (newPos > cursorCoords.top) {\n             cursor.line += (newPos - cursorCoords.top) / lineHeight;\n             cursor.line = Math.ceil(cursor.line);\n             cm.setCursor(cursor);\n             cursorCoords = cm.charCoords(cursor, 'local');\n             cm.scrollTo(null, cursorCoords.top);\n          } else {\n             // Cursor stays within bounds.  Just reposition the scroll window.\n             cm.scrollTo(null, newPos);\n          }\n        } else {\n          var newBottom = newPos + cm.getScrollInfo().clientHeight;\n          if (newBottom < cursorCoords.bottom) {\n             cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;\n             cursor.line = Math.floor(cursor.line);\n             cm.setCursor(cursor);\n             cursorCoords = cm.charCoords(cursor, 'local');\n             cm.scrollTo(\n                 null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);\n          } else {\n             // Cursor stays within bounds.  Just reposition the scroll window.\n             cm.scrollTo(null, newPos);\n          }\n        }\n      },\n      scrollToCursor: function(cm, actionArgs) {\n        var lineNum = cm.getCursor().line;\n        var charCoords = cm.charCoords(new Pos(lineNum, 0), 'local');\n        var height = cm.getScrollInfo().clientHeight;\n        var y = charCoords.top;\n        switch (actionArgs.position) {\n          case 'center': y = charCoords.bottom - height / 2;\n            break;\n          case 'bottom':\n            var lineLastCharPos = new Pos(lineNum, cm.getLine(lineNum).length - 1);\n            var lineLastCharCoords = cm.charCoords(lineLastCharPos, 'local');\n            var lineHeight = lineLastCharCoords.bottom - y;\n            y = y - height + lineHeight\n            break;\n        }\n        cm.scrollTo(null, y);\n      },\n      replayMacro: function(cm, actionArgs, vim) {\n        var registerName = actionArgs.selectedCharacter;\n        var repeat = actionArgs.repeat;\n        var macroModeState = vimGlobalState.macroModeState;\n        if (registerName == '@') {\n          registerName = macroModeState.latestRegister;\n        } else {\n          macroModeState.latestRegister = registerName;\n        }\n        while(repeat--){\n          executeMacroRegister(cm, vim, macroModeState, registerName);\n        }\n      },\n      enterMacroRecordMode: function(cm, actionArgs) {\n        var macroModeState = vimGlobalState.macroModeState;\n        var registerName = actionArgs.selectedCharacter;\n        if (vimGlobalState.registerController.isValidRegister(registerName)) {\n          macroModeState.enterMacroRecordMode(cm, registerName);\n        }\n      },\n      toggleOverwrite: function(cm) {\n        if (!cm.state.overwrite) {\n          cm.toggleOverwrite(true);\n          cm.setOption('keyMap', 'vim-replace');\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"replace\"});\n        } else {\n          cm.toggleOverwrite(false);\n          cm.setOption('keyMap', 'vim-insert');\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"insert\"});\n        }\n      },\n      enterInsertMode: function(cm, actionArgs, vim) {\n        if (cm.getOption('readOnly')) { return; }\n        vim.insertMode = true;\n        vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1;\n        var insertAt = (actionArgs) ? actionArgs.insertAt : null;\n        var sel = vim.sel;\n        var head = actionArgs.head || cm.getCursor('head');\n        var height = cm.listSelections().length;\n        if (insertAt == 'eol') {\n          head = new Pos(head.line, lineLength(cm, head.line));\n        } else if (insertAt == 'bol') {\n          head = new Pos(head.line, 0);\n        } else if (insertAt == 'charAfter') {\n          var newPosition = updateSelectionForSurrogateCharacters(cm, head, offsetCursor(head, 0, 1));\n          head = newPosition.end;\n        } else if (insertAt == 'firstNonBlank') {\n          var newPosition = updateSelectionForSurrogateCharacters(cm, head, motions.moveToFirstNonWhiteSpaceCharacter(cm, head));\n          head = newPosition.end;\n        } else if (insertAt == 'startOfSelectedArea') {\n          if (!vim.visualMode)\n              return;\n          if (!vim.visualBlock) {\n            if (sel.head.line < sel.anchor.line) {\n              head = sel.head;\n            } else {\n              head = new Pos(sel.anchor.line, 0);\n            }\n          } else {\n            head = new Pos(\n                Math.min(sel.head.line, sel.anchor.line),\n                Math.min(sel.head.ch, sel.anchor.ch));\n            height = Math.abs(sel.head.line - sel.anchor.line) + 1;\n          }\n        } else if (insertAt == 'endOfSelectedArea') {\n            if (!vim.visualMode)\n              return;\n          if (!vim.visualBlock) {\n            if (sel.head.line >= sel.anchor.line) {\n              head = offsetCursor(sel.head, 0, 1);\n            } else {\n              head = new Pos(sel.anchor.line, 0);\n            }\n          } else {\n            head = new Pos(\n                Math.min(sel.head.line, sel.anchor.line),\n                Math.max(sel.head.ch, sel.anchor.ch) + 1);\n            height = Math.abs(sel.head.line - sel.anchor.line) + 1;\n          }\n        } else if (insertAt == 'inplace') {\n          if (vim.visualMode){\n            return;\n          }\n        } else if (insertAt == 'lastEdit') {\n          head = getLastEditPos(cm) || head;\n        }\n        cm.setOption('disableInput', false);\n        if (actionArgs && actionArgs.replace) {\n          // Handle Replace-mode as a special case of insert mode.\n          cm.toggleOverwrite(true);\n          cm.setOption('keyMap', 'vim-replace');\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"replace\"});\n        } else {\n          cm.toggleOverwrite(false);\n          cm.setOption('keyMap', 'vim-insert');\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"insert\"});\n        }\n        if (!vimGlobalState.macroModeState.isPlaying) {\n          // Only record if not replaying.\n          cm.on('change', onChange);\n          if (vim.insertEnd) vim.insertEnd.clear();\n          vim.insertEnd = cm.setBookmark(head, {insertLeft: true});\n          CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);\n        }\n        if (vim.visualMode) {\n          exitVisualMode(cm);\n        }\n        selectForInsert(cm, head, height);\n      },\n      toggleVisualMode: function(cm, actionArgs, vim) {\n        var repeat = actionArgs.repeat;\n        var anchor = cm.getCursor();\n        var head;\n        // TODO: The repeat should actually select number of characters/lines\n        //     equal to the repeat times the size of the previous visual\n        //     operation.\n        if (!vim.visualMode) {\n          // Entering visual mode\n          vim.visualMode = true;\n          vim.visualLine = !!actionArgs.linewise;\n          vim.visualBlock = !!actionArgs.blockwise;\n          head = clipCursorToContent(\n              cm, new Pos(anchor.line, anchor.ch + repeat - 1));\n          var newPosition = updateSelectionForSurrogateCharacters(cm, anchor, head)\n          vim.sel = {\n            anchor: newPosition.start,\n            head: newPosition.end\n          };\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: vim.visualLine ? \"linewise\" : vim.visualBlock ? \"blockwise\" : \"\"});\n          updateCmSelection(cm);\n          updateMark(cm, vim, '<', cursorMin(anchor, head));\n          updateMark(cm, vim, '>', cursorMax(anchor, head));\n        } else if (vim.visualLine ^ actionArgs.linewise ||\n            vim.visualBlock ^ actionArgs.blockwise) {\n          // Toggling between modes\n          vim.visualLine = !!actionArgs.linewise;\n          vim.visualBlock = !!actionArgs.blockwise;\n          CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: vim.visualLine ? \"linewise\" : vim.visualBlock ? \"blockwise\" : \"\"});\n          updateCmSelection(cm);\n        } else {\n          exitVisualMode(cm);\n        }\n      },\n      reselectLastSelection: function(cm, _actionArgs, vim) {\n        var lastSelection = vim.lastSelection;\n        if (vim.visualMode) {\n          updateLastSelection(cm, vim);\n        }\n        if (lastSelection) {\n          var anchor = lastSelection.anchorMark.find();\n          var head = lastSelection.headMark.find();\n          if (!anchor || !head) {\n            // If the marks have been destroyed due to edits, do nothing.\n            return;\n          }\n          vim.sel = {\n            anchor: anchor,\n            head: head\n          };\n          vim.visualMode = true;\n          vim.visualLine = lastSelection.visualLine;\n          vim.visualBlock = lastSelection.visualBlock;\n          updateCmSelection(cm);\n          updateMark(cm, vim, '<', cursorMin(anchor, head));\n          updateMark(cm, vim, '>', cursorMax(anchor, head));\n          CodeMirror.signal(cm, 'vim-mode-change', {\n            mode: 'visual',\n            subMode: vim.visualLine ? 'linewise' :\n                     vim.visualBlock ? 'blockwise' : ''});\n        }\n      },\n      joinLines: function(cm, actionArgs, vim) {\n        var curStart, curEnd;\n        if (vim.visualMode) {\n          curStart = cm.getCursor('anchor');\n          curEnd = cm.getCursor('head');\n          if (cursorIsBefore(curEnd, curStart)) {\n            var tmp = curEnd;\n            curEnd = curStart;\n            curStart = tmp;\n          }\n          curEnd.ch = lineLength(cm, curEnd.line) - 1;\n        } else {\n          // Repeat is the number of lines to join. Minimum 2 lines.\n          var repeat = Math.max(actionArgs.repeat, 2);\n          curStart = cm.getCursor();\n          curEnd = clipCursorToContent(cm, new Pos(curStart.line + repeat - 1,\n                                               Infinity));\n        }\n        var finalCh = 0;\n        for (var i = curStart.line; i < curEnd.line; i++) {\n          finalCh = lineLength(cm, curStart.line);\n          var text = '';\n          var nextStartCh = 0;\n          if (!actionArgs.keepSpaces) {\n            var nextLine = cm.getLine(curStart.line + 1);\n            nextStartCh = nextLine.search(/\\S/);\n            if (nextStartCh == -1) {\n              nextStartCh = nextLine.length;\n            } else {\n              text = \" \";\n            }\n          }\n          cm.replaceRange(text, \n            new Pos(curStart.line, finalCh),\n            new Pos(curStart.line + 1, nextStartCh));\n        }\n        var curFinalPos = clipCursorToContent(cm, new Pos(curStart.line, finalCh));\n        if (vim.visualMode) {\n          exitVisualMode(cm, false);\n        }\n        cm.setCursor(curFinalPos);\n      },\n      newLineAndEnterInsertMode: function(cm, actionArgs, vim) {\n        vim.insertMode = true;\n        var insertAt = copyCursor(cm.getCursor());\n        if (insertAt.line === cm.firstLine() && !actionArgs.after) {\n          // Special case for inserting newline before start of document.\n          cm.replaceRange('\\n', new Pos(cm.firstLine(), 0));\n          cm.setCursor(cm.firstLine(), 0);\n        } else {\n          insertAt.line = (actionArgs.after) ? insertAt.line :\n              insertAt.line - 1;\n          insertAt.ch = lineLength(cm, insertAt.line);\n          cm.setCursor(insertAt);\n          var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment ||\n              CodeMirror.commands.newlineAndIndent;\n          newlineFn(cm);\n        }\n        this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);\n      },\n      paste: function(cm, actionArgs, vim) {\n        var register = vimGlobalState.registerController.getRegister(\n            actionArgs.registerName);\n        var fallback = () => {\n          var text = register.toString();\n          this.continuePaste(cm, actionArgs, vim, text, register);\n        }\n        if (actionArgs.registerName === '+' &&\n              typeof navigator !== 'undefined' &&\n              typeof navigator.clipboard !== 'undefined' &&\n              typeof navigator.clipboard.readText === 'function') {\n          navigator.clipboard.readText().then((value) => {\n            this.continuePaste(cm, actionArgs, vim, value, register);\n          }, () => { fallback() })\n        } else {\n          fallback()\n        }\n      },\n      continuePaste: function(cm, actionArgs, vim, text, register) {\n        var cur = copyCursor(cm.getCursor());\n        if (!text) {\n          return;\n        }\n        if (actionArgs.matchIndent) {\n          var tabSize = cm.getOption(\"tabSize\");\n          // length that considers tabs and tabSize\n          var whitespaceLength = function(str) {\n            var tabs = (str.split(\"\\t\").length - 1);\n            var spaces = (str.split(\" \").length - 1);\n            return tabs * tabSize + spaces * 1;\n          };\n          var currentLine = cm.getLine(cm.getCursor().line);\n          var indent = whitespaceLength(currentLine.match(/^\\s*/)[0]);\n          // chomp last newline b/c don't want it to match /^\\s*/gm\n          var chompedText = text.replace(/\\n$/, '');\n          var wasChomped = text !== chompedText;\n          var firstIndent = whitespaceLength(text.match(/^\\s*/)[0]);\n          var text = chompedText.replace(/^\\s*/gm, function(wspace) {\n            var newIndent = indent + (whitespaceLength(wspace) - firstIndent);\n            if (newIndent < 0) {\n              return \"\";\n            }\n            else if (cm.getOption(\"indentWithTabs\")) {\n              var quotient = Math.floor(newIndent / tabSize);\n              return Array(quotient + 1).join('\\t');\n            }\n            else {\n              return Array(newIndent + 1).join(' ');\n            }\n          });\n          text += wasChomped ? \"\\n\" : \"\";\n        }\n        if (actionArgs.repeat > 1) {\n          var text = Array(actionArgs.repeat + 1).join(text);\n        }\n        var linewise = register.linewise;\n        var blockwise = register.blockwise;\n        if (blockwise) {\n          text = text.split('\\n');\n          if (linewise) {\n            text.pop();\n          }\n          for (var i = 0; i < text.length; i++) {\n            text[i] = (text[i] == '') ? ' ' : text[i];\n          }\n          cur.ch += actionArgs.after ? 1 : 0;\n          cur.ch = Math.min(lineLength(cm, cur.line), cur.ch);\n        } else if (linewise) {\n          if(vim.visualMode) {\n            text = vim.visualLine ? text.slice(0, -1) : '\\n' + text.slice(0, text.length - 1) + '\\n';\n          } else if (actionArgs.after) {\n            // Move the newline at the end to the start instead, and paste just\n            // before the newline character of the line we are on right now.\n            text = '\\n' + text.slice(0, text.length - 1);\n            cur.ch = lineLength(cm, cur.line);\n          } else {\n            cur.ch = 0;\n          }\n        } else {\n          cur.ch += actionArgs.after ? 1 : 0;\n        }\n        var curPosFinal;\n        if (vim.visualMode) {\n          //  save the pasted text for reselection if the need arises\n          vim.lastPastedText = text;\n          var lastSelectionCurEnd;\n          var selectedArea = getSelectedAreaRange(cm, vim);\n          var selectionStart = selectedArea[0];\n          var selectionEnd = selectedArea[1];\n          var selectedText = cm.getSelection();\n          var selections = cm.listSelections();\n          var emptyStrings = new Array(selections.length).join('1').split('1');\n          // save the curEnd marker before it get cleared due to cm.replaceRange.\n          if (vim.lastSelection) {\n            lastSelectionCurEnd = vim.lastSelection.headMark.find();\n          }\n          // push the previously selected text to unnamed register\n          vimGlobalState.registerController.unnamedRegister.setText(selectedText);\n          if (blockwise) {\n            // first delete the selected text\n            cm.replaceSelections(emptyStrings);\n            // Set new selections as per the block length of the yanked text\n            selectionEnd = new Pos(selectionStart.line + text.length-1, selectionStart.ch);\n            cm.setCursor(selectionStart);\n            selectBlock(cm, selectionEnd);\n            cm.replaceSelections(text);\n            curPosFinal = selectionStart;\n          } else if (vim.visualBlock) {\n            cm.replaceSelections(emptyStrings);\n            cm.setCursor(selectionStart);\n            cm.replaceRange(text, selectionStart, selectionStart);\n            curPosFinal = selectionStart;\n          } else {\n            cm.replaceRange(text, selectionStart, selectionEnd);\n            curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1);\n          }\n          // restore the the curEnd marker\n          if(lastSelectionCurEnd) {\n            vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd);\n          }\n          if (linewise) {\n            curPosFinal.ch=0;\n          }\n        } else {\n          if (blockwise) {\n            cm.setCursor(cur);\n            for (var i = 0; i < text.length; i++) {\n              var line = cur.line+i;\n              if (line > cm.lastLine()) {\n                cm.replaceRange('\\n',  new Pos(line, 0));\n              }\n              var lastCh = lineLength(cm, line);\n              if (lastCh < cur.ch) {\n                extendLineToColumn(cm, line, cur.ch);\n              }\n            }\n            cm.setCursor(cur);\n            selectBlock(cm, new Pos(cur.line + text.length-1, cur.ch));\n            cm.replaceSelections(text);\n            curPosFinal = cur;\n          } else {\n            cm.replaceRange(text, cur);\n            // Now fine tune the cursor to where we want it.\n            if (linewise) {\n              var line = actionArgs.after ? cur.line + 1 : cur.line;\n              curPosFinal = new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n            } else {\n              curPosFinal = copyCursor(cur);\n              if (!/\\n/.test(text)) {\n                curPosFinal.ch += text.length - (actionArgs.after ? 1 : 0);\n              }\n            }\n          }\n        }\n        if (vim.visualMode) {\n          exitVisualMode(cm, false);\n        }\n        cm.setCursor(curPosFinal);\n      },\n      undo: function(cm, actionArgs) {\n        cm.operation(function() {\n          repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)();\n          cm.setCursor(clipCursorToContent(cm, cm.getCursor('start')));\n        });\n      },\n      redo: function(cm, actionArgs) {\n        repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)();\n      },\n      setRegister: function(_cm, actionArgs, vim) {\n        vim.inputState.registerName = actionArgs.selectedCharacter;\n      },\n      insertRegister: function(cm, actionArgs, vim) {\n        var registerName = actionArgs.selectedCharacter;\n        var register = vimGlobalState.registerController.getRegister(registerName);\n        var text = register && register.toString();\n        if (text) {\n          cm.replaceSelection(text);\n        }\n      },\n      oneNormalCommand: function(cm, actionArgs, vim) {\n        exitInsertMode(cm, true);\n        vim.insertModeReturn = true;\n        CodeMirror.on(cm, 'vim-command-done', function handler() {\n          if (vim.visualMode) return;\n          if (vim.insertModeReturn) {\n            vim.insertModeReturn = false;\n            if (!vim.insertMode) {\n              actions.enterInsertMode(cm, {}, vim);\n            }\n          }\n          CodeMirror.off(cm, 'vim-command-done', handler);\n        });\n      },\n      setMark: function(cm, actionArgs, vim) {\n        var markName = actionArgs.selectedCharacter;\n        updateMark(cm, vim, markName, cm.getCursor());\n      },\n      replace: function(cm, actionArgs, vim) {\n        var replaceWith = actionArgs.selectedCharacter;\n        var curStart = cm.getCursor();\n        var replaceTo;\n        var curEnd;\n        var selections = cm.listSelections();\n        if (vim.visualMode) {\n          curStart = cm.getCursor('start');\n          curEnd = cm.getCursor('end');\n        } else {\n          var line = cm.getLine(curStart.line);\n          replaceTo = curStart.ch + actionArgs.repeat;\n          if (replaceTo > line.length) {\n            replaceTo=line.length;\n          }\n          curEnd = new Pos(curStart.line, replaceTo);\n        }\n\n        var newPositions = updateSelectionForSurrogateCharacters(cm, curStart, curEnd);\n        curStart = newPositions.start;\n        curEnd = newPositions.end;\n        if (replaceWith=='\\n') {\n          if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);\n          // special case, where vim help says to replace by just one line-break\n          (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm);\n        } else {\n          var replaceWithStr = cm.getRange(curStart, curEnd);\n          // replace all surrogate characters with selected character\n          replaceWithStr = replaceWithStr.replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, replaceWith);\n          //replace all characters in range by selected, but keep linebreaks\n          replaceWithStr = replaceWithStr.replace(/[^\\n]/g, replaceWith);\n          if (vim.visualBlock) {\n            // Tabs are split in visua block before replacing\n            var spaces = new Array(cm.getOption(\"tabSize\")+1).join(' ');\n            replaceWithStr = cm.getSelection();\n            replaceWithStr = replaceWithStr.replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, replaceWith);\n            replaceWithStr = replaceWithStr.replace(/\\t/g, spaces).replace(/[^\\n]/g, replaceWith).split('\\n');\n            cm.replaceSelections(replaceWithStr);\n          } else {\n            cm.replaceRange(replaceWithStr, curStart, curEnd);\n          }\n          if (vim.visualMode) {\n            curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?\n                         selections[0].anchor : selections[0].head;\n            cm.setCursor(curStart);\n            exitVisualMode(cm, false);\n          } else {\n            cm.setCursor(offsetCursor(curEnd, 0, -1));\n          }\n        }\n      },\n      incrementNumberToken: function(cm, actionArgs) {\n        var cur = cm.getCursor();\n        var lineStr = cm.getLine(cur.line);\n        var re = /(-?)(?:(0x)([\\da-f]+)|(0b|0|)(\\d+))/gi;\n        var match;\n        var start;\n        var end;\n        var numberStr;\n        while ((match = re.exec(lineStr)) !== null) {\n          start = match.index;\n          end = start + match[0].length;\n          if (cur.ch < end)break;\n        }\n        if (!actionArgs.backtrack && (end <= cur.ch))return;\n        if (match) {\n          var baseStr = match[2] || match[4]\n          var digits = match[3] || match[5]\n          var increment = actionArgs.increase ? 1 : -1;\n          var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];\n          var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);\n          numberStr = number.toString(base);\n          var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''\n          if (numberStr.charAt(0) === '-') {\n            numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);\n          } else {\n            numberStr = baseStr + zeroPadding + numberStr;\n          }\n          var from = new Pos(cur.line, start);\n          var to = new Pos(cur.line, end);\n          cm.replaceRange(numberStr, from, to);\n        } else {\n          return;\n        }\n        cm.setCursor(new Pos(cur.line, start + numberStr.length - 1));\n      },\n      repeatLastEdit: function(cm, actionArgs, vim) {\n        var lastEditInputState = vim.lastEditInputState;\n        if (!lastEditInputState) { return; }\n        var repeat = actionArgs.repeat;\n        if (repeat && actionArgs.repeatIsExplicit) {\n          vim.lastEditInputState.repeatOverride = repeat;\n        } else {\n          repeat = vim.lastEditInputState.repeatOverride || repeat;\n        }\n        repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */);\n      },\n      indent: function(cm, actionArgs) {\n        cm.indentLine(cm.getCursor().line, actionArgs.indentRight);\n      },\n      exitInsertMode: exitInsertMode\n    };\n\n    function defineAction(name, fn) {\n      actions[name] = fn;\n    }\n\n    /*\n     * Below are miscellaneous utility functions used by vim.js\n     */\n\n    /**\n     * Clips cursor to ensure that line is within the buffer's range\n     * and is not inside surrogate pair\n     * If includeLineBreak is true, then allow cur.ch == lineLength.\n     */\n    function clipCursorToContent(cm, cur, oldCur) {\n      var vim = cm.state.vim;\n      var includeLineBreak = vim.insertMode || vim.visualMode;\n      var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );\n      var text = cm.getLine(line);\n      var maxCh = text.length - 1 + Number(!!includeLineBreak);\n      var ch = Math.min(Math.max(0, cur.ch), maxCh);\n      // prevent cursor from entering surrogate pair\n      var charCode = text.charCodeAt(ch);\n      if (0xDC00 <= charCode && charCode <= 0xDFFF) {\n        var direction = 1;\n        if (oldCur && oldCur.line == line && oldCur.ch > ch) {\n          direction = -1;\n        }\n        ch +=direction;\n        if (ch > maxCh) ch -=2;\n      }\n      return new Pos(line, ch);\n    }\n    function copyArgs(args) {\n      var ret = {};\n      for (var prop in args) {\n        if (args.hasOwnProperty(prop)) {\n          ret[prop] = args[prop];\n        }\n      }\n      return ret;\n    }\n    function offsetCursor(cur, offsetLine, offsetCh) {\n      if (typeof offsetLine === 'object') {\n        offsetCh = offsetLine.ch;\n        offsetLine = offsetLine.line;\n      }\n      return new Pos(cur.line + offsetLine, cur.ch + offsetCh);\n    }\n    function commandMatches(keys, keyMap, context, inputState) {\n      // Partial matches are not applied. They inform the key handler\n      // that the current key sequence is a subsequence of a valid key\n      // sequence, so that the key buffer is not cleared.\n      if (inputState.operator) context = \"operatorPending\";\n      var match, partial = [], full = [];\n      // if currently expanded key comes from a noremap, searcg only in default keys\n      var startIndex = noremap ? keyMap.length - defaultKeymapLength : 0;\n      for (var i = startIndex; i < keyMap.length; i++) {\n        var command = keyMap[i];\n        if (context == 'insert' && command.context != 'insert' ||\n            (command.context && command.context != context) ||\n            inputState.operator && command.type == 'action' ||\n            !(match = commandMatch(keys, command.keys))) { continue; }\n        if (match == 'partial') { partial.push(command); }\n        if (match == 'full') { full.push(command); }\n      }\n      return {\n        partial: partial.length && partial,\n        full: full.length && full\n      };\n    }\n    function commandMatch(pressed, mapped) {\n      const isLastCharacter = mapped.slice(-11) == '<character>';\n      const isLastRegister = mapped.slice(-10) == '<register>';\n      if (isLastCharacter || isLastRegister) {\n        // Last character matches anything.\n        var prefixLen = mapped.length - (isLastCharacter ? 11 : 10);\n        var pressedPrefix = pressed.slice(0, prefixLen);\n        var mappedPrefix = mapped.slice(0, prefixLen);\n        return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' :\n               mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false;\n      } else {\n        return pressed == mapped ? 'full' :\n               mapped.indexOf(pressed) == 0 ? 'partial' : false;\n      }\n    }\n    function lastChar(keys) {\n      var match = /^.*(<[^>]+>)$/.exec(keys);\n      var selectedCharacter = match ? match[1] : keys.slice(-1);\n      if (selectedCharacter.length > 1){\n        switch(selectedCharacter){\n          case '<CR>':\n            selectedCharacter='\\n';\n            break;\n          case '<Space>':\n            selectedCharacter=' ';\n            break;\n          default:\n            selectedCharacter='';\n            break;\n        }\n      }\n      return selectedCharacter;\n    }\n    function repeatFn(cm, fn, repeat) {\n      return function() {\n        for (var i = 0; i < repeat; i++) {\n          fn(cm);\n        }\n      };\n    }\n    function copyCursor(cur) {\n      return new Pos(cur.line, cur.ch);\n    }\n    function cursorEqual(cur1, cur2) {\n      return cur1.ch == cur2.ch && cur1.line == cur2.line;\n    }\n    function cursorIsBefore(cur1, cur2) {\n      if (cur1.line < cur2.line) {\n        return true;\n      }\n      if (cur1.line == cur2.line && cur1.ch < cur2.ch) {\n        return true;\n      }\n      return false;\n    }\n    function cursorMin(cur1, cur2) {\n      if (arguments.length > 2) {\n        cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1));\n      }\n      return cursorIsBefore(cur1, cur2) ? cur1 : cur2;\n    }\n    function cursorMax(cur1, cur2) {\n      if (arguments.length > 2) {\n        cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1));\n      }\n      return cursorIsBefore(cur1, cur2) ? cur2 : cur1;\n    }\n    function cursorIsBetween(cur1, cur2, cur3) {\n      // returns true if cur2 is between cur1 and cur3.\n      var cur1before2 = cursorIsBefore(cur1, cur2);\n      var cur2before3 = cursorIsBefore(cur2, cur3);\n      return cur1before2 && cur2before3;\n    }\n    function lineLength(cm, lineNum) {\n      return cm.getLine(lineNum).length;\n    }\n    function trim(s) {\n      if (s.trim) {\n        return s.trim();\n      }\n      return s.replace(/^\\s+|\\s+$/g, '');\n    }\n    function escapeRegex(s) {\n      return s.replace(/([.?*+$\\[\\]\\/\\\\(){}|\\-])/g, '\\\\$1');\n    }\n    function extendLineToColumn(cm, lineNum, column) {\n      var endCh = lineLength(cm, lineNum);\n      var spaces = new Array(column-endCh+1).join(' ');\n      cm.setCursor(new Pos(lineNum, endCh));\n      cm.replaceRange(spaces, cm.getCursor());\n    }\n    // This functions selects a rectangular block\n    // of text with selectionEnd as any of its corner\n    // Height of block:\n    // Difference in selectionEnd.line and first/last selection.line\n    // Width of the block:\n    // Distance between selectionEnd.ch and any(first considered here) selection.ch\n    function selectBlock(cm, selectionEnd) {\n      var selections = [], ranges = cm.listSelections();\n      var head = copyCursor(cm.clipPos(selectionEnd));\n      var isClipped = !cursorEqual(selectionEnd, head);\n      var curHead = cm.getCursor('head');\n      var primIndex = getIndex(ranges, curHead);\n      var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor);\n      var max = ranges.length - 1;\n      var index = max - primIndex > primIndex ? max : 0;\n      var base = ranges[index].anchor;\n\n      var firstLine = Math.min(base.line, head.line);\n      var lastLine = Math.max(base.line, head.line);\n      var baseCh = base.ch, headCh = head.ch;\n\n      var dir = ranges[index].head.ch - baseCh;\n      var newDir = headCh - baseCh;\n      if (dir > 0 && newDir <= 0) {\n        baseCh++;\n        if (!isClipped) { headCh--; }\n      } else if (dir < 0 && newDir >= 0) {\n        baseCh--;\n        if (!wasClipped) { headCh++; }\n      } else if (dir < 0 && newDir == -1) {\n        baseCh--;\n        headCh++;\n      }\n      for (var line = firstLine; line <= lastLine; line++) {\n        var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)};\n        selections.push(range);\n      }\n      cm.setSelections(selections);\n      selectionEnd.ch = headCh;\n      base.ch = baseCh;\n      return base;\n    }\n    function selectForInsert(cm, head, height) {\n      var sel = [];\n      for (var i = 0; i < height; i++) {\n        var lineHead = offsetCursor(head, i, 0);\n        sel.push({anchor: lineHead, head: lineHead});\n      }\n      cm.setSelections(sel, 0);\n    }\n    // getIndex returns the index of the cursor in the selections.\n    function getIndex(ranges, cursor, end) {\n      for (var i = 0; i < ranges.length; i++) {\n        var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor);\n        var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor);\n        if (atAnchor || atHead) {\n          return i;\n        }\n      }\n      return -1;\n    }\n    function getSelectedAreaRange(cm, vim) {\n      var lastSelection = vim.lastSelection;\n      var getCurrentSelectedAreaRange = function() {\n        var selections = cm.listSelections();\n        var start =  selections[0];\n        var end = selections[selections.length-1];\n        var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head;\n        var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor;\n        return [selectionStart, selectionEnd];\n      };\n      var getLastSelectedAreaRange = function() {\n        var selectionStart = cm.getCursor();\n        var selectionEnd = cm.getCursor();\n        var block = lastSelection.visualBlock;\n        if (block) {\n          var width = block.width;\n          var height = block.height;\n          selectionEnd = new Pos(selectionStart.line + height, selectionStart.ch + width);\n          var selections = [];\n          // selectBlock creates a 'proper' rectangular block.\n          // We do not want that in all cases, so we manually set selections.\n          for (var i = selectionStart.line; i < selectionEnd.line; i++) {\n            var anchor = new Pos(i, selectionStart.ch);\n            var head = new Pos(i, selectionEnd.ch);\n            var range = {anchor: anchor, head: head};\n            selections.push(range);\n          }\n          cm.setSelections(selections);\n        } else {\n          var start = lastSelection.anchorMark.find();\n          var end = lastSelection.headMark.find();\n          var line = end.line - start.line;\n          var ch = end.ch - start.ch;\n          selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch};\n          if (lastSelection.visualLine) {\n            selectionStart = new Pos(selectionStart.line, 0);\n            selectionEnd = new Pos(selectionEnd.line, lineLength(cm, selectionEnd.line));\n          }\n          cm.setSelection(selectionStart, selectionEnd);\n        }\n        return [selectionStart, selectionEnd];\n      };\n      if (!vim.visualMode) {\n      // In case of replaying the action.\n        return getLastSelectedAreaRange();\n      } else {\n        return getCurrentSelectedAreaRange();\n      }\n    }\n    // Updates the previous selection with the current selection's values. This\n    // should only be called in visual mode.\n    function updateLastSelection(cm, vim) {\n      var anchor = vim.sel.anchor;\n      var head = vim.sel.head;\n      // To accommodate the effect of lastPastedText in the last selection\n      if (vim.lastPastedText) {\n        head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length);\n        vim.lastPastedText = null;\n      }\n      vim.lastSelection = {'anchorMark': cm.setBookmark(anchor),\n                           'headMark': cm.setBookmark(head),\n                           'anchor': copyCursor(anchor),\n                           'head': copyCursor(head),\n                           'visualMode': vim.visualMode,\n                           'visualLine': vim.visualLine,\n                           'visualBlock': vim.visualBlock};\n    }\n    function expandSelection(cm, start, end, move) {\n      var sel = cm.state.vim.sel;\n      var head = move ? start: sel.head;\n      var anchor = move ? start: sel.anchor;\n      var tmp;\n      if (cursorIsBefore(end, start)) {\n        tmp = end;\n        end = start;\n        start = tmp;\n      }\n      if (cursorIsBefore(head, anchor)) {\n        head = cursorMin(start, head);\n        anchor = cursorMax(anchor, end);\n      } else {\n        anchor = cursorMin(start, anchor);\n        head = cursorMax(head, end);\n        head = offsetCursor(head, 0, -1);\n        if (head.ch == -1 && head.line != cm.firstLine()) {\n          head = new Pos(head.line - 1, lineLength(cm, head.line - 1));\n        }\n      }\n      return [anchor, head];\n    }\n    /**\n     * Updates the CodeMirror selection to match the provided vim selection.\n     * If no arguments are given, it uses the current vim selection state.\n     */\n    function updateCmSelection(cm, sel, mode) {\n      var vim = cm.state.vim;\n      sel = sel || vim.sel;\n      var mode = mode ||\n        vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char';\n      var cmSel = makeCmSelection(cm, sel, mode);\n      cm.setSelections(cmSel.ranges, cmSel.primary);\n    }\n    function makeCmSelection(cm, sel, mode, exclusive) {\n      var head = copyCursor(sel.head);\n      var anchor = copyCursor(sel.anchor);\n      if (mode == 'char') {\n        var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;\n        var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;\n        head = offsetCursor(sel.head, 0, headOffset);\n        anchor = offsetCursor(sel.anchor, 0, anchorOffset);\n        return {\n          ranges: [{anchor: anchor, head: head}],\n          primary: 0\n        };\n      } else if (mode == 'line') {\n        if (!cursorIsBefore(sel.head, sel.anchor)) {\n          anchor.ch = 0;\n\n          var lastLine = cm.lastLine();\n          if (head.line > lastLine) {\n            head.line = lastLine;\n          }\n          head.ch = lineLength(cm, head.line);\n        } else {\n          head.ch = 0;\n          anchor.ch = lineLength(cm, anchor.line);\n        }\n        return {\n          ranges: [{anchor: anchor, head: head}],\n          primary: 0\n        };\n      } else if (mode == 'block') {\n        var top = Math.min(anchor.line, head.line),\n            fromCh = anchor.ch,\n            bottom = Math.max(anchor.line, head.line),\n            toCh = head.ch;\n        if (fromCh < toCh) { toCh += 1 }\n        else { fromCh += 1 };\n        var height = bottom - top + 1;\n        var primary = head.line == top ? 0 : height - 1;\n        var ranges = [];\n        for (var i = 0; i < height; i++) {\n          ranges.push({\n            anchor: new Pos(top + i, fromCh),\n            head: new Pos(top + i, toCh)\n          });\n        }\n        return {\n          ranges: ranges,\n          primary: primary\n        };\n      }\n    }\n    function getHead(cm) {\n      var cur = cm.getCursor('head');\n      if (cm.getSelection().length == 1) {\n        // Small corner case when only 1 character is selected. The \"real\"\n        // head is the left of head and anchor.\n        cur = cursorMin(cur, cm.getCursor('anchor'));\n      }\n      return cur;\n    }\n\n    /**\n     * If moveHead is set to false, the CodeMirror selection will not be\n     * touched. The caller assumes the responsibility of putting the cursor\n    * in the right place.\n     */\n    function exitVisualMode(cm, moveHead) {\n      var vim = cm.state.vim;\n      if (moveHead !== false) {\n        cm.setCursor(clipCursorToContent(cm, vim.sel.head));\n      }\n      updateLastSelection(cm, vim);\n      vim.visualMode = false;\n      vim.visualLine = false;\n      vim.visualBlock = false;\n      if (!vim.insertMode) CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n    }\n\n    // Remove any trailing newlines from the selection. For\n    // example, with the caret at the start of the last word on the line,\n    // 'dw' should word, but not the newline, while 'w' should advance the\n    // caret to the first character of the next line.\n    function clipToLine(cm, curStart, curEnd) {\n      var selection = cm.getRange(curStart, curEnd);\n      // Only clip if the selection ends with trailing newline + whitespace\n      if (/\\n\\s*$/.test(selection)) {\n        var lines = selection.split('\\n');\n        // We know this is all whitespace.\n        lines.pop();\n\n        // Cases:\n        // 1. Last word is an empty line - do not clip the trailing '\\n'\n        // 2. Last word is not an empty line - clip the trailing '\\n'\n        var line;\n        // Find the line containing the last word, and clip all whitespace up\n        // to it.\n        for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) {\n          curEnd.line--;\n          curEnd.ch = 0;\n        }\n        // If the last word is not an empty line, clip an additional newline\n        if (line) {\n          curEnd.line--;\n          curEnd.ch = lineLength(cm, curEnd.line);\n        } else {\n          curEnd.ch = 0;\n        }\n      }\n    }\n\n    // Expand the selection to line ends.\n    function expandSelectionToLine(_cm, curStart, curEnd) {\n      curStart.ch = 0;\n      curEnd.ch = 0;\n      curEnd.line++;\n    }\n\n    function findFirstNonWhiteSpaceCharacter(text) {\n      if (!text) {\n        return 0;\n      }\n      var firstNonWS = text.search(/\\S/);\n      return firstNonWS == -1 ? text.length : firstNonWS;\n    }\n\n    function expandWordUnderCursor(cm, {inclusive, innerWord, bigWord, noSymbol, multiline}, cursor) {\n      var cur = cursor || getHead(cm);\n      var line = cm.getLine(cur.line);\n      var endLine = line;\n      var startLineNumber = cur.line\n      var endLineNumber = startLineNumber;\n      var idx = cur.ch;\n\n      var wordOnNextLine;\n      // Seek to first word or non-whitespace character, depending on if\n      // noSymbol is true.\n      var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0];\n      if (innerWord && /\\s/.test(line.charAt(idx))) {\n        test = function(ch) { return /\\s/.test(ch); };\n      } else {\n        while (!test(line.charAt(idx))) {\n          idx++;\n          if (idx >= line.length) {\n            if (!multiline) return null;\n            idx--;\n            wordOnNextLine = findWord(cm, cur, true, bigWord, true);\n            break\n          }\n        }\n\n        if (bigWord) {\n          test = bigWordCharTest[0];\n        } else {\n          test = wordCharTest[0];\n          if (!test(line.charAt(idx))) {\n            test = wordCharTest[1];\n          }\n        }\n      }\n\n      var end = idx, start = idx;\n      while (test(line.charAt(start)) && start >= 0) { start--; }\n      start++;\n      if (wordOnNextLine) {\n        end = wordOnNextLine.to;\n        endLineNumber = wordOnNextLine.line;\n        endLine = cm.getLine(endLineNumber);\n        if (!endLine && end == 0) end++;\n      } else {\n        while (test(line.charAt(end)) && end < line.length) { end++; }\n      }\n\n      if (inclusive) {\n        // If present, include all whitespace after word.\n        // Otherwise, include all whitespace before word, except indentation.\n        var wordEnd = end;\n        var startsWithSpace = cur.ch <= start && /\\s/.test(line.charAt(cur.ch));\n        if (!startsWithSpace) {\n          while (/\\s/.test(endLine.charAt(end)) && end < endLine.length) { end++; }\n        }\n        if (wordEnd == end || startsWithSpace) {\n          var wordStart = start;\n          while (/\\s/.test(line.charAt(start - 1)) && start > 0) { start--; }\n          if (!start && !startsWithSpace) { start = wordStart; }\n        }\n      }\n\n      return { start: new Pos(startLineNumber, start), end: new Pos(endLineNumber, end) };\n    }\n\n    /**\n     * Depends on the following:\n     *\n     * - editor mode should be htmlmixedmode / xml\n     * - mode/xml/xml.js should be loaded\n     * - addon/fold/xml-fold.js should be loaded\n     *\n     * If any of the above requirements are not true, this function noops.\n     *\n     * This is _NOT_ a 100% accurate implementation of vim tag text objects.\n     * The following caveats apply (based off cursory testing, I'm sure there\n     * are other discrepancies):\n     *\n     * - Does not work inside comments:\n     *   ```\n     *   <!-- <div>broken</div> -->\n     *   ```\n     * - Does not work when tags have different cases:\n     *   ```\n     *   <div>broken</DIV>\n     *   ```\n     * - Does not work when cursor is inside a broken tag:\n     *   ```\n     *   <div><brok><en></div>\n     *   ```\n     */\n    function expandTagUnderCursor(cm, head, inclusive) {\n      var cur = head;\n      if (!CodeMirror.findMatchingTag || !CodeMirror.findEnclosingTag) {\n        return { start: cur, end: cur };\n      }\n\n      var tags = CodeMirror.findMatchingTag(cm, head) || CodeMirror.findEnclosingTag(cm, head);\n      if (!tags || !tags.open || !tags.close) {\n        return { start: cur, end: cur };\n      }\n\n      if (inclusive) {\n        return { start: tags.open.from, end: tags.close.to };\n      }\n      return { start: tags.open.to, end: tags.close.from };\n    }\n\n    function recordJumpPosition(cm, oldCur, newCur) {\n      if (!cursorEqual(oldCur, newCur)) {\n        vimGlobalState.jumpList.add(cm, oldCur, newCur);\n      }\n    }\n\n    function recordLastCharacterSearch(increment, args) {\n        vimGlobalState.lastCharacterSearch.increment = increment;\n        vimGlobalState.lastCharacterSearch.forward = args.forward;\n        vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter;\n    }\n\n    var symbolToMode = {\n        '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket',\n        '[': 'section', ']': 'section',\n        '*': 'comment', '/': 'comment',\n        'm': 'method', 'M': 'method',\n        '#': 'preprocess'\n    };\n    var findSymbolModes = {\n      bracket: {\n        isComplete: function(state) {\n          if (state.nextCh === state.symb) {\n            state.depth++;\n            if (state.depth >= 1)return true;\n          } else if (state.nextCh === state.reverseSymb) {\n            state.depth--;\n          }\n          return false;\n        }\n      },\n      section: {\n        init: function(state) {\n          state.curMoveThrough = true;\n          state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}';\n        },\n        isComplete: function(state) {\n          return state.index === 0 && state.nextCh === state.symb;\n        }\n      },\n      comment: {\n        isComplete: function(state) {\n          var found = state.lastCh === '*' && state.nextCh === '/';\n          state.lastCh = state.nextCh;\n          return found;\n        }\n      },\n      // TODO: The original Vim implementation only operates on level 1 and 2.\n      // The current implementation doesn't check for code block level and\n      // therefore it operates on any levels.\n      method: {\n        init: function(state) {\n          state.symb = (state.symb === 'm' ? '{' : '}');\n          state.reverseSymb = state.symb === '{' ? '}' : '{';\n        },\n        isComplete: function(state) {\n          if (state.nextCh === state.symb)return true;\n          return false;\n        }\n      },\n      preprocess: {\n        init: function(state) {\n          state.index = 0;\n        },\n        isComplete: function(state) {\n          if (state.nextCh === '#') {\n            var token = state.lineText.match(/^#(\\w+)/)[1];\n            if (token === 'endif') {\n              if (state.forward && state.depth === 0) {\n                return true;\n              }\n              state.depth++;\n            } else if (token === 'if') {\n              if (!state.forward && state.depth === 0) {\n                return true;\n              }\n              state.depth--;\n            }\n            if (token === 'else' && state.depth === 0)return true;\n          }\n          return false;\n        }\n      }\n    };\n    function findSymbol(cm, repeat, forward, symb) {\n      var cur = copyCursor(cm.getCursor());\n      var increment = forward ? 1 : -1;\n      var endLine = forward ? cm.lineCount() : -1;\n      var curCh = cur.ch;\n      var line = cur.line;\n      var lineText = cm.getLine(line);\n      var state = {\n        lineText: lineText,\n        nextCh: lineText.charAt(curCh),\n        lastCh: null,\n        index: curCh,\n        symb: symb,\n        reverseSymb: (forward ?  { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb],\n        forward: forward,\n        depth: 0,\n        curMoveThrough: false\n      };\n      var mode = symbolToMode[symb];\n      if (!mode)return cur;\n      var init = findSymbolModes[mode].init;\n      var isComplete = findSymbolModes[mode].isComplete;\n      if (init) { init(state); }\n      while (line !== endLine && repeat) {\n        state.index += increment;\n        state.nextCh = state.lineText.charAt(state.index);\n        if (!state.nextCh) {\n          line += increment;\n          state.lineText = cm.getLine(line) || '';\n          if (increment > 0) {\n            state.index = 0;\n          } else {\n            var lineLen = state.lineText.length;\n            state.index = (lineLen > 0) ? (lineLen-1) : 0;\n          }\n          state.nextCh = state.lineText.charAt(state.index);\n        }\n        if (isComplete(state)) {\n          cur.line = line;\n          cur.ch = state.index;\n          repeat--;\n        }\n      }\n      if (state.nextCh || state.curMoveThrough) {\n        return new Pos(line, state.index);\n      }\n      return cur;\n    }\n\n    /*\n     * Returns the boundaries of the next word. If the cursor in the middle of\n     * the word, then returns the boundaries of the current word, starting at\n     * the cursor. If the cursor is at the start/end of a word, and we are going\n     * forward/backward, respectively, find the boundaries of the next word.\n     *\n     * @param {CodeMirror} cm CodeMirror object.\n     * @param {Cursor} cur The cursor position.\n     * @param {boolean} forward True to search forward. False to search\n     *     backward.\n     * @param {boolean} bigWord True if punctuation count as part of the word.\n     *     False if only [a-zA-Z0-9] characters count as part of the word.\n     * @param {boolean} emptyLineIsWord True if empty lines should be treated\n     *     as words.\n     * @return {Object{from:number, to:number, line: number}} The boundaries of\n     *     the word, or null if there are no more words.\n     */\n    function findWord(cm, cur, forward, bigWord, emptyLineIsWord) {\n      var lineNum = cur.line;\n      var pos = cur.ch;\n      var line = cm.getLine(lineNum);\n      var dir = forward ? 1 : -1;\n      var charTests = bigWord ? bigWordCharTest: wordCharTest;\n\n      if (emptyLineIsWord && line == '') {\n        lineNum += dir;\n        line = cm.getLine(lineNum);\n        if (!isLine(cm, lineNum)) {\n          return null;\n        }\n        pos = (forward) ? 0 : line.length;\n      }\n\n      while (true) {\n        if (emptyLineIsWord && line == '') {\n          return { from: 0, to: 0, line: lineNum };\n        }\n        var stop = (dir > 0) ? line.length : -1;\n        var wordStart = stop, wordEnd = stop;\n        // Find bounds of next word.\n        while (pos != stop) {\n          var foundWord = false;\n          for (var i = 0; i < charTests.length && !foundWord; ++i) {\n            if (charTests[i](line.charAt(pos))) {\n              wordStart = pos;\n              // Advance to end of word.\n              while (pos != stop && charTests[i](line.charAt(pos))) {\n                pos += dir;\n              }\n              wordEnd = pos;\n              foundWord = wordStart != wordEnd;\n              if (wordStart == cur.ch && lineNum == cur.line &&\n                  wordEnd == wordStart + dir) {\n                // We started at the end of a word. Find the next one.\n                continue;\n              } else {\n                return {\n                  from: Math.min(wordStart, wordEnd + 1),\n                  to: Math.max(wordStart, wordEnd),\n                  line: lineNum };\n              }\n            }\n          }\n          if (!foundWord) {\n            pos += dir;\n          }\n        }\n        // Advance to next/prev line.\n        lineNum += dir;\n        if (!isLine(cm, lineNum)) {\n          return null;\n        }\n        line = cm.getLine(lineNum);\n        pos = (dir > 0) ? 0 : line.length;\n      }\n    }\n\n    /**\n     * @param {CodeMirror} cm CodeMirror object.\n     * @param {Pos} cur The position to start from.\n     * @param {int} repeat Number of words to move past.\n     * @param {boolean} forward True to search forward. False to search\n     *     backward.\n     * @param {boolean} wordEnd True to move to end of word. False to move to\n     *     beginning of word.\n     * @param {boolean} bigWord True if punctuation count as part of the word.\n     *     False if only alphabet characters count as part of the word.\n     * @return {Cursor} The position the cursor should move to.\n     */\n    function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) {\n      var curStart = copyCursor(cur);\n      var words = [];\n      if (forward && !wordEnd || !forward && wordEnd) {\n        repeat++;\n      }\n      // For 'e', empty lines are not considered words, go figure.\n      var emptyLineIsWord = !(forward && wordEnd);\n      for (var i = 0; i < repeat; i++) {\n        var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord);\n        if (!word) {\n          var eodCh = lineLength(cm, cm.lastLine());\n          words.push(forward\n              ? {line: cm.lastLine(), from: eodCh, to: eodCh}\n              : {line: 0, from: 0, to: 0});\n          break;\n        }\n        words.push(word);\n        cur = new Pos(word.line, forward ? (word.to - 1) : word.from);\n      }\n      var shortCircuit = words.length != repeat;\n      var firstWord = words[0];\n      var lastWord = words.pop();\n      if (forward && !wordEnd) {\n        // w\n        if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) {\n          // We did not start in the middle of a word. Discard the extra word at the end.\n          lastWord = words.pop();\n        }\n        return new Pos(lastWord.line, lastWord.from);\n      } else if (forward && wordEnd) {\n        return new Pos(lastWord.line, lastWord.to - 1);\n      } else if (!forward && wordEnd) {\n        // ge\n        if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) {\n          // We did not start in the middle of a word. Discard the extra word at the end.\n          lastWord = words.pop();\n        }\n        return new Pos(lastWord.line, lastWord.to);\n      } else {\n        // b\n        return new Pos(lastWord.line, lastWord.from);\n      }\n    }\n\n    function moveToEol(cm, head, motionArgs, vim, keepHPos) {\n      var cur = head;\n      var retval= new Pos(cur.line + motionArgs.repeat - 1, Infinity);\n      var end=cm.clipPos(retval);\n      end.ch--;\n      if (!keepHPos) {\n        vim.lastHPos = Infinity;\n        vim.lastHSPos = cm.charCoords(end,'div').left;\n      }\n      return retval;\n    }\n\n    function moveToCharacter(cm, repeat, forward, character, head) {\n      var cur = head || cm.getCursor();\n      var start = cur.ch;\n      var idx;\n      for (var i = 0; i < repeat; i ++) {\n        var line = cm.getLine(cur.line);\n        idx = charIdxInLine(start, line, character, forward, true);\n        if (idx == -1) {\n          return null;\n        }\n        start = idx;\n      }\n      return new Pos(cm.getCursor().line, idx);\n    }\n\n    function moveToColumn(cm, repeat) {\n      // repeat is always >= 1, so repeat - 1 always corresponds\n      // to the column we want to go to.\n      var line = cm.getCursor().line;\n      return clipCursorToContent(cm, new Pos(line, repeat - 1));\n    }\n\n    function updateMark(cm, vim, markName, pos) {\n      if (!inArray(markName, validMarks) && !latinCharRegex.test(markName)) {\n        return;\n      }\n      if (vim.marks[markName]) {\n        vim.marks[markName].clear();\n      }\n      vim.marks[markName] = cm.setBookmark(pos);\n    }\n\n    function charIdxInLine(start, line, character, forward, includeChar) {\n      // Search for char in line.\n      // motion_options: {forward, includeChar}\n      // If includeChar = true, include it too.\n      // If forward = true, search forward, else search backwards.\n      // If char is not found on this line, do nothing\n      var idx;\n      if (forward) {\n        idx = line.indexOf(character, start + 1);\n        if (idx != -1 && !includeChar) {\n          idx -= 1;\n        }\n      } else {\n        idx = line.lastIndexOf(character, start - 1);\n        if (idx != -1 && !includeChar) {\n          idx += 1;\n        }\n      }\n      return idx;\n    }\n\n    function findParagraph(cm, head, repeat, dir, inclusive) {\n      var line = head.line;\n      var min = cm.firstLine();\n      var max = cm.lastLine();\n      var start, end, i = line;\n      function isEmpty(i) { return !/\\S/.test(cm.getLine(i)); } // ace_patch\n      function isBoundary(i, dir, any) {\n        if (any) { return isEmpty(i) != isEmpty(i + dir); }\n        return !isEmpty(i) && isEmpty(i + dir);\n      }\n      function skipFold(i) {\n          dir = dir > 0 ? 1 : -1;\n          var foldLine = cm.ace.session.getFoldLine(i);\n          if (foldLine) {\n              if (i + dir > foldLine.start.row && i + dir < foldLine.end.row)\n                  dir = (dir > 0 ? foldLine.end.row : foldLine.start.row) - i;\n          }\n      }\n      if (dir) {\n        while (min <= i && i <= max && repeat > 0) {\n          skipFold(i);\n          if (isBoundary(i, dir)) { repeat--; }\n          i += dir;\n        }\n        return new Pos(i, 0);\n      }\n\n      var vim = cm.state.vim;\n      if (vim.visualLine && isBoundary(line, 1, true)) {\n        var anchor = vim.sel.anchor;\n        if (isBoundary(anchor.line, -1, true)) {\n          if (!inclusive || anchor.line != line) {\n            line += 1;\n          }\n        }\n      }\n      var startState = isEmpty(line);\n      for (i = line; i <= max && repeat; i++) {\n        if (isBoundary(i, 1, true)) {\n          if (!inclusive || isEmpty(i) != startState) {\n            repeat--;\n          }\n        }\n      }\n      end = new Pos(i, 0);\n      // select boundary before paragraph for the last one\n      if (i > max && !startState) { startState = true; }\n      else { inclusive = false; }\n      for (i = line; i > min; i--) {\n        if (!inclusive || isEmpty(i) == startState || i == line) {\n          if (isBoundary(i, -1, true)) { break; }\n        }\n      }\n      start = new Pos(i, 0);\n      return { start: start, end: end };\n    }\n\n    /**\n     * Based on {@link findSentence}. The internal functions have the same names,\n     * but their behaviour is different. findSentence() crosses line breaks and \n     * is used for jumping to sentence beginnings before or after the current cursor position, \n     * whereas getSentence() is for getting the beginning or end of the sentence \n     * at the current cursor position, either including (a) or excluding (i) whitespace.\n     */\n    function getSentence(cm, cur, repeat, dir, inclusive /*includes whitespace*/) {\n\n      /*\n        Takes an index object\n        {\n          line: the line string,\n          ln: line number,\n          pos: index in line,\n          dir: direction of traversal (-1 or 1)\n        }\n        and modifies the pos member to represent the\n        next valid position or sets the line to null if there are\n        no more valid positions.\n       */\n      function nextChar(curr) {\n        if (curr.pos + curr.dir < 0 || curr.pos + curr.dir >= curr.line.length) {\n          curr.line = null;\n        }\n        else {\n          curr.pos += curr.dir;\n        }\n      }\n      /*\n        Performs one iteration of traversal in forward direction\n        Returns an index object of the sentence end\n       */\n      function forward(cm, ln, pos, dir) {\n        var line = cm.getLine(ln);\n\n        var curr = {\n          line: line,\n          ln: ln,\n          pos: pos,\n          dir: dir,\n        };\n\n        if (curr.line === \"\") {\n          return { ln: curr.ln, pos: curr.pos };\n        }\n\n        var lastSentencePos = curr.pos;\n\n        // Move one step to skip character we start on\n        nextChar(curr);\n\n        while (curr.line !== null) {\n          lastSentencePos = curr.pos;\n          if (isEndOfSentenceSymbol(curr.line[curr.pos])) {\n            if (!inclusive) {\n              return { ln: curr.ln, pos: curr.pos + 1 };\n            } \n            else {\n              nextChar(curr);\n              while (curr.line !== null ) {\n                if (isWhiteSpaceString(curr.line[curr.pos])) {\n                  lastSentencePos = curr.pos;\n                  nextChar(curr)\n                } \n                else {\n                  break;\n                }\n              }\n              return { ln: curr.ln, pos: lastSentencePos + 1 };\n            }\n          }\n          nextChar(curr);\n        }\n        return { ln: curr.ln, pos: lastSentencePos + 1 };\n      }\n\n      /*\n        Performs one iteration of traversal in reverse direction\n        Returns an index object of the sentence start\n       */\n      function reverse(cm, ln, pos, dir) {\n        var line = cm.getLine(ln);\n\n        var curr = {\n          line: line,\n          ln: ln,\n          pos: pos,\n          dir: dir,\n        }\n\n        if (curr.line === \"\") {\n          return { ln: curr.ln, pos: curr.pos };\n        }\n\n        var lastSentencePos = curr.pos;\n\n        // Move one step to skip character we start on\n        nextChar(curr);\n\n        while (curr.line !== null) {\n          if (!isWhiteSpaceString(curr.line[curr.pos]) && !isEndOfSentenceSymbol(curr.line[curr.pos])) {\n            lastSentencePos = curr.pos;\n          }\n\n          else if (isEndOfSentenceSymbol(curr.line[curr.pos]) ) {\n            if (!inclusive) {\n              return { ln: curr.ln, pos: lastSentencePos };\n            } \n            else {\n              if (isWhiteSpaceString(curr.line[curr.pos + 1])) {\n                return { ln: curr.ln, pos: curr.pos + 1 };\n              } \n              else {\n                return { ln: curr.ln, pos: lastSentencePos };\n              }\n            }\n          }\n\n          nextChar(curr);\n        }\n        curr.line = line\n        if (inclusive && isWhiteSpaceString(curr.line[curr.pos])) {\n          return { ln: curr.ln, pos: curr.pos };\n        } \n        else {\n          return { ln: curr.ln, pos: lastSentencePos };\n        }\n\n      }\n\n      var curr_index = {\n        ln: cur.line,\n        pos: cur.ch,\n      };\n\n      while (repeat > 0) {\n        if (dir < 0) {\n          curr_index = reverse(cm, curr_index.ln, curr_index.pos, dir);\n        }\n        else {\n          curr_index = forward(cm, curr_index.ln, curr_index.pos, dir);\n        }\n        repeat--;\n      }\n\n      return new Pos(curr_index.ln, curr_index.pos);\n    }\n\n    function findSentence(cm, cur, repeat, dir) {\n\n       /*\n         Takes an index object\n         {\n           line: the line string,\n           ln: line number,\n           pos: index in line,\n           dir: direction of traversal (-1 or 1)\n         }\n         and modifies the line, ln, and pos members to represent the\n         next valid position or sets them to null if there are\n         no more valid positions.\n       */\n      function nextChar(cm, idx) {\n        if (idx.pos + idx.dir < 0 || idx.pos + idx.dir >= idx.line.length) {\n          idx.ln += idx.dir;\n          if (!isLine(cm, idx.ln)) {\n            idx.line = null;\n            idx.ln = null;\n            idx.pos = null;\n            return;\n          }\n          idx.line = cm.getLine(idx.ln);\n          idx.pos = (idx.dir > 0) ? 0 : idx.line.length - 1;\n        }\n        else {\n          idx.pos += idx.dir;\n        }\n      }\n\n      /*\n        Performs one iteration of traversal in forward direction\n        Returns an index object of the new location\n       */\n      function forward(cm, ln, pos, dir) {\n        var line = cm.getLine(ln);\n        var stop = (line === \"\");\n\n        var curr = {\n          line: line,\n          ln: ln,\n          pos: pos,\n          dir: dir,\n        }\n\n        var last_valid = {\n          ln: curr.ln,\n          pos: curr.pos,\n        }\n\n        var skip_empty_lines = (curr.line === \"\");\n\n        // Move one step to skip character we start on\n        nextChar(cm, curr);\n\n        while (curr.line !== null) {\n          last_valid.ln = curr.ln;\n          last_valid.pos = curr.pos;\n\n          if (curr.line === \"\" && !skip_empty_lines) {\n            return { ln: curr.ln, pos: curr.pos, };\n          }\n          else if (stop && curr.line !== \"\" && !isWhiteSpaceString(curr.line[curr.pos])) {\n            return { ln: curr.ln, pos: curr.pos, };\n          }\n          else if (isEndOfSentenceSymbol(curr.line[curr.pos])\n            && !stop\n            && (curr.pos === curr.line.length - 1\n              || isWhiteSpaceString(curr.line[curr.pos + 1]))) {\n            stop = true;\n          }\n\n          nextChar(cm, curr);\n        }\n\n        /*\n          Set the position to the last non whitespace character on the last\n          valid line in the case that we reach the end of the document.\n        */\n        var line = cm.getLine(last_valid.ln);\n        last_valid.pos = 0;\n        for(var i = line.length - 1; i >= 0; --i) {\n          if (!isWhiteSpaceString(line[i])) {\n            last_valid.pos = i;\n            break;\n          }\n        }\n\n        return last_valid;\n\n      }\n\n      /*\n        Performs one iteration of traversal in reverse direction\n        Returns an index object of the new location\n       */\n      function reverse(cm, ln, pos, dir) {\n        var line = cm.getLine(ln);\n\n        var curr = {\n          line: line,\n          ln: ln,\n          pos: pos,\n          dir: dir,\n        }\n\n        var last_valid = {\n          ln: curr.ln,\n          pos: null,\n        };\n\n        var skip_empty_lines = (curr.line === \"\");\n\n        // Move one step to skip character we start on\n        nextChar(cm, curr);\n\n        while (curr.line !== null) {\n\n          if (curr.line === \"\" && !skip_empty_lines) {\n            if (last_valid.pos !== null) {\n              return last_valid;\n            }\n            else {\n              return { ln: curr.ln, pos: curr.pos };\n            }\n          }\n          else if (isEndOfSentenceSymbol(curr.line[curr.pos])\n              && last_valid.pos !== null\n              && !(curr.ln === last_valid.ln && curr.pos + 1 === last_valid.pos)) {\n            return last_valid;\n          }\n          else if (curr.line !== \"\" && !isWhiteSpaceString(curr.line[curr.pos])) {\n            skip_empty_lines = false;\n            last_valid = { ln: curr.ln, pos: curr.pos }\n          }\n\n          nextChar(cm, curr);\n        }\n\n        /*\n          Set the position to the first non whitespace character on the last\n          valid line in the case that we reach the beginning of the document.\n        */\n        var line = cm.getLine(last_valid.ln);\n        last_valid.pos = 0;\n        for(var i = 0; i < line.length; ++i) {\n          if (!isWhiteSpaceString(line[i])) {\n            last_valid.pos = i;\n            break;\n          }\n        }\n        return last_valid;\n      }\n\n      var curr_index = {\n        ln: cur.line,\n        pos: cur.ch,\n      };\n\n      while (repeat > 0) {\n        if (dir < 0) {\n          curr_index = reverse(cm, curr_index.ln, curr_index.pos, dir);\n        }\n        else {\n          curr_index = forward(cm, curr_index.ln, curr_index.pos, dir);\n        }\n        repeat--;\n      }\n\n      return new Pos(curr_index.ln, curr_index.pos);\n    }\n\n    // TODO: perhaps this finagling of start and end positions belongs\n    // in codemirror/replaceRange?\n    function selectCompanionObject(cm, head, symb, inclusive) {\n      var cur = head, start, end;\n\n      var bracketRegexp = ({\n        '(': /[()]/, ')': /[()]/,\n        '[': /[[\\]]/, ']': /[[\\]]/,\n        '{': /[{}]/, '}': /[{}]/,\n        '<': /[<>]/, '>': /[<>]/})[symb];\n      var openSym = ({\n        '(': '(', ')': '(',\n        '[': '[', ']': '[',\n        '{': '{', '}': '{',\n        '<': '<', '>': '<'})[symb];\n      var curChar = cm.getLine(cur.line).charAt(cur.ch);\n      // Due to the behavior of scanForBracket, we need to add an offset if the\n      // cursor is on a matching open bracket.\n      var offset = curChar === openSym ? 1 : 0;\n\n      start = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp});\n      end = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp});\n\n      if (!start || !end) return null;\n\n      start = start.pos;\n      end = end.pos;\n\n      if ((start.line == end.line && start.ch > end.ch)\n          || (start.line > end.line)) {\n        var tmp = start;\n        start = end;\n        end = tmp;\n      }\n\n      if (inclusive) {\n        end.ch += 1;\n      } else {\n        start.ch += 1;\n      }\n\n      return { start: start, end: end };\n    }\n\n    // Takes in a symbol and a cursor and tries to simulate text objects that\n    // have identical opening and closing symbols\n    // TODO support across multiple lines\n    function findBeginningAndEnd(cm, head, symb, inclusive) {\n      var cur = copyCursor(head);\n      var line = cm.getLine(cur.line);\n      var chars = line.split('');\n      var start, end, i, len;\n      var firstIndex = chars.indexOf(symb);\n\n      // the decision tree is to always look backwards for the beginning first,\n      // but if the cursor is in front of the first instance of the symb,\n      // then move the cursor forward\n      if (cur.ch < firstIndex) {\n        cur.ch = firstIndex;\n      }\n      // otherwise if the cursor is currently on the closing symbol\n      else if (firstIndex < cur.ch && chars[cur.ch] == symb) {\n        var stringAfter = /string/.test(cm.getTokenTypeAt(offsetCursor(head, 0, 1)));\n        var stringBefore = /string/.test(cm.getTokenTypeAt(head));\n        var isStringStart = stringAfter && !stringBefore\n        if (!isStringStart) {\n          end = cur.ch; // assign end to the current cursor\n          --cur.ch; // make sure to look backwards\n        }\n      }\n\n      // if we're currently on the symbol, we've got a start\n      if (chars[cur.ch] == symb && !end) {\n        start = cur.ch + 1; // assign start to ahead of the cursor\n      } else {\n        // go backwards to find the start\n        for (i = cur.ch; i > -1 && !start; i--) {\n          if (chars[i] == symb) {\n            start = i + 1;\n          }\n        }\n      }\n\n      // look forwards for the end symbol\n      if (start && !end) {\n        for (i = start, len = chars.length; i < len && !end; i++) {\n          if (chars[i] == symb) {\n            end = i;\n          }\n        }\n      }\n\n      // nothing found\n      if (!start || !end) {\n        return { start: cur, end: cur };\n      }\n\n      // include the symbols\n      if (inclusive) {\n        --start; ++end;\n      }\n\n      return {\n        start: new Pos(cur.line, start),\n        end: new Pos(cur.line, end)\n      };\n    }\n\n    // Search functions\n    defineOption('pcre', true, 'boolean');\n    function SearchState() {}\n    SearchState.prototype = {\n      getQuery: function() {\n        return vimGlobalState.query;\n      },\n      setQuery: function(query) {\n        vimGlobalState.query = query;\n      },\n      getOverlay: function() {\n        return this.searchOverlay;\n      },\n      setOverlay: function(overlay) {\n        this.searchOverlay = overlay;\n      },\n      isReversed: function() {\n        return vimGlobalState.isReversed;\n      },\n      setReversed: function(reversed) {\n        vimGlobalState.isReversed = reversed;\n      },\n      getScrollbarAnnotate: function() {\n        return this.annotate;\n      },\n      setScrollbarAnnotate: function(annotate) {\n        this.annotate = annotate;\n      }\n    };\n    function getSearchState(cm) {\n      var vim = cm.state.vim;\n      return vim.searchState_ || (vim.searchState_ = new SearchState());\n    }\n    function splitBySlash(argString) {\n      return splitBySeparator(argString, '/');\n    }\n\n    function findUnescapedSlashes(argString) {\n      return findUnescapedSeparators(argString, '/');\n    }\n\n    function splitBySeparator(argString, separator) {\n      var slashes = findUnescapedSeparators(argString, separator) || [];\n      if (!slashes.length) return [];\n      var tokens = [];\n      // in case of strings like foo/bar\n      if (slashes[0] !== 0) return;\n      for (var i = 0; i < slashes.length; i++) {\n        if (typeof slashes[i] == 'number')\n          tokens.push(argString.substring(slashes[i] + 1, slashes[i+1]));\n      }\n      return tokens;\n    }\n\n    function findUnescapedSeparators(str, separator) {\n      if (!separator)\n        separator = '/';\n\n      var escapeNextChar = false;\n      var slashes = [];\n      for (var i = 0; i < str.length; i++) {\n        var c = str.charAt(i);\n        if (!escapeNextChar && c == separator) {\n          slashes.push(i);\n        }\n        escapeNextChar = !escapeNextChar && (c == '\\\\');\n      }\n      return slashes;\n    }\n\n    // Translates a search string from ex (vim) syntax into javascript form.\n    function translateRegex(str) {\n      // When these match, add a '\\' if unescaped or remove one if escaped.\n      var specials = '|(){';\n      // Remove, but never add, a '\\' for these.\n      var unescape = '}';\n      var escapeNextChar = false;\n      var out = [];\n      for (var i = -1; i < str.length; i++) {\n        var c = str.charAt(i) || '';\n        var n = str.charAt(i+1) || '';\n        var specialComesNext = (n && specials.indexOf(n) != -1);\n        if (escapeNextChar) {\n          if (c !== '\\\\' || !specialComesNext) {\n            out.push(c);\n          }\n          escapeNextChar = false;\n        } else {\n          if (c === '\\\\') {\n            escapeNextChar = true;\n            // Treat the unescape list as special for removing, but not adding '\\'.\n            if (n && unescape.indexOf(n) != -1) {\n              specialComesNext = true;\n            }\n            // Not passing this test means removing a '\\'.\n            if (!specialComesNext || n === '\\\\') {\n              out.push(c);\n            }\n          } else {\n            out.push(c);\n            if (specialComesNext && n !== '\\\\') {\n              out.push('\\\\');\n            }\n          }\n        }\n      }\n      return out.join('');\n    }\n\n    // Translates the replace part of a search and replace from ex (vim) syntax into\n    // javascript form.  Similar to translateRegex, but additionally fixes back references\n    // (translates '\\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.\n    var charUnescapes = {'\\\\n': '\\n', '\\\\r': '\\r', '\\\\t': '\\t'};\n    function translateRegexReplace(str) {\n      var escapeNextChar = false;\n      var out = [];\n      for (var i = -1; i < str.length; i++) {\n        var c = str.charAt(i) || '';\n        var n = str.charAt(i+1) || '';\n        if (charUnescapes[c + n]) {\n          out.push(charUnescapes[c+n]);\n          i++;\n        } else if (escapeNextChar) {\n          // At any point in the loop, escapeNextChar is true if the previous\n          // character was a '\\' and was not escaped.\n          out.push(c);\n          escapeNextChar = false;\n        } else {\n          if (c === '\\\\') {\n            escapeNextChar = true;\n            if ((isNumber(n) || n === '$')) {\n              out.push('$');\n            } else if (n !== '/' && n !== '\\\\') {\n              out.push('\\\\');\n            }\n          } else {\n            if (c === '$') {\n              out.push('$');\n            }\n            out.push(c);\n            if (n === '/') {\n              out.push('\\\\');\n            }\n          }\n        }\n      }\n      return out.join('');\n    }\n\n    // Unescape \\ and / in the replace part, for PCRE mode.\n    var unescapes = {'\\\\/': '/', '\\\\\\\\': '\\\\', '\\\\n': '\\n', '\\\\r': '\\r', '\\\\t': '\\t', '\\\\&':'&'};\n    function unescapeRegexReplace(str) {\n      var stream = new CodeMirror.StringStream(str);\n      var output = [];\n      while (!stream.eol()) {\n        // Search for \\.\n        while (stream.peek() && stream.peek() != '\\\\') {\n          output.push(stream.next());\n        }\n        var matched = false;\n        for (var matcher in unescapes) {\n          if (stream.match(matcher, true)) {\n            matched = true;\n            output.push(unescapes[matcher]);\n            break;\n          }\n        }\n        if (!matched) {\n          // Don't change anything\n          output.push(stream.next());\n        }\n      }\n      return output.join('');\n    }\n\n    /**\n     * Extract the regular expression from the query and return a Regexp object.\n     * Returns null if the query is blank.\n     * If ignoreCase is passed in, the Regexp object will have the 'i' flag set.\n     * If smartCase is passed in, and the query contains upper case letters,\n     *   then ignoreCase is overridden, and the 'i' flag will not be set.\n     * If the query contains the /i in the flag part of the regular expression,\n     *   then both ignoreCase and smartCase are ignored, and 'i' will be passed\n     *   through to the Regex object.\n     */\n    function parseQuery(query, ignoreCase, smartCase) {\n      // First update the last search register\n      var lastSearchRegister = vimGlobalState.registerController.getRegister('/');\n      lastSearchRegister.setText(query);\n      // Check if the query is already a regex.\n      if (query instanceof RegExp) { return query; }\n      // First try to extract regex + flags from the input. If no flags found,\n      // extract just the regex. IE does not accept flags directly defined in\n      // the regex string in the form /regex/flags\n      var slashes = findUnescapedSlashes(query);\n      var regexPart;\n      var forceIgnoreCase;\n      if (!slashes.length) {\n        // Query looks like 'regexp'\n        regexPart = query;\n      } else {\n        // Query looks like 'regexp/...'\n        regexPart = query.substring(0, slashes[0]);\n        var flagsPart = query.substring(slashes[0]);\n        forceIgnoreCase = (flagsPart.indexOf('i') != -1);\n      }\n      if (!regexPart) {\n        return null;\n      }\n      if (!getOption('pcre')) {\n        regexPart = translateRegex(regexPart);\n      }\n      if (smartCase) {\n        ignoreCase = (/^[^A-Z]*$/).test(regexPart);\n      }\n      var regexp = new RegExp(regexPart,\n          (ignoreCase || forceIgnoreCase) ? 'im' : 'm');\n      return regexp;\n    }\n\n    /**\n     * dom - Document Object Manipulator\n     * Usage:\n     *   dom('<tag>'|<node>[, ...{<attributes>|<$styles>}|<child-node>|'<text>'])\n     * Examples:\n     *   dom('div', {id:'xyz'}, dom('p', 'CM rocks!', {$color:'red'}))\n     *   dom(document.head, dom('script', 'alert(\"hello!\")'))\n     * Not supported:\n     *   dom('p', ['arrays are objects'], Error('objects specify attributes'))\n     */\n    function dom(n) {\n      if (typeof n === 'string') n = document.createElement(n);\n      for (var a, i = 1; i < arguments.length; i++) {\n        if (!(a = arguments[i])) continue;\n        if (typeof a !== 'object') a = document.createTextNode(a);\n        if (a.nodeType) n.appendChild(a);\n        else for (var key in a) {\n          if (!Object.prototype.hasOwnProperty.call(a, key)) continue;\n          if (key[0] === '$') n.style[key.slice(1)] = a[key];\n          else n.setAttribute(key, a[key]);\n        }\n      }\n      return n;\n    }\n\n    function showConfirm(cm, template) {\n      var pre = dom('div', {$color: 'red', $whiteSpace: 'pre', class: 'cm-vim-message'}, template);\n      if (cm.openNotification) {\n        cm.openNotification(pre, {bottom: true, duration: 5000});\n      } else {\n        alert(pre.innerText);\n      }\n    }\n\n    function makePrompt(prefix, desc) {\n      return dom('div', {$display: 'flex'},\n               dom('span', {$fontFamily: 'monospace', $whiteSpace: 'pre', $flex: 1},\n                 prefix,\n                 dom('input', {type: 'text', autocorrect: 'off',\n                               autocapitalize: 'off', spellcheck: 'false', $width: '100%'})),\n               desc && dom('span', {$color: '#888'}, desc));\n    }\n\n    function showPrompt(cm, options) {\n      if (keyToKeyStack.length) {\n        if (!options.value) options.value = '';\n        virtualPrompt = options;\n        return;\n      }\n      var template = makePrompt(options.prefix, options.desc);\n      if (cm.openDialog) {\n        cm.openDialog(template, options.onClose, {\n          onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,\n          bottom: true, selectValueOnOpen: false, value: options.value\n        });\n      }\n      else {\n        var shortText = '';\n        if (typeof options.prefix != \"string\" && options.prefix) shortText += options.prefix.textContent;\n        if (options.desc) shortText += \" \" + options.desc;\n        options.onClose(prompt(shortText, ''));\n      }\n    }\n\n    function regexEqual(r1, r2) {\n      if (r1 instanceof RegExp && r2 instanceof RegExp) {\n          var props = ['global', 'multiline', 'ignoreCase', 'source'];\n          for (var i = 0; i < props.length; i++) {\n              var prop = props[i];\n              if (r1[prop] !== r2[prop]) {\n                  return false;\n              }\n          }\n          return true;\n      }\n      return false;\n    }\n    // Returns true if the query is valid.\n    function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) {\n      if (!rawQuery) {\n        return;\n      }\n      var state = getSearchState(cm);\n      var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase);\n      if (!query) {\n        return;\n      }\n      highlightSearchMatches(cm, query);\n      if (regexEqual(query, state.getQuery())) {\n        return query;\n      }\n      state.setQuery(query);\n      return query;\n    }\n    function searchOverlay(query) {\n      if (query.source.charAt(0) == '^') {\n        var matchSol = true;\n      }\n      return {\n        token: function(stream) {\n          if (matchSol && !stream.sol()) {\n            stream.skipToEnd();\n            return;\n          }\n          var match = stream.match(query, false);\n          if (match) {\n            if (match[0].length == 0) {\n              // Matched empty string, skip to next.\n              stream.next();\n              return 'searching';\n            }\n            if (!stream.sol()) {\n              // Backtrack 1 to match \\b\n              stream.backUp(1);\n              if (!query.exec(stream.next() + match[0])) {\n                stream.next();\n                return null;\n              }\n            }\n            stream.match(query);\n            return 'searching';\n          }\n          while (!stream.eol()) {\n            stream.next();\n            if (stream.match(query, false)) break;\n          }\n        },\n        query: query\n      };\n    }\n    var highlightTimeout = 0;\n    function highlightSearchMatches(cm, query) {\n      clearTimeout(highlightTimeout);\n      var searchState = getSearchState(cm);\n      searchState.highlightTimeout = highlightTimeout;\n      highlightTimeout = setTimeout(function() {\n        if (!cm.state.vim) return;\n        var searchState = getSearchState(cm);\n        searchState.highlightTimeout = null;\n        var overlay = searchState.getOverlay();\n        if (!overlay || query != overlay.query) {\n          if (overlay) {\n            cm.removeOverlay(overlay);\n          }\n          overlay = searchOverlay(query);\n          cm.addOverlay(overlay);\n          if (cm.showMatchesOnScrollbar) {\n            if (searchState.getScrollbarAnnotate()) {\n              searchState.getScrollbarAnnotate().clear();\n            }\n            searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));\n          }\n          searchState.setOverlay(overlay);\n        }\n      }, 50);\n    }\n    function findNext(cm, prev, query, repeat) {\n      if (repeat === undefined) { repeat = 1; }\n      return cm.operation(function() {\n        var pos = cm.getCursor();\n        var cursor = cm.getSearchCursor(query, pos);\n        for (var i = 0; i < repeat; i++) {\n          var found = cursor.find(prev);\n          if (i == 0 && found && cursorEqual(cursor.from(), pos)) {\n            var lastEndPos = prev ? cursor.from() : cursor.to();\n            found = cursor.find(prev);\n            if (found && !found[0] && cursorEqual(cursor.from(), lastEndPos)) {\n              if (cm.getLine(lastEndPos.line).length == lastEndPos.ch)\n                found = cursor.find(prev);\n            }\n          }\n          if (!found) {\n            // SearchCursor may have returned null because it hit EOF, wrap\n            // around and try again.\n            cursor = cm.getSearchCursor(query,\n                (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) );\n            if (!cursor.find(prev)) {\n              return;\n            }\n          }\n        }\n        return cursor.from();\n      });\n    }\n    /**\n     * Pretty much the same as `findNext`, except for the following differences:\n     *\n     * 1. Before starting the search, move to the previous search. This way if our cursor is\n     * already inside a match, we should return the current match.\n     * 2. Rather than only returning the cursor's from, we return the cursor's from and to as a tuple.\n     */\n    function findNextFromAndToInclusive(cm, prev, query, repeat, vim) {\n      if (repeat === undefined) { repeat = 1; }\n      return cm.operation(function() {\n        var pos = cm.getCursor();\n        var cursor = cm.getSearchCursor(query, pos);\n\n        // Go back one result to ensure that if the cursor is currently a match, we keep it.\n        var found = cursor.find(!prev);\n\n        // If we haven't moved, go back one more (similar to if i==0 logic in findNext).\n        if (!vim.visualMode && found && cursorEqual(cursor.from(), pos)) {\n          cursor.find(!prev);\n        }\n\n        for (var i = 0; i < repeat; i++) {\n          found = cursor.find(prev);\n          if (!found) {\n            // SearchCursor may have returned null because it hit EOF, wrap\n            // around and try again.\n            cursor = cm.getSearchCursor(query,\n                (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) );\n            if (!cursor.find(prev)) {\n              return;\n            }\n          }\n        }\n        return [cursor.from(), cursor.to()];\n      });\n    }\n    function clearSearchHighlight(cm) {\n      var state = getSearchState(cm);\n      if (state.highlightTimeout) {\n        clearTimeout(state.highlightTimeout);\n        state.highlightTimeout = null;\n      }\n      cm.removeOverlay(getSearchState(cm).getOverlay());\n      state.setOverlay(null);\n      if (state.getScrollbarAnnotate()) {\n        state.getScrollbarAnnotate().clear();\n        state.setScrollbarAnnotate(null);\n      }\n    }\n    /**\n     * Check if pos is in the specified range, INCLUSIVE.\n     * Range can be specified with 1 or 2 arguments.\n     * If the first range argument is an array, treat it as an array of line\n     * numbers. Match pos against any of the lines.\n     * If the first range argument is a number,\n     *   if there is only 1 range argument, check if pos has the same line\n     *       number\n     *   if there are 2 range arguments, then check if pos is in between the two\n     *       range arguments.\n     */\n    function isInRange(pos, start, end) {\n      if (typeof pos != 'number') {\n        // Assume it is a cursor position. Get the line number.\n        pos = pos.line;\n      }\n      if (start instanceof Array) {\n        return inArray(pos, start);\n      } else {\n        if (typeof end == 'number') {\n          return (pos >= start && pos <= end);\n        } else {\n          return pos == start;\n        }\n      }\n    }\n    function getUserVisibleLines(cm) {\n      // ace_patch{\n      var renderer = cm.ace.renderer;\n      return {\n        top: renderer.getFirstFullyVisibleRow(),\n        bottom: renderer.getLastFullyVisibleRow()\n      }\n      // ace_patch}\n    }\n\n    function getMarkPos(cm, vim, markName) {\n      if (markName == '\\'' || markName == '`') {\n        return vimGlobalState.jumpList.find(cm, -1) || new Pos(0, 0);\n      } else if (markName == '.') {\n        return getLastEditPos(cm);\n      }\n\n      var mark = vim.marks[markName];\n      return mark && mark.find();\n    }\n\n    function getLastEditPos(cm) {\n      if (cm.getLastEditEnd) {\n        return cm.getLastEditEnd();\n      }\n      // for old cm\n      var done = cm.doc.history.done;\n      for (var i = done.length; i--;) {\n        if (done[i].changes) {\n          return copyCursor(done[i].changes[0].to);\n        }\n      }\n    }\n\n    var ExCommandDispatcher = function() {\n      this.buildCommandMap_();\n    };\n    ExCommandDispatcher.prototype = {\n      processCommand: function(cm, input, opt_params) {\n        var that = this;\n        cm.operation(function () {\n          cm.curOp.isVimOp = true;\n          that._processCommand(cm, input, opt_params);\n        });\n      },\n      _processCommand: function(cm, input, opt_params) {\n        var vim = cm.state.vim;\n        var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');\n        var previousCommand = commandHistoryRegister.toString();\n        var inputStream = new CodeMirror.StringStream(input);\n        // update \": with the latest command whether valid or invalid\n        commandHistoryRegister.setText(input);\n        var params = opt_params || {};\n        params.input = input;\n        try {\n          this.parseInput_(cm, inputStream, params);\n        } catch(e) {\n          showConfirm(cm, e.toString());\n          throw e;\n        }\n\n        if (vim.visualMode) {\n          exitVisualMode(cm);\n        }\n\n        var command;\n        var commandName;\n        if (!params.commandName) {\n          // If only a line range is defined, move to the line.\n          if (params.line !== undefined) {\n            commandName = 'move';\n          }\n        } else {\n          command = this.matchCommand_(params.commandName);\n          if (command) {\n            commandName = command.name;\n            if (command.excludeFromCommandHistory) {\n              commandHistoryRegister.setText(previousCommand);\n            }\n            this.parseCommandArgs_(inputStream, params, command);\n            if (command.type == 'exToKey') {\n              // Handle Ex to Key mapping.\n              doKeyToKey(cm, command.toKeys, command);\n              return;\n            } else if (command.type == 'exToEx') {\n              // Handle Ex to Ex mapping.\n              this.processCommand(cm, command.toInput);\n              return;\n            }\n          }\n        }\n        if (!commandName) {\n          showConfirm(cm, 'Not an editor command \":' + input + '\"');\n          return;\n        }\n        try {\n          exCommands[commandName](cm, params);\n          // Possibly asynchronous commands (e.g. substitute, which might have a\n          // user confirmation), are responsible for calling the callback when\n          // done. All others have it taken care of for them here.\n          if ((!command || !command.possiblyAsync) && params.callback) {\n            params.callback();\n          }\n        } catch(e) {\n          showConfirm(cm, e.toString());\n          throw e;\n        }\n      },\n      parseInput_: function(cm, inputStream, result) {\n        inputStream.eatWhile(':');\n        // Parse range.\n        if (inputStream.eat('%')) {\n          result.line = cm.firstLine();\n          result.lineEnd = cm.lastLine();\n        } else {\n          result.line = this.parseLineSpec_(cm, inputStream);\n          if (result.line !== undefined && inputStream.eat(',')) {\n            result.lineEnd = this.parseLineSpec_(cm, inputStream);\n          }\n        }\n\n        if (result.line == undefined) {\n          if (cm.state.vim.visualMode) {\n            var pos = getMarkPos(cm, cm.state.vim, '<');\n            result.selectionLine = pos && pos.line;\n            pos = getMarkPos(cm, cm.state.vim, '>');\n            result.selectionLineEnd = pos && pos.line;\n          } else {\n            result.selectionLine = cm.getCursor().line;\n          }\n        } else {\n          result.selectionLine = result.line;\n          result.selectionLineEnd = result.lineEnd;\n        }\n\n        // Parse command name.\n        var commandMatch = inputStream.match(/^(\\w+|!!|@@|[!#&*<=>@~])/);\n        if (commandMatch) {\n          result.commandName = commandMatch[1];\n        } else {\n          result.commandName = inputStream.match(/.*/)[0];\n        }\n\n        return result;\n      },\n      parseLineSpec_: function(cm, inputStream) {\n        var numberMatch = inputStream.match(/^(\\d+)/);\n        if (numberMatch) {\n          // Absolute line number plus offset (N+M or N-M) is probably a typo,\n          // not something the user actually wanted. (NB: vim does allow this.)\n          return parseInt(numberMatch[1], 10) - 1;\n        }\n        switch (inputStream.next()) {\n          case '.':\n            return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);\n          case '$':\n            return this.parseLineSpecOffset_(inputStream, cm.lastLine());\n          case '\\'':\n            var markName = inputStream.next();\n            var markPos = getMarkPos(cm, cm.state.vim, markName);\n            if (!markPos) throw new Error('Mark not set');\n            return this.parseLineSpecOffset_(inputStream, markPos.line);\n          case '-':\n          case '+':\n            inputStream.backUp(1);\n            // Offset is relative to current line if not otherwise specified.\n            return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);\n          default:\n            inputStream.backUp(1);\n            return undefined;\n        }\n      },\n      parseLineSpecOffset_: function(inputStream, line) {\n        var offsetMatch = inputStream.match(/^([+-])?(\\d+)/);\n        if (offsetMatch) {\n          var offset = parseInt(offsetMatch[2], 10);\n          if (offsetMatch[1] == \"-\") {\n            line -= offset;\n          } else {\n            line += offset;\n          }\n        }\n        return line;\n      },\n      parseCommandArgs_: function(inputStream, params, command) {\n        if (inputStream.eol()) {\n          return;\n        }\n        params.argString = inputStream.match(/.*/)[0];\n        // Parse command-line arguments\n        var delim = command.argDelimiter || /\\s+/;\n        var args = trim(params.argString).split(delim);\n        if (args.length && args[0]) {\n          params.args = args;\n        }\n      },\n      matchCommand_: function(commandName) {\n        // Return the command in the command map that matches the shortest\n        // prefix of the passed in command name. The match is guaranteed to be\n        // unambiguous if the defaultExCommandMap's shortNames are set up\n        // correctly. (see @code{defaultExCommandMap}).\n        for (var i = commandName.length; i > 0; i--) {\n          var prefix = commandName.substring(0, i);\n          if (this.commandMap_[prefix]) {\n            var command = this.commandMap_[prefix];\n            if (command.name.indexOf(commandName) === 0) {\n              return command;\n            }\n          }\n        }\n        return null;\n      },\n      buildCommandMap_: function() {\n        this.commandMap_ = {};\n        for (var i = 0; i < defaultExCommandMap.length; i++) {\n          var command = defaultExCommandMap[i];\n          var key = command.shortName || command.name;\n          this.commandMap_[key] = command;\n        }\n      },\n      map: function(lhs, rhs, ctx, noremap) {\n        if (lhs != ':' && lhs.charAt(0) == ':') {\n          if (ctx) { throw Error('Mode not supported for ex mappings'); }\n          var commandName = lhs.substring(1);\n          if (rhs != ':' && rhs.charAt(0) == ':') {\n            // Ex to Ex mapping\n            this.commandMap_[commandName] = {\n              name: commandName,\n              type: 'exToEx',\n              toInput: rhs.substring(1),\n              user: true\n            };\n          } else {\n            // Ex to key mapping\n            this.commandMap_[commandName] = {\n              name: commandName,\n              type: 'exToKey',\n              toKeys: rhs,\n              user: true\n            };\n          }\n        } else {\n          // Key to key or ex mapping\n          var mapping = {\n            keys: lhs,\n            type: 'keyToKey',\n            toKeys: rhs,\n            noremap: !!noremap\n          };\n          if (ctx) { mapping.context = ctx; }\n          defaultKeymap.unshift(mapping);\n        }\n      },\n      unmap: function(lhs, ctx) {\n        if (lhs != ':' && lhs.charAt(0) == ':') {\n          // Ex to Ex or Ex to key mapping\n          if (ctx) { throw Error('Mode not supported for ex mappings'); }\n          var commandName = lhs.substring(1);\n          if (this.commandMap_[commandName] && this.commandMap_[commandName].user) {\n            delete this.commandMap_[commandName];\n            return true;\n          }\n        } else {\n          // Key to Ex or key to key mapping\n          var keys = lhs;\n          for (var i = 0; i < defaultKeymap.length; i++) {\n            if (keys == defaultKeymap[i].keys\n                && defaultKeymap[i].context === ctx) {\n              defaultKeymap.splice(i, 1);\n              return true;\n            }\n          }\n        }\n      }\n    };\n\n    var exCommands = {\n      colorscheme: function(cm, params) {\n        if (!params.args || params.args.length < 1) {\n          showConfirm(cm, cm.getOption('theme'));\n          return;\n        }\n        cm.setOption('theme', params.args[0]);\n      },\n      map: function(cm, params, ctx, defaultOnly) {\n        var mapArgs = params.args;\n        if (!mapArgs || mapArgs.length < 2) {\n          if (cm) {\n            showConfirm(cm, 'Invalid mapping: ' + params.input);\n          }\n          return;\n        }\n        exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx, defaultOnly);\n      },\n      imap: function(cm, params) { this.map(cm, params, 'insert'); },\n      nmap: function(cm, params) { this.map(cm, params, 'normal'); },\n      vmap: function(cm, params) { this.map(cm, params, 'visual'); },\n      omap: function(cm, params) { this.map(cm, params, 'operatorPending'); },\n      noremap: function(cm, params) { this.map(cm, params, undefined, true); },\n      inoremap: function(cm, params) { this.map(cm, params, 'insert', true); },\n      nnoremap: function(cm, params) { this.map(cm, params, 'normal', true); },\n      vnoremap: function(cm, params) { this.map(cm, params, 'visual', true); },\n      onoremap: function(cm, params) { this.map(cm, params, 'operatorPending', true); },\n      unmap: function(cm, params, ctx) {\n        var mapArgs = params.args;\n        if (!mapArgs || mapArgs.length < 1 || !exCommandDispatcher.unmap(mapArgs[0], ctx)) {\n          if (cm) {\n            showConfirm(cm, 'No such mapping: ' + params.input);\n          }\n        }\n      },\n      mapclear: function(cm, params) { vimApi.mapclear(); },\n      imapclear: function(cm, params) { vimApi.mapclear('insert'); },\n      nmapclear: function(cm, params) { vimApi.mapclear('normal'); },\n      vmapclear: function(cm, params) { vimApi.mapclear('visual'); },\n      omapclear: function(cm, params) { vimApi.mapclear('operatorPending'); },\n      move: function(cm, params) {\n        commandDispatcher.processCommand(cm, cm.state.vim, {\n            type: 'motion',\n            motion: 'moveToLineOrEdgeOfDocument',\n            motionArgs: { forward: false, explicitRepeat: true,\n              linewise: true },\n            repeatOverride: params.line+1});\n      },\n      set: function(cm, params) {\n        var setArgs = params.args;\n        // Options passed through to the setOption/getOption calls. May be passed in by the\n        // local/global versions of the set command\n        var setCfg = params.setCfg || {};\n        if (!setArgs || setArgs.length < 1) {\n          if (cm) {\n            showConfirm(cm, 'Invalid mapping: ' + params.input);\n          }\n          return;\n        }\n        var expr = setArgs[0].split('=');\n        var optionName = expr[0];\n        var value = expr[1];\n        var forceGet = false;\n        var forceToggle = false;\n\n        if (optionName.charAt(optionName.length - 1) == '?') {\n          // If post-fixed with ?, then the set is actually a get.\n          if (value) { throw Error('Trailing characters: ' + params.argString); }\n          optionName = optionName.substring(0, optionName.length - 1);\n          forceGet = true;\n        } else if (optionName.charAt(optionName.length - 1) == '!') {\n          optionName = optionName.substring(0, optionName.length - 1);\n          forceToggle = true;\n        }\n        if (value === undefined && optionName.substring(0, 2) == 'no') {\n          // To set boolean options to false, the option name is prefixed with\n          // 'no'.\n          optionName = optionName.substring(2);\n          value = false;\n        }\n\n        var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean';\n        if (optionIsBoolean) {\n          if (forceToggle) {\n            value = !getOption(optionName, cm, setCfg);\n          } else if (value == undefined) {\n            // Calling set with a boolean option sets it to true.\n            value = true;\n          }\n        }\n        // If no value is provided, then we assume this is a get.\n        if (!optionIsBoolean && value === undefined || forceGet) {\n          var oldValue = getOption(optionName, cm, setCfg);\n          if (oldValue instanceof Error) {\n            showConfirm(cm, oldValue.message);\n          } else if (oldValue === true || oldValue === false) {\n            showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName);\n          } else {\n            showConfirm(cm, '  ' + optionName + '=' + oldValue);\n          }\n        } else {\n          var setOptionReturn = setOption(optionName, value, cm, setCfg);\n          if (setOptionReturn instanceof Error) {\n            showConfirm(cm, setOptionReturn.message);\n          }\n        }\n      },\n      setlocal: function (cm, params) {\n        // setCfg is passed through to setOption\n        params.setCfg = {scope: 'local'};\n        this.set(cm, params);\n      },\n      setglobal: function (cm, params) {\n        // setCfg is passed through to setOption\n        params.setCfg = {scope: 'global'};\n        this.set(cm, params);\n      },\n      registers: function(cm, params) {\n        var regArgs = params.args;\n        var registers = vimGlobalState.registerController.registers;\n        var regInfo = '----------Registers----------\\n\\n';\n        if (!regArgs) {\n          for (var registerName in registers) {\n            var text = registers[registerName].toString();\n            if (text.length) {\n              regInfo += '\"' + registerName + '    ' + text + '\\n'\n            }\n          }\n        } else {\n          var registerName;\n          regArgs = regArgs.join('');\n          for (var i = 0; i < regArgs.length; i++) {\n            registerName = regArgs.charAt(i);\n            if (!vimGlobalState.registerController.isValidRegister(registerName)) {\n              continue;\n            }\n            var register = registers[registerName] || new Register();\n            regInfo += '\"' + registerName + '    ' + register.toString() + '\\n'\n          }\n        }\n        showConfirm(cm, regInfo);\n      },\n      sort: function(cm, params) {\n        var reverse, ignoreCase, unique, number, pattern;\n        function parseArgs() {\n          if (params.argString) {\n            var args = new CodeMirror.StringStream(params.argString);\n            if (args.eat('!')) { reverse = true; }\n            if (args.eol()) { return; }\n            if (!args.eatSpace()) { return 'Invalid arguments'; }\n            var opts = args.match(/([dinuox]+)?\\s*(\\/.+\\/)?\\s*/);\n            if (!opts && !args.eol()) { return 'Invalid arguments'; }\n            if (opts[1]) {\n              ignoreCase = opts[1].indexOf('i') != -1;\n              unique = opts[1].indexOf('u') != -1;\n              var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1;\n              var hex = opts[1].indexOf('x') != -1 && 1;\n              var octal = opts[1].indexOf('o') != -1 && 1;\n              if (decimal + hex + octal > 1) { return 'Invalid arguments'; }\n              number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';\n            }\n            if (opts[2]) {\n              pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : '');\n            }\n          }\n        }\n        var err = parseArgs();\n        if (err) {\n          showConfirm(cm, err + ': ' + params.argString);\n          return;\n        }\n        var lineStart = params.line || cm.firstLine();\n        var lineEnd = params.lineEnd || params.line || cm.lastLine();\n        if (lineStart == lineEnd) { return; }\n        var curStart = new Pos(lineStart, 0);\n        var curEnd = new Pos(lineEnd, lineLength(cm, lineEnd));\n        var text = cm.getRange(curStart, curEnd).split('\\n');\n        var numberRegex = pattern ? pattern :\n           (number == 'decimal') ? /(-?)([\\d]+)/ :\n           (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i :\n           (number == 'octal') ? /([0-7]+)/ : null;\n        var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null;\n        var numPart = [], textPart = [];\n        if (number || pattern) {\n          for (var i = 0; i < text.length; i++) {\n            var matchPart = pattern ? text[i].match(pattern) : null;\n            if (matchPart && matchPart[0] != '') {\n              numPart.push(matchPart);\n            } else if (!pattern && numberRegex.exec(text[i])) {\n              numPart.push(text[i]);\n            } else {\n              textPart.push(text[i]);\n            }\n          }\n        } else {\n          textPart = text;\n        }\n        function compareFn(a, b) {\n          if (reverse) { var tmp; tmp = a; a = b; b = tmp; }\n          if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); }\n          var anum = number && numberRegex.exec(a);\n          var bnum = number && numberRegex.exec(b);\n          if (!anum) { return a < b ? -1 : 1; }\n          anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix);\n          bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix);\n          return anum - bnum;\n        }\n        function comparePatternFn(a, b) {\n          if (reverse) { var tmp; tmp = a; a = b; b = tmp; }\n          if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); }\n          return (a[0] < b[0]) ? -1 : 1;\n        }\n        numPart.sort(pattern ? comparePatternFn : compareFn);\n        if (pattern) {\n          for (var i = 0; i < numPart.length; i++) {\n            numPart[i] = numPart[i].input;\n          }\n        } else if (!number) { textPart.sort(compareFn); }\n        text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart);\n        if (unique) { // Remove duplicate lines\n          var textOld = text;\n          var lastLine;\n          text = [];\n          for (var i = 0; i < textOld.length; i++) {\n            if (textOld[i] != lastLine) {\n              text.push(textOld[i]);\n            }\n            lastLine = textOld[i];\n          }\n        }\n        cm.replaceRange(text.join('\\n'), curStart, curEnd);\n      },\n      vglobal: function(cm, params) {\n        // global inspects params.commandName\n        this.global(cm, params);\n      },\n      normal: function(cm, params) {\n        var argString = params.argString;\n        if (argString && argString[0] == '!') {\n            argString = argString.slice(1);\n            noremap = true;\n        }\n        argString = argString.trimStart();\n        if (!argString) {\n          showConfirm(cm, 'Argument is required.');\n          return;\n        }\n        var line = params.line;\n        if (typeof line == 'number') {\n          var lineEnd = isNaN(params.lineEnd) ? line : params.lineEnd;\n          for (var i = line; i <= lineEnd; i++) {\n            cm.setCursor(i, 0);\n            doKeyToKey(cm, params.argString.trimStart());\n            if (cm.state.vim.insertMode) {\n              exitInsertMode(cm, true);\n            }\n          }\n        } else {\n          doKeyToKey(cm, params.argString.trimStart());\n          if (cm.state.vim.insertMode) {\n            exitInsertMode(cm, true);\n          }\n        }\n      },\n      global: function(cm, params) {\n        // a global command is of the form\n        // :[range]g/pattern/[cmd]\n        // argString holds the string /pattern/[cmd]\n        var argString = params.argString;\n        if (!argString) {\n          showConfirm(cm, 'Regular Expression missing from global');\n          return;\n        }\n        var inverted = params.commandName[0] === 'v';\n        if (argString[0] === '!' && params.commandName[0] === 'g') {\n          inverted = true;\n          argString = argString.slice(1);\n        }\n        // range is specified here\n        var lineStart = (params.line !== undefined) ? params.line : cm.firstLine();\n        var lineEnd = params.lineEnd || params.line || cm.lastLine();\n        // get the tokens from argString\n        var tokens = splitBySlash(argString);\n        var regexPart = argString, cmd;\n        if (tokens.length) {\n          regexPart = tokens[0];\n          cmd = tokens.slice(1, tokens.length).join('/');\n        }\n        if (regexPart) {\n          // If regex part is empty, then use the previous query. Otherwise\n          // use the regex part as the new query.\n          try {\n           updateSearchQuery(cm, regexPart, true /** ignoreCase */,\n             true /** smartCase */);\n          } catch (e) {\n           showConfirm(cm, 'Invalid regex: ' + regexPart);\n           return;\n          }\n        }\n        // now that we have the regexPart, search for regex matches in the\n        // specified range of lines\n        var query = getSearchState(cm).getQuery();\n        var matchedLines = [];\n        for (var i = lineStart; i <= lineEnd; i++) {\n          var line = cm.getLine(i);\n          var matched = query.test(line);\n          if (matched !== inverted) {\n            matchedLines.push(cmd ? cm.getLineHandle(i) : line);\n          }\n        }\n        // if there is no [cmd], just display the list of matched lines\n        if (!cmd) {\n          showConfirm(cm, matchedLines.join('\\n'));\n          return;\n        }\n        var index = 0;\n        var nextCommand = function() {\n          if (index < matchedLines.length) {\n            var lineHandle = matchedLines[index++];\n            var lineNum = cm.getLineNumber(lineHandle);\n            if (lineNum == null) {\n              nextCommand();\n              return;\n            }\n            var command = (lineNum + 1) + cmd;\n            exCommandDispatcher.processCommand(cm, command, {\n              callback: nextCommand\n            });\n          } else if (cm.releaseLineHandles) {\n            cm.releaseLineHandles();\n          }\n        };\n        nextCommand();\n      },\n      substitute: function(cm, params) {\n        if (!cm.getSearchCursor) {\n          throw new Error('Search feature not available. Requires searchcursor.js or ' +\n              'any other getSearchCursor implementation.');\n        }\n        var argString = params.argString;\n        var tokens = argString ? splitBySeparator(argString, argString[0]) : [];\n        var regexPart, replacePart = '', trailing, flagsPart, count;\n        var confirm = false; // Whether to confirm each replace.\n        var global = false; // True to replace all instances on a line, false to replace only 1.\n        if (tokens.length) {\n          regexPart = tokens[0];\n          if (getOption('pcre') && regexPart !== '') {\n              regexPart = new RegExp(regexPart).source; //normalize not escaped characters\n          }\n          replacePart = tokens[1];\n          if (replacePart !== undefined) {\n            if (getOption('pcre')) {\n              replacePart = unescapeRegexReplace(replacePart.replace(/([^\\\\])&/g,\"$1$$&\"));\n            } else {\n              replacePart = translateRegexReplace(replacePart);\n            }\n            vimGlobalState.lastSubstituteReplacePart = replacePart;\n          }\n          trailing = tokens[2] ? tokens[2].split(' ') : [];\n        } else {\n          // either the argString is empty or its of the form ' hello/world'\n          // actually splitBySlash returns a list of tokens\n          // only if the string starts with a '/'\n          if (argString && argString.length) {\n            showConfirm(cm, 'Substitutions should be of the form ' +\n                ':s/pattern/replace/');\n            return;\n          }\n        }\n        // After the 3rd slash, we can have flags followed by a space followed\n        // by count.\n        if (trailing) {\n          flagsPart = trailing[0];\n          count = parseInt(trailing[1]);\n          if (flagsPart) {\n            if (flagsPart.indexOf('c') != -1) {\n              confirm = true;\n            }\n            if (flagsPart.indexOf('g') != -1) {\n              global = true;\n            }\n            if (getOption('pcre')) {\n               regexPart = regexPart + '/' + flagsPart;\n            } else {\n               regexPart = regexPart.replace(/\\//g, \"\\\\/\") + '/' + flagsPart;\n            }\n          }\n        }\n        if (regexPart) {\n          // If regex part is empty, then use the previous query. Otherwise use\n          // the regex part as the new query.\n          try {\n            updateSearchQuery(cm, regexPart, true /** ignoreCase */,\n              true /** smartCase */);\n          } catch (e) {\n            showConfirm(cm, 'Invalid regex: ' + regexPart);\n            return;\n          }\n        }\n        replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart;\n        if (replacePart === undefined) {\n          showConfirm(cm, 'No previous substitute regular expression');\n          return;\n        }\n        var state = getSearchState(cm);\n        var query = state.getQuery();\n        var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;\n        var lineEnd = params.lineEnd || lineStart;\n        if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {\n          lineEnd = Infinity;\n        }\n        if (count) {\n          lineStart = lineEnd;\n          lineEnd = lineStart + count - 1;\n        }\n        var startPos = clipCursorToContent(cm, new Pos(lineStart, 0));\n        var cursor = cm.getSearchCursor(query, startPos);\n        doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback);\n      },\n      startinsert: function(cm, params) {\n        doKeyToKey(cm, params.argString == '!' ? 'A' : 'i', {});\n      },\n      redo: CodeMirror.commands.redo,\n      undo: CodeMirror.commands.undo,\n      write: function(cm) {\n        if (CodeMirror.commands.save) {\n          // If a save command is defined, call it.\n          CodeMirror.commands.save(cm);\n        } else if (cm.save) {\n          // Saves to text area if no save command is defined and cm.save() is available.\n          cm.save();\n        }\n      },\n      nohlsearch: function(cm) {\n        clearSearchHighlight(cm);\n      },\n      yank: function (cm) {\n        var cur = copyCursor(cm.getCursor());\n        var line = cur.line;\n        var lineText = cm.getLine(line);\n        vimGlobalState.registerController.pushText(\n          '0', 'yank', lineText, true, true);\n      },\n      delete: function(cm, params) {\n        var line = params.selectionLine;\n        var lineEnd = isNaN(params.selectionLineEnd) ? line : params.selectionLineEnd;\n        operators.delete(cm, {linewise: true}, [\n          { anchor: new Pos(line, 0),\n            head: new Pos(lineEnd + 1, 0) }\n        ]);\n      },\n      join: function(cm, params) {\n        var line = params.selectionLine;\n        var lineEnd = isNaN(params.selectionLineEnd) ? line : params.selectionLineEnd;\n        cm.setCursor(new Pos(line, 0));\n        actions.joinLines(cm, {repeat: lineEnd - line}, cm.state.vim);\n      },\n      delmarks: function(cm, params) {\n        if (!params.argString || !trim(params.argString)) {\n          showConfirm(cm, 'Argument required');\n          return;\n        }\n\n        var state = cm.state.vim;\n        var stream = new CodeMirror.StringStream(trim(params.argString));\n        while (!stream.eol()) {\n          stream.eatSpace();\n\n          // Record the streams position at the beginning of the loop for use\n          // in error messages.\n          var count = stream.pos;\n\n          if (!stream.match(/[a-zA-Z]/, false)) {\n            showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n            return;\n          }\n\n          var sym = stream.next();\n          // Check if this symbol is part of a range\n          if (stream.match('-', true)) {\n            // This symbol is part of a range.\n\n            // The range must terminate at an alphabetic character.\n            if (!stream.match(/[a-zA-Z]/, false)) {\n              showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n              return;\n            }\n\n            var startMark = sym;\n            var finishMark = stream.next();\n            // The range must terminate at an alphabetic character which\n            // shares the same case as the start of the range.\n            if (isLowerCase(startMark) && isLowerCase(finishMark) ||\n                isUpperCase(startMark) && isUpperCase(finishMark)) {\n              var start = startMark.charCodeAt(0);\n              var finish = finishMark.charCodeAt(0);\n              if (start >= finish) {\n                showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n                return;\n              }\n\n              // Because marks are always ASCII values, and we have\n              // determined that they are the same case, we can use\n              // their char codes to iterate through the defined range.\n              for (var j = 0; j <= finish - start; j++) {\n                var mark = String.fromCharCode(start + j);\n                delete state.marks[mark];\n              }\n            } else {\n              showConfirm(cm, 'Invalid argument: ' + startMark + '-');\n              return;\n            }\n          } else {\n            // This symbol is a valid mark, and is not part of a range.\n            delete state.marks[sym];\n          }\n        }\n      }\n    };\n\n    var exCommandDispatcher = new ExCommandDispatcher();\n\n    /**\n    * @param {CodeMirror} cm CodeMirror instance we are in.\n    * @param {boolean} confirm Whether to confirm each replace.\n    * @param {Cursor} lineStart Line to start replacing from.\n    * @param {Cursor} lineEnd Line to stop replacing at.\n    * @param {RegExp} query Query for performing matches with.\n    * @param {string} replaceWith Text to replace matches with. May contain $1,\n    *     $2, etc for replacing captured groups using JavaScript replace.\n    * @param {function()} callback A callback for when the replace is done.\n    */\n    function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query,\n        replaceWith, callback) {\n      // Set up all the functions.\n      cm.state.vim.exMode = true;\n      var done = false;\n      var lastPos, modifiedLineNumber, joined;\n      function replaceAll() {\n        cm.operation(function() {\n          while (!done) {\n            replace();\n            next();\n          }\n          stop();\n        });\n      }\n      function replace() {\n        var text = cm.getRange(searchCursor.from(), searchCursor.to());\n        var newText = text.replace(query, replaceWith);\n        var unmodifiedLineNumber = searchCursor.to().line;\n        searchCursor.replace(newText);\n        modifiedLineNumber = searchCursor.to().line;\n        lineEnd += modifiedLineNumber - unmodifiedLineNumber;\n        joined = modifiedLineNumber < unmodifiedLineNumber;\n      }\n      function findNextValidMatch() {\n        var lastMatchTo = lastPos && copyCursor(searchCursor.to());\n        var match = searchCursor.findNext();\n        if (match && !match[0] && lastMatchTo && cursorEqual(searchCursor.from(), lastMatchTo)) {\n          match = searchCursor.findNext();\n        }\n        return match;\n      }\n      function next() {\n        // The below only loops to skip over multiple occurrences on the same\n        // line when 'global' is not true.\n        while(findNextValidMatch() &&\n              isInRange(searchCursor.from(), lineStart, lineEnd)) {\n          if (!global && searchCursor.from().line == modifiedLineNumber && !joined) {\n            continue;\n          }\n          cm.scrollIntoView(searchCursor.from(), 30);\n          cm.setSelection(searchCursor.from(), searchCursor.to());\n          lastPos = searchCursor.from();\n          done = false;\n          return;\n        }\n        done = true;\n      }\n      function stop(close) {\n        if (close) { close(); }\n        cm.focus();\n        if (lastPos) {\n          cm.setCursor(lastPos);\n          var vim = cm.state.vim;\n          vim.exMode = false;\n          vim.lastHPos = vim.lastHSPos = lastPos.ch;\n        }\n        if (callback) { callback(); }\n      }\n      function onPromptKeyDown(e, _value, close) {\n        // Swallow all keys.\n        CodeMirror.e_stop(e);\n        var keyName = vimKeyFromEvent(e);\n        switch (keyName) {\n          case 'y':\n            replace(); next(); break;\n          case 'n':\n            next(); break;\n          case 'a':\n            // replaceAll contains a call to close of its own. We don't want it\n            // to fire too early or multiple times.\n            var savedCallback = callback;\n            callback = undefined;\n            cm.operation(replaceAll);\n            callback = savedCallback;\n            break;\n          case 'l':\n            replace();\n            // fall through and exit.\n          case 'q':\n          case '<Esc>':\n          case '<C-c>':\n          case '<C-[>':\n            stop(close);\n            break;\n        }\n        if (done) { stop(close); }\n        return true;\n      }\n\n      // Actually do replace.\n      next();\n      if (done) {\n        showConfirm(cm, 'No matches for ' + query.source);\n        return;\n      }\n      if (!confirm) {\n        replaceAll();\n        if (callback) { callback(); }\n        return;\n      }\n      showPrompt(cm, {\n        prefix: dom('span', 'replace with ', dom('strong', replaceWith), ' (y/n/a/q/l)'),\n        onKeyDown: onPromptKeyDown\n      });\n    }\n\n    function exitInsertMode(cm, keepCursor) {\n      var vim = cm.state.vim;\n      var macroModeState = vimGlobalState.macroModeState;\n      var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.');\n      var isPlaying = macroModeState.isPlaying;\n      var lastChange = macroModeState.lastInsertModeChanges;\n      if (!isPlaying) {\n        cm.off('change', onChange);\n        if (vim.insertEnd) vim.insertEnd.clear();\n        vim.insertEnd = null;\n        CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);\n      }\n      if (!isPlaying && vim.insertModeRepeat > 1) {\n        // Perform insert mode repeat for commands like 3,a and 3,o.\n        repeatLastEdit(cm, vim, vim.insertModeRepeat - 1,\n            true /** repeatForInsert */);\n        vim.lastEditInputState.repeatOverride = vim.insertModeRepeat;\n      }\n      delete vim.insertModeRepeat;\n      vim.insertMode = false;\n      if (!keepCursor) {\n        cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1);\n      }\n      cm.setOption('keyMap', 'vim');\n      cm.setOption('disableInput', true);\n      cm.toggleOverwrite(false); // exit replace mode if we were in it.\n      // update the \". register before exiting insert mode\n      insertModeChangeRegister.setText(lastChange.changes.join(''));\n      CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n      if (macroModeState.isRecording) {\n        logInsertModeChange(macroModeState);\n      }\n    }\n\n    function _mapCommand(command) {\n      defaultKeymap.unshift(command);\n    }\n\n    function mapCommand(keys, type, name, args, extra) {\n      var command = {keys: keys, type: type};\n      command[type] = name;\n      command[type + \"Args\"] = args;\n      for (var key in extra)\n        command[key] = extra[key];\n      _mapCommand(command);\n    }\n\n    // The timeout in milliseconds for the two-character ESC keymap should be\n    // adjusted according to your typing speed to prevent false positives.\n    defineOption('insertModeEscKeysTimeout', 200, 'number');\n\n\n    function executeMacroRegister(cm, vim, macroModeState, registerName) {\n      var register = vimGlobalState.registerController.getRegister(registerName);\n      if (registerName == ':') {\n        // Read-only register containing last Ex command.\n        if (register.keyBuffer[0]) {\n          exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);\n        }\n        macroModeState.isPlaying = false;\n        return;\n      }\n      var keyBuffer = register.keyBuffer;\n      var imc = 0;\n      macroModeState.isPlaying = true;\n      macroModeState.replaySearchQueries = register.searchQueries.slice(0);\n      for (var i = 0; i < keyBuffer.length; i++) {\n        var text = keyBuffer[i];\n        var match, key;\n        while (text) {\n          // Pull off one command key, which is either a single character\n          // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.\n          match = (/<\\w+-.+?>|<\\w+>|./).exec(text);\n          key = match[0];\n          text = text.substring(match.index + key.length);\n          vimApi.handleKey(cm, key, 'macro');\n          if (vim.insertMode) {\n            var changes = register.insertModeChanges[imc++].changes;\n            vimGlobalState.macroModeState.lastInsertModeChanges.changes =\n                changes;\n            repeatInsertModeChanges(cm, changes, 1);\n            exitInsertMode(cm);\n          }\n        }\n      }\n      macroModeState.isPlaying = false;\n    }\n\n    function logKey(macroModeState, key) {\n      if (macroModeState.isPlaying) { return; }\n      var registerName = macroModeState.latestRegister;\n      var register = vimGlobalState.registerController.getRegister(registerName);\n      if (register) {\n        register.pushText(key);\n      }\n    }\n\n    function logInsertModeChange(macroModeState) {\n      if (macroModeState.isPlaying) { return; }\n      var registerName = macroModeState.latestRegister;\n      var register = vimGlobalState.registerController.getRegister(registerName);\n      if (register && register.pushInsertModeChanges) {\n        register.pushInsertModeChanges(macroModeState.lastInsertModeChanges);\n      }\n    }\n\n    function logSearchQuery(macroModeState, query) {\n      if (macroModeState.isPlaying) { return; }\n      var registerName = macroModeState.latestRegister;\n      var register = vimGlobalState.registerController.getRegister(registerName);\n      if (register && register.pushSearchQuery) {\n        register.pushSearchQuery(query);\n      }\n    }\n\n    /**\n     * Listens for changes made in insert mode.\n     * Should only be active in insert mode.\n     */\n    function onChange(cm, changeObj) {\n      var macroModeState = vimGlobalState.macroModeState;\n      var lastChange = macroModeState.lastInsertModeChanges;\n      if (!macroModeState.isPlaying) {\n        var vim = cm.state.vim;\n        while(changeObj) {\n          lastChange.expectCursorActivityForChange = true;\n          if (lastChange.ignoreCount > 1) {\n            lastChange.ignoreCount--;\n          } else if (changeObj.origin == '+input' || changeObj.origin == 'paste'\n              || changeObj.origin === undefined /* only in testing */) {\n            var selectionCount = cm.listSelections().length;\n            if (selectionCount > 1)\n              lastChange.ignoreCount = selectionCount;\n            var text = changeObj.text.join('\\n');\n            if (lastChange.maybeReset) {\n              lastChange.changes = [];\n              lastChange.maybeReset = false;\n            }\n            if (text) {\n              if (cm.state.overwrite && !/\\n/.test(text)) {\n                lastChange.changes.push([text]);\n              } else {\n                if (text.length > 1) {\n                  var insertEnd = vim && vim.insertEnd && vim.insertEnd.find()\n                  var cursor = cm.getCursor();\n                  if (insertEnd && insertEnd.line == cursor.line) {\n                    var offset = insertEnd.ch - cursor.ch;\n                    if (offset > 0 && offset < text.length) {\n                      lastChange.changes.push([text, offset]);\n                      text = '';\n                    }\n                  }\n                }\n                if (text) lastChange.changes.push(text);\n              }\n            }\n          }\n          // Change objects may be chained with next.\n          changeObj = changeObj.next;\n        }\n      }\n    }\n\n    /**\n    * Listens for any kind of cursor activity on CodeMirror.\n    */\n    function onCursorActivity(cm) {\n      var vim = cm.state.vim;\n      if (vim.insertMode) {\n        // Tracking cursor activity in insert mode (for macro support).\n        var macroModeState = vimGlobalState.macroModeState;\n        if (macroModeState.isPlaying) { return; }\n        var lastChange = macroModeState.lastInsertModeChanges;\n        if (lastChange.expectCursorActivityForChange) {\n          lastChange.expectCursorActivityForChange = false;\n        } else {\n          // Cursor moved outside the context of an edit. Reset the change.\n          lastChange.maybeReset = true;\n          if (vim.insertEnd) vim.insertEnd.clear();\n          vim.insertEnd = cm.setBookmark(cm.getCursor(), {insertLeft: true});\n        }\n      } else if (!cm.curOp.isVimOp) {\n        handleExternalSelection(cm, vim);\n      }\n    }\n    function handleExternalSelection(cm, vim, keepHPos) {\n      var anchor = cm.getCursor('anchor');\n      var head = cm.getCursor('head');\n      // Enter or exit visual mode to match mouse selection.\n      if (vim.visualMode && !cm.somethingSelected()) {\n        exitVisualMode(cm, false);\n      } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {\n        vim.visualMode = true;\n        vim.visualLine = false;\n        CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\"});\n      }\n      if (vim.visualMode) {\n        // Bind CodeMirror selection model to vim selection model.\n        // Mouse selections are considered visual characterwise.\n        var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0;\n        var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0;\n        head = offsetCursor(head, 0, headOffset);\n        anchor = offsetCursor(anchor, 0, anchorOffset);\n        vim.sel = {\n          anchor: anchor,\n          head: head\n        };\n        updateMark(cm, vim, '<', cursorMin(head, anchor));\n        updateMark(cm, vim, '>', cursorMax(head, anchor));\n      } else if (!vim.insertMode && !keepHPos) {\n        // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse.\n        vim.lastHPos = cm.getCursor().ch;\n      }\n    }\n\n    /** Wrapper for special keys pressed in insert mode */\n    function InsertModeKey(keyName, e) {\n      this.keyName = keyName;\n      this.key = e.key;\n      this.ctrlKey = e.ctrlKey;\n      this.altKey = e.altKey;\n      this.metaKey = e.metaKey;\n      this.shiftKey = e.shiftKey;\n    }\n\n    /**\n    * Handles raw key down events from the text area.\n    * - Should only be active in insert mode.\n    * - For recording deletes in insert mode.\n    */\n    function onKeyEventTargetKeyDown(e) {\n      var macroModeState = vimGlobalState.macroModeState;\n      var lastChange = macroModeState.lastInsertModeChanges;\n      var keyName = CodeMirror.keyName ? CodeMirror.keyName(e) : e.key;\n      if (!keyName) { return; }\n      \n      if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) {\n        if (lastChange.maybeReset) {\n          lastChange.changes = [];\n          lastChange.maybeReset = false;\n        }\n        lastChange.changes.push(new InsertModeKey(keyName, e));\n      }\n    }\n\n    /**\n     * Repeats the last edit, which includes exactly 1 command and at most 1\n     * insert. Operator and motion commands are read from lastEditInputState,\n     * while action commands are read from lastEditActionCommand.\n     *\n     * If repeatForInsert is true, then the function was called by\n     * exitInsertMode to repeat the insert mode changes the user just made. The\n     * corresponding enterInsertMode call was made with a count.\n     */\n    function repeatLastEdit(cm, vim, repeat, repeatForInsert) {\n      var macroModeState = vimGlobalState.macroModeState;\n      macroModeState.isPlaying = true;\n      var isAction = !!vim.lastEditActionCommand;\n      var cachedInputState = vim.inputState;\n      function repeatCommand() {\n        if (isAction) {\n          commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand);\n        } else {\n          commandDispatcher.evalInput(cm, vim);\n        }\n      }\n      function repeatInsert(repeat) {\n        if (macroModeState.lastInsertModeChanges.changes.length > 0) {\n          // For some reason, repeat cw in desktop VIM does not repeat\n          // insert mode changes. Will conform to that behavior.\n          repeat = !vim.lastEditActionCommand ? 1 : repeat;\n          var changeObject = macroModeState.lastInsertModeChanges;\n          repeatInsertModeChanges(cm, changeObject.changes, repeat);\n        }\n      }\n      vim.inputState = vim.lastEditInputState;\n      if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) {\n        // o and O repeat have to be interlaced with insert repeats so that the\n        // insertions appear on separate lines instead of the last line.\n        for (var i = 0; i < repeat; i++) {\n          repeatCommand();\n          repeatInsert(1);\n        }\n      } else {\n        if (!repeatForInsert) {\n          // Hack to get the cursor to end up at the right place. If I is\n          // repeated in insert mode repeat, cursor will be 1 insert\n          // change set left of where it should be.\n          repeatCommand();\n        }\n        repeatInsert(repeat);\n      }\n      vim.inputState = cachedInputState;\n      if (vim.insertMode && !repeatForInsert) {\n        // Don't exit insert mode twice. If repeatForInsert is set, then we\n        // were called by an exitInsertMode call lower on the stack.\n        exitInsertMode(cm);\n      }\n      macroModeState.isPlaying = false;\n    }\n\n    function sendCmKey(cm, key) {\n      CodeMirror.lookupKey(key, 'vim-insert', function keyHandler(binding) {\n        if (typeof binding == 'string') {\n          CodeMirror.commands[binding](cm);\n        } else {\n          binding(cm);\n        }\n        return true;\n      });\n    }\n    function repeatInsertModeChanges(cm, changes, repeat) {\n      var head = cm.getCursor('head');\n      var visualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.visualBlock;\n      if (visualBlock) {\n        // Set up block selection again for repeating the changes.\n        selectForInsert(cm, head, visualBlock + 1);\n        repeat = cm.listSelections().length;\n        cm.setCursor(head);\n      }\n      for (var i = 0; i < repeat; i++) {\n        if (visualBlock) {\n          cm.setCursor(offsetCursor(head, i, 0));\n        }\n        for (var j = 0; j < changes.length; j++) {\n          var change = changes[j];\n          if (change instanceof InsertModeKey) {\n            sendCmKey(cm, change.keyName, change);\n          } else if (typeof change == \"string\") {\n            cm.replaceSelection(change);\n          } else {\n            var start = cm.getCursor();\n            var end = offsetCursor(start, 0, change[0].length - (change[1] || 0));\n            cm.replaceRange(change[0], start, change[1] ? start: end);\n            cm.setCursor(end);\n          }\n        }\n      }\n      if (visualBlock) {\n        cm.setCursor(offsetCursor(head, 0, 1));\n      }\n    }\n\n    // multiselect support\n  // Initialize Vim and make it available as an API.\n  CodeMirror.Vim = vimApi;\n\n  var specialKeyAce = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc',\n    left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space',insert: 'Ins',\n    home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR'\n  };\n  function lookupKey(hashId, key, e, vim) {\n    if (key.length > 1 && key[0] == \"n\") {\n      key = key.replace(\"numpad\", \"\");\n    }\n    key = specialKeyAce[key] || key;\n    var name = '';\n    if (e.ctrlKey) { name += 'C-'; }\n    if (e.altKey) { name += 'A-'; }\n    if ((name || key.length > 1) && e.shiftKey) { name += 'S-'; }\n\n    if (vim && !vim.expectLiteralNext && key.length == 1) {\n      if (langmap.keymap && key in langmap.keymap) {\n        if (langmap.remapCtrl !== false || !name)\n          key = langmap.keymap[key];\n      } else if (key.charCodeAt(0) > 255) {\n        var code = e.code && e.code.slice(-1) || \"\";\n        if (!e.shiftKey) code = code.toLowerCase();\n        if (code) key = code;\n      }\n    }\n\n    name += key;\n    if (name.length > 1) { name = '<' + name + '>'; }\n    return name;\n  }\n  var handleKey = vimApi.handleKey.bind(vimApi);\n  vimApi.handleKey = function(cm, key, origin) {\n    return cm.operation(function() {\n      return handleKey(cm, key, origin);\n    }, true);\n  }\n    function cloneVimState(state) {\n      var n = new state.constructor();\n      Object.keys(state).forEach(function(key) {\n        if (key == \"insertEnd\") return;\n        var o = state[key];\n        if (Array.isArray(o))\n          o = o.slice();\n        else if (o && typeof o == \"object\" && o.constructor != Object)\n          o = cloneVimState(o);\n        n[key] = o;\n      });\n      if (state.sel) {\n        n.sel = {\n          head: state.sel.head && copyCursor(state.sel.head),\n          anchor: state.sel.anchor && copyCursor(state.sel.anchor)\n        };\n      }\n      return n;\n    }\n    function multiSelectHandleKey(cm, key, origin) {\n      var isHandled = false;\n      var vim = vimApi.maybeInitVimState_(cm);\n      var visualBlock = vim.visualBlock || vim.wasInVisualBlock;\n\n      var wasMultiselect = cm.ace.inMultiSelectMode;\n      if (vim.wasInVisualBlock && !wasMultiselect) {\n        vim.wasInVisualBlock = false;\n      } else if (wasMultiselect && vim.visualBlock) {\n         vim.wasInVisualBlock = true;\n      }\n\n    if (key == '<Esc>' && !vim.insertMode && !vim.visualMode && wasMultiselect) {\n      cm.ace.exitMultiSelectMode();\n    } else if (visualBlock || !wasMultiselect || cm.ace.inVirtualSelectionMode) {\n      isHandled = vimApi.handleKey(cm, key, origin);\n      } else {\n        var old = cloneVimState(vim);\n        var changeQueueList = vim.inputState.changeQueueList || [];\n\n        cm.operation(function() {\n          cm.curOp.isVimOp = true;\n          var index = 0;\n          cm.ace.forEachSelection(function() {\n            var sel = cm.ace.selection;\n            cm.state.vim.lastHPos = sel.$desiredColumn == null ? sel.lead.column : sel.$desiredColumn;\n            cm.state.vim.inputState.changeQueue = changeQueueList[index];\n            var head = cm.getCursor(\"head\");\n            var anchor = cm.getCursor(\"anchor\");\n            var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0;\n            var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0;\n            head = offsetCursor(head, 0, headOffset);\n            anchor = offsetCursor(anchor, 0, anchorOffset);\n            cm.state.vim.sel.head = head;\n            cm.state.vim.sel.anchor = anchor;\n\n            isHandled = handleKey(cm, key, origin);\n            sel.$desiredColumn = cm.state.vim.lastHPos == -1 ? null : cm.state.vim.lastHPos;\n            // TODO why does cm.virtualSelectionMode check index?\n            if (cm.ace.inVirtualSelectionMode) {\n              changeQueueList[index] = cm.state.vim.inputState.changeQueue;\n            }\n            if (cm.virtualSelectionMode()) {\n              cm.state.vim = cloneVimState(old);\n            }\n            index++;\n          });\n          if (cm.curOp.cursorActivity && !isHandled)\n            cm.curOp.cursorActivity = false;\n          vim.status = cm.state.vim.status;\n          cm.state.vim = vim;\n          vim.inputState.changeQueueList = changeQueueList;\n          vim.inputState.changeQueue = null;\n        }, true);\n      }\n      // some commands may bring visualMode and selection out of sync\n      if (isHandled && !vim.visualMode && !vim.insert && vim.visualMode != cm.somethingSelected()) {\n        handleExternalSelection(cm, vim, true);\n      }\n      return isHandled;\n    }\n    resetVimGlobalState();\n\n\n  exports.CodeMirror = CodeMirror;\n  var getVim = vimApi.maybeInitVimState_;\n  exports.handler = {\n    $id: \"ace/keyboard/vim\",\n    drawCursor: function(element, pixelPos, config, sel, session) {\n      var vim = this.state.vim || {};\n      var w = config.characterWidth;\n      var h = config.lineHeight;\n      var top = pixelPos.top;\n      var left = pixelPos.left;\n      if (!vim.insertMode) {\n        var isbackwards = !sel.cursor\n            ? session.selection.isBackwards() || session.selection.isEmpty()\n            : Range.comparePoints(sel.cursor, sel.start) <= 0;\n        if (!isbackwards && left > w)\n          left -= w;\n      }\n      if (!vim.insertMode && vim.status) {\n        h = h / 2;\n        top += h;\n      }\n      domLib.translate(element, left, top);\n      domLib.setStyle(element.style, \"width\", w + \"px\");\n      domLib.setStyle(element.style, \"height\", h + \"px\");\n    },\n    $getDirectionForHighlight: function (editor) {\n      var cm = editor.state.cm;\n      var vim = getVim(cm);\n      if (!vim.insertMode) {\n        return editor.session.selection.isBackwards() || editor.session.selection.isEmpty();\n      }\n    },\n    handleKeyboard: function(data, hashId, key, keyCode, e) {\n      var editor = data.editor;\n      var cm = editor.state.cm;\n      var vim = getVim(cm);\n      if (keyCode == -1) return;\n\n      // in non-insert mode we try to find the ascii key corresponding to the text in textarea\n      // this is needed because in languages that use latin alphabet we want to get the key that browser sends to the textarea\n      // and in non\n      if (!vim.insertMode) {\n        if (hashId == -1) {\n          if (key.charCodeAt(0) > 0xFF) {\n            if (data.inputKey) {\n              key = data.inputKey;\n              if (key && data.inputHash == 4)\n                key = key.toUpperCase();\n            }\n          }\n          data.inputChar = key;\n        }\n        else if (hashId == 4 || hashId == 0) {\n          if (data.inputKey == key && data.inputHash == hashId && data.inputChar) {\n            // on mac text input doesn't repeat\n            key = data.inputChar;\n            hashId = -1\n          }\n          else {\n            data.inputChar = null;\n            data.inputKey = key;\n            data.inputHash = hashId;\n          }\n        }\n        else {\n          data.inputChar = data.inputKey = null;\n        }\n      }\n      \n      if (cm.state.overwrite && vim.insertMode && key == \"backspace\" && hashId == 0) {\n        return {command: \"gotoleft\"}\n      }\n\n      // ctrl-c is special it both exits mode and copies text\n      if (key == \"c\" && hashId == 1) { // key == \"ctrl-c\"\n        if (!useragent.isMac && editor.getCopyText()) {\n          editor.once(\"copy\", function() {\n            if (vim.insertMode) editor.selection.clearSelection();\n            else cm.operation(function() { exitVisualMode(cm); });\n          });\n          return {command: \"null\", passEvent: true};\n        }\n      }\n\n      if (key == \"esc\" && !vim.insertMode && !vim.visualMode && !cm.ace.inMultiSelectMode) {\n        var searchState = getSearchState(cm);\n        var overlay = searchState.getOverlay();\n        if (overlay) cm.removeOverlay(overlay);\n      }\n\n      if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) {\n        var insertMode = vim.insertMode;\n        var name = lookupKey(hashId, key, e || {}, vim);\n        if (vim.status == null)\n          vim.status = \"\";\n        var isHandled = multiSelectHandleKey(cm, name, 'user');\n        vim = getVim(cm); // may be changed by multiSelectHandleKey\n        if (isHandled && vim.status != null)\n          vim.status += name;\n        else if (vim.status == null)\n          vim.status = \"\";\n        cm._signal(\"changeStatus\");\n        if (!isHandled && (hashId != -1 || insertMode))\n          return;\n        return {command: \"null\", passEvent: !isHandled};\n      }\n    },\n    attach: function(editor) {\n      if (!editor.state) editor.state = {};\n      var cm = new CodeMirror(editor);\n      editor.state.cm = cm;\n      editor.$vimModeHandler = this;\n      enterVimMode(cm);\n      getVim(cm).status = null;\n      cm.on('vim-command-done', function() {\n        if (cm.virtualSelectionMode()) return;\n        getVim(cm).status = null;\n        cm.ace._signal(\"changeStatus\");\n        cm.ace.session.markUndoGroup();\n      });\n      cm.on(\"changeStatus\", function() {\n        cm.ace.renderer.updateCursor();\n        cm.ace._signal(\"changeStatus\");\n      });\n      cm.on(\"vim-mode-change\", function() {\n        if (cm.virtualSelectionMode()) return;\n        updateInputMode();\n        cm._signal(\"changeStatus\");\n      });\n      function updateInputMode() {\n        var isIntsert = getVim(cm).insertMode;\n        cm.ace.renderer.setStyle(\"normal-mode\", !isIntsert);\n        editor.textInput.setCommandMode(!isIntsert);\n        // without this press and hodl popup in mac is shown in normal mode\n        editor.renderer.$keepTextAreaAtCursor = isIntsert;\n        editor.renderer.$blockCursor = !isIntsert;\n      }\n      updateInputMode();\n      editor.renderer.$cursorLayer.drawCursor = this.drawCursor.bind(cm);\n    },\n    detach: function(editor) {\n      var cm = editor.state.cm;\n      leaveVimMode(cm);\n      cm.destroy();\n      editor.state.cm = null;\n      editor.$vimModeHandler = null;\n      editor.renderer.$cursorLayer.drawCursor = null;\n      editor.renderer.setStyle(\"normal-mode\", false);\n      editor.textInput.setCommandMode(false);\n      editor.renderer.$keepTextAreaAtCursor = true;\n    },\n    getStatusText: function(editor) {\n      var cm = editor.state.cm;\n      var vim = getVim(cm);\n      if (vim.insertMode)\n        return \"INSERT\";\n      var status = \"\";\n      if (vim.visualMode) {\n        status += \"VISUAL\";\n        if (vim.visualLine)\n          status += \" LINE\";\n        if (vim.visualBlock)\n          status += \" BLOCK\";\n      }\n      if (vim.status)\n        status += (status ? \" \" : \"\") + vim.status;\n      return status;\n    }\n  };\n  vimApi.defineOption({\n    name: \"wrap\",\n    set: function(value, cm) {\n      if (cm) {cm.ace.setOption(\"wrap\", value)}\n    },\n    type: \"boolean\"\n  }, false);\n  vimApi.defineEx('write', 'w', function() {\n    console.log(':write is not implemented')\n  });\n  defaultKeymap.push(\n    { keys: 'zc', type: 'action', action: 'fold', actionArgs: { open: false } },\n    { keys: 'zC', type: 'action', action: 'fold', actionArgs: { open: false, all: true } },\n    { keys: 'zo', type: 'action', action: 'fold', actionArgs: { open: true } },\n    { keys: 'zO', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },\n    { keys: 'za', type: 'action', action: 'fold', actionArgs: { toggle: true } },\n    { keys: 'zA', type: 'action', action: 'fold', actionArgs: { toggle: true, all: true } },\n    { keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },\n    { keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },\n\n    { keys: '<C-A-k>', type: 'action', action: 'aceCommand', actionArgs: { name: \"addCursorAbove\" } },\n    { keys: '<C-A-j>', type: 'action', action: 'aceCommand', actionArgs: { name: \"addCursorBelow\" } },\n    { keys: '<C-A-S-k>', type: 'action', action: 'aceCommand', actionArgs: { name: \"addCursorAboveSkipCurrent\" } },\n    { keys: '<C-A-S-j>', type: 'action', action: 'aceCommand', actionArgs: { name: \"addCursorBelowSkipCurrent\" } },\n    { keys: '<C-A-h>', type: 'action', action: 'aceCommand', actionArgs: { name: \"selectMoreBefore\" } },\n    { keys: '<C-A-l>', type: 'action', action: 'aceCommand', actionArgs: { name: \"selectMoreAfter\" } },\n    { keys: '<C-A-S-h>', type: 'action', action: 'aceCommand', actionArgs: { name: \"selectNextBefore\" } },\n    { keys: '<C-A-S-l>', type: 'action', action: 'aceCommand', actionArgs: { name: \"selectNextAfter\" } }\n  );\n  \n  defaultKeymap.push({\n    keys: 'gq',\n    type: 'operator',\n    operator: 'hardWrap'\n  });\n  vimApi.defineOperator(\"hardWrap\", function(cm, operatorArgs, ranges, oldAnchor, newHead) {\n    var anchor = ranges[0].anchor.line;\n    var head = ranges[0].head.line;\n    if (operatorArgs.linewise) head--;\n    hardWrap(cm.ace, {startRow: anchor, endRow: head});\n    return Pos(head, 0);\n  });\n  defineOption('textwidth', undefined, 'number', ['tw'], function(width, cm) {\n    // Option is local. Do nothing for global.\n    if (cm === undefined) {\n      return;\n    }\n    // The 'filetype' option proxies to the CodeMirror 'mode' option.\n    if (width === undefined) {\n      var value = cm.ace.getOption('printMarginColumn');\n      return value;\n    } else {\n      var column = Math.round(width);\n      if (column > 1) {\n        cm.ace.setOption('printMarginColumn', column);\n      }\n    }\n  });\n    \n  actions.aceCommand = function(cm, actionArgs, vim) {\n    cm.vimCmd = actionArgs;\n    if (cm.ace.inVirtualSelectionMode)\n      cm.ace.on(\"beforeEndOperation\", delayedExecAceCommand);\n    else\n      delayedExecAceCommand(null, cm.ace);\n  };\n  function delayedExecAceCommand(op, ace) {\n    ace.off(\"beforeEndOperation\", delayedExecAceCommand);\n    var cmd = ace.state.cm.vimCmd;\n    if (cmd) {\n      ace.execCommand(cmd.exec ? cmd : cmd.name, cmd.args);\n    }\n    ace.curOp = ace.prevOp;\n  }\n  actions.fold = function(cm, actionArgs, vim) {\n    cm.ace.execCommand(['toggleFoldWidget', 'toggleFoldWidget', 'foldOther', 'unfoldall'\n      ][(actionArgs.all ? 2 : 0) + (actionArgs.open ? 1 : 0)]);\n  };\n\n  defaultKeymapLength = defaultKeymap.length; // ace_patch\n\n  exports.handler.defaultKeymap = defaultKeymap;\n  exports.handler.actions = actions;\n  exports.Vim = vimApi;\n"
  },
  {
    "path": "src/keyboard/vim_ace_test.js",
    "content": "/*global CustomEvent*/\n \n\"use strict\";\n\nvar assert = require(\"./../test/assertions\");\nvar Range = require(\"../range\").Range;\nrequire(\"./../test/mockdom\");\nvar ace = require(\"../ace\");\nvar vim = require(\"./vim\");\nvar editor, changes, textarea;\nvar user = require(\"../test/user\");\n\nfunction testSelection(editor, data) {\n    assert.equal(getSelection(editor) + \"\", data + \"\");\n}\n\nfunction setSelection(editor, data) {\n    if (typeof data[0] == \"number\")\n        data = [data];\n    editor.selection.fromJSON(data.map(function(x) {\n        var start = {row: x[0], column: x[1]};\n        var end = x.length == 2 ? start : {row: x[2], column: x[3]};\n        var isBackwards = Range.comparePoints(start, end) > 0;\n        return isBackwards ? {\n            start: end,\n            end: start,\n            isBackwards: true\n        } : {\n            start: start,\n            end: end,\n            isBackwards: true\n        };\n    }));\n}\n\nfunction getSelection(editor) {\n    var data = editor.multiSelect.toJSON();\n    if (!data.length) data = [data];\n    data = data.map(function(x) {\n        var a, c;\n        if (x.isBackwards) {\n            a = x.end;\n            c = x.start;\n        } else {\n            c = x.end;\n            a = x.start;\n        }\n        return Range.comparePoints(a, c) \n            ? [a.row, a.column, c.row, c.column]\n            : [a.row, a.column];\n    });\n    return data.length > 1 ? data : data[0];\n}\n\nfunction testValue(editor, value) {\n    assert.equal(editor.getValue(), value);\n}\n\nfunction applyEvent(data) {\n    if (typeof data == \"function\")\n        return data();\n    \n    var type = data._;\n    var event = new CustomEvent(type);\n    for (var i in data.key || {})\n        event[i] = data.key[i];\n    data.modifier && data.modifier.split(\"-\").map(function(m) {\n        if (m) event[m + \"Key\"] = true;\n    });\n    if (/input|select|composition/.test(type)) {\n        textarea.value = data.value;\n        textarea.setSelectionRange(data.range[0], data.range[1]);\n    }\n    textarea.dispatchEvent(event); \n    if (data.value != null)\n        assert.equal(textarea.value, data.value);\n    \n    if (data.range != null) {\n        assert.equal(textarea.selectionStart, data.range[0]);\n        assert.equal(textarea.selectionEnd, data.range[1]);\n    }\n    editor.resize(true);\n}\n\nfunction scrollTop() {\n    editor.endOperation();\n    editor.renderer.$loop._flush();\n    return editor.renderer.scrollTop / editor.renderer.lineHeight;\n}\n\nmodule.exports = {\n    setUp: function() {\n        if (!editor) {\n            editor = ace.edit(null);\n            document.body.appendChild(editor.container);\n            editor.container.style.height = \"200px\";\n            editor.container.style.width = \"300px\";\n            editor.container.style.position = \"absolute\";\n            editor.container.style.outline = \"solid\";\n            editor.resize(true);\n            editor.on(\"change\", function(e) {\n                changes.push(e);\n            });\n            editor.setKeyboardHandler(vim.handler);\n        }\n        textarea = editor.textInput.getElement();\n        changes = [];\n        editor.focus();\n    },\n    tearDown: function() {\n        if (editor) {\n            editor.destroy();\n            editor.container.remove();\n            editor = textarea = null;\n        }\n    },\n    \"test: multiselect and composition\": function() {\n        editor.setValue(\"hello world\\n\\thello world\");\n        editor.execCommand(\"gotoend\");\n        [\n            { _: \"keydown\", range: [12,12], value: \"\\thello world\\n\\n\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [12,12], value: \"\\thello world\\n\\n\", key: { code: \"AltLeft\", key: \"Alt\", keyCode: 18}, modifier: \"ctrl-alt-\"},\n            { _: \"keydown\", range: [6,11], value: \"hello world\\n\\n\", key: { code: \"KeyL\", key: \"ﬁ\", keyCode: 76}, modifier: \"ctrl-alt-\"},\n\n            { _: \"keydown\", range: [6,11], value: \"hello world\\n\\n\", key: { code: \"KeyC\", key: \"c\", keyCode: 67}},\n            { _: \"input\", range: [7,7], value: \"hello c\\n\\n\"},\n            { _: \"keydown\", range: [7,7], value: \"hello c\\n\\n\", key: { code: \"KeyX\", key: \"x\", keyCode: 88}},\n            { _: \"input\", range: [8,8], value: \"hello cx\\n\\n\"},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"BracketRight\", key: \"Dead\", keyCode: 229}, modifier: \"shift-\"},\n            { _: \"compositionstart\", range: [6,6], value: \"hello x\\n\\n\"},\n            { _: \"compositionupdate\", range: [6,6], value: \"hello x\\n\\n\"},\n            { _: \"compositionend\", range: [7,7], value: \"hello ^x\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"hello ^x\\n\\n\"},\n            function() {\n                testSelection(editor, [[0,0],[1,1]]);\n            },\n            { _: \"keydown\", range: [7,7], value: \"hello ^x\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keydown\",  key: { code: \"KeyH\", key: \"˛\", keyCode: 72}, modifier: \"ctrl-alt-\"},\n\n            { _: \"keydown\", range: [1,6], value: \"\\thello x\\n\\n\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}, modifier: \"alt-\"},\n            { _: \"keydown\", range: [1,6], value: \"\\thello x\\n\\n\", key: { code: \"Digit4\", key: \"$\", keyCode: 52}, modifier: \"alt-\"},\n\n            { _: \"input\", range: [2,2], value: \"\\t$ x\\n\\n\"},\n            function() {\n                testSelection(editor, [[1,5,1,8], [0,4,0,7]]);\n            },\n            { _: \"keydown\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            function() {\n                testSelection(editor, [[1,7],[0,6]]);\n            },\n            { _: \"keydown\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n\n        ].forEach(function(data) {\n            applyEvent(data);\n        });\n        assert.equal(editor.getValue(), \"hello x\\n\\thello x\");\n    },\n    \"test: vim virtual selection\": function() {\n        editor.setValue(\"hello world\\n\\thello world\");\n        editor.execCommand(\"gotoend\");\n        [\n            { _: \"keydown\", range: [12,12], value: \"\\thello world\\n\\n\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n            { _: \"keydown\", range: [12,12], value: \"\\thello world\\n\\n\", key: { code: \"AltLeft\", key: \"Alt\", keyCode: 18}, modifier: \"ctrl-alt-\"},\n            { _: \"keydown\", range: [6,11], value: \"hello world\\n\\n\", key: { code: \"KeyL\", key: \"ﬁ\", keyCode: 76}, modifier: \"ctrl-alt-\"},\n\n            { _: \"keydown\", range: [6,11], value: \"hello world\\n\\n\", key: { code: \"KeyC\", key: \"c\", keyCode: 67}},\n            { _: \"input\", range: [7,7], value: \"hello c\\n\\n\"},\n            { _: \"keydown\", range: [7,7], value: \"hello c\\n\\n\", key: { code: \"KeyX\", key: \"x\", keyCode: 88}},\n            { _: \"input\", range: [8,8], value: \"hello cx\\n\\n\"},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}, modifier: \"shift-\"},\n            { _: \"keydown\", range: [6,6], value: \"hello x\\n\\n\", key: { code: \"BracketRight\", key: \"Dead\", keyCode: 229}, modifier: \"shift-\"},\n            { _: \"compositionstart\", range: [6,6], value: \"hello x\\n\\n\"},\n            { _: \"compositionupdate\", range: [6,6], value: \"hello x\\n\\n\"},\n            { _: \"compositionend\", range: [7,7], value: \"hello ^x\\n\\n\"},\n            { _: \"input\", range: [7,7], value: \"hello ^x\\n\\n\"},\n            function() {\n                testSelection(editor, [[0,0],[1,1]]);\n            },\n            { _: \"keydown\", range: [7,7], value: \"hello ^x\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keydown\",  key: { code: \"KeyH\", key: \"˛\", keyCode: 72}, modifier: \"ctrl-alt-\"},\n\n            { _: \"keydown\", range: [1,6], value: \"\\thello x\\n\\n\", key: { code: \"AltRight\", key: \"Alt\", keyCode: 18}, modifier: \"alt-\"},\n            { _: \"keydown\", range: [1,6], value: \"\\thello x\\n\\n\", key: { code: \"Digit4\", key: \"$\", keyCode: 52}, modifier: \"alt-\"},\n\n            { _: \"input\", range: [2,2], value: \"\\t$ x\\n\\n\"},\n            function() {\n                testSelection(editor, [[1,5,1,8], [0,4,0,7]]);\n            },\n            { _: \"keydown\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            function() {\n                testSelection(editor, [[1,7],[0,6]]);\n            },\n            { _: \"keydown\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n\n        ].forEach(function(data) {\n            applyEvent(data);\n        });\n        assert.equal(editor.getValue(), \"hello x\\n\\thello x\");\n    },\n    \"test: vim visual selection\": function() {\n        editor.setValue(\"xxx\\nccc\\n\\nzzz\\nccc\");\n        setSelection(editor, [2,0]);\n        [\n            { _: \"input\", range: [1,1], value: \"V\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \"V\\n\\n\", key: { code: \"KeyV\", key: \"V\", keyCode: 86}, modifier: \"shift-\"},\n            { _: \"keyup\", range: [1,1], value: \"V\\n\\n\", key: { code: \"ShiftLeft\", key: \"Shift\", keyCode: 16}},\n            { _: \"keydown\", range: [1,1], value: \"V\\n\\n\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keypress\", range: [1,1], value: \"V\\n\\n\", key: { code: \"KeyK\", key: \"k\", keyCode: 107}},\n            { _: \"input\", range: [2,2], value: \"Vk\\n\\n\"},\n            { _: \"keyup\", range: [2,2], value: \"Vk\\n\\n\", key: { code: \"KeyK\", key: \"k\", keyCode: 75}},\n            { _: \"keydown\", range: [2,2], value: \"Vk\\n\\n\", key: { code: \"KeyC\", key: \"c\", keyCode: 67}},\n            { _: \"keypress\", range: [2,2], value: \"Vk\\n\\n\", key: { code: \"KeyC\", key: \"c\", keyCode: 99}},\n            { _: \"input\", range: [3,3], value: \"Vkc\\n\\n\"},\n            { _: \"keyup\", range: [3,3], value: \"Vkc\\n\\n\", key: { code: \"KeyC\", key: \"c\", keyCode: 67}},\n            { _: \"keydown\", range: [3,3], value: \"Vkc\\n\\n\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            { _: \"keypress\", range: [3,3], value: \"Vkc\\n\\n\", key: { code: \"KeyO\", key: \"o\", keyCode: 111}},\n            { _: \"input\", range: [4,4], value: \"Vkco\\n\\n\"},\n            { _: \"keyup\", range: [4,4], value: \"Vkco\\n\\n\", key: { code: \"KeyO\", key: \"o\", keyCode: 79}},\n            function() {\n                testValue(editor, \"xxx\\nozzz\\nccc\")\n                testSelection(editor, [1,1])\n            },\n            { _: \"keydown\", range: [0,0], value: \"ozzz\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keyup\", range: [0,0], value: \"ozzz\\n\\n\", key: { code: \"Escape\", key: \"Escape\", keyCode: 27}},\n            { _: \"keydown\", range: [0,0], value: \"ozzz\\n\\n\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}, modifier: \"ctrl-\"},\n\n            { _: \"keydown\", range: [0,1], value: \"ozzz\\n\\n\", key: { code: \"KeyV\", key: \"v\", keyCode: 86}, modifier: \"ctrl-\"},\n            { _: \"select\", range: [0,1], value: \"ozzz\\n\\n\"},\n            { _: \"keyup\", range: [0,1], value: \"ozzz\\n\\n\", key: { code: \"KeyV\", key: \"v\", keyCode: 86}, modifier: \"ctrl-\"},\n            { _: \"keyup\", range: [0,1], value: \"ozzz\\n\\n\", key: { code: \"ControlLeft\", key: \"Control\", keyCode: 17}},\n\n            { _: \"keydown\", range: [0,1], value: \"ccc\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}},\n            { _: \"select\", range: [0,1], value: \"ccc\\n\\n\"},\n            { _: \"keyup\", range: [0,1], value: \"ccc\\n\\n\", key: { code: \"ArrowDown\", key: \"ArrowDown\", keyCode: 40}},\n            function() {\n                testValue(editor, \"xxx\\nozzz\\nccc\")\n                testSelection(editor, [[2,1,2,0],[1,1,1,0]])\n            },\n            { _: \"keydown\", range: [0,1], value: \"ccc\\n\\n\", key: { code: \"Period\", key: \".\", keyCode: 190}},\n            { _: \"keypress\", range: [0,1], value: \"ccc\\n\\n\", key: { code: \"Period\", key: \".\", keyCode: 46}},\n\n            { _: \"input\", range: [1,1], value: \".cc\\n\\n\"},\n            { _: \"keyup\", range: [1,1], value: \".cc\\n\\n\", key: { code: \"Period\", key: \".\", keyCode: 190}},\n            function() {\n                testValue(editor, \"xxx\\no\");\n                testSelection(editor, [1,0]);\n            }\n        ].forEach(function(data) {\n            applyEvent(data);\n        });\n    },\n    \"test vim gq\": function() {\n        editor.setValue(\n            \"1\\n2\\nhello world\\n\"\n             + \"xxx \".repeat(20) + \"\\nyyy\"\n             + \"\\n\\nnext\\nparagraph\"\n        );\n        editor.selection.moveTo(2,5)\n        editor.focus()\n        user.type(\"gqgq\")\n        assert.deepEqual(editor.getCursorPosition(), {row: 2, column: 0})\n        assert.equal(editor.session.getLine(2), \"hello world\")\n\n        user.type(\"gqj\")\n        assert.deepEqual(editor.getCursorPosition(), {row: 3, column: 0})\n        assert.equal(editor.session.getLine(3), \"xxx xxx xxx \")\n\n        user.type(\"gq}\")\n        assert.deepEqual(editor.getCursorPosition(), {row: 4, column: 0})\n        assert.equal(editor.session.getLine(3), \"xxx xxx xxx yyy\")\n\n        user.type(\"gqG\")\n        user.type(\"gqgg\")\n        user.type(\":set tw=15\\n\")\n\n        user.type(\"gg\")\n        user.type(\"V\")\n        user.type(\"gq\")\n        assert.equal(editor.session.getLine(0), \"1 2 hello world\")\n\n        assert.equal(editor.session.getLine(5), \"xxx xxx xxx xxx yyy\")\n        user.type(\":6\\n\")\n        user.type(\"gqq\")\n\n        assert.equal(editor.session.getLine(6), \"yyy\")\n    },\n    \"test vim search\": function() {\n        editor.renderer.setOption(\"animatedScroll\", false);\n        editor.setValue(\n            \"very\\nlong\\n\\ntext\\n\".repeat(10)\n            + \"needle \"\n            + \"some\\nmore\\ntext\\n\".repeat(6),\n            -1\n        );\n\n        editor.focus();\n        var screenSize = editor.renderer.layerConfig.height / editor.renderer.lineHeight;\n\n        user.type(\"Escape\", \"gg\");\n        assert.equal(scrollTop(), 0);\n        user.type(\"/\", \"needle\");\n        assert.ok(scrollTop() > 40 - screenSize);\n        editor.endOperation();\n        user.type(\"Escape\");\n        assert.equal(scrollTop(), 0);\n\n        user.type(\"/\", \"needle\", \"Enter\");\n        assert.ok(scrollTop() > 40 - screenSize);\n        assert.ok(scrollTop() < 40);\n        user.type(\"6\", \"/\", \"more\", \"Enter\");\n        editor.endOperation();\n        assert.ok(scrollTop() > 40 + 16 - screenSize);\n    },\n    \"test: vim normal mode brackets highlighting\": function () {\n        editor.setValue(\"{((hello, world))}\");\n        editor.focus();\n\n        var handler = editor.getKeyboardHandler();\n        var vimDirectionFunc = handler && handler.$getDirectionForHighlight;\n        assert.ok(vimDirectionFunc);\n        var values = [\n            {isBackwards: true, anchorRow: 0, anchorColumn: 0, cursorRow: 0, cursorColumn: 0,\n                startRow: 0, startColumn: 17, endRow: 0, endColumn: 18},\n            {isBackwards: true, anchorRow: 0, anchorColumn: 2, cursorRow: 0, cursorColumn: 2,\n                startRow: 0, startColumn: 15, endRow: 0, endColumn: 16},\n            {isBackwards: false, anchorRow: 0, anchorColumn: 15, cursorRow: 0, cursorColumn: 17,\n                startRow: 0, startColumn: 1, endRow: 0, endColumn: 2},\n            {isBackwards: true, anchorRow: 0, anchorColumn: 17, cursorRow: 0, cursorColumn: 16,\n                startRow: 0, startColumn: 1, endRow: 0, endColumn: 2}\n        ];\n        values.forEach((el) => {\n            editor.session.selection.$setSelection(el.anchorRow, el.anchorColumn, el.cursorRow, el.cursorColumn);\n            var isBackwards = vimDirectionFunc(editor);\n            assert.ok(isBackwards === el.isBackwards);\n            var ranges = editor.session.getMatchingBracketRanges({\n                row: el.cursorRow,\n                column: el.cursorColumn\n            }, isBackwards);\n            assert.range(ranges[1], el.startRow, el.startColumn, el.endRow, el.endColumn);\n        });\n    },\n    \"test: gotoline\": function () {\n        editor.renderer.setOption(\"animatedScroll\", false);\n        editor.setValue(\n            \"very\\nlong\\n\\ntext\\n\".repeat(20),\n            -1\n        );\n\n        editor.focus();\n        var screenSize = editor.renderer.layerConfig.height / editor.renderer.lineHeight;\n\n        assert.equal(scrollTop(), 0);\n        user.type(\":30\", \"Enter\");\n        editor.endOperation();\n\n        assert.ok(scrollTop() > 30 - screenSize);\n        assert.ok(scrollTop() < 30);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/vim_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\nvar EditSession = require(\"./../edit_session\").EditSession;\nvar Editor = require(\"../editor\").Editor;\nvar UndoManager = require(\"./../undomanager\").UndoManager;\nvar MockRenderer = require(\"./../test/mockrenderer\").MockRenderer;\nvar JavaScriptMode = require(\"./../mode/javascript\").Mode;\nvar CSSMode = require(\"./../mode/css\").Mode;\nvar XMLMode = require(\"./../mode/xml\").Mode;\nvar VirtualRenderer = require(\"./../virtual_renderer\").VirtualRenderer;\nvar assert = require(\"./../test/assertions\");\nvar keys = require(\"./../lib/keys\");\nvar vim = require(\"./vim\");\nvar isAce = true;\n\nvar el = document.createElement(\"div\");\nel.style.position = \"fixed\";\nel.style.left = \"320px\";\nel.style.top = \"30px\";\nel.style.width = \"500px\";\nel.style.height = \"300px\";\ndocument.body.appendChild(el);\n\nvar phantom = window.name == \"nodejs\";\n\nvar renderer = new VirtualRenderer(el);\nvar editor = window.editor = new Editor(renderer);\neditor.session.setUndoManager(new UndoManager());\nvar modes = {\n    js: new JavaScriptMode(),\n    css: new CSSMode(),\n    xml: new XMLMode()\n};\neditor.setOptions({\n    useWorker: false,\n    behavioursEnabled: false,\n});\nfunction CodeMirror(place, opts) {\n    if (!editor.container.parentNode) {\n        document.body.appendChild(editor.container);\n    }\n    var cm = editor.state && editor.state.cm;\n    if (cm && cm.state.currentNotificationClose)\n        cm.state.currentNotificationClose();\n    if (cm) cm.focus();\n    \n    editor.setKeyboardHandler(null);\n    editor.setKeyboardHandler(vim.handler);\n    cm = editor.state.cm;\n\n    if (opts.value != null)\n        editor.session.setValue(opts.value);\n    editor.setOption(\"indentedSoftWrap\", false);\n    editor.setOption(\"wrap\", opts.lineWrapping);\n    editor.setOption(\"useSoftTabs\", !opts.indentWithTabs);\n    editor.setOption(\"mode\", opts.mode ? modes[opts.mode] : modes.js);\n    cm.setOption(\"tabSize\", opts.tabSize || 4);\n    cm.setOption(\"indentUnit\", opts.indentUnit || 2);\n\n    cm.setSize = function(w, h) {\n        var changed = false;\n        if (w && editor.w != w) {\n            changed = true;\n            el.style.width = (editor.w = w) + \"px\";\n        }\n        if (h && editor.h != h) {\n            changed = true;\n            el.style.height = (editor.h = h) + \"px\";\n        }\n        if (changed)\n            editor.resize(true);\n    };\n    cm.setSize(500, 300);\n    return cm;\n}\nCodeMirror.defineMode = function() {}\nfor (var key in vim.CodeMirror)\n    CodeMirror[key] = vim.CodeMirror[key];\nvar editor;\nvar i = 0;\nfunction test(name, fn) {\n    // if (name != 'vim_search_history') return\n    // for (i = 0; i < 1000; i++)\n        // exports[\"test \" + name + i] = fn; // vim_ex_global_confirm\n    if (i++ < 0 || /-    /.test(name))\n        exports[\"test \" + name] = function() {};\n    else\n        exports[\"test \" + name] = fn;\n}\n\nvim.CodeMirror.Vim.unmap(\"Y\");\nvim.CodeMirror.Vim.defineEx('write', 'w', function(cm) {\n  CodeMirror.commands.save(cm);\n});\n\n\n\n// cm.setBookmark({ch: 5, line: 0})\n// cm.setBookmark({ch: 4, line: 0})\n// cm.replaceRange(\"x-\", {ch: 4, line: 0}, {ch: 5, line: 0}); [editor.$vimModeHandler.cm.marks[0].find(),editor.$vimModeHandler.cm.marks[1].find()]\n\nvar lineText, verbose = true;\n// ace_patch}\n\n\nfunction eqCursorPos(a, b) {\n  if (a.line != b.line || a.ch != b.ch)\n    throw failure(\n      \"Expected cursor position \" +\n       JSON.stringify([a.line, a.ch]) +\n       \" to be equal to \" +\n       JSON.stringify([b.line, b.ch]),\n       eqCursorPos\n      );\n}\nfunction eq(a, b, _reason) {\n  if(a != b)\n    throw failure(\"Expected \" + a +  \" to be equal to \" + b, eq);\n}\nfunction is(a) {\n  if (!a) throw failure(\"Expected \" + a +  \" to be truthy\", is);\n}\nfunction failure(message, root) {\n  var error = new Error(message);\n  if (Error.captureStackTrace)\n    Error.captureStackTrace(error, root);\n  return error;\n}\n\nvar Pos = CodeMirror.Pos;\nCodeMirror.Vim.suppressErrorLogging = true;\n\nvar isOldCodeMirror = /^5\\./.test(CodeMirror.version);\n\nvar code = '' +\n' wOrd1 (#%\\n' +\n' word3] \\n' +\n'aopop pop 0 1 2 3 4\\n' +\n' (a) [b] {c} \\n' +\n'int getchar(void) {\\n' +\n'  static char buf[BUFSIZ];\\n' +\n'  static char *bufp = buf;\\n' +\n'  if (n == 0) {  /* buffer is empty */\\n' +\n'    n = read(0, buf, sizeof buf);\\n' +\n'    bufp = buf;\\n' +\n'  }\\n' +\n'\\n' +\n'  return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\\n' +\n' \\n' +\n'}\\n';\n\nvar lines = (function() {\n  var lineText = code.split('\\n');\n  var ret = [];\n  for (var i = 0; i < lineText.length; i++) {\n    ret[i] = {\n      line: i,\n      length: lineText[i].length,\n      lineText: lineText[i],\n      textStart: /^\\s*/.exec(lineText[i])[0].length\n    };\n  }\n  return ret;\n})();\nvar endOfDocument = makeCursor(lines.length - 1,\n    lines[lines.length - 1].length);\nvar wordLine = lines[0];\nvar bigWordLine = lines[1];\nvar charLine = lines[2];\nvar bracesLine = lines[3];\nvar seekBraceLine = lines[4];\nvar foldingStart = lines[7];\nvar foldingEnd = lines[11];\n\nvar word1 = {\n  start: new Pos(wordLine.line, 1),\n  end: new Pos(wordLine.line, 5)\n};\nvar word2 = {\n  start: new Pos(wordLine.line, word1.end.ch + 2),\n  end: new Pos(wordLine.line, word1.end.ch + 4)\n};\nvar word3 = {\n  start: new Pos(bigWordLine.line, 1),\n  end: new Pos(bigWordLine.line, 5)\n};\nvar bigWord1 = word1;\nvar bigWord2 = word2;\nvar bigWord3 = {\n  start: new Pos(bigWordLine.line, 1),\n  end: new Pos(bigWordLine.line, 7)\n};\nvar bigWord4 = {\n  start: new Pos(bigWordLine.line, bigWord1.end.ch + 3),\n  end: new Pos(bigWordLine.line, bigWord1.end.ch + 7)\n};\n\nvar oChars = [ new Pos(charLine.line, 1),\n    new Pos(charLine.line, 3),\n    new Pos(charLine.line, 7) ];\nvar pChars = [ new Pos(charLine.line, 2),\n    new Pos(charLine.line, 4),\n    new Pos(charLine.line, 6),\n    new Pos(charLine.line, 8) ];\nvar numChars = [ new Pos(charLine.line, 10),\n    new Pos(charLine.line, 12),\n    new Pos(charLine.line, 14),\n    new Pos(charLine.line, 16),\n    new Pos(charLine.line, 18)];\nvar parens1 = {\n  start: new Pos(bracesLine.line, 1),\n  end: new Pos(bracesLine.line, 3)\n};\nvar squares1 = {\n  start: new Pos(bracesLine.line, 5),\n  end: new Pos(bracesLine.line, 7)\n};\nvar curlys1 = {\n  start: new Pos(bracesLine.line, 9),\n  end: new Pos(bracesLine.line, 11)\n};\nvar seekOutside = {\n  start: new Pos(seekBraceLine.line, 1),\n  end: new Pos(seekBraceLine.line, 16)\n};\nvar seekInside = {\n  start: new Pos(seekBraceLine.line, 14),\n  end: new Pos(seekBraceLine.line, 11)\n};\nvar foldingRangeDown = {\n  start: new Pos(foldingStart.line, 3),\n  end: new Pos(foldingEnd.line, 0)\n};\nvar foldingRangeUp = {\n  start: new Pos(foldingEnd.line, 0),\n  end: new Pos(foldingStart.line, 0)\n};\n\nfunction copyCursor(cur) {\n  return new Pos(cur.line, cur.ch);\n}\n\nfunction forEach(arr, func) {\n  for (var i = 0; i < arr.length; i++) {\n    func(arr[i], i, arr);\n  }\n}\n\nfunction vimKeyToKeyName(key) {\n  return key.replace(/[CS]-|CR|BS/g, function(part) {\n    return {\"C-\": \"Ctrl-\", \"S-\": \"Shift-\", CR: \"Return\", BS: \"Backspace\"}[part];\n  });\n}\n\nfunction testVim(name, run, opts, expectedFail) {\n  var vimOpts = {\n    lineNumbers: true,\n    vimMode: true,\n    showCursorWhenSelecting: true,\n    value: code\n  };\n  for (var prop in opts) {\n    if (opts.hasOwnProperty(prop)) {\n      vimOpts[prop] = opts[prop];\n    }\n  }\n  return test('vim_' + name, async function(done) {\n    var place = document.createElement(\"testground\"); //ace_patch\n    place.style.visibility = \"visible\";\n    var cm = CodeMirror(place, vimOpts);\n    var vim = CodeMirror.Vim.maybeInitVimState_(cm);\n    CodeMirror.Vim.mapclear();\n\n    cm.focus();\n    // workaround for cm5 slow polling in blurred window\n    Object.defineProperty(cm.state, \"focused\", {\n        set: function(e) {},\n        get: function() {\n            return document.activeElement == cm.getInputField();\n        }\n    });\n\n    var helpers = {\n      doKeys: function() {\n        var args = arguments[0]\n        if (!Array.isArray(args)) { args = arguments; }\n        for (var i = 0; i < args.length; i++) {\n          var key = args[i];\n          if (key.length > 1 && key[0] == \"<\" && key.slice(-1) == \">\") {\n              key = vimKeyToKeyName(key.slice(1, -1));\n          }\n          typeKey(key);\n        }\n      },\n      doEx: function(command) {\n        helpers.doKeys(':', command, '\\n');\n      },\n      assertCursorAt: function(line, ch) {\n        var pos;\n        if (ch == null && typeof line.line == 'number') {\n          pos = line;\n        } else {\n          pos = makeCursor(line, ch);\n        }\n        eqCursorPos(cm.getCursor(), pos);\n      },\n      getRegisterController: function() {\n        return CodeMirror.Vim.getRegisterController();\n      },\n      getNotificationText: function() {\n        var container = cm.getWrapperElement().querySelector(\".cm-vim-message\");\n        return container && container.textContent;\n      }\n    };\n    CodeMirror.Vim.resetVimGlobalState_();\n    var successful = false;\n    try {\n      await run(cm, vim, helpers);\n      successful = true;\n    } finally {\n      if (successful && !verbose) {\n        cm.getWrapperElement().remove();\n      }\n      done(successful ? null : true);\n    }\n  }, expectedFail);\n};\ntestVim('qq@q', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'q', 'l', 'l', 'q');\n  helpers.assertCursorAt(0,2);\n  helpers.doKeys('@', 'q');\n  helpers.assertCursorAt(0,4);\n}, { value: '            '});\ntestVim('@@', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'q', 'l', 'l', 'q');\n  helpers.assertCursorAt(0,2);\n  helpers.doKeys('@', 'q');\n  helpers.assertCursorAt(0,4);\n  helpers.doKeys('@', '@');\n  helpers.assertCursorAt(0,6);\n}, { value: '            '});\nvar jumplistScene = ''+\n  'word\\n'+\n  '(word)\\n'+\n  '{word\\n'+\n  'word.\\n'+\n  '\\n'+\n  'word search\\n'+\n  '}word\\n'+\n  'word\\n'+\n  'word\\n';\nfunction testJumplist(name, keys, endPos, startPos) {\n  endPos = makeCursor(endPos[0], endPos[1]);\n  startPos = makeCursor(startPos[0], startPos[1]);\n  testVim(name, function(cm, vim, helpers) {\n    CodeMirror.Vim.resetVimGlobalState_();\n    cm.setCursor(startPos);\n    helpers.doKeys.apply(null, keys);\n    helpers.assertCursorAt(endPos);\n  }, {value: jumplistScene});\n}\ntestJumplist('jumplist_H', ['H', '<C-o>'], [5,2], [5,2]);\ntestJumplist('jumplist_M', ['M', '<C-o>'], [2,2], [2,2]);\ntestJumplist('jumplist_L', ['L', '<C-o>'], [2,2], [2,2]);\ntestJumplist('jumplist_[[', ['[', '[', '<C-o>'], [5,2], [5,2]);\ntestJumplist('jumplist_]]', [']', ']', '<C-o>'], [2,2], [2,2]);\ntestJumplist('jumplist_G', ['G', '<C-o>'], [5,2], [5,2]);\ntestJumplist('jumplist_gg', ['g', 'g', '<C-o>'], [5,2], [5,2]);\ntestJumplist('jumplist_%', ['%', '<C-o>'], [1,5], [1,5]);\ntestJumplist('jumplist_{', ['{', '<C-o>'], [1,5], [1,5]);\ntestJumplist('jumplist_}', ['}', '<C-o>'], [1,5], [1,5]);\ntestJumplist('jumplist_\\'', ['m', 'a', 'h', '\\'', 'a', 'h', '<C-i>'], [1,0], [1,5]);\ntestJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', '<C-i>'], [1,5], [1,5]);\ntestJumplist('jumplist_*_cachedCursor', ['*', '<C-o>'], [1,3], [1,3]);\ntestJumplist('jumplist_#_cachedCursor', ['#', '<C-o>'], [1,3], [1,3]);\ntestJumplist('jumplist_n', ['#', 'n', '<C-o>'], [1,1], [2,3]);\ntestJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);\ntestJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);\ntestJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);\ntestJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);\ntestJumplist('jumplist_/', ['/', 'dialog\\n', '<C-o>'], [2,3], [2,3]);\ntestJumplist('jumplist_?', ['?', 'dialog\\n', '<C-o>'], [2,3], [2,3]);\ntestJumplist('jumplist_skip_deleted_mark<c-o>',\n             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],\n             [0,2], [0,2]);\ntestJumplist('jumplist_skip_deleted_mark<c-i>',\n             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],\n             [1,0], [0,2]);\n\n/**\n * @param name Name of the test\n * @param keys An array of keys or a string with a single key to simulate.\n * @param endPos The expected end position of the cursor.\n * @param startPos The position the cursor should start at, defaults to 0, 0.\n */\nfunction testMotion(name, keys, endPos, startPos) {\n  testVim(name, function(cm, vim, helpers) {\n    if (!startPos) {\n      startPos = new Pos(0, 0);\n    }\n    cm.setCursor(startPos);\n    helpers.doKeys(keys);\n    helpers.assertCursorAt(endPos);\n  });\n}\n\nfunction testMotionWithFolding(name, keys, endPos, startPos) {\n  testVim(name, function (cm, vim, helpers) {\n    cm.foldCode(startPos);\n    cm.foldCode(endPos);\n    cm.setCursor(startPos);\n    helpers.doKeys(keys);\n    helpers.assertCursorAt(endPos)\n  })\n}\n\nfunction makeCursor(line, ch) {\n  return new Pos(line, ch);\n}\n\nfunction offsetCursor(cur, offsetLine, offsetCh) {\n  return new Pos(cur.line + offsetLine, cur.ch + offsetCh);\n}\n\n// Motion tests\ntestMotion('|', '|', makeCursor(0, 0), makeCursor(0,4));\ntestMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4));\ntestMotion('h', 'h', makeCursor(0, 0), word1.start);\ntestMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end);\ntestMotion('l', 'l', makeCursor(0, 1));\ntestMotion('Space', 'Space', makeCursor(0, 1));\ntestMotion('l_repeat', ['2', 'l'], makeCursor(0, 2));\ntestMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end);\ntestMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end);\ntestMotion('j_repeat_clip', ['1000', 'j'], endOfDocument);\ntestMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end);\ntestMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4));\ntestMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4));\ntestMotion('w', 'w', word1.start);\ntestMotion('keepHPos', ['5', 'j', 'j', '7', 'k'], makeCursor(8, 12), makeCursor(12, 12));\ntestMotion('keepHPosEol', ['$', '2', 'j'], makeCursor(2, 18));\ntestMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2));\ntestMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51));\ntestMotion('w_repeat', ['2', 'w'], word2.start);\ntestMotion('w_wrap', ['w'], word3.start, word2.start);\ntestMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument);\ntestMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0));\ntestMotion('W', 'W', bigWord1.start);\ntestMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start);\ntestMotion('e', 'e', word1.end);\ntestMotion('e_repeat', ['2', 'e'], word2.end);\ntestMotion('e_wrap', 'e', word3.end, word2.end);\ntestMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument);\ntestMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0));\ntestMotion('b', 'b', word3.start, word3.end);\ntestMotion('b_repeat', ['2', 'b'], word2.start, word3.end);\ntestMotion('b_wrap', 'b', word2.start, word3.start);\ntestMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0));\ntestMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument);\ntestMotion('ge', ['g', 'e'], word2.end, word3.end);\ntestMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start);\ntestMotion('ge_wrap', ['g', 'e'], word2.end, word3.start);\ntestMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0),\n    makeCursor(0, 0));\ntestMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument);\ntestMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart),\n    makeCursor(3, 1));\ntestMotion('gg_repeat', ['3', 'g', 'g'],\n    makeCursor(lines[2].line, lines[2].textStart));\ntestMotion('G', 'G',\n    makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart),\n    makeCursor(3, 1));\ntestMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line,\n    lines[2].textStart));\n// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B.\ntestMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8));\ntestMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8));\ntestMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8));\ntestMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4));\ntestMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));\ntestMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));\ntestMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),\n    makeCursor(0, 3));\ntestMotion('$', ['v', '$'], makeCursor(0, lines[0].length), makeCursor(0, 1));\ntestMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));\ntestMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);\ntestMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));\ntestMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1),\n    makeCursor(charLine.line, 0));\ntestMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1),\n    pChars[0]);\ntestMotion('F', ['F', 'p'], pChars[0], pChars[1]);\ntestMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]);\ntestMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]);\ntestMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]);\ntestMotion('%_parens', ['%'], parens1.end, parens1.start);\ntestMotion('%_squares', ['%'], squares1.end, squares1.start);\ntestMotion('%_braces', ['%'], curlys1.end, curlys1.start);\ntestMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start);\ntestMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start);\n\n// Motion with folding tests\ntestMotionWithFolding('j_with_folding', 'j', foldingRangeDown.end, foldingRangeDown.start);\ntestMotionWithFolding('k_with_folding', 'k', foldingRangeUp.end, foldingRangeUp.start);\n\ntestVim('%_seek_skip', function(cm, vim, helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys(['%']);\n  helpers.assertCursorAt(0,9);\n}, {value:'01234\"(\"()'});\ntestVim('%_skip_string', function(cm, vim, helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys(['%']);\n  helpers.assertCursorAt(0,4);\n  cm.setCursor(0,2);\n  helpers.doKeys(['%']);\n  helpers.assertCursorAt(0,0);\n}, {value:'(\")\")'});\ntestVim('%_skip_comment', function(cm, vim, helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys(['%']);\n  helpers.assertCursorAt(0,6);\n  cm.setCursor(0,3);\n  helpers.doKeys(['%']);\n  helpers.assertCursorAt(0,0);\n}, {value:'(/*)*/)'});\n// Make sure that moving down after going to the end of a line always leaves you\n// at the end of a line, but preserves the offset in other cases\ntestVim('Changing lines after Eol operation', function(cm, vim, helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys(['$']);\n  helpers.doKeys(['j']);\n  // After moving to Eol and then down, we should be at Eol of line 2\n  helpers.assertCursorAt(new Pos(1, lines[1].length - 1));\n  helpers.doKeys(['j']);\n  // After moving down, we should be at Eol of line 3\n  helpers.assertCursorAt(new Pos(2, lines[2].length - 1));\n  helpers.doKeys(['h']);\n  helpers.doKeys(['j']);\n  // After moving back one space and then down, since line 4 is shorter than line 2, we should\n  // be at Eol of line 2 - 1\n  helpers.assertCursorAt(new Pos(3, lines[3].length - 1));\n  helpers.doKeys(['j']);\n  helpers.doKeys(['j']);\n  // After moving down again, since line 3 has enough characters, we should be back to the\n  // same place we were at on line 1\n  helpers.assertCursorAt(new Pos(5, lines[2].length - 2));\n});\n//making sure gj and gk recover from clipping\ntestVim('gj_gk_clipping', function(cm,vim,helpers){\n  cm.setCursor(0, 1);\n  helpers.doKeys('g','j','g','j');\n  helpers.assertCursorAt(2, 1);\n  helpers.doKeys('g','k','g','k');\n  helpers.assertCursorAt(0, 1);\n},{value: 'line 1\\n\\nline 2'});\n//testing a mix of j/k and gj/gk\ntestVim('j_k_and_gj_gk', function(cm,vim,helpers){\n  cm.setSize(120);\n  cm.setCursor(0, 0);\n  //go to the last character on the first line\n  helpers.doKeys('$');\n  //move up/down on the column within the wrapped line\n  //side-effect: cursor is not locked to eol anymore\n  helpers.doKeys('g','k');\n  var cur=cm.getCursor();\n  eq(cur.line,0);\n  is((cur.ch<176),'gk didn\\'t move cursor back (1)');\n  helpers.doKeys('g','j');\n  helpers.assertCursorAt(0, 176);\n  //should move to character 177 on line 2 (j/k preserve character index within line)\n  helpers.doKeys('j');\n  //due to different line wrapping, the cursor can be on a different screen-x now\n  //gj and gk preserve screen-x on movement, much like moveV\n  helpers.doKeys('3','g','k');\n  cur=cm.getCursor();\n  eq(cur.line,1);\n  is((cur.ch<176),'gk didn\\'t move cursor back (2)');\n  helpers.doKeys('g','j','2','g','j');\n  //should return to the same character-index\n  helpers.doKeys('k');\n  helpers.assertCursorAt(0, 176);\n},{ lineWrapping:true, value: 'This line is intentionally long. It tests movements of gj and gk over wrapped lines. Starts on the end of this line, then makes a step up and back to set the origin for j and k.\\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\\'s target character but both j/k and gj/gk change each other\\'s reference position.'});\ntestVim('gj_gk', function(cm, vim, helpers) {\n  cm.setSize(120);\n  // Test top of document edge case.\n  cm.setCursor(0, 4);\n  helpers.doKeys('g', 'j');\n  helpers.doKeys('10', 'g', 'k');\n  helpers.assertCursorAt(0, 4);\n\n  // Test moving down preserves column position.\n  helpers.doKeys('g', 'j');\n  var pos1 = cm.getCursor();\n  var expectedPos2 = new Pos(0, (pos1.ch - 4) * 2 + 4);\n  helpers.doKeys('g', 'j');\n  helpers.assertCursorAt(expectedPos2);\n\n  // Move to the last character\n  cm.setCursor(0, 0);\n  // Move left to reset HSPos\n  helpers.doKeys('h');\n  // Test bottom of document edge case.\n  helpers.doKeys('100', 'g', 'j');\n  var endingPos = cm.getCursor();\n  is(endingPos.ch != 0, 'gj should not be on wrapped line 0');\n  var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));\n  var endingCharCoords = cm.charCoords(endingPos);\n  is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');\n},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' });\ntestVim('g0_g$', function(cm, vim, helpers) {\n  cm.setSize(120);\n  var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));\n  cm.setCursor(0, 4);\n  helpers.doKeys('g', 'Down');\n  var secondLineCoords = cm.charCoords(cm.getCursor());\n  is(secondLineCoords.top > topLeftCharCoords.top);\n  is(secondLineCoords.left > topLeftCharCoords.left);\n\n  helpers.doKeys('g', '0');\n  var start = cm.getCursor();\n  var startCoords = cm.charCoords(start);\n  is(start.ch != 0);\n  is(startCoords.left == topLeftCharCoords.left);\n  is(secondLineCoords.top === startCoords.top);\n  is(secondLineCoords.left > startCoords.left);\n\n  helpers.doKeys('g', '$');\n  var end = cm.getCursor();\n  var endCoords = cm.charCoords(end);\n  is(startCoords.left < endCoords.left);\n  is(startCoords.top == endCoords.top);\n  is(start.ch < end.ch && end.ch < cm.getValue().length / 2);\n  is(/\\.$/.test(cm.getValue()));\n  helpers.doKeys('$', 'g', '0', 'd', 'g', '$');\n  is(!/\\.$/.test(cm.getValue()));\n  \n},{ lineNumbers: false, lineWrapping:true, value: 'This line is long to test movement of g$ and g0 over wrapped lines...' });\ntestVim('}', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('}');\n  helpers.assertCursorAt(1, 0);\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', '}');\n  helpers.assertCursorAt(4, 0);\n  cm.setCursor(0, 0);\n  helpers.doKeys('6', '}');\n  helpers.assertCursorAt(5, 0);\n}, { value: 'a\\n\\nb\\nc\\n\\nd' });\ntestVim('{', function(cm, vim, helpers) {\n  cm.setCursor(5, 0);\n  helpers.doKeys('{');\n  helpers.assertCursorAt(4, 0);\n  cm.setCursor(5, 0);\n  helpers.doKeys('2', '{');\n  helpers.assertCursorAt(1, 0);\n  cm.setCursor(5, 0);\n  helpers.doKeys('6', '{');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'a\\n\\nb\\nc\\n\\nd' });\ntestVim('(', function(cm, vim, helpers) {\n  cm.setCursor(6, 23);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(6, 14);\n  helpers.doKeys('2', '(');\n  helpers.assertCursorAt(5, 0);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(4, 0);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(3, 0);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(2, 0);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('(');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'sentence1.\\n\\n\\nsentence2\\n\\nsentence3. sentence4\\n   sentence5? sentence6!' });\ntestVim(')', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', ')');\n  helpers.assertCursorAt(3, 0);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(4, 0);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(5, 0);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(5, 11);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(6, 14);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(6, 23);\n  helpers.doKeys(')');\n  helpers.assertCursorAt(6, 23);\n}, { value: 'sentence1.\\n\\n\\nsentence2\\n\\nsentence3. sentence4\\n   sentence5? sentence6!' });\ntestVim('paragraph_motions', function(cm, vim, helpers) {\n  cm.setCursor(10, 0);\n  helpers.doKeys('{');\n  helpers.assertCursorAt(4, 0);\n  helpers.doKeys('{');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('2', '}');\n  helpers.assertCursorAt(7, 0);\n  helpers.doKeys('2', '}');\n  helpers.assertCursorAt(16, 0);\n\n  cm.setCursor(9, 0);\n  helpers.doKeys('}');\n  helpers.assertCursorAt(14, 0);\n\n  cm.setCursor(6, 0);\n  helpers.doKeys('}');\n  helpers.assertCursorAt(7, 0);\n\n  // ip inside empty space\n  cm.setCursor(10, 0);\n  helpers.doKeys('v', 'i', 'p');\n  eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(12, 0), cm.getCursor('head'));\n  helpers.doKeys('i', 'p');\n  eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(13, 1), cm.getCursor('head'));\n  helpers.doKeys('2', 'i', 'p');\n  eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(16, 1), cm.getCursor('head'));\n\n  // should switch to visualLine mode\n  cm.setCursor(14, 0);\n  helpers.doKeys('<Esc>', 'v', 'i', 'p');\n  helpers.assertCursorAt(14, 0);\n\n  cm.setCursor(14, 0);\n  helpers.doKeys('<Esc>', 'V', 'i', 'p');\n  eqCursorPos(new Pos(16, 1), cm.getCursor('head'));\n\n  // ap inside empty space\n  cm.setCursor(10, 0);\n  helpers.doKeys('<Esc>', 'v', 'a', 'p');\n  eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(13, 1), cm.getCursor('head'));\n  helpers.doKeys('a', 'p');\n  eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(16, 1), cm.getCursor('head'));\n\n  cm.setCursor(13, 0);\n  helpers.doKeys('v', 'a', 'p');\n  eqCursorPos(new Pos(13, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(14, 0), cm.getCursor('head'));\n\n  cm.setCursor(16, 0);\n  helpers.doKeys('v', 'a', 'p');\n  eqCursorPos(new Pos(14, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(16, 1), cm.getCursor('head'));\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'a', 'p');\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(4, 0), cm.getCursor('head'));\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'i', 'p');\n  var register = helpers.getRegisterController().getRegister();\n  eq('a\\na\\n', register.toString());\n  is(register.linewise);\n  helpers.doKeys('3', 'j', 'p');\n  helpers.doKeys('y', 'i', 'p');\n  is(register.linewise);\n  eq('b\\na\\na\\nc\\n', register.toString());\n}, { value: 'a\\na\\n\\n\\n\\nb\\nc\\n\\n\\n\\n\\n\\n\\nd\\n\\ne\\nf' });\n\ntestVim('sentence_selections', function(cm, vim, helpers) {\n  // vis at beginning of line\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'i', 's');\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(0, 14), cm.getCursor('head'));\n\n  // vas at beginning of line\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'a', 's');\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(0, 15), cm.getCursor('head'));\n\n  // vis on sentence end\n  cm.setCursor(0, 13);\n  helpers.doKeys('v', 'i', 's');\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(0, 14), cm.getCursor('head'));\n\n  // vas on sentence end\n  cm.setCursor(0, 13);\n  helpers.doKeys('v', 'a', 's');\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(0, 15), cm.getCursor('head'));\n\n  // vis at sentence end, no whitespace after it\n  cm.setCursor(1, 18);\n  helpers.doKeys('v', 'i', 's');\n  eqCursorPos(new Pos(1, 13), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(1, 19), cm.getCursor('head'));\n\n  // vas at sentence end, no whitespace after it\n  cm.setCursor(1, 18);\n  helpers.doKeys('v', 'a', 's');\n  eqCursorPos(new Pos(1, 12), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(1, 19), cm.getCursor('head'));\n\n  // vis at sentence beginning, on whitespace\n  cm.setCursor(0, 14);\n  helpers.doKeys('v', 'i', 's');\n  eqCursorPos(new Pos(0, 14), cm.getCursor('anchor'));\n  eqCursorPos(new Pos(0, 29), cm.getCursor('head'));\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'i', 's');\n  var register = helpers.getRegisterController().getRegister();\n  eq('Test sentence.', register.toString());\n\n  // return to original value\n  helpers.doKeys('u')\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'a', 's');\n  register = helpers.getRegisterController().getRegister();\n  eq('Test sentence. ', register.toString());\n\n  // return to original value\n  helpers.doKeys('u')\n\n  cm.setCursor(1, 20);\n  helpers.doKeys('c', 'a', 's', '<Esc>');\n  register = helpers.getRegisterController().getRegister();\n  eq('Test.', register.toString());\n\n  // return to original value\n  helpers.doKeys('u')\n\n  cm.setCursor(3, 11);\n  helpers.doKeys('y', 'a', 's');\n  register = helpers.getRegisterController().getRegister();\n  eq('This is more text. ', register.toString());\n\n  cm.setCursor(3, 31);\n  helpers.doKeys('y', 'a', 's');\n  register = helpers.getRegisterController().getRegister();\n  eq(' No end of sentence symbol', register.toString());\n\n}, { value: 'Test sentence. Test question?\\nAgain.Never. Again.Test.\\n\\nHello. This is more text. No end of sentence symbol\\n' });\n\ntestVim('w_text_object_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('v', '3', 'a', 'w');\n  eq('w1  ++  w_2   ', cm.getSelection());\n  helpers.doKeys('<Esc>', 'v', 'a', 'w');\n  eq('   \\n w3', cm.getSelection());\n  \n  helpers.doKeys('2', 'a', 'w');\n  eq('   \\n w3   xx \\n', cm.getSelection());\n  helpers.doKeys('a', 'w');\n  eq('   \\n w3   xx \\n\\nw4', cm.getSelection());\n\n  cm.setValue(\"  w0 word1  word2  word3    word4\")\n  cm.setCursor(0, 8);\n  helpers.doKeys('c', '3', 'a', 'w');\n  eq('  w0 word4', cm.getValue());\n}, { value: ' w1  ++  w_2   \\n w3   xx \\n\\nw4\\nword5\\nword6' });\n\n// Operator tests\ntestVim('dl', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 0);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'l');\n  eq('word1 ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' ', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1 ' });\ntestVim('dl_eol', function(cm, vim, helpers) {\n  cm.setCursor(0, 6);\n  helpers.doKeys('d', 'l');\n  eq(' word1', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' ', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 5);\n}, { value: ' word1 ' });\ntestVim('dl_repeat', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 0);\n  cm.setCursor(curStart);\n  helpers.doKeys('2', 'd', 'l');\n  eq('ord1 ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' w', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1 ' });\ntestVim('dh', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'h');\n  eq(' wrd1 ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('o', register.toString());\n  is(!register.linewise);\n  eqCursorPos(offsetCursor(curStart, 0 , -1), cm.getCursor());\n}, { value: ' word1 ' });\ntestVim('dj', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'j');\n  eq(' word3', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' word1\\nword2\\n', register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, 1);\n}, { value: ' word1\\nword2\\n word3' });\ntestVim('dj_end_of_document', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'j');\n  eq('', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' word1 \\n', register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1 ' });\ntestVim('dk', function(cm, vim, helpers) {\n  var curStart = makeCursor(1, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'k');\n  eq(' word3', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' word1\\nword2\\n', register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, 1);\n}, { value: ' word1\\nword2\\n word3' });\ntestVim('dk_start_of_document', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'k');\n  eq('', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' word1 \\n', register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1 ' });\ntestVim('dw_space', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 0);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'w');\n  eq('word1 ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' ', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1 ' });\ntestVim('dw_word', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 1);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'w');\n  eq(' word2', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1 ', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1 word2' });\ntestVim('dw_unicode_word', function(cm, vim, helpers) {\n  helpers.doKeys('d', 'w');\n  eq(cm.getValue().length, 10);\n  helpers.doKeys('d', 'w');\n  eq(cm.getValue().length, 6);\n  helpers.doKeys('d', 'w');\n  eq(cm.getValue().length, 5);\n  helpers.doKeys('d', 'e');\n  eq(cm.getValue().length, 2);\n}, { value: '  \\u0562\\u0561\\u0580\\u0587\\xbbe\\xb5g  ' });\ntestVim('dw_only_word', function(cm, vim, helpers) {\n  // Test that if there is only 1 word left, dw deletes till the end of the\n  // line.\n  cm.setCursor(0, 1);\n  helpers.doKeys('d', 'w');\n  eq(' ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1 ', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1 ' });\ntestVim('dw_eol', function(cm, vim, helpers) {\n  // Assert that dw does not delete the newline if last word to delete is at end\n  // of line.\n  cm.setCursor(0, 1);\n  helpers.doKeys('d', 'w');\n  eq(' \\nword2', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1\\nword2' });\ntestVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) {\n  // Assert that dw does not delete the newline if last word to delete is at end\n  // of line and it is followed by multiple newlines.\n  cm.setCursor(0, 1);\n  helpers.doKeys('d', 'w');\n  eq(' \\n\\nword2', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1\\n\\nword2' });\ntestVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('  \\nword', cm.getValue());\n}, { value: '\\n  \\nword' });\ntestVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('word', cm.getValue());\n}, { value: '\\nword' });\ntestVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('\\n', cm.getValue());\n}, { value: '\\n\\n' });\ntestVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('\\n   \\n', cm.getValue());\n}, { value: '  \\n   \\n' });\ntestVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('\\n\\n', cm.getValue());\n}, { value: '  \\n\\n' });\ntestVim('dw_word_whitespace_word', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'w');\n  eq('\\n   \\nword2', cm.getValue());\n}, { value: 'word1\\n   \\nword2'})\ntestVim('dw_end_of_document', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('d', 'w');\n  eq('\\nab', cm.getValue());\n}, { value: '\\nabc' });\ntestVim('dw_repeat', function(cm, vim, helpers) {\n  // Assert that dw does delete newline if it should go to the next line, and\n  // that repeat works properly.\n  cm.setCursor(0, 1);\n  helpers.doKeys('d', '2', 'w');\n  eq(' ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1\\nword2', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 0);\n}, { value: ' word1\\nword2' });\ntestVim('de_word_start_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'e');\n  eq('\\n\\n', cm.getValue());\n}, { value: 'word\\n\\n' });\ntestVim('de_word_end_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('d', 'e');\n  eq('wor', cm.getValue());\n}, { value: 'word\\n\\n\\n' });\ntestVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'e');\n  eq('', cm.getValue());\n}, { value: '   \\n\\n\\n' });\ntestVim('de_end_of_document', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('d', 'e');\n  eq('\\nab', cm.getValue());\n}, { value: '\\nabc' });\ntestVim('db_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('d', 'b');\n  eq('\\n\\n', cm.getValue());\n}, { value: '\\n\\n\\n' });\ntestVim('db_word_start_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('d', 'b');\n  eq('\\nword', cm.getValue());\n}, { value: '\\n\\nword' });\ntestVim('db_word_end_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(2, 3);\n  helpers.doKeys('d', 'b');\n  eq('\\n\\nd', cm.getValue());\n}, { value: '\\n\\nword' });\ntestVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('d', 'b');\n  eq('', cm.getValue());\n}, { value: '\\n   \\n' });\ntestVim('db_start_of_document', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'b');\n  eq('abc\\n', cm.getValue());\n}, { value: 'abc\\n' });\ntestVim('dge_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doKeys('d', 'g', 'e');\n  // Note: In real VIM the result should be '', but it's not quite consistent,\n  // since 2 newlines are deleted. But in the similar case of word\\n\\n, only\n  // 1 newline is deleted. We'll diverge from VIM's behavior since it's much\n  // easier this way.\n  eq('\\n', cm.getValue());\n}, { value: '\\n\\n' });\ntestVim('dge_word_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doKeys('d', 'g', 'e');\n  eq('wor\\n', cm.getValue());\n}, { value: 'word\\n\\n'});\ntestVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('d', 'g', 'e');\n  eq('', cm.getValue());\n}, { value: '\\n  \\n' });\ntestVim('dge_start_of_document', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', 'g', 'e');\n  eq('bc\\n', cm.getValue());\n}, { value: 'abc\\n' });\ntestVim('d_inclusive', function(cm, vim, helpers) {\n  // Assert that when inclusive is set, the character the cursor is on gets\n  // deleted too.\n  var curStart = makeCursor(0, 1);\n  cm.setCursor(curStart);\n  helpers.doKeys('d', 'e');\n  eq('  ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1 ' });\ntestVim('d_reverse', function(cm, vim, helpers) {\n  // Test that deleting in reverse works.\n  cm.setCursor(1, 0);\n  helpers.doKeys('d', 'b');\n  eq(' word2 ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1\\n', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 1);\n}, { value: ' word1\\nword2 ' });\ntestVim('dd', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(1, 0));\n  var expectedLineCount = cm.lineCount() - 1;\n  helpers.doKeys('d', 'd');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[1].textStart);\n});\ntestVim('dd_prefix_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(2, 0));\n  var expectedLineCount = cm.lineCount() - 2;\n  helpers.doKeys('2', 'd', 'd');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[2].textStart);\n});\ntestVim('dd_motion_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(2, 0));\n  var expectedLineCount = cm.lineCount() - 2;\n  helpers.doKeys('d', '2', 'd');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[2].textStart);\n});\ntestVim('dd_multiply_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(6, 0));\n  var expectedLineCount = cm.lineCount() - 6;\n  helpers.doKeys('2', 'd', '3', 'd');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[6].textStart);\n});\ntestVim('dd_lastline', function(cm, vim, helpers) {\n  cm.setCursor(cm.lineCount(), 0);\n  var expectedLineCount = cm.lineCount() - 1;\n  helpers.doKeys('d', 'd');\n  eq(expectedLineCount, cm.lineCount());\n  helpers.assertCursorAt(cm.lineCount() - 1, 0);\n});\ntestVim('dd_only_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  var expectedRegister = cm.getValue() + \"\\n\";\n  helpers.doKeys('d','d');\n  eq(1, cm.lineCount());\n  eq('', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedRegister, register.toString());\n}, { value: \"thisistheonlyline\" });\ntestVim('cG', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', 'G', 'inserted');\n  eq('inserted', cm.getValue());\n  helpers.assertCursorAt(0, 8);\n  cm.setValue(\"    indented\\nlines\");\n  helpers.doKeys('<Esc>', 'c', 'G', 'inserted');\n  eq('    inserted', cm.getValue());\n}, { value: 'line1\\nline2\\n'});\n// Yank commands should behave the exact same as d commands, expect that nothing\n// gets deleted.\ntestVim('yw_repeat', function(cm, vim, helpers) {\n  // Assert that yw does yank newline if it should go to the next line, and\n  // that repeat works properly.\n  var curStart = makeCursor(0, 1);\n  cm.setCursor(curStart);\n  helpers.doKeys('y', '2', 'w');\n  eq(' word1\\nword2', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1\\nword2', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1\\nword2' });\ntestVim('yy_multiply_repeat', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(6, 0));\n  var expectedLineCount = cm.lineCount();\n  helpers.doKeys('2', 'y', '3', 'y');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n});\ntestVim('2dd_blank_P', function(cm, vim, helpers) {\n  helpers.doKeys('2', 'd', 'd', 'P');\n  eq('\\na\\n\\n', cm.getValue());\n}, { value: '\\na\\n\\n' });\n// Change commands behave like d commands except that it also enters insert\n// mode. In addition, when the change is linewise, an additional newline is\n// inserted so that insert mode starts on that line.\ntestVim('cw', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', '2', 'w');\n  eq(' word3', cm.getValue());\n  helpers.assertCursorAt(0, 0);\n}, { value: 'word1 word2 word3'});\ntestVim('cw_repeat', function(cm, vim, helpers) {\n  // Assert that cw does delete newline if it should go to the next line, and\n  // that repeat works properly.\n  var curStart = makeCursor(0, 1);\n  cm.setCursor(curStart);\n  helpers.doKeys('c', '2', 'w');\n  eq(' ', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1\\nword2', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: ' word1\\nword2' });\ntestVim('cc_multiply_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(6, 0));\n  var expectedLineCount = cm.lineCount() - 5;\n  helpers.doKeys('2', 'c', '3', 'c');\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('ct', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('c', 't', 'w');\n  eq('  word1  word3', cm.getValue());\n  helpers.doKeys('<Esc>', 'c', '|');\n  eq(' word3', cm.getValue());\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('<Esc>', '2', 'u', 'w', 'h');\n  helpers.doKeys('c', '2', 'g', 'e');\n  eq('  wordword3', cm.getValue());\n}, { value: '  word1  word2  word3'});\ntestVim('cc_should_not_append_to_document', function(cm, vim, helpers) {\n  var expectedLineCount = cm.lineCount();\n  cm.setCursor(cm.lastLine(), 0);\n  helpers.doKeys('c', 'c');\n  eq(expectedLineCount, cm.lineCount());\n});\nfunction fillArray(val, times) {\n  var arr = [];\n  for (var i = 0; i < times; i++) {\n    arr.push(val);\n  }\n  return arr;\n}\ntestVim('c_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 'c');\n  helpers.doKeys('hello');\n  eq('1hello\\n5hello\\nahellofg', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(2, 3);\n  helpers.doKeys('<C-v>', '2', 'k', 'h', 'C');\n  helpers.doKeys('world');\n  eq('1hworld\\n5hworld\\nahworld', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\ntestVim('c_visual_block_replay', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'c');\n  helpers.doKeys('fo');\n  eq('1fo4\\n5fo8\\nafodefg', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(0, 0);\n  helpers.doKeys('.');\n  eq('foo4\\nfoo8\\nfoodefg', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\ntestVim('I_visual_block_replay', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'I');\n  helpers.doKeys('+-')\n  eq('12+-34\\n56+-78\\nab+-cdefg\\nxyz', cm.getValue());\n  helpers.doKeys('<Esc>');\n  // ensure that repeat location doesn't depend on last selection\n  cm.setCursor(3, 2);\n  helpers.doKeys('g', 'v')\n  eq(\"+-34\\n+-78\\n+-cd\", cm.getSelection())\n  cm.setCursor(0, 3);\n  helpers.doKeys('<C-v>', '1', 'j', '2', 'l');\n  eq(\"-34\\n-78\", cm.getSelection());\n  cm.setCursor(0, 0);\n  eq(\"\", cm.getSelection());\n  helpers.doKeys('g', 'v');\n  eq(\"-34\\n-78\", cm.getSelection());\n  cm.setCursor(1, 1);\n  helpers.doKeys('.');\n  eq('12+-34\\n5+-6+-78\\na+-b+-cdefg\\nx+-yz', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg\\nxyz'});\n\ntestVim('visual_block_backwards', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('3', 'l');\n  helpers.doKeys('<C-v>', '2', 'j', '2', '<Left>');\n  eq('123\\n678\\nbcd', cm.getSelection());\n  helpers.doKeys('A');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('A', '<Esc>');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('g', 'v');\n  eq('123\\n678\\nbcd', cm.getSelection());\n  helpers.doKeys('x');\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('g', 'v');\n  eq('A4 \\nA9 \\nAef', cm.getSelection());\n}, {value: '01234 line 1\\n56789 line 2\\nabcdefg line 3\\nline 4'});\n\ntestVim('d_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 'd');\n  eq('1\\n5\\nafg', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\ntestVim('D_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'D');\n  eq('1\\n5\\na', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\n\ntestVim('s_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 's');\n  helpers.doKeys('hello{');\n  eq('1hello{\\n5hello{\\nahello{fg\\n', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(2, 3);\n  helpers.doKeys('<C-v>', '1', 'k', 'h', 'S');\n  helpers.doKeys('world');\n  eq('1hello{\\n  world\\n', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg\\n'});\n\n// Test mode change event. It should only fire once per mode transition.\ntestVim('on_mode_change', async function(cm, vim, helpers) {\n  var modeHist = [];\n  function callback(arg) {\n    var subMode = arg.subMode ? ':' + arg.subMode : '';\n    modeHist.push(arg.mode + subMode);\n  }\n  helpers.doKeys('<Esc>', '<Esc>');\n  cm.on('vim-mode-change', callback);\n  async function test(key, mode) {\n    modeHist.length = 0;\n    helpers.doKeys(key);\n    if (key == '<C-c>' && !isOldCodeMirror)\n      await delay(0);\n    eq(modeHist.join(';'), mode);\n  }\n  test('v', 'visual');\n  test('c', 'insert');\n  test('<Esc>', 'normal');\n  test('<C-v>', 'visual:blockwise');\n  test('I', 'insert');\n  test('<Esc>', 'normal');\n  test('R', 'replace');\n  test('x', '');\n  test('<C-[>', 'normal');\n  test('v', 'visual');\n  test('V', 'visual:linewise');\n  test('<C-v>', 'visual:blockwise');\n  test('v', 'visual');\n  await test('<C-c>', 'normal');\n  test('a', 'insert');\n  test('<Esc>', 'normal');\n  test('v', 'visual');\n  test(':', ''); // Event for Command-line mode not implemented.\n  test('y\\n', 'normal');\n  test(\":startinsert\\n\", \"insert\");\n});\n\n// Swapcase commands edit in place and do not modify registers.\ntestVim('g~w_repeat', function(cm, vim, helpers) {\n  // Assert that dw does delete newline if it should go to the next line, and\n  // that repeat works properly.\n  var curStart = makeCursor(0, 1);\n  cm.setCursor(curStart);\n  helpers.doKeys('g', '~', '2', 'w');\n  eq(' WORD1\\nWORD2', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1\\nword2' });\ntestVim('g~g~', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  var expectedLineCount = cm.lineCount();\n  var expectedValue = cm.getValue().toUpperCase();\n  helpers.doKeys('2', 'g', '~', '3', 'g', '~');\n  eq(expectedValue, cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n}, { value: ' word1\\nword2\\nword3\\nword4\\nword5\\nword6' });\ntestVim('gu_and_gU', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 7);\n  var value = cm.getValue();\n  cm.setCursor(curStart);\n  helpers.doKeys('2', 'g', 'U', 'w');\n  eq(cm.getValue(), 'wa wb xX WC wd');\n  eqCursorPos(curStart, cm.getCursor());\n  helpers.doKeys('2', 'g', 'u', 'w');\n  eq(cm.getValue(), value);\n\n  helpers.doKeys('2', 'g', 'U', 'B');\n  eq(cm.getValue(), 'wa WB Xx wc wd');\n  eqCursorPos(makeCursor(0, 3), cm.getCursor());\n\n  cm.setCursor(makeCursor(0, 4));\n  helpers.doKeys('g', 'u', 'i', 'w');\n  eq(cm.getValue(), 'wa wb Xx wc wd');\n  eqCursorPos(makeCursor(0, 3), cm.getCursor());\n\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n\n  cm.setCursor(curStart);\n  cm.setValue('abc efg\\nxyz');\n  helpers.doKeys('g', 'U', 'g', 'U');\n  eq(cm.getValue(), 'ABC EFG\\nxyz');\n  helpers.doKeys('g', 'u', 'u');\n  eq(cm.getValue(), 'abc efg\\nxyz');\n  eqCursorPos(makeCursor(0, 0), cm.getCursor());\n  helpers.doKeys('g', 'U', '2', 'U');\n  eq(cm.getValue(), 'ABC EFG\\nXYZ');\n}, { value: 'wa wb xx wc wd' });\ntestVim('visual_block_~', function(cm, vim, helpers) {\n  cm.setCursor(1, 1);\n  helpers.doKeys('<C-v>', 'l', 'l', 'j', '~');\n  helpers.assertCursorAt(1, 1);\n  eq('hello\\nwoRLd\\naBCDe', cm.getValue());\n  cm.setCursor(2, 0);\n  helpers.doKeys('v', 'l', 'l', '~');\n  helpers.assertCursorAt(2, 0);\n  eq('hello\\nwoRLd\\nAbcDe', cm.getValue());\n},{value: 'hello\\nwOrld\\nabcde' });\ntestVim('._swapCase_visualBlock', function(cm, vim, helpers) {\n  helpers.doKeys('<C-v>', 'j', 'j', 'l', '~');\n  cm.setCursor(0, 3);\n  helpers.doKeys('.');\n  eq('HelLO\\nWorLd\\nAbcdE', cm.getValue());\n},{value: 'hEllo\\nwOrlD\\naBcDe' });\ntestVim('._delete_visualBlock', function(cm, vim, helpers) {\n  helpers.doKeys('<C-v>', 'j', 'x');\n  eq('ive\\ne\\nsome\\nsugar', cm.getValue());\n  helpers.doKeys('.');\n  eq('ve\\n\\nsome\\nsugar', cm.getValue());\n  helpers.doKeys('j', 'j', '.');\n  eq('ve\\n\\nome\\nugar', cm.getValue());\n  helpers.doKeys('u');\n  if (!isOldCodeMirror) helpers.assertCursorAt(2, 0);\n  eq('ve\\n\\nsome\\nsugar', cm.getValue());\n  helpers.doKeys('<C-r>');\n  helpers.assertCursorAt(2, 0);\n  eq('ve\\n\\nome\\nugar', cm.getValue());\n  helpers.doKeys('.');\n  helpers.assertCursorAt(2, 0);\n  eq('ve\\n\\nme\\ngar', cm.getValue());\n},{value: 'give\\nme\\nsome\\nsugar' });\ntestVim('>{motion}', function(cm, vim, helpers) {\n  cm.setCursor(1, 3);\n  var expectedLineCount = cm.lineCount();\n  var expectedValue = '   word1\\n  word2\\nword3 ';\n  helpers.doKeys('>', 'k');\n  eq(expectedValue, cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 3);\n}, { value: ' word1\\nword2\\nword3 ', indentUnit: 2 });\ntestVim('>>', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedLineCount = cm.lineCount();\n  var expectedValue = '   word1\\n  word2\\nword3 ';\n  helpers.doKeys('2', '>', '>');\n  eq(expectedValue, cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 3);\n}, { value: ' word1\\nword2\\nword3 ', indentUnit: 2 });\ntestVim('<{motion}', function(cm, vim, helpers) {\n  cm.setCursor(1, 3);\n  var expectedLineCount = cm.lineCount();\n  var expectedValue = ' word1\\nword2\\nword3 ';\n  helpers.doKeys('<', 'k');\n  eq(expectedValue, cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 1);\n}, { value: '   word1\\n  word2\\nword3 ', indentUnit: 2 });\ntestVim('<<', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedLineCount = cm.lineCount();\n  var expectedValue = ' word1\\nword2\\nword3 ';\n  helpers.doKeys('2', '<', '<');\n  eq(expectedValue, cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 1);\n}, { value: '   word1\\n  word2\\nword3 ', indentUnit: 2 });\ntestVim('=', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('<C-v>', 'j', 'j');\n  var expectedValue = 'word1\\nword2\\nword3';\n  helpers.doKeys('=');\n  eq(expectedValue, cm.getValue());\n}, { value: '  word1\\n  word2\\n  word3', indentUnit: 2 });\ntestVim('><visualblock', function(cm, vim, helpers) {\n  cm.setCursor(0, 6);\n  helpers.doKeys('<C-v>', 'j', 'j');\n  helpers.doKeys('4', '>');\n  eq('  word        1\\n  word        2\\n  word        3', cm.getValue());\n  helpers.doKeys('g', 'v', '14', '<');\n  eq('  word1\\n  word2\\n  word3', cm.getValue());\n}, { value: '  word1\\n  word2\\n  word3', indentUnit: 2 });\n\n\n// Edit tests\nfunction testEdit(name, before, pos, edit, after, opts) {\n  if (!opts) opts = {};\n  opts.value = before;\n  return testVim(name, function(cm, vim, helpers) {\n             var ch = before.search(pos)\n             var line = before.substring(0, ch).split('\\n').length - 1;\n             if (line) {\n               ch = before.substring(0, ch).split('\\n').pop().length;\n             }\n             cm.setCursor(line, ch);\n             helpers.doKeys.apply(this, edit.split(''));\n             eq(after, cm.getValue());\n           }, opts);\n}\n\n// These Delete tests effectively cover word-wise Change, Visual & Yank.\n// Tabs are used as differentiated whitespace to catch edge cases.\n// Normal word:\ntestEdit('diw_mid_spc', 'foo \\tbAr\\t baz', /A/, 'diw', 'foo \\t\\t baz');\ntestEdit('daw_mid_spc', 'foo \\tbAr\\t baz', /A/, 'daw', 'foo \\tbaz');\ntestEdit('diw_mid_punct', 'foo \\tbAr.\\t baz', /A/, 'diw', 'foo \\t.\\t baz');\ntestEdit('daw_mid_punct', 'foo \\tbAr.\\t baz', /A/, 'daw', 'foo.\\t baz');\ntestEdit('diw_mid_punct2', 'foo \\t,bAr.\\t baz', /A/, 'diw', 'foo \\t,.\\t baz');\ntestEdit('daw_mid_punct2', 'foo \\t,bAr.\\t baz', /A/, 'daw', 'foo \\t,.\\t baz');\ntestEdit('diw_start_spc', 'bAr \\tbaz', /A/, 'diw', ' \\tbaz');\ntestEdit('daw_start_spc', 'bAr \\tbaz', /A/, 'daw', 'baz');\ntestEdit('diw_start_punct', 'bAr. \\tbaz', /A/, 'diw', '. \\tbaz');\ntestEdit('daw_start_punct', 'bAr. \\tbaz', /A/, 'daw', '. \\tbaz');\ntestEdit('diw_end_spc', 'foo \\tbAr', /A/, 'diw', 'foo \\t');\ntestEdit('daw_end_spc', 'foo \\tbAr', /A/, 'daw', 'foo');\ntestEdit('diw_end_punct', 'foo \\tbAr.', /A/, 'diw', 'foo \\t.');\ntestEdit('daw_end_punct', 'foo \\tbAr.', /A/, 'daw', 'foo.');\ntestEdit('diw_space_word1', 'foo \\t\\n\\tbar.', /\\t/, 'diw', 'foo\\n\\tbar.');\ntestEdit('diw_space_word2', 'foo +bar.', / /, 'diw', 'foo+bar.');\ntestEdit('diw_space_word3', ' foo bar.', / /, 'diw', 'foo bar.');\n// Big word:\ntestEdit('diW_mid_spc', 'foo \\tbAr\\t baz', /A/, 'diW', 'foo \\t\\t baz');\ntestEdit('daW_mid_spc', 'foo \\tbAr\\t baz', /A/, 'daW', 'foo \\tbaz');\ntestEdit('diW_mid_punct', 'foo \\tbAr.\\t baz', /A/, 'diW', 'foo \\t\\t baz');\ntestEdit('daW_mid_punct', 'foo \\tbAr.\\t baz', /A/, 'daW', 'foo \\tbaz');\ntestEdit('diW_mid_punct2', 'foo \\t,bAr.\\t baz', /A/, 'diW', 'foo \\t\\t baz');\ntestEdit('daW_mid_punct2', 'foo \\t,bAr.\\t baz', /A/, 'daW', 'foo \\tbaz');\ntestEdit('diW_start_spc', 'bAr\\t baz', /A/, 'diW', '\\t baz');\ntestEdit('daW_start_spc', 'bAr\\t baz', /A/, 'daW', 'baz');\ntestEdit('diW_start_punct', 'bAr.\\t baz', /A/, 'diW', '\\t baz');\ntestEdit('daW_start_punct', 'bAr.\\t baz', /A/, 'daW', 'baz');\ntestEdit('diW_end_spc', 'foo \\tbAr', /A/, 'diW', 'foo \\t');\ntestEdit('daW_end_spc', 'foo \\tbAr', /A/, 'daW', 'foo');\ntestEdit('diW_end_punct', 'foo \\tbAr.', /A/, 'diW', 'foo \\t');\ntestEdit('daW_end_punct', 'foo \\tbAr.', /A/, 'daW', 'foo');\ntestEdit('diW_space_word2', 'foo +bar.', / /, 'diW', 'foo+bar.');\n// Deleting text objects\n//    Open and close on same line\ntestEdit('di(_open_spc', 'foo (bAr) baz', /\\(/, 'di(', 'foo () baz');\ntestEdit('di)_open_spc', 'foo (bAr) baz', /\\(/, 'di)', 'foo () baz');\ntestEdit('dib_open_spc', 'foo (bAr) baz', /\\(/, 'dib', 'foo () baz');\ntestEdit('da(_open_spc', 'foo (bAr) baz', /\\(/, 'da(', 'foo  baz');\ntestEdit('da)_open_spc', 'foo (bAr) baz', /\\(/, 'da)', 'foo  baz');\n\ntestEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz');\ntestEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz');\ntestEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo  baz');\ntestEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo  baz');\n\ntestEdit('di(_close_spc', 'foo (bAr) baz', /\\)/, 'di(', 'foo () baz');\ntestEdit('di)_close_spc', 'foo (bAr) baz', /\\)/, 'di)', 'foo () baz');\ntestEdit('da(_close_spc', 'foo (bAr) baz', /\\)/, 'da(', 'foo  baz');\ntestEdit('da)_close_spc', 'foo (bAr) baz', /\\)/, 'da)', 'foo  baz');\n\ntestEdit('di`', 'foo `bAr` baz', /`/, 'di`', 'foo `` baz');\ntestEdit('di>', 'foo <bAr> baz', /</, 'di>', 'foo <> baz');\ntestEdit('da<', 'foo <bAr> baz', /</, 'da<', 'foo  baz');\n\n//  delete around and inner b.\ntestEdit('dab_on_(_should_delete_around_()block', 'o( in(abc) )', /\\(a/, 'dab', 'o( in )');\n\n//  delete around and inner B.\ntestEdit('daB_on_{_should_delete_around_{}block', 'o{ in{abc} }', /{a/, 'daB', 'o{ in }');\ntestEdit('diB_on_{_should_delete_inner_{}block', 'o{ in{abc} }', /{a/, 'diB', 'o{ in{} }');\n\ntestEdit('da{_on_{_should_delete_inner_block', 'o{ in{abc} }', /{a/, 'da{', 'o{ in }');\ntestEdit('di[_on_(_should_not_delete', 'foo (bAr) baz', /\\(/, 'di[', 'foo (bAr) baz');\ntestEdit('di[_on_)_should_not_delete', 'foo (bAr) baz', /\\)/, 'di[', 'foo (bAr) baz');\ntestEdit('da[_on_(_should_not_delete', 'foo (bAr) baz', /\\(/, 'da[', 'foo (bAr) baz');\ntestEdit('da[_on_)_should_not_delete', 'foo (bAr) baz', /\\)/, 'da[', 'foo (bAr) baz');\ntestMotion('di(_outside_should_stay', ['d', 'i', '('], new Pos(0, 0), new Pos(0, 0));\n\n//  Open and close on different lines, equally indented\ntestEdit('di{_middle_spc', 'a{\\n\\tbar\\n}b', /r/, 'di{', 'a{}b');\ntestEdit('di}_middle_spc', 'a{\\n\\tbar\\n}b', /r/, 'di}', 'a{}b');\ntestEdit('da{_middle_spc', 'a{\\n\\tbar\\n}b', /r/, 'da{', 'ab');\ntestEdit('da}_middle_spc', 'a{\\n\\tbar\\n}b', /r/, 'da}', 'ab');\ntestEdit('daB_middle_spc', 'a{\\n\\tbar\\n}b', /r/, 'daB', 'ab');\n\n// open and close on diff lines, open indented less than close\ntestEdit('di{_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'di{', 'a{}b');\ntestEdit('di}_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'di}', 'a{}b');\ntestEdit('da{_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'da{', 'ab');\ntestEdit('da}_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'da}', 'ab');\n\n// open and close on diff lines, open indented more than close\ntestEdit('di[_middle_spc', 'a\\t[\\n\\tbar\\n]b', /r/, 'di[', 'a\\t[]b');\ntestEdit('di]_middle_spc', 'a\\t[\\n\\tbar\\n]b', /r/, 'di]', 'a\\t[]b');\ntestEdit('da[_middle_spc', 'a\\t[\\n\\tbar\\n]b', /r/, 'da[', 'a\\tb');\ntestEdit('da]_middle_spc', 'a\\t[\\n\\tbar\\n]b', /r/, 'da]', 'a\\tb');\n\n// open and close on diff lines, open indented more than close\ntestEdit('di<_middle_spc', 'a\\t<\\n\\tbar\\n>b', /r/, 'di<', 'a\\t<>b');\ntestEdit('di>_middle_spc', 'a\\t<\\n\\tbar\\n>b', /r/, 'di>', 'a\\t<>b');\ntestEdit('da<_middle_spc', 'a\\t<\\n\\tbar\\n>b', /r/, 'da<', 'a\\tb');\ntestEdit('da>_middle_spc', 'a\\t<\\n\\tbar\\n>b', /r/, 'da>', 'a\\tb');\n\n// deleting tag objects\ntestEdit('dat_noop', '<outer><inner>hello</inner></outer>', /n/, 'dat', '<outer><inner>hello</inner></outer>',{\n    mode: 'css'\n});\ntestEdit('dat_open_tag', '<outer><inner>hello</inner></outer>', /n/, 'dat', '<outer></outer>', {\n  mode: 'xml'\n});\ntestEdit('dat_inside_tag', '<outer><inner>hello</inner></outer>', /l/, 'dat', '<outer></outer>', {\n  mode: 'xml'\n});\ntestEdit('dat_close_tag', '<outer><inner>hello</inner></outer>', /\\//, 'dat', '<outer></outer>', {\n  mode: 'xml'\n});\n\ntestEdit('dit_open_tag', '<outer><inner>hello</inner></outer>', /n/, 'dit', '<outer><inner></inner></outer>', {\n  mode: 'xml'\n});\ntestEdit('dit_inside_tag', '<outer><inner>hello</inner></outer>', /l/, 'dit', '<outer><inner></inner></outer>', {\n  mode: 'xml'\n});\ntestEdit('dit_close_tag', '<outer><inner>hello</inner></outer>', /\\//, 'dit', '<outer><inner></inner></outer>', {\n  mode: 'xml'\n});\n\nfunction testSelection(name, before, pos, keys, sel) {\n  return testVim(name, function(cm, vim, helpers) {\n             var ch = before.search(pos)\n             var line = before.substring(0, ch).split('\\n').length - 1;\n             if (line) {\n               ch = before.substring(0, ch).split('\\n').pop().length;\n             }\n             cm.setCursor(line, ch);\n             helpers.doKeys.apply(this, keys.split(''));\n             eq(sel, cm.getSelection());\n           }, {value: before});\n}\ntestSelection('viw_middle_spc', 'foo \\tbAr\\t baz', /A/, 'viw', 'bAr');\ntestSelection('vaw_middle_spc', 'foo \\tbAr\\t baz', /A/, 'vaw', 'bAr\\t ');\ntestSelection('viw_middle_punct', 'foo \\tbAr,\\t baz', /A/, 'viw', 'bAr');\ntestSelection('vaW_middle_punct', 'foo \\tbAr,\\t baz', /A/, 'vaW', 'bAr,\\t ');\ntestSelection('viw_start_spc', 'foo \\tbAr\\t baz', /b/, 'viw', 'bAr');\ntestSelection('viw_end_spc', 'foo \\tbAr\\t baz', /r/, 'viw', 'bAr');\ntestSelection('viw_eol', 'foo \\tbAr', /r/, 'viw', 'bAr');\ntestSelection('vi{_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'vi{', '\\n\\tbar\\n\\t');\ntestSelection('va{_middle_spc', 'a{\\n\\tbar\\n\\t}b', /r/, 'va{', '{\\n\\tbar\\n\\t}');\ntestSelection('va{outside', 'xa{\\n\\tbar\\n\\t}b', /x/, 'va{', '{\\n\\tbar\\n\\t}');\n\ntestVim('ci\" for two strings', function(cm, vim, helpers) {\n  cm.setCursor(0, 11);\n  helpers.doKeys('c', 'i', '\"');\n  eq('   \"\":  \"string2\";', cm.getValue());\n  helpers.doKeys('<Esc>', 'u', 'f', '\"', '<Right>');\n  helpers.doKeys('c', 'i', '\"');\n  eq('   \"string1\"\"string2\";', cm.getValue());\n  helpers.doKeys('<Esc>', 'u', 'f', '\"');\n  helpers.doKeys('c', 'i', '\"');\n  eq('   \"string1\":  \"\";', cm.getValue());\n}, {value: '   \"string1\":  \"string2\";'});\n\ntestVim('mouse_select', function(cm, vim, helpers) {\n  cm.setSelection(new Pos(0, 2), new Pos(0, 4), {origin: '*mouse'});\n  is(cm.state.vim.visualMode);\n  is(!cm.state.vim.visualLine);\n  is(!cm.state.vim.visualBlock);\n  helpers.doKeys('<Esc>');\n  is(!cm.somethingSelected());\n  helpers.doKeys('g', 'v');\n  eq('cd', cm.getSelection());\n}, {value: 'abcdef'});\n\n// Operator-motion tests\ntestVim('D', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('D');\n  eq(' wo\\nword2\\n word3', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('rd1', register.toString());\n  is(!register.linewise);\n  helpers.assertCursorAt(0, 2);\n}, { value: ' word1\\nword2\\n word3' });\ntestVim('C', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('C');\n  eq(' wo\\nword2\\n word3', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('rd1', register.toString());\n  is(!register.linewise);\n  eqCursorPos(curStart, cm.getCursor());\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: ' word1\\nword2\\n word3' });\ntestVim('Y', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('Y');\n  eq(' word1\\nword2\\n word3', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq(' word1\\n', register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, 3);\n}, { value: ' word1\\nword2\\n word3' });\ntestVim('Yy_blockwise', function(cm, vim, helpers) {\n  helpers.doKeys('<C-v>', 'j', '2', 'l', 'Y');\n  helpers.doKeys('G', 'p', 'g', 'g');\n  helpers.doKeys('<C-v>', 'j', '2', 'l', 'y');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('$', 'p');\n  eq('123456123\\n123456123\\n123456\\n123456', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('123\\n123', register.toString());\n  is(register.blockwise);\n  helpers.assertCursorAt(0, 6);\n  helpers.doKeys('$', 'j', 'p');\n  helpers.doKeys('$', 'j', 'P');\n  eq(\"123456123\\n123456123123\\n123456   121233\\n123456     123\", cm.getValue());\n}, { value: '123456\\n123456\\n' });\ntestVim('~', function(cm, vim, helpers) {\n  helpers.doKeys('3', '~');\n  eq('ABCdefg', cm.getValue());\n  helpers.assertCursorAt(0, 3);\n}, { value: 'abcdefg' });\n\n// Action tests\ntestVim('ctrl-a', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('-9', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('2','<C-a>');\n  eq('-7', cm.getValue());\n}, {value: '-10'});\ntestVim('ctrl-x', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-x>');\n  eq('-1', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('2','<C-x>');\n  eq('-3', cm.getValue());\n}, {value: '0'});\ntestVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {\n  forEach(['<C-x>', '<C-a>'], function(key) {\n    cm.setCursor(0, 0);\n    helpers.doKeys(key);\n    helpers.assertCursorAt(0, 5);\n    helpers.doKeys('l');\n    helpers.doKeys(key);\n    helpers.assertCursorAt(0, 10);\n    cm.setCursor(0, 11);\n    helpers.doKeys(key);\n    helpers.assertCursorAt(0, 11);\n  });\n}, {value: '__jmp1 jmp2 jmp'});\ntestVim('insert_ctrl_o', function(cm, vim, helpers) {\n  helpers.doKeys('i');\n  is(vim.insertMode);\n  helpers.doKeys('<C-o>');\n  is(!vim.insertMode);\n  helpers.doKeys('3', 'w');\n  is(vim.insertMode);\n  eqCursorPos(makeCursor(0, 14), cm.getCursor());\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'one two three here' });\ntestVim('insert_ctrl_u', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 10);\n  cm.setCursor(curStart);\n  helpers.doKeys('a');\n  helpers.doKeys('<C-u>');\n  eq('', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word1/word2', register.toString());\n  is(!register.linewise);\n  var curEnd = makeCursor(0, 0);\n  eqCursorPos(curEnd, cm.getCursor());\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'word1/word2' });\ntestVim('insert_ctrl_w', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 10);\n  cm.setCursor(curStart);\n  helpers.doKeys('a');\n  helpers.doKeys('<C-w>');\n  eq('word1/', cm.getValue());\n  var register = helpers.getRegisterController().getRegister();\n  eq('word2', register.toString());\n  is(!register.linewise);\n  var curEnd = makeCursor(0, 6);\n  eqCursorPos(curEnd, cm.getCursor());\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'word1/word2' });\ntestVim('normal_ctrl_w', function(cm, vim, helpers) {\n  var curStart = makeCursor(0, 3);\n  cm.setCursor(curStart);\n  helpers.doKeys('<C-w>');\n  eq('word', cm.getValue());\n  var curEnd = makeCursor(0, 3);\n  helpers.assertCursorAt(0,3);\n  eqCursorPos(curEnd, cm.getCursor());\n  eq('vim', cm.getOption('keyMap'));\n}, {value: 'word'});\ntestVim('a', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('a');\n  helpers.assertCursorAt(0, 2);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('a_eol', function(cm, vim, helpers) {\n  cm.setCursor(0, lines[0].length - 1);\n  helpers.doKeys('a');\n  helpers.assertCursorAt(0, lines[0].length);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('a with surrogate characters', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('a');\n  helpers.doKeys('test');\n  helpers.doKeys('<Esc>');\n  eq('😀test', cm.getValue());\n}, {value: '😀'});\ntestVim('A_endOfSelectedArea', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'j', 'l');\n  helpers.doKeys('A');\n  helpers.assertCursorAt(1, 2);\n  eq('vim-insert', cm.getOption('keyMap'));\n}, {value: 'foo\\nbar'});\ntestVim('i', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('i');\n  helpers.assertCursorAt(0, 1);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('i with surrogate characters', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('i');\n  helpers.doKeys('test');\n  helpers.doKeys('<Esc>');\n  eq('test😀', cm.getValue());\n}, { value: '😀' });\ntestVim('i_repeat', function(cm, vim, helpers) {\n  helpers.doKeys('3', 'i');\n  helpers.doKeys('test')\n  helpers.doKeys('<Esc>');\n  eq('testtesttest', cm.getValue());\n  helpers.assertCursorAt(0, 11);\n}, { value: '' });\ntestVim('i_repeat_delete', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('2', 'i');\n  helpers.doKeys('z')\n  helpers.doKeys('Backspace', 'Backspace');\n  helpers.doKeys('<Esc>');\n  eq('abe', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n}, { value: 'abcde' });\ntestVim('insert', function(cm, vim, helpers) {\n  helpers.doKeys('i');\n  eq('vim-insert', cm.getOption('keyMap'));\n  eq(false, cm.state.overwrite);\n  helpers.doKeys('<Ins>');\n  eq('vim-replace', cm.getOption('keyMap'));\n  eq(true, cm.state.overwrite);\n  helpers.doKeys('<Ins>');\n  eq('vim-insert', cm.getOption('keyMap'));\n  eq(false, cm.state.overwrite);\n});\ntestVim('i_backspace', function(cm, vim, helpers) {\n  cm.setCursor(0, 10);\n  helpers.doKeys('i');\n  helpers.doKeys('Backspace');\n  helpers.assertCursorAt(0, 9);\n  eq('012345678', cm.getValue());\n}, { value: '0123456789'});\ntestVim('i_overwrite_backspace', function(cm, vim, helpers) {\n  cm.setCursor(0, 10);\n  helpers.doKeys('i');\n  helpers.doKeys('<Ins>');\n  helpers.doKeys('Backspace');\n  helpers.assertCursorAt(new Pos(0, 9, \"after\"));\n  eq('0123456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('i_forward_delete', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('i');\n  helpers.doKeys('Delete');\n  helpers.assertCursorAt(0, 3);\n  eq('A124\\nBCD', cm.getValue());\n  helpers.doKeys('Delete');\n  helpers.assertCursorAt(0, 3);\n  eq('A12\\nBCD', cm.getValue());\n  helpers.doKeys('Delete');\n  helpers.assertCursorAt(0, 3);\n  eq('A12BCD', cm.getValue());\n}, { value: 'A1234\\nBCD'});\ntestVim('forward_delete', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('<Del>');\n  helpers.assertCursorAt(0, 3);\n  eq('A124\\nBCD', cm.getValue());\n  helpers.doKeys('<Del>');\n  helpers.assertCursorAt(0, 2);\n  eq('A12\\nBCD', cm.getValue());\n  helpers.doKeys('<Del>');\n  helpers.assertCursorAt(0, 1);\n  eq('A1\\nBCD', cm.getValue());\n}, { value: 'A1234\\nBCD'});\ntestVim('A', function(cm, vim, helpers) {\n  helpers.doKeys('A');\n  helpers.assertCursorAt(0, lines[0].length);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('A_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'A');\n  helpers.doKeys('hello');\n  eq('testhello\\nmehello\\npleahellose', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(0, 0);\n  helpers.doKeys('.');\n  // TODO this doesn't work yet\n  // eq('teshellothello\\nme hello hello\\nplehelloahellose', cm.getValue());\n}, {value: 'test\\nme\\nplease'});\ntestVim('I', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('I');\n  helpers.assertCursorAt(0, lines[0].textStart);\n  eq('vim-insert', cm.getOption('keyMap'));\n});\ntestVim('I_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('3', 'I');\n  helpers.doKeys('test')\n  helpers.doKeys('<Esc>');\n  eq('testtesttestblah', cm.getValue());\n  helpers.assertCursorAt(0, 11);\n}, { value: 'blah' });\ntestVim('I_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'I');\n  helpers.doKeys('hello');\n  eq('hellotest\\nhellome\\nhelloplease', cm.getValue());\n}, {value: 'test\\nme\\nplease'});\ntestVim('o', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('o');\n  eq('word1\\n\\nword2', cm.getValue());\n  helpers.assertCursorAt(1, 0);\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'word1\\nword2' });\ntestVim('o_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('3', 'o');\n  helpers.doKeys('test')\n  helpers.doKeys('<Esc>');\n  eq('\\ntest\\ntest\\ntest', cm.getValue());\n  helpers.assertCursorAt(3, 3);\n}, { value: '' });\ntestVim('O', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('O');\n  eq('\\nword1\\nword2', cm.getValue());\n  helpers.assertCursorAt(0, 0);\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'word1\\nword2' });\ntestVim('J', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('J');\n  var expectedValue = 'word1  word2\\nword3\\n word4';\n  eq(expectedValue, cm.getValue());\n  helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1);\n}, { value: 'word1 \\n    word2\\nword3\\n word4' });\ntestVim('J_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('3', 'J');\n  var expectedValue = 'word1  word2 word3\\n word4';\n  eq(expectedValue, cm.getValue());\n  helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1);\n}, { value: 'word1 \\n    word2\\nword3\\n word4' });\ntestVim('gJ', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('g', 'J');\n  eq('word1word2 \\n word3', cm.getValue());\n  helpers.assertCursorAt(0, 5);\n  helpers.doKeys('g', 'J');\n  eq('word1word2  word3', cm.getValue());\n  helpers.assertCursorAt(0, 11);\n}, { value: 'word1\\nword2 \\n word3' });\ntestVim('gi', function(cm, vim, helpers) {\n  cm.setCursor(1, 5);\n  helpers.doKeys('g', 'I');\n  helpers.doKeys('a', 'a', '<Esc>', 'k');\n  eq('12\\naa  xxxx', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('g', 'i');\n  helpers.assertCursorAt(1, 2);\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: '12\\n  xxxx' });\ntestVim('p', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().pushText('\"', 'yank', 'abc\\ndef', false);\n  helpers.doKeys('p');\n  eq('__abc\\ndef_', cm.getValue());\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('y', 'e', 'p');\n  eq('__aabcbc\\ndef_', cm.getValue());\n  helpers.assertCursorAt(0, 5);\n  helpers.doKeys('u');\n  // helpers.assertCursorAt(0, 2); // TODO  undo should return  to the same position\n\n}, { value: '___' });\ntestVim('p_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().getRegister('a').setText('abc\\ndef', false);\n  helpers.doKeys('\"', 'a', 'p');\n  eq('__abc\\ndef_', cm.getValue());\n  helpers.assertCursorAt(0, 2);\n}, { value: '___' });\ntestVim('p_wrong_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().getRegister('a').setText('abc\\ndef', false);\n  helpers.doKeys('p');\n  eq('___', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n}, { value: '___' });\ntestVim('p_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().pushText('\"', 'yank', '  a\\nd\\n', true);\n  helpers.doKeys('2', 'p');\n  eq('___\\n  a\\nd\\n  a\\nd', cm.getValue());\n  helpers.assertCursorAt(1, 2);\n}, { value: '___' });\ntestVim('p_lastline', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().pushText('\"', 'yank', '  a\\nd', true);\n  helpers.doKeys('2', 'p');\n  eq('___\\n  a\\nd\\n  a\\nd', cm.getValue());\n  helpers.assertCursorAt(1, 2);\n}, { value: '___' });\ntestVim(']p_first_indent_is_smaller', function(cm, vim, helpers) {\n  helpers.getRegisterController().pushText('\"', 'yank', '  abc\\n    def\\n', true);\n  helpers.doKeys(']', 'p');\n  eq('  ___\\n  abc\\n    def', cm.getValue());\n}, { value: '  ___' });\ntestVim(']p_first_indent_is_larger', function(cm, vim, helpers) {\n  helpers.getRegisterController().pushText('\"', 'yank', '    abc\\n  def\\n', true);\n  helpers.doKeys(']', 'p');\n  eq('  ___\\n  abc\\ndef', cm.getValue());\n}, { value: '  ___' });\ntestVim(']p_with_tab_indents', function(cm, vim, helpers) {\n  helpers.getRegisterController().pushText('\"', 'yank', '\\t\\tabc\\n\\t\\t\\tdef\\n', true);\n  helpers.doKeys(']', 'p');\n  eq('\\t___\\n\\tabc\\n\\t\\tdef', cm.getValue());\n}, { value: '\\t___', indentWithTabs: true});\ntestVim(']p_with_spaces_translated_to_tabs', function(cm, vim, helpers) {\n  helpers.getRegisterController().pushText('\"', 'yank', '  abc\\n    def\\n', true);\n  helpers.doKeys(']', 'p');\n  eq('\\t___\\n\\tabc\\n\\t\\tdef', cm.getValue());\n}, { value: '\\t___', indentWithTabs: true, tabSize: 2 });\ntestVim('[p', function(cm, vim, helpers) {\n  helpers.getRegisterController().pushText('\"', 'yank', '  abc\\n    def\\n', true);\n  helpers.doKeys('[', 'p');\n  eq('  abc\\n    def\\n  ___', cm.getValue());\n}, { value: '  ___' });\ntestVim('P', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().pushText('\"', 'yank', 'abc\\ndef', false);\n  helpers.doKeys('P');\n  eq('_abc\\ndef__', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('y', 'e', 'P');\n  eq('_abcabc\\ndef__', cm.getValue());\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('u');\n  // helpers.assertCursorAt(0, 1); // TODO  undo should return  to the same position\n}, { value: '___' });\ntestVim('P_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.getRegisterController().pushText('\"', 'yank', '  a\\nd\\n', true);\n  helpers.doKeys('2', 'P');\n  eq('  a\\nd\\n  a\\nd\\n___', cm.getValue());\n  helpers.assertCursorAt(0, 2);\n}, { value: '___' });\ntestVim('r', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('3', 'r', 'u');\n  eq('wuuuet\\nanother', cm.getValue(),'3r failed');\n  helpers.assertCursorAt(0, 3);\n  cm.setCursor(0, 4);\n  helpers.doKeys('v', 'j', 'h', 'r', '<Space>');\n  eq('wuuu  \\n    her', cm.getValue(),'Replacing selection by space-characters failed');\n  cm.setValue(\"ox\");\n  helpers.doKeys('r', '<C-c>');\n  eq('ox', cm.getValue());\n  helpers.doKeys('r', '<Del>');\n  eq('ox', cm.getValue());\n  helpers.doKeys('r', '<CR>');\n  eq('\\nx', cm.getValue());\n}, { value: 'wordet\\nanother' });\ntestVim('r with surrogate characters', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('r', 'u');\n  eq('u', cm.getValue());\n}, { value: '😀' });\ntestVim('r_visual_block', function(cm, vim, helpers) {\n  cm.ace.setOptions({tabSize: 4, useSoftTabs: false}); // ace_patch TODO\n  cm.setCursor(2, 3);\n  helpers.doKeys('<C-v>', 'k', 'k', 'h', 'h', 'r', 'l');\n  eq('1lll\\n5lll\\nalllefg', cm.getValue());\n  helpers.doKeys('<C-v>', 'l', 'j', 'r', '<Space>');\n  eq('1  l\\n5  l\\nalllefg', cm.getValue());\n  cm.setCursor(2, 0);\n  helpers.doKeys('o');\n  helpers.doKeys('\\t\\t');\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('<C-v>', 'h', 'h', 'r', 'r');\n  eq('1  l\\n5  l\\nalllefg\\nrrrrrrrr', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg', indentWithTabs: true});\ntestVim('r_visual with surrogate characters', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'r', 'u');\n  eq('u', cm.getValue());\n}, { value: '😀' });\ntestVim('r_visual_block with surrogate characters', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', 'r', 'u');\n  eq('u', cm.getValue());\n}, { value: '😀' });\ntestVim('R', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('R');\n  helpers.assertCursorAt(0, 1);\n  eq('vim-replace', cm.getOption('keyMap'));\n  is(cm.state.overwrite, 'Setting overwrite state failed');\n});\ntestVim('R_visual', function(cm, vim, helpers) {\n  helpers.doKeys('<C-v>', 'j', 'R', '0', '<Esc>');\n  eq('0\\nb33\\nc44\\nc55', cm.getValue());\n  helpers.doKeys('2', 'j', '.');\n  eq('0\\nb33\\n0', cm.getValue());\n  helpers.doKeys('k', 'v', 'R', '1', '<Esc>');\n  eq('0\\n1\\n0', cm.getValue());\n  helpers.doKeys('k', '.');\n  eq('1\\n1\\n0', cm.getValue());\n  helpers.doKeys('p');\n  eq('1\\n0\\n1\\n0', cm.getValue());\n}, {value: 'a11\\na22\\nb33\\nc44\\nc55'});\ntestVim('mark', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 't');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 't');\n  helpers.assertCursorAt(2, 2);\n  cm.setCursor(2, 0);\n  cm.replaceRange('   h', cm.getCursor());\n  cm.setCursor(0, 0);\n  helpers.doKeys('\\'', 't');\n  helpers.assertCursorAt(2, 3);\n});\ntestVim('mark\\'', function(cm, vim, helpers) {\n  // motions that do not update jumplist\n  cm.setCursor(2, 2);\n  helpers.doKeys('`', '\\'');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('j', '3', 'l');\n  helpers.doKeys('`', '`');\n  helpers.assertCursorAt(2, 2);\n  helpers.doKeys('`', '`');\n  helpers.assertCursorAt(1, 3);\n  // motions that update jumplist\n  helpers.doKeys('/', '=', '\\n');\n  helpers.assertCursorAt(6, 20);\n  helpers.doKeys('`', '`');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('\\'', '\\'');\n  helpers.assertCursorAt(6, 2);\n  helpers.doKeys('\\'', '`');\n  helpers.assertCursorAt(1, 1);\n  // edits\n  helpers.doKeys('g', 'I', '\\n', '<Esc>', 'l');\n  // the column may be different depending on editor behavior in insert mode\n  var ch = cm.getCursor().ch;\n  helpers.doKeys('`', '`');\n  helpers.assertCursorAt(7, 2);\n  helpers.doKeys('`', '`');\n  helpers.assertCursorAt(2, ch);\n});\ntestVim('mark.', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('O', 'testing', '<Esc>');\n  cm.setCursor(3, 3);\n  helpers.doKeys('\\'', '.');\n  helpers.assertCursorAt(0, 0);\n  cm.setCursor(4, 4);\n  helpers.doKeys('`', '.');\n  helpers.assertCursorAt(0, 6);\n});\ntestVim('jumpToMark_next', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 't');\n  cm.setCursor(0, 0);\n  helpers.doKeys(']', '`');\n  helpers.assertCursorAt(2, 2);\n  cm.setCursor(0, 0);\n  helpers.doKeys(']', '\\'');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_next_repeat', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', ']', '`');\n  helpers.assertCursorAt(3, 2);\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', ']', '\\'');\n  helpers.assertCursorAt(3, 1);\n});\ntestVim('jumpToMark_next_sameline', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 4);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(2, 2);\n  helpers.doKeys(']', '`');\n  helpers.assertCursorAt(2, 4);\n});\ntestVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(4, 0);\n  helpers.doKeys(']', '`');\n  helpers.assertCursorAt(4, 0);\n});\ntestVim('jumpToMark_next_nomark', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys(']', '`');\n  helpers.assertCursorAt(2, 2);\n  helpers.doKeys(']', '\\'');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(3, 4);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(2, 1);\n  helpers.doKeys(']', '\\'');\n  helpers.assertCursorAt(3, 1);\n});\ntestVim('jumpToMark_next_action', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 't');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ']', '`');\n  helpers.assertCursorAt(0, 0);\n  var actual = cm.getLine(0);\n  var expected = 'pop pop 0 1 2 3 4';\n  eq(actual, expected, \"Deleting while jumping to the next mark failed.\");\n});\ntestVim('jumpToMark_next_line_action', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 't');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ']', '\\'');\n  helpers.assertCursorAt(0, 1);\n  var actual = cm.getLine(0);\n  var expected = ' (a) [b] {c} '\n  eq(actual, expected, \"Deleting while jumping to the next mark line failed.\");\n});\ntestVim('jumpToMark_prev', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 't');\n  cm.setCursor(4, 0);\n  helpers.doKeys('[', '`');\n  helpers.assertCursorAt(2, 2);\n  cm.setCursor(4, 0);\n  helpers.doKeys('[', '\\'');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_prev_repeat', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(5, 0);\n  helpers.doKeys('2', '[', '`');\n  helpers.assertCursorAt(3, 2);\n  cm.setCursor(5, 0);\n  helpers.doKeys('2', '[', '\\'');\n  helpers.assertCursorAt(3, 1);\n});\ntestVim('jumpToMark_prev_sameline', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 4);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(2, 2);\n  helpers.doKeys('[', '`');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) {\n  cm.setCursor(4, 4);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 0);\n  helpers.doKeys('[', '`');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_prev_nomark', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('[', '`');\n  helpers.assertCursorAt(2, 2);\n  helpers.doKeys('[', '\\'');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) {\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(3, 4);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(3, 6);\n  helpers.doKeys('[', '\\'');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('delmark_single', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('m', 't');\n  helpers.doEx('delmarks t');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 't');\n  helpers.assertCursorAt(0, 0);\n});\ntestVim('delmark_range', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'd');\n  cm.setCursor(5, 2);\n  helpers.doKeys('m', 'e');\n  helpers.doEx('delmarks b-d');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 'a');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'b');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'c');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'd');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'e');\n  helpers.assertCursorAt(5, 2);\n});\ntestVim('delmark_multi', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'd');\n  cm.setCursor(5, 2);\n  helpers.doKeys('m', 'e');\n  helpers.doEx('delmarks bcd');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 'a');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'b');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'c');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'd');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'e');\n  helpers.assertCursorAt(5, 2);\n});\ntestVim('delmark_multi_space', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'd');\n  cm.setCursor(5, 2);\n  helpers.doKeys('m', 'e');\n  helpers.doEx('delmarks b c d');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 'a');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'b');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'c');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'd');\n  helpers.assertCursorAt(1, 2);\n  helpers.doKeys('`', 'e');\n  helpers.assertCursorAt(5, 2);\n});\ntestVim('delmark_all', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', 'b');\n  cm.setCursor(3, 2);\n  helpers.doKeys('m', 'c');\n  cm.setCursor(4, 2);\n  helpers.doKeys('m', 'd');\n  cm.setCursor(5, 2);\n  helpers.doKeys('m', 'e');\n  helpers.doEx('delmarks a b-de');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', 'a');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('`', 'b');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('`', 'c');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('`', 'd');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('`', 'e');\n  helpers.assertCursorAt(0, 0);\n});\ntestVim('visual', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'v', 'l', 'l');\n  helpers.assertCursorAt(0, 4);\n  eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor'));\n  helpers.doKeys('d');\n  eq('15', cm.getValue());\n}, { value: '12345' });\ntestVim('visual_yank', function(cm, vim, helpers) {\n  helpers.doKeys('v', '3', 'l', 'y');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('p');\n  eq('aa te test for yank', cm.getValue());\n}, { value: 'a test for yank' })\ntestVim('visual_w', function(cm, vim, helpers) {\n  helpers.doKeys('v', 'w');\n  eq(cm.getSelection(), 'motion t');\n}, { value: 'motion test'});\ntestVim('visual_initial_selection', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('v');\n  cm.getSelection('n');\n}, { value: 'init'});\ntestVim('visual_crossover_left', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('v', 'l', 'h', 'h');\n  cm.getSelection('ro');\n}, { value: 'cross'});\ntestVim('visual_crossover_left', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('v', 'h', 'l', 'l');\n  cm.getSelection('os');\n}, { value: 'cross'});\ntestVim('visual_crossover_up', function(cm, vim, helpers) {\n  cm.setCursor(3, 2);\n  helpers.doKeys('v', 'j', 'k', 'k');\n  eqCursorPos(new Pos(2, 2), cm.getCursor('head'));\n  eqCursorPos(new Pos(3, 3), cm.getCursor('anchor'));\n  helpers.doKeys('k');\n  eqCursorPos(new Pos(1, 2), cm.getCursor('head'));\n  eqCursorPos(new Pos(3, 3), cm.getCursor('anchor'));\n}, { value: 'cross\\ncross\\ncross\\ncross\\ncross\\n'});\ntestVim('visual_crossover_down', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('v', 'k', 'j', 'j');\n  eqCursorPos(new Pos(2, 3), cm.getCursor('head'));\n  eqCursorPos(new Pos(1, 2), cm.getCursor('anchor'));\n  helpers.doKeys('j');\n  eqCursorPos(new Pos(3, 3), cm.getCursor('head'));\n  eqCursorPos(new Pos(1, 2), cm.getCursor('anchor'));\n}, { value: 'cross\\ncross\\ncross\\ncross\\ncross\\n'});\ntestVim('visual_exit', function(cm, vim, helpers) {\n  helpers.doKeys('<C-v>', 'l', 'j', 'j', '<Esc>');\n  eqCursorPos(cm.getCursor('anchor'), cm.getCursor('head'));\n  eq(vim.visualMode, false);\n}, { value: 'hello\\nworld\\nfoo' });\ntestVim('visual_line', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');\n  eq(' 4\\n 5', cm.getValue());\n}, { value: ' 1\\n 2\\n 3\\n 4\\n 5' });\ntestVim('visual_block_move_to_eol', function(cm, vim, helpers) {\n  // moveToEol should move all block cursors to end of line\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', 'G', '$');\n  var selections = cm.getSelections().join();\n  eq('123,45,6', selections);\n  // Checks that with cursor at Infinity, finding words backwards still works.\n  helpers.doKeys('2', 'k', 'b');\n  selections = cm.getSelections().join();\n  eq('1', selections);\n}, {value: '123\\n45\\n6'});\ntestVim('visual_block_different_line_lengths', function(cm, vim, helpers) {\n  // test the block selection with lines of different length\n  // i.e. extending the selection\n  // till the end of the longest line.\n  helpers.doKeys('<C-v>', 'l', 'j', 'j', '6', 'l', 'd');\n  helpers.doKeys('d', 'd', 'd', 'd');\n  eq('', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\ntestVim('visual_block_truncate_on_short_line', function(cm, vim, helpers) {\n  // check for left side selection in case\n  // of moving up to a shorter line.\n  cm.replaceRange('', cm.getCursor());\n  cm.setCursor(3, 4);\n  helpers.doKeys('<C-v>', 'l', 'k', 'k', 'd');\n  eq('hello world\\n{\\ntis\\nsa!', cm.getValue());\n}, {value: 'hello world\\n{\\nthis is\\nsparta!'});\ntestVim('visual_block_corners', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('<C-v>', '2', 'l', 'k');\n  // circle around the anchor\n  // and check the selections\n  var selections = cm.getSelections();\n  eq('345891', selections.join(''));\n  helpers.doKeys('4', 'h');\n  selections = cm.getSelections();\n  eq('123678', selections.join(''));\n  helpers.doKeys('j', 'j');\n  selections = cm.getSelections();\n  eq('678abc', selections.join(''));\n  helpers.doKeys('4', 'l');\n  selections = cm.getSelections();\n  eq('891cde', selections.join(''));\n}, {value: '12345\\n67891\\nabcde'});\ntestVim('visual_block_mode_switch', function(cm, vim, helpers) {\n  // switch between visual modes\n  cm.setCursor(1, 1);\n  // blockwise to characterwise visual\n  helpers.doKeys('<C-v>', 'j', 'l', 'v');\n  var selections = cm.getSelections();\n  eq('7891\\nabc', selections.join(''));\n  // characterwise to blockwise\n  helpers.doKeys('<C-v>');\n  selections = cm.getSelections();\n  eq('78bc', selections.join(''));\n  // blockwise to linewise visual\n  helpers.doKeys('V');\n  selections = cm.getSelections();\n  eq('67891\\nabcde', selections.join(''));\n}, {value: '12345\\n67891\\nabcde'});\ntestVim('visual_block_crossing_short_line', function(cm, vim, helpers) {\n  // visual block with long and short lines\n  cm.setCursor(0, 3);\n  helpers.doKeys('<C-v>', 'j', 'j', 'j');\n  var selections = cm.getSelections().join();\n  eq('4,,d,b', selections);\n  helpers.doKeys('3', 'k');\n  selections = cm.getSelections().join();\n  eq('4', selections);\n  helpers.doKeys('5', 'j', 'k');\n  selections = cm.getSelections().join(\"\");\n  eq(10, selections.length);\n}, {value: '123456\\n78\\nabcdefg\\nfoobar\\n}\\n'});\ntestVim('visual_block_curPos_on_exit', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '3' , 'l', '<Esc>');\n  eqCursorPos(makeCursor(0, 3), cm.getCursor());\n  helpers.doKeys('h', '<C-v>', '2' , 'j' ,'3' , 'l');\n  eq(cm.getSelections().join(), \"3456,,cdef\");\n  helpers.doKeys('4' , 'h');\n  eq(cm.getSelections().join(), \"23,8,bc\");\n  helpers.doKeys('2' , 'l');\n  eq(cm.getSelections().join(), \"34,,cd\");\n}, {value: '123456\\n78\\nabcdefg\\nfoobar'});\n\ntestVim('visual_marks', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'v', 'l', 'l', 'j', 'j', 'v');\n  // Test visual mode marks\n  cm.setCursor(2, 1);\n  helpers.doKeys('\\'', '<');\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('\\'', '>');\n  helpers.assertCursorAt(2, 0);\n});\ntestVim('visual_join', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J');\n  eq(' 1 2 3\\n 4\\n 5', cm.getValue());\n  is(!vim.visualMode);\n}, { value: ' 1\\n 2\\n 3\\n 4\\n 5' });\ntestVim('visual_join_2', function(cm, vim, helpers) {\n  helpers.doKeys('G', 'V', 'g', 'g', 'J');\n  eq('1 2 3 4 5 6', cm.getValue());\n  is(!vim.visualMode);\n}, { value: '1\\n2\\n3\\n4\\n5\\n6\\n'});\ntestVim('visual_join_blank', function(cm, vim, helpers) {\n  var initialValue = cm.getValue();\n  helpers.doKeys('G', 'V', 'g', 'g', 'J');\n  eq('1  2 5 6', cm.getValue());\n  is(!vim.visualMode);\n  helpers.doKeys('u');\n  eq(initialValue, cm.getValue());\n  helpers.doKeys('G', 'V', 'g', 'g', 'g', 'J');\n  eq('1 \\t2\\t  5 6', cm.getValue());\n  helpers.doKeys('u');\n  eq(cm.getCursor().line, 0);\n  eq(initialValue, cm.getValue());\n  helpers.doKeys('J', 'J', 'J');\n  helpers.assertCursorAt(0, 3);\n  helpers.doKeys('J');\n  helpers.assertCursorAt(0, 4);\n  eq('1  2 5\\n 6\\n', cm.getValue());\n  helpers.doKeys('u');\n  eq('1  2\\n5\\n 6\\n', cm.getValue());  \n}, { value: '1 \\n\\t2\\n\\t  \\n\\n5\\n 6\\n'});\ntestVim('visual_blank', function(cm, vim, helpers) {\n  helpers.doKeys('v', 'k');\n  eq(vim.visualMode, true);\n}, { value: '\\n' });\ntestVim('reselect_visual', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'v', 'l', 'l', 'l', 'y', 'g', 'v');\n  helpers.assertCursorAt(0, 5);\n  eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor'));\n  helpers.doKeys('v');\n  cm.setCursor(1, 0);\n  helpers.doKeys('v', 'l', 'l', 'p');\n  eq('123456\\n2345\\nbar', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('g', 'v');\n  // here the fake cursor is at (1, 3)\n  helpers.assertCursorAt(1, 4);\n  eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor'));\n  helpers.doKeys('v');\n  cm.setCursor(2, 0);\n  helpers.doKeys('v', 'l', 'l', 'g', 'v');\n  helpers.assertCursorAt(1, 4);\n  eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor'));\n  helpers.doKeys('g', 'v');\n  helpers.assertCursorAt(2, 3);\n  eqCursorPos(makeCursor(2, 0), cm.getCursor('anchor'));\n  eq('123456\\n2345\\nbar', cm.getValue());\n}, { value: '123456\\nfoo\\nbar' });\ntestVim('reselect_visual_line', function(cm, vim, helpers) {\n  helpers.doKeys('l', 'V', 'j', 'j', 'V', 'g', 'v', 'd');\n  eq('foo\\nand\\nbar', cm.getValue());\n  cm.setCursor(1, 0);\n  helpers.doKeys('V', 'y', 'j');\n  helpers.doKeys('V', 'p' , 'g', 'v', 'd');\n  eq('foo\\nand', cm.getValue());\n}, { value: 'hello\\nthis\\nis\\nfoo\\nand\\nbar' });\ntestVim('reselect_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(1, 2);\n  helpers.doKeys('<C-v>', 'k', 'h', '<C-v>');\n  cm.setCursor(2, 1);\n  helpers.doKeys('v', 'l', 'g', 'v');\n  eqCursorPos(new Pos(1, 2), vim.sel.anchor);\n  eqCursorPos(new Pos(0, 1), vim.sel.head);\n  // Ensure selection is done with visual block mode rather than one\n  // continuous range.\n  eq(cm.getSelections().join(''), '23oo')\n  helpers.doKeys('g', 'v');\n  eqCursorPos(new Pos(2, 1), vim.sel.anchor);\n  eqCursorPos(new Pos(2, 2), vim.sel.head);\n  helpers.doKeys('<Esc>');\n  // Ensure selection of deleted range\n  cm.setCursor(1, 1);\n  helpers.doKeys('v', '<C-v>', 'j', 'd', 'g', 'v');\n  eq(cm.getSelections().join(''), 'or');\n}, { value: '123456\\nfoo\\nbar' });\ntestVim('s_normal', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('s');\n  helpers.doKeys('<Esc>');\n  eq('ac', cm.getValue());\n}, { value: 'abc'});\ntestVim('s_normal surrogate character', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('s');\n  helpers.doKeys('test');\n  helpers.doKeys('<Esc>');\n  eq('test', cm.getValue());\n}, { value: '😀' });\ntestVim('s_visual', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('v', 's');\n  helpers.doKeys('<Esc>');\n  helpers.assertCursorAt(0, 0);\n  eq('ac', cm.getValue());\n}, { value: 'abc'});\ntestVim('d with surrogate character', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v');\n  helpers.doKeys('d');\n  helpers.doKeys('<Esc>');\n  eq('', cm.getValue());\n}, { value: '😀' });\ntestVim('o_visual', function(cm, vim, helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys('v','l','l','l','o');\n  helpers.assertCursorAt(0,0);\n  helpers.doKeys('v','v','j','j','j','o');\n  helpers.assertCursorAt(0,0);\n  helpers.doKeys('O');\n  helpers.doKeys('l','l')\n  helpers.assertCursorAt(3, 3);\n  helpers.doKeys('d');\n  eq('p',cm.getValue());\n}, { value: 'abcd\\nefgh\\nijkl\\nmnop'});\ntestVim('o_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>','3','j','l','l', 'o');\n  eqCursorPos(new Pos(3, 3), vim.sel.anchor);\n  eqCursorPos(new Pos(0, 1), vim.sel.head);\n  helpers.doKeys('O');\n  eqCursorPos(new Pos(3, 1), vim.sel.anchor);\n  eqCursorPos(new Pos(0, 3), vim.sel.head);\n  helpers.doKeys('o');\n  eqCursorPos(new Pos(0, 3), vim.sel.anchor);\n  eqCursorPos(new Pos(3, 1), vim.sel.head);\n}, { value: 'abcd\\nefgh\\nijkl\\nmnop'});\ntestVim('changeCase_visual', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'l', 'l');\n  helpers.doKeys('U');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('v', 'l', 'l');\n  helpers.doKeys('u');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('l', 'l', 'l', '.');\n  helpers.assertCursorAt(0, 3);\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('j', '@', 'a');\n  helpers.assertCursorAt(1, 0);\n  cm.setCursor(3, 0);\n  helpers.doKeys('V', 'U', 'j', '.');\n  eq('ABCDEF\\nGHIJKL\\nMnopq\\nSHORT LINE\\nLONG LINE OF TEXT', cm.getValue());\n}, { value: 'abcdef\\nghijkl\\nmnopq\\nshort line\\nlong line of text'});\ntestVim('changeCase_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(2, 1);\n  helpers.doKeys('<C-v>', 'k', 'k', 'h', 'U');\n  eq('ABcdef\\nGHijkl\\nMNopq\\nfoo', cm.getValue());\n  cm.setCursor(0, 2);\n  helpers.doKeys('.');\n  eq('ABCDef\\nGHIJkl\\nMNOPq\\nfoo', cm.getValue());\n  // check when last line is shorter.\n  cm.setCursor(2, 2);\n  helpers.doKeys('.');\n  eq('ABCDef\\nGHIJkl\\nMNOPq\\nfoO', cm.getValue());\n}, { value: 'abcdef\\nghijkl\\nmnopq\\nfoo'});\ntestVim('visual_paste', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'l', 'l', 'y');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('3', 'l', 'j', 'v', 'l', 'p');\n  helpers.assertCursorAt(1, 5);\n  eq('this is a\\nunithitest for visual paste', cm.getValue());\n  cm.setCursor(0, 0);\n  // in case of pasting whole line\n  helpers.doKeys('y', 'y');\n  cm.setCursor(1, 6);\n  helpers.doKeys('v', 'l', 'l', 'l', 'p');\n  helpers.assertCursorAt(2, 0);\n  eq('this is a\\nunithi\\nthis is a\\n for visual paste', cm.getValue());\n}, { value: 'this is a\\nunit test for visual paste'});\n\n// This checks the contents of the register used to paste the text\ntestVim('v_paste_from_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'w');\n  cm.setCursor(1, 0);\n  helpers.doKeys('v', 'p');\n  helpers.doEx('registers');\n  is(/a\\s+register/.test(helpers.getNotificationText()));\n}, { value: 'register contents\\nare not erased'});\ntestVim('S_normal', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('j', 'S');\n  helpers.doKeys('<Esc>');\n  helpers.assertCursorAt(1, 1);\n  eq('aa{\\n  \\ncc', cm.getValue());\n  helpers.doKeys('j', 'S');\n  eq('aa{\\n  \\n', cm.getValue());\n  helpers.assertCursorAt(2, 0);\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('d', 'd', 'd', 'd');\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('S');\n  is(vim.insertMode);\n  eq('', cm.getValue());\n}, { value: 'aa{\\n  bb\\ncc'});\ntestVim('blockwise_paste', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '3', 'j', 'l', 'y');\n  cm.setCursor(0, 2);\n  // paste one char after the current cursor position\n  helpers.doKeys('p');\n  eq('helhelo\\nworwold\\nfoofo\\nbarba', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', '4', 'l', 'y');\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '3', 'j', 'p');\n  eq('helheelhelo\\norwold\\noofo\\narba', cm.getValue());\n}, { value: 'hello\\nworld\\nfoo\\nbar'});\ntestVim('blockwise_paste_long/short_line', function(cm, vim, helpers) {\n  // extend short lines in case of different line lengths.\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', 'j', 'j', 'y');\n  cm.setCursor(0, 3);\n  helpers.doKeys('p');\n  eq('hellho\\nfoo f\\nbar b', cm.getValue());\n}, { value: 'hello\\nfoo\\nbar'});\ntestVim('blockwise_paste_cut_paste', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '2', 'j', 'x');\n  cm.setCursor(0, 0);\n  helpers.doKeys('P');\n  eq('cut\\nand\\npaste\\nme', cm.getValue());\n}, { value: 'cut\\nand\\npaste\\nme'});\ntestVim('blockwise_paste_from_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '2', 'j', '\"', 'a', 'y');\n  cm.setCursor(0, 3);\n  helpers.doKeys('\"', 'a', 'p');\n  eq('foobfar\\nhellho\\nworlwd', cm.getValue());\n}, { value: 'foobar\\nhello\\nworld'});\ntestVim('blockwise_paste_last_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'y');\n  cm.setCursor(3, 0);\n  helpers.doKeys('p');\n  eq('cut\\nand\\npaste\\nmcue\\n an\\n pa', cm.getValue());\n}, { value: 'cut\\nand\\npaste\\nme'});\n\ntestVim('S_visual', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('v', 'j', 'S');\n  helpers.doKeys('<Esc>');\n  helpers.assertCursorAt(0, 0);\n  eq('\\ncc', cm.getValue());\n}, { value: 'aa\\nbb\\ncc'});\n\ntestVim('d_/', function(cm, vim, helpers) {\n  helpers.doKeys('2', 'd', '/', 'match', '\\n');\n  helpers.assertCursorAt(0, 0);\n  eq('match \\n next', cm.getValue());\n  helpers.doKeys('d', ':', '2', '\\n');\n  // TODO eq(' next', cm.getValue());\n}, { value: 'text match match \\n next' });\ntestVim('/ and n/N', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 6);\n  helpers.doKeys('N');\n  helpers.assertCursorAt(0, 11);\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', '/', 'match', '\\n');\n  helpers.assertCursorAt(1, 6);\n}, { value: 'match nope match \\n nope Match' });\ntestVim('/ and gn selects the appropriate word', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n\n  // gn should highlight the the current word while it is within a match.\n\n  // gn when cursor is in beginning of match\n  helpers.doKeys('gn', '<Esc>');\n  helpers.assertCursorAt(0, 15);\n\n  // gn when cursor is at end of match\n  helpers.doKeys('gn', '<Esc>');\n  helpers.doKeys('<Esc>');\n  helpers.assertCursorAt(0, 15);\n\n  // consecutive gns should extend the selection\n  helpers.doKeys('gn');\n  helpers.assertCursorAt(0, 16);\n  helpers.doKeys('gn');\n  helpers.assertCursorAt(1, 11);\n\n  // we should have selected the second and third \"match\"\n  helpers.doKeys('d');\n  eq('match nope ', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('/ and gN selects the appropriate word', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n\n  // gN when cursor is at beginning of match\n  helpers.doKeys('gN', '<Esc>');\n  helpers.assertCursorAt(0, 11);\n\n  // gN when cursor is at end of match\n  helpers.doKeys('e', 'gN', '<Esc>');\n  helpers.assertCursorAt(0, 11);\n\n  // consecutive gNs should extend the selection\n  helpers.doKeys('gN');\n  helpers.assertCursorAt(0, 11);\n  helpers.doKeys('gN');\n  helpers.assertCursorAt(0, 0);\n\n  // we should have selected the first and second \"match\"\n  helpers.doKeys('d');\n  eq(' \\n nope Match', cm.getValue());\n}, { value: 'match nope match \\n nope Match' })\ntestVim('/ and gn with an associated operator', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n\n  helpers.doKeys('c', 'gn', 'changed', '<Esc>');\n\n  // change the current match.\n  eq('match nope changed \\n nope Match', cm.getValue());\n\n  // change the next match.\n  helpers.doKeys('.');\n  eq('match nope changed \\n nope changed', cm.getValue());\n\n  // change the final match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope changed', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('/ and gN with an associated operator', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n\n  helpers.doKeys('c', 'gN', 'changed', '<Esc>');\n\n  // change the current match.\n  eq('match nope changed \\n nope Match', cm.getValue());\n\n  // change the next match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope Match', cm.getValue());\n\n  // change the final match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope changed', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('/_case', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'Match', '\\n');\n  helpers.assertCursorAt(1, 6);\n}, { value: 'match nope match \\n nope Match' });\ntestVim('/_2_pcre', function(cm, vim, helpers) {\n  CodeMirror.Vim.setOption('pcre', true);\n  helpers.doKeys('/', '(word){2}', '\\n');\n  helpers.assertCursorAt(1, 9);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(2, 1);\n}, { value: 'word\\n another wordword\\n wordwordword\\n' });\ntestVim('/_2_nopcre', function(cm, vim, helpers) {\n  CodeMirror.Vim.setOption('pcre', false);\n  helpers.doKeys('/', '\\\\(word\\\\)\\\\{2}', '\\n');\n  helpers.assertCursorAt(1, 9);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(2, 1);\n}, { value: 'word\\n another wordword\\n wordwordword\\n' });\ntestVim('/_nongreedy', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'aa', '\\n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'aaa aa \\n a aa'});\ntestVim('?_nongreedy', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'aa', '\\n');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, isOldCodeMirror ? 1 : 0);\n}, { value: 'aaa aa \\n a aa'});\ntestVim('/_greedy', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'a+', '\\n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 1);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'aaa aa \\n a aa'});\ntestVim('?_greedy', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'a+', '\\n');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 1);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'aaa aa \\n a aa'});\ntestVim('/_greedy_0_or_more', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'a*', '\\n');\n  helpers.assertCursorAt(0, 3);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 5);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 0);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 1);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'aaa  aa\\n aa'});\ntestVim('?_greedy_0_or_more', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'a*', '\\n');\n  helpers.assertCursorAt(1, 1);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(1, 0);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 5);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 3); // ace_patch\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 0);\n}, { value: 'aaa  aa\\n aa'});\ntestVim('? and n/N', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n');\n  helpers.assertCursorAt(1, 6);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 11);\n  helpers.doKeys('N');\n  helpers.assertCursorAt(1, 6);\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', '?', 'match', '\\n');\n  helpers.assertCursorAt(0, 11);\n}, { value: 'match nope match \\n nope Match' });\ntestVim('? and gn selects the appropriate word', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n', 'n');\n  helpers.assertCursorAt(0, 11);\n\n  // gn should highlight the the current word while it is within a match.\n\n  // gn when cursor is in beginning of match\n  helpers.doKeys('gn', '<Esc>');\n  helpers.assertCursorAt(0, 11);\n\n  // gn when cursor is at end of match\n  helpers.doKeys('e', 'gn', '<Esc>');\n  helpers.assertCursorAt(0, 11);\n\n  // consecutive gns should extend the selection\n  helpers.doKeys('gn');\n  helpers.assertCursorAt(0, 11);\n  helpers.doKeys('gn');\n  helpers.assertCursorAt(0, 0);\n\n  // we should have selected the first and second \"match\"\n  helpers.doKeys('d');\n  eq(' \\n nope Match', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('? and gN selects the appropriate word', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n', 'n');\n  helpers.assertCursorAt(0, 11);\n\n  // gN when cursor is at beginning of match\n  helpers.doKeys('gN', '<Esc>');\n  helpers.assertCursorAt(0, 15);\n\n  // gN when cursor is at end of match\n  helpers.doKeys('gN', '<Esc>');\n  helpers.assertCursorAt(0, 15);\n\n  // consecutive gNs should extend the selection\n  helpers.doKeys('gN');\n  helpers.assertCursorAt(0, 16);\n  helpers.doKeys('gN');\n  helpers.assertCursorAt(1, 11);\n\n  // we should have selected the second and third \"match\"\n  helpers.doKeys('d');\n  eq('match nope ', cm.getValue());\n}, { value: 'match nope match \\n nope Match' })\ntestVim('? and gn with an associated operator', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n', 'n');\n  helpers.assertCursorAt(0, 11);\n\n  helpers.doKeys('c', 'gn', 'changed', '<Esc>');\n\n  // change the current match.\n  eq('match nope changed \\n nope Match', cm.getValue());\n\n  // change the next match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope Match', cm.getValue());\n\n  // change the final match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope changed', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('? and gN with an associated operator', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n', 'n');\n  helpers.assertCursorAt(0, 11);\n\n  helpers.doKeys('c', 'gN', 'changed', '<Esc>');\n\n  // change the current match.\n  eq('match nope changed \\n nope Match', cm.getValue());\n\n  // change the next match.\n  helpers.doKeys('.');\n  eq('match nope changed \\n nope changed', cm.getValue());\n\n  // change the final match.\n  helpers.doKeys('.');\n  eq('changed nope changed \\n nope changed', cm.getValue());\n}, { value: 'match nope match \\n nope Match' });\ntestVim('*', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('*');\n  helpers.assertCursorAt(0, 22);\n\n  cm.setCursor(0, 9);\n  helpers.doKeys('2', '*');\n  helpers.assertCursorAt(1, 8);\n}, { value: 'nomatch match nomatch match \\nnomatch Match' });\ntestVim('*_no_word', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('*');\n  helpers.assertCursorAt(0, 0);\n}, { value: ' \\n match \\n' });\ntestVim('*_symbol', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('*');\n  helpers.assertCursorAt(1, 0);\n}, { value: ' /}\\n/} match \\n' });\ntestVim('#', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('#');\n  helpers.assertCursorAt(1, 8);\n\n  cm.setCursor(0, 9);\n  helpers.doKeys('2', '#');\n  helpers.assertCursorAt(0, 22);\n}, { value: 'nomatch match nomatch match \\nnomatch Match' });\ntestVim('*_seek', function(cm, vim, helpers) {\n  // Should skip over space and symbols.\n  cm.setCursor(0, 3);\n  helpers.doKeys('*');\n  helpers.assertCursorAt(0, 22);\n}, { value: '    :=  match nomatch match \\nnomatch Match' });\ntestVim('#', function(cm, vim, helpers) {\n  // Should skip over space and symbols.\n  cm.setCursor(0, 3);\n  helpers.doKeys('#');\n  helpers.assertCursorAt(1, 8);\n}, { value: '    :=  match nomatch match \\nnomatch Match' });\ntestVim('g*', function(cm, vim, helpers) {\n  cm.setCursor(0, 8);\n  helpers.doKeys('g', '*');\n  helpers.assertCursorAt(0, 18);\n  cm.setCursor(0, 8);\n  helpers.doKeys('3', 'g', '*');\n  helpers.assertCursorAt(1, 8);\n}, { value: 'matches match alsoMatch\\nmatchme matching' });\ntestVim('g#', function(cm, vim, helpers) {\n  cm.setCursor(0, 8);\n  helpers.doKeys('g', '#');\n  helpers.assertCursorAt(0, 0);\n  cm.setCursor(0, 8);\n  helpers.doKeys('3', 'g', '#');\n  helpers.assertCursorAt(1, 0);\n}, { value: 'matches match alsoMatch\\nmatchme matching' });\ntestVim('macro_insert', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', '0', 'i');\n  helpers.doKeys('foo')\n  helpers.doKeys('<Esc>');\n  eq(helpers.getNotificationText(), 'recording @a');\n  helpers.doKeys('q', '@', 'a');\n  eq(helpers.getNotificationText(), null);\n  eq('foofoo', cm.getValue());\n}, { value: ''});\ntestVim('macro_insert_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', '$', 'a');\n  helpers.doKeys('larry.')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('a');\n  helpers.doKeys('curly.')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doKeys('a');\n  helpers.doKeys('moe.')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('@', 'a');\n  // At this point, the most recent edit should be the 2nd insert change\n  // inside the macro, i.e. \"curly.\".\n  helpers.doKeys('.');\n  eq('larry.curly.moe.larry.curly.curly.', cm.getValue());\n}, { value: ''});\ntestVim('macro_space', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('<Space>', '<Space>');\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('q', 'a', '<Space>', '<Space>', 'q');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('@', 'a');\n  helpers.assertCursorAt(0, 6);\n  helpers.doKeys('@', 'a');\n  helpers.assertCursorAt(0, 8);\n}, { value: 'one line of text.'});\ntestVim('macro_t_search', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', 't', 'e', 'q');\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('l', '@', 'a');\n  helpers.assertCursorAt(0, 6);\n  helpers.doKeys('l', ';');\n  helpers.assertCursorAt(0, 12);\n}, { value: 'one line of text.'});\ntestVim('macro_f_search', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'b', 'f', 'e', 'q');\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('@', 'b');\n  helpers.assertCursorAt(0, 7);\n  helpers.doKeys(';');\n  helpers.assertCursorAt(0, 13);\n}, { value: 'one line of text.'});\ntestVim('macro_slash_search', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'c');\n  helpers.doKeys('/', 'e', '\\n', 'q');\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('@', 'c');\n  helpers.assertCursorAt(0, 7);\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 13);\n}, { value: 'one line of text.'});\ntestVim('macro_multislash_search', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'd');\n  helpers.doKeys('/', 'e', '\\n');\n  helpers.doKeys('/', 't', '\\n', 'q');\n  helpers.assertCursorAt(0, 12);\n  helpers.doKeys('@', 'd');\n  helpers.assertCursorAt(0, 15);\n}, { value: 'one line of text to rule them all.'});\ntestVim('macro_last_ex_command_register', function (cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('s/a/b');\n  helpers.doKeys('2', '@', ':');\n  eq('bbbaa', cm.getValue());\n  helpers.assertCursorAt(0, 2);\n}, { value: 'aaaaa'});\ntestVim('macro_last_run_macro', function (cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', 'C', 'a', '<Esc>', 'q');\n  helpers.doKeys('q', 'b', 'C', 'b', '<Esc>', 'q');\n  helpers.doKeys('@', 'a');\n  helpers.doKeys('d', 'd');\n  helpers.doKeys('@', '@');\n  eq('a', cm.getValue());\n}, { value: ''});\ntestVim('macro_parens', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'z', 'i');\n  helpers.doKeys('(')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('e', 'a');\n  helpers.doKeys(')')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doKeys('w', '@', 'z');\n  helpers.doKeys('w', '@', 'z');\n  eq('(see) (spot) (run)', cm.getValue());\n}, { value: 'see spot run'});\ntestVim('macro_overwrite', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'z', '0', 'i');\n  helpers.doKeys('I ')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doKeys('e');\n  // Now replace the macro with something else.\n  helpers.doKeys('q', 'z', 'a');\n  helpers.doKeys('.')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doKeys('e', '@', 'z');\n  helpers.doKeys('e', '@', 'z');\n  eq('I see. spot. run.', cm.getValue());\n}, { value: 'see spot run'});\ntestVim('macro_search_f', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', 'f', ' ');\n  helpers.assertCursorAt(0,3);\n  helpers.doKeys('q', '0');\n  helpers.assertCursorAt(0,0);\n  helpers.doKeys('@', 'a');\n  helpers.assertCursorAt(0,3);\n}, { value: 'The quick brown fox jumped over the lazy dog.'});\ntestVim('macro_search_2f', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', '2', 'f', ' ');\n  helpers.assertCursorAt(0,9);\n  helpers.doKeys('q', '0');\n  helpers.assertCursorAt(0,0);\n  helpers.doKeys('@', 'a');\n  helpers.assertCursorAt(0,9);\n}, { value: 'The quick brown fox jumped over the lazy dog.'});\ntestVim('macro_yank_tick', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  // Start recording a macro into the \\' register.\n  helpers.doKeys('q', '\\'');\n  helpers.doKeys('y', '<Right>', '<Right>', '<Right>', '<Right>', 'p');\n  helpers.assertCursorAt(0,4);\n  eq('the tex parrot', cm.getValue());\n}, { value: 'the ex parrot'});\ntestVim('yank_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'y');\n  helpers.doKeys('j', '\"', 'b', 'y', 'y');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+foo/.test(text));\n  is(/b\\s+bar/.test(text));\n}, { value: 'foo\\nbar'});\ntestVim('yank_visual_block', function(cm, vim, helpers) {\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', 'l', 'j', '\"', 'a', 'y');\n  helpers.doEx('registers');\n  is(/a\\s+oo\\nar/.test(helpers.getNotificationText()));\n}, { value: 'foo\\nbar'});\ntestVim('yank_append_line_to_line_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'y');\n  helpers.doKeys('j', '\"', 'A', 'y', 'y');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+foo\\nbar/.test(text));\n  is(/\"\\s+foo\\nbar/.test(text));\n}, { value: 'foo\\nbar'});\ntestVim('yank_append_word_to_word_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'w');\n  helpers.doKeys('j', '\"', 'A', 'y', 'w');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+foobar/.test(text));\n  is(/\"\\s+foobar/.test(text));\n}, { value: 'foo\\nbar'});\ntestVim('yank_append_line_to_word_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'w');\n  helpers.doKeys('j', '\"', 'A', 'y', 'y');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+foo\\nbar/.test(text));\n  is(/\"\\s+foo\\nbar/.test(text));\n}, { value: 'foo\\nbar'});\ntestVim('yank_append_word_to_line_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('\"', 'a', 'y', 'y');\n  helpers.doKeys('j', '\"', 'A', 'y', 'w');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+foo\\nbar/.test(text));\n  is(/\"\\s+foo\\nbar/.test(text));\n}, { value: 'foo\\nbar'});\ntestVim('black_hole_register', function(cm,vim,helpers) {\n  helpers.doKeys('g', 'g', 'y', 'G');\n  helpers.doEx('registers');\n  var registersText = helpers.getNotificationText();\n  helpers.doKeys('\"', '_', 'd', 'G');\n  helpers.doEx('registers');\n  eq(registersText, helpers.getNotificationText(), 'One or more registers were modified');\n  helpers.doKeys('\"', '_', 'p');\n  eq('', cm.getValue());\n}, { value: 'foo\\nbar'});\ntestVim('macro_register', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('q', 'a', 'i');\n  helpers.doKeys('gangnam')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doKeys('q', 'b', 'o');\n  helpers.doKeys('style')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('q');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/a\\s+i/.test(text));\n  is(/b\\s+o/.test(text));\n}, { value: ''});\ntestVim('._register', function(cm,vim,helpers) {\n  cm.setCursor(0,0);\n  helpers.doKeys('i');\n  helpers.doKeys('foo')\n  helpers.doKeys('<Esc>');\n  helpers.doEx('registers');\n  is(/\\.\\s+foo/.test(helpers.getNotificationText()));\n}, {value: ''});\ntestVim(':_register', function(cm,vim,helpers) {\n  helpers.doEx('bar');\n  helpers.doEx('registers');\n  is(/:\\s+bar/.test(helpers.getNotificationText()));\n}, {value: ''});\ntestVim('registers_html_encoding', function(cm,vim,helpers) {\n  helpers.doKeys('y', 'y');\n  helpers.doEx('registers');\n  is(/\"\\s+<script>throw \"&amp;\"<\\/script>/.test(helpers.getNotificationText()));\n}, {value: '<script>throw \"&amp;\"</script>'});\ntestVim('search_register_escape', function(cm, vim, helpers) {\n  // Check that the register is restored if the user escapes rather than confirms.\n  helpers.doKeys('/', 'waldo', '\\n');\n  helpers.doKeys('/', 'foo', '<Esc>');\n  helpers.doEx('registers');\n  var text = helpers.getNotificationText();\n  is(/waldo/.test(text));\n  is(!/foo/.test(text));\n}, {value: ''});\ntestVim('search_register', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'foo', '\\n');\n  helpers.doEx('registers');\n  is(/\\/\\s+foo/.test(helpers.getNotificationText()));\n}, {value: ''});\ntestVim('search_history', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'this', '\\n');\n  helpers.doKeys('/', 'checks', '\\n');\n  helpers.doKeys('/', 'search', '\\n');\n  helpers.doKeys('/', 'history', '\\n');\n  helpers.doKeys('/', 'checks', '\\n');\n  helpers.doKeys('/');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'checks');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'history');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'search');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'this');\n  helpers.doKeys('Down');\n  eq(document.activeElement.value, 'search');\n}, {value: ''});\ntestVim('exCommand_history', function(cm, vim, helpers) {\n  helpers.doEx('registers');\n  helpers.doEx('sort');\n  helpers.doEx('map');\n  helpers.doEx('invalid');\n  helpers.doKeys(':');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'invalid');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'map');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'sort');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'registers');\n  helpers.doKeys('<Esc>', ':');\n  helpers.doKeys('s');\n  eq(document.activeElement.value, 's');\n  helpers.doKeys('Up');\n  eq(document.activeElement.value, 'sort');\n}, {value: ''});\ntestVim('search_clear', function(cm, vim, helpers) {\n  helpers.doKeys('/', 'foo');\n  eq(document.activeElement.value, 'foo');\n  helpers.doKeys('<C-u>');\n  eq(document.activeElement.value, '');\n});\ntestVim('exCommand_clear', function(cm, vim, helpers) {\n  helpers.doKeys(':', 'foo');\n  eq(document.activeElement.value, 'foo');\n  helpers.doKeys('<C-u>');\n  eq(document.activeElement.value, '');\n});\ntestVim('._normal', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', 'd', 'w');\n  helpers.doKeys('.');\n  eq('5 6', cm.getValue());\n\n  helpers.doKeys('a');\n  cm.operation(function() {\n    cm.curOp.isVimOp = true;\n    cm.replaceSelection(\"()\");\n    var pos = cm.getCursor();\n    pos.ch--;\n    cm.setCursor(pos);\n  });\n  helpers.doKeys('x', 'y', '<Esc>');\n  helpers.doKeys('.');\n  eq('5(xy(xy)) 6', cm.getValue());\n}, { value: '1 2 3 4 5 6'});\ntestVim('._repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('2', 'd', 'w');\n  helpers.doKeys('3', '.');\n  eq('6', cm.getValue());\n}, { value: '1 2 3 4 5 6'});\ntestVim('._insert', function(cm, vim, helpers) {\n  helpers.doKeys('i');\n  helpers.doKeys('test')\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('testestt', cm.getValue());\n  helpers.assertCursorAt(0, 6);\n  helpers.doKeys('O');\n  helpers.doKeys('xyz')\n  helpers.doKeys('Backspace');\n  helpers.doKeys('Down');\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('xy\\nxy\\ntestestt', cm.getValue());\n  helpers.assertCursorAt(1, 1);\n}, { value: ''});\ntestVim('._startinsert', function(cm, vim, helpers) {\n  helpers.doEx('map i x');\n  helpers.doKeys('i');\n  eq('', cm.getValue());\n  helpers.doEx('start');\n  helpers.doKeys('test');\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('testestt', cm.getValue());\n  helpers.assertCursorAt(0, 6);\n  helpers.doEx('start!');\n  helpers.doKeys('xyz');\n  eq('testesttxyz', cm.getValue());\n  helpers.assertCursorAt(0, 11);\n}, { value: 'x'});\ntestVim('._insert_repeat', function(cm, vim, helpers) {\n  helpers.doKeys('i');\n  helpers.doKeys('test')\n  cm.setCursor(0, 4);\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('2', '.');\n  eq('testesttestt', cm.getValue());\n  helpers.assertCursorAt(0, 10);\n}, { value: ''});\ntestVim('._repeat_insert', function(cm, vim, helpers) {\n  helpers.doKeys('3', 'i');\n  helpers.doKeys('te')\n  cm.setCursor(0, 2);\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('tetettetetee', cm.getValue());\n  helpers.assertCursorAt(0, 10);\n}, { value: ''});\ntestVim('._insert_o', function(cm, vim, helpers) {\n  helpers.doKeys('o');\n  helpers.doKeys('z')\n  cm.setCursor(1, 1);\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('\\nz\\nz', cm.getValue());\n  helpers.assertCursorAt(2, 0);\n}, { value: ''});\ntestVim('._insert_o_repeat', function(cm, vim, helpers) {\n  helpers.doKeys('o');\n  helpers.doKeys('z')\n  helpers.doKeys('<Esc>');\n  cm.setCursor(1, 0);\n  helpers.doKeys('2', '.');\n  eq('\\nz\\nz\\nz', cm.getValue());\n  helpers.assertCursorAt(3, 0);\n}, { value: ''});\ntestVim('._insert_o_indent', function(cm, vim, helpers) {\n  helpers.doKeys('o');\n  helpers.doKeys('z')\n  helpers.doKeys('<Esc>');\n  cm.setCursor(1, 2);\n  helpers.doKeys('.');\n  eq('{\\n  z\\n  z', cm.getValue());\n  helpers.assertCursorAt(2, 2);\n}, { value: '{'});\ntestVim('._insert_cw', function(cm, vim, helpers) {\n  helpers.doKeys('c', 'w');\n  helpers.doKeys('test')\n  helpers.doKeys('<Esc>');\n  cm.setCursor(0, 3);\n  helpers.doKeys('2', 'l');\n  helpers.doKeys('.');\n  eq('test test word3', cm.getValue());\n  helpers.assertCursorAt(0, 8);\n}, { value: 'word1 word2 word3' });\ntestVim('._insert_cw_repeat', function(cm, vim, helpers) {\n  // For some reason, repeat cw in desktop VIM will does not repeat insert mode\n  // changes. Will conform to that behavior.\n  helpers.doKeys('c', 'w');\n  helpers.doKeys('test');\n  helpers.doKeys('<Esc>');\n  cm.setCursor(0, 4);\n  helpers.doKeys('l');\n  helpers.doKeys('2', '.');\n  eq('test test', cm.getValue());\n  helpers.assertCursorAt(0, 8);\n}, { value: 'word1 word2 word3' });\ntestVim('._delete', function(cm, vim, helpers) {\n  cm.setCursor(0, 5);\n  helpers.doKeys('i');\n  helpers.doKeys('Backspace');\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('.');\n  eq('zace', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n}, { value: 'zabcde'});\ntestVim('._delete_repeat', function(cm, vim, helpers) {\n  cm.setCursor(0, 6);\n  helpers.doKeys('i');\n  helpers.doKeys('Backspace');\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('2', '.');\n  eq('zzce', cm.getValue());\n  helpers.assertCursorAt(0, 1);\n}, { value: 'zzabcde'});\ntestVim('._visual_>', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('V', 'j', '>');\n  cm.setCursor(2, 0)\n  helpers.doKeys('.');\n  eq('  1\\n  2\\n  3\\n  4', cm.getValue());\n  helpers.assertCursorAt(2, 2);\n}, { value: '1\\n2\\n3\\n4'});\ntestVim('._replace_repeat', function(cm, vim, helpers) {\n  helpers.doKeys('R');\n  cm.replaceRange('123', cm.getCursor(), offsetCursor(cm.getCursor(), 0, 3));\n  cm.setCursor(0, 3);\n  helpers.doKeys('<Esc>');\n  helpers.doKeys('2', '.');\n  eq('12123123\\nabcdefg', cm.getValue());\n  helpers.assertCursorAt(0, 7);\n  cm.setCursor(1, 0);\n  helpers.doKeys('.');\n  eq('12123123\\n123123g', cm.getValue());\n  helpers.doKeys('l', '\"', '.', 'p');\n  eq('12123123\\n123123g123', cm.getValue());\n}, { value: 'abcdef\\nabcdefg'});\ntestVim('f;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('f', 'x');\n  helpers.doKeys(';');\n  helpers.doKeys('2', ';');\n  eq(9, cm.getCursor().ch);\n}, { value: '01x3xx678x'});\ntestVim('F;', function(cm, vim, helpers) {\n  cm.setCursor(0, 8);\n  helpers.doKeys('F', 'x');\n  helpers.doKeys(';');\n  helpers.doKeys('2', ';');\n  eq(2, cm.getCursor().ch);\n}, { value: '01x3xx6x8x'});\ntestVim('t;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('t', 'x');\n  helpers.doKeys(';');\n  helpers.doKeys('2', ';');\n  eq(8, cm.getCursor().ch);\n}, { value: '01x3xx678x'});\ntestVim('T;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('T', 'x');\n  helpers.doKeys(';');\n  helpers.doKeys('2', ';');\n  eq(2, cm.getCursor().ch);\n}, { value: '0xx3xx678x'});\ntestVim('f,', function(cm, vim, helpers) {\n  cm.setCursor(0, 6);\n  helpers.doKeys('f', 'x');\n  helpers.doKeys(',');\n  helpers.doKeys('2', ',');\n  eq(2, cm.getCursor().ch);\n}, { value: '01x3xx678x'});\ntestVim('F,', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doKeys('F', 'x');\n  helpers.doKeys(',');\n  helpers.doKeys('2', ',');\n  eq(9, cm.getCursor().ch);\n}, { value: '01x3xx678x'});\ntestVim('t,', function(cm, vim, helpers) {\n  cm.setCursor(0, 6);\n  helpers.doKeys('t', 'x');\n  helpers.doKeys(',');\n  helpers.doKeys('2', ',');\n  eq(3, cm.getCursor().ch);\n}, { value: '01x3xx678x'});\ntestVim('T,', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('T', 'x');\n  helpers.doKeys(',');\n  helpers.doKeys('2', ',');\n  eq(8, cm.getCursor().ch);\n}, { value: '01x3xx67xx'});\ntestVim('fd,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('f', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ';');\n  eq('56789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('d', ',');\n  eq('01239', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Fd,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('F', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('d', ';');\n  eq('01239', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ',');\n  eq('56789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('td,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('t', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ';');\n  eq('456789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('d', ',');\n  eq('012349', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Td,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('T', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('d', ';');\n  eq('012349', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('d', ',');\n  eq('456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('fc,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('f', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', ';', '<Esc>');\n  eq('56789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('c', ',');\n  eq('01239', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Fc,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('F', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('c', ';', '<Esc>');\n  eq('01239', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', ',');\n  eq('56789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('tc,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('t', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', ';', '<Esc>');\n  eq('456789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('c', ',');\n  eq('012349', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Tc,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('T', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('c', ';', '<Esc>');\n  eq('012349', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('c', ',');\n  eq('456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('fy,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('f', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('y', ';', 'P');\n  eq('012340123456789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('y', ',', 'P');\n  eq('012345678456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Fy,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('F', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('y', ';', 'p');\n  eq('012345678945678', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('y', ',', 'P');\n  eq('012340123456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('ty,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('t', '4');\n  cm.setCursor(0, 0);\n  helpers.doKeys('y', ';', 'P');\n  eq('01230123456789', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 9);\n  helpers.doKeys('y', ',', 'p');\n  eq('01234567895678', cm.getValue());\n}, { value: '0123456789'});\ntestVim('Ty,;', function(cm, vim, helpers) {\n  cm.setCursor(0, 9);\n  helpers.doKeys('T', '4');\n  cm.setCursor(0, 9);\n  helpers.doKeys('y', ';', 'p');\n  eq('01234567895678', cm.getValue());\n  helpers.doKeys('u');\n  cm.setCursor(0, 0);\n  helpers.doKeys('y', ',', 'P');\n  eq('01230123456789', cm.getValue());\n}, { value: '0123456789'});\ntestVim('vFT', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys('v', 'f', '1');\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('2', 't', ' ');\n  helpers.assertCursorAt(0, 8);\n  eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));\n  helpers.doKeys('<Esc>');\n  eqCursorPos(new Pos(0, 7), cm.getCursor('anchor'));\n  helpers.doKeys('v', 'F', '3');\n  helpers.assertCursorAt(0, 3);\n  eqCursorPos(new Pos(0, 8), cm.getCursor('anchor'));\n  helpers.doKeys('T', '1');\n  helpers.assertCursorAt(0, 2);\n  helpers.doKeys('F', '1');\n  helpers.assertCursorAt(0, 1);\n  helpers.doKeys('F', '1');\n  helpers.assertCursorAt(0, 0);\n}, { value: '1123 123 123'});\ntestVim('page_motions', function(cm, vim, helpers) {\n  var value = \"x\".repeat(200).split(\"\").map((_, i)=>i).join(\"\\n\");\n  cm.setValue(value);\n  cm.refresh();\n  var lines = 10;\n  var textHeight = cm.defaultTextHeight();\n  cm.setSize(600, lines*textHeight);\n  cm.setCursor(100, 0);\n  cm.refresh();\n  helpers.doKeys('<C-u>');\n  helpers.assertCursorAt(95, 0);\n  helpers.doKeys('<C-u>');\n  helpers.assertCursorAt(90, 0);\n  helpers.doKeys('<C-d>');\n  helpers.doKeys('<C-d>');\n  helpers.assertCursorAt(100, 0);\n  cm.refresh();\n  helpers.doKeys('<C-f>');\n  cm.refresh();\n  helpers.assertCursorAt(110, 0);\n\n  helpers.doKeys('<C-b>');\n  cm.refresh();\n  helpers.assertCursorAt(100, 0);\n  eq(value, cm.getValue());\n});\ntestVim('HML', function(cm, vim, helpers) {\n  cm.refresh();\n  var lines = 35;\n  var textHeight = cm.defaultTextHeight();\n  cm.setSize(600, lines*textHeight);\n  cm.setCursor(120, 0);\n  cm.ace.renderer.scrollCursorIntoView(); cm.refresh(); //ace_patch\n  helpers.doKeys('H');\n  helpers.assertCursorAt(86, 2);\n  helpers.doKeys('L');\n  helpers.assertCursorAt(120, 4);\n  helpers.doKeys('M');\n  helpers.assertCursorAt(103,4);\n}, { value: (function(){\n  var lines = new Array(100);\n  var upper = '  xx\\n';\n  var lower = '    xx\\n';\n  upper = lines.join(upper);\n  lower = lines.join(lower);\n  return upper + lower;\n})()});\n\nvar zVals = [];\nvar cursorIndexVals = [];\nforEach(['zb','zz','zt','z-','z.','z<CR>'], function(e, idx){\n  var lineNum = 250;\n  var lines = 35;\n  testVim(e, function(cm, vim, helpers) {\n    cm.refresh();\n    var k1 = e[0];\n    var k2 = e.substring(1);\n    var textHeight = cm.defaultTextHeight();\n    cm.setSize(600, lines*textHeight);\n    cm.setCursor(lineNum, 1);\n    var originalCursorIndex = cm.indexFromPos(cm.getCursor());\n    helpers.doKeys(k1, k2);\n    zVals[idx] = cm.getScrollInfo().top;\n    cursorIndexVals[idx] = {\n      before: originalCursorIndex,\n      after: cm.indexFromPos(cm.getCursor())\n    };\n  }, { value: (function(){\n    return new Array(500).join('12\\n');\n  })()});\n});\ntestVim('zb_to_bottom', function(cm, vim, helpers){\n  cm.refresh();\n  var lineNum = 250;\n  cm.setSize(600, 35*cm.defaultTextHeight());\n  cm.setCursor(lineNum, 0);\n  helpers.doKeys('z', 'b');\n  var scrollInfo = cm.getScrollInfo();\n  eq(scrollInfo.top + scrollInfo.clientHeight, cm.charCoords(new Pos(lineNum, 0), 'local').bottom);\n}, { value: (function(){\n  return new Array(500).join('\\n');\n})()});\ntestVim('zt_to_top', function(cm, vim, helpers){\n  cm.refresh();\n  var lineNum = 250;\n  cm.setSize(600, 35*cm.defaultTextHeight());\n  cm.setCursor(lineNum, 0);\n  helpers.doKeys('z', 't');\n  eq(cm.getScrollInfo().top, cm.charCoords(new Pos(lineNum, 0), 'local').top);\n}, { value: (function(){\n  return new Array(500).join('\\n');\n})()});\ntestVim('zb<zz', function(cm, vim, helpers){\n  eq(zVals[0]<zVals[1], true);\n});\ntestVim('zz<zt', function(cm, vim, helpers){\n  eq(zVals[1]<zVals[2], true);\n});\ntestVim('zb==z-', function(cm, vim, helpers){\n  eq(zVals[0], zVals[3]);\n});\ntestVim('zz==z.', function(cm, vim, helpers){\n  eq(zVals[1], zVals[4]);\n});\ntestVim('zt==z<CR>', function(cm, vim, helpers){\n  eq(zVals[2], zVals[5]);\n});\ntestVim('zt_no_cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[2];\n  eq(cursorIndexes.before, cursorIndexes.after);\n});\ntestVim('z<CR>_cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[5];\n  eq(cursorIndexes.before, 751);\n  eq(cursorIndexes.after, 750);\n});\ntestVim('zz_no_cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[1];\n  eq(cursorIndexes.before, cursorIndexes.after);\n});\ntestVim('z._cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[4];\n  eq(cursorIndexes.before, 751);\n  eq(cursorIndexes.after, 750);\n});\ntestVim('zb_no_cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[0];\n  eq(cursorIndexes.before, cursorIndexes.after);\n});\ntestVim('z-_cursor_change', function(cm, vim, helpers){\n  var cursorIndexes = cursorIndexVals[3];\n  eq(cursorIndexes.before, 751);\n  eq(cursorIndexes.after, 750);\n});\n\nvar moveTillCharacterSandbox =\n  'The quick brown fox \\n';\ntestVim('moveTillCharacter', function(cm, vim, helpers){\n  cm.setCursor(0, 0);\n  // Search for the 'q'.\n  helpers.doKeys('/', 'q', '\\n');\n  eq(4, cm.getCursor().ch);\n  // Jump to just before the first o in the list.\n  helpers.doKeys('t');\n  helpers.doKeys('o');\n  eq('The quick brown fox \\n', cm.getValue());\n  // Delete that one character.\n  helpers.doKeys('d');\n  helpers.doKeys('t');\n  helpers.doKeys('o');\n  eq('The quick bown fox \\n', cm.getValue());\n  // Delete everything until the next 'o'.\n  helpers.doKeys('.');\n  eq('The quick box \\n', cm.getValue());\n  // An unmatched character should have no effect.\n  helpers.doKeys('d');\n  helpers.doKeys('t');\n  helpers.doKeys('q');\n  eq('The quick box \\n', cm.getValue());\n  // Matches should only be possible on single lines.\n  helpers.doKeys('d');\n  helpers.doKeys('t');\n  helpers.doKeys('z');\n  eq('The quick box \\n', cm.getValue());\n  // After all that, the search for 'q' should still be active, so the 'N' command\n  // can run it again in reverse. Use that to delete everything back to the 'q'.\n  helpers.doKeys('d');\n  helpers.doKeys('N');\n  eq('The ox \\n', cm.getValue());\n  eq(4, cm.getCursor().ch);\n}, { value: moveTillCharacterSandbox});\ntestVim('searchForPipe', function(cm, vim, helpers){\n  CodeMirror.Vim.setOption('pcre', false);\n  cm.setCursor(0, 0);\n  // Search for the '|'.\n  helpers.doKeys('/', '|', '\\n');\n  eq(4, cm.getCursor().ch);\n}, { value: 'this|that'});\n\n\nvar scrollMotionSandbox =\n  '\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n';\ntestVim('scrollMotion', function(cm, vim, helpers){\n  var prevCursor, prevScrollInfo;\n  cm.setSize(320, 200);\n  cm.setCursor(0, 0);\n  cm.refresh();\n  // ctrl-y at the top of the file should have no effect.\n  helpers.doKeys('<C-y>');\n  eq(0, cm.getCursor().line);\n  cm.refresh();\n  prevScrollInfo = cm.getScrollInfo();\n  helpers.doKeys('<C-e>');\n  eq(1, cm.getCursor().line);\n  cm.refresh();\n  is(prevScrollInfo.top < cm.getScrollInfo().top);\n  // Jump to the end of the sandbox.\n  cm.setCursor(1000, 0);\n  cm.refresh();\n  prevCursor = cm.getCursor();\n  // ctrl-e at the bottom of the file should have no effect.\n  helpers.doKeys('<C-e>');\n  eq(prevCursor.line, cm.getCursor().line);\n  cm.refresh(); //ace_patch\n  prevScrollInfo = cm.getScrollInfo();\n  helpers.doKeys('<C-y>');\n  eq(prevCursor.line - 1, cm.getCursor().line, \"Y\");\n  is(prevScrollInfo.top > cm.getScrollInfo().top);\n}, { value: scrollMotionSandbox});\n\nvar squareBracketMotionSandbox = ''+\n  '({\\n'+//0\n  '  ({\\n'+//11\n  '  /*comment {\\n'+//2\n  '            */(\\n'+//3\n  '#else                \\n'+//4\n  '  /*       )\\n'+//5\n  '#if        }\\n'+//6\n  '  )}*/\\n'+//7\n  ')}\\n'+//8\n  '{}\\n'+//9\n  '#else {{\\n'+//10\n  '{}\\n'+//11\n  '}\\n'+//12\n  '{\\n'+//13\n  '#endif\\n'+//14\n  '}\\n'+//15\n  '}\\n'+//16\n  '#else';//17\ntestVim('[[, ]]', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys(']', ']');\n  helpers.assertCursorAt(9,0);\n  helpers.doKeys('2', ']', ']');\n  helpers.assertCursorAt(13,0);\n  helpers.doKeys(']', ']');\n  helpers.assertCursorAt(17,0);\n  helpers.doKeys('[', '[');\n  helpers.assertCursorAt(13,0);\n  helpers.doKeys('2', '[', '[');\n  helpers.assertCursorAt(9,0);\n  helpers.doKeys('[', '[');\n  helpers.assertCursorAt(0,0);\n}, { value: squareBracketMotionSandbox});\ntestVim('[], ][', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doKeys(']', '[');\n  helpers.assertCursorAt(12,0);\n  helpers.doKeys('2', ']', '[');\n  helpers.assertCursorAt(16,0);\n  helpers.doKeys(']', '[');\n  helpers.assertCursorAt(17,0);\n  helpers.doKeys('[', ']');\n  helpers.assertCursorAt(16,0);\n  helpers.doKeys('2', '[', ']');\n  helpers.assertCursorAt(12,0);\n  helpers.doKeys('[', ']');\n  helpers.assertCursorAt(0,0);\n}, { value: squareBracketMotionSandbox});\ntestVim('[{, ]}', function(cm, vim, helpers) {\n  cm.setCursor(4, 10);\n  helpers.doKeys('[', '{');\n  helpers.assertCursorAt(2,12);\n  helpers.doKeys('2', '[', '{');\n  helpers.assertCursorAt(0,1);\n  cm.setCursor(4, 10);\n  helpers.doKeys(']', '}');\n  helpers.assertCursorAt(6,11);\n  helpers.doKeys('2', ']', '}');\n  helpers.assertCursorAt(8,1);\n  cm.setCursor(0,1);\n  helpers.doKeys(']', '}');\n  helpers.assertCursorAt(8,1);\n  helpers.doKeys('[', '{');\n  helpers.assertCursorAt(0,1);\n}, { value: squareBracketMotionSandbox});\ntestVim('[(, ])', function(cm, vim, helpers) {\n  cm.setCursor(4, 10);\n  helpers.doKeys('[', '(');\n  helpers.assertCursorAt(3,14);\n  helpers.doKeys('2', '[', '(');\n  helpers.assertCursorAt(0,0);\n  cm.setCursor(4, 10);\n  helpers.doKeys(']', ')');\n  helpers.assertCursorAt(5,11);\n  helpers.doKeys('2', ']', ')');\n  helpers.assertCursorAt(8,0);\n  helpers.doKeys('[', '(');\n  helpers.assertCursorAt(0,0);\n  helpers.doKeys(']', ')');\n  helpers.assertCursorAt(8,0);\n}, { value: squareBracketMotionSandbox});\ntestVim('[*, ]*, [/, ]/', function(cm, vim, helpers) {\n  forEach(['*', '/'], function(key){\n    cm.setCursor(7, 0);\n    helpers.doKeys('2', '[', key);\n    helpers.assertCursorAt(2,2);\n    helpers.doKeys('2', ']', key);\n    helpers.assertCursorAt(7,5);\n  });\n}, { value: squareBracketMotionSandbox});\ntestVim('[#, ]#', function(cm, vim, helpers) {\n  cm.setCursor(10, 3);\n  helpers.doKeys('2', '[', '#');\n  helpers.assertCursorAt(4,0);\n  helpers.doKeys('5', ']', '#');\n  helpers.assertCursorAt(17,0);\n  cm.setCursor(10, 3);\n  helpers.doKeys(']', '#');\n  helpers.assertCursorAt(14,0);\n}, { value: squareBracketMotionSandbox});\ntestVim('[m, ]m, [M, ]M', function(cm, vim, helpers) {\n  cm.setCursor(11, 0);\n  helpers.doKeys('[', 'm');\n  helpers.assertCursorAt(10,7);\n  helpers.doKeys('4', '[', 'm');\n  helpers.assertCursorAt(1,3);\n  helpers.doKeys('5', ']', 'm');\n  helpers.assertCursorAt(11,0);\n  helpers.doKeys('[', 'M');\n  helpers.assertCursorAt(9,1);\n  helpers.doKeys('3', ']', 'M');\n  helpers.assertCursorAt(15,0);\n  helpers.doKeys('5', '[', 'M');\n  helpers.assertCursorAt(7,3);\n}, { value: squareBracketMotionSandbox});\n\ntestVim('i_indent_right', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedValue = '   word1\\nword2\\nword3 ';\n  helpers.doKeys('i', '<C-t>');\n  eq(expectedValue, cm.getValue());\n  helpers.assertCursorAt(0, 5);\n}, { value: ' word1\\nword2\\nword3 ', indentUnit: 2 });\ntestVim('i_indent_left', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  var expectedValue = ' word1\\nword2\\nword3 ';\n  helpers.doKeys('i', '<C-d>');\n  eq(expectedValue, cm.getValue());\n  helpers.assertCursorAt(0, 1);\n}, { value: '   word1\\nword2\\nword3 ', indentUnit: 2 });\n\n// Ex mode tests\ntestVim('ex_go_to_line', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('4');\n  helpers.assertCursorAt(3, 0);\n}, { value: 'a\\nb\\nc\\nd\\ne\\n'});\ntestVim('ex_go_to_mark', function(cm, vim, helpers) {\n  cm.setCursor(3, 0);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(0, 0);\n  helpers.doEx('\\'a');\n  helpers.assertCursorAt(3, 0);\n}, { value: 'a\\nb\\nc\\nd\\ne\\n'});\ntestVim('ex_go_to_line_offset', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('+3');\n  helpers.assertCursorAt(3, 0);\n  helpers.doEx('-1');\n  helpers.assertCursorAt(2, 0);\n  helpers.doEx('.2');\n  helpers.assertCursorAt(4, 0);\n  helpers.doEx('.-3');\n  helpers.assertCursorAt(1, 0);\n}, { value: 'a\\nb\\nc\\nd\\ne\\n'});\ntestVim('ex_go_to_mark_offset', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('m', 'a');\n  cm.setCursor(0, 0);\n  helpers.doEx('\\'a1');\n  helpers.assertCursorAt(3, 0);\n  helpers.doEx('\\'a-1');\n  helpers.assertCursorAt(1, 0);\n  helpers.doEx('\\'a+2');\n  helpers.assertCursorAt(4, 0);\n}, { value: 'a\\nb\\nc\\nd\\ne\\n'});\ntestVim('ex_write', function(cm, vim, helpers) {\n  var tmp = CodeMirror.commands.save;\n  var written;\n  var actualCm;\n  CodeMirror.commands.save = function(cm) {\n    written = true;\n    actualCm = cm;\n  };\n  // Test that w, wr, wri ... write all trigger :write.\n  var command = 'write';\n  for (var i = 1; i < command.length; i++) {\n    written = false;\n    actualCm = null;\n    helpers.doEx(command.substring(0, i));\n    eq(written, true);\n    eq(actualCm, cm);\n  }\n  CodeMirror.commands.save = tmp;\n});\ntestVim('ex_delete', function(cm, vim, helpers) {\n  helpers.doKeys(\"j\");\n  helpers.doEx('delete');\n  eq('l 1\\nl 3\\nl 4\\n', cm.getValue());\n  helpers.doEx('d');\n  eq('l 1\\nl 4\\n', cm.getValue());\n}, { value: 'l 1\\nl 2\\nl 3\\nl 4\\n'});\ntestVim('ex_sort', function(cm, vim, helpers) {\n  helpers.doEx('sort');\n  eq('Z\\na\\nb\\nc\\nd', cm.getValue());\n}, { value: 'b\\nZ\\nd\\nc\\na'});\ntestVim('ex_sort_reverse', function(cm, vim, helpers) {\n  helpers.doEx('sort!');\n  eq('d\\nc\\nb\\na', cm.getValue());\n}, { value: 'b\\nd\\nc\\na'});\ntestVim('ex_sort_range', function(cm, vim, helpers) {\n  helpers.doEx('2,3sort');\n  eq('b\\nc\\nd\\na', cm.getValue());\n}, { value: 'b\\nd\\nc\\na'});\ntestVim('ex_sort_oneline', function(cm, vim, helpers) {\n  helpers.doEx('2sort');\n  // Expect no change.\n  eq('b\\nd\\nc\\na', cm.getValue());\n}, { value: 'b\\nd\\nc\\na'});\ntestVim('ex_sort_ignoreCase', function(cm, vim, helpers) {\n  helpers.doEx('sort i');\n  eq('a\\nb\\nc\\nd\\nZ', cm.getValue());\n}, { value: 'b\\nZ\\nd\\nc\\na'});\ntestVim('ex_sort_unique', function(cm, vim, helpers) {\n  helpers.doEx('sort u');\n  eq('Z\\na\\nb\\nc\\nd', cm.getValue());\n}, { value: 'b\\nZ\\na\\na\\nd\\na\\nc\\na'});\ntestVim('ex_sort_decimal', function(cm, vim, helpers) {\n  helpers.doEx('sort d');\n  eq('d3\\n s5\\n6\\n.9', cm.getValue());\n}, { value: '6\\nd3\\n s5\\n.9'});\ntestVim('ex_sort_decimal_negative', function(cm, vim, helpers) {\n  helpers.doEx('sort d');\n  eq('z-9\\nd3\\n s5\\n6\\n.9', cm.getValue());\n}, { value: '6\\nd3\\n s5\\n.9\\nz-9'});\ntestVim('ex_sort_decimal_reverse', function(cm, vim, helpers) {\n  helpers.doEx('sort! d');\n  eq('.9\\n6\\n s5\\nd3', cm.getValue());\n}, { value: '6\\nd3\\n s5\\n.9'});\ntestVim('ex_sort_hex', function(cm, vim, helpers) {\n  helpers.doEx('sort x');\n  eq(' s5\\n6\\n.9\\n&0xB\\nd3', cm.getValue());\n}, { value: '6\\nd3\\n s5\\n&0xB\\n.9'});\ntestVim('ex_sort_octal', function(cm, vim, helpers) {\n  helpers.doEx('sort o');\n  eq('.9\\n.8\\nd3\\n s5\\n6', cm.getValue());\n}, { value: '6\\nd3\\n s5\\n.9\\n.8'});\ntestVim('ex_sort_decimal_mixed', function(cm, vim, helpers) {\n  helpers.doEx('sort d');\n  eq('z\\ny\\nc1\\nb2\\na3', cm.getValue());\n}, { value: 'a3\\nz\\nc1\\ny\\nb2'});\ntestVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) {\n  helpers.doEx('sort! d');\n  eq('a3\\nb2\\nc1\\nz\\ny', cm.getValue());\n}, { value: 'a3\\nz\\nc1\\ny\\nb2'});\ntestVim('ex_sort_pattern_alpha', function(cm, vim, helpers) {\n  helpers.doEx('sort /[a-z]/');\n  eq('a3\\nb2\\nc1\\ny\\nz', cm.getValue());\n}, { value: 'z\\ny\\nc1\\nb2\\na3'});\ntestVim('ex_sort_pattern_alpha_reverse', function(cm, vim, helpers) {\n  helpers.doEx('sort! /[a-z]/');\n  eq('z\\ny\\nc1\\nb2\\na3', cm.getValue());\n}, { value: 'z\\ny\\nc1\\nb2\\na3'});\ntestVim('ex_sort_pattern_alpha_ignoreCase', function(cm, vim, helpers) {\n  helpers.doEx('sort i/[a-z]/');\n  eq('a3\\nb2\\nC1\\nY\\nz', cm.getValue());\n}, { value: 'z\\nY\\nC1\\nb2\\na3'});\ntestVim('ex_sort_pattern_alpha_longer', function(cm, vim, helpers) {\n  helpers.doEx('sort /[a-z]+/');\n  eq('a\\naa\\nab\\nade\\nadele\\nadelle\\nadriana\\nalex\\nalexandra\\nb\\nc\\ny\\nz', cm.getValue());\n}, { value: 'z\\nab\\naa\\nade\\nadelle\\nalexandra\\nalex\\nadriana\\nadele\\ny\\nc\\nb\\na'});\ntestVim('ex_sort_pattern_alpha_only', function(cm, vim, helpers) {\n  helpers.doEx('sort /^[a-z]$/');\n  eq('z1\\ny2\\na3\\nb\\nc', cm.getValue());\n}, { value: 'z1\\ny2\\na3\\nc\\nb'});\ntestVim('ex_sort_pattern_alpha_only_reverse', function(cm, vim, helpers) {\n  helpers.doEx('sort! /^[a-z]$/');\n  eq('c\\nb\\nz1\\ny2\\na3', cm.getValue());\n}, { value: 'z1\\ny2\\na3\\nc\\nb'});\ntestVim('ex_sort_pattern_alpha_num', function(cm, vim, helpers) {\n  helpers.doEx('sort /[a-z][0-9]/');\n  eq('c\\nb\\na3\\ny2\\nz1', cm.getValue());\n}, { value: 'z1\\ny2\\na3\\nc\\nb'});\n// test for :global command\ntestVim('ex_global', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('g/one/s//two');\n  eq('two one\\n two one\\n two one', cm.getValue());\n  helpers.doEx('1,2g/two/s//one');\n  eq('one one\\n one one\\n two one', cm.getValue());\n  helpers.doEx('g/^ /');\n  eq(' one one\\n two one', helpers.getNotificationText());\n}, {value: 'one one\\n one one\\n one one'});\ntestVim('ex_normal', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('g/one/normal    cw 1<lt>Esc><Esc>$i$');\n  helpers.doKeys(\"rt\");\n  eq(' 1<Esc> on$e\\nxx\\n 1<Esc> on$e\\n 1<Esc> on$t', cm.getValue());\n  helpers.doKeys('/', '<', '\\n');\n  helpers.doKeys('x', 'x', 'p');\n  eq(' 1sEc> on$e\\nxx\\n 1<Esc> on$e\\n 1<Esc> on$t', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doEx('map k j');\n  helpers.doEx('normal kkk');\n  helpers.assertCursorAt(3, 0);\n  helpers.doEx('normal! kkk');\n  helpers.assertCursorAt(0, 0);\n}, {value: 'one one\\nxx\\none one\\none one'});\ntestVim('ex_global_substitute_join', function(cm, vim, helpers) {\n  helpers.doEx('g/o/s/\\\\n/;');\n  eq('one;two\\nthree\\nfour;five\\n', cm.getValue());\n}, {value: 'one\\ntwo\\nthree\\nfour\\nfive\\n'});\ntestVim('ex_global_substitute_split', function(cm, vim, helpers) {\n  helpers.doEx('g/e/s/[or]/\\\\n');\n  eq('\\nne\\ntwo\\nth\\nee\\nfour\\nfive\\n', cm.getValue());\n}, {value: 'one\\ntwo\\nthree\\nfour\\nfive\\n'});\ntestVim('ex_global_delete', function(cm, vim, helpers) {\n  helpers.doEx('g/e/d\\\\n');\n  eq('two\\nfour\\nsix\\n---', cm.getValue());\n  helpers.doKeys('u');\n  helpers.doEx('g/e/g/v/d\\\\n');\n  eq('one\\ntwo\\nthree\\nfour\\nsix\\nnine\\n---', cm.getValue());\n}, {value: 'one\\ntwo\\nthree\\nfour\\nfive\\nsix\\nseven\\nnine\\n---'});\ntestVim('ex_global_confirm', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('g/one/s//two/gc');\n  helpers.doKeys('n');\n  helpers.doKeys('y');\n  helpers.doKeys('a');\n  helpers.doKeys('q');\n  helpers.doKeys('y');\n  eq('one two\\n two two\\n one one\\n two one\\n one one', cm.getValue());\n}, {value: 'one one\\n one one\\n one one\\n one one\\n one one'});\n// test for :vglobal command\ntestVim('ex_vglobal', function(cm, vim, helpers) {\n  helpers.doEx('v/e/s/o/e');\n  eq('one\\n twe\\n three\\n feur\\n five\\n', cm.getValue());\n  helpers.doEx('v/[vw]');\n  eq('one\\n three\\n feur\\n', helpers.getNotificationText());\n}, {value: 'one\\n two\\n three\\n four\\n five\\n'});\n// Basic substitute tests.\ntestVim('ex_substitute_same_line', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('s/one/two/g');\n  eq('one one\\n two two', cm.getValue());\n}, { value: 'one one\\n one one'});\ntestVim('ex_substitute_alternate_separator', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('s#o/e#two#g');\n  eq('o/e o/e\\n two two', cm.getValue());\n}, { value: 'o/e o/e\\n o/e o/e'});\n// ace_patch{\ntestVim('ex_substitute_with_newline (\\\\n)', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('s/\\\\.\\\\s/.\\\\n/');\n  eq('a. b. c.\\n1.\\n2. 3.', cm.getValue());\n}, { value: 'a. b. c.\\n1. 2. 3.'});\ntestVim('ex_substitute_all_in_range_with_newline (\\\\n)', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('1,2s/\\\\.\\\\s/.\\\\n/g');\n  eq('a.\\nb.\\nc.\\n1.\\n2.\\n3.', cm.getValue());\n}, { value: 'a. b. c.\\n1. 2. 3.'});\ntestVim('ex_substitute_all_in_range_with_newline (\\\\r)', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('1,2s/\\\\.\\\\s/.\\\\r/g');\n  eq('a.\\rb.\\rc.\\r1.\\r2.\\r3.', cm.getValue());\n}, { value: 'a. b. c.\\r1. 2. 3.'});\ntestVim('ex_substitute_all_in_range_with_multiple newlines (\\\\r)', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('1,2s/\\\\.\\\\s/.\\\\r\\\\r/g');\n  eq('a.\\r\\rb.\\r\\rc.\\r1.\\r\\r2.\\r\\r3.', cm.getValue());\n}, { value: 'a. b. c.\\r1. 2. 3.'});\n// ace_patch}\ntestVim('ex_substitute_full_file', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('%s/one/two/g');\n  eq('two two\\n two two', cm.getValue());\n}, { value: 'one one\\n one one'});\ntestVim('ex_substitute_input_range', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('1,3s/\\\\d/0/g');\n  eq('0\\n0\\n0\\n4', cm.getValue());\n}, { value: '1\\n2\\n3\\n4' });\ntestVim('ex_substitute_range_current_to_input', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  helpers.doEx('.,3s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n4', cm.getValue());\n}, { value: '1\\n2\\n3\\n4' });\ntestVim('ex_substitute_range_input_to_current', function(cm, vim, helpers) {\n  cm.setCursor(3, 0);\n  helpers.doEx('2,.s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n0\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_range_offset', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doEx('-1,+1s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n0\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_range_implicit_offset', function(cm, vim, helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('.1,.3s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n0\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_to_eof', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doEx('.,$s/\\\\d/0/g');\n  eq('1\\n2\\n0\\n0\\n0', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_to_relative_eof', function(cm, vim, helpers) {\n  cm.setCursor(4, 0);\n  helpers.doEx('2,$-2s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n4\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_range_mark', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('ma');\n  cm.setCursor(0, 0);\n  helpers.doEx('.,\\'as/\\\\d/0/g');\n  eq('0\\n0\\n0\\n4\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_range_mark_offset', function(cm, vim, helpers) {\n  cm.setCursor(2, 0);\n  helpers.doKeys('ma');\n  cm.setCursor(0, 0);\n  helpers.doEx('\\'a-1,\\'a+1s/\\\\d/0/g');\n  eq('1\\n0\\n0\\n0\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_visual_range', function(cm, vim, helpers) {\n  cm.setCursor(1, 0);\n  // Set last visual mode selection marks '< and '> at lines 2 and 4\n  helpers.doKeys('V', '2', 'j', 'v');\n  helpers.doKeys(':');\n  eq(document.activeElement.value, \"'<,'>\");\n  helpers.doKeys('s/\\\\d/0/g', '\\n');\n  eq('1\\n0\\n0\\n0\\n5', cm.getValue());\n}, { value: '1\\n2\\n3\\n4\\n5' });\ntestVim('ex_substitute_empty_query', function(cm, vim, helpers) {\n  // If the query is empty, use last query.\n  cm.setCursor(1, 0);\n  helpers.doKeys('/', '1\\n');\n  helpers.doEx('s//b/g');\n  eq('abb ab2 ab3', cm.getValue());\n}, { value: 'a11 a12 a13' });\ntestVim('ex_substitute_javascript', function(cm, vim, helpers) {\n  CodeMirror.Vim.setOption('pcre', false);\n  cm.setCursor(1, 0);\n  // Throw all the things that javascript likes to treat as special values\n  // into the replace part. All should be literal (this is VIM).\n  helpers.doEx('s/\\\\(\\\\d+\\\\)/$$ $\\' $` $& \\\\1/g')\n  eq('a $$ $\\' $` $& 0 b', cm.getValue());\n}, { value: 'a 0 b' });\ntestVim('ex_substitute_empty_arguments', function(cm,vim,helpers) {\n  cm.setCursor(0, 0);\n  helpers.doEx('s/a/b/g');\n  cm.setCursor(1, 0);\n  helpers.doEx('s');\n  eq('b b\\nb a', cm.getValue());\n}, {value: 'a a\\na a'});\n\n// More complex substitute tests that test both pcre and nopcre options.\nfunction testSubstitute(name, options) {\n  testVim(name + '_pcre', function(cm, vim, helpers) {\n    cm.setCursor(1, 0);\n    CodeMirror.Vim.setOption('pcre', true);\n    helpers.doEx(options.expr);\n    eq(options.expectedValue, cm.getValue());\n  }, options);\n  // If no noPcreExpr is defined, assume that it's the same as the expr.\n  var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr;\n  testVim(name + '_nopcre', function(cm, vim, helpers) {\n    cm.setCursor(1, 0);\n    CodeMirror.Vim.setOption('pcre', false);\n    helpers.doEx(noPcreExpr);\n    eq(options.expectedValue, cm.getValue());\n  }, options);\n}\ntestSubstitute('ex_substitute_capture', {\n  value: 'a11 a12 a13',\n  expectedValue: 'a1111 a1212 a1313',\n  // $n is a backreference\n  expr: 's/(\\\\d+)/$1$1/g',\n  // \\n is a backreference.\n  noPcreExpr: 's/\\\\(\\\\d+\\\\)/\\\\1\\\\1/g'});\ntestSubstitute('ex_substitute_capture2', {\n  value: 'a 0 b',\n  expectedValue: 'a $00 b',\n  expr: 's/(\\\\d+)/$$$1$1/g',\n  noPcreExpr: 's/\\\\(\\\\d+\\\\)/$\\\\1\\\\1/g'});\ntestSubstitute('ex_substitute_nocapture', {\n  value: 'a11 a12 a13',\n  expectedValue: 'a$1$1 a$1$1 a$1$1',\n  expr: 's/(\\\\d+)/$$1$$1/g',\n  noPcreExpr: 's/\\\\(\\\\d+\\\\)/$1$1/g'});\ntestSubstitute('ex_substitute_nocapture2', {\n  value: 'a 0 b',\n  expectedValue: 'a $10 b',\n  expr: 's/(\\\\d+)/$$1$1/g',\n  noPcreExpr: 's/\\\\(\\\\d+\\\\)/\\\\$1\\\\1/g'});\ntestSubstitute('ex_substitute_nocapture', {\n  value: 'a b c',\n  expectedValue: 'a $ c',\n  expr: 's/b/$$/',\n  noPcreExpr: 's/b/$/'});\ntestSubstitute('ex_substitute_slash_regex', {\n  value: 'one/two \\n three/four',\n  expectedValue: 'one|two \\n three|four',\n  expr: '%s/\\\\//|'});\ntestSubstitute('ex_substitute_pipe_regex', {\n  value: 'one|two \\n three|four',\n  expectedValue: 'one,two \\n three,four',\n  expr: '%s/\\\\|/,/',\n  noPcreExpr: '%s/|/,/'});\ntestSubstitute('ex_substitute_or_regex', {\n  value: 'one|two \\n three|four',\n  expectedValue: 'ana|twa \\n thraa|faar',\n  expr: '%s/o|e|u/a/g',\n  noPcreExpr: '%s/o\\\\|e\\\\|u/a/g'});\ntestSubstitute('ex_substitute_or_word_regex', {\n  value: 'one|two \\n three|four',\n  expectedValue: 'five|five \\n three|four',\n  expr: '%s/(one|two)/five/g',\n  noPcreExpr: '%s/\\\\(one\\\\|two\\\\)/five/g'});\ntestSubstitute('ex_substitute_forward_slash_regex', {\n    value: 'forward slash \\/ was here',\n  expectedValue: 'forward slash  was here',\n  expr: '%s#\\\\/##g',\n  noPcreExpr: '%s#/##g'});\ntestVim(\"ex_substitute_ampersand_pcre\", function(cm, vim, helpers) {\n    cm.setCursor(0, 0);\n    CodeMirror.Vim.setOption('pcre', true);\n    helpers.doEx('%s/foo/namespace.&/');\n    eq(\"namespace.foo\", cm.getValue());\n  }, { value: 'foo' });\ntestVim(\"ex_substitute_ampersand_multiple_pcre\", function(cm, vim, helpers) {\n    cm.setCursor(0, 0);\n    CodeMirror.Vim.setOption('pcre', true);\n    helpers.doEx('%s/f.o/namespace.&/');\n    eq(\"namespace.foo\\nnamespace.fzo\", cm.getValue());\n  }, { value: 'foo\\nfzo' });\ntestVim(\"ex_escaped_ampersand_should_not_substitute_pcre\", function(cm, vim, helpers) {\n    cm.setCursor(0, 0);\n    CodeMirror.Vim.setOption('pcre', true);\n    helpers.doEx('%s/foo/namespace.\\\\&/');\n    eq(\"namespace.&\", cm.getValue());\n  }, { value: 'foo' });\ntestSubstitute('ex_substitute_backslashslash_regex', {\n  value: 'one\\\\two \\n three\\\\four',\n  expectedValue: 'one,two \\n three,four',\n  expr: '%s/\\\\\\\\/,'});\ntestSubstitute('ex_substitute_slash_replacement', {\n  value: 'one,two \\n three,four',\n  expectedValue: 'one/two \\n three/four',\n  expr: '%s/,/\\\\/'});\ntestSubstitute('ex_substitute_backslash_replacement', {\n  value: 'one,two \\n three,four',\n  expectedValue: 'one\\\\two \\n three\\\\four',\n  expr: '%s/,/\\\\\\\\/g'});\ntestSubstitute('ex_substitute_multibackslash_replacement', {\n  value: 'one,two \\n three,four',\n  expectedValue: 'one\\\\\\\\\\\\\\\\two \\n three\\\\\\\\\\\\\\\\four', // 2*8 backslashes.\n  expr: '%s/,/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.\ntestSubstitute('ex_substitute_dollar_assertion', {\n  value: 'one,two \\n three,four',\n  expectedValue: 'one,two ,\\n three,four,',\n  expr: '%s/$/,/g'});\ntestSubstitute('ex_substitute_dollar_assertion_empty_lines', {\n  value: '\\n\\n\\n\\n\\n\\n',\n  expectedValue: ';\\n;\\n;\\n;\\n;\\n;\\n;',\n  expr: '%s/$/;/g'});\ntestSubstitute('ex_substitute_dollar_literal', {\n  value: 'one$two\\n$three\\nfour$\\n$',\n  expectedValue: 'one,two\\n,three\\nfour,\\n,',\n  expr: '%s/\\\\$/,/g'});\ntestSubstitute('ex_substitute_newline_match', {\n  value: 'one,two \\n three,four',\n  expectedValue: 'one,two , three,four',\n  expr: '%s/\\\\n/,/g'});\ntestSubstitute('ex_substitute_newline_join_global', {\n  value: 'one,two \\n three,four \\n five \\n six',\n  expectedValue: 'one,two \\n three,four , five \\n six',\n  expr: '2s/\\\\n/,/g'});\ntestSubstitute('ex_substitute_newline_join_noglobal', {\n  value: 'one,two \\n three,four \\n five \\n six\\n',\n  expectedValue: 'one,two \\n three,four , five , six\\n',\n  expr: '2,3s/\\\\n/,/'});\ntestSubstitute('ex_substitute_newline_replacement', {\n  value: 'one,two, \\n three,four,',\n  expectedValue: 'one\\ntwo\\n \\n three\\nfour\\n',\n  expr: '%s/,/\\\\n/g'});\ntestSubstitute('ex_substitute_newline_multiple_splits', {\n  value: 'one,two, \\n three,four,five,six, \\n seven,',\n  expectedValue: 'one,two, \\n three\\nfour\\nfive\\nsix\\n \\n seven,',\n  expr: '2s/,/\\\\n/g'});\ntestSubstitute('ex_substitute_newline_first_occurrences', {\n  value: 'one,two, \\n three,four,five,six, \\n seven,',\n  expectedValue: 'one\\ntwo, \\n three\\nfour,five,six, \\n seven\\n',\n  expr: '%s/,/\\\\n/'});\ntestSubstitute('ex_substitute_braces_word', {\n  value: 'ababab abb ab{2}',\n  expectedValue: 'ab abb ab{2}',\n  expr: '%s/(ab){2}//g',\n  noPcreExpr: '%s/\\\\(ab\\\\)\\\\{2\\\\}//g'});\ntestSubstitute('ex_substitute_braces_range', {\n  value: 'a aa aaa aaaa',\n  expectedValue: 'a   a',\n  expr: '%s/a{2,3}//g',\n  noPcreExpr: '%s/a\\\\{2,3\\\\}//g'});\ntestSubstitute('ex_substitute_braces_literal', {\n  value: 'ababab abb ab{2}',\n  expectedValue: 'ababab abb ',\n  expr: '%s/ab\\\\{2\\\\}//g',\n  noPcreExpr: '%s/ab{2}//g'});\ntestSubstitute('ex_substitute_braces_char', {\n  value: 'ababab abb ab{2}',\n  expectedValue: 'ababab  ab{2}',\n  expr: '%s/ab{2}//g',\n  noPcreExpr: '%s/ab\\\\{2\\\\}//g'});\ntestSubstitute('ex_substitute_braces_no_escape', {\n  value: 'ababab abb ab{2}',\n  expectedValue: 'ababab  ab{2}',\n  expr: '%s/ab{2}//g',\n  noPcreExpr: '%s/ab\\\\{2}//g'});\ntestSubstitute('ex_substitute_count', {\n  value: '1\\n2\\n3\\n4',\n  expectedValue: '1\\n0\\n0\\n4',\n  expr: 's/\\\\d/0/i 2'});\ntestSubstitute('ex_substitute_count_with_range', {\n  value: '1\\n2\\n3\\n4',\n  expectedValue: '1\\n2\\n0\\n0',\n  expr: '1,3s/\\\\d/0/ 3'});\ntestSubstitute('ex_substitute_not_global', {\n  value: 'aaa\\nbaa\\ncaa',\n  expectedValue: 'xaa\\nbxa\\ncxa',\n  expr: '%s/a/x/'});\ntestSubstitute('ex_substitute_optional', {\n  value: 'aaa  aa\\n aa',\n  expectedValue: '<aaa> <> <aa>\\n<> <aa>',\n  expr: '%s/(a*)/<$1>/g',\n  noPcreExpr: '%s/\\\\(a*\\\\)/<\\\\1>/g'});\ntestSubstitute('ex_substitute_empty_match', {\n  value: 'aaa  aa\\n aa\\nbb\\n',\n  expectedValue: '<aaa>  <aa>\\n <aa>\\nbb<>\\n<>',\n  expr: '%s/(a+|$)/<$1>/g',\n  noPcreExpr: '%s/\\\\(a+\\\\|$\\\\)/<\\\\1>/g'});\ntestSubstitute('ex_substitute_empty_or_match', {\n  value: '1234\\n567\\n89\\n0\\n',\n  expectedValue: '<12><34>\\n<56>7<>\\n<89>\\n0<>\\n<>',\n  expr: '%s/(..|$)/<$1>/g',\n  noPcreExpr: '%s/\\\\(..\\\\|$\\\\)/<\\\\1>/g'});\nfunction testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {\n  testVim(name, function(cm, vim, helpers) {\n    helpers.doEx(command);\n    for (var i = 0; i < keys.length; i++) {\n      helpers.doKeys(keys.charAt(i))\n    }\n    eq(expectedValue, cm.getValue());\n    helpers.assertCursorAt(finalPos);\n  }, { value: initialValue });\n}\ntestSubstituteConfirm('ex_substitute_confirm_emptydoc',\n    '%s/x/b/c', '', '', '', makeCursor(0, 0));\ntestSubstituteConfirm('ex_substitute_confirm_nomatch',\n    '%s/x/b/c', 'ba a\\nbab', 'ba a\\nbab', '', makeCursor(0, 0));\ntestSubstituteConfirm('ex_substitute_confirm_accept',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb b\\nbbb', 'yyy', makeCursor(1, 1));\ntestSubstituteConfirm('ex_substitute_confirm_random_keys',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb b\\nbbb', 'ysdkywerty', makeCursor(1, 1));\ntestSubstituteConfirm('ex_substitute_confirm_some',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb a\\nbbb', 'yny', makeCursor(1, 1));\ntestSubstituteConfirm('ex_substitute_confirm_all',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb b\\nbbb', 'a', makeCursor(1, 1));\ntestSubstituteConfirm('ex_substitute_confirm_accept_then_all',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb b\\nbbb', 'ya', makeCursor(1, 1));\ntestSubstituteConfirm('ex_substitute_confirm_quit',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb a\\nbab', 'yq', makeCursor(0, 3));\ntestSubstituteConfirm('ex_substitute_confirm_last',\n    '%s/a/b/cg', 'ba a\\nbab', 'bb b\\nbab', 'yl', makeCursor(0, 3));\ntestSubstituteConfirm('ex_substitute_confirm_oneline',\n    '1s/a/b/cg', 'ba a\\nbab', 'bb b\\nbab', 'yl', makeCursor(0, 3));\ntestSubstituteConfirm('ex_substitute_confirm_range_accept',\n    '1,2s/a/b/cg', 'aa\\na \\na\\na', 'bb\\nb \\na\\na', 'yyy', makeCursor(1, 0));\ntestSubstituteConfirm('ex_substitute_confirm_range_some',\n    '1,3s/a/b/cg', 'aa\\na \\na\\na', 'ba\\nb \\nb\\na', 'ynyy', makeCursor(2, 0));\ntestSubstituteConfirm('ex_substitute_confirm_range_all',\n    '1,3s/a/b/cg', 'aa\\na \\na\\na', 'bb\\nb \\nb\\na', 'a', makeCursor(2, 0));\ntestSubstituteConfirm('ex_substitute_confirm_range_last',\n    '1,3s/a/b/cg', 'aa\\na \\na\\na', 'bb\\nb \\na\\na', 'yyl', makeCursor(1, 0));\n//:noh should clear highlighting of search-results but allow to resume search through n\ntestVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {\n  helpers.doKeys('?', 'match', '\\n');\n  helpers.doEx('noh');\n  eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\\'t cleared');\n  helpers.doKeys('n');\n  helpers.assertCursorAt(0, 11,'can\\'t resume search after clearing highlighting');\n}, { value: 'match nope match \\n nope Match' });\ntestVim('ex_yank', function (cm, vim, helpers) {\n  var curStart = makeCursor(3, 0);\n  cm.setCursor(curStart);\n  helpers.doEx('y');\n  var register = helpers.getRegisterController().getRegister();\n  var line = cm.getLine(3);\n  eq(line + '\\n', register.toString());\n});\ntestVim('set_boolean', function(cm, vim, helpers) {\n  CodeMirror.Vim.defineOption('testoption', true, 'boolean');\n  // Test default value is set.\n  is(CodeMirror.Vim.getOption('testoption'));\n  // Test fail to set to non-boolean\n  var result = CodeMirror.Vim.setOption('testoption', '5');\n  is(result instanceof Error);\n  // Test setOption\n  CodeMirror.Vim.setOption('testoption', false);\n  is(!CodeMirror.Vim.getOption('testoption'));\n});\ntestVim('ex_set_boolean', function(cm, vim, helpers) {\n  CodeMirror.Vim.defineOption('testoption', true, 'boolean');\n  // Test default value is set.\n  is(CodeMirror.Vim.getOption('testoption'));\n  is(!cm.state.currentNotificationClose);\n  // Test fail to set to non-boolean\n  helpers.doEx('set testoption=22');\n  is(cm.state.currentNotificationClose);\n  // Test setOption\n  helpers.doEx('set notestoption');\n  is(!CodeMirror.Vim.getOption('testoption'));\n  // Test toggle with !\n  helpers.doEx('set notestoption!');\n  is(CodeMirror.Vim.getOption('testoption'));\n  helpers.doEx('set notestoption!');\n  is(!CodeMirror.Vim.getOption('testoption'));\n  helpers.doEx('set testoption!');\n  is(CodeMirror.Vim.getOption('testoption'));\n  helpers.doEx('set testoption!');\n  is(!CodeMirror.Vim.getOption('testoption'));\n});\ntestVim('set_string', function(cm, vim, helpers) {\n  CodeMirror.Vim.defineOption('testoption', 'a', 'string');\n  // Test default value is set.\n  eq('a', CodeMirror.Vim.getOption('testoption'));\n  // Test no fail to set non-string.\n  var result = CodeMirror.Vim.setOption('testoption', true);\n  is(!result);\n  // Test fail to set 'notestoption'\n  result = CodeMirror.Vim.setOption('notestoption', 'b');\n  is(result instanceof Error);\n  // Test setOption\n  CodeMirror.Vim.setOption('testoption', 'c');\n  eq('c', CodeMirror.Vim.getOption('testoption'));\n});\ntestVim('ex_set_string', function(cm, vim, helpers) {\n  CodeMirror.Vim.defineOption('testopt', 'a', 'string');\n  // Test default value is set.\n  eq('a', CodeMirror.Vim.getOption('testopt'));\n  // Test fail to set 'notestopt'\n  is(!cm.state.currentNotificationClose);\n  helpers.doEx('set notestopt=b');\n  is(cm.state.currentNotificationClose);\n  // Test setOption\n  helpers.doEx('set testopt=c')\n  eq('c', CodeMirror.Vim.getOption('testopt'));\n  helpers.doEx('set testopt=c')\n  eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global\n  eq('c', CodeMirror.Vim.getOption('testopt')); // global\n  // Test setOption global\n  helpers.doEx('setg testopt=d')\n  eq('c', CodeMirror.Vim.getOption('testopt', cm));\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));\n  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));\n  eq('d', CodeMirror.Vim.getOption('testopt'));\n  // Test setOption local\n  helpers.doEx('setl testopt=e')\n  eq('e', CodeMirror.Vim.getOption('testopt', cm));\n  eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));\n  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));\n  eq('d', CodeMirror.Vim.getOption('testopt'));\n});\ntestVim('ex_set_callback', function(cm, vim, helpers) {\n  var global;\n\n  function cb(val, cm, cfg) {\n    if (val === undefined) {\n      // Getter\n      if (cm) {\n        return cm._local;\n      } else {\n        return global;\n      }\n    } else {\n      // Setter\n      if (cm) {\n        cm._local = val;\n      } else {\n        global = val;\n      }\n    }\n  }\n\n  CodeMirror.Vim.defineOption('testopt', 'a', 'string', cb);\n  // Test default value is set.\n  eq('a', CodeMirror.Vim.getOption('testopt'));\n  // Test fail to set 'notestopt'\n  is(!cm.state.currentNotificationClose);\n  helpers.doEx('set notestopt=b');\n  is(cm.state.currentNotificationClose);\n  // Test setOption (Identical to the string tests, but via callback instead)\n  helpers.doEx('set testopt=c')\n  eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global\n  eq('c', CodeMirror.Vim.getOption('testopt')); // global\n  // Test setOption global\n  helpers.doEx('setg testopt=d')\n  eq('c', CodeMirror.Vim.getOption('testopt', cm));\n  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));\n  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));\n  eq('d', CodeMirror.Vim.getOption('testopt'));\n  // Test setOption local\n  helpers.doEx('setl testopt=e')\n  eq('e', CodeMirror.Vim.getOption('testopt', cm));\n  eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));\n  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));\n  eq('d', CodeMirror.Vim.getOption('testopt'));\n})\ntestVim('ex_set_filetype', function(cm, vim, helpers) {\n  CodeMirror.defineMode('test_mode', function() {\n    return {token: function(stream) {\n      stream.match(/^\\s+|^\\S+/);\n    }};\n  });\n  CodeMirror.defineMode('test_mode_2', function() {\n    return {token: function(stream) {\n      stream.match(/^\\s+|^\\S+/);\n    }};\n  });\n  // Test mode is set.\n  helpers.doEx('set filetype=test_mode');\n  eq('test_mode', cm.getMode().name);\n  // Test 'ft' alias also sets mode.\n  helpers.doEx('set ft=test_mode_2');\n  eq('test_mode_2', cm.getMode().name);\n});\ntestVim('ex_set_filetype_null', function(cm, vim, helpers) {\n  CodeMirror.defineMode('test_mode', function() {\n    return {token: function(stream) {\n      stream.match(/^\\s+|^\\S+/);\n    }};\n  });\n  cm.setOption('mode', 'test_mode');\n  // Test mode is set to null.\n  helpers.doEx('set filetype=');\n  eq('null', cm.getMode().name);\n});\n\ntestVim('map_prompt', function(cm, vim, helpers) {\n  function highlighted() {\n    return vim.searchState_ && (vim.searchState_.getOverlay() || vim.searchState_.highlightTimeout);\n  }\n  is(!highlighted());\n\n  helpers.doKeys('/a\\n');\n  helpers.doKeys('i');\n  is(highlighted());\n  helpers.doKeys('<Esc>');\n  helpers.doEx('nohl');\n  is(!highlighted());\n  helpers.assertCursorAt(1, 2);\n\n  helpers.doEx('nnoremap i :nohl<CR>i<space>xx<lt>');\n  helpers.doEx('map :sayhi ihi<Esc>');\n  helpers.doEx('map j :sayhi<CR>/<up><up>b');\n\n  helpers.doKeys('/1\\n');\n  helpers.assertCursorAt(1, 1);\n\n  helpers.doKeys('j');\n  eq(cm.getWrapperElement().querySelector(\"input\").value, \"ab\");\n  helpers.doKeys('<CR>');\n  is(highlighted());\n  helpers.doKeys('i');\n  is(!highlighted());\n\n  eq(cm.getValue(), ' 0 xyz\\n hi1  xx<abc \\n 2 abc');\n\n  helpers.doKeys('mapclear');\n}, { value: ' 0 xyz\\n 1 abc \\n 2 abc' });\ntestVim('mapclear', function(cm, vim, helpers) {\n  CodeMirror.Vim.map('w', 'l');\n  cm.setCursor(0, 0);\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('w');\n  helpers.assertCursorAt(0, 1);\n  CodeMirror.Vim.mapclear('visual');\n  helpers.doKeys('v', 'w', 'v');\n  helpers.assertCursorAt(0, 4);\n  helpers.doKeys('w');\n  helpers.assertCursorAt(0, 5);\n}, { value: 'abc abc' });\ntestVim('mapclear_context', function(cm, vim, helpers) {\n  CodeMirror.Vim.map('w', 'l', 'normal');\n  cm.setCursor(0, 0);\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('w');\n  helpers.assertCursorAt(0, 1);\n  CodeMirror.Vim.mapclear('normal');\n  helpers.doKeys('w');\n  helpers.assertCursorAt(0, 4);\n}, { value: 'abc abc' });\n\ntestVim('ex_map_key2key', function(cm, vim, helpers) {\n  helpers.doEx('map a x');\n  helpers.doKeys('a');\n  helpers.assertCursorAt(0, 0);\n  eq('bc', cm.getValue());\n}, { value: 'abc' });\ntestVim('ex_unmap_key2key', function(cm, vim, helpers) {\n  helpers.doEx('map a x');\n  helpers.doEx('unmap a');\n  helpers.doKeys('a');\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'abc' });\ntestVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) {\n  helpers.doEx('unmap a');\n  is(/No such mapping: unmap a/.test(helpers.getNotificationText()));\n  helpers.doKeys('a');\n  eq('vim-insert', cm.getOption('keyMap'));\n}, { value: 'abc' });\ntestVim('ex_map_key2key_to_colon', function(cm, vim, helpers) {\n  helpers.doEx('map ; :');\n  var dialogOpened = false;\n  cm.openDialog = function() {\n    dialogOpened = true;\n  }\n  helpers.doKeys(';');\n  eq(dialogOpened, true);\n});\ntestVim('ex_map_ex2key:', function(cm, vim, helpers) {\n  helpers.doEx('map :del x');\n  helpers.doEx('del');\n  helpers.assertCursorAt(0, 0);\n  eq('bc', cm.getValue());\n}, { value: 'abc' });\ntestVim('ex_map_ex2ex', function(cm, vim, helpers) {\n  helpers.doEx('map :del :w');\n  var tmp = CodeMirror.commands.save;\n  var written = false;\n  var actualCm;\n  CodeMirror.commands.save = function(cm) {\n    written = true;\n    actualCm = cm;\n  };\n  helpers.doEx('del');\n  CodeMirror.commands.save = tmp;\n  eq(written, true);\n  eq(actualCm, cm);\n});\ntestVim('ex_map_key2ex', function(cm, vim, helpers) {\n  helpers.doEx('map a :w<CR>');\n  var tmp = CodeMirror.commands.save;\n  var written = false;\n  var actualCm;\n  CodeMirror.commands.save = function(cm) {\n    written = true;\n    actualCm = cm;\n  };\n  helpers.doKeys('a');\n  CodeMirror.commands.save = tmp;\n  eq(written, true);\n  eq(actualCm, cm);\n});\ntestVim('ex_map_key2key_visual_api', function(cm, vim, helpers) {\n  CodeMirror.Vim.map('b', ':w<CR>', 'visual');\n  var tmp = CodeMirror.commands.save;\n  var written = false;\n  var actualCm;\n  CodeMirror.commands.save = function(cm) {\n    written = true;\n    actualCm = cm;\n  };\n  // Mapping should not work in normal mode.\n  helpers.doKeys('b');\n  eq(written, false);\n  // Mapping should work in visual mode.\n  helpers.doKeys('v', 'b');\n  eq(written, true);\n  eq(actualCm, cm);\n\n  CodeMirror.commands.save = tmp;\n});\ntestVim('ex_omap', function(cm, vim, helpers) {\n  helpers.doKeys('0', 'w', 'd', 'w');\n  eq(cm.getValue(), 'hello world');\n  helpers.doKeys('u');\n  helpers.doKeys(':', 'omap w $\\n');\n  helpers.doKeys( '0', 'w');\n  helpers.assertCursorAt(0, 6);\n  helpers.doKeys('d', 'w');\n  eq(cm.getValue(), 'hello ');\n}, {value: 'hello unfair world'});\ntestVim('ex_nmap', function(cm, vim, helpers) {\n  cm.setCursor(0, 3);\n  helpers.doEx('nmap k gj');\n  helpers.doKeys('k');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('d', 'k');\n  eq(cm.getValue(), 'world');\n  helpers.doKeys('u');\n  cm.setCursor(1, 3);\n  helpers.doEx('map k gj');\n  helpers.doKeys('d', 'k');\n  eq(cm.getValue(), 'hello\\nunfld');\n  helpers.assertCursorAt(1, 3);\n  helpers.doKeys('<Up>');\n  helpers.assertCursorAt(0, 3);\n}, {value: 'hello\\nunfair\\nworld'});\ntestVim('ex_imap', function(cm, vim, helpers) {\n  CodeMirror.Vim.map('jk', '<Esc>', 'insert');\n  helpers.doKeys('i');\n  is(vim.insertMode);\n  helpers.doKeys('j', 'k');\n  is(!vim.insertMode);\n  cm.setCursor(0, 1);\n  CodeMirror.Vim.map('jj', '<Esc>', 'insert');\n  helpers.doKeys('<C-v>', '2', 'j', 'l', 'c');\n  helpers.doKeys('f', 'o');\n  eq('1fo4\\n5fo8\\nafodefg', cm.getValue());\n  helpers.doKeys('j', 'j');\n  cm.setCursor(0, 0);\n  helpers.doKeys('.');\n  eq('foo4\\nfoo8\\nfoodefg', cm.getValue());\n  helpers.doKeys('R', 'x', 'j', 'j');\n  eq('xoo4\\nfoo8\\nfoodefg', cm.getValue());\n  helpers.doKeys('i');\n  cm.setSelections([\n    {head: makeCursor(0, 0), anchor: makeCursor(0, 1)},\n    {head: makeCursor(1, 0), anchor: makeCursor(1, 2)}\n  ]);\n  helpers.doKeys('j');\n  eq('joo4\\njo8\\nfoodefg', cm.getValue());\n  helpers.doKeys('j');\n  eq('xoo4\\nfoo8\\nfoodefg', cm.getValue());\n  \n  if (cm.forEachSelection) {\n    cm.setSelections([\n      {head: makeCursor(0, 2), anchor: makeCursor(0, 2)},\n      {head: makeCursor(1, 2), anchor: makeCursor(1, 2)},\n      {head: makeCursor(2, 4), anchor: makeCursor(2, 4)}\n    ]);\n    helpers.doKeys('R', 'x');\n    eq('xox4\\nfox8\\nfoodxfg', cm.getValue());\n    helpers.doKeys('j');\n    eq('xoxj\\nfoxj\\nfoodxjg', cm.getValue());\n    helpers.doKeys('k');\n    eq('xox4\\nfox8\\nfoodxfg', cm.getValue());\n    eq(3, cm.listSelections().length);\n  }\n}, { value: '1234\\n5678\\nabcdefg' });\ntestVim('ex_unmap_api', function(cm, vim, helpers) {\n  CodeMirror.Vim.map('<Alt-X>', 'gg', 'normal');\n  is(CodeMirror.Vim.handleKey(cm, \"<Alt-X>\", \"normal\"), \"Alt-X key is mapped\");\n  CodeMirror.Vim.unmap(\"<Alt-X>\", \"normal\");\n  is(!CodeMirror.Vim.handleKey(cm, \"<Alt-X>\", \"normal\"), \"Alt-X key is unmapped\");\n});\n// Testing registration of functions as ex-commands and mapping to <Key>-keys\ntestVim('ex_api_test', function(cm, vim, helpers) {\n  var res=false;\n  var val='from';\n  CodeMirror.Vim.defineEx('extest','ext',function(cm,params){\n    if(params.args)val=params.args[0];\n    else res=true;\n  });\n  helpers.doEx(':ext to');\n  eq(val,'to','Defining ex-command failed');\n  CodeMirror.Vim.map('<C-CR><Space>',':ext<CR>');\n  helpers.doKeys('<C-CR>','<Space>');\n  is(res,'Mapping to key failed');\n});\n// Testing ex-commands with non-alpha names.\ntestVim('ex_special_names', function(cm, vim, helpers) {\n  var ran,val;\n  var cmds = ['!','!!','#','&','*','<','=','>','@','@@','~','regtest1','RT2'];\n  cmds.forEach(function(name){\n    CodeMirror.Vim.defineEx(name,'',function(cm,params){\n      ran=params.commandName;\n      val=params.argString;\n    });\n    helpers.doEx(':'+name);\n    eq(ran,name,'Running ex-command failed');\n    helpers.doEx(':'+name+' x');\n    eq(val,' x','Running ex-command with param failed: '+name);\n    if(/^\\W+$/.test(name)){\n      helpers.doEx(':'+name+'y');\n      eq(val,'y','Running ex-command with param failed: '+name);\n    }\n    else{\n      helpers.doEx(':'+name+'-y');\n      eq(val,'-y','Running ex-command with param failed: '+name);\n    }\n    if(name!=='!'){\n      helpers.doEx(':'+name+'!');\n      eq(ran,name,'Running ex-command with bang failed');\n      eq(val,'!','Running ex-command with bang failed: '+name);\n      helpers.doEx(':'+name+'!z');\n      eq(ran,name,'Running ex-command with bang & param failed');\n      eq(val,'!z','Running ex-command with bang & param failed: '+name);\n    }\n  });\n});\n// For now, this test needs to be last because it messes up : for future tests.\ntestVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {\n  helpers.doEx('map : x');\n  helpers.doKeys(':');\n  helpers.assertCursorAt(0, 0);\n  eq('bc', cm.getValue());\n}, { value: 'abc' });\n\ntestVim('map <Esc> in normal mode', function(cm, vim, helpers) {\n  CodeMirror.Vim.noremap('<Esc>', 'i', 'normal');\n  helpers.doKeys('<Esc>');\n  is(vim.insertMode, \"Didn't switch to insert mode.\");\n  helpers.doKeys('<Esc>');\n  is(!vim.insertMode, \"Didn't switch to normal mode.\");\n});\n\ntestVim('noremap', function(cm, vim, helpers) {\n  helpers.doEx('noremap ; l');\n  helpers.doEx('map l $');\n  helpers.doEx('map q l');\n  helpers.doKeys('l');\n  helpers.assertCursorAt(0, 4);\n  cm.setCursor(0, 0);\n  helpers.doKeys('q');\n  helpers.assertCursorAt(0, 4);\n  cm.setCursor(0, 0);\n  eq('wOrd1', cm.getValue());\n  // Mapping should work in normal mode.\n  helpers.doKeys(';', 'r', '1');\n  eq('w1rd1', cm.getValue());\n  // Mapping will not work in insert mode because of no current fallback\n  // keyToKey mapping support.\n  helpers.doKeys('i', ';', '<Esc>');\n  eq('w;1rd1', cm.getValue());\n  // unmap all mappings\n  helpers.doEx('mapclear');\n  cm.setCursor(0, 0);\n  helpers.doKeys('l');\n  helpers.assertCursorAt(0, 1);\n  // map key to itself\n  helpers.doKeys('x', 'p', 'l');\n  eq('w1;rd1', cm.getValue());\n  helpers.doEx('noremap x \"_x');\n  helpers.doKeys('x', 'p');\n  eq('w1;d;1', cm.getValue());\n  helpers.doEx('mapclear');\n}, { value: 'wOrd1' });\n// noremap should capture all mappings of the rhs \ntestVim('noremap_all_mappings', function(cm, vim, helpers) {\n  // mapping to 'u' should undo in normal mode and lowercase in visual mode\n  CodeMirror.Vim.noremap('a', 'u');\n  helpers.doKeys('y', 'y', 'p');\n  eq('HeY\\nHeY', cm.getValue());\n  // undo\n  helpers.doKeys('a');\n  eq('HeY', cm.getValue());\n  // lowercase\n  helpers.doKeys('V', 'a');\n  eq('hey', cm.getValue());\n}, { value: 'HeY' });\ntestVim('noremap_swap', function(cm, vim, helpers) {\n  CodeMirror.Vim.noremap('i', 'a', 'normal');\n  CodeMirror.Vim.noremap('a', 'i', 'normal');\n  cm.setCursor(0, 0);\n  // 'a' should act like 'i'.\n  helpers.doKeys('a');\n  eqCursorPos(new Pos(0, 0), cm.getCursor());\n  // ...and 'i' should act like 'a'.\n  helpers.doKeys('<Esc>', 'i');\n  eqCursorPos(new Pos(0, 1), cm.getCursor());\n}, { value: 'foo' });\ntestVim('noremap_map_interaction', function(cm, vim, helpers) {\n  // noremap should clobber map\n  CodeMirror.Vim.map(';', 'l');\n  CodeMirror.Vim.noremap(';', 'l');\n  CodeMirror.Vim.map('l', 'j');\n  cm.setCursor(0, 0);\n  helpers.doKeys(';');\n  eqCursorPos(new Pos(0, 1), cm.getCursor());\n  helpers.doKeys('l');\n  eqCursorPos(new Pos(1, 1), cm.getCursor());\n  // map should be able to point to a noremap\n  CodeMirror.Vim.map('m', ';');\n  helpers.doKeys('m');\n  eqCursorPos(new Pos(1, 2), cm.getCursor());\n}, { value: 'wOrd1\\nwOrd2' });\ntestVim('noremap_map_interaction2', function(cm, vim, helpers) {\n  // map should point to the most recent noremap\n  CodeMirror.Vim.noremap(';', 'l');\n  CodeMirror.Vim.map('m', ';');\n  CodeMirror.Vim.noremap(';', 'h');\n  cm.setCursor(0, 0);\n  helpers.doKeys('l');\n  eqCursorPos(new Pos(0, 1), cm.getCursor());\n  helpers.doKeys('m');\n  eqCursorPos(new Pos(0, 0), cm.getCursor());\n}, { value: 'wOrd1\\nwOrd2' });\n\ntestVim('gq_and_gw', function(cm, vim, helpers) {\n  cm.setValue(\n    \"1\\n2\\nhello world\\n\"\n    + \"xxx \".repeat(20)\n    + \"\\nyyy\"\n    + \"\\n\\nnext\\nparagraph\"\n  );\n  cm.setCursor(2,5);\n  helpers.doKeys(\"gqgq\");\n  helpers.assertCursorAt(2, 0);\n  eq(cm.getLine(2), \"hello world\");\n\n  helpers.doKeys(\"gqj\");\n  helpers.assertCursorAt(3, 0);\n  eq(cm.getLine(3), \"xxx xxx xxx \")\n\n  helpers.doKeys(\"gq}\")\n  helpers.assertCursorAt(4, 0);\n  eq(cm.getLine(3), \"xxx xxx xxx yyy\")\n\n  helpers.doKeys(\"gqG\");\n  helpers.doKeys(\"gqgg\");\n  helpers.doKeys(\":set tw=15\\n\");\n\n  helpers.doKeys(\"gg\", \"V\", \"gq\");\n  eq(cm.getLine(0), \"1 2 hello world\");\n  eq(cm.getLine(5), \"xxx xxx xxx xxx yyy\");\n  helpers.doKeys(\":6\\n\");\n  helpers.doKeys(\"gqq\");\n\n  eq(cm.getLine(6), \"yyy\");\n}, { value: 'wOrd1\\nwOrd2' });\n\ntestVim('updateStatus', function(cm, vim, helpers) {\n  var keys = '';\n  CodeMirror.on(cm, 'vim-keypress', function(key) {\n    keys = keys + key;\n  });\n  CodeMirror.on(cm, 'vim-command-done', function(e) {\n    keys = '';\n  });\n  // ace_patch\n  helpers.doKeys('d');\n  eq(vim.status, 'd');\n  helpers.doKeys('/', 'match', '\\n');\n  eq(vim.status, null);\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('d');\n  eq(vim.status, 'd');\n  helpers.doKeys('/', '<Esc>');\n  eq(vim.status, null);\n  helpers.doKeys('d');\n  eq(vim.status, 'd');\n  helpers.doKeys(':');\n  eq(vim.status, 'd:');\n  helpers.doKeys('<Esc>');\n  eq(vim.status, null);\n}, { value: 'text match match \\n next' });\n\n// Test event handlers\ntestVim('beforeSelectionChange', function(cm, vim, helpers) {\n  cm.setCursor(0, 100);\n  eqCursorPos(cm.getCursor('head'), cm.getCursor('anchor'));\n}, { value: 'abc' });\n\ntestVim('increment_binary', function(cm, vim, helpers) {\n  cm.setCursor(0, 4);\n  helpers.doKeys('<C-a>');\n  eq('0b001', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0b010', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0b001', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0b000', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('0b001', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0b010', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0b001', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0b000', cm.getValue());\n}, { value: '0b000' });\n\ntestVim('increment_octal', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('<C-a>');\n  eq('001', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('002', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('003', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('004', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('005', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('006', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('007', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('010', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('007', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('006', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('005', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('004', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('003', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('002', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('001', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('000', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('001', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('002', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('001', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('000', cm.getValue());\n}, { value: '000' });\n\ntestVim('increment_decimal', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('<C-a>');\n  eq('101', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('102', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('103', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('104', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('105', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('106', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('107', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('108', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('109', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('110', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('109', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('108', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('107', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('106', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('105', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('104', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('103', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('102', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('101', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('100', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('101', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('102', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('101', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('100', cm.getValue());\n}, { value: '100' });\n\ntestVim('increment_decimal_single_zero', function(cm, vim, helpers) {\n  helpers.doKeys('<C-a>');\n  eq('1', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('2', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('3', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('4', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('5', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('6', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('7', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('8', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('9', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('10', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('9', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('8', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('7', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('6', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('5', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('4', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('3', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('2', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('1', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('1', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('2', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('1', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0', cm.getValue());\n}, { value: '0' });\n\ntestVim('increment_hexadecimal', function(cm, vim, helpers) {\n  cm.setCursor(0, 2);\n  helpers.doKeys('<C-a>');\n  eq('0x1', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x2', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x3', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x4', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x5', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x6', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x7', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x8', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x9', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xa', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xb', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xc', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xd', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xe', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0xf', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x10', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0f', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0e', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0d', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0c', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0b', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x0a', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x09', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x08', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x07', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x06', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x05', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x04', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x03', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x02', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x01', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x00', cm.getValue());\n  cm.setCursor(0, 0);\n  helpers.doKeys('<C-a>');\n  eq('0x01', cm.getValue());\n  helpers.doKeys('<C-a>');\n  eq('0x02', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x01', cm.getValue());\n  helpers.doKeys('<C-x>');\n  eq('0x00', cm.getValue());\n}, { value: '0x0' });\n\ntestVim('option_key_on_mac', function(cm, vim, helpers) {\n  CodeMirror.isMac = true;\n  helpers.assertCursorAt(0, 0);\n  typeKey.optionTextInput('9', '}');\n  helpers.assertCursorAt(3, 0);\n  typeKey.optionTextInput('8', '{');\n  helpers.assertCursorAt(0, 0);\n  CodeMirror.isMac = false;\n}, { value: '0\\n1\\n2\\n\\n\\n3\\n4\\n' });\n\n\n!isOldCodeMirror && testVim('<C-c>copy', async function(cm, vim, helpers) {\n  helpers.doKeys('v', 'e');\n  is(vim.visualMode);\n  typeKey.clipboard.$data = '';\n  helpers.doKeys('<C-c>');\n  eq(typeKey.clipboard.$data, 'hello');\n  await delay(0);\n  is(!vim.visualMode);\n  helpers.doKeys('w', 'i', '<S-C-Right>');\n  is(vim.insertMode);\n  helpers.doKeys('<C-c>');\n  is(vim.insertMode);\n  eq(typeKey.clipboard.$data, 'world');\n  helpers.doKeys('<C-c>'); // ace_patch\n  is(!vim.insertMode);\n}, { value: 'hello world' })\n\ntestVim('<C-r>_insert_mode', function(cm, vim, helpers) {\n  helpers.assertCursorAt(0, 0);\n  helpers.doKeys('d', 'w', 'A');\n  helpers.doKeys('<C-r>', '-');\n  eq('456 123 ', cm.getValue());\n}, { value: '123 456 ' });\n\n//\n//  test correct langmap function\n//\nconst dvorakLangmap = \"'q,\\\\,w,.e,pr,yt,fy,gu,ci,ro,lp,/[,=],aa,os,ed,uf,ig,dh,hj,tk,nl,s\\\\;,-',\\\\;z,qx,jc,kv,xb,bn,mm,w\\\\,,v.,z/,[-,]=,\\\"Q,<W,>E,PR,YT,FY,GU,CI,RO,LP,?{,+},AA,OS,ED,UF,IG,DH,HJ,TK,NL,S:,_\\\",:Z,QX,JC,KV,XB,BN,MM,W<,V>,Z?\";\n// this test makes sure that remapping works on an example binding\ntestVim('langmap_dd', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(0, 0),\n    new Pos(1, 0));\n  var expectedLineCount = cm.lineCount() - 1;\n\n  helpers.doKeys('e', 'e');\n\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[1].textStart);\n});\n// this test serves two functions:\n// - make sure that \"dd\" is **not** interpreted as delete line (correct unmapping)\n// - make sure that \"dd\" **is** interpreted as move left twice (correct mapping)\ntestVim('langmap_hh', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  const startPos = word1.end;\n  const endPos = offsetCursor(word1.end, 0, -2);\n\n  cm.setCursor(startPos);\n  helpers.doKeys('d', 'd');\n  helpers.assertCursorAt(endPos);\n});\n// this test serves two functions:\n// - make sure tha the register is properly remapped so that special registers aren't mixed up\n// - make sure that recording and replaying macros works without \"double remapping\"\ntestVim('langmap_qqddq@q', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  cm.setCursor(0, 3);\n  var expectedBuffer = cm.getRange(new Pos(1, 0),\n    new Pos(2, 0));\n  var expectedLineCount = cm.lineCount() - 2;\n\n  helpers.doKeys('\\'\\'', 'e', 'e', '\\'', '@\\'');\n\n  eq(expectedLineCount, cm.lineCount());\n  var register = helpers.getRegisterController().getRegister();\n  eq(expectedBuffer, register.toString());\n  is(register.linewise);\n  helpers.assertCursorAt(0, lines[2].textStart);\n});\n// this test makes sure that <character> directives are interpreted literally\ntestVim('langmap_fd', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  cm.setCursor(0, 0);\n  helpers.doKeys('u', 'd');\n  helpers.assertCursorAt(0, 4);\n});\n// this test makes sure that markers work properly\ntestVim('langmap_mark', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  cm.setCursor(2, 2);\n  helpers.doKeys('m', '\\'');\n  cm.setCursor(0, 0);\n  helpers.doKeys('`', '\\'');\n  helpers.assertCursorAt(2, 2);\n  cm.setCursor(2, 0);\n  cm.replaceRange('   h', cm.getCursor());\n  cm.setCursor(0, 0);\n  helpers.doKeys('-', '\\'');\n  helpers.assertCursorAt(2, 3);\n});\n// check that ctrl remapping works properly\ntestVim('langmap_visual_block', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap);\n\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-k>', '2', 'h', 'n', 'n', 'n', 'j');\n  helpers.doKeys('hello');\n  eq('1hello\\n5hello\\nahellofg', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(2, 3);\n  helpers.doKeys('<C-k>', '2', 't', 'd', 'J');\n  helpers.doKeys('world');\n  eq('1hworld\\n5hworld\\nahworld', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\n// check that ctrl remapping can be disabled\ntestVim('langmap_visual_block_no_ctrl_remap', function(cm, vim, helpers) {\n  CodeMirror.Vim.langmap(dvorakLangmap, false);\n\n  cm.setCursor(0, 1);\n  helpers.doKeys('<C-v>', '2', 'h', 'n', 'n', 'n', 'j');\n  helpers.doKeys('hello');\n  eq('1hello\\n5hello\\nahellofg', cm.getValue());\n  helpers.doKeys('<Esc>');\n  cm.setCursor(2, 3);\n  helpers.doKeys('<C-v>', '2', 't', 'd', 'J');\n  helpers.doKeys('world');\n  eq('1hworld\\n5hworld\\nahworld', cm.getValue());\n}, {value: '1234\\n5678\\nabcdefg'});\n\n\nasync function delay(t) {\n  return await new Promise(resolve => setTimeout(resolve, t));\n}\n\n\n\nvar typeKey = function() {\n  var keyCodeToKey = {};\n  var keyCodeToCode = {};\n\n  var alias = {};\n  alias.Ctrl = \"Control\";\n  alias.Option = \"Alt\";\n  alias.Cmd = alias.Super = alias.Meta = \"Command\";\n\n  var controlKeys = {\n    Shift: 16, Control: 17, Alt: 18, Meta: 224, Command: 224,\n    Backspace:8, Tab:9, Return: 13, Enter: 13,\n    Pause: 19, Escape: 27, PageUp: 33, PageDown: 34, End: 35, Home: 36,\n    Left: 37, Up: 38, Right: 39, Down: 40, Insert: 45, Delete: 46,\n    ArrowLeft: 37, ArrowUp: 38, ArrowRight: 39, ArrowDown: 40,\n  };\n  var shiftedKeys = {};\n  var printableKeys = {};\n  var specialKeys = {\n    Backquote: [192, \"`\", \"~\"], Minus: [189, \"-\", \"_\"], Equal: [187, \"=\", \"+\"],\n    BracketLeft: [219, \"[\", \"{\"], Backslash: [220, \"\\\\\", \"|\"], BracketRight: [221, \"]\", \"}\"],\n    Semicolon: [186, \";\", \":\"], Quote: [222, \"'\", '\"'], Comma: [188, \",\", \"<\"],\n    Period: [190, \".\", \">\"], Slash: [191, \"/\", \"?\"], Space: [32, \" \", \" \"], NumpadAdd: [107, \"+\"],\n    NumpadDecimal: [110, \".\"], NumpadSubtract: [109, \"-\"], NumpadDivide: [111, \"/\"], NumpadMultiply: [106, \"*\"]\n  };\n  for (var i in specialKeys) {\n    var key = specialKeys[i];\n    printableKeys[i] = printableKeys[key[1]] = shiftedKeys[key[2]] = key[0];\n    keyCodeToCode[key[0]] = i;\n    keyCodeToKey[key[0]] = key[1];\n    keyCodeToKey[\"s-\" + key[0]] = key[2];\n  }\n  for (var i = 0; i < 10; i++) {\n    var shifted = \"!@#$%^&*()\"[i];\n    printableKeys[i] = shiftedKeys[shifted] = 48 + i;\n    keyCodeToCode[48 + i] = \"Digit\" + i;\n    keyCodeToKey[48 + i] = i.toString();\n    keyCodeToKey[\"s-\" + (48 + i)] = shifted;\n  }\n  for (var i = 65; i < 91; i++) {\n    var chr = String.fromCharCode(i + 32);\n    printableKeys[chr] = shiftedKeys[chr.toUpperCase()] = i;\n    keyCodeToCode[i] = \"Key\" + chr.toUpperCase();\n    keyCodeToKey[i] = chr;\n    keyCodeToKey[\"s-\" + i] = chr.toUpperCase();\n  }\n  for (var i = 1; i < 13; i++) {\n    controlKeys[\"F\" + i] = 111 + i;\n  }\n\n  for (var i in controlKeys) {\n    keyCodeToKey[controlKeys[i]] = i;\n    keyCodeToCode[controlKeys[i]] = i;\n  }\n  controlKeys[\"\\t\"] = controlKeys.Tab;\n  controlKeys[\"\\n\"] = controlKeys.Return;\n  controlKeys.Del = controlKeys.Delete;\n  controlKeys.Esc = controlKeys.Escape;\n  controlKeys.Ins = controlKeys.Insert;\n\n  var shift = false;\n  var ctrl = false;\n  var meta = false;\n  var alt = false;\n  function reset() {\n    shift = ctrl = meta = alt = false;\n  }\n  function updateModifierStates(keyCode) {\n    if (keyCode == controlKeys.Shift)\n      return shift = true;\n    if (keyCode == controlKeys.Control)\n      return ctrl = true;\n    if (keyCode == controlKeys.Meta)\n      return meta = true;\n    if (keyCode == controlKeys.Alt)\n      return alt = true;\n  }\n\n  function sendKey(letter, options) {\n    var keyCode = controlKeys[letter] || printableKeys[letter] || shiftedKeys[letter];\n    var isModifier = updateModifierStates(keyCode);\n\n    var text = letter;\n    var isTextInput = true;\n    if (ctrl || alt || meta) {\n      isTextInput = false;\n    } else if (controlKeys[letter]) {\n        if (keyCode == controlKeys.Return) {\n            text = \"\\n\";\n            isTextInput = true;\n        } else {\n            isTextInput = false;\n        }\n    } else if (shift) {\n      text = text.toUpperCase();\n    }\n\n    if (keyCodeToKey[keyCode] != text && keyCodeToKey[\"s-\" + keyCode] == text) {\n      shift = true;\n    }\n    var key = keyCodeToKey[(shift ? \"s-\" : \"\") + keyCode];\n    \n    if (options && options.macAltText) {\n      alt = true;\n      text = key = options.macAltText;\n      isTextInput = true;\n    }\n\n    var target = document.activeElement;\n    var prevented = emit(\"keydown\", true);\n    if (isModifier) return;\n    if (!prevented && isTextInput) prevented = emit(\"keypress\", true);\n    if (!prevented && ctrl && !alt && !meta && letter == \"c\") emitClipboard(\"copy\");\n    if (!prevented) updateTextInput();\n    emit(\"keyup\", true);\n\n    function emitClipboard(eventType) {\n      var data = {bubbles: true, cancelable:true};\n      var event = new KeyboardEvent(eventType, data);\n      event.clipboardData = {\n        setData: function(mime, text) {\n          type.clipboard.$data = text;\n        },\n        getData: function() {\n          return type.clipboard.$data;\n        },\n        clearData: function() {},\n      };\n      target.dispatchEvent(event);\n    }\n    function emit(type, bubbles) {\n      var el = document.activeElement;\n      var data = {bubbles: bubbles, cancelable:true};\n      data.charCode = text.charCodeAt(0);\n      data.keyCode = type == \"keypress\" ? data.charCode : keyCode;\n      data.which = data.keyCode;\n      data.shiftKey = shift || (shiftedKeys[text] && !printableKeys[text]);\n      data.ctrlKey = ctrl;\n      data.altKey = alt;\n      data.metaKey = meta;\n      data.key = key;\n      data.code = keyCodeToCode[keyCode];\n      var event = new KeyboardEvent(type, data);\n\n      var el = document.activeElement;\n      el.dispatchEvent(event);\n      return event.defaultPrevented;\n    }\n    function updateTextInput() {\n      if (!isTextInput && keyCode == controlKeys.Return) {\n        text = \"\\n\";\n      }\n      if (target._handleInputEventForTest) {\n        if (!isTextInput) return;\n        return target._handleInputEventForTest(text);\n      }\n      var isTextarea = \"selectionStart\" in target && typeof target.value == \"string\";\n      if (!isTextarea) return;\n\n      var start = target.selectionStart;\n      var end = target.selectionEnd;\n      var value = target.value;\n\n      if (!isTextInput) {\n        if (keyCode == controlKeys.Backspace) {\n          if (start != end) start = Math.max(start - 1, 0);\n        } else if (keyCode == controlKeys.Delete) {\n          if (start != end) end = Math.min(end + 1, value.length);\n        } else {\n          return;\n        }\n      }\n      var newValue = value.slice(0, start) + text + value.slice(end);\n      var newStart = start + text.length;\n      var newEnd = newStart;\n      if (newValue != value || newStart != start || newEnd != end) {\n        target.value = newValue;\n        target.setSelectionRange(newStart, newEnd);\n        emit(\"input\", false);\n      }\n    }\n  }\n\n  function type() {\n    var keys = Array.prototype.slice.call(arguments);\n    for (var i = 0; i < keys.length; i++) {\n      var key = keys[i];\n      if (Array.isArray(key)) {\n        type.apply(null, key);\n        continue;\n      }\n      reset();\n      if (key.length > 1) {\n        var isKeyName = controlKeys[key] || printableKeys[key] || shiftedKeys[key];\n        if (!isKeyName) {\n          var parts = key.split(\"-\");\n          var modifiers = parts.slice(0, parts.length - 1).map(function(part) {\n            return controlKeys[alias[part] || part];\n          });\n          var isValid = modifiers.length && modifiers.every(updateModifierStates);\n          if (!isValid) {\n            type.apply(null, key.split(\"\"));\n            continue;\n          }\n          key = parts.pop();\n          parts.forEach(function(part) {\n            var keyCode = controlKeys[part];\n            updateModifierStates(keyCode);\n          });\n        }\n      }\n      sendKey(key);\n    }\n  }\n\n  // emulates option-9 inputting } on mac swiss keyboard\n  type.optionTextInput = function(letter, altText) {\n    reset();\n    sendKey(letter, {macAltText: altText});\n  };\n\n  type.clipboard = {};\n\n  return type;\n}();\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/keyboard/vscode.js",
    "content": "\"use strict\";\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nvar config = require(\"../config\");\n\nexports.handler = new HashHandler();\nexports.handler.$id = \"ace/keyboard/vscode\";\n\nexports.handler.addCommands([{\n    name: \"toggleWordWrap\",\n    exec: function(editor) {\n        var wrapUsed = editor.session.getUseWrapMode();\n        editor.session.setUseWrapMode(!wrapUsed);\n    },\n    readOnly: true\n}, {\n    name: \"navigateToLastEditLocation\",\n    exec: function(editor) {\n        var lastDelta = editor.session.getUndoManager().$lastDelta;\n        var range = (lastDelta.action  == \"remove\")? lastDelta.start: lastDelta.end;\n        editor.moveCursorTo(range.row, range.column);\n        editor.clearSelection();\n    }\n}, {\n    name: \"replaceAll\",\n    exec: function (editor) {\n        if (!editor.searchBox) {\n            config.loadModule(\"ace/ext/searchbox\", function(e) {\n                e.Search(editor, true);\n            });\n        } else {\n            if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) {\n                editor.searchBox.replaceAll();\n            }\n        }\n    }\n}, {\n    name: \"replaceOne\",\n    exec: function (editor) {\n        if (!editor.searchBox) {\n            config.loadModule(\"ace/ext/searchbox\", function(e) {\n                e.Search(editor, true);\n            });\n        } else {\n            if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) {\n                editor.searchBox.replace();\n            }\n        }\n    }\n}, {\n    name: \"selectAllMatches\",\n    exec: function (editor) {\n        if (!editor.searchBox) {\n            config.loadModule(\"ace/ext/searchbox\", function(e) {\n                e.Search(editor, false);\n            });\n        } else {\n            if (editor.searchBox.active === true) {\n                editor.searchBox.findAll();\n            }\n        }\n    }\n}, {\n    name: \"toggleFindCaseSensitive\",\n    exec: function (editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {\n            e.Search(editor, false);\n            var sb = editor.searchBox;\n            sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked;\n            sb.$syncOptions();\n        });\n\n    }\n}, {\n    name: \"toggleFindInSelection\",\n    exec: function (editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {\n            e.Search(editor, false);\n            var sb = editor.searchBox;\n            sb.searchOption.checked = !sb.searchRange;\n            sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange());\n            sb.$syncOptions();\n        });\n    }\n}, {\n    name: \"toggleFindRegex\",\n    exec: function (editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {\n            e.Search(editor, false);\n            var sb = editor.searchBox;\n            sb.regExpOption.checked = !sb.regExpOption.checked;\n            sb.$syncOptions();\n        });\n    }\n}, {\n    name: \"toggleFindWholeWord\",\n    exec: function (editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {\n            e.Search(editor, false);\n            var sb = editor.searchBox;\n            sb.wholeWordOption.checked = !sb.wholeWordOption.checked;\n            sb.$syncOptions();\n        });\n    }\n}, {\n    name: \"removeSecondaryCursors\",\n    exec: function (editor) {\n        var ranges = editor.selection.ranges;\n        if (ranges && ranges.length > 1)\n            editor.selection.toSingleRange(ranges[ranges.length - 1]);\n        else\n            editor.selection.clearSelection();\n    }\n}]);\n\n\n[{\n    bindKey: {mac: \"Ctrl-G\", win: \"Ctrl-G\"},\n    name: \"gotoline\"\n}, {\n    bindKey: {mac: \"Command-Shift-L|Command-F2\", win: \"Ctrl-Shift-L|Ctrl-F2\"},\n    name: \"findAll\"\n}, {\n    bindKey: {mac: \"Shift-F8|Shift-Option-F8\", win: \"Shift-F8|Shift-Alt-F8\"},\n    name: \"goToPreviousError\"\n}, {\n    bindKey: {mac: \"F8|Option-F8\", win: \"F8|Alt-F8\"},\n    name: \"goToNextError\"\n}, {\n    bindKey: {mac: \"Command-Shift-P|F1\", win: \"Ctrl-Shift-P|F1\"},\n    name: \"openCommandPalette\"\n}, {\n    bindKey: {mac: \"Shift-Option-Up\", win: \"Alt-Shift-Up\"},\n    name: \"copylinesup\"\n}, {\n    bindKey: {mac: \"Shift-Option-Down\", win: \"Alt-Shift-Down\"},\n    name: \"copylinesdown\"\n}, {\n    bindKey: {mac: \"Command-Shift-K\", win: \"Ctrl-Shift-K\"},\n    name: \"removeline\"\n}, {\n    bindKey: {mac: \"Command-Enter\", win: \"Ctrl-Enter\"},\n    name: \"addLineAfter\"\n}, {\n    bindKey: {mac: \"Command-Shift-Enter\", win: \"Ctrl-Shift-Enter\"},\n    name: \"addLineBefore\"\n}, {\n    bindKey: {mac: \"Command-Shift-\\\\\", win: \"Ctrl-Shift-\\\\\"},\n    name: \"jumptomatching\"\n}, {\n    bindKey: {mac: \"Command-]\", win: \"Ctrl-]\"},\n    name: \"blockindent\"\n}, {\n    bindKey: {mac: \"Command-[\", win: \"Ctrl-[\"},\n    name: \"blockoutdent\"\n}, {\n    bindKey: {mac: \"Ctrl-PageDown\", win: \"Alt-PageDown\"},\n    name: \"pagedown\"\n}, {\n    bindKey: {mac: \"Ctrl-PageUp\", win: \"Alt-PageUp\"},\n    name: \"pageup\"\n}, {\n    bindKey: {mac: \"Shift-Option-A\", win: \"Shift-Alt-A\"},\n    name: \"toggleBlockComment\"\n}, {\n    bindKey: {mac: \"Option-Z\", win: \"Alt-Z\"},\n    name: \"toggleWordWrap\"\n}, {\n    bindKey: {mac: \"Command-G\", win: \"F3|Ctrl-K Ctrl-D\"},\n    name: \"findnext\"\n}, {\n    bindKey: {mac: \"Command-Shift-G\", win: \"Shift-F3\"},\n    name: \"findprevious\"\n}, {\n    bindKey: {mac: \"Option-Enter\", win: \"Alt-Enter\"},\n    name: \"selectAllMatches\"\n}, {\n    bindKey: {mac: \"Command-D\", win: \"Ctrl-D\"},\n    name: \"selectMoreAfter\"\n}, {\n    bindKey: {mac: \"Command-K Command-D\", win: \"Ctrl-K Ctrl-D\"},\n    name: \"selectOrFindNext\"\n}, {\n    bindKey: {mac: \"Shift-Option-I\", win: \"Shift-Alt-I\"},\n    name: \"splitSelectionIntoLines\"\n}, {\n    bindKey: {mac: \"Command-K M\", win: \"Ctrl-K M\"},\n    name: \"modeSelect\"\n}, {\n    // In VsCode this command is used only for folding instead of toggling fold\n    bindKey: {mac: \"Command-Option-[\", win: \"Ctrl-Shift-[\"},\n    name: \"toggleFoldWidget\"\n}, {\n    bindKey: {mac: \"Command-Option-]\", win: \"Ctrl-Shift-]\"},\n    name: \"toggleFoldWidget\"\n}, {\n    bindKey: {mac: \"Command-K Command-0\", win: \"Ctrl-K Ctrl-0\"},\n    name: \"foldall\"\n}, {\n    bindKey: {mac: \"Command-K Command-J\", win: \"Ctrl-K Ctrl-J\"},\n    name: \"unfoldall\"\n}, {\n    bindKey: { mac: \"Command-K Command-1\", win: \"Ctrl-K Ctrl-1\" },\n    name: \"foldOther\"\n}, {\n    bindKey: { mac: \"Command-K Command-Q\", win: \"Ctrl-K Ctrl-Q\" },\n    name: \"navigateToLastEditLocation\"\n}, {\n    bindKey: { mac: \"Command-K Command-R|Command-K Command-S\", win: \"Ctrl-K Ctrl-R|Ctrl-K Ctrl-S\" },\n    name: \"showKeyboardShortcuts\"\n}, {\n    bindKey: { mac: \"Command-K Command-X\", win: \"Ctrl-K Ctrl-X\" },\n    name: \"trimTrailingSpace\"\n}, {\n    bindKey: {mac: \"Shift-Down|Command-Shift-Down\", win: \"Shift-Down|Ctrl-Shift-Down\"},\n    name: \"selectdown\"\n}, {\n    bindKey: {mac: \"Shift-Up|Command-Shift-Up\", win: \"Shift-Up|Ctrl-Shift-Up\"},\n    name: \"selectup\"\n}, {\n    // TODO: add similar command to work inside SearchBox\n    bindKey: {mac: \"Command-Alt-Enter\", win: \"Ctrl-Alt-Enter\"},\n    name: \"replaceAll\"\n}, {\n    // TODO: add similar command to work inside SearchBox\n    bindKey: {mac: \"Command-Shift-1\", win: \"Ctrl-Shift-1\"},\n    name: \"replaceOne\"\n}, {\n    bindKey: {mac: \"Option-C\", win: \"Alt-C\"},\n    name: \"toggleFindCaseSensitive\"\n}, {\n    bindKey: {mac: \"Option-L\", win: \"Alt-L\"},\n    name: \"toggleFindInSelection\"\n}, {\n    bindKey: {mac: \"Option-R\", win: \"Alt-R\"},\n    name: \"toggleFindRegex\"\n}, {\n    bindKey: {mac: \"Option-W\", win: \"Alt-W\"},\n    name: \"toggleFindWholeWord\"\n}, {\n    bindKey: {mac: \"Command-L\", win: \"Ctrl-L\"},\n    name: \"expandtoline\"\n}, {\n    bindKey: {mac: \"Shift-Esc\", win: \"Shift-Esc\"},\n    name: \"removeSecondaryCursors\"\n} \n// not implemented\n/*{\n    bindKey: {mac: \"Option-Shift-Command-Right\", win: \"Shift-Alt-Right\"},\n    name: \"smartSelect.expand\"\n}, {\n    bindKey: {mac: \"Ctrl-Shift-Command-Left\", win: \"Shift-Alt-Left\"},\n    name: \"smartSelect.shrink\"\n}, {\n    bindKey: {mac: \"Shift-Option-F\", win: \"Shift-Alt-F\"},\n    name: \"beautify\"\n}, {\n    bindKey: {mac: \"Command-K Command-F\", win: \"Ctrl-K Ctrl-F\"},\n    name: \"formatSelection\"\n}, {\n    bindKey: {mac: \"Command-K Command-C\", win: \"Ctrl-K Ctrl-C\"},\n    name: \"addCommentLine\"\n}, {\n    bindKey: {mac: \"Command-K Command-U\", win: \"Ctrl-K Ctrl-U\"},\n    name: \"removeCommentLine\"\n}, {\n    bindKey: {mac: \"Command-K Command-/\", win: \"Ctrl-K Ctrl-/\"},\n    name: \"foldAllBlockComments\"\n}, {\n    bindKey: {mac: \"Command-K Command-2\", win: \"Ctrl-K Ctrl-2\"},\n    name: \"foldLevel2\"\n}, {\n    bindKey: {mac: \"Command-K Command-3\", win: \"Ctrl-K Ctrl-3\"},\n    name: \"foldLevel3\"\n}, {\n    bindKey: {mac: \"Command-K Command-4\", win: \"Ctrl-K Ctrl-4\"},\n    name: \"foldLevel4\"\n}, {\n    bindKey: {mac: \"Command-K Command-5\", win: \"Ctrl-K Ctrl-5\"},\n    name: \"foldLevel5\"\n}, {\n    bindKey: {mac: \"Command-K Command-6\", win: \"Ctrl-K Ctrl-6\"},\n    name: \"foldLevel6\"\n}, {\n    bindKey: {mac: \"Command-K Command-7\", win: \"Ctrl-K Ctrl-7\"},\n    name: \"foldLevel7\"\n}, {\n    bindKey: {mac: \"Command-K Command-[\", win: \"Ctrl-K Ctrl-[\"},\n    name: \"foldRecursively\"\n}, {\n    bindKey: {mac: \"Command-K Command-8\", win: \"Ctrl-K Ctrl-8\"},\n    name: \"foldAllMarkerRegions\"\n}, {\n    bindKey: {mac: \"Command-K Command-9\", win: \"Ctrl-K Ctrl-9\"},\n    name: \"unfoldAllMarkerRegions\"\n}, {\n    bindKey: {mac: \"Command-K Command-]\", win: \"Ctrl-K Ctrl-]\"},\n    name: \"unfoldRecursively\"\n}, {\n    bindKey: {mac: \"Command-K Command-T\", win: \"Ctrl-K Ctrl-T\"},\n    name: \"selectTheme\"\n}, {\n    bindKey: {mac: \"Command-K Command-M\", win: \"Ctrl-K Ctrl-M\"},\n    name: \"selectKeymap\"\n}, {\n    bindKey: {mac: \"Command-U\", win: \"Ctrl-U\"},\n    name: \"cursorUndo\"\n}*/\n].forEach(function(binding) {\n    var command = exports.handler.commands[binding.name];\n    if (command)\n        command.bindKey = binding.bindKey;\n    exports.handler.bindKey(binding.bindKey, command || binding.name);\n});\n"
  },
  {
    "path": "src/layer/cursor.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n */\nvar dom = require(\"../lib/dom\");\n\n\nclass Cursor {\n    /**\n     * @param {HTMLElement} parentEl\n     */\n    constructor(parentEl) {\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_layer ace_cursor-layer\";\n        parentEl.appendChild(this.element);\n\n        this.isVisible = false;\n        this.isBlinking = true;\n        this.blinkInterval = 1000;\n        this.smoothBlinking = false;\n\n        this.cursors = [];\n        this.cursor = this.addCursor();\n        dom.addCssClass(this.element, \"ace_hidden-cursors\");\n        this.$updateCursors = this.$updateOpacity.bind(this);\n    }\n\n    /**\n     * @param {boolean} [val]\n     */\n    $updateOpacity(val) {\n        var cursors = this.cursors;\n        for (var i = cursors.length; i--; )\n            dom.setStyle(cursors[i].style, \"opacity\", val ? \"\" : \"0\");\n    }\n\n    $startCssAnimation() {\n        var cursors = this.cursors;\n        for (var i = cursors.length; i--; )\n            cursors[i].style.animationDuration = this.blinkInterval + \"ms\";\n\n        this.$isAnimating = true;\n        setTimeout(function() {\n            if (this.$isAnimating) {\n                dom.addCssClass(this.element, \"ace_animate-blinking\");\n            }\n        }.bind(this));\n    }\n    \n    $stopCssAnimation() {\n        this.$isAnimating = false;\n        dom.removeCssClass(this.element, \"ace_animate-blinking\");\n    }\n\n    /**\n     * @param {number} padding\n     */\n    setPadding(padding) {\n        this.$padding = padding;\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    setSession(session) {\n        this.session = session;\n    }\n\n    /**\n     * @param {boolean} blinking\n     */\n    setBlinking(blinking) {\n        if (blinking != this.isBlinking) {\n            this.isBlinking = blinking;\n            this.restartTimer();\n        }\n    }\n\n    /**\n     * @param {number} blinkInterval\n     */\n    setBlinkInterval(blinkInterval) {\n        if (blinkInterval != this.blinkInterval) {\n            this.blinkInterval = blinkInterval;\n            this.restartTimer();\n        }\n    }\n\n    /**\n     * @param {boolean} smoothBlinking\n     */\n    setSmoothBlinking(smoothBlinking) {\n        if (smoothBlinking != this.smoothBlinking) {\n            this.smoothBlinking = smoothBlinking;\n            dom.setCssClass(this.element, \"ace_smooth-blinking\", smoothBlinking);\n            this.$updateCursors(true);\n            this.restartTimer();\n        }\n    }\n\n    addCursor() {\n        var el = dom.createElement(\"div\");\n        el.className = \"ace_cursor\";\n        this.element.appendChild(el);\n        this.cursors.push(el);\n        return el;\n    }\n\n    removeCursor() {\n        if (this.cursors.length > 1) {\n            var el = this.cursors.pop();\n            el.parentNode.removeChild(el);\n            return el;\n        }\n    }\n\n    hideCursor() {\n        this.isVisible = false;\n        dom.addCssClass(this.element, \"ace_hidden-cursors\");\n        this.restartTimer();\n    }\n\n    showCursor() {\n        this.isVisible = true;\n        dom.removeCssClass(this.element, \"ace_hidden-cursors\");\n        this.restartTimer();\n    }\n\n    restartTimer() {\n        var update = this.$updateCursors;\n        clearInterval(this.intervalId);\n        clearTimeout(this.timeoutId);\n        this.$stopCssAnimation();\n\n        if (this.smoothBlinking) {\n            this.$isSmoothBlinking = false;\n            dom.removeCssClass(this.element, \"ace_smooth-blinking\");\n        }\n        \n        update(true);\n\n        if (!this.isBlinking || !this.blinkInterval || !this.isVisible) {\n            this.$stopCssAnimation();\n            return;\n        }\n\n        if (this.smoothBlinking) {\n            this.$isSmoothBlinking = true;\n            setTimeout(function() {\n                if (this.$isSmoothBlinking) {\n                    dom.addCssClass(this.element, \"ace_smooth-blinking\");\n                }\n            }.bind(this));\n        }\n        \n        if (dom.HAS_CSS_ANIMATION) {\n            this.$startCssAnimation();\n        } else {\n            var blink = /**@this{Cursor}*/function(){\n                /**@type{ReturnType<typeof setTimeout>}*/\n                this.timeoutId = setTimeout(function() {\n                    update(false);\n                }, 0.6 * this.blinkInterval);\n            }.bind(this);\n\n            /**@type{ReturnType<typeof setInterval>}*/\n            this.intervalId = setInterval(function() {\n                update(true);\n                blink();\n            }, this.blinkInterval);\n            blink();\n        }\n    }\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.Point} [position]\n     * @param {boolean} [onScreen]\n     */\n    getPixelPosition(position, onScreen) {\n        if (!this.config || !this.session)\n            return {left : 0, top : 0};\n\n        if (!position)\n            position = this.session.selection.getCursor();\n        var pos = this.session.documentToScreenPosition(position);\n        var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row)\n            ? this.session.$bidiHandler.getPosLeft(pos.column)\n            : pos.column * this.config.characterWidth);\n\n        var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *\n            this.config.lineHeight;\n\n        return {left : cursorLeft, top : cursorTop};\n    }\n\n    isCursorInView(pixelPos, config) {\n        return pixelPos.top >= 0 && pixelPos.top < config.maxHeight;\n    }\n\n    update(config) {\n        this.config = config;\n\n        var selections = this.session.$selectionMarkers;\n        var i = 0, cursorIndex = 0;\n\n        if (selections === undefined || selections.length === 0){\n            selections = [{cursor: null}];\n        }\n\n        for (var i = 0, n = selections.length; i < n; i++) {\n            var pixelPos = this.getPixelPosition(selections[i].cursor, true);\n            if ((pixelPos.top > config.height + config.offset ||\n                 pixelPos.top < 0) && i > 1) {\n                continue;\n            }\n\n            var element = this.cursors[cursorIndex++] || this.addCursor();\n            var style = element.style;\n            \n            if (!this.drawCursor) {\n                if (!this.isCursorInView(pixelPos, config)) {\n                    dom.setStyle(style, \"display\", \"none\");\n                } else {\n                    dom.setStyle(style, \"display\", \"block\");\n                    dom.translate(element, pixelPos.left, pixelPos.top);\n                    dom.setStyle(style, \"width\", Math.round(config.characterWidth) + \"px\");\n                    dom.setStyle(style, \"height\", config.lineHeight + \"px\");\n                }\n            } else {\n                this.drawCursor(element, pixelPos, config, selections[i], this.session);\n            }\n        }\n        while (this.cursors.length > cursorIndex)\n            this.removeCursor();\n\n        var overwrite = this.session.getOverwrite();\n        this.$setOverwrite(overwrite);\n\n        // cache for textarea and gutter highlight\n        this.$pixelPos = pixelPos;\n        this.restartTimer();\n    }\n\n    /**\n     * @param {boolean} overwrite\n     */\n    $setOverwrite(overwrite) {\n        if (overwrite != this.overwrite) {\n            this.overwrite = overwrite;\n            if (overwrite)\n                dom.addCssClass(this.element, \"ace_overwrite-cursors\");\n            else\n                dom.removeCssClass(this.element, \"ace_overwrite-cursors\");\n        }\n    }\n\n    destroy() {\n        clearInterval(this.intervalId);\n        clearTimeout(this.timeoutId);\n    }\n\n}\n\nCursor.prototype.$padding = 0;\nCursor.prototype.drawCursor = null;\n\n\nexports.Cursor = Cursor;\n"
  },
  {
    "path": "src/layer/decorators.js",
    "content": "\"use strict\";\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nclass Decorator {\n    /**\n     * @param {import(\"../../ace-internal\").Ace.VScrollbar} scrollbarV\n     * @param {import(\"../virtual_renderer\").VirtualRenderer} renderer\n     */\n    constructor(scrollbarV, renderer) {\n        this.renderer = renderer;\n\n        this.pixelRatio = 1;\n        this.maxHeight = renderer.layerConfig.maxHeight;\n        this.lineHeight = renderer.layerConfig.lineHeight;\n        this.minDecorationHeight = (2 * this.pixelRatio) | 0;\n        this.halfMinDecorationHeight = (this.minDecorationHeight / 2) | 0;\n        this.colors = {};\n        this.colors.dark = {\n            \"error\": \"rgba(255, 18, 18, 1)\",\n            \"warning\": \"rgba(18, 136, 18, 1)\",\n            \"info\": \"rgba(18, 18, 136, 1)\",\n        };\n\n        this.colors.light = {\n            \"error\": \"rgb(255,51,51)\",\n            \"warning\": \"rgb(32,133,72)\",\n            \"info\": \"rgb(35,68,138)\",\n        };\n\n        this.setScrollBarV(scrollbarV);\n    }\n\n    $createCanvas() {\n        this.canvas = dom.createElement(\"canvas\");\n        this.canvas.style.top = 0 + \"px\";\n        this.canvas.style.right = 0 + \"px\";\n        this.canvas.style.zIndex = \"7\";\n        this.canvas.style.position = \"absolute\";\n    }\n\n    setScrollBarV(scrollbarV) {\n        this.$createCanvas();\n        this.scrollbarV = scrollbarV;\n        scrollbarV.element.appendChild(this.canvas);\n        this.setDimensions();\n    }\n\n    $updateDecorators(config) {\n        if (typeof this.canvas.getContext !== \"function\") {\n            return;\n        }\n        var colors = (this.renderer.theme.isDark === true) ? this.colors.dark : this.colors.light;\n        this.setDimensions(config);\n\n        var ctx = this.canvas.getContext(\"2d\");\n\n        function compare(a, b) {\n            if (a.priority < b.priority) return -1;\n            if (a.priority > b.priority) return 1;\n            return 0;\n        }\n\n        var annotations = this.renderer.session.$annotations;\n        ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n        if (annotations) {\n            var priorities = {\n                \"info\": 1,\n                \"warning\": 2,\n                \"error\": 3\n            };\n            annotations.forEach(function (item) {\n                item[\"priority\"] = priorities[item.type] || null;\n            });\n            annotations = annotations.sort(compare);\n\n            for (let i = 0; i < annotations.length; i++) {\n                let row = annotations[i].row;\n                const offset1 = this.getVerticalOffsetForRow(row);\n                const offset2 = offset1 + this.lineHeight;\n\n                const y1 = Math.round(this.heightRatio * offset1);\n                const y2 = Math.round(this.heightRatio * offset2);\n                let ycenter = Math.round((y1 + y2) / 2);\n                let halfHeight = (y2 - ycenter);\n\n                if (halfHeight < this.halfMinDecorationHeight) {\n                    halfHeight = this.halfMinDecorationHeight;\n                }\n                if (ycenter - halfHeight < 0) {\n                    ycenter = halfHeight;\n                }\n                if (ycenter + halfHeight > this.canvasHeight) {\n                    ycenter = this.canvasHeight - halfHeight;\n                }\n\n                const from =  ycenter - halfHeight;\n                const to = ycenter + halfHeight;\n                const zoneHeight = to - from;\n\n                ctx.fillStyle = colors[annotations[i].type] || null;\n                ctx.fillRect(0, from, Math.round(this.oneZoneWidth - 1), zoneHeight);\n            }\n        }\n        var cursor = this.renderer.session.selection.getCursor();\n        if (cursor) {\n            let currentY = Math.round(this.getVerticalOffsetForRow(cursor.row) * this.heightRatio);\n            ctx.fillStyle = \"rgba(0, 0, 0, 0.5)\";\n            ctx.fillRect(0, currentY, this.canvasWidth, 2);\n        }\n\n    }\n\n    getVerticalOffsetForRow(row) {\n        row = row | 0;\n        const offset = this.renderer.session.documentToScreenRow(row, 0) * this.lineHeight;\n        return offset;\n    }\n\n    setDimensions(config) {\n        config = config || this.renderer.layerConfig;\n        this.maxHeight = config.maxHeight;\n        this.lineHeight = config.lineHeight;\n        this.canvasHeight = config.height;\n        this.canvasWidth = this.scrollbarV.width || this.canvasWidth;\n\n        this.setZoneWidth();\n\n        this.canvas.width = this.canvasWidth;\n        this.canvas.height = this.canvasHeight;\n\n        if (this.maxHeight < this.canvasHeight) {\n            this.heightRatio = 1;\n        }\n        else {\n            this.heightRatio = this.canvasHeight / this.maxHeight;\n        }\n    }\n\n    setZoneWidth() {\n        this.oneZoneWidth = this.canvasWidth;\n    }\n\n    destroy() {\n        this.canvas.parentNode.removeChild(this.canvas);\n    }\n}\n\noop.implement(Decorator.prototype, EventEmitter);\n\nexports.Decorator = Decorator;\n"
  },
  {
    "path": "src/layer/font_metrics.js",
    "content": "var oop = require(\"../lib/oop\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nvar CHAR_COUNT = 512;\nvar USE_OBSERVER = typeof ResizeObserver == \"function\";\nvar L = 200;\n\nclass FontMetrics {\n\n    /**\n     * @param {HTMLElement} parentEl\n     */\n    constructor(parentEl) {\n        this.el = dom.createElement(\"div\");\n        this.$setMeasureNodeStyles(this.el.style, true);\n\n        this.$main = dom.createElement(\"div\");\n        this.$setMeasureNodeStyles(this.$main.style);\n\n        this.$measureNode = dom.createElement(\"div\");\n        this.$setMeasureNodeStyles(this.$measureNode.style);\n\n\n        this.el.appendChild(this.$main);\n        this.el.appendChild(this.$measureNode);\n        parentEl.appendChild(this.el);\n\n        this.$measureNode.textContent = lang.stringRepeat(\"X\", CHAR_COUNT);\n\n        this.$characterSize = {width: 0, height: 0};\n\n\n        if (USE_OBSERVER)\n            this.$addObserver();\n        else\n            this.checkForSizeChanges();\n    }\n    \n    $setMeasureNodeStyles(style, isRoot) {\n        style.width = style.height = \"auto\";\n        style.left = style.top = \"0px\";\n        style.visibility = \"hidden\";\n        style.position = \"absolute\";\n        style.whiteSpace = \"pre\";\n\n        if (useragent.isIE < 8) {\n            style[\"font-family\"] = \"inherit\";\n        } else {\n            style.font = \"inherit\";\n        }\n        style.overflow = isRoot ? \"hidden\" : \"visible\";\n    }\n\n    /**\n     * @param {{height: number, width: number} | null} [size]\n     */\n    checkForSizeChanges(size) {\n        if (size === undefined)\n            size = this.$measureSizes();\n        if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {\n            this.$measureNode.style.fontWeight = \"bold\";\n            var boldSize = this.$measureSizes();\n            this.$measureNode.style.fontWeight = \"\";\n            this.$characterSize = size;\n            this.charSizes = Object.create(null);\n            this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;\n            this._emit(\"changeCharacterSize\", {data: size});\n        }\n    }\n\n    $addObserver() {\n        var self = this;\n        this.$observer = new window.ResizeObserver(function(e) {\n            // e[0].contentRect is broken on safari when zoomed;\n            self.checkForSizeChanges();\n        });\n        this.$observer.observe(this.$measureNode);\n    }\n\n    /**\n     * @return {number}\n     */\n    $pollSizeChanges() {\n        if (this.$pollSizeChangesTimer || this.$observer)\n            return this.$pollSizeChangesTimer;\n        var self = this;\n        \n        return this.$pollSizeChangesTimer = event.onIdle(function cb() {\n            self.checkForSizeChanges();\n            event.onIdle(cb, 500);\n        }, 500);\n    }\n\n    /**\n     * @param {boolean} val\n     */\n    setPolling(val) {\n        if (val) {\n            this.$pollSizeChanges();\n        } else if (this.$pollSizeChangesTimer) {\n            clearInterval(this.$pollSizeChangesTimer);\n            this.$pollSizeChangesTimer = 0;\n        }\n    }\n\n    $measureSizes(node) {\n        var size = {\n            height: (node || this.$measureNode).clientHeight,\n            width: (node || this.$measureNode).clientWidth / CHAR_COUNT\n        };\n        \n        // Size and width can be null if the editor is not visible or\n        // detached from the document\n        if (size.width === 0 || size.height === 0)\n            return null;\n        return size;\n    }\n\n    $measureCharWidth(ch) {\n        this.$main.textContent = lang.stringRepeat(ch, CHAR_COUNT);\n        var rect = this.$main.getBoundingClientRect();\n        return rect.width / CHAR_COUNT;\n    }\n    \n    getCharacterWidth(ch) {\n        var w = this.charSizes[ch];\n        if (w === undefined) {\n            w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;\n        }\n        return w;\n    }\n\n    destroy() {\n        clearInterval(this.$pollSizeChangesTimer);\n        if (this.$observer)\n            this.$observer.disconnect();\n        if (this.el && this.el.parentNode)\n            this.el.parentNode.removeChild(this.el);\n    }\n\n    \n    $getZoom(element) {\n        if (!element || !element.parentElement) return 1;\n        return (Number(window.getComputedStyle(element)[\"zoom\"]) || 1) * this.$getZoom(element.parentElement);\n    }\n    \n    $initTransformMeasureNodes() {\n        var t = function(t, l) {\n            return [\"div\", {\n                style: \"position: absolute;top:\" + t + \"px;left:\" + l + \"px;\"\n            }];\n        };\n        this.els = dom.buildDom([t(0, 0), t(L, 0), t(0, L), t(L, L)], this.el);\n    }\n    // general transforms from element coordinates x to screen coordinates u have the form\n    // | m1[0] m2[0] t[0] |   | x |       | u |\n    // | m1[1] m2[1] t[1] | . | y |  == k | v |\n    // | h[0]  h[1]  1    |   | 1 |       | 1 |\n    // this function finds the coeeficients of the matrix using positions of four points\n    //  \n    transformCoordinates(clientPos, elPos) {\n        if (clientPos) {\n            var zoom = this.$getZoom(this.el);\n            clientPos = mul(1 / zoom, clientPos);\n        }\n        function solve(l1, l2, r) {\n            var det = l1[1] * l2[0] - l1[0] * l2[1];\n            return [\n                (-l2[1] * r[0] + l2[0] * r[1]) / det,\n                (+l1[1] * r[0] - l1[0] * r[1]) / det\n            ];\n        }\n        function sub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }\n        function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; }\n        function mul(a, b) { return [a * b[0], a * b[1]]; }\n\n        if (!this.els)\n            this.$initTransformMeasureNodes();\n        \n        function p(el) {\n            var r = el.getBoundingClientRect();\n            return [r.left, r.top];\n        }\n\n        var a = p(this.els[0]);\n        var b = p(this.els[1]);\n        var c = p(this.els[2]);\n        var d = p(this.els[3]);\n\n        var h = solve(sub(d, b), sub(d, c), sub(add(b, c), add(d, a)));\n\n        var m1 = mul(1 + h[0], sub(b, a));\n        var m2 = mul(1 + h[1], sub(c, a));\n        \n        if (elPos) {\n            var x = elPos;\n            var k = h[0] * x[0] / L + h[1] * x[1] / L + 1;\n            var ut = add(mul(x[0], m1), mul(x[1], m2));\n            return  add(mul(1 / k / L, ut), a);\n        }\n        var u = sub(clientPos, a);\n        var f = solve(sub(m1, mul(h[0], u)), sub(m2, mul(h[1], u)), u);\n        return mul(L, f);\n    }\n    \n}\nFontMetrics.prototype.$characterSize = {width: 0, height: 0};\n\noop.implement(FontMetrics.prototype, EventEmitter);\n\nexports.FontMetrics = FontMetrics;\n"
  },
  {
    "path": "src/layer/gutter.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n * @typedef {import(\"../editor\").Editor} Editor\n * @typedef {import(\"../../ace-internal\").Ace.LayerConfig} LayerConfig\n */\n/**\n * @typedef {Object} GutterRenderer\n * @property {(session: EditSession, row: number) => string} getText - Gets the text to display for a given row\n * @property {(session: EditSession, lastLineNumber: number, config: Object) => number} getWidth - Calculates the width needed for the gutter\n * @property {(e: undefined, editor: Editor) => void} [update] - Updates the gutter display\n * @property {(editor: Editor) => void} [attach] - Attaches the renderer to an editor\n * @property {(editor: Editor) => void} [detach] - Detaches the renderer from an editor\n */\n\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar Lines = require(\"./lines\").Lines;\nvar nls = require(\"../config\").nls;\n\nclass Gutter{\n    /**\n     * @param {HTMLElement} parentEl\n     */\n    constructor(parentEl) {\n        this.$showCursorMarker = null;\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_layer ace_gutter-layer\";\n        parentEl.appendChild(this.element);\n        this.setShowFoldWidgets(this.$showFoldWidgets);\n\n        this.gutterWidth = 0;\n\n        this.$annotations = [];\n        this.$updateAnnotations = this.$updateAnnotations.bind(this);\n\n        this.$lines = new Lines(this.element);\n        this.$lines.$offsetCoefficient = 1;\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    setSession(session) {\n        if (this.session)\n            this.session.off(\"change\", this.$updateAnnotations);\n        this.session = session;\n        if (session)\n            session.on(\"change\", this.$updateAnnotations);\n    }\n\n    /**\n     * @param {number} row\n     * @param {string} className\n     */\n    addGutterDecoration(row, className) {\n        if (window.console)\n            console.warn && console.warn(\"deprecated use session.addGutterDecoration\");\n        this.session.addGutterDecoration(row, className);\n    }\n\n    /**\n     * @param {number} row\n     * @param {string} className\n     */\n    removeGutterDecoration(row, className) {\n        if (window.console)\n            console.warn && console.warn(\"deprecated use session.removeGutterDecoration\");\n        this.session.removeGutterDecoration(row, className);\n    }\n\n    /**\n     * @param {any[]} annotations\n     */\n    setAnnotations(annotations) {\n        // iterate over sparse array\n        this.$annotations = [];\n        for (var i = 0; i < annotations.length; i++) {\n            var annotation = annotations[i];\n            var row = annotation.row;\n            var rowInfo = this.$annotations[row];\n            if (!rowInfo)\n                rowInfo = this.$annotations[row] = {text: [], type: [], displayText: []};\n           \n            var annoText = annotation.text;\n            var displayAnnoText = annotation.text;\n            var annoType = annotation.type;\n            annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || \"\";\n            displayAnnoText = displayAnnoText ? displayAnnoText : annotation.html || \"\";\n\n            if (rowInfo.text.indexOf(annoText) === -1){\n                rowInfo.text.push(annoText);\n                rowInfo.type.push(annoType);\n                rowInfo.displayText.push(displayAnnoText);\n            }\n\n            var className = annotation.className;\n            if (className) {\n                rowInfo.className = className;\n            } else if (annoType === \"error\") {\n                rowInfo.className = \" ace_error\";\n            } else if (annoType === \"security\" && !/\\bace_error\\b/.test(rowInfo.className)) {\n                rowInfo.className = \" ace_security\";\n            } else if (annoType === \"warning\" && !/\\bace_(error|security)\\b/.test(rowInfo.className)) {\n                rowInfo.className = \" ace_warning\";\n            } else if (annoType === \"info\" && !rowInfo.className) {\n                rowInfo.className = \" ace_info\";\n            } else if (annoType === \"hint\" && !rowInfo.className) {\n                rowInfo.className = \" ace_hint\";\n            }\n        }\n    }\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.Delta} delta\n     */\n    $updateAnnotations(delta) {\n        if (!this.$annotations.length)\n            return;\n        var firstRow = delta.start.row;\n        var len = delta.end.row - firstRow;\n        if (len === 0) {\n            // do nothing\n        } else if (delta.action == 'remove') {\n            this.$annotations.splice(firstRow, len + 1, null);\n        } else {\n            var args = new Array(len + 1);\n            args.unshift(firstRow, 1);\n            this.$annotations.splice.apply(this.$annotations, args);\n        }\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    update(config) {\n        this.config = config;\n        \n        var session = this.session;\n        var firstRow = config.firstRow;\n        var lastRow = Math.min(config.lastRow + config.gutterOffset,  // needed to compensate for hor scollbar\n            session.getLength() - 1);\n            \n        this.oldLastRow = lastRow;\n        this.config = config;\n        \n        this.$lines.moveContainer(config);\n        this.$updateCursorRow();\n            \n        var fold = session.getNextFoldLine(firstRow);\n        var foldStart = fold ? fold.start.row : Infinity;\n\n        var cell = null;\n        var index = -1;\n        var row = firstRow;\n        \n        while (true) {\n            if (row > foldStart) {\n                row = fold.end.row + 1;\n                fold = session.getNextFoldLine(row, fold);\n                foldStart = fold ? fold.start.row : Infinity;\n            }\n            if (row > lastRow) {\n                while (this.$lines.getLength() > index + 1)\n                    this.$lines.pop();\n                    \n                break;\n            }\n\n            cell = this.$lines.get(++index);\n            if (cell) {\n                cell.row = row;\n            } else {\n                cell = this.$lines.createCell(row, config, this.session, onCreateCell);\n                this.$lines.push(cell);\n            }\n\n            this.$renderCell(cell, config, fold, row);\n            row++;\n        }\n        \n        this._signal(\"afterRender\");\n        this.$updateGutterWidth(config);\n        \n        if (this.$showCursorMarker && this.$highlightGutterLine)\n            this.$updateCursorMarker();\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    $updateGutterWidth(config) {\n        var session = this.session;\n        \n        var gutterRenderer = session.gutterRenderer || this.$renderer;\n        \n        var firstLineNumber = session.$firstLineNumber;\n        var lastLineText = this.$lines.last() ? this.$lines.last().text : \"\";\n        \n        if (this.$fixedWidth || session.$useWrapMode)\n            lastLineText = session.getLength() + firstLineNumber - 1;\n\n        var gutterWidth = gutterRenderer \n            ? gutterRenderer.getWidth(session, lastLineText, config)\n            : lastLineText.toString().length * config.characterWidth;\n        \n        var padding = this.$padding || this.$computePadding();\n        gutterWidth += padding.left + padding.right;\n        if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {\n            this.gutterWidth = gutterWidth;\n            /**@type{any}*/(this.element.parentNode).style.width = \n            this.element.style.width = Math.ceil(this.gutterWidth) + \"px\";\n            this._signal(\"changeGutterWidth\", gutterWidth);\n        }\n    }\n    \n    $updateCursorRow() {\n        if (!this.$highlightGutterLine)\n            return;\n            \n        var position = this.session.selection.getCursor();\n        if (this.$cursorRow === position.row)\n            return;\n        \n        this.$cursorRow = position.row;\n    }\n    \n    updateLineHighlight() {\n        if (this.$showCursorMarker)\n            this.$updateCursorMarker();\n\n        if (!this.$highlightGutterLine)\n            return;\n        var row = this.session.selection.cursor.row;\n        this.$cursorRow = row;\n\n        if (this.$cursorCell && this.$cursorCell.row == row)\n            return;\n        if (this.$cursorCell)\n            this.$cursorCell.element.className = this.$cursorCell.element.className.replace(\"ace_gutter-active-line \", \"\");\n        var cells = this.$lines.cells;\n        this.$cursorCell = null;\n        for (var i = 0; i < cells.length; i++) {\n            var cell = cells[i];\n            if (cell.row >= this.$cursorRow) {\n                if (cell.row > this.$cursorRow) {\n                    var fold = this.session.getFoldLine(this.$cursorRow);\n                    if (i > 0 && fold && fold.start.row == cells[i - 1].row)\n                        cell = cells[i - 1];\n                    else\n                        break;\n                }\n                cell.element.className = \"ace_gutter-active-line \" + cell.element.className;\n                this.$cursorCell = cell;\n                break;\n            }\n        }\n    }\n\n    $updateCursorMarker() {\n        if (!this.session)\n            return;\n        var session = this.session;\n        if (!this.$highlightElement) {\n            this.$highlightElement = dom.createElement(\"div\");\n            this.$highlightElement.className = \"ace_gutter-cursor\";\n            this.$highlightElement.style.pointerEvents = \"none\";\n            this.element.appendChild(this.$highlightElement);\n        }\n        var pos = session.selection.cursor;\n        var config = this.config;\n        var lines = this.$lines;\n\n        var screenTop = config.firstRowScreen * config.lineHeight;\n        var screenPage = Math.floor(screenTop / lines.canvasHeight);\n        var lineTop = session.documentToScreenRow(pos) * config.lineHeight;\n        var top = lineTop - (screenPage * lines.canvasHeight);\n\n        dom.setStyle(this.$highlightElement.style, \"height\", config.lineHeight + \"px\");\n        dom.setStyle(this.$highlightElement.style, \"top\", top + \"px\");\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    scrollLines(config) {\n        var oldConfig = this.config;\n        this.config = config;\n        \n        this.$updateCursorRow();\n        if (this.$lines.pageChanged(oldConfig, config))\n            return this.update(config);\n        \n        this.$lines.moveContainer(config);\n\n        var lastRow = Math.min(config.lastRow + config.gutterOffset,  // needed to compensate for hor scollbar\n            this.session.getLength() - 1);\n        var oldLastRow = this.oldLastRow;\n        this.oldLastRow = lastRow;\n        \n        if (!oldConfig || oldLastRow < config.firstRow)\n            return this.update(config);\n\n        if (lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (oldConfig.firstRow < config.firstRow)\n            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)\n                this.$lines.shift();\n\n        if (oldLastRow > lastRow)\n            for (var row=this.session.getFoldedRowCount(lastRow + 1, oldLastRow); row>0; row--)\n                this.$lines.pop();\n\n        if (config.firstRow < oldConfig.firstRow) {\n            this.$lines.unshift(this.$renderLines(config, config.firstRow, oldConfig.firstRow - 1));\n        }\n\n        if (lastRow > oldLastRow) {\n            this.$lines.push(this.$renderLines(config, oldLastRow + 1, lastRow));\n        }\n        \n        this.updateLineHighlight();\n        \n        this._signal(\"afterRender\");\n        this.$updateGutterWidth(config);\n    }\n\n    /**\n     * @param {LayerConfig} config\n     * @param {number} firstRow\n     * @param {number} lastRow\n     */\n    $renderLines(config, firstRow, lastRow) {\n        var fragment = [];\n        var row = firstRow;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row : Infinity;\n            }\n            if (row > lastRow)\n                break;\n\n            var cell = this.$lines.createCell(row, config, this.session, onCreateCell);\n            this.$renderCell(cell, config, foldLine, row);\n            fragment.push(cell);\n\n            row++;\n        }\n        return fragment;\n    }\n\n\n    /**\n     * @param {any} cell\n     * @param {LayerConfig} config\n     * @param {import(\"../../ace-internal\").Ace.IRange | undefined} fold\n     * @param {number} row\n     */\n    $renderCell(cell, config, fold, row) {\n        var element = cell.element;\n        \n        var session = this.session;\n        \n        var textNode = element.childNodes[0];\n        var foldWidget = element.childNodes[1];\n        var annotationNode = element.childNodes[2];\n        var customWidget = element.childNodes[3];\n        var annotationIconNode = annotationNode.firstChild;\n\n        var firstLineNumber = session.$firstLineNumber;\n        \n        var breakpoints = session.$breakpoints;\n        var decorations = session.$decorations;\n        var gutterRenderer = session.gutterRenderer || this.$renderer;\n        var foldWidgets = this.$showFoldWidgets && session.foldWidgets;\n        var foldStart = fold ? fold.start.row : Number.MAX_VALUE;\n        \n        var lineHeight = config.lineHeight + \"px\";\n\n        var className = this.$useSvgGutterIcons ? \"ace_gutter-cell_svg-icons \" : \"ace_gutter-cell \";\n        var iconClassName = this.$useSvgGutterIcons ? \"ace_icon_svg\" : \"ace_icon\";\n        \n        var rowText = (gutterRenderer\n            ? gutterRenderer.getText(session, row)\n            : row + firstLineNumber).toString();\n\n        if (this.$highlightGutterLine) {\n            if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart &&  this.$cursorRow <= fold.end.row)) {\n                className += \"ace_gutter-active-line \";\n                if (this.$cursorCell != cell) {\n                    if (this.$cursorCell)\n                        this.$cursorCell.element.className = this.$cursorCell.element.className.replace(\"ace_gutter-active-line \", \"\");\n                    this.$cursorCell = cell;\n                }\n            }\n        }\n        \n        if (breakpoints[row])\n            className += breakpoints[row];\n        if (decorations[row])\n            className += decorations[row];\n        if (this.$annotations[row] && row !== foldStart)\n            className += this.$annotations[row].className;\n\n        if (foldWidgets) {\n            var c = foldWidgets[row];\n            // check if cached value is invalidated and we need to recompute\n            if (c == null)\n                c = foldWidgets[row] = session.getFoldWidget(row);\n        }\n\n        if (c) {\n            var foldClass = \"ace_fold-widget ace_\" + c;\n            var isClosedFold = c == \"start\" && row == foldStart && row < fold.end.row;\n            if (isClosedFold) {\n                foldClass += \" ace_closed\";\n                var foldAnnotationClass = \"\";\n                var annotationInFold = false;\n\n                for (var i = row + 1; i <= fold.end.row; i++) {\n                    if (!this.$annotations[i]) continue;\n\n                    if (this.$annotations[i].className === \" ace_error\") {\n                        annotationInFold = true;\n                        foldAnnotationClass = \" ace_error_fold\";\n                        break;\n                    }\n\n                    if (this.$annotations[i].className === \" ace_security\") {\n                        annotationInFold = true;\n                        foldAnnotationClass = \" ace_security_fold\";\n                    } else if (\n                        this.$annotations[i].className === \" ace_warning\" &&\n                        foldAnnotationClass !== \" ace_security_fold\"\n                    ) {\n                        annotationInFold = true;\n                        foldAnnotationClass = \" ace_warning_fold\";\n                    }\n                }\n\n                className += foldAnnotationClass;\n            }\n            else\n                foldClass += \" ace_open\";\n            if (foldWidget.className != foldClass)\n                foldWidget.className = foldClass;\n\n            dom.setStyle(foldWidget.style, \"height\", lineHeight);\n            dom.setStyle(foldWidget.style, \"display\", \"inline-block\");\n\n            // Set a11y properties.\n            foldWidget.setAttribute(\"role\", \"button\");\n            foldWidget.setAttribute(\"tabindex\", \"-1\");\n\n            var foldRange = session.getFoldWidgetRange(row);\n\n            // getFoldWidgetRange is optional to be implemented by fold modes, if not available we fall-back.\n            if (foldRange)\n                foldWidget.setAttribute(\n                    \"aria-label\",\n                    nls(\"gutter.code-folding.range.aria-label\", \"Toggle code folding, rows $0 through $1\", [\n                        foldRange.start.row + 1,\n                        foldRange.end.row + 1\n                    ])\n                );\n            else {\n                if (fold)\n                    foldWidget.setAttribute(\n                        \"aria-label\",\n                        nls(\"gutter.code-folding.closed.aria-label\", \"Toggle code folding, rows $0 through $1\", [\n                            fold.start.row + 1,\n                            fold.end.row + 1\n                        ])\n                    );\n                else\n                    foldWidget.setAttribute(\n                        \"aria-label\",\n                        nls(\"gutter.code-folding.open.aria-label\", \"Toggle code folding, row $0\", [row + 1])\n                    );\n            }\n\n            if (isClosedFold) {\n                foldWidget.setAttribute(\"aria-expanded\", \"false\");\n                foldWidget.setAttribute(\"title\", nls(\"gutter.code-folding.closed.title\", \"Unfold code\"));\n            } else {\n                foldWidget.setAttribute(\"aria-expanded\", \"true\");\n                foldWidget.setAttribute(\"title\", nls(\"gutter.code-folding.open.title\", \"Fold code\"));\n            }\n        } else {\n            if (foldWidget) {\n                dom.setStyle(foldWidget.style, \"display\", \"none\");\n                foldWidget.setAttribute(\"tabindex\", \"0\");\n                foldWidget.removeAttribute(\"role\");\n                foldWidget.removeAttribute(\"aria-label\");\n            }\n        }\n        // fold logic ends here \n        const customWidgetAttributes = this.session.$gutterCustomWidgets[row];\n        if (customWidgetAttributes) {\n            this.$addCustomWidget(row, customWidgetAttributes,cell);\n        }\n        else if (customWidget){\n            this.$removeCustomWidget(row,cell);\n        }\n\n        if (annotationInFold && this.$showFoldedAnnotations){\n            annotationNode.className = \"ace_gutter_annotation\";\n            annotationIconNode.className = iconClassName;\n            annotationIconNode.className += foldAnnotationClass;\n\n            dom.setStyle(annotationIconNode.style, \"height\", lineHeight);\n            dom.setStyle(annotationNode.style, \"display\", \"block\");\n            dom.setStyle(annotationNode.style, \"height\", lineHeight);\n            var ariaLabel;\n            switch(foldAnnotationClass) {\n                case \" ace_error_fold\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.error\", \"Error, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_security_fold\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.security\", \"Security finding, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_warning_fold\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.warning\", \"Warning, read annotations row $0\", [rowText]);\n                    break;\n            }\n            annotationNode.setAttribute(\"aria-label\", ariaLabel);\n            annotationNode.setAttribute(\"tabindex\", \"-1\");\n            annotationNode.setAttribute(\"role\", \"button\");\n        }\n        else if (this.$annotations[row]){\n            annotationNode.className = \"ace_gutter_annotation\";\n            annotationIconNode.className = iconClassName;\n\n            if (this.$useSvgGutterIcons)\n                annotationIconNode.className += this.$annotations[row].className;\n            else \n                element.classList.add(this.$annotations[row].className.replace(\" \", \"\"));\n\n            dom.setStyle(annotationIconNode.style, \"height\", lineHeight);\n            dom.setStyle(annotationNode.style, \"display\", \"block\");\n            dom.setStyle(annotationNode.style, \"height\", lineHeight);\n            var ariaLabel;\n            switch(this.$annotations[row].className) {\n                case \" ace_error\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.error\", \"Error, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_security\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.security\", \"Security finding, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_warning\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.warning\", \"Warning, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_info\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.info\", \"Info, read annotations row $0\", [rowText]);\n                    break;\n\n                case \" ace_hint\":\n                    ariaLabel = nls(\"gutter.annotation.aria-label.hint\", \"Suggestion, read annotations row $0\", [rowText]);\n                    break;\n            }\n            annotationNode.setAttribute(\"aria-label\", ariaLabel);\n            annotationNode.setAttribute(\"tabindex\", \"-1\");\n            annotationNode.setAttribute(\"role\", \"button\");\n        }\n        else {\n            dom.setStyle(annotationNode.style, \"display\", \"none\");\n            annotationNode.removeAttribute(\"aria-label\");\n            annotationNode.removeAttribute(\"role\");\n            annotationNode.setAttribute(\"tabindex\", \"0\");\n        }\n        if (rowText !== textNode.data) {\n            textNode.data = rowText;\n        } \n\n        if (element.className != className)\n            element.className = className;\n        dom.setStyle(cell.element.style, \"height\", this.$lines.computeLineHeight(row, config, session) + \"px\");\n        dom.setStyle(cell.element.style, \"top\", this.$lines.computeLineTop(row, config, session) + \"px\");\n        \n        cell.text = rowText;\n\n        // If there are no annotations or fold widgets in the gutter cell, hide it from assistive tech.\n        if (annotationNode.style.display === \"none\" && foldWidget.style.display === \"none\" && !customWidgetAttributes)\n            cell.element.setAttribute(\"aria-hidden\", true);\n        else\n            cell.element.setAttribute(\"aria-hidden\", false);\n        \n        return cell;\n    }\n\n    /**\n     * @param {boolean} highlightGutterLine\n     */\n    setHighlightGutterLine(highlightGutterLine) {\n        this.$highlightGutterLine = highlightGutterLine;\n        if (!highlightGutterLine && this.$highlightElement) {\n            this.$highlightElement.remove();\n            this.$highlightElement = null;\n        }\n    }\n\n    /**\n     * @param {boolean} show\n     */\n    setShowLineNumbers(show) {\n        /**@type{GutterRenderer}*/\n        this.$renderer = !show && {\n            getWidth: function() {return 0;},\n            getText: function() {return \"\";}\n        };\n    }\n    \n    getShowLineNumbers() {\n        return this.$showLineNumbers;\n    }\n\n    /**\n     * @param {boolean} [show]\n     */\n    setShowFoldWidgets(show) {\n        if (show)\n            dom.addCssClass(this.element, \"ace_folding-enabled\");\n        else\n            dom.removeCssClass(this.element, \"ace_folding-enabled\");\n\n        this.$showFoldWidgets = show;\n        this.$padding = null;\n    }\n    \n    getShowFoldWidgets() {\n        return this.$showFoldWidgets;\n    }\n    \n    /**\n     * Hides the fold widget/icon from a specific row in the gutter\n     * @param {number} row The row number from which to hide the fold icon\n     * @param {any} cell - Gutter cell \n     * @experimental\n     */\n    $hideFoldWidget(row, cell) {\n        const rowCell = cell || this.$getGutterCell(row);\n        if (rowCell && rowCell.element) {\n            const foldWidget = rowCell.element.childNodes[1];\n            if (foldWidget) {\n                dom.setStyle(foldWidget.style, \"display\", \"none\");\n            }\n        }\n    }\n\n    /**\n     * Shows the fold widget/icon from a specific row in the gutter\n     * @param {number} row The row number from which to show the fold icon\n     * @param {any} cell - Gutter cell \n     * @experimental\n     */\n    $showFoldWidget(row,cell) {\n        const rowCell = cell || this.$getGutterCell(row);\n        if (rowCell && rowCell.element) {\n            const foldWidget = rowCell.element.childNodes[1];\n            if (foldWidget && this.session.foldWidgets && this.session.foldWidgets[rowCell.row]) {\n                dom.setStyle(foldWidget.style, \"display\", \"inline-block\");\n            }\n        }\n    }\n\n    /**\n    * Retrieves the gutter cell element at the specified cursor row position.\n    * @param {number} row - The row number in the editor where the gutter cell is located starts from 0\n    * @returns {HTMLElement|undefined} The gutter cell element at the specified row, or undefined if not found\n    * @experimental\n    */\n    $getGutterCell(row) {\n        var cells = this.$lines.cells;\n        var min = 0;\n        var max = cells.length - 1;\n        \n        if (row < cells[0].row || row > cells[max].row)\n            return;\n\n        while (min <= max) {\n            var mid = Math.floor((min + max) / 2);\n            var cell = cells[mid];\n            if (cell.row > row) {\n                max = mid - 1;\n            } else if (cell.row < row) {\n                min = mid + 1;\n            } else {\n                return cell;\n            }\n        }\n        return cell;\n    }\n\n    /**\n    * Displays a custom widget for a specific row\n    * @param {number} row - The row number where the widget will be displayed\n    * @param {Object} attributes - Configuration attributes for the widget\n    * @param {string} attributes.className - CSS class name for styling the widget\n    * @param {string} attributes.label - Text label to display in the widget\n    * @param {string} attributes.title - Tooltip text for the widget\n    * @param {Object} attributes.callbacks - Event callback functions for the widget e.g onClick; \n    * @param {any} cell - Gutter cell \n    * @returns {void}\n    * @experimental\n    */\n    $addCustomWidget(row, {className, label, title, callbacks}, cell) {\n        this.session.$gutterCustomWidgets[row] = {className, label, title, callbacks};\n        this.$hideFoldWidget(row,cell);\n\n        // cell is required because when cached cell is used to render, $lines won't have that cell\n        const rowCell = cell || this.$getGutterCell(row);\n        if (rowCell && rowCell.element) {\n            let customWidget = rowCell.element.querySelector(\".ace_custom-widget\");\n            // deleting the old custom widget to remove the old click event listener\n            if (customWidget) {\n                customWidget.remove();\n            }\n\n            customWidget = dom.createElement(\"span\");\n            customWidget.className = `ace_custom-widget ${className}`;\n            customWidget.setAttribute(\"tabindex\", \"-1\");\n            customWidget.setAttribute(\"role\", 'button');\n            customWidget.setAttribute(\"aria-label\", label);\n            customWidget.setAttribute(\"title\", title);\n            dom.setStyle(customWidget.style, \"display\", \"inline-block\");\n            dom.setStyle(customWidget.style, \"height\", \"inherit\");\n            \n            if (callbacks&& callbacks.onClick) {\n                customWidget.addEventListener(\"click\", (e) => {\n                    callbacks.onClick(e, row);\n                    e.stopPropagation();\n                });\n            }\n\n            rowCell.element.appendChild(customWidget);\n        }\n    }\n    \n    /**\n    * Remove a custom widget for a specific row\n    * @param {number} row - The row number where the widget will be removed\n    * @param {any} cell - Gutter cell \n    * @returns {void}\n    * @experimental\n    */\n    $removeCustomWidget(row, cell) {\n        delete this.session.$gutterCustomWidgets[row];\n        this.$showFoldWidget(row,cell);\n\n        // cell is required because when cached cell is used to render, $lines won't have that cell\n        const rowCell = cell || this.$getGutterCell(row);\n        if (rowCell && rowCell.element) {\n            const customWidget = rowCell.element.querySelector(\".ace_custom-widget\");\n            if (customWidget) {\n                rowCell.element.removeChild(customWidget);\n            }\n        }\n    }\n\n    $computePadding() {\n        if (!this.element.firstChild)\n            return {left: 0, right: 0};\n        var style = dom.computedStyle(/**@type{Element}*/(this.element.firstChild));\n        this.$padding = {};\n        this.$padding.left = (parseInt(style.borderLeftWidth) || 0)\n            + (parseInt(style.paddingLeft) || 0) + 1;\n        this.$padding.right = (parseInt(style.borderRightWidth) || 0)\n            + (parseInt(style.paddingRight) || 0);\n        return this.$padding;\n    }\n\n    /**\n     * @param {{ x: number; }} point\n     */\n    getRegion(point) {\n        var padding = this.$padding || this.$computePadding();\n        var rect = this.element.getBoundingClientRect();\n        if (point.x < padding.left + rect.left)\n            return \"markers\";\n        if (this.$showFoldWidgets && point.x > rect.right - padding.right)\n            return \"foldWidgets\";\n    }\n\n}\n\nGutter.prototype.$fixedWidth = false;\nGutter.prototype.$highlightGutterLine = true;\nGutter.prototype.$renderer = undefined;\nGutter.prototype.$showLineNumbers = true;\nGutter.prototype.$showFoldWidgets = true;\n\noop.implement(Gutter.prototype, EventEmitter);\n\nfunction onCreateCell(element) {\n    var textNode = document.createTextNode('');\n    element.appendChild(textNode);\n    \n    var foldWidget = dom.createElement(\"span\");\n    element.appendChild(foldWidget);\n\n    var annotationNode = dom.createElement(\"span\");\n    element.appendChild(annotationNode);\n\n    var annotationIconNode = dom.createElement(\"span\");\n    annotationNode.appendChild(annotationIconNode);\n    \n    return element;\n}\n\nexports.Gutter = Gutter;\n"
  },
  {
    "path": "src/layer/gutter_test.js",
    "content": "\"use strict\";\n\nif (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\nvar keys = require(\"../lib/keys\");\n\nrequire(\"../multi_select\");\nrequire(\"../theme/textmate\");\nvar Editor = require(\"../editor\").Editor;\nvar Mode = require(\"../mode/java\").Mode;\nvar VirtualRenderer = require(\"../virtual_renderer\").VirtualRenderer;\nvar assert = require(\"../test/assertions\");\nvar lang = require(\"../lib/lang\");\n\nfunction emit(keyCode) {\n    var data = {bubbles: true, keyCode};\n    var event = new KeyboardEvent(\"keydown\", data);\n\n    var el = document.activeElement;\n    el.dispatchEvent(event);\n}\n\nmodule.exports = {\n    setUp: function() {\n        this.editor = new Editor(new VirtualRenderer());\n        this.editor.container.style.position = \"absolute\";\n        this.editor.container.style.height = \"500px\";\n        this.editor.container.style.width = \"500px\";\n        this.editor.container.style.left = \"50px\";\n        this.editor.container.style.top = \"10px\";\n        document.body.appendChild(this.editor.container);\n    },\n    \"test: custom icon replaces the fold icon sucessfully\": async function (done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the fold widget.\n        emit(keys[\"enter\"]);\n        editor.renderer.$gutterLayer.$addCustomWidget(13, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\"\n        });\n\n        await lang.sleep(20);\n        // Check that custom widget is shown\n        editor.renderer.$loop._flush();\n        console.log(lines.cells[13].element.childNodes[2].className);\n        assert.ok(/ace_users_css/.test(lines.cells[13].element.childNodes[3].className));\n        // fold widget is not shown\n        assert.equal(lines.cells[13].element.childNodes[1].style.display, \"none\");\n\n        // After escape focus should be back to the gutter.\n        emit(keys[\"escape\"]);\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n    \"test: after hiding custom icon fold icon is visible automatically\": async function (done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the custom widget.\n        emit(keys[\"enter\"]);\n        editor.renderer.$gutterLayer.$addCustomWidget(0, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\"\n        });\n        editor.renderer.$gutterLayer.$removeCustomWidget(0);\n\n        await lang.sleep(20);\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[1]);\n\n        await lang.sleep(20);\n        // Check that custom widget is hidden.\n        editor.renderer.$loop._flush();\n        assert.equal(lines.cells[0].element.childNodes[3], undefined);\n        assert.equal(lines.cells[0].element.childNodes[1].style.display, \"inline-block\");\n        assert.ok(/ace_open/.test(lines.cells[0].element.childNodes[1].className));\n\n        // After escape focus should be back to the gutter.\n        emit(keys[\"escape\"]);\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n    \"test: folding is kept consistent when custom widget is shown first and then hidden\": async function (done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the fold widget.\n        emit(keys[\"enter\"]);\n\n        await lang.sleep(20);\n        assert.equal(document.activeElement, lines.cells[0].element.childNodes[1]);\n\n        // Click the fold widget to fold the lines.\n        emit(keys[\"enter\"]);\n        editor.renderer.$gutterLayer.$addCustomWidget(0, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\"\n        });\n        editor.renderer.$gutterLayer.$removeCustomWidget(0);\n\n        await lang.sleep(20);\n        // Check that custom widget is hidden.\n        editor.renderer.$loop._flush();\n        assert.equal(lines.cells[0].element.childNodes[3], undefined);\n        assert.ok(/ace_closed/.test(lines.cells[0].element.childNodes[1].className));\n\n        // After escape focus should be back to the gutter.\n        emit(keys[\"escape\"]);\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n\n    \"test: onClick callback is getting called and updated when updating the custom widget\": async function (done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\\n\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.setOption(\"enableKeyboardAccessibility\", true);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n\n        // Set focus to the gutter div.\n        editor.renderer.$gutter.focus();\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        // Focus on the fold widget.\n        emit(keys[\"enter\"]);\n\n        let firstCallbackCalledCount=0;\n        const firstCallback = () =>{ \n            firstCallbackCalledCount++;\n        };\n        let secondCallbackCalledCount=0;\n        const secondCallback = () =>{\n            secondCallbackCalledCount++;\n        };\n        editor.renderer.$gutterLayer.$addCustomWidget(0, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\",\n            callbacks: {\n                onClick: firstCallback\n            }\n        });\n        editor.renderer.$gutterLayer.$addCustomWidget(0, {\n            className: \"ace_users_css\",\n            label: \"Open_label\",\n            title: \"Open_title\",\n            callbacks: {\n                onClick: secondCallback\n            }\n        });\n        // clicking the custom widget\n        lines.cells[0].element.childNodes[3].dispatchEvent(new CustomEvent(\"click\"));\n\n        await lang.sleep(20);\n        // Check that custom widget is hidden.\n        editor.renderer.$loop._flush();\n        assert.equal(firstCallbackCalledCount, 0);\n        assert.equal(secondCallbackCalledCount, 1);\n        // After escape focus should be back to the gutter.\n        emit(keys[\"escape\"]);\n        assert.equal(document.activeElement, editor.renderer.$gutter);\n\n        done();\n    },\n    tearDown: function () {\n        this.editor.destroy();\n        document.body.removeChild(this.editor.container);\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/layer/lines.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n * @typedef {import(\"../../ace-internal\").Ace.LayerConfig} LayerConfig\n */\nvar dom = require(\"../lib/dom\");\n\nclass Lines {\n    /**\n     * @param {HTMLElement} element\n     * @param {number} [canvasHeight]\n     */\n    constructor(element, canvasHeight) {\n        this.element = element;\n        this.canvasHeight = canvasHeight || 500000;\n        this.element.style.height = (this.canvasHeight * 2) + \"px\";\n\n        this.cells = [];\n        this.cellCache = [];\n        this.$offsetCoefficient = 0;\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    moveContainer(config) {\n        dom.translate(this.element, 0, -((config.firstRowScreen * config.lineHeight) % this.canvasHeight) - config.offset * this.$offsetCoefficient);\n    }\n\n    /**\n     * @param {LayerConfig} oldConfig\n     * @param {LayerConfig} newConfig\n     */\n    pageChanged(oldConfig, newConfig) {\n        return (\n            Math.floor((oldConfig.firstRowScreen * oldConfig.lineHeight) / this.canvasHeight) !==\n            Math.floor((newConfig.firstRowScreen * newConfig.lineHeight) / this.canvasHeight)\n        );\n    }\n\n    /**\n     * @param {number} row\n     * @param {Partial<LayerConfig>} config\n     * @param {EditSession} session\n     */\n    computeLineTop(row, config, session) {\n        var screenTop = config.firstRowScreen * config.lineHeight;\n        var screenPage = Math.floor(screenTop / this.canvasHeight);\n        var lineTop = session.documentToScreenRow(row, 0) * config.lineHeight;\n        return lineTop - (screenPage * this.canvasHeight);\n    }\n\n    /**\n     * @param {number} row\n     * @param {LayerConfig} config\n     * @param {EditSession} session\n     */\n    computeLineHeight(row, config, session) {\n        return config.lineHeight * session.getRowLineCount(row);\n    }\n    \n    getLength() {\n        return this.cells.length;\n    }\n\n    /**\n     * @param {number} index\n     */\n    get(index) {\n        return this.cells[index];\n    }\n    \n    shift() {\n        this.$cacheCell(this.cells.shift());\n    }\n    \n    pop() {\n        this.$cacheCell(this.cells.pop());\n    }\n    \n    push(cell) {\n        if (Array.isArray(cell)) {\n            this.cells.push.apply(this.cells, cell);\n            var fragment = dom.createFragment(this.element);\n            for (var i=0; i<cell.length; i++) {\n                fragment.appendChild(cell[i].element);\n            }\n            this.element.appendChild(fragment);\n        } else {\n            this.cells.push(cell);\n            this.element.appendChild(cell.element);\n        }\n    }\n    \n    unshift(cell) {\n        if (Array.isArray(cell)) {\n            this.cells.unshift.apply(this.cells, cell);\n            var fragment = dom.createFragment(this.element);\n            for (var i=0; i<cell.length; i++) {\n                fragment.appendChild(cell[i].element);\n            }\n            if (this.element.firstChild)\n                this.element.insertBefore(fragment, this.element.firstChild);\n            else\n                this.element.appendChild(fragment);\n        } else {\n            this.cells.unshift(cell);\n            this.element.insertAdjacentElement(\"afterbegin\", cell.element);\n        }\n    }\n    \n    last() {\n        if (this.cells.length)\n            return this.cells[this.cells.length-1];\n        else\n            return null;\n    }\n    \n    $cacheCell(cell) {\n        if (!cell)\n            return;\n            \n        cell.element.remove();\n        this.cellCache.push(cell);\n    }\n    \n    createCell(row, config, session, initElement) {\n        var cell = this.cellCache.pop();\n        if (!cell) {\n            var element = dom.createElement(\"div\");\n            if (initElement)\n                initElement(element);\n            \n            this.element.appendChild(element);\n            \n            cell = {\n                element: element,\n                text: \"\",\n                row: row\n            };\n        }\n        cell.row = row;\n        \n        return cell;\n    }\n    \n}\n\nexports.Lines = Lines;\n"
  },
  {
    "path": "src/layer/marker.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n * @typedef {import(\"../../ace-internal\").Ace.LayerConfig} LayerConfig\n */\nvar Range = require(\"../range\").Range;\nvar dom = require(\"../lib/dom\");\n\n\nclass Marker {\n    /**\n     * @param {HTMLElement} parentEl\n     */\n    constructor(parentEl) {\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_layer ace_marker-layer\";\n        parentEl.appendChild(this.element);\n    }\n\n    /**\n     * @param {number} padding\n     */\n    setPadding(padding) {\n        this.$padding = padding;\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    setSession(session) {\n        this.session = session;\n    }\n\n    /**\n     * @param {{ [x: number]: import(\"../../ace-internal\").Ace.MarkerLike; }} markers\n     */\n    setMarkers(markers) {\n        this.markers = markers;\n    }\n\n    /**\n     * @param {string} className\n     * @param {string} css\n     */\n    elt(className, css) {\n        /**@type {any}*/\n        var x = this.i != -1 && this.element.childNodes[this.i];\n        if (!x) {\n            x = document.createElement(\"div\");\n            this.element.appendChild(x);\n            this.i = -1;\n        } else {\n            this.i++;\n        }\n        x.style.cssText = css;\n        x.className = className;\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    update(config) {\n        if (!config) return;\n\n        this.config = config;\n\n        this.i = 0;\n        var html;\n        for (var key in this.markers) {\n            var marker = this.markers[key];\n\n            if (!marker.range) {\n                marker.update(html, this, this.session, config);\n                continue;\n            }\n\n            var range = marker.range.clipRows(config.firstRow, config.lastRow);\n            if (range.isEmpty()) continue;\n\n            range = range.toScreenRange(this.session);\n            if (marker.renderer) {\n                var top = this.$getTop(range.start.row, config);\n                var left = this.$padding + range.start.column * config.characterWidth;\n                marker.renderer(html, range, left, top, config);\n            } else if (marker.type == \"fullLine\") {\n                this.drawFullLineMarker(html, range, marker.clazz, config);\n            } else if (marker.type == \"screenLine\") {\n                this.drawScreenLineMarker(html, range, marker.clazz, config);\n            } else if (range.isMultiLine()) {\n                if (marker.type == \"text\")\n                    this.drawTextMarker(html, range, marker.clazz, config);\n                else\n                    this.drawMultiLineMarker(html, range, marker.clazz, config);\n            } else {\n                this.drawSingleLineMarker(html, range, marker.clazz + \" ace_start\" + \" ace_br15\", config);\n            }\n        }\n        if (this.i !=-1) {\n            while (this.i < this.element.childElementCount)\n                this.element.removeChild(this.element.lastChild);\n        }\n    }\n\n    /**\n     * @param {number} row\n     * @param {Partial<LayerConfig>} layerConfig\n     */\n    $getTop(row, layerConfig) {\n        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;\n    }\n\n\n    // Draws a marker, which spans a range of text on multiple lines \n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {Partial<LayerConfig>} layerConfig\n     * @param {string} [extraStyle]\n     */\n    drawTextMarker(stringBuilder, range, clazz, layerConfig, extraStyle) {\n        var session = this.session;\n        var start = range.start.row;\n        var end = range.end.row;\n        var row = start;\n        var prev = 0; \n        var curr = 0;\n        var next = session.getScreenLastRowColumn(row);\n        var lineRange = new Range(row, range.start.column, row, curr);\n        for (; row <= end; row++) {\n            lineRange.start.row = lineRange.end.row = row;\n            lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row);\n            lineRange.end.column = next;\n            prev = curr;\n            curr = next;\n            next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column;\n            this.drawSingleLineMarker(stringBuilder, lineRange, \n                clazz + (row == start  ? \" ace_start\" : \"\") + \" ace_br\"\n                    + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end),\n                layerConfig, row == end ? 0 : 1, extraStyle);\n        }\n    }\n\n    // Draws a multi line marker, where lines span the full width\n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {LayerConfig} config\n     * @param {string} [extraStyle]\n     */\n    drawMultiLineMarker(stringBuilder, range, clazz, config, extraStyle) {\n        // from selection start to the end of the line\n        var padding = this.$padding;\n        var height = config.lineHeight;\n        var top = this.$getTop(range.start.row, config);\n        var left = padding + range.start.column * config.characterWidth;\n        extraStyle = extraStyle || \"\";\n\n        if (this.session.$bidiHandler.isBidiRow(range.start.row)) {\n           var range1 = range.clone();\n           range1.end.row = range1.start.row;\n           range1.end.column = this.session.getLine(range1.start.row).length;\n           this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + \" ace_br1 ace_start\", config, null, extraStyle);\n        } else {\n            this.elt(\n                clazz + \" ace_br1 ace_start\",\n                \"height:\"+ height+ \"px;\"+ \"right:\" + padding + \"px;\"+ \"top:\"+top+ \"px;left:\"+ left+ \"px;\" + (extraStyle || \"\")\n            );\n        }\n        // from start of the last line to the selection end\n        if (this.session.$bidiHandler.isBidiRow(range.end.row)) {\n           var range1 = range.clone();\n           range1.start.row = range1.end.row;\n           range1.start.column = 0;\n           this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + \" ace_br12\", config, null, extraStyle);\n        } else {\n            top = this.$getTop(range.end.row, config);\n            var width = range.end.column * config.characterWidth;\n\n            this.elt(\n                clazz + \" ace_br12\",\n                \"height:\"+ height+ \"px;\"+\n                \"width:\"+ width+ \"px;\"+\n                \"top:\"+ top+ \"px;\"+\n                \"left:\"+ padding+ \"px;\"+ (extraStyle || \"\")\n            );\n        }\n        // all the complete lines\n        height = (range.end.row - range.start.row - 1) * config.lineHeight;\n        if (height <= 0)\n            return;\n        top = this.$getTop(range.start.row + 1, config);\n        \n        var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);\n\n        this.elt(\n            clazz + (radiusClass ? \" ace_br\" + radiusClass : \"\"),\n            \"height:\"+ height+ \"px;\"+\n            \"right:\" + padding + \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:\"+ padding+ \"px;\"+ (extraStyle || \"\")\n        );\n    }\n\n    // Draws a marker which covers part or whole width of a single screen line\n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {Partial<LayerConfig>} config\n     * @param {number} [extraLength]\n     * @param {string} [extraStyle]\n     */\n    drawSingleLineMarker(stringBuilder, range, clazz, config, extraLength, extraStyle) {\n        if (this.session.$bidiHandler.isBidiRow(range.start.row))\n            return this.drawBidiSingleLineMarker(stringBuilder, range, clazz, config, extraLength, extraStyle);\n        var height = config.lineHeight;\n        var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;\n\n        var top = this.$getTop(range.start.row, config);\n        var left = this.$padding + range.start.column * config.characterWidth;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"width:\"+ width+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:\"+ left+ \"px;\"+ (extraStyle || \"\")\n        );\n    }\n\n    // Draws Bidi marker which covers part or whole width of a single screen line\n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {Partial<LayerConfig>} config\n     * @param {number} extraLength\n     * @param {string} extraStyle\n     */\n    drawBidiSingleLineMarker(stringBuilder, range, clazz, config, extraLength, extraStyle) {\n        var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding;\n        var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);\n\n        selections.forEach(function(selection) {\n            this.elt(\n                clazz,\n                \"height:\" + height + \"px;\" +\n                \"width:\" + (selection.width + (extraLength || 0)) + \"px;\" +\n                \"top:\" + top + \"px;\" +\n                \"left:\" + (padding + selection.left) + \"px;\" + (extraStyle || \"\")\n            );\n        }, this);\n    }\n\n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {Partial<LayerConfig>} config\n     * @param {undefined} [extraStyle]\n     */\n    drawFullLineMarker(stringBuilder, range, clazz, config, extraStyle) {\n        var top = this.$getTop(range.start.row, config);\n        var height = config.lineHeight;\n        if (range.start.row != range.end.row)\n            height += this.$getTop(range.end.row, config) - top;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:0;right:0;\"+ (extraStyle || \"\")\n        );\n    }\n\n    /**\n     * @param {undefined} stringBuilder\n     * @param {Range} range\n     * @param {string} clazz\n     * @param {Partial<LayerConfig>} config\n     * @param {undefined} [extraStyle]\n     */\n    drawScreenLineMarker(stringBuilder, range, clazz, config, extraStyle) {\n        var top = this.$getTop(range.start.row, config);\n        var height = config.lineHeight;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:0;right:0;\"+ (extraStyle || \"\")\n        );\n    }\n\n}\n\nMarker.prototype.$padding = 0;\n\nfunction getBorderClass(tl, tr, br, bl) {\n    return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0);\n}\n\nexports.Marker = Marker;\n"
  },
  {
    "path": "src/layer/text.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../../ace-internal\").Ace.LayerConfig} LayerConfig\n * @typedef {import(\"../edit_session\").EditSession} EditSession\n */\nvar oop = require(\"../lib/oop\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar Lines = require(\"./lines\").Lines;\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar nls = require(\"../config\").nls;\nvar isTextToken = require(\"./text_util\").isTextToken;\n\nclass Text {\n    /**\n     * @param {HTMLElement} parentEl\n     */\n    constructor(parentEl) {\n        this.dom = dom;\n        this.element = this.dom.createElement(\"div\");\n        this.element.className = \"ace_layer ace_text-layer\";\n        parentEl.appendChild(this.element);\n        this.$updateEolChar = this.$updateEolChar.bind(this);\n        this.$lines = new Lines(this.element);\n    }\n    \n    $updateEolChar() {\n        var doc = this.session.doc;\n        var unixMode = doc.getNewLineCharacter() == \"\\n\" && doc.getNewLineMode() != \"windows\";\n        var EOL_CHAR = unixMode ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF;\n        if (this.EOL_CHAR != EOL_CHAR) {\n            this.EOL_CHAR = EOL_CHAR;\n            return true;\n        }\n    }\n\n    /**\n     * @param {number} padding\n     */\n    setPadding(padding) {\n        this.$padding = padding;\n        this.element.style.margin = \"0 \" + padding + \"px\";\n    }\n    \n    /**\n     * @returns {number}\n     */\n    getLineHeight() {\n        return this.$fontMetrics.$characterSize.height || 0;\n    }\n\n    /**\n     * @returns {number}\n     */\n    getCharacterWidth() {\n        return this.$fontMetrics.$characterSize.width || 0;\n    }\n\n    /**\n     * @param {any} measure\n     */\n    $setFontMetrics(measure) {\n        this.$fontMetrics = measure;\n        this.$fontMetrics.on(\"changeCharacterSize\",\n            /**\n             * @this {Text}\n             */\n            function (e) {\n                this._signal(\"changeCharacterSize\", e);\n        }.bind(this));\n        this.$pollSizeChanges();\n    }\n\n    checkForSizeChanges() {\n        this.$fontMetrics.checkForSizeChanges();\n    }\n    $pollSizeChanges() {\n        return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    setSession(session) {\n        /**@type {EditSession}*/\n        this.session = session;\n        if (session)\n            this.$computeTabString();\n    }\n\n    /**\n     * @param {string} showInvisibles\n     */\n    setShowInvisibles(showInvisibles) {\n        if (this.showInvisibles == showInvisibles)\n            return false;\n\n        this.showInvisibles = showInvisibles;\n        if (typeof showInvisibles == \"string\") {\n            this.showSpaces = /tab/i.test(showInvisibles);\n            this.showTabs = /space/i.test(showInvisibles);\n            this.showEOL = /eol/i.test(showInvisibles);\n        } else {\n            this.showSpaces = this.showTabs = this.showEOL = showInvisibles;\n        }\n        this.$computeTabString();\n        return true;\n    }\n\n    /**\n     * @param {boolean} display\n     */\n    setDisplayIndentGuides(display) {\n        if (this.displayIndentGuides == display)\n            return false;\n\n        this.displayIndentGuides = display;\n        this.$computeTabString();\n        return true;\n    }\n\n    /**\n     * @param {boolean} highlight\n     */\n    setHighlightIndentGuides(highlight) {\n        if (this.$highlightIndentGuides === highlight) return false;\n\n        this.$highlightIndentGuides = highlight;\n        return highlight;\n    }\n    \n    $computeTabString() {\n        var tabSize = this.session.getTabSize();\n        this.tabSize = tabSize;\n        /**@type{any}*/var tabStr = this.$tabStrings = [0];\n        for (var i = 1; i < tabSize + 1; i++) {\n            if (this.showTabs) {\n                var span = this.dom.createElement(\"span\");\n                span.className = \"ace_invisible ace_invisible_tab\";\n                span.textContent = lang.stringRepeat(this.TAB_CHAR, i);\n                tabStr.push(span);\n            } else {\n                tabStr.push(this.dom.createTextNode(lang.stringRepeat(\" \", i), this.element));\n            }\n        }\n        if (this.displayIndentGuides) {\n            this.$indentGuideRe =  /\\s\\S| \\t|\\t |\\s$/;\n            var className = \"ace_indent-guide\";\n            var spaceClass = this.showSpaces ? \" ace_invisible ace_invisible_space\" : \"\";\n            var spaceContent = this.showSpaces\n                ? lang.stringRepeat(this.SPACE_CHAR, this.tabSize)\n                : lang.stringRepeat(\" \", this.tabSize);\n\n            var tabClass = this.showTabs ? \" ace_invisible ace_invisible_tab\" : \"\";\n            var tabContent = this.showTabs\n                ? lang.stringRepeat(this.TAB_CHAR, this.tabSize)\n                : spaceContent;\n\n            var span = this.dom.createElement(\"span\");\n            span.className = className + spaceClass;\n            span.textContent = spaceContent;\n            this.$tabStrings[\" \"] = span;\n\n            var span = this.dom.createElement(\"span\");\n            span.className = className + tabClass;\n            span.textContent = tabContent;\n            this.$tabStrings[\"\\t\"] = span;\n        }\n    }\n\n    /**\n     * @param {LayerConfig} config\n     * @param {number} firstRow\n     * @param {number} lastRow\n     */\n    updateLines(config, firstRow, lastRow) {\n        // Due to wrap line changes there can be new lines if e.g.\n        // the line to updated wrapped in the meantime.\n        if (this.config.lastRow != config.lastRow ||\n            this.config.firstRow != config.firstRow) {\n            return this.update(config);\n        }\n\n        this.config = config;\n\n        var first = Math.max(firstRow, config.firstRow);\n        var last = Math.min(lastRow, config.lastRow);\n\n        var lineElements = this.element.childNodes;\n        var lineElementsIdx = 0;\n\n        for (var row = config.firstRow; row < first; row++) {\n            var foldLine = this.session.getFoldLine(row);\n            if (foldLine) {\n                if (foldLine.containsRow(first)) {\n                    first = foldLine.start.row;\n                    break;\n                } else {\n                    row = foldLine.end.row;\n                }\n            }\n            lineElementsIdx ++;\n        }\n\n        var heightChanged = false;\n        var row = first;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row :Infinity;\n            }\n            if (row > last)\n                break;\n\n            /**@type{any}*/var lineElement = lineElements[lineElementsIdx++];\n            if (lineElement) {\n                this.dom.removeChildren(lineElement);\n                this.$renderLine(\n                    lineElement, row, row == foldStart ? foldLine : false\n                );\n\n                if (heightChanged)\n                    lineElement.style.top = this.$lines.computeLineTop(row, config, this.session) + \"px\";\n\n                var height = (config.lineHeight * this.session.getRowLength(row)) + \"px\";\n                if (lineElement.style.height != height) {\n                    heightChanged = true;\n                    lineElement.style.height = height;\n                }\n            }\n            row++;\n        }\n        if (heightChanged) {\n            while (lineElementsIdx < this.$lines.cells.length) {\n                var cell = this.$lines.cells[lineElementsIdx++];\n                cell.element.style.top = this.$lines.computeLineTop(cell.row, config, this.session) + \"px\";\n            }\n        }\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    scrollLines(config) {\n        var oldConfig = this.config;\n        this.config = config;\n\n        if (this.$lines.pageChanged(oldConfig, config))\n            return this.update(config);\n\n        this.$lines.moveContainer(config);\n\n        var lastRow = config.lastRow;\n        var oldLastRow = oldConfig ? oldConfig.lastRow : -1;\n\n        if (!oldConfig || oldLastRow < config.firstRow)\n            return this.update(config);\n\n        if (lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (!oldConfig || oldConfig.lastRow < config.firstRow)\n            return this.update(config);\n\n        if (config.lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (oldConfig.firstRow < config.firstRow)\n            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)\n                this.$lines.shift();\n\n        if (oldConfig.lastRow > config.lastRow)\n            for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)\n                this.$lines.pop();\n\n        if (config.firstRow < oldConfig.firstRow) {\n            this.$lines.unshift(this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1));\n        }\n\n        if (config.lastRow > oldConfig.lastRow) {\n            this.$lines.push(this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow));\n        }\n        this.$highlightIndentGuide();\n    }\n\n    /**\n     * @param {LayerConfig} config\n     * @param {number} firstRow\n     * @param {number} lastRow\n     */\n    $renderLinesFragment(config, firstRow, lastRow) {\n        var fragment = [];\n        var row = firstRow;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row : Infinity;\n            }\n            if (row > lastRow)\n                break;\n\n            var line = this.$lines.createCell(row, config, this.session);\n\n            var lineEl = line.element;\n            this.dom.removeChildren(lineEl);\n            dom.setStyle(lineEl.style, \"height\", this.$lines.computeLineHeight(row, config, this.session) + \"px\");\n            dom.setStyle(lineEl.style, \"top\", this.$lines.computeLineTop(row, config, this.session) + \"px\");\n\n            // Get the tokens per line as there might be some lines in between\n            // beeing folded.\n            this.$renderLine(lineEl, row, row == foldStart ? foldLine : false);\n\n            if (this.$useLineGroups()) {\n                lineEl.className = \"ace_line_group\";\n            } else {\n                lineEl.className = \"ace_line\";\n            }\n            fragment.push(line);\n\n            row++;\n        }\n        return fragment;\n    }\n\n    /**\n     * @param {LayerConfig} config\n     */\n    update(config) {\n        this.$lines.moveContainer(config);\n\n        this.config = config;\n\n        var firstRow = config.firstRow;\n        var lastRow = config.lastRow;\n\n        var lines = this.$lines;\n        while (lines.getLength())\n            lines.pop();\n\n        lines.push(this.$renderLinesFragment(config, firstRow, lastRow));\n    }\n\n    $renderToken(parent, screenColumn, token, value) {\n        var self = this;\n        var re = /(\\t)|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\uFEFF\\uFFF9-\\uFFFC\\u2066\\u2067\\u2068\\u202A\\u202B\\u202D\\u202E\\u202C\\u2069\\u2060\\u2061\\u2062\\u2063\\u2064\\u206A\\u206B\\u206B\\u206C\\u206D\\u206E\\u206F]+)|(\\u3000)|([\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3001-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g;\n\n        var valueFragment = this.dom.createFragment(this.element);\n\n        var m;\n        var i = 0;\n        while (m = re.exec(value)) {\n            var tab = m[1];\n            var simpleSpace = m[2];\n            var controlCharacter = m[3];\n            var cjkSpace = m[4];\n            var cjk = m[5];\n\n            if (!self.showSpaces && simpleSpace)\n                continue;\n\n            var before = i != m.index ? value.slice(i, m.index) : \"\";\n\n            i = m.index + m[0].length;\n\n            if (before) {\n                valueFragment.appendChild(this.dom.createTextNode(before, this.element));\n            }\n\n            if (tab) {\n                var tabSize = self.session.getScreenTabSize(screenColumn + m.index);\n                var text = self.$tabStrings[tabSize].cloneNode(true);\n                text[\"charCount\"] = 1;\n                valueFragment.appendChild(text);\n                screenColumn += tabSize - 1;\n            } else if (simpleSpace) {\n                if (self.showSpaces) {\n                    var span = this.dom.createElement(\"span\");\n                    span.className = \"ace_invisible ace_invisible_space\";\n                    span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length);\n                    valueFragment.appendChild(span);\n                } else {\n                    valueFragment.appendChild(this.dom.createTextNode(simpleSpace, this.element));\n                }\n            } else if (controlCharacter) {\n                var span = this.dom.createElement(\"span\");\n                span.className = \"ace_invisible ace_invisible_space ace_invalid\";\n                span.textContent = lang.stringRepeat(self.SPACE_CHAR, controlCharacter.length);\n                valueFragment.appendChild(span);\n            } else if (cjkSpace) {\n                // U+3000 is both invisible AND full-width, so must be handled uniquely\n                screenColumn += 1;\n\n                var span = this.dom.createElement(\"span\");\n                span.style.width = (self.config.characterWidth * 2) + \"px\";\n                span.className = self.showSpaces ? \"ace_cjk ace_invisible ace_invisible_space\" : \"ace_cjk\";\n                span.textContent = self.showSpaces ? self.SPACE_CHAR : cjkSpace;\n                valueFragment.appendChild(span);\n            } else if (cjk) {\n                screenColumn += 1;\n                var span = this.dom.createElement(\"span\");\n                span.style.width = (self.config.characterWidth * 2) + \"px\";\n                span.className = \"ace_cjk\";\n                span.textContent = cjk;\n                valueFragment.appendChild(span);\n            }\n        }\n\n        valueFragment.appendChild(this.dom.createTextNode(i ? value.slice(i) : value, this.element));\n\n        if (!isTextToken(token.type)) {\n            var classes = \"ace_\" + token.type.replace(/\\./g, \" ace_\");\n            var span = this.dom.createElement(\"span\");\n            if (token.type == \"fold\"){\n                span.style.width = (token.value.length * this.config.characterWidth) + \"px\";\n                span.setAttribute(\"title\", nls(\"inline-fold.closed.title\", \"Unfold code\"));\n            }\n\n            span.className = classes;\n            span.appendChild(valueFragment);\n\n            parent.appendChild(span);\n        }\n        else {\n            parent.appendChild(valueFragment);\n        }\n\n        return screenColumn + value.length;\n    }\n\n    renderIndentGuide(parent, value, max) {\n        var cols = value.search(this.$indentGuideRe);\n        if (cols <= 0 || cols >= max)\n            return value;\n        if (value[0] == \" \") {\n            cols -= cols % this.tabSize;\n            var count = cols/this.tabSize;\n            for (var i=0; i<count; i++) {\n                parent.appendChild(this.$tabStrings[\" \"].cloneNode(true));\n            }\n            this.$highlightIndentGuide();\n            return value.substr(cols);\n        } else if (value[0] == \"\\t\") {\n            for (var i=0; i<cols; i++) {\n                var tabSpan = this.$tabStrings[\"\\t\"].cloneNode(true);\n                tabSpan[\"charCount\"] = 1;\n                parent.appendChild(tabSpan);\n            }\n            this.$highlightIndentGuide();\n            return value.substr(cols);\n        }\n        this.$highlightIndentGuide();\n        return value;\n    }\n\n    $highlightIndentGuide() {\n        if (!this.$highlightIndentGuides || !this.displayIndentGuides) return;\n        /**@type {{ indentLevel?: number; start?: number; end?: number; dir?: number; }}*/\n        this.$highlightIndentGuideMarker = {\n            indentLevel: undefined,\n            start: undefined,\n            end: undefined,\n            dir: undefined\n        };\n        var lines = this.session.doc.$lines;\n        if (!lines) return;\n\n        var cursor = this.session.selection.getCursor();\n        var initialIndent = /^\\s*/.exec(this.session.doc.getLine(cursor.row))[0].length;\n        var elementIndentLevel = Math.floor(initialIndent / this.tabSize);\n        this.$highlightIndentGuideMarker = {\n            indentLevel: elementIndentLevel,\n            start: cursor.row\n        };\n\n        var bracketHighlight = this.session.$bracketHighlight;\n        if (bracketHighlight) {\n            var ranges = this.session.$bracketHighlight.ranges;\n            for (var i = 0; i < ranges.length; i++) {\n                if (cursor.row !== ranges[i].start.row) {\n                    this.$highlightIndentGuideMarker.end = ranges[i].start.row + 1;\n                    if (cursor.row > ranges[i].start.row) {\n                        this.$highlightIndentGuideMarker.dir = -1;\n                    }\n                    else {\n                        this.$highlightIndentGuideMarker.dir = 1;\n                    }\n                    break;\n                }\n            }\n        }\n\n        if (!this.$highlightIndentGuideMarker.end) {\n            if (lines[cursor.row] !== '' && cursor.column === lines[cursor.row].length) {\n                this.$highlightIndentGuideMarker.dir = 1;\n                for (var i = cursor.row + 1; i < lines.length; i++) {\n                    var line = lines[i];\n                    var currentIndent = /^\\s*/.exec(line)[0].length;\n                    if (line !== '') {\n                        this.$highlightIndentGuideMarker.end = i;\n                        if (currentIndent <= initialIndent) break;\n                    }\n                }\n            }\n        }\n\n        this.$renderHighlightIndentGuide();\n    }\n\n    $clearActiveIndentGuide() {\n        var activeIndentGuides = this.element.querySelectorAll(\".ace_indent-guide-active\");\n        for (var i = 0; i < activeIndentGuides.length; i++) {\n            activeIndentGuides[i].classList.remove(\"ace_indent-guide-active\");\n        }\n    }\n\n    $setIndentGuideActive(cell, indentLevel) {\n        var line = this.session.doc.getLine(cell.row);\n        if (line !== \"\") {\n            let element = cell.element;\n            if (cell.element.classList && cell.element.classList.contains(\"ace_line_group\")) {\n                if (cell.element.childNodes.length > 0) {\n                    element = cell.element.childNodes[0];\n                }\n                else {\n                    return;\n                }\n            }\n            var childNodes = element.childNodes;\n            if (childNodes) {\n                let node = childNodes[indentLevel - 1];\n                if (node && node.classList && node.classList.contains(\"ace_indent-guide\")) node.classList.add(\n                    \"ace_indent-guide-active\");\n            }\n        }\n    }\n\n    $renderHighlightIndentGuide() {\n        if (!this.$lines) return;\n        var cells = this.$lines.cells;\n        this.$clearActiveIndentGuide();\n        var indentLevel = this.$highlightIndentGuideMarker.indentLevel;\n        if (indentLevel !== 0) {\n            if (this.$highlightIndentGuideMarker.dir === 1) {\n                for (var i = 0; i < cells.length; i++) {\n                    var cell = cells[i];\n                    if (this.$highlightIndentGuideMarker.end && cell.row >= this.$highlightIndentGuideMarker.start\n                        + 1) {\n                        if (cell.row >= this.$highlightIndentGuideMarker.end) break;\n                        this.$setIndentGuideActive(cell, indentLevel);\n                    }\n                }\n            }\n            else {\n                for (var i = cells.length - 1; i >= 0; i--) {\n                    var cell = cells[i];\n                    if (this.$highlightIndentGuideMarker.end && cell.row < this.$highlightIndentGuideMarker.start) {\n                        if (cell.row < this.$highlightIndentGuideMarker.end) break;\n                        this.$setIndentGuideActive(cell, indentLevel);\n                    }\n                }\n            }\n        }\n    }\n\n    $createLineElement(parent) {\n        var lineEl = this.dom.createElement(\"div\");\n        lineEl.className = \"ace_line\";\n        lineEl.style.height = this.config.lineHeight + \"px\";\n\n        return lineEl;\n    }\n\n    $renderWrappedLine(parent, tokens, splits) {\n        var chars = 0;\n        var split = 0;\n        var splitChars = splits[0];\n        var screenColumn = 0;\n\n        var lineEl = this.$createLineElement();\n        parent.appendChild(lineEl);\n\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            var value = token.value;\n            if (i == 0 && this.displayIndentGuides) {\n                chars = value.length;\n                value = this.renderIndentGuide(lineEl, value, splitChars);\n                if (!value)\n                    continue;\n                chars -= value.length;\n            }\n\n            if (chars + value.length < splitChars) {\n                screenColumn = this.$renderToken(lineEl, screenColumn, token, value);\n                chars += value.length;\n            } else {\n                while (chars + value.length >= splitChars) {\n                    screenColumn = this.$renderToken(\n                        lineEl, screenColumn,\n                        token, value.substring(0, splitChars - chars)\n                    );\n                    value = value.substring(splitChars - chars);\n                    chars = splitChars;\n\n                    lineEl = this.$createLineElement();\n                    parent.appendChild(lineEl);\n\n                    var text = this.dom.createTextNode(lang.stringRepeat(\"\\xa0\", splits.indent), this.element);\n                    text[\"charCount\"] = 0; // not to take into account when we are counting columns\n                    lineEl.appendChild(text);\n\n                    split ++;\n                    screenColumn = 0;\n                    splitChars = splits[split] || Number.MAX_VALUE;\n                }\n                if (value.length != 0) {\n                    chars += value.length;\n                    screenColumn = this.$renderToken(\n                        lineEl, screenColumn, token, value\n                    );\n                }\n            }\n        }\n\n        if (splits[splits.length - 1] > this.MAX_LINE_LENGTH)\n            this.$renderOverflowMessage(lineEl, screenColumn, null, \"\", true);\n    }\n\n    $renderSimpleLine(parent, tokens) {\n        var screenColumn = 0;\n\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            var value = token.value;\n            if (i == 0 && this.displayIndentGuides) {\n                value = this.renderIndentGuide(parent, value);\n                if (!value)\n                    continue;\n            }\n            if (screenColumn + value.length > this.MAX_LINE_LENGTH)\n                return this.$renderOverflowMessage(parent, screenColumn, token, value);\n            screenColumn = this.$renderToken(parent, screenColumn, token, value);\n        }\n    }\n\n    $renderOverflowMessage(parent, screenColumn, token, value, hide) {\n        token && this.$renderToken(parent, screenColumn, token,\n            value.slice(0, this.MAX_LINE_LENGTH - screenColumn));\n\n        var overflowEl = this.dom.createElement(\"span\");\n        overflowEl.className = \"ace_inline_button ace_keyword ace_toggle_wrap\";\n        overflowEl.textContent = hide ? \"<hide>\" : \"<click to see more...>\";\n\n        parent.appendChild(overflowEl);\n    }\n\n    // row is either first row of foldline or not in fold\n    $renderLine(parent, row, foldLine) {\n        if (!foldLine && foldLine != false)\n            foldLine = this.session.getFoldLine(row);\n\n        if (foldLine)\n            var tokens = this.$getFoldLineTokens(row, foldLine);\n        else\n            var tokens = this.session.getTokens(row);\n\n        var lastLineEl = parent;\n        if (tokens.length) {\n            var splits = this.session.getRowSplitData(row);\n            if (splits && splits.length) {\n                this.$renderWrappedLine(parent, tokens, splits);\n                var lastLineEl = parent.lastChild;\n            } else {\n                var lastLineEl = parent;\n                if (this.$useLineGroups()) {\n                    lastLineEl = this.$createLineElement();\n                    parent.appendChild(lastLineEl);\n                }\n                this.$renderSimpleLine(lastLineEl, tokens);\n            }\n        } else if (this.$useLineGroups()) {\n            lastLineEl = this.$createLineElement();\n            parent.appendChild(lastLineEl);\n        }\n\n        if (this.showEOL && lastLineEl) {\n            if (foldLine)\n                row = foldLine.end.row;\n\n            var invisibleEl = this.dom.createElement(\"span\");\n            invisibleEl.className = \"ace_invisible ace_invisible_eol\";\n            invisibleEl.textContent = row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR;\n\n            lastLineEl.appendChild(invisibleEl);\n        }\n    }\n\n    /**\n     * @param {number} row\n     * @param {import(\"../../ace-internal\").Ace.FoldLine} foldLine\n     * @return {import(\"../../ace-internal\").Ace.Token[]}\n     */\n    $getFoldLineTokens(row, foldLine) {\n        var session = this.session;\n        var renderTokens = [];\n\n        function addTokens(tokens, from, to) {\n            var idx = 0, col = 0;\n            while ((col + tokens[idx].value.length) < from) {\n                col += tokens[idx].value.length;\n                idx++;\n\n                if (idx == tokens.length)\n                    return;\n            }\n            if (col != from) {\n                var value = tokens[idx].value.substring(from - col);\n                // Check if the token value is longer then the from...to spacing.\n                if (value.length > (to - from))\n                    value = value.substring(0, to - from);\n\n                renderTokens.push({\n                    type: tokens[idx].type,\n                    value: value\n                });\n\n                col = from + value.length;\n                idx += 1;\n            }\n\n            while (col < to && idx < tokens.length) {\n                var value = tokens[idx].value;\n                if (value.length + col > to) {\n                    renderTokens.push({\n                        type: tokens[idx].type,\n                        value: value.substring(0, to - col)\n                    });\n                } else\n                    renderTokens.push(tokens[idx]);\n                col += value.length;\n                idx += 1;\n            }\n        }\n\n        var tokens = session.getTokens(row);\n        foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {\n            if (placeholder != null) {\n                renderTokens.push({\n                    type: \"fold\",\n                    value: placeholder\n                });\n            } else {\n                if (isNewRow)\n                    tokens = session.getTokens(row);\n\n                if (tokens.length)\n                    addTokens(tokens, lastColumn, column);\n            }\n        }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);\n\n        return renderTokens;\n    }\n\n    $useLineGroups() {\n        // For the updateLines function to work correctly, it's important that the\n        // child nodes of this.element correspond on a 1-to-1 basis to rows in the\n        // document (as distinct from lines on the screen). For sessions that are\n        // wrapped, this means we need to add a layer to the node hierarchy (tagged\n        // with the class name ace_line_group).\n        return this.session.getUseWrapMode();\n    }\n}\n\nText.prototype.EOF_CHAR = \"\\xB6\";\nText.prototype.EOL_CHAR_LF = \"\\xAC\";\nText.prototype.EOL_CHAR_CRLF = \"\\xa4\";\nText.prototype.EOL_CHAR = Text.prototype.EOL_CHAR_LF;\nText.prototype.TAB_CHAR = \"\\u2014\"; //\"\\u21E5\";\nText.prototype.SPACE_CHAR = \"\\xB7\";\nText.prototype.$padding = 0;\nText.prototype.MAX_LINE_LENGTH = 10000;\nText.prototype.showInvisibles = false;\nText.prototype.showSpaces = false;\nText.prototype.showTabs = false;\nText.prototype.showEOL = false;\nText.prototype.displayIndentGuides = true;\nText.prototype.$highlightIndentGuides = true;\nText.prototype.$tabStrings = [];\nText.prototype.destroy = {};\nText.prototype.onChangeTabSize = Text.prototype.$computeTabString;\n\noop.implement(Text.prototype, EventEmitter);\n\nexports.Text = Text;\n"
  },
  {
    "path": "src/layer/text_markers.js",
    "content": "var Text = require(\"./text\").Text;\nvar lang = require(\"../lib/lang\");\n/**\n * @typedef TextMarker\n * @property {import(\"../../ace-internal\").Ace.IRange} range\n * @property {number} id\n * @property {string} className\n * @property {string} [type]\n */\n\n/**\n * @typedef SelectionSegment\n * @property {number} beforeSelection - Characters before selection\n * @property {number} selectionLength - Length of selection\n * @property {number} afterSelection - Characters after selection\n */\n\nvar textMarkerMixin = {\n    /**\n     * @param {string} className\n     * @this {Text}\n     */\n    $removeClass(className) {\n        if (!this.element || !className) return;\n        var selectedElements = this.element.querySelectorAll('.' + className);\n        for (let i = 0; i < selectedElements.length; i++) {\n            var element = selectedElements[i];\n            element.classList.remove(className);\n\n            if (element.hasAttribute('data-whitespace')) {\n                var originalWhitespace = element.getAttribute('data-whitespace');\n                var textNode = this.dom.createTextNode(originalWhitespace, this.element);\n                textNode[\"charCount\"] = element[\"charCount\"];\n                element.parentNode.replaceChild(textNode, element);\n            }\n        }\n    },\n    /**\n     * @this {Text}\n     */\n    $applyTextMarkers() {\n        if (this.session.$scheduleForRemove) {\n            this.session.$scheduleForRemove.forEach(className => {\n                this.$removeClass(className);\n            });\n\n            this.session.$scheduleForRemove = new Set();\n        }\n\n        var textMarkers = this.session.getTextMarkers();\n\n        if (textMarkers.length === 0) {\n            return;\n        }\n\n        var classNameGroups = new Set();\n        textMarkers.forEach(marker => {\n            classNameGroups.add(marker.className);\n        });\n\n        classNameGroups.forEach(className => {\n            this.$removeClass(className);\n        });\n\n        textMarkers.forEach((marker) => {\n            for (let row = marker.range.start.row; row <= marker.range.end.row; row++) {\n                var cell = this.$lines.cells.find((el) => el.row === row);\n\n                if (cell) {\n                    this.$modifyDomForMarkers(cell.element, row, marker);\n                }\n            }\n        });\n    },\n\n    /**\n     * Modifies the DOM for marker rendering.\n     * @param {HTMLElement} lineElement - The line element to modify\n     * @param {number} row - The row being processed\n     * @param {TextMarker} marker - The marker to apply\n     */\n    $modifyDomForMarkers(lineElement, row, marker) {\n        var lineLength = this.session.getLine(row).length;\n        let startCol = row > marker.range.start.row ? 0 : marker.range.start.column;\n        let endCol = row < marker.range.end.row ? lineLength : marker.range.end.column;\n        if (startCol === endCol) {\n            return;\n        }\n\n        var lineElements = [];\n        if (lineElement.classList.contains('ace_line_group')) {\n            lineElements = Array.from(lineElement.childNodes);\n        }\n        else {\n            lineElements = [lineElement];\n        }\n\n        var currentColumn = 0;\n        lineElements.forEach((lineElement) => {\n            var childNodes = Array.from(lineElement.childNodes);\n            for (let i = 0; i < childNodes.length; i++) {\n                let subChildNodes = [childNodes[i]];\n                let parentNode = lineElement;\n                if (childNodes[i].childNodes && childNodes[i].childNodes.length > 0) {\n                    subChildNodes = Array.from(childNodes[i].childNodes);\n                    parentNode = childNodes[i];\n                }\n                for (let j = 0; j < subChildNodes.length; j++) {\n                    var node = subChildNodes[j];\n                    var nodeText = node.textContent || '';\n                    if (node.parentNode[\"charCount\"]) {\n                        node[\"charCount\"] = node.parentNode[\"charCount\"];\n                    }\n                    var contentLength = node[\"charCount\"] || nodeText.length;\n                    var nodeStart = currentColumn;\n                    var nodeEnd = currentColumn + contentLength;\n\n                    if (node[\"charCount\"] === 0 || contentLength === 0) {\n                        continue;\n                    }\n\n                    if (nodeStart < endCol && nodeEnd > startCol) {\n                        var beforeSelection = Math.max(0, startCol - nodeStart);\n                        var afterSelection = Math.max(0, nodeEnd - endCol);\n                        var selectionLength = contentLength - beforeSelection - afterSelection;\n\n                        if (marker.type === \"invisible\") {\n                            this.$processInvisibleMarker(node, parentNode, {\n                                beforeSelection,\n                                selectionLength,\n                                afterSelection\n                            }, marker);\n                        }\n                        else {\n                            this.$processRegularMarker(node, parentNode, {\n                                beforeSelection,\n                                selectionLength,\n                                afterSelection\n                            }, marker, nodeStart, startCol, endCol);\n                        }\n                    }\n                    currentColumn = nodeEnd;\n                }\n            }\n        });\n    },\n\n    /**\n     * Process text nodes for invisible markers (whitespace visualization)\n     * @param {Node} node - The DOM node to process\n     * @param {Node} parentNode - The parent node\n     * @param {SelectionSegment} selectionSegment\n     * @param {object} marker - The marker being applied\n     */\n    $processInvisibleMarker(node, parentNode, selectionSegment, marker) {\n        var nodeText = node.textContent || '';\n        if (node.nodeType === 3) { // Text node\n            var fragment = this.dom.createFragment(this.element);\n\n            if (selectionSegment.beforeSelection > 0) {\n                fragment.appendChild(\n                    this.dom.createTextNode(nodeText.substring(0, selectionSegment.beforeSelection), this.element));\n            }\n\n            if (selectionSegment.selectionLength > 0) {\n                var selectedText = selectionSegment.beforeSelection === 0 && selectionSegment.afterSelection === 0\n                    ? nodeText : nodeText.substring(\n                        selectionSegment.beforeSelection,\n                        selectionSegment.beforeSelection + selectionSegment.selectionLength\n                    );\n\n                var segments = selectedText.match(/\\s+|[^\\s]+/g) || [];\n\n                for (let k = 0; k < segments.length; k++) {\n                    var segment = segments[k];\n                    let span;\n                    if (/^\\s+$/.test(segment)) {\n                        span = this.dom.createElement(\"span\");\n                        span.className = marker.className;\n                        var symbol = node[\"charCount\"] ? this.TAB_CHAR : this.SPACE_CHAR;\n                        span.textContent = lang.stringRepeat(symbol, segment.length);\n                        span.setAttribute(\"data-whitespace\", segment);\n                        fragment.appendChild(span);\n                    }\n                    else {\n                        span = this.dom.createElement(\"span\");\n                        span.textContent = segment;\n                    }\n                    if (node[\"charCount\"] && segments.length === 1) { //this is for real tabs\n                        span[\"charCount\"] = node[\"charCount\"];\n                    }\n                    fragment.appendChild(span);\n                }\n            }\n\n            if (selectionSegment.afterSelection > 0) {\n                fragment.appendChild(this.dom.createTextNode(\n                    nodeText.substring(selectionSegment.beforeSelection + selectionSegment.selectionLength),\n                    this.element\n                ));\n            }\n\n            parentNode.replaceChild(fragment, node);\n        }\n    },\n\n    /**\n     * Process nodes for regular markers (not invisible whitespace)\n     * @param {Node} node - The DOM node to process\n     * @param {Node} parentNode - The parent node\n     * @param {SelectionSegment} selectionSegment\n     * @param {TextMarker} marker - The marker being applied\n     * @param {number} nodeStart - Starting column of the node\n     * @param {number} startCol - Starting column of the selection\n     * @param {number} endCol - Ending column of the selection\n     */\n    $processRegularMarker(node, parentNode, selectionSegment, marker, nodeStart, startCol, endCol) {\n        var nodeText = node.textContent || '';\n        if (node.nodeType === 3) { // Text node\n            if (selectionSegment.beforeSelection > 0 || selectionSegment.afterSelection > 0) {\n                var fragment = this.dom.createFragment(this.element);\n\n                if (selectionSegment.beforeSelection > 0) {\n                    fragment.appendChild(\n                        this.dom.createTextNode(nodeText.substring(0, selectionSegment.beforeSelection), this.element));\n                }\n\n                if (selectionSegment.selectionLength > 0) {\n                    var selectedSpan = this.dom.createElement('span');\n                    selectedSpan.classList.add(marker.className);\n                    selectedSpan.textContent = nodeText.substring(\n                        selectionSegment.beforeSelection,\n                        selectionSegment.beforeSelection + selectionSegment.selectionLength\n                    );\n                    fragment.appendChild(selectedSpan);\n                }\n\n                if (selectionSegment.afterSelection > 0) {\n                    fragment.appendChild(this.dom.createTextNode(\n                        nodeText.substring(selectionSegment.beforeSelection + selectionSegment.selectionLength),\n                        this.element\n                    ));\n                }\n\n                parentNode.replaceChild(fragment, node);\n            }\n            else {\n                var selectedSpan = this.dom.createElement('span');\n                selectedSpan.classList.add(marker.className);\n                selectedSpan.textContent = nodeText;\n                selectedSpan[\"charCount\"] = node[\"charCount\"];\n                parentNode.replaceChild(selectedSpan, node);\n            }\n        }\n        else if (node.nodeType === 1) { // Element node\n            if (nodeStart >= startCol && nodeStart + (nodeText.length || 0) <= endCol) {\n                // @ts-ignore\n                node.classList.add(marker.className);\n            }\n            else {\n                if (selectionSegment.beforeSelection > 0 || selectionSegment.afterSelection > 0) {\n                    // @ts-ignore\n                    var nodeClasses = node.className;\n                    var fragment = this.dom.createFragment(this.element);\n\n                    if (selectionSegment.beforeSelection > 0) {\n                        var beforeSpan = this.dom.createElement('span');\n                        beforeSpan.className = nodeClasses;\n                        beforeSpan.textContent = nodeText.substring(0, selectionSegment.beforeSelection);\n                        fragment.appendChild(beforeSpan);\n                    }\n\n                    if (selectionSegment.selectionLength > 0) {\n                        var selectedSpan = this.dom.createElement('span');\n                        selectedSpan.className = nodeClasses + ' ' + marker.className;\n                        selectedSpan.textContent = nodeText.substring(\n                            selectionSegment.beforeSelection,\n                            selectionSegment.beforeSelection + selectionSegment.selectionLength\n                        );\n                        fragment.appendChild(selectedSpan);\n                    }\n\n                    if (selectionSegment.afterSelection > 0) {\n                        var afterSpan = this.dom.createElement('span');\n                        afterSpan.className = nodeClasses;\n                        afterSpan.textContent = nodeText.substring(selectionSegment.beforeSelection + selectionSegment.selectionLength);\n                        fragment.appendChild(afterSpan);\n                    }\n\n                    parentNode.replaceChild(fragment, node);\n                }\n            }\n        }\n    }\n\n};\nObject.assign(Text.prototype, textMarkerMixin);\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar editSessionTextMarkerMixin = {\n    /**\n     * Adds a text marker to the current edit session.\n     *\n     * @param {import(\"../../ace-internal\").Ace.IRange} range - The range to mark in the document\n     * @param {string} className - The CSS class name to apply to the marked text\n     * @param {string} [type] - The type of marker (e.g. \"invisible\" for whitespace rendering)\n     * @returns {number} The unique identifier for the added text marker\n     *\n     * @this {EditSession}\n     */\n    addTextMarker(range, className, type) {\n        /**@type{number}*/\n        this.$textMarkerId = this.$textMarkerId || 0;\n        this.$textMarkerId++;\n        var marker = {\n            range: range,\n            id: this.$textMarkerId,\n            className: className,\n            type: type\n        };\n        if (!this.$textMarkers) {\n            this.$textMarkers = [];\n        }\n        this.$textMarkers[marker.id] = marker;\n        return marker.id;\n    },\n    /**\n     * Removes a text marker from the current edit session.\n     *\n     * @param {number} markerId - The unique identifier of the text marker to remove\n     *\n     * @this {EditSession}\n     */\n    removeTextMarker(markerId) {\n        if (!this.$textMarkers) {\n            return;\n        }\n\n        var marker = this.$textMarkers[markerId];\n        if (!marker) {\n            return;\n        }\n        if (!this.$scheduleForRemove) {\n            this.$scheduleForRemove = new Set();\n        }\n        this.$scheduleForRemove.add(marker.className);\n        delete this.$textMarkers[markerId];\n    },\n    /**\n     * Retrieves the text markers associated with the current edit session.\n     *\n     * @returns {TextMarker[]} An array of text markers, or an empty array if no markers exist\n     *\n     * @this {EditSession}\n     */\n    getTextMarkers() {\n        return this.$textMarkers || [];\n    }\n};\nObject.assign(EditSession.prototype, editSessionTextMarkerMixin);\n\n\nvar onAfterRender = (e, renderer) => {\n    renderer.$textLayer.$applyTextMarkers();\n};\n\nvar Editor = require(\"../editor\").Editor;\nrequire(\"../config\").defineOptions(Editor.prototype, \"editor\", {\n    enableTextMarkers: {\n        /**\n         * @param {boolean} val\n         * @this {Editor}\n         */\n        set: function (val) {\n            if (val) {\n                this.renderer.on(\"afterRender\", onAfterRender);\n            }\n            else {\n                this.renderer.off(\"afterRender\", onAfterRender);\n            }\n        },\n        value: true\n    }\n});\n\nexports.textMarkerMixin = textMarkerMixin;\nexports.editSessionTextMarkerMixin = editSessionTextMarkerMixin;"
  },
  {
    "path": "src/layer/text_markers_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"../test/assertions\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar TextLayer = require(\"./text\").Text;\nvar JavaScriptMode = require(\"../mode/javascript\").Mode;\nvar dom = require(\"../lib/dom\");\nvar Range = require(\"../range\").Range;\n\nrequire(\"./text_markers\");\n\nfunction normalize(str) {\n    return str.replace(/\\s/gm, \"\");\n}\n\nfunction getText(nodes) {\n    var markedContent = \"\";\n    nodes.forEach(node => {\n        markedContent += node.textContent;\n    });\n\n    return markedContent;\n}\n\nmodule.exports = {\n    setUp: function () {\n        this.session = new EditSession(\"\");\n        this.session.setMode(new JavaScriptMode());\n\n        this.container = document.createElement(\"div\");\n        this.textLayer = new TextLayer(this.container);\n        this.textLayer.setSession(this.session);\n        this.textLayer.config = {\n            characterWidth: 10,\n            lineHeight: 20,\n            firstRow: 0,\n            lastRow: 10,\n            firstRowScreen: 0,\n            padding: 0,\n            offset: 0\n        };\n    },\n\n    \"test: marker splits single token into multiple DOM nodes\": function () {\n        this.session.setValue('var functionName = \"test\";');\n\n        this.textLayer.update(this.textLayer.config);\n\n        this.session.addTextMarker(new Range(0, 6, 0, 10), \"split-token-marker\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var markerSpans = this.textLayer.element.querySelectorAll('.split-token-marker');\n        assert.equal(markerSpans.length, 1);\n        assert.equal(getText(markerSpans), \"ncti\");\n\n        var result = normalize(`<span class=\"ace_storage ace_type\">var</span>\n            <span class=\"ace_identifier\">fu<span class=\" split-token-marker\">ncti</span>onName</span> <span\n                class=\"ace_keyword ace_operator\">=</span> <span class=\"ace_string\">\"test\"</span><span\n                class=\"ace_punctuation ace_operator\">;</span>`);\n        var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);\n        assert.equal(actual, result);\n    },\n\n    \"test: marker partially overlaps multiple tokens\": function () {\n        this.session.setValue('var test = 123;');\n\n        this.textLayer.update(this.textLayer.config);\n\n        this.session.addTextMarker(new Range(0, 6, 0, 12), \"overlap-marker\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var markerSpans = this.textLayer.element.querySelectorAll('.overlap-marker');\n        assert.equal(getText(markerSpans), \"st = 1\");\n\n        var result = normalize(`<span class=\"ace_storage ace_type\">var</span> <span class=\"ace_identifier\">te\n    <span class=\" overlap-marker\">st</span></span><span class=\" overlap-marker\"> </span>\n    <span class=\"ace_keyword ace_operator\">\n    <span class=\" overlap-marker\">=</span></span><span class=\" overlap-marker\"> </span><span class=\"ace_constant ace_numeric\">\n    <span class=\" overlap-marker\">1</span>23</span><span class=\"ace_punctuation ace_operator\">;</span>`);\n        var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);\n        assert.equal(actual, result);\n    },\n\n    \"test: multiple overlapping markers split tokens differently\": function () {\n        this.session.setValue('var longVariableName = 42;');\n\n        this.textLayer.update(this.textLayer.config);\n\n        this.session.addTextMarker(new Range(0, 4, 0, 12), \"marker-1\");\n        this.session.addTextMarker(new Range(0, 8, 0, 16), \"marker-2\");\n        this.session.addTextMarker(new Range(0, 6, 0, 14), \"marker-3\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var line = this.textLayer.element.childNodes[0];\n\n        // Verify all markers are applied\n        assert.ok(line.querySelectorAll('.marker-1').length > 0);\n        assert.ok(line.querySelectorAll('.marker-2').length > 0);\n        assert.ok(line.querySelectorAll('.marker-3').length > 0);\n\n        assert.equal(line.textContent, 'var longVariableName = 42;');\n\n        var result = normalize(`<span class=\"ace_storage ace_type\">var</span> <span class=\"ace_identifier\">\n            <span class=\" marker-1\">lo</span><span class=\" marker-1 marker-3\">ng</span>\n            <span class=\" marker-1 marker-2 marker-3\">Vari</span><span class=\" marker-2 marker-3\">ab</span>\n            <span class=\" marker-2\">le</span>Name</span> <span class=\"ace_keyword ace_operator\">=</span> \n            <span class=\"ace_constant ace_numeric\">42</span><span class=\"ace_punctuation ace_operator\">;</span>`);\n        var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);\n        assert.equal(actual, result);\n    },\n\n    \"test: marker with tab characters and invisible rendering\": function () {\n        this.session.setValue(\"func\\t\\ttest\");\n        this.textLayer.setShowInvisibles(\"tab\");\n        this.textLayer.$computeTabString();\n\n        this.textLayer.update(this.textLayer.config);\n\n        this.session.addTextMarker(new Range(0, 3, 0, 7), \"tab-marker\");\n\n        this.textLayer.$applyTextMarkers();\n\n        //preserve whitespaces\n        var result = `<span class=\"ace_identifier\">fun<span class=\" tab-marker\">c</span></span><span class=\" tab-marker\">    </span><span class=\" tab-marker\">    </span><span class=\"ace_identifier\"><span class=\" tab-marker\">t</span>est</span>`;\n        var actual = this.textLayer.element.childNodes[0].innerHTML;\n        assert.equal(actual, result);\n    },\n\n    \"test: marker with CJK characters and proper width calculation\": function () {\n        this.session.setValue(\"测试function测试\");\n\n        this.textLayer.update(this.textLayer.config);\n\n        this.session.addTextMarker(new Range(0, 1, 0, 11), \"cjk-marker\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var line = this.textLayer.element.childNodes[0];\n        var cjkMarkers = line.querySelectorAll('.cjk-marker');\n        assert.ok(cjkMarkers.length > 0, \"CJK marker should be present\");\n\n        var markedText = \"\";\n        cjkMarkers.forEach(span => {\n            markedText += span.textContent;\n        });\n        assert.equal(markedText, \"试function测\");\n\n        var result = normalize(`<span class=\"ace_identifier\"><span class=\"ace_cjk\" style=\"width: 20px;\">测</span>\n            <span class=\"ace_cjk cjk-marker\" style=\"width: 20px;\">试</span><span class=\" cjk-marker\">function</span>\n            <span class=\"ace_cjk cjk-marker\" style=\"width: 20px;\">测</span>\n            <span class=\"ace_cjk\" style=\"width: 20px;\">试</span></span>`);\n        var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);\n        assert.equal(actual, result);\n    },\n\n    \"test: marker removal properly cleans up split tokens\": function() {\n        this.session.setValue('var functionName = \"test\";');\n\n        this.textLayer.update(this.textLayer.config);\n\n        var markerId = this.session.addTextMarker(new Range(0, 6, 0, 10), \"temp-marker\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var line = this.textLayer.element.childNodes[0];\n\n        var markerSpans = line.querySelectorAll('.temp-marker');\n        assert.ok(markerSpans.length > 0, \"Marker should be present\");\n\n        this.session.removeTextMarker(markerId);\n\n        this.textLayer.update(this.textLayer.config);\n        this.textLayer.$applyTextMarkers();\n\n        var newLine = this.textLayer.element.childNodes[0];\n\n        markerSpans = newLine.querySelectorAll('.temp-marker');\n        assert.equal(markerSpans.length, 0, \"Marker should be removed\");\n    },\n\n    \"test: invisible marker with mixed whitespace and complete cleanup verification\": function() {\n        var value = \"function\\t  test() { //test     comment\\n    var x = 1;\\n}\";\n        this.session.setValue(value);\n\n        this.textLayer.update(this.textLayer.config);\n\n        var markerId = this.session.addTextMarker(new Range(0, 8, 0, 30), \"invisible-marker\", \"invisible\");\n\n        this.textLayer.$applyTextMarkers();\n\n        var markerElements = this.textLayer.element.querySelectorAll('.invisible-marker');\n        assert.ok(markerElements.length > 0, \"Invisible marker should be applied\");\n\n        var line = this.textLayer.element.childNodes[0];\n\n        var hasTabSymbol = line.innerHTML.includes(this.textLayer.TAB_CHAR);\n        var hasSpaceSymbol = line.innerHTML.includes(this.textLayer.SPACE_CHAR);\n        assert.ok(hasTabSymbol, \"Should contain TAB_CHAR symbol\");\n        assert.ok(hasSpaceSymbol, \"Should contain SPACE_CHAR symbol\");\n\n        var result = normalize(`<span class=\"ace_storage ace_type\">function</span>\n            <span class=\"invisible-marker\" data-whitespace=\"    \">————</span>\n            <span class=\"invisible-marker\" data-whitespace=\"  \">··</span>\n            <span class=\"ace_entity ace_name ace_function\"><span>test</span></span>\n            <span class=\"ace_paren ace_lparen\"><span>(</span></span>\n            <span class=\"ace_paren ace_rparen\"><span>)</span></span>\n            <span class=\"invisible-marker\" data-whitespace=\" \">·</span><span class=\"ace_paren ace_lparen\">\n            <span>{</span></span><span class=\"invisible-marker\" data-whitespace=\" \">·</span>\n            <span class=\"ace_comment\"><span>//test</span>\n            <span class=\"invisible-marker\" data-whitespace=\"    \">····</span> comment</span>`);\n        var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);\n        assert.equal(actual, result);\n\n        this.session.removeTextMarker(markerId);\n        this.textLayer.$applyTextMarkers();\n\n        markerElements = this.textLayer.element.querySelectorAll('.invisible-marker');\n        assert.equal(markerElements.length, 0, \"Marker class should be removed\");\n\n        var finalLine = this.textLayer.element.childNodes[0];\n        assert.ok(!finalLine.innerHTML.includes(this.textLayer.TAB_CHAR),\n            \"TAB_CHAR should be removed from DOM\");\n        assert.ok(!finalLine.innerHTML.includes(this.textLayer.SPACE_CHAR),\n            \"SPACE_CHAR should be removed from DOM\");\n\n        var elementsWithWhitespace = this.textLayer.element.querySelectorAll('[data-whitespace]');\n        assert.equal(elementsWithWhitespace.length, 0, \"No data-whitespace attributes should remain\");\n    },\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/layer/text_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"../test/assertions\");\nvar EditSession = require(\"../edit_session\").EditSession;\nvar TextLayer = require(\"./text\").Text;\nvar JavaScriptMode = require(\"../mode/javascript\").Mode;\nvar dom = require(\"../lib/dom\");\n\nmodule.exports = {\n\n    setUp: function() {\n        this.session = new EditSession(\"\");\n        this.session.setMode(new JavaScriptMode());\n        this.textLayer = new TextLayer(document.createElement(\"div\"));\n        this.textLayer.setSession(this.session);\n        this.textLayer.config = {\n            characterWidth: 10,\n            lineHeight: 20\n        };\n    },\n\n    \"test: render line with hard tabs should render the same as lines with soft tabs\" : function() {\n        this.session.setValue(\"a\\ta\\ta\\t\\na   a   a   \\n\");\n        this.textLayer.$computeTabString();\n        \n        // row with hard tabs\n        var parent1 = dom.createElement(\"div\");\n        this.textLayer.$renderLine(parent1, 0);\n        \n        // row with soft tabs\n        var parent2 = dom.createElement(\"div\");\n        this.textLayer.$renderLine(parent2, 1);\n        assert.equal(parent1.innerHTML, parent2.innerHTML);\n    },\n    \n    \"test rendering width of ideographic space (U+3000)\" : function() {\n        this.session.setValue(\"\\u3000\");\n        \n        var parent = dom.createElement(\"div\");\n        this.textLayer.$renderLine(parent, 0);\n        assert.domNode(parent, [\"div\", {}, [\"span\", {class: \"ace_cjk\", style: \"width: 20px;\"}, \"\\u3000\"]]);\n\n        this.textLayer.setShowInvisibles(true);\n        var parent = dom.createElement(\"div\");\n        this.textLayer.$renderLine(parent, 0);\n        assert.domNode(parent, [\"div\", {},\n            [\"span\", {class: \"ace_cjk ace_invisible ace_invisible_space\", style: \"width: 20px;\"}, this.textLayer.SPACE_CHAR],\n            [\"span\", {class: \"ace_invisible ace_invisible_eol\"}, \"\\xB6\"]\n        ]);\n    },\n\n    \"test rendering of indent guides\" : function() {\n        var textLayer = this.textLayer;\n        var EOL = \"<span class=\\\"ace_invisible ace_invisible_eol\\\">\" + textLayer.EOL_CHAR + \"</span>\";\n        var SPACE = function(i) {return Array(i+1).join(\" \");};\n        var DOT = function(i) {return Array(i+1).join(textLayer.SPACE_CHAR);};\n        var TAB = function(i) {return Array(i+1).join(textLayer.TAB_CHAR);};\n        function testRender(results) {\n            for (var i = results.length; i--; ) {\n                var parent = dom.createElement(\"div\");\n                textLayer.$renderLine(parent, i);\n                \n                assert.equal(parent.innerHTML, results[i]);\n            }\n        }\n        \n        this.session.setValue(\"      \\n\\t\\tf\\n   \");\n        testRender([\n            \"<span class=\\\"ace_indent-guide\\\">\" + SPACE(4) + \"</span>\" + SPACE(2),\n            \"<span class=\\\"ace_indent-guide\\\">\" + SPACE(4) + \"</span>\" + SPACE(4) + \"<span class=\\\"ace_identifier\\\">f</span>\",\n            SPACE(3)\n        ]);\n        \n        this.textLayer.setShowInvisibles(true);\n        testRender([\n            \"<span class=\\\"ace_indent-guide ace_invisible ace_invisible_space\\\">\" + DOT(4) + \"</span><span class=\\\"ace_invisible ace_invisible_space\\\">\" + DOT(2) + \"</span>\" + EOL,\n            \"<span class=\\\"ace_indent-guide ace_invisible ace_invisible_tab\\\">\" + TAB(4) + \"</span><span class=\\\"ace_invisible ace_invisible_tab\\\">\" + TAB(4) + \"</span><span class=\\\"ace_identifier\\\">f</span>\" + EOL\n        ]);\n        \n        this.textLayer.setDisplayIndentGuides(false);\n        testRender([\n            \"<span class=\\\"ace_invisible ace_invisible_space\\\">\" + DOT(6) + \"</span>\" + EOL,\n            \"<span class=\\\"ace_invisible ace_invisible_tab\\\">\" + TAB(4) + \"</span><span class=\\\"ace_invisible ace_invisible_tab\\\">\" + TAB(4) + \"</span><span class=\\\"ace_identifier\\\">f</span>\" + EOL\n        ]);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/layer/text_util.js",
    "content": "// Tokens for which Ace just uses a simple TextNode and does not add any special className.\nconst textTokens = new Set([\"text\", \"rparen\", \"lparen\"]);\n\nexports.isTextToken = function(tokenType) {\n    return textTokens.has(tokenType);\n};\n"
  },
  {
    "path": "src/lib/app_config.js",
    "content": "\"no use strict\";\nvar oop = require(\"./oop\");\nvar EventEmitter = require(\"./event_emitter\").EventEmitter;\nconst reportError = require(\"./report_error\").reportError;\nconst defaultEnglishMessages = require(\"./default_english_messages\").defaultEnglishMessages;\n\nvar optionsProvider = {\n    setOptions: function(optList) {\n        Object.keys(optList).forEach(function(key) {\n            this.setOption(key, optList[key]);\n        }, this);\n    },\n    getOptions: function(optionNames) {\n        var result = {};\n        if (!optionNames) {\n            var options = this.$options;\n            optionNames = Object.keys(options).filter(function(key) {\n                return !options[key].hidden;\n            });\n        } else if (!Array.isArray(optionNames)) {\n            optionNames = Object.keys(optionNames);\n        }\n        optionNames.forEach(function(key) {\n            result[key] = this.getOption(key);\n        }, this);\n        return result;\n    },\n    setOption: function(name, value) {\n        if (this[\"$\" + name] === value)\n            return;\n        //@ts-ignore\n        var opt = this.$options[name];\n        if (!opt) {\n            return warn('misspelled option \"' + name + '\"');\n        }\n        if (opt.forwardTo)\n            return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);\n\n        if (!opt.handlesSet)\n            this[\"$\" + name] = value;\n        if (opt && opt.set)\n            opt.set.call(this, value);\n    },\n    getOption: function(name) {\n        var opt = this.$options[name];\n        if (!opt) {\n            return warn('misspelled option \"' + name + '\"');\n        }\n        if (opt.forwardTo)\n            return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);\n        return opt && opt.get ? opt.get.call(this) : this[\"$\" + name];\n    }\n};\n\nfunction warn(message) {\n    if (typeof console != \"undefined\" && console.warn)\n        console.warn.apply(console, arguments);\n}\n\nvar messages;\nvar nlsPlaceholders;\n\nclass AppConfig {\n    constructor() {\n            this.$defaultOptions = {};\n            messages = defaultEnglishMessages;\n            nlsPlaceholders = \"dollarSigns\";\n        }\n\n    /**\n     * @param {Object} obj\n     * @param {string} path\n     * @param {{ [key: string]: any }} options\n     * @returns {import(\"../../ace-internal\").Ace.AppConfig}\n     */\n    defineOptions(obj, path, options) {\n        if (!obj.$options)\n            this.$defaultOptions[path] = obj.$options = {};\n\n        Object.keys(options).forEach(function(key) {\n            var opt = options[key];\n            if (typeof opt == \"string\")\n                opt = {forwardTo: opt};\n\n            opt.name || (opt.name = key);\n            obj.$options[opt.name] = opt;\n            if (\"initialValue\" in opt)\n                obj[\"$\" + opt.name] = opt.initialValue;\n        });\n\n        // implement option provider interface\n        oop.implement(obj, optionsProvider);\n\n        return this;\n    }\n\n    /**\n     * @param {Object} obj\n     */\n    resetOptions(obj) {\n        Object.keys(obj.$options).forEach(function(key) {\n            var opt = obj.$options[key];\n            if (\"value\" in opt)\n                obj.setOption(key, opt.value);\n        });\n    }\n\n    /**\n     * @param {string} path\n     * @param {string} name\n     * @param {any} value\n     */\n    setDefaultValue(path, name, value) {\n        if (!path) {\n            for (path in this.$defaultOptions)\n                if (this.$defaultOptions[path][name])\n                    break;\n            if (!this.$defaultOptions[path][name])\n                return false;\n        }\n        var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});\n        if (opts[name]) {\n            if (opts.forwardTo)\n                this.setDefaultValue(opts.forwardTo, name, value);\n            else\n                opts[name].value = value;\n        }\n    }\n\n    /**\n     * @param {string} path\n     * @param {{ [key: string]: any; }} optionHash\n     */\n    setDefaultValues(path, optionHash) {\n        Object.keys(optionHash).forEach(function(key) {\n            this.setDefaultValue(path, key, optionHash[key]);\n        }, this);\n    }\n\n    /**\n     * @param {any} value\n     * @param {{placeholders?: \"dollarSigns\" | \"curlyBrackets\"}} [options]\n     */\n    setMessages(value, options) {\n        messages = value;\n        if (options && options.placeholders) {\n            nlsPlaceholders = options.placeholders;\n        }\n    }\n\n    /**\n     * @param {string} key\n     * @param {string} defaultString\n     * @param {{ [x: string]: any; }} [params]\n     */\n    nls(key, defaultString, params) {\n        if (!messages[key])  {\n            warn(\"No message found for the key '\" + key + \"' in messages with id \" + messages.$id + \", trying to find a translation for the default string '\" + defaultString + \"'.\");\n            if (!messages[defaultString]) {\n                warn(\"No message found for the default string '\" + defaultString + \"' in the provided messages. Falling back to the default English message.\");\n            }\n        }\n\n        var translated = messages[key] || messages[defaultString] || defaultString;\n        if (params) {\n            // We support both $n or {n} as placeholder indicators in the provided translated strings\n            if (nlsPlaceholders === \"dollarSigns\") {\n                // Replace $n with the nth element in params\n                translated = translated.replace(/\\$(\\$|[\\d]+)/g, function(_, dollarMatch) {\n                    if (dollarMatch == \"$\") return \"$\";\n                    return params[dollarMatch];\n                });\n            }\n            if (nlsPlaceholders === \"curlyBrackets\") {\n                // Replace {n} with the nth element in params\n                translated = translated.replace(/\\{([^\\}]+)\\}/g, function(_, curlyBracketMatch) {\n                    return params[curlyBracketMatch];\n                });\n            }\n        }\n        return translated;\n    }\n}\nAppConfig.prototype.warn = warn;\nAppConfig.prototype.reportError = reportError;\n\n// module loading\noop.implement(AppConfig.prototype, EventEmitter);\n\nexports.AppConfig = AppConfig;\n"
  },
  {
    "path": "src/lib/bidiutil.js",
    "content": "\"use strict\";\n\nvar ArabicAlefBetIntervalsBegine = ['\\u0621', '\\u0641'];\nvar ArabicAlefBetIntervalsEnd = ['\\u063A', '\\u064a'];\nvar dir = 0, hiLevel = 0;\nvar lastArabic = false, hasUBAT_AL = false,  hasUBAT_B = false,  hasUBAT_S = false, hasBlockSep = false, hasSegSep = false;\n\nvar impTab_LTR = [\n\t\t\t\t/*\t\tL,\t\tR,\t\tEN,\t\tAN,\t\tN,\t\tIL,\t\tCond */\n/* 0 LTR text\t*/\t[\t0,\t\t3,\t\t0,\t\t1,\t\t0,\t\t0,\t\t0\t],\n/* 1 LTR+AN\t\t*/\t[\t0,\t\t3,\t\t0,\t\t1,\t\t2,\t\t2,\t\t0\t],\n/* 2 LTR+AN+N\t*/\t[\t0,\t\t3,\t\t0,\t\t0x11,\t\t2,\t\t0,\t\t1\t],\n/* 3 RTL text\t*/\t[\t0,\t\t3,\t\t5,\t\t5,\t\t4,\t\t1,\t\t0\t],\n/* 4 RTL cont\t*/\t[\t0,\t\t3,\t\t0x15,\t\t0x15,\t\t4,\t\t0,\t\t1\t],\n/* 5 RTL+EN/AN\t*/\t[\t0,\t\t3,\t\t5,\t\t5,\t\t4,\t\t2,\t\t0\t]\n];\n\nvar impTab_RTL = [\n\t\t/*\t\tL,\t\tR,\t\tEN,\t\tAN,\t\tN,\t\tIL,\t\tCond */\n/* 0 RTL text\t*/\t[\t2,\t\t0,\t\t1,\t\t1,\t\t0,\t\t1,\t\t0\t],\n/* 1 RTL+EN/AN\t*/\t[\t2,\t\t0,\t\t1,\t\t1,\t\t0,\t\t2,\t\t0\t],\n/* 2 LTR text\t*/\t[\t2,\t\t0,\t\t2,\t\t1,\t\t3,\t\t2,\t\t0\t],\n/* 3 LTR+cont\t*/\t[\t2,\t\t0,\t\t2,\t\t0x21,\t\t3,\t\t1,\t\t1\t]\n];\n\nvar LTR = 0, RTL = 1;\n\nvar L = 0; /* left to right */\nvar R = 1; /* right to left */\nvar EN = 2; /* European digit */\nvar AN = 3; /* Arabic-Indic digit */\nvar ON = 4; /* neutral */\nvar B = 5; /* block separator */\nvar S = 6; /* segment separator */\nvar AL = 7; /* Arabic Letter */\nvar WS = 8; /* white space */\nvar CS = 9; /* common digit separator */\nvar ES = 10; /* European digit separator */\nvar ET = 11; /* European digit terminator */\nvar NSM = 12; /* Non Spacing Mark */\nvar LRE = 13; /* LRE */\nvar RLE = 14; /* RLE */\nvar PDF = 15; /* PDF */\nvar LRO = 16; /* LRO */\nvar RLO = 17; /* RLO */\nvar BN = 18; /* Boundary Neutral */\n\nvar UnicodeTBL00 = [\nBN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN,\nBN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S,\nWS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS,\nEN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON,\nON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,\nL,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON,\nON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,\nL,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN,\nBN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,\nBN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,\nCS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON,\nET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON\n];\n\nvar UnicodeTBL20 = [\nWS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R\t,\nON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS,\nET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS\n];\n\nfunction _computeLevels(chars, levels, len, charTypes) {\n\tvar impTab = dir ? impTab_RTL : impTab_LTR\n\t\t, prevState = null, newClass = null, newLevel = null, newState = 0\n\t\t, action = null, cond = null, condPos = -1, i = null, ix = null, classes = [];\n\n\tif (!charTypes) {\n\t\tfor (i = 0, charTypes = []; i < len; i++) {\n\t\t\tcharTypes[i] = _getCharacterType(chars[i]);\n\t\t}\n\t}\n\thiLevel = dir;\n\tlastArabic = false;\n\thasUBAT_AL = false;\n\thasUBAT_B = false;\n\thasUBAT_S = false;\n\tfor (ix = 0; ix < len; ix++){\n\t\tprevState = newState;\n\t\tclasses[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);\n\t\tnewState = impTab[prevState][newClass];\n\t\taction = newState & 0xF0;\n\t\tnewState &= 0x0F;\n\t\tlevels[ix] = newLevel = impTab[newState][5];\n\t\tif (action > 0){\n\t\t\tif (action == 0x10){\n\t\t\t\tfor(i = condPos; i < ix; i++){\n\t\t\t\t\tlevels[i] = 1;\n\t\t\t\t}\n\t\t\t\tcondPos = -1;\n\t\t\t} else {\n\t\t\t\tcondPos = -1;\n\t\t\t}\n\t\t}\n\t\tcond = impTab[newState][6];\n\t\tif (cond){\n\t\t\tif(condPos == -1){\n\t\t\t\tcondPos = ix;\n\t\t\t}\n\t\t}else{\n\t\t\tif (condPos > -1){\n\t\t\t\tfor(i = condPos; i < ix; i++){\n\t\t\t\t\tlevels[i] = newLevel;\n\t\t\t\t}\n\t\t\t\tcondPos = -1;\n\t\t\t}\n\t\t}\n\t\tif (charTypes[ix] == B){\n\t\t\tlevels[ix] = 0;\n\t\t}\n\t\thiLevel |= newLevel;\n\t}\n\tif (hasUBAT_S){\n\t\tfor(i = 0; i < len; i++){\n\t\t\tif(charTypes[i] == S){\n\t\t\t\tlevels[i] = dir;\n\t\t\t\tfor(var j = i - 1; j >= 0; j--){\n\t\t\t\t\tif(charTypes[j] == WS){\n\t\t\t\t\t\tlevels[j] = dir;\n\t\t\t\t\t}else{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction _invertLevel(lev, levels, _array) {\n\tif (hiLevel < lev){\n\t\treturn;\n\t}\n\tif (lev == 1 && dir == RTL && !hasUBAT_B){\n\t\t_array.reverse();\n\t\treturn;\n\t}\n\tvar len = _array.length, start = 0, end, lo, hi, tmp;\n\twhile(start < len){\n\t\tif (levels[start] >= lev){\n\t\t\tend = start + 1;\n\t\twhile(end < len && levels[end] >= lev){\n\t\t\tend++;\n\t\t}\n\t\tfor(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){\n\t\t\ttmp = _array[lo];\n\t\t\t_array[lo] = _array[hi];\n\t\t\t_array[hi] = tmp;\n\t\t}\n\t\tstart = end;\n\t}\n\tstart++;\n\t}\n}\n\nfunction _getCharClass(chars, types, classes, ix) {\t\t\t\n\tvar cType = types[ix], wType, nType, len, i;\n\tswitch(cType){\n\t\tcase L:\n\t\tcase R:\n\t\t\tlastArabic = false;\n\t\tcase ON:\n\t\tcase AN:\n\t\t\treturn cType;\n\t\tcase EN:\n\t\t\treturn lastArabic ? AN : EN;\n\t\tcase AL:\n\t\t\tlastArabic = true;\n\t\t\thasUBAT_AL = true;\n\t\t\treturn R;\n\t\tcase WS:\n\t\t\treturn ON;\n\t\tcase CS:\n\t\t\tif (ix < 1 || (ix + 1) >= types.length ||\n\t\t\t\t((wType = classes[ix - 1]) != EN && wType != AN) ||\n\t\t\t\t((nType = types[ix + 1]) != EN && nType != AN)){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\tif (lastArabic){nType = AN;}\n\t\t\treturn nType == wType ? nType : ON;\n\t\tcase ES:\n\t\t\twType = ix > 0 ? classes[ix - 1] : B;\n\t\t\tif (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\treturn ON;\n\t\tcase ET:\n\t\t\tif (ix > 0 && classes[ix - 1] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\tif (lastArabic){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\ti = ix + 1;\n\t\t\tlen = types.length;\n\t\t\twhile (i < len && types[i] == ET){\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i < len && types[i] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\treturn ON;\n\t\tcase NSM:\n\t\t\tlen = types.length;\n\t\t\ti = ix + 1;\n\t\t\twhile (i < len && types[i] == NSM){\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i < len){\n\t\t\t\tvar c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E;\n\t\t\t\t\n\t\t\t\twType = types[i];\n\t\t\t\tif (rtlCandidate && (wType == R || wType == AL)){\n\t\t\t\t\treturn R;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ix < 1 || (wType = types[ix - 1]) == B){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\treturn classes[ix - 1];\n\t\tcase B:\n\t\t\tlastArabic = false;\n\t\t\thasUBAT_B = true;\n\t\t\treturn dir;\n\t\tcase S:\n\t\t\thasUBAT_S = true;\n\t\t\treturn ON;\n\t\tcase LRE:\n\t\tcase RLE:\n\t\tcase LRO:\n\t\tcase RLO:\n\t\tcase PDF:\n\t\t\tlastArabic = false;\n\t\tcase BN:\n\t\t\treturn ON;\n\t}\n}\n\nfunction _getCharacterType( ch ) {\t\t\n\tvar uc = ch.charCodeAt(0), hi = uc >> 8;\n\t\n\tif (hi == 0) {\t\t\n\t\treturn ((uc > 0x00BF) ? L : UnicodeTBL00[uc]);\n\t} else if (hi == 5) {\n\t\treturn (/[\\u0591-\\u05f4]/.test(ch) ? R : L);\n\t} else if (hi == 6) {\n\t\tif (/[\\u0610-\\u061a\\u064b-\\u065f\\u06d6-\\u06e4\\u06e7-\\u06ed]/.test(ch))\n\t\t\treturn NSM;\n\t\telse if (/[\\u0660-\\u0669\\u066b-\\u066c]/.test(ch))\n\t\t\treturn AN;\n\t\telse if (uc == 0x066A)\n\t\t\treturn ET;\n\t\telse if (/[\\u06f0-\\u06f9]/.test(ch))\n\t\t\treturn EN;\t\t\t\n\t\telse\n\t\t\treturn AL;\n\t} else if (hi == 0x20 && uc <= 0x205F) {\n\t\treturn UnicodeTBL20[uc & 0xFF];\n\t} else if (hi == 0xFE) {\n\t\treturn (uc >= 0xFE70 ? AL : ON);\n\t}\t\t\n\treturn ON;\t\n}\n\nfunction _isArabicDiacritics( ch ) {\n\treturn (ch >= '\\u064b' && ch <= '\\u0655');\n}\n\n/* Strong LTR character (0 - even), regular width */\nexports.L = L;\n/* Strong RTL character (1 - odd), Bidi width */\nexports.R = R;\n/* European digit (2 - even), regular width */\nexports.EN = EN;\n/* Neutral RTL-by-context character (3 - odd), regular width */\nexports.ON_R = 3;\n/* Hindi (Arabic) digit (4 - even), Bidi width */\nexports.AN = 4;\n/* Arabic LamAlef (5 - odd), Half Bidi width */\nexports.R_H = 5;\n/* invisible EOL (6 - even), zero width */\nexports.B = 6;\n/* invisible RLE (7 - odd), zero width */\nexports.RLE = 7;\n\nexports.DOT = \"\\xB7\";\n\n/**\n * Performs text reordering by implementing Unicode Bidi algorithm\n * with aim to produce logical<->visual map and Bidi levels\n * @param {String} text string to be reordered\n * @param {Array} textCharTypes unicode character types produced by call to 'hasBidiCharacters'\n * @param {Boolean} isRtl 'true' for right-to-left text direction, otherwise 'false'\n *\n * @return {Object} An object containing logicalFromVisual map and Bidi levels\n **/\nexports.doBidiReorder = function(text, textCharTypes, isRtl) {\n\tif (text.length < 2)\n\t\treturn {};\n\t\t\n\tvar chars = text.split(\"\"), logicalFromVisual = new Array(chars.length),\n\t\tbidiLevels = new Array(chars.length), levels = []; \n\n\tdir = isRtl ? RTL : LTR;\n\n\t_computeLevels(chars, levels, chars.length, textCharTypes);\n\n\tfor (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);\n\n\t_invertLevel(2, levels, logicalFromVisual);\n\t_invertLevel(1, levels, logicalFromVisual);\n\n\tfor (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width\n\t\tif (textCharTypes[i] === AN) {\n\t\t\tlevels[i] = exports.AN;\n\t\t} else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE) \n\t\t\t|| textCharTypes[i] === ON || textCharTypes[i] === BN)) {\n\t\t\tlevels[i] = exports.ON_R;\n\t\t} else if ((i > 0 && chars[i - 1] === '\\u0644') && /\\u0622|\\u0623|\\u0625|\\u0627/.test(chars[i])) {\n\t\t\tlevels[i - 1] = levels[i] = exports.R_H;\n\t\t\ti++;\n\t\t}\n\t}\n\t/* fix level to mark zero length EOL */\n\tif (chars[chars.length - 1] === exports.DOT)\n\t\tlevels[chars.length - 1] = exports.B;\n\t\t\t\t\n\tif (chars[0] === '\\u202B')\n\t\tlevels[0] = exports.RLE;\n\t\t\t\t\n\tfor (var i = 0; i < logicalFromVisual.length; i++) {\n\t\tbidiLevels[i] = levels[logicalFromVisual[i]];\n\t}\n\n\treturn {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels};\n};\t\n\n/**\n * Performs character classification, to be used in Unicode Bidi algorithm.\n * @param {String} text string to be reordered\n * @param {Array} textCharTypes unicode character types (to be filled by this method)\n *\n * @return {Boolean} 'true' if text contains Bidi characters, otherwise 'false' \n **/\nexports.hasBidiCharacters = function(text, textCharTypes){\n\tvar ret = false;\n\tfor (var i = 0; i < text.length; i++){\n\t\ttextCharTypes[i] = _getCharacterType(text.charAt(i));\n\t\tif (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL || textCharTypes[i] == AN))\n\t\t\tret = true;\n\t}\n\treturn ret;\n};\n\n/**\n * Returns visual index corresponding to logical index basing on logicalFromvisual \n * map provided by Unicode Bidi algorithm.\n * @param {Number} logIdx logical index of character in text buffer\n * @param {Object} rowMap object containing logicalFromVisual map\n *\n * @return {Number} visual index (on display) corresponding to logical index\n **/\t\nexports.getVisualFromLogicalIdx = function(logIdx, rowMap) {\n\tfor (var i = 0; i < rowMap.logicalFromVisual.length; i++) {\n\t\tif (rowMap.logicalFromVisual[i] == logIdx)\n\t\t\treturn i;\n\t}\n\treturn 0;\n};\n"
  },
  {
    "path": "src/lib/deep_copy.js",
    "content": "exports.deepCopy = function deepCopy(obj) {\n    if (typeof obj !== \"object\" || !obj)\n        return obj;\n    var copy;\n    if (Array.isArray(obj)) {\n        copy = [];\n        for (let key = 0; key < obj.length; key++) {\n            copy[key] = deepCopy(obj[key]);\n        }\n        return copy;\n    }\n    if (Object.prototype.toString.call(obj) !== \"[object Object]\")\n        return obj;\n    \n    copy = {};\n    for (let key in obj)\n        copy[key] = deepCopy(obj[key]);\n    return copy;\n};\n"
  },
  {
    "path": "src/lib/default_english_messages.js",
    "content": "var defaultEnglishMessages = {\n    \"autocomplete.popup.aria-roledescription\": \"Autocomplete suggestions\",\n    \"autocomplete.popup.aria-label\": \"Autocomplete suggestions\",\n    \"autocomplete.popup.item.aria-roledescription\": \"item\",\n    \"autocomplete.loading\": \"Loading...\",\n    \"editor.scroller.aria-roledescription\": \"editor\",\n    \"editor.scroller.aria-label\": \"Editor content, press Enter to start editing, press Escape to exit\",\n    \"editor.gutter.aria-roledescription\": \"editor gutter\",\n    \"editor.gutter.aria-label\": \"Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit\",\n    \"error-marker.good-state\": \"Looks good!\",\n    \"prompt.recently-used\": \"Recently used\",\n    \"prompt.other-commands\": \"Other commands\",\n    \"prompt.no-matching-commands\": \"No matching commands\",\n    \"search-box.find.placeholder\": \"Search for\",\n    \"search-box.find-all.text\": \"All\",\n    \"search-box.replace.placeholder\": \"Replace with\",\n    \"search-box.replace-next.text\": \"Replace\",\n    \"search-box.replace-all.text\": \"All\",\n    \"search-box.toggle-replace.title\": \"Toggle Replace mode\",\n    \"search-box.toggle-regexp.title\": \"RegExp Search\",\n    \"search-box.toggle-case.title\": \"CaseSensitive Search\",\n    \"search-box.toggle-whole-word.title\": \"Whole Word Search\",\n    \"search-box.toggle-in-selection.title\": \"Search In Selection\",\n    \"search-box.search-counter\": \"$0 of $1\",\n    \"text-input.aria-roledescription\": \"editor\",\n    \"text-input.aria-label\": \"Cursor at row $0\",\n    \"gutter.code-folding.range.aria-label\": \"Toggle code folding, rows $0 through $1\",\n    \"gutter.code-folding.closed.aria-label\": \"Toggle code folding, rows $0 through $1\",\n    \"gutter.code-folding.open.aria-label\": \"Toggle code folding, row $0\",\n    \"gutter.code-folding.closed.title\": \"Unfold code\",\n    \"gutter.code-folding.open.title\": \"Fold code\",\n    \"gutter.annotation.aria-label.error\": \"Error, read annotations row $0\",\n    \"gutter.annotation.aria-label.warning\": \"Warning, read annotations row $0\",\n    \"gutter.annotation.aria-label.info\": \"Info, read annotations row $0\",\n    \"inline-fold.closed.title\": \"Unfold code\",\n    \"gutter-tooltip.aria-label.error.singular\": \"error\",\n    \"gutter-tooltip.aria-label.error.plural\": \"errors\",\n    \"gutter-tooltip.aria-label.warning.singular\": \"warning\",\n    \"gutter-tooltip.aria-label.warning.plural\": \"warnings\",\n    \"gutter-tooltip.aria-label.info.singular\": \"information message\",\n    \"gutter-tooltip.aria-label.info.plural\": \"information messages\",\n    \"gutter.annotation.aria-label.security\": \"Security finding, read annotations row $0\",\n    \"gutter.annotation.aria-label.hint\": \"Suggestion, read annotations row $0\",\n    \"gutter-tooltip.aria-label.security.singular\": \"security finding\",\n    \"gutter-tooltip.aria-label.security.plural\": \"security findings\",\n    \"gutter-tooltip.aria-label.hint.singular\": \"suggestion\",\n    \"gutter-tooltip.aria-label.hint.plural\": \"suggestions\",\n    \"editor.tooltip.disable-editing\": \"Editing is disabled\"\n}\n\nexports.defaultEnglishMessages = defaultEnglishMessages;"
  },
  {
    "path": "src/lib/dom.js",
    "content": "\"use strict\";\n\nvar useragent = require(\"./useragent\"); \nvar XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n\n/**\n * @template {keyof HTMLElementTagNameMap} K\n * @overload\n * @param {[K, ...any[]]} arr\n * @param {HTMLElement} [parent]\n * @param {Record<string, Node>} [refs]\n * @returns {HTMLElementTagNameMap[K]} \n */\n/**\n * @overload\n * @param {any} arr\n * @param {HTMLElement} [parent]\n * @param [refs]\n * @returns {HTMLElement | Text | any[]} \n */\nexports.buildDom = function buildDom(arr, parent, refs) {\n    if (typeof arr == \"string\" && arr) {\n        var txt = document.createTextNode(arr);\n        if (parent)\n            parent.appendChild(txt);\n        return txt;\n    }\n    \n    if (!Array.isArray(arr)) {\n        if (arr && arr.appendChild && parent)\n            parent.appendChild(arr);\n        return arr;\n    }\n    if (typeof arr[0] != \"string\" || !arr[0]) {\n        var els = [];\n        for (var i = 0; i < arr.length; i++) {\n            var ch = buildDom(arr[i], parent, refs);\n            ch && els.push(ch);\n        }\n        return els;\n    }\n    \n    var el = document.createElement(arr[0]);\n    var options = arr[1];\n    var childIndex = 1;\n    if (options && typeof options == \"object\" && !Array.isArray(options))\n        childIndex = 2;\n    for (var i = childIndex; i < arr.length; i++)\n        buildDom(arr[i], el, refs);\n    if (childIndex == 2) {\n        Object.keys(options).forEach(function(n) {\n            var val = options[n];\n            if (n === \"class\") {\n                el.className = Array.isArray(val) ? val.join(\" \") : val;\n            } else if (typeof val == \"function\" || n == \"value\" || n[0] == \"$\") {\n                el[n] = val;\n            } else if (n === \"ref\") {\n                if (refs) refs[val] = el;\n            } else if (n === \"style\") {\n                if (typeof val == \"string\") el.style.cssText = val;\n            } else if (val != null) {\n                el.setAttribute(n, val);\n            }\n        });\n    }\n    if (parent)\n        parent.appendChild(el);\n    return el;\n};\n\n/**\n * \n * @param {Document} [doc]\n * @returns {HTMLHeadElement|HTMLElement}\n */\nexports.getDocumentHead = function(doc) {\n    if (!doc)\n        doc = document;\n    return doc.head || doc.getElementsByTagName(\"head\")[0] || doc.documentElement;\n};\n\n\n/**\n * @template {keyof HTMLElementTagNameMap} T\n * @param {T | string} tag\n * @param {string} [ns]\n * @returns {HTMLElementTagNameMap[T]}\n */\nexports.createElement = function(tag, ns) {\n    // @ts-expect-error\n    return document.createElementNS ? document.createElementNS(ns || XHTML_NS, tag) : document.createElement(tag);\n};\n\n/**\n * @param {HTMLElement} element\n */\nexports.removeChildren = function(element) {\n    element.innerHTML = \"\";\n};\n\n/**\n * @param {string} textContent\n * @param {HTMLElement} [element]\n * @returns {Text}\n */\nexports.createTextNode = function(textContent, element) {\n    var doc = element ? element.ownerDocument : document;\n    return doc.createTextNode(textContent);\n};\n\n/**\n * @param {HTMLElement} [element]\n * @returns {DocumentFragment}\n */\nexports.createFragment = function(element) {\n    var doc = element ? element.ownerDocument : document;\n    return doc.createDocumentFragment();\n};\n\n/**\n * @param {HTMLElement} el\n * @param {string} name\n * @returns {boolean}\n */\nexports.hasCssClass = function(el, name) {\n    var classes = (el.className + \"\").split(/\\s+/g);\n    return classes.indexOf(name) !== -1;\n};\n\n/**\n * Add a CSS class to the list of classes on the given node\n * @param {HTMLElement} el\n * @param {string} name\n*/\nexports.addCssClass = function(el, name) {\n    if (!exports.hasCssClass(el, name)) {\n        el.className += \" \" + name;\n    }\n};\n\n/**\n * Remove a CSS class from the list of classes on the given node\n * @param {HTMLElement} el\n * @param {string} name\n */\nexports.removeCssClass = function(el, name) {\n    var classes = el.className.split(/\\s+/g);\n    while (true) {\n        var index = classes.indexOf(name);\n        if (index == -1) {\n            break;\n        }\n        classes.splice(index, 1);\n    }\n    el.className = classes.join(\" \");\n};\n\n/**\n * @param {HTMLElement} el\n * @param {string} name\n * @returns {boolean}\n */\nexports.toggleCssClass = function(el, name) {\n    var classes = el.className.split(/\\s+/g), add = true;\n    while (true) {\n        var index = classes.indexOf(name);\n        if (index == -1) {\n            break;\n        }\n        add = false;\n        classes.splice(index, 1);\n    }\n    if (add)\n        classes.push(name);\n\n    el.className = classes.join(\" \");\n    return add;\n};\n\n/**\n * Add or remove a CSS class from the list of classes on the given node\n * depending on the value of <tt>include</tt>\n * @param {HTMLElement} node\n * @param {string} className\n * @param {boolean} include\n */\nexports.setCssClass = function(node, className, include) {\n    if (include) {\n        exports.addCssClass(node, className);\n    } else {\n        exports.removeCssClass(node, className);\n    }\n};\n\n/**\n * @param {string} id\n * @param {Document} [doc]\n * @returns {boolean}\n */\nexports.hasCssString = function(id, doc) {\n    var index = 0, sheets;\n    doc = doc || document;\n    if ((sheets = doc.querySelectorAll(\"style\"))) {\n        while (index < sheets.length) {\n            if (sheets[index++].id === id) {\n                return true;\n            }\n        }\n    }\n};\n\n/**\n * @param {string} id\n * @param {Document} [doc]\n */\nexports.removeElementById = function(id, doc) {\n    doc = doc || document;\n    if(doc.getElementById(id)) {\n        doc.getElementById(id).remove();\n    }\n};\n\nvar strictCSP;\nvar cssCache = [];\nexports.useStrictCSP = function(value) {\n    strictCSP = value;\n    if (value == false) insertPendingStyles();\n    else if (!cssCache) cssCache = [];\n};\n\nfunction insertPendingStyles() {\n    var cache = cssCache;\n    cssCache = null;\n    cache && cache.forEach(function(item) {\n        importCssString(item[0], item[1]);\n    });\n}\n\n/**\n * @param {string} cssText\n * @param {string} [id]\n * @param {any} [target]\n */\nfunction importCssString(cssText, id, target) {\n    if (typeof document == \"undefined\")\n        return;\n    if (cssCache) {\n        if (target) {\n            insertPendingStyles();\n        } else if (target === false) {\n            return cssCache.push([cssText, id]);\n        }\n    }\n    if (strictCSP) return;\n\n    var container = target;\n    if (!target || !target.getRootNode) {\n        container = document;\n    } else {\n        container = target.getRootNode();\n        if (!container || container == target)\n            container = document;\n    }\n    \n    var doc = container.ownerDocument || container;\n    \n    // If style is already imported return immediately.\n    if (id && exports.hasCssString(id, container))\n        return null;\n    \n    if (id)\n        cssText += \"\\n/*# sourceURL=ace/css/\" + id + \" */\";\n    \n    var style = exports.createElement(\"style\");\n    style.appendChild(doc.createTextNode(cssText));\n    if (id)\n        style.id = id;\n\n    if (container == doc)\n        container = exports.getDocumentHead(doc);\n    container.insertBefore(style, container.firstChild);\n}\nexports.importCssString = importCssString;\n\n/**\n * @param {string} uri\n * @param {Document} [doc]\n */\nexports.importCssStylsheet = function(uri, doc) {\n    exports.buildDom([\"link\", {rel: \"stylesheet\", href: uri}], exports.getDocumentHead(doc));\n};\n\n/**\n * Due to bug in html specification fixed position elements are placed relative to \n * ancestor with transform instead of screen, so we attempt to detect and compensate for that\n * @param {HTMLElement} el with position: fixed\n */\nexports.$fixPositionBug = function(el) {\n    var rect = el.getBoundingClientRect();\n    if (el.style.left) {\n        var target = parseFloat(el.style.left);\n        var result = +rect.left;\n        if (Math.abs(target - result) > 1) {\n            el.style.left = 2 * target - result + \"px\";\n        }\n    }\n    if (el.style.right) {\n        var target = parseFloat(el.style.right);\n        var result = window.innerWidth - rect.right;\n        if (Math.abs(target - result) > 1) {\n            el.style.right = 2 * target - result + \"px\";\n        }\n    }\n    if (el.style.top) {\n        var target = parseFloat(el.style.top);\n        var result = +rect.top;\n        if (Math.abs(target - result) > 1) {\n            el.style.top = 2 * target - result + \"px\";\n        }\n    }\n    if (el.style.bottom) {\n        var target = parseFloat(el.style.bottom);\n        var result = window.innerHeight - rect.bottom;\n        if (Math.abs(target - result) > 1) {\n            el.style.bottom = 2 * target - result + \"px\";\n        }\n    }\n};\n\n/**\n * @param {Document} [doc]\n * @returns {number}\n */\nexports.scrollbarWidth = function(doc) {\n    var inner = exports.createElement(\"ace_inner\");\n    inner.style.width = \"100%\";\n    inner.style.minWidth = \"0px\";\n    inner.style.height = \"200px\";\n    inner.style.display = \"block\";\n\n    var outer = exports.createElement(\"ace_outer\");\n    var style = outer.style;\n\n    style.position = \"absolute\";\n    style.left = \"-10000px\";\n    style.overflow = \"hidden\";\n    style.width = \"200px\";\n    style.minWidth = \"0px\";\n    style.height = \"150px\";\n    style.display = \"block\";\n\n    outer.appendChild(inner);\n\n    var body = (doc && doc.documentElement) || (document && document.documentElement);\n    if (!body) return 0;\n\n    body.appendChild(outer);\n\n    var noScrollbar = inner.offsetWidth;\n\n    style.overflow = \"scroll\";\n    var withScrollbar = inner.offsetWidth;\n\n    if (noScrollbar === withScrollbar) {\n        withScrollbar = outer.clientWidth;\n    }\n\n    body.removeChild(outer);\n\n    return noScrollbar - withScrollbar;\n};\n\n/**\n * @param {Element} element\n * @param [style]\n * @returns {Partial<CSSStyleDeclaration>}\n */\nexports.computedStyle = function(element, style) {\n    return window.getComputedStyle(element, \"\") || {};\n};\n\n/**\n * \n * @param {CSSStyleDeclaration} styles\n * @param {string} property\n * @param {string} value\n */\nexports.setStyle = function(styles, property, value) {\n    if (styles[property] !== value) {\n        //console.log(\"set style\", property, styles[property], value);\n        styles[property] = value;\n    }\n};\n\nexports.HAS_CSS_ANIMATION = false;\nexports.HAS_CSS_TRANSFORMS = false;\nexports.HI_DPI = useragent.isWin\n    ? typeof window !== \"undefined\" && window.devicePixelRatio >= 1.5\n    : true;\n\nif (useragent.isChromeOS) exports.HI_DPI = false;\n\nif (typeof document !== \"undefined\") {\n    // detect CSS transformation support\n    var div = document.createElement(\"div\");\n    if (exports.HI_DPI && div.style.transform  !== undefined)\n        exports.HAS_CSS_TRANSFORMS = true;\n    if (!useragent.isEdge && typeof div.style.animationName !== \"undefined\")\n        exports.HAS_CSS_ANIMATION = true;\n    div = null;\n}\n\nif (exports.HAS_CSS_TRANSFORMS) {\n    exports.translate = function(element, tx, ty) {\n        element.style.transform = \"translate(\" + Math.round(tx) + \"px, \" + Math.round(ty) +\"px)\";\n    };\n} else {\n    exports.translate = function(element, tx, ty) {\n        element.style.top = Math.round(ty) + \"px\";\n        element.style.left = Math.round(tx) + \"px\";\n    };\n}\n"
  },
  {
    "path": "src/lib/es6-shim.js",
    "content": "function defineProp(obj, name, val) {\n    Object.defineProperty(obj, name, {\n      value: val,\n      enumerable: false,\n      writable: true,\n      configurable: true\n    });\n  }\n  if (!String.prototype.startsWith) {\n    defineProp(\n      String.prototype,\n      \"startsWith\",\n      function (searchString, position) {\n        position = position || 0;\n        return this.lastIndexOf(searchString, position) === position;\n      }\n    );\n  }\n  if (!String.prototype.endsWith) {\n    // Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\n    defineProp(String.prototype, \"endsWith\", function (searchString, position) {\n      var subjectString = this;\n      if (position === undefined || position > subjectString.length) {\n        position = subjectString.length;\n      }\n      position -= searchString.length;\n      var lastIndex = subjectString.indexOf(searchString, position);\n      return lastIndex !== -1 && lastIndex === position;\n    });\n  }\n  if (!String.prototype.repeat) {\n    defineProp(String.prototype, \"repeat\", function (count) {\n      var result = \"\";\n      var string = this;\n      while (count > 0) {\n        if (count & 1) result += string;\n\n        if ((count >>= 1)) string += string;\n      }\n      return result;\n    });\n  }\n  if (!String.prototype.includes) {\n    defineProp(String.prototype, \"includes\", function (str, position) {\n      return this.indexOf(str, position) != -1;\n    });\n  }\n  if (!Object.assign) {\n    Object.assign = function (target) {\n      if (target === undefined || target === null) {\n        throw new TypeError(\"Cannot convert undefined or null to object\");\n      }\n\n      var output = Object(target);\n      for (var index = 1; index < arguments.length; index++) {\n        var source = arguments[index];\n        if (source !== undefined && source !== null) {\n          Object.keys(source).forEach(function (key) {\n            output[key] = source[key];\n          });\n        }\n      }\n      return output;\n    };\n  }\n  if (!Object.values) {\n    Object.values = function (o) {\n      return Object.keys(o).map(function (k) {\n        return o[k];\n      });\n    };\n  }\n  if (!Array.prototype.find) {\n    defineProp(Array.prototype, \"find\", function (predicate) {\n      var len = this.length;\n      var thisArg = arguments[1];\n      for (var k = 0; k < len; k++) {\n        var kValue = this[k];\n        if (predicate.call(thisArg, kValue, k, this)) {\n          return kValue;\n        }\n      }\n    });\n  }\n  if (!Array.prototype.findIndex) {\n    defineProp(Array.prototype, \"findIndex\", function (predicate) {\n      var len = this.length;\n      var thisArg = arguments[1];\n      for (var k = 0; k < len; k++) {\n        var kValue = this[k];\n        if (predicate.call(thisArg, kValue, k, this)) {\n          return k;\n        }\n      }\n    });\n  }\n  if (!Array.prototype.includes) {\n    defineProp(Array.prototype, \"includes\", function (item, position) {\n      return this.indexOf(item, position) != -1;\n    });\n  }\n  if (!Array.prototype.fill) {\n    defineProp(Array.prototype, \"fill\", function (value) {\n      var O = this;\n      var len = O.length >>> 0;\n      var start = arguments[1];\n      var relativeStart = start >> 0;\n      var k =\n        relativeStart < 0\n          ? Math.max(len + relativeStart, 0)\n          : Math.min(relativeStart, len);\n      var end = arguments[2];\n      var relativeEnd = end === undefined ? len : end >> 0;\n      var final =\n        relativeEnd < 0\n          ? Math.max(len + relativeEnd, 0)\n          : Math.min(relativeEnd, len);\n      while (k < final) {\n        O[k] = value;\n        k++;\n      }\n      return O;\n    });\n  }\n  if (!Array.of) {\n    defineProp(Array, \"of\", function () {\n      return Array.prototype.slice.call(arguments);\n    });\n  }\n"
  },
  {
    "path": "src/lib/event.js",
    "content": "\"use strict\";\n\n/** @type {any} */var keys = require(\"./keys\");\nvar useragent = require(\"./useragent\");\n\nvar pressedKeys = null;\nvar ts = 0;\n\nvar activeListenerOptions;\nfunction detectListenerOptionsSupport() {\n    activeListenerOptions = false;\n    try {\n        document.createComment(\"\").addEventListener(\"test\", function() {}, { \n            get passive() { \n                activeListenerOptions = {passive: false};\n                return true;\n            }\n        });\n    } catch(e) {}\n}\n\nfunction getListenerOptions() {\n    if (activeListenerOptions == undefined)\n        detectListenerOptionsSupport();\n    return activeListenerOptions;\n}\n\nfunction EventListener(elem, type, callback) {\n    this.elem = elem;\n    this.type = type;\n    this.callback = callback;\n}\nEventListener.prototype.destroy = function() {\n    removeListener(this.elem, this.type, this.callback);\n    this.elem = this.type = this.callback = undefined;\n};\n\n/**\n * Adds an event listener to the specified element.\n *\n * @param {any} elem - The element to add the event listener to.\n * @param {string} type - The type of event to listen for.\n * @param {any} callback - The callback function to be executed when the event is triggered.\n * @param {any} [destroyer] - An optional object that will have the created EventListener instance added to its $toDestroy array, allowing it to be easily destroyed later.\n */\nvar addListener = exports.addListener = function(elem, type, callback, destroyer) {\n    elem.addEventListener(type, callback, getListenerOptions());\n    if (destroyer)\n        destroyer.$toDestroy.push(new EventListener(elem, type, callback));\n};\n\nvar removeListener = exports.removeListener = function(elem, type, callback) {\n    elem.removeEventListener(type, callback, getListenerOptions());\n};\n\n/*\n* Prevents propagation and clobbers the default action of the passed event\n*/\nexports.stopEvent = function(e) {\n    exports.stopPropagation(e);\n    exports.preventDefault(e);\n    return false;\n};\n\nexports.stopPropagation = function(e) {\n    if (e.stopPropagation)\n        e.stopPropagation();\n};\n\nexports.preventDefault = function(e) {\n    if (e.preventDefault)\n        e.preventDefault();\n};\n\n/*\n * @return {Number} 0 for left button, 1 for middle button, 2 for right button\n */\nexports.getButton = function(e) {\n    if (e.type == \"dblclick\")\n        return 0;\n    if (e.type == \"contextmenu\" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))\n        return 2;\n\n    // DOM Event\n    return e.button;\n};\n\nexports.capture = function(el, eventHandler, releaseCaptureHandler) {\n    var ownerDocument = el && el.ownerDocument || document;\n    function onMouseUp(e) {\n        eventHandler && eventHandler(e);\n        releaseCaptureHandler && releaseCaptureHandler(e);\n\n        removeListener(ownerDocument, \"mousemove\", eventHandler);\n        removeListener(ownerDocument, \"mouseup\", onMouseUp);\n        removeListener(ownerDocument, \"dragstart\", onMouseUp);\n    }\n\n    addListener(ownerDocument, \"mousemove\", eventHandler);\n    addListener(ownerDocument, \"mouseup\", onMouseUp);\n    addListener(ownerDocument, \"dragstart\", onMouseUp);\n    \n    return onMouseUp;\n};\n\n/**\n * @param el\n * @param callback\n * @param [destroyer]\n */\nexports.addMouseWheelListener = function(el, callback, destroyer) {\n    addListener(el, \"wheel\",  function(e) {\n        var factor = 0.15;\n        // workaround for firefox changing deltaMode based on which property is accessed first\n        var deltaX = e.deltaX || 0;\n        var deltaY = e.deltaY || 0;\n        switch (e.deltaMode) {\n            case e.DOM_DELTA_PIXEL:\n                e.wheelX = deltaX * factor;\n                e.wheelY = deltaY * factor;\n                break;\n            case e.DOM_DELTA_LINE:\n                var linePixels = 15;\n                e.wheelX = deltaX * linePixels;\n                e.wheelY = deltaY * linePixels;\n                break;\n            case e.DOM_DELTA_PAGE:\n                var pagePixels = 150;\n                e.wheelX = deltaX * pagePixels;\n                e.wheelY = deltaY * pagePixels;\n                break;\n        }\n        callback(e);\n    }, destroyer);\n};\n\n/**\n * @param elements\n * @param timeouts\n * @param eventHandler\n * @param callbackName\n * @param [destroyer]\n */\nexports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName, destroyer) {\n    var clicks = 0;\n    var startX, startY, timer; \n    var eventNames = {\n        2: \"dblclick\",\n        3: \"tripleclick\",\n        4: \"quadclick\"\n    };\n\n    function onMousedown(e) {\n        if (exports.getButton(e) !== 0) {\n            clicks = 0;\n        } else if (e.detail > 1) {\n            clicks++;\n            if (clicks > 4)\n                clicks = 1;\n        } else {\n            clicks = 1;\n        }\n        if (useragent.isIE) {\n            var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;\n            if (!timer || isNewClick)\n                clicks = 1;\n            if (timer)\n                clearTimeout(timer);\n            timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);\n\n            if (clicks == 1) {\n                startX = e.clientX;\n                startY = e.clientY;\n            }\n        }\n        \n        e._clicks = clicks;\n\n        eventHandler[callbackName](\"mousedown\", e);\n\n        if (clicks > 4)\n            clicks = 0;\n        else if (clicks > 1)\n            return eventHandler[callbackName](eventNames[clicks], e);\n    }\n    if (!Array.isArray(elements))\n        elements = [elements];\n    elements.forEach(function(el) {\n        addListener(el, \"mousedown\", onMousedown, destroyer);\n    });\n};\n\n/** @param {KeyboardEvent|MouseEvent} e */\nfunction getModifierHash(e) {\n    return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);\n}\n\n/**\n * @param {KeyboardEvent|MouseEvent} e\n * @returns string\n */\nexports.getModifierString = function(e) {\n    return keys.KEY_MODS[getModifierHash(e)];\n};\n\n/**\n * @param {(e: KeyboardEvent, hashId: number, keyCode: number)=> void } callback\n * @param {KeyboardEvent} e\n * @param {number} keyCode\n */\nfunction normalizeCommandKeys(callback, e, keyCode) {\n    var hashId = getModifierHash(e);\n\n    if (!keyCode && e.code) {\n        keyCode = keys.$codeToKeyCode[e.code] || keyCode;\n    }\n\n    if (!useragent.isMac && pressedKeys) {\n        if (e.getModifierState && (e.getModifierState(\"OS\") || e.getModifierState(\"Win\")))\n            hashId |= 8;\n        if (pressedKeys.altGr) {\n            if ((3 & hashId) != 3)\n                pressedKeys.altGr = 0;\n            else\n                return;\n        }\n        if (keyCode === 18 || keyCode === 17) {\n            var location = e.location;\n            if (keyCode === 17 && location === 1) {\n                if (pressedKeys[keyCode] == 1)\n                    ts = e.timeStamp;\n            } else if (keyCode === 18 && hashId === 3 && location === 2) {\n                var dt = e.timeStamp - ts;\n                if (dt < 50)\n                    pressedKeys.altGr = true;\n            }\n        }\n    }\n    \n    if (keyCode in keys.MODIFIER_KEYS) {\n        keyCode = -1;\n    }\n    \n    if (!hashId && keyCode === 13) {\n        if (e.location === 3) {\n            callback(e, hashId, -keyCode);\n            if (e.defaultPrevented)\n                return;\n        }\n    }\n    \n    if (useragent.isChromeOS && hashId & 8) {\n        callback(e, hashId, keyCode);\n        if (e.defaultPrevented)\n            return;\n        else\n            hashId &= ~8;\n    }\n\n    // If there is no hashId and the keyCode is not a function key, then\n    // we don't call the callback as we don't handle a command key here\n    // (it's a normal key/character input).\n    if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {\n        return false;\n    }\n    \n    return callback(e, hashId, keyCode);\n}\n\n/**\n * @param {EventTarget} el\n * @param {(e: KeyboardEvent, hashId: number, keyCode: number)=>void} callback\n * @param [destroyer]\n */\nexports.addCommandKeyListener = function(el, callback, destroyer) {\n    var lastDefaultPrevented = null;\n\n    addListener(el, \"keydown\", function(e) {\n        pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1;\n        var result = normalizeCommandKeys(callback, e, e.keyCode);\n        lastDefaultPrevented = e.defaultPrevented;\n        return result;\n    }, destroyer);\n\n    addListener(el, \"keypress\", function(e) {\n        if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {\n            exports.stopEvent(e);\n            lastDefaultPrevented = null;\n        }\n    }, destroyer);\n\n    addListener(el, \"keyup\", function(e) {\n        pressedKeys[e.keyCode] = null;\n    }, destroyer);\n\n    if (!pressedKeys) {\n        resetPressedKeys();\n        addListener(window, \"focus\", resetPressedKeys);\n    }\n};\nfunction resetPressedKeys() {\n    pressedKeys = Object.create(null);\n}\n\nif (typeof window == \"object\" && window.postMessage && !useragent.isOldIE) {\n    var postMessageId = 1;\n    exports.nextTick = function(callback, win) {\n        win = win || window;\n        var messageName = \"zero-timeout-message-\" + (postMessageId++);\n        \n        var listener = function(e) {\n            if (e.data == messageName) {\n                exports.stopPropagation(e);\n                removeListener(win, \"message\", listener);\n                callback();\n            }\n        };\n        \n        addListener(win, \"message\", listener);\n        win.postMessage(messageName, \"*\");\n    };\n}\n\nexports.$idleBlocked = false;\n/**\n *\n * @param {CallableFunction} cb\n * @param {number} timeout\n * @return {ReturnType<typeof setTimeout>}\n */\nexports.onIdle = function(cb, timeout) {\n    return setTimeout(function handler() {\n        if (!exports.$idleBlocked) {\n            cb();\n        } else {\n            setTimeout(handler, 100);\n        }\n    }, timeout);\n};\n\n/**@type {null | ReturnType<typeof setTimeout>}*/\nexports.$idleBlockId = null;\n/** @arg [delay] {null | number} */\nexports.blockIdle = function(delay) {\n    if (exports.$idleBlockId)\n        clearTimeout(exports.$idleBlockId);\n        \n    exports.$idleBlocked = true;\n    exports.$idleBlockId = setTimeout(function() {\n        exports.$idleBlocked = false;\n    }, delay || 100);\n};\n\nexports.nextFrame = typeof window == \"object\" && (window.requestAnimationFrame\n    || window[\"mozRequestAnimationFrame\"]\n    || window[\"webkitRequestAnimationFrame\"]\n    || window[\"msRequestAnimationFrame\"]\n    || window[\"oRequestAnimationFrame\"]);\n\nif (exports.nextFrame)\n    exports.nextFrame = exports.nextFrame.bind(window);\nelse\n    exports.nextFrame = function(callback) {\n        setTimeout(callback, 17);\n    };\n"
  },
  {
    "path": "src/lib/event_emitter.js",
    "content": "\"use strict\";\n/**@type {any}*/\nvar EventEmitter = {};\nvar stopPropagation = function() { this.propagationStopped = true; };\nvar preventDefault = function() { this.defaultPrevented = true; };\n\nEventEmitter._emit =\nEventEmitter._dispatchEvent = function(eventName, e) {\n    this._eventRegistry || (this._eventRegistry = {});\n    this._defaultHandlers || (this._defaultHandlers = {});\n\n    var listeners = this._eventRegistry[eventName] || [];\n    var defaultHandler = this._defaultHandlers[eventName];\n    if (!listeners.length && !defaultHandler)\n        return;\n\n    if (typeof e != \"object\" || !e)\n        e = {};\n\n    if (!e.type)\n        e.type = eventName;\n    if (!e.stopPropagation)\n        e.stopPropagation = stopPropagation;\n    if (!e.preventDefault)\n        e.preventDefault = preventDefault;\n\n    listeners = listeners.slice();\n    for (var i=0; i<listeners.length; i++) {\n        listeners[i](e, this);\n        if (e.propagationStopped)\n            break;\n    }\n    \n    if (defaultHandler && !e.defaultPrevented)\n        return defaultHandler(e, this);\n};\n\n\nEventEmitter._signal = function(eventName, e) {\n    var listeners = (this._eventRegistry || {})[eventName];\n    if (!listeners)\n        return;\n    listeners = listeners.slice();\n    for (var i=0; i<listeners.length; i++)\n        listeners[i](e, this);\n};\n\nEventEmitter.once = function(eventName, callback) {\n    var _self = this;\n    this.on(eventName, function newCallback() {\n        _self.off(eventName, newCallback);\n        callback.apply(null, arguments);\n    });\n    if (!callback) {\n        /*global Promise*/\n        return new Promise(function(resolve) {\n            callback = resolve;\n        });\n    }\n};\n\n\nEventEmitter.setDefaultHandler = function(eventName, callback) {\n    /**@type {any}*/\n    var handlers = this._defaultHandlers;\n    if (!handlers)\n        handlers = this._defaultHandlers = {_disabled_: {}};\n    \n    if (handlers[eventName]) {\n        var old = handlers[eventName];\n        var disabled = handlers._disabled_[eventName];\n        if (!disabled)\n            handlers._disabled_[eventName] = disabled = [];\n        disabled.push(old);\n        var i = disabled.indexOf(callback);\n        if (i != -1) \n            disabled.splice(i, 1);\n    }\n    handlers[eventName] = callback;\n};\nEventEmitter.removeDefaultHandler = function(eventName, callback) {\n    var handlers = this._defaultHandlers;\n    if (!handlers)\n        return;\n    var disabled = handlers._disabled_[eventName];\n    \n    if (handlers[eventName] == callback) {\n        if (disabled)\n            this.setDefaultHandler(eventName, disabled.pop());\n    } else if (disabled) {\n        var i = disabled.indexOf(callback);\n        if (i != -1)\n            disabled.splice(i, 1);\n    }\n};\n\nEventEmitter.on =\nEventEmitter.addEventListener = function(eventName, callback, capturing) {\n    this._eventRegistry = this._eventRegistry || {};\n\n    var listeners = this._eventRegistry[eventName];\n    if (!listeners)\n        listeners = this._eventRegistry[eventName] = [];\n\n    if (listeners.indexOf(callback) == -1)\n        listeners[capturing ? \"unshift\" : \"push\"](callback);\n    return callback;\n};\n\nEventEmitter.off =\nEventEmitter.removeListener =\nEventEmitter.removeEventListener = function(eventName, callback) {\n    this._eventRegistry = this._eventRegistry || {};\n\n    var listeners = this._eventRegistry[eventName];\n    if (!listeners)\n        return;\n\n    var index = listeners.indexOf(callback);\n    if (index !== -1)\n        listeners.splice(index, 1);\n};\n/**\n * @this {EventEmitter}\n */\nEventEmitter.removeAllListeners = function(eventName) {\n    if (!eventName) this._eventRegistry = this._defaultHandlers = undefined;\n    if (this._eventRegistry) this._eventRegistry[eventName] = undefined;\n    if (this._defaultHandlers) this._defaultHandlers[eventName] = undefined;\n};\n\nexports.EventEmitter = EventEmitter;\n"
  },
  {
    "path": "src/lib/event_emitter_test.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar EventEmitter = require(\"./event_emitter\").EventEmitter;\nvar assert = require(\"../test/assertions\");\n\nvar Emitter = function() {};\n\noop.implement(Emitter.prototype, EventEmitter);\n\nmodule.exports = {\n    \"test: dispatch event with no data\" : function() {\n        var emitter = new Emitter();\n\n        var called = false;\n        emitter.addEventListener(\"juhu\", function(e) {\n           called = true;\n           assert.equal(e.type, \"juhu\");\n        });\n\n        emitter._emit(\"juhu\");\n        assert.ok(called);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/lib/fixoldbrowsers.js",
    "content": "// vim:set ts=4 sts=4 sw=4 st:\n// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License\n// -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)\n// -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified\n// -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License\n// -- Irakli Gozalishvili Copyright (C) 2010 MIT License\n\n/*!\n    Copyright (c) 2009, 280 North Inc. http://280north.com/\n    MIT License. http://github.com/280north/narwhal/blob/master/README.md\n*/\n\n\"use strict\";\n\n// @ts-ignore\nrequire(\"./es6-shim\");\n"
  },
  {
    "path": "src/lib/keys.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./oop\");\n\n\nvar Keys = {\n    MODIFIER_KEYS: {\n        16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta',\n        91: 'MetaLeft', 92: 'MetaRight', 93: 'ContextMenu'\n    },\n\n    KEY_MODS: {\n        \"ctrl\": 1, \"alt\": 2, \"option\" : 2, \"shift\": 4,\n        \"super\": 8, \"meta\": 8, \"command\": 8, \"cmd\": 8, \n        \"control\": 1\n    },\n\n    FUNCTION_KEYS : {\n        8  : \"Backspace\",\n        9  : \"Tab\",\n        13 : \"Return\",\n        19 : \"Pause\",\n        27 : \"Esc\",\n        32 : \"Space\",\n        33 : \"PageUp\",\n        34 : \"PageDown\",\n        35 : \"End\",\n        36 : \"Home\",\n        37 : \"Left\",\n        38 : \"Up\",\n        39 : \"Right\",\n        40 : \"Down\",\n        44 : \"Print\",\n        45 : \"Insert\",\n        46 : \"Delete\",\n        '-13': \"NumpadEnter\",\n        144: \"Numlock\",\n        145: \"Scrolllock\"\n    },\n\n    PRINTABLE_KEYS: {\n        32: ' ',  59: ';',  61: '=', 107: '+', 109: '-', 110: '.',\n        186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',\n        219: '[', 220: '\\\\',221: ']', 222: \"'\", 111: '/', 106: '*'\n    }\n};\n\nvar codeToKeyCode = {\n    Command: 224,\n    Backspace: 8,\n    Tab: 9,\n    Return: 13,\n    Enter: 13,\n    Pause: 19,\n    Escape: 27,\n    PageUp: 33,\n    PageDown: 34,\n    End: 35,\n    Home: 36,\n    Insert: 45,\n    Delete: 46,\n    ArrowLeft: 37,\n    ArrowUp: 38,\n    ArrowRight: 39,\n    ArrowDown: 40,\n    // special keys\n    Backquote: 192,\n    Minus: 189,\n    Equal: 187,\n    BracketLeft: 219,\n    Backslash: 220,\n    BracketRight: 221,\n    Semicolon: 186,\n    Quote: 222,\n    Comma: 188,\n    Period: 190,\n    Slash: 191,\n    Space: 32,\n    NumpadAdd: 107,\n    NumpadDecimal: 110,\n    NumpadSubtract: 109,\n    NumpadDivide: 111,\n    NumpadMultiply: 106\n};\nfor (var i = 0; i < 10; i++) {\n    codeToKeyCode[\"Digit\" + i] = 48 + i;\n    codeToKeyCode[\"Numpad\" + i] = 96 + i;\n    Keys.PRINTABLE_KEYS[48 + i] = \"\" + i;\n    Keys.FUNCTION_KEYS[96 + i] = \"Numpad\" + i;\n}\nfor (var i = 65; i < 91; i++) {\n    var chr = String.fromCharCode(i + 32);\n    codeToKeyCode[\"Key\" + chr.toUpperCase()] = i;\n    Keys.PRINTABLE_KEYS[i] = chr;\n}\nfor (var i = 1; i < 13; i++) {\n    codeToKeyCode[\"F\" + i] = 111 + i;\n    Keys.FUNCTION_KEYS[111 + i] = \"F\" + i;\n}\nvar modifiers = { \n    Shift: 16,\n    Control: 17,\n    Alt: 18,\n    Meta: 224\n};\nfor (var mod in modifiers) {\n    codeToKeyCode[mod] = codeToKeyCode[mod + \"Left\"]\n        = codeToKeyCode[mod + \"Right\"] = modifiers[mod];\n}\nexports.$codeToKeyCode = codeToKeyCode;\n\n// workaround for firefox bug\nKeys.PRINTABLE_KEYS[173] = '-';\n\n// A reverse map of FUNCTION_KEYS\nfor (var j in Keys.FUNCTION_KEYS) {\n    var name = Keys.FUNCTION_KEYS[j].toLowerCase();\n    Keys[name] = parseInt(j, 10);\n}\n\n// A reverse map of PRINTABLE_KEYS\nfor (var j in Keys.PRINTABLE_KEYS) {\n    var name = Keys.PRINTABLE_KEYS[j].toLowerCase();\n    Keys[name] = parseInt(j, 10);\n}\n\n// Add the MODIFIER_KEYS, FUNCTION_KEYS and PRINTABLE_KEYS to the KEY\n// variables as well.\noop.mixin(Keys, Keys.MODIFIER_KEYS);\noop.mixin(Keys, Keys.PRINTABLE_KEYS);\noop.mixin(Keys, Keys.FUNCTION_KEYS);\n\n// aliases\nKeys.enter = Keys[\"return\"];\nKeys.escape = Keys.esc;\nKeys.del = Keys[\"delete\"];\n\n(function() {\n    var mods = [\"cmd\", \"ctrl\", \"alt\", \"shift\"];\n    for (var i = Math.pow(2, mods.length); i--;) {\n        Keys.KEY_MODS[i] = mods.filter(function(x) {\n            return i & Keys.KEY_MODS[x];\n        }).join(\"-\") + \"-\";\n    }\n})();\n\nKeys.KEY_MODS[0] = \"\";\nKeys.KEY_MODS[-1] = \"input-\";\n\n/**@deprecated*/\noop.mixin(exports, Keys);\n\nexports.default = exports;\n\n/**\n * @param {number} keyCode\n * @return {string}\n */\nexports.keyCodeToString = function(keyCode) {\n    // Language-switching keystroke in Chrome/Linux emits keyCode 0.\n    var keyString = Keys[keyCode];\n    if (typeof keyString != \"string\")\n        keyString = String.fromCharCode(keyCode);\n    return keyString.toLowerCase();\n};\n"
  },
  {
    "path": "src/lib/lang.js",
    "content": "\"use strict\";\n\nexports.last = function(a) {\n    return a[a.length - 1];\n};\n\n\n/** @param {string} string */\nexports.stringReverse = function(string) {\n    return string.split(\"\").reverse().join(\"\");\n};\n\nexports.stringRepeat = function (string, count) {\n    var result = '';\n    while (count > 0) {\n        if (count & 1)\n            result += string;\n\n        if (count >>= 1)\n            string += string;\n    }\n    return result;\n};\n\nvar trimBeginRegexp = /^\\s\\s*/;\nvar trimEndRegexp = /\\s\\s*$/;\n\nexports.stringTrimLeft = function (string) {\n    return string.replace(trimBeginRegexp, '');\n};\n\nexports.stringTrimRight = function (string) {\n    return string.replace(trimEndRegexp, '');\n};\n/**\n * @template T\n * @param {T} obj\n * @return {T}\n */\nexports.copyObject = function(obj) {\n    /** @type Object*/\n    var copy = {};\n    for (var key in obj) {\n        copy[key] = obj[key];\n    }\n    return copy;\n};\n\nexports.copyArray = function(array){\n    var copy = [];\n    for (var i=0, l=array.length; i<l; i++) {\n        if (array[i] && typeof array[i] == \"object\")\n            copy[i] = this.copyObject(array[i]);\n        else\n            copy[i] = array[i];\n    }\n    return copy;\n};\n\nexports.deepCopy = require(\"./deep_copy\").deepCopy;\n\nexports.arrayToMap = function(arr) {\n    var map = {};\n    for (var i=0; i<arr.length; i++) {\n        map[arr[i]] = 1;\n    }\n    return map;\n\n};\n\nexports.createMap = function(props) {\n    var map = Object.create(null);\n    for (var i in props) {\n        map[i] = props[i];\n    }\n    return map;\n};\n\n/*\n * splice out of 'array' anything that === 'value'\n */\nexports.arrayRemove = function(array, value) {\n  for (var i = 0; i <= array.length; i++) {\n    if (value === array[i]) {\n      array.splice(i, 1);\n    }\n  }\n};\n\nexports.escapeRegExp = function(str) {\n    return str.replace(/([.*+?^${}()|[\\]\\/\\\\])/g, '\\\\$1');\n};\n\nexports.escapeHTML = function(str) {\n    return (\"\" + str).replace(/&/g, \"&#38;\").replace(/\"/g, \"&#34;\").replace(/'/g, \"&#39;\").replace(/</g, \"&#60;\");\n};\n\nexports.getMatchOffsets = function(string, regExp) {\n    var matches = [];\n\n    string.replace(regExp, function(str) {\n        matches.push({\n            offset: arguments[arguments.length-2],\n            length: str.length\n        });\n    });\n\n    return matches;\n};\n\n/* deprecated */\nexports.deferredCall = function(fcn) {\n    var timer = null;\n    var callback = function() {\n        timer = null;\n        fcn();\n    };\n\n    var deferred = function(timeout) {\n        deferred.cancel();\n        timer = setTimeout(callback, timeout || 0);\n        return deferred;\n    };\n\n    deferred.schedule = deferred;\n\n    deferred.call = function() {\n        this.cancel();\n        fcn();\n        return deferred;\n    };\n\n    deferred.cancel = function() {\n        clearTimeout(timer);\n        timer = null;\n        return deferred;\n    };\n\n    deferred.isPending = function() {\n        return timer;\n    };\n\n    return deferred;\n};\n\n/**\n * @param {number} [defaultTimeout]\n */\nexports.delayedCall = function(fcn, defaultTimeout) {\n    var timer = null;\n    var callback = function() {\n        timer = null;\n        fcn();\n    };\n    /**\n     * @param {number} [timeout]\n     */\n    var _self = function(timeout) {\n        if (timer == null)\n            timer = setTimeout(callback, timeout || defaultTimeout);\n    };\n    /**\n     * @param {number} [timeout]\n     */\n    _self.delay = function(timeout) {\n        timer && clearTimeout(timer);\n        timer = setTimeout(callback, timeout || defaultTimeout);\n    };\n    _self.schedule = _self;\n\n    _self.call = function() {\n        this.cancel();\n        fcn();\n    };\n\n    _self.cancel = function() {\n        timer && clearTimeout(timer);\n        timer = null;\n    };\n\n    _self.isPending = function() {\n        return timer;\n    };\n\n    return _self;\n};\n\n/**\n * @param {number} ms\n * @returns {Promise<void>}\n */\nexports.sleep = function(ms) {\n    return new Promise(function(resolve) {\n        setTimeout(resolve, ms);\n    });\n};\n\nexports.supportsLookbehind = function () {\n    try {\n        new RegExp('(?<=.)');\n    } catch (e) {\n        return false;\n    }\n    return true;\n};\n\nexports.skipEmptyMatch = function(line, last, supportsUnicodeFlag) {\n    return supportsUnicodeFlag && line.codePointAt(last) > 0xffff ? 2 : 1;\n};\n"
  },
  {
    "path": "src/lib/net.js",
    "content": "/*\n * based on code from:\n *\n * @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/jrburke/requirejs for details\n */\n\n\"use strict\";\nvar dom = require(\"./dom\");\n\nexports.get = function (url, callback) {\n    var xhr = new XMLHttpRequest();\n    xhr.open('GET', url, true);\n    xhr.onreadystatechange = function () {\n        //Do not explicitly handle errors, those should be\n        //visible via console output in the browser.\n        if (xhr.readyState === 4) {\n            callback(xhr.responseText);\n        }\n    };\n    xhr.send(null);\n};\n\nexports.loadScript = function(path, callback) {\n    var head = dom.getDocumentHead();\n    /**@type {HTMLScriptElement & {onload?: Function, onreadystatechange?: Function, readyState?: string}}*/\n    var s = document.createElement('script');\n\n    s.src = path;\n    head.appendChild(s);\n\n    s.onload = s.onreadystatechange = function(_, isAbort) {\n        if (isAbort || !s.readyState || s.readyState == \"loaded\" || s.readyState == \"complete\") {\n            s = s.onload = s.onreadystatechange = null;\n            if (!isAbort)\n                callback();\n        }\n    };\n};\n\n/*\n * Convert a url into a fully qualified absolute URL\n * This function does not work in IE6\n */\nexports.qualifyURL = function(url) {\n    var a = document.createElement('a');\n    a.href = url;\n    return a.href;\n};\n"
  },
  {
    "path": "src/lib/oop.js",
    "content": "\"use strict\";\n\nexports.inherits = function(ctor, superCtor) {\n    ctor.super_ = superCtor;\n    ctor.prototype = Object.create(superCtor.prototype, {\n        constructor: {\n            value: ctor,\n            enumerable: false,\n            writable: true,\n            configurable: true\n        }\n    });\n};\n\n/**\n * Implements mixin properties into the prototype of an object.\n * @template T\n * @param {T} obj - The prototype of the target object.\n * @param {Object} mixin - The source object.\n * @returns {T & Object} The merged prototype.\n */\nexports.mixin = function(obj, mixin) {\n    for (var key in mixin) {\n        obj[key] = mixin[key];\n    }\n    return obj;\n};\n\n/**\n * Implements mixin properties into the prototype of an object.\n * @template T\n * @param {T} proto - The prototype of the target object.\n * @param {Object} mixin - The source object.\n * @returns {T & Object} The merged prototype.\n */\nexports.implement = function(proto, mixin) {\n    exports.mixin(proto, mixin);\n};\n"
  },
  {
    "path": "src/lib/report_error.js",
    "content": "\nexports.reportError = function reportError(msg, data) {\n    var e = new Error(msg);\n    e[\"data\"] = data;\n    if (typeof console == \"object\" && console.error)\n        console.error(e);\n    setTimeout(function() { throw e; });\n};\n"
  },
  {
    "path": "src/lib/scroll.js",
    "content": "exports.preventParentScroll = function preventParentScroll(event) {\n    event.stopPropagation();\n    var target = event.currentTarget;\n    var contentOverflows = target.scrollHeight > target.clientHeight;\n    if (!contentOverflows) {\n        event.preventDefault();\n    }\n};"
  },
  {
    "path": "src/lib/useragent.js",
    "content": "\"use strict\";\n\n/*\n * I hate doing this, but we need some way to determine if the user is on a Mac\n * The reason is that users have different expectations of their key combinations.\n *\n * Take copy as an example, Mac people expect to use CMD or APPLE + C\n * Windows folks expect to use CTRL + C\n */\nexports.OS = {\n    LINUX: \"LINUX\",\n    MAC: \"MAC\",\n    WINDOWS: \"WINDOWS\"\n};\n\n/*\n * Return an exports.OS constant\n */\nexports.getOS = function() {\n    if (exports.isMac) {\n        return exports.OS.MAC;\n    } else if (exports.isLinux) {\n        return exports.OS.LINUX;\n    } else {\n        return exports.OS.WINDOWS;\n    }\n};\n\n// this can be called in non browser environments (e.g. from ace/requirejs/text)\nvar _navigator = typeof navigator == \"object\" ? navigator : {};\n\nvar os = (/mac|win|linux/i.exec(_navigator.platform) || [\"other\"])[0].toLowerCase();\nvar ua = _navigator.userAgent || \"\";\nvar appName = _navigator.appName || \"\";\n\n// Is the user using a browser that identifies itself as Windows\nexports.isWin = (os == \"win\");\n\n// Is the user using a browser that identifies itself as Mac OS\nexports.isMac = (os == \"mac\");\n\n// Is the user using a browser that identifies itself as Linux\nexports.isLinux = (os == \"linux\");\n\n// Windows Store JavaScript apps (aka Metro apps written in HTML5 and JavaScript) do not use the \"Microsoft Internet Explorer\" string in their user agent, but \"MSAppHost\" instead.\nexports.isIE = \n    (appName == \"Microsoft Internet Explorer\" || appName.indexOf(\"MSAppHost\") >= 0)\n    ? parseFloat((ua.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1])\n    : parseFloat((ua.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]); // for ie\n    \nexports.isOldIE = exports.isIE && exports.isIE < 9;\n\n// Is this Firefox or related?\nexports.isGecko = exports.isMozilla = ua.match(/ Gecko\\/\\d+/);\n\n// Is this Opera \n// @ts-expect-error\nexports.isOpera = typeof opera == \"object\" && Object.prototype.toString.call(window[\"opera\"]) == \"[object Opera]\";\n\n// Is the user using a browser that identifies itself as WebKit \nexports.isWebKit = parseFloat(ua.split(\"WebKit/\")[1]) || undefined;\n\nexports.isChrome = parseFloat(ua.split(\" Chrome/\")[1]) || undefined;\n\nexports.isSafari = parseFloat(ua.split(\" Safari/\")[1]) && !exports.isChrome || undefined;\n\nexports.isEdge = parseFloat(ua.split(\" Edge/\")[1]) || undefined;\n\nexports.isAIR = ua.indexOf(\"AdobeAIR\") >= 0;\n\nexports.isAndroid = ua.indexOf(\"Android\") >= 0;\n\nexports.isChromeOS = ua.indexOf(\" CrOS \") >= 0;\n\nexports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window[\"MSStream\"];\n\nif (exports.isIOS) exports.isMac = true;\n\nexports.isMobile = exports.isIOS || exports.isAndroid;\n"
  },
  {
    "path": "src/line_widgets.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"./editor\").Editor} Editor\n * @typedef {import(\"./virtual_renderer\").VirtualRenderer} VirtualRenderer\n * @typedef {import(\"../ace-internal\").Ace.LineWidget} LineWidget\n */\n\nvar dom = require(\"./lib/dom\");\n\n\nclass LineWidgets {\n    /**\n     * @param {EditSession} session\n     */\n    constructor(session) {\n        this.session = session;\n        this.session.widgetManager = this;\n        this.session.getRowLength = this.getRowLength;\n        this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;\n        this.updateOnChange = this.updateOnChange.bind(this);\n        this.renderWidgets = this.renderWidgets.bind(this);\n        this.measureWidgets = this.measureWidgets.bind(this);\n        this.session._changedWidgets = [];\n        this.$onChangeEditor = this.$onChangeEditor.bind(this);\n\n        this.session.on(\"change\", this.updateOnChange);\n        this.session.on(\"changeFold\", this.updateOnFold);\n        this.session.on(\"changeEditor\", this.$onChangeEditor);\n    }\n\n    /**\n     * @param {number} row\n     * @return {number}\n     */\n    getRowLength(row) {\n        var h;\n        if (this.lineWidgets)\n            h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;\n        else\n            h = 0;\n        if (!this[\"$useWrapMode\"] || !this[\"$wrapData\"][row]) {\n            return 1 + h;\n        } else {\n            return this[\"$wrapData\"][row].length + 1 + h;\n        }\n    }\n\n    /**\n     * @return {number}\n     */\n    $getWidgetScreenLength() {\n        var screenRows = 0;\n        this.lineWidgets.forEach(function(w){\n            if (w && w.rowCount && !w.hidden)\n                screenRows += w.rowCount;\n        });\n        return screenRows;\n    }\n\n    $onChangeEditor(e) {\n        this.attach(e.editor);\n    }\n\n    /**\n     *\n     * @param {Editor} editor\n     */\n    attach(editor) {\n        if (editor  && editor.widgetManager && editor.widgetManager != this)\n            editor.widgetManager.detach();\n\n        if (this.editor == editor)\n            return;\n\n        this.detach();\n        /**@type {Editor} */\n        this.editor = editor;\n\n        if (editor) {\n            editor.widgetManager = this;\n            editor.renderer.on(\"beforeRender\", this.measureWidgets);\n            editor.renderer.on(\"afterRender\", this.renderWidgets);\n        }\n    }\n    detach(e) {\n        var editor = this.editor;\n        if (!editor)\n            return;\n\n        this.editor = null;\n        editor.widgetManager = null;\n\n        editor.renderer.off(\"beforeRender\", this.measureWidgets);\n        editor.renderer.off(\"afterRender\", this.renderWidgets);\n        var lineWidgets = this.session.lineWidgets;\n        lineWidgets && lineWidgets.forEach(function(w) {\n            if (w && w.el && w.el.parentNode) {\n                w._inDocument = false;\n                w.el.parentNode.removeChild(w.el);\n            }\n        });\n    }\n\n    /**\n     *\n     * @param e\n     * @param {EditSession} session\n     */\n    updateOnFold(e, session) {\n        var lineWidgets = session.lineWidgets;\n        if (!lineWidgets || !e.action)\n            return;\n        var fold = e.data;\n        var start = fold.start.row;\n        var end = fold.end.row;\n        var hide = e.action == \"add\";\n        for (var i = start + 1; i < end; i++) {\n            if (lineWidgets[i])\n                lineWidgets[i].hidden = hide;\n        }\n        if (lineWidgets[end]) {\n            if (hide) {\n                if (!lineWidgets[start])\n                    lineWidgets[start] = lineWidgets[end];\n                else\n                    lineWidgets[end].hidden = hide;\n            } else {\n                if (lineWidgets[start] == lineWidgets[end])\n                    lineWidgets[start] = undefined;\n                lineWidgets[end].hidden = hide;\n            }\n        }\n    }\n\n    /**\n     *\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     */\n    updateOnChange(delta) {\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets) return;\n\n        var startRow = delta.start.row;\n        var len = delta.end.row - startRow;\n\n        if (len === 0) {\n            // return\n        } else if (delta.action == \"remove\") {\n            var removed = lineWidgets.splice(startRow + 1, len);\n            if (!lineWidgets[startRow] && removed[removed.length - 1]) {\n                lineWidgets[startRow] = removed.pop();\n            }\n            removed.forEach(function(w) {\n                w && this.removeLineWidget(w);\n            }, this);\n            this.$updateRows();\n        } else {\n            var args = new Array(len);\n            if (lineWidgets[startRow] && lineWidgets[startRow].column != null) {\n                if (delta.start.column > lineWidgets[startRow].column)\n                    startRow++;\n            }\n            args.unshift(startRow, 0);\n            lineWidgets.splice.apply(lineWidgets, args);\n            this.$updateRows();\n        }\n    }\n\n    $updateRows() {\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets) return;\n        var noWidgets = true;\n        lineWidgets.forEach(function(w, i) {\n            if (w) {\n                noWidgets = false;\n                w.row = i;\n                while (w.$oldWidget) {\n                    w.$oldWidget.row = i;\n                    w = w.$oldWidget;\n                }\n            }\n        });\n        if (noWidgets)\n            this.session.lineWidgets = null;\n    }\n\n    /**\n     *\n     * @param {LineWidget} w\n     * @return {LineWidget}\n     */\n    $registerLineWidget(w) {\n        if (!this.session.lineWidgets)\n            this.session.lineWidgets = new Array(this.session.getLength());\n\n        var old = this.session.lineWidgets[w.row];\n        if (old) {\n            w.$oldWidget = old;\n            if (old.el && old.el.parentNode) {\n                old.el.parentNode.removeChild(old.el);\n                old._inDocument = false;\n            }\n        }\n\n        this.session.lineWidgets[w.row] = w;\n        return w;\n    }\n\n    /**\n     *\n     * @param {LineWidget} w\n     * @return {LineWidget}\n     */\n    addLineWidget(w) {\n        this.$registerLineWidget(w);\n        w.session = this.session;\n\n        if (!this.editor) return w;\n\n        var renderer = this.editor.renderer;\n        if (w.html && !w.el) {\n            w.el = dom.createElement(\"div\");\n            w.el.innerHTML = w.html;\n        }\n        if (w.text && !w.el) {\n            w.el = dom.createElement(\"div\");\n            w.el.textContent = w.text;\n        }\n        if (w.el) {\n            dom.addCssClass(w.el, \"ace_lineWidgetContainer\");\n            if (w.className) {\n                dom.addCssClass(w.el, w.className);\n            }\n            w.el.style.position = \"absolute\";\n            w.el.style.zIndex = \"5\";\n            renderer.container.appendChild(w.el);\n            w._inDocument = true;\n\n            if (!w.coverGutter) {\n                w.el.style.zIndex = \"3\";\n            }\n            if (w.pixelHeight == null) {\n                w.pixelHeight = w.el.offsetHeight;\n            }\n        }\n        if (w.rowCount == null) {\n            w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;\n        }\n\n        var fold = this.session.getFoldAt(w.row, 0);\n        w.$fold = fold;\n        if (fold) {\n            var lineWidgets = this.session.lineWidgets;\n            if (w.row == fold.end.row && !lineWidgets[fold.start.row])\n                lineWidgets[fold.start.row] = w;\n            else\n                w.hidden = true;\n        }\n\n        this.session._emit(\"changeFold\", {data:{start:{row: w.row}}});\n\n        this.$updateRows();\n        this.renderWidgets(null, renderer);\n        this.onWidgetChanged(w);\n        return w;\n    }\n\n    /**\n     * @param {LineWidget} w\n     */\n    removeLineWidget(w) {\n        w._inDocument = false;\n        w.session = null;\n        if (w.el && w.el.parentNode)\n            w.el.parentNode.removeChild(w.el);\n        if (w.editor && w.editor.destroy) try {\n            w.editor.destroy();\n        } catch(e){}\n        if (this.session.lineWidgets) {\n            var w1 = this.session.lineWidgets[w.row];\n            if (w1 == w) {\n                this.session.lineWidgets[w.row] = w.$oldWidget;\n                if (w.$oldWidget)\n                    this.onWidgetChanged(w.$oldWidget);\n            } else {\n                while (w1) {\n                    if (w1.$oldWidget == w) {\n                        w1.$oldWidget = w.$oldWidget;\n                        break;\n                    }\n                    w1 = w1.$oldWidget;\n                }\n            }\n        }\n        this.session._emit(\"changeFold\", {data:{start:{row: w.row}}});\n        this.$updateRows();\n    }\n\n    /**\n     *\n     * @param {number} row\n     * @return {LineWidget[]}\n     */\n    getWidgetsAtRow(row) {\n        var lineWidgets = this.session.lineWidgets;\n        var w = lineWidgets && lineWidgets[row];\n        var list = [];\n        while (w) {\n            list.push(w);\n            w = w.$oldWidget;\n        }\n        return list;\n    }\n\n    /**\n     * @param {LineWidget} w\n     * @internal\n     */\n    onWidgetChanged(w) {\n        this.session._changedWidgets.push(w);\n        this.editor && this.editor.renderer.updateFull();\n    }\n\n    /**\n     * @param {any} e\n     * @param {VirtualRenderer} renderer\n     */\n    measureWidgets(e, renderer) {\n        var changedWidgets = this.session._changedWidgets;\n        var config = renderer.layerConfig;\n\n        if (!changedWidgets || !changedWidgets.length) return;\n        var min = Infinity;\n        for (var i = 0; i < changedWidgets.length; i++) {\n            var w = changedWidgets[i];\n            if (!w || !w.el) continue;\n            if (w.session != this.session) continue;\n            if (!w._inDocument) {\n                if (this.session.lineWidgets[w.row] != w)\n                    continue;\n                w._inDocument = true;\n                renderer.container.appendChild(w.el);\n            }\n\n            w.h = w.el.offsetHeight;\n\n            if (!w.fixedWidth) {\n                w.w = w.el.offsetWidth;\n                w.screenWidth = Math.ceil(w.w / config.characterWidth);\n            }\n\n            var rowCount = w.h / config.lineHeight;\n            if (w.coverLine) {\n                rowCount -= this.session.getRowLineCount(w.row);\n                if (rowCount < 0)\n                    rowCount = 0;\n            }\n            if (w.rowCount != rowCount) {\n                w.rowCount = rowCount;\n                if (w.row < min)\n                    min = w.row;\n            }\n        }\n        if (min != Infinity) {\n            this.session._emit(\"changeFold\", {data:{start:{row: min}}});\n            this.session.lineWidgetWidth = null;\n        }\n        this.session._changedWidgets = [];\n    }\n\n    /**\n     * @param {any} e\n     * @param {VirtualRenderer} renderer\n     */\n    renderWidgets(e, renderer) {\n        var config = renderer.layerConfig;\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets)\n            return;\n        var first = Math.min(this.firstRow, config.firstRow);\n        var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);\n\n        while (first > 0 && !lineWidgets[first])\n            first--;\n\n        this.firstRow = config.firstRow;\n        this.lastRow = config.lastRow;\n\n        renderer.$cursorLayer.config = config;\n        for (var i = first; i <= last; i++) {\n            /**@type{LineWidget}*/\n            var w = lineWidgets[i];\n            if (!w || !w.el) continue;\n            if (w.hidden) {\n                w.el.style.top = -100 - (w.pixelHeight || 0) + \"px\";\n                continue;\n            }\n            if (!w._inDocument) {\n                w._inDocument = true;\n                renderer.container.appendChild(w.el);\n            }\n            var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;\n            if (!w.coverLine)\n                top += config.lineHeight * this.session.getRowLineCount(w.row);\n            w.el.style.top = top - config.offset + \"px\";\n\n            var left = w.coverGutter ? 0 : renderer.gutterWidth;\n            if (!w.fixedWidth)\n                left -= renderer.scrollLeft;\n            w.el.style.left = left + \"px\";\n\n            if (w.fullWidth && w.screenWidth) {\n                w.el.style.minWidth = config.width + 2 * config.padding + \"px\";\n            }\n\n            if (w.fixedWidth) {\n                w.el.style.right = renderer.scrollBar.getWidth() + \"px\";\n            } else {\n                w.el.style.right = \"\";\n            }\n        }\n    }\n\n}\n\n\nexports.LineWidgets = LineWidgets;\n"
  },
  {
    "path": "src/marker_group.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {{range: import(\"./range\").Range, className: string}} MarkerGroupItem\n * @typedef {import(\"../ace-internal\").Ace.LayerConfig} LayerConfig\n */\n/**\n * @typedef {import(\"./layer/marker\").Marker} Marker\n */\n\n/*\nPotential improvements:\n- use binary search when looking for hover match\n*/\n\nclass MarkerGroup {\n    /**\n     * @param {EditSession} session\n     * @param {{markerType: \"fullLine\" | \"line\" | undefined}} [options] Options controlling the behvaiour of the marker.\n     * User `markerType` to control how the markers which are part of this group will be rendered:\n     * - `undefined`: uses `text` type markers where only text characters within the range will be highlighted.\n     * - `fullLine`: will fully highlight all the rows within the range, including the characters before and after the range on the respective rows.\n     * - `line`: will fully highlight the lines within the range but will only cover the characters between the start and end of the range.\n     */\n    constructor(session, options) {\n        if (options)\n            this.markerType = options.markerType;\n        /**@type {import(\"../ace-internal\").Ace.MarkerGroupItem[]}*/\n        this.markers = [];\n        /**@type {EditSession}*/\n        this.session = session;\n        // @ts-expect-error TODO: could potential error here, or most likely missing checks in other places\n        session.addDynamicMarker(this);\n    }\n\n    /**\n     * Finds the first marker containing pos\n     * @param {import(\"../ace-internal\").Ace.Point} pos\n     * @returns {import(\"../ace-internal\").Ace.MarkerGroupItem | undefined}\n     */\n    getMarkerAtPosition(pos) {\n        return this.markers.find(function(marker) {\n            return marker.range.contains(pos.row, pos.column);\n        });\n    }\n\n    /**\n     * Comparator for Array.sort function, which sorts marker definitions by their positions\n     *\n     * @param {MarkerGroupItem} a first marker.\n     * @param {MarkerGroupItem} b second marker.\n     * @returns {number} negative number if a should be before b, positive number if b should be before a, 0 otherwise.\n     */\n    markersComparator(a, b) {\n        return a.range.start.row - b.range.start.row;\n    }\n\n    /**\n     * Sets marker definitions to be rendered. Limits the number of markers at MAX_MARKERS.\n     * @param {MarkerGroupItem[]} markers an array of marker definitions.\n     */\n    setMarkers(markers) {\n        this.markers = markers.sort(this.markersComparator).slice(0, this.MAX_MARKERS);\n        this.session._signal(\"changeBackMarker\");\n    }\n\n    /**\n     * @param {any} html\n     * @param {Marker} markerLayer\n     * @param {EditSession} session\n     * @param {LayerConfig} config\n     */\n    update(html, markerLayer, session, config) {\n        if (!this.markers || !this.markers.length)\n            return;\n        var visibleRangeStartRow = config.firstRow, visibleRangeEndRow = config.lastRow;\n        var foldLine;\n        var markersOnOneLine = 0;\n        var lastRow = 0;\n\n        for (var i = 0; i < this.markers.length; i++) {\n            var marker = this.markers[i];\n\n            if (marker.range.end.row < visibleRangeStartRow) continue;\n            if (marker.range.start.row > visibleRangeEndRow) continue;\n\n            if (marker.range.start.row === lastRow) {\n                markersOnOneLine++;\n            } else {\n                lastRow = marker.range.start.row;\n                markersOnOneLine = 0;\n            }\n            // do not render too many markers on one line\n            // because we do not have virtual scroll for horizontal direction\n            if (markersOnOneLine > 200) {\n                continue;\n            }\n\n            var markerVisibleRange = marker.range.clipRows(visibleRangeStartRow, visibleRangeEndRow);\n            if (markerVisibleRange.start.row === markerVisibleRange.end.row\n                && markerVisibleRange.start.column === markerVisibleRange.end.column) {\n                    continue; // visible range is empty\n                }\n\n            var screenRange = markerVisibleRange.toScreenRange(session);\n            if (screenRange.isEmpty()) {\n                // we are inside a fold\n                foldLine = session.getNextFoldLine(markerVisibleRange.end.row, foldLine);\n                if (foldLine && foldLine.end.row > markerVisibleRange.end.row) {\n                    visibleRangeStartRow = foldLine.end.row;\n                }\n                continue;\n            }\n\n            if (this.markerType === \"fullLine\") {\n                markerLayer.drawFullLineMarker(html, screenRange, marker.className, config);\n            } else if (screenRange.isMultiLine()) {\n                if (this.markerType === \"line\")\n                    markerLayer.drawMultiLineMarker(html, screenRange, marker.className, config);\n                else\n                    markerLayer.drawTextMarker(html, screenRange, marker.className, config);\n            } else {\n                markerLayer.drawSingleLineMarker(html, screenRange, marker.className + \" ace_br15\", config);\n            }\n        }\n    }\n\n}\n\n// this caps total amount of markers at 10K\nMarkerGroup.prototype.MAX_MARKERS = 10000;\n\nexports.MarkerGroup = MarkerGroup;\n\n"
  },
  {
    "path": "src/marker_group_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar ace = require(\"./ace\");\nvar dom = require(\"./lib/dom\");\nvar assert = require(\"./test/assertions\");\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Range = require(\"./range\").Range;\nvar MarkerGroup = require(\"./marker_group\").MarkerGroup;\nvar editor;\nvar session1, session2;\n\nmodule.exports = {\n    setUp: function() {\n        var value = \"Hello empty world\\n\"\n            + \"This is a second line\"\n            + \"\\n\".repeat(100)\n            + \"line number 100\";\n        session1 = new EditSession(value);\n        session2 = new EditSession(\"2 \" + value);\n        editor = ace.edit(null, {\n            session: session1\n        });\n        document.body.appendChild(editor.container);\n        editor.container.style.height = \"200px\";\n        editor.container.style.width = \"300px\";\n        dom.importCssString('.ace_tooltip-marker_test { position: absolute; background: rgba(255, 0, 0, 0.3); }', 'marker_group_test');\n    },\n   \"test: should show and update markers\": function() {\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n        var markerGroup = new MarkerGroup(session1);\n\n        markerGroup.setMarkers([{\n            range: new Range(0, 0, 0, 5),\n            className: \"ace_tooltip-marker_test m2\"\n        }, {\n            range: new Range(0, 12, 1, 4),\n            className: \"ace_tooltip-marker_test m1\",\n            isSecond: true\n        }]);\n        assert.ok(markerGroup.getMarkerAtPosition({row: 1, column: 1}).isSecond);\n        assert.ok(!markerGroup.getMarkerAtPosition({row: 3, column: 1}));\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 2);\n        assert.equal(editor.container.querySelectorAll(\".m2\").length, 1);\n        editor.setSession(session2);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 0);\n        editor.setSession(session1);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 2);\n        editor.execCommand(\"gotoend\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 0);\n        editor.execCommand(\"gotostart\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 2);\n        markerGroup.setMarkers([]);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m1\").length, 0);\n    },\n    \"test: should show markers of fullLine type\": function() {\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n        var markerGroup = new MarkerGroup(session1, {markerType: \"fullLine\"});\n\n        // this marker should be rendered as a full block across lines 1 and 2\n        markerGroup.setMarkers([{\n            range: new Range(0, 12, 1, 4),\n            className: \"ace_tooltip-marker_test m\"\n        }]);\n        assert.ok(markerGroup.getMarkerAtPosition({row: 1, column: 1}));\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.querySelectorAll(\".m\").length, 1);\n\n        // Get dimensions of the full line marker\n        var markerSize = editor.container.querySelector(\".m\").getBoundingClientRect();\n        var lineHeight = editor.renderer.lineHeight;\n\n        // Height should be two lines\n        assert.equal(markerSize.height, 2 * lineHeight);\n        // Should start at the beginning of the line\n        assert.equal(markerSize.left, editor.renderer.scroller.getBoundingClientRect().left);\n        // Shoud be as wide as the marker layer itself.\n        assert.equal(markerSize.width, editor.renderer.$markerBack.element.getBoundingClientRect().width);\n    },\n    \"test: should show markers of line type\": function() {\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n        var markerGroup = new MarkerGroup(session1, {markerType: \"line\"});\n\n        // this marker should be rendered just covering the range, but extending to the edge of the editor on newlines\n        markerGroup.setMarkers([{\n            range: new Range(0, 12, 1, 4),\n            className: \"ace_tooltip-marker_test m\"\n        }]);\n        assert.ok(markerGroup.getMarkerAtPosition({row: 1, column: 1}));\n        editor.renderer.$loop._flush();\n        // Should render two separate markers for each row\n        assert.equal(editor.container.querySelectorAll(\".m\").length, 2);\n\n        // Get dimensions of the first line marker\n        var markerSize = editor.container.querySelectorAll(\".m\")[0].getBoundingClientRect();\n        var lineHeight = editor.renderer.lineHeight;\n        var characterWidth = editor.renderer.characterWidth;\n\n        var baseRect = editor.renderer.$markerBack.element.getBoundingClientRect();\n        // Height should be one lines\n        assert.equal(markerSize.height, lineHeight);\n        // Should start at the 13th character (including 4px offset)\n        assert.equal(markerSize.left, 12 * characterWidth + 4 + baseRect.left);\n        // Shoud be as wide as the marker layer - 12 characters and the offset on both sides.\n        assert.equal(markerSize.width, baseRect.width - 12 * characterWidth - 4 - 4);\n    },\n    \"test: should default to markers of text type\": function() {\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n\n        // We don't set options.markerType, should default to text markers\n        var markerGroup = new MarkerGroup(session1);\n\n        // this marker should be rendered just covering the range\n        markerGroup.setMarkers([{\n            range: new Range(0, 12, 1, 4),\n            className: \"ace_tooltip-marker_test m\"\n        }]);\n        assert.ok(markerGroup.getMarkerAtPosition({row: 1, column: 1}));\n        editor.renderer.$loop._flush();\n        // Should render two separate markers for each row\n        assert.equal(editor.container.querySelectorAll(\".m\").length, 2);\n\n        // Get dimensions of the first line marker\n        var markerSize = editor.container.querySelectorAll(\".m\")[0].getBoundingClientRect();\n        var lineHeight = editor.renderer.lineHeight;\n        var characterWidth = editor.renderer.characterWidth;\n        var baseRect = editor.renderer.$markerBack.element.getBoundingClientRect();\n\n        // Height should be one lines\n        assert.equal(markerSize.height, lineHeight);\n        // Should start at the 13th character (including 4px offset)\n        assert.equal(markerSize.left, 12 * characterWidth + 4 + baseRect.left);\n        // Shoud be as wide as the remaining characters in the range on the first line.\n        assert.equal(Math.round(markerSize.width), Math.round(6 * characterWidth));\n    },\n    tearDown: function() {\n        editor.destroy();\n    }\n};\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/mode/_test/Readme.md",
    "content": "`tokens_<modeName>.json` files keep information about correct tokens and tokenizer states for all modes supported by ace.\nThey are generated from `text_<modeName>.txt` or `demo/kitchen-sink/docs/*` with\n\n```sh\nnode highlight_rules_test.js -gen\n```\n\ncommand.\n\n"
  },
  {
    "path": "src/mode/_test/highlight_rules_test.js",
    "content": "var fs = require(\"fs\");\nvar path = require(\"path\");\nvar regexpTokenizer = require(\"../../../tool/regexp_tokenizer\");\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar Editor = require(\"../../editor\").Editor;\nvar MockRenderer = require(\"../../test/mockrenderer\").MockRenderer;\nrequire(\"../../multi_select\").MultiSelect;\nvar editor = new Editor(new MockRenderer());\n\nif (!fs.existsSync)\n    fs.existsSync = path.existsSync;\n\nvar cwd = __dirname + \"/\";\nvar root = path.normalize(cwd + Array(4).join(\"../\"));\n\nfunction jsFileList(path, filter) {\n    if (!filter) filter = /_test/;\n    return fs.readdirSync(path).map(function(x) {\n        if (x.slice(-3) == \".js\" && !filter.test(x) && !/\\s/.test(x))\n            return x.slice(0, -3);\n    }).filter(Boolean);\n}\n\nfunction modeList() {\n    return jsFileList(cwd + \"../\", /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/);\n}\n\nfunction checkModes() {\n    var snippets = {};\n    modeList().forEach(function(modeName, i) {\n        silent || console.log(padNumber(i+1, 3) + \") check: \\u001b[33m\" + modeName + \"\\u001b[0m\");\n        try {\n            var Mode = require(\"../\" + modeName).Mode;\n        } catch(e) {\n            console.warn(\"Can't load mode :\" + modeName, e);\n            return;\n        }\n        var m = new Mode();\n        if (!m.lineCommentStart && !m.blockComment)\n            console.error(\"missing comment in \" + modeName);\n        if (!m.$id)\n            console.warn(\"missing id in \" + modeName);\n        if (!m.$behaviour)\n            console.warn(\"missing behavior in \" + modeName);\n        var tokenizer = m.getTokenizer();\n\n        testNextState(tokenizer, modeName);\n        testComments(m.lineCommentStart, testLineComment, tokenizer, modeName);\n        testComments(m.blockComment, testBlockComment, tokenizer, modeName);\n        testBrackets(m, modeName);\n        \n        if (m.snippetFileId)\n            snippets[m.snippetFileId] = modeName;\n    });\n    \n    jsFileList(cwd + \"../../snippets\").forEach(function(snippetFileName) {\n        if (/\\.snippets$/.test(snippetFileName)) return;\n        if (!snippets[\"ace/snippets/\" + snippetFileName])\n            throw new Error(\"Snippet file \" + snippetFileName + \" is not used\");\n        delete snippets[\"ace/snippets/\" + snippetFileName];\n    }) ;\n    if (Object.keys(snippets).length) {\n        console.error(\"Snippet files missing\", snippets);\n        throw new Error(\"Snippet files missing\");\n    }\n    \n    function testNextState(tokenizer, modeName) {\n        let keys = Object.keys(tokenizer.states);\n        for (let i = 0; i < keys.length; i++) {\n            let key = keys[i];\n            let tokens = tokenizer.states[key];\n            for (let j = 0; j < tokens.length; j++) {\n                let token = tokens[j];\n                checkState(keys, token, \"nextState\", modeName);\n                checkState(keys, token, \"next\", modeName);\n            }\n        }\n    }\n\n    function checkState(stateNames, token, property, modeName) {\n        if (token.hasOwnProperty(property) && typeof token[property] === \"string\" && !stateNames.includes(\n            token[property])) {\n            console.warn(\"non-existent next state '\" + token[property] + \"' in \" + modeName);\n        }\n    }\n    \n    function testComments(desc, fn, tokenizer, modeName) {\n        if (desc) {\n            if (Array.isArray(desc)) {\n                desc.forEach(function(x) {\n                    fn(tokenizer, x, modeName);\n                });\n            } else {\n                fn(tokenizer, desc, modeName);\n            }\n        }\n    }\n    \n    function testBlockComment(tokenizer, blockComment, modeName) {\n        if (blockComment.lineStartOnly)\n            return; // TODO test \n        var str = blockComment.start + \" \" + blockComment.end;\n        str = blockComment.start + str;\n        if (blockComment.nestable)\n            str += blockComment.end;     \n        var data = tokenizer.getLineTokens(str, \"start\");\n        var isBroken = data.tokens.some(function(t) { return !/comment/.test(t.type); });\n        if (isBroken) {\n            die(\"broken blockComment in \" + modeName, data);\n        }\n        if (!/start/.test(data.state)) {\n            die(\"broken state after blockComment in \" + modeName, data);\n        }\n    }\n    \n    function testLineComment(tokenizer, commentStart, modeName) {\n        var tokens = tokenizer.getLineTokens(commentStart + \" \", \"start\").tokens;\n        if (!/comment/.test(tokens[0].type)) {\n            die(\"broken lineCommentStart in \" + modeName, tokens);\n        }\n    }\n\n    function testBrackets(mode, modeName) {\n        if (/^(forth|mask)$/.test(modeName)) return;\n        \n        var session = new EditSession(\"{ foo[ bar(baz) ] }\", mode);\n        \n        var isInvalid = session.getTokens(0).some(function(t) { \n            return /invalid|illegal|string/.test(t.type); \n        });\n        if (isInvalid) return;\n\n        var position = session.findMatchingBracket({row:0, column:1});\n        if (!position || position.column != 18)\n            die(\"Matching bracket not found in \" + modeName);\n        position = session.findMatchingBracket({row:0, column:6});\n        if (!position || position.column != 16)\n            die(\"Matching bracket not found in \" + modeName);\n        position = session.findMatchingBracket({row:0, column:11});\n        if (!position || position.column != 14)\n            die(\"Matching bracket not found in \" + modeName);\n        \n        if (mode.$behaviour) {\n            session.setValue(\"\");\n            editor.setSession(session);\n            editor.execCommand(\"insertstring\", \"(\");\n            if (editor.getValue() != \"()\")\n                return silent || console.log(\"() not paired in \" + modeName);\n            editor.execCommand(\"insertstring\", \"(\");\n            if (editor.getValue() != \"(())\")\n                die(\"(()) not paired in \" + modeName);\n        }\n    }\n\n    function die() {\n        console.warn.apply(console, arguments);\n        process.exit(1);\n    }\n}\n\nfunction generateTestData(names, force) {\n    var docRoot = root + \"/demo/kitchen-sink/docs\";\n    var docs = fs.readdirSync(docRoot);\n    var specialDocs = fs.readdirSync(cwd);\n    var modes = modeList();\n\n    // console.log(\"Docs:\", docs);\n    // console.log(\"Modes:\", modes);\n\n    docs.forEach(function(docName) {\n        var p = docName.toLowerCase().split(\".\");\n        if (!p[1])\n            return;\n        var modeName;\n        if (modes.indexOf(p[0]) != -1)\n            modeName = p[0];\n        else if (modes.indexOf(p[1]) != -1)\n            modeName = p[1];\n        else\n            modeName = {\"txt\": \"text\", cpp: \"c_cpp\"}[p[1]];\n\n        if (names && names.length && names.indexOf(modeName) == -1)\n            return;\n        \n        var outputPath = cwd + \"tokens_\" + modeName + \".json\";\n        try {\n            var oldOutput = require(outputPath);\n        } catch(e) {}\n        if (oldOutput && !force) {\n            var oldText = oldOutput.map(function(x) {\n                if (x.length > 1 && typeof x[x.length - 1] == \"string\")\n                    return x[x.length - 1];\n                return x.slice(1).map(function(tok) {\n                    return tok[1];\n                }).join(\"\");\n            }).join(\"\\n\");\n        }\n        \n        var filePath = \"text_\" + modeName + \".txt\";\n        if (specialDocs.indexOf(filePath) !== -1) {\n            filePath = cwd + filePath;\n        } else {\n            filePath = docRoot + \"/\" + docName;\n            // oldText = \"\";\n        }\n        var text = oldText ||fs.readFileSync(filePath, \"utf8\");\n        \n        try {\n            var Mode = require(\"../\" + modeName).Mode;\n        } catch(e) {\n            console.warn(\"Can't load mode :\" + modeName, p, e);\n            return;\n        }\n        silent || console.log(modeName);\n        var tokenizer = new Mode().getTokenizer();\n\n        var state = \"start\";\n        var data = text.split(/\\r\\n|\\r|\\n/).map(function(line) {\n            var data = tokenizer.getLineTokens(line, state);\n            var tmp = [];\n            tmp.push(JSON.stringify(data.state));\n            var tokenizedLine = \"\";\n            data.tokens.forEach(function(x) {\n                tokenizedLine += x.value;\n                tmp.push(JSON.stringify([x.type, x.value]));\n            });\n            if (tokenizedLine != line)\n                tmp.push(JSON.stringify(line));\n            state = data.state;\n            return tmp.join(\",\\n  \");\n        });\n        \n        var jsonStr = \"[[\\n   \" + data.join(\"\\n],[\\n   \") + \"\\n]]\";\n        \n        if (oldOutput && JSON.stringify(JSON.parse(jsonStr)) == JSON.stringify(oldOutput))\n            return;\n        \n        fs.writeFileSync(outputPath, jsonStr, \"utf8\");\n    });\n}\n\nfunction test(startAt) {\n    var modes = fs.readdirSync(cwd).map(function(x) {\n        return (x.match(/tokens_(.*).json/) || {})[1];\n    }).filter(function(x){return !!x;});\n\n    for (var i = Math.max(0, startAt||0); i < modes.length; i++)\n        testMode(modes[i], i);\n\n    silent || console.log(\"\\u001b[32m\" + \"all ok\" + \"\\u001b[0m\");\n}\nfunction testMode(modeName, i) {\n    silent || console.log(padNumber(i+1, 3) + \") testing: \\u001b[33m\" + modeName + \"\\u001b[0m\");\n\n    var text = fs.readFileSync(cwd + \"tokens_\" + modeName + \".json\", \"utf8\");\n    var data = JSON.parse(text);\n    var Mode = require(\"../\" + modeName).Mode;\n    var tokenizer = new Mode().getTokenizer();\n\n    // TODO this is too slow to run in regular tests\n    if (RECHECK) checkBacktracking(tokenizer);\n\n    var state = \"start\";\n    data.forEach(function(lineData) {\n        lineData.values = [];\n        lineData.types = [];\n        lineData.state = lineData.shift();\n        var line = null;\n        if (typeof lineData[lineData.length - 1] == \"string\")\n            line = lineData.pop();\n        lineData.forEach(function(x) {\n            lineData.types.push(x[0]);\n            lineData.values.push(x[1]);\n        });\n        if (typeof line != \"string\")\n            line = lineData.values.join(\"\");\n\n        var tokens = tokenizer.getLineTokens(line, state);\n        var values = tokens.tokens.map(function(x) {return x.value;});\n        var types = tokens.tokens.map(function(x) {return x.type;});\n\n        var err = testEqual([\n            JSON.stringify(lineData.state), JSON.stringify(tokens.state),\n            lineData.types, types,\n            lineData.values, values]);\n        \n        if (err) {\n            console.log(line);\n            throw \"error\";\n        }\n\n        state = tokens.state;\n    });\n}\nfunction testEqual(a) {\n    var err;\n    if (a[0] + \"\" !== a[1] + \"\") {\n        console.log(a[0],a[1]);\n        err = 1;\n    }\n\n    if ( a[2] + \"\" !== a[3] + \"\" || a[4] + \"\" !== a[5] + \"\") {\n        arrayDiff(a[2],a[3]);\n        arrayDiff(a[4],a[5]);\n        err = 1;\n    }\n    return err;\n}\nfunction arrayDiff(a1, a2) {\n    var l = Math.max(a1.length, a2.length);\n    var out = [];\n    for (var i = 0; i < l; i++) {\n        out.push(\"\\n\", padNumber(i+1, 3), \") \");\n        if (a1[i] !== a2[i])\n            out.push(\"\\u001b[31m\", a1[i], \"\\u001b[0m != \\u001b[32m\", a2[i], \"\\u001b[0m\");\n        else\n            out.push(a1[i]);\n    }\n    console.log(out.join(\"\"));\n}\nfunction padNumber(num, digits) {\n    return (\"      \" + num).slice(-digits);\n}\n\nfunction checkBacktracking(tokenizer) {\n    var states = tokenizer.states;\n    Object.keys(states || {}).forEach(function(state) {\n        states[state].forEach(function(rule) {\n            var regex = rule.regex;\n            if (regex && typeof regex != \"string\") regex = regex.source;\n            if (!regex) return;\n            regex = \"(\" + regex + \")|\";\n            var result = require(\"recheck\").checkSync(regex, \"gmi\", {\n                checker: \"automaton\",\n                timeout: 100000\n            });\n            if (result.status != \"safe\") {\n                if (result.attack && result.attack.string) delete result.attack.string;\n                \n                console.log(\"\\tPossible error in\", state, rule, result);\n            }\n        });\n    });\n}\n\n// cli\nvar silent = false;\nvar arg = process.argv[2];\nvar RECHECK = process.argv.indexOf(\"--recheck\") !== -1;\nif (global.describe && global.it) {\n    silent = true;\n    global.describe(\"check modes\", function() {\n        if (this.timeout) this.timeout(20000);\n        global.it(\"should check modes\", function() {\n            checkModes();\n        });\n        global.it(\"should test modes\", function() {\n            test();\n        });\n    });\n}\nelse if (!arg) {\n    test();\n    checkModes();\n} else if (/--?g(en)?/.test(arg))\n    generateTestData(process.argv.splice(3));\nelse if (/--?c(heck)?/.test(arg))\n    checkModes();\nelse if (/\\d+/.test(arg))\n    test(parseInt(process.argv[2],10) || 0);\nelse\n    testMode(arg, -1);\n"
  },
  {
    "path": "src/mode/_test/text_alda.txt",
    "content": "vibraphone:\n  (quant 200)\n  (key-signature \"f+ c+ g+\")\n  a8 b > c d e f g a <\n  a b > c_ d e f_ g_ a <\n\n  (key-signature [:g :minor])\n  g a b > c+ d e f+ g <\n\n  (key-signature {:e [:flat] :b [:flat]})\n  g1~1/b/d"
  },
  {
    "path": "src/mode/_test/text_asciidoc.txt",
    "content": "------------------------------------\n-----------------------------------\n_ita_lic_, *bo*ld*, +mo+no+, normal. \n``double quoted'', `single quoted'.\n  normal, ^super^, ~sub~.\n\n''''\nEscaped:\n\\_italic_, +++_italic_+++,\nt\\__e__st, +++t__e__st+++,\n+++<b>bold</b>+++, $$<b>normal</b>$$\n\\&#182; &#182;\n\\`not single quoted'\n\\`\\`not double quoted''\n\n\n[fffff]\n+++++++++++++++++++++++++++++++++++++\n(C) {ss} ss\n+++++++++++++++++++++++++++++++++++++\n\n.............\ncallout <1>\n..............\n\n> 1\n1> 2\n<2> 3\n\nEscaped:\n\\_italic_,\nt\\__e__st, o__\n\n.optional title\n.............\ncallout <1>\n..............\n\n\n:macro: dddd\n\n.lists\n. 1\n.. 2\n... d\n..... big\n+\ncontinue +\nnext line\nxi) no ++la+tin++\n\nxi) la++tin++\n2. num__ber__  [red]#red#\n--\n  5. f <<x6,ssss>> {macro}\n--\nimage::path[beauty] ->--<= -- replacements\n\n image::s\nsssss\nsss \nsssss\n\n\n== 1\n  heading\n=== not a heading\n====================================\n\n==================================\n====4 \nNOTE: above\n\nNOTE: above\n\n[[x6]]\nWARNING: \n\n[options[]]\n---------------------------\nliteral\n---------------------------\n\n\n= Tables\n|====================================\n| _italic_ |  *bold* | text | (R)\n\n|====================================\n\n\n[more, options]\n///////////\ncomment\n///////////\n// one line comment\n\n\n\n[red]#red text# [yellow-background]#on yellow#\n[big]#large# [red yellow-background big]*all bold*\n\n\t\nhttps://site text <mail@i.am> callto:ace http://ace.ajaxorg.com[awesome]\n  .still normal text\n.break out thoug should not\n---------------------------\n///////////////////////////\n---------------------------\n\n\n"
  },
  {
    "path": "src/mode/_test/text_coffee.txt",
    "content": "#test: tokenize keyword\n    for (i 1..2)\n#test: tokenize regexp\n/\"[a]/\n#test: tokenize functions\nfoo = ({args}) ->\n    foo = ({a1, a2}) ->\n    foo = ({@a1, a2}) ->\n    foo : ({args}) ->\n    foo = ({args}) ->\n    foo = ({0abc}) ->\n    foo = ({/abc}) =>\n    foo = ({abc/}) ->\n    foo = ({#abc}) ->\n    foo = ({abc#}) ->\n    foo = ({)abc}) ->\n    foo = ({abc)}) ->\n    foo = ({a{bc}) ->\n    foo = ({}) ->\n    foo = ({ }) ->\n    foo : ({}) ->\n    foo = (args) ->\n    foo = (arg1, arg2) ->\n    foo = (arg1 = 1, arg2 = 'name') ->\n    foo = (@arg1 = /abc/, arg2 = 'name') ->\n    #test: tokenize function: invalid case:\n    foo=(/args) ->\n    foo = () ->\n    foo = ( ) ->\n    foo : ( ) ->\n    window.foo = (args) ->\n    foo = ->\n    foo = ->\n    foo : ->\n    #test: tokenize callback function\n    foo bar: 1, (args) ->\n    foo = (1, 2 (x) ->\n#test: tokenize class\nclass Foo\nclass Foo extends Bar\n#test: tokenize illegal name property\nfoo.static.function\n#!test tokenize string with interpolation\na = \"#{ 22 / 7 + {x: \"#{a + b}\"} + 2}\"\n\" #{ \"\" + {} } )\"  \n\"\"\"heredoc\n   \"\"\"\ndo ->\n    ###\n    herecomment\n    ###\n    re = /regex/imgy.test ///\n        heregex  # comment\n    ///imgy\n    this isnt: `just \n       JavaScript`\n    undefined\n"
  },
  {
    "path": "src/mode/_test/text_coldfusion.txt",
    "content": "<!--- hello world --->\n\n<cfset <!--- x <!--- y --->  z ---> welcome=\"Hello World!\">\n<!-- x <!--- y --->  z -->\n<cfoutput>#welcome#</cfoutput>\n<cfscript>\n    Dateformat(now())\n</cfscript>"
  },
  {
    "path": "src/mode/_test/text_curly.txt",
    "content": "tokenize Curly template{{test}}\ntokenize embedded script\n<script a='a'>var</script>'123'\ntokenize multiline attribute value with double quotes\n<a href=\"abc{{xyz}}\ndef\">\ntokenize multiline attribute value with single quotes\n<a href='abc\ndef\\\"'>\n"
  },
  {
    "path": "src/mode/_test/text_ejs.txt",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>Cloud9 Rocks!</title>\n    </head>\n    <body>\n\n    <table class=\"table\">\n        <tr>\n            <th>Name</th>\n            <th>Size</th>\n        </tr>\n        <% if (!isRoot) { %>\n            <tr>\n                <td><a href=\"..\">..</a></td>\n                <td></td></td>\n            </tr>\n        <% } %>\n        <% entries.forEach(function(entry) { %>\n            <tr>\n                <td>\n                    <span class=\"glyphicon <%= entry.mime == 'directory' ? 'folder': 'file'%>\"></span>\n                    <a href=\"<%= entry.name %>\"><%= entry.name %></a>\n                </td>\n                <td><%= entry.size %></td>\n            </tr>\n        <% }) %>\n    </table>\n    <input  placeholder=\"Username or email\" \n<%\nif (typeof window != 'undefined') { \n%>\nvalue=\"<%=window%>\"\n<% \n\t}\n%>\n\t\t\t\t\t\t\t\t/>\n    </body>\n</html>"
  },
  {
    "path": "src/mode/_test/text_gobstones.txt",
    "content": "/*\n * A Gobstones implementation of Conwey's Game of Life\n * that tries to use most of Gobstones syntax.\n *\n * Check out more about Gobstones at http://gobstones.org\n */\n\n-----------------------------------------------------------\n--         HELPERS TO MOVE AROUND ALL THE BOARD          --\n-----------------------------------------------------------\n\n// This helpers allow the user to move around the board\n// one cell at a time\nprocedure GoToStartOfBoard(firstDir, secondDir) {\n    IrAlBorde(opuesto(firstDir))\n    IrAlBorde(opuesto(secondDir))\n}\n\nfunction isEndOfBoard(firstDir, secondDir) {\n    return (not puedeMover(firstDir) && not puedeMover(secondDir))\n}\n\nprocedure NextCellOfTheBoard(firstDir, secondDir) {\n    if (puedeMover(firstDir)) {\n        Mover(firstDir)\n    } else {\n        IrAlBorde(opuesto(firstDir))\n        Mover(secondDir)\n    }\n}\n\n-----------------------------------------------------------\n--                   TYPE DECLARATIONS                   --\n-----------------------------------------------------------\n// The cell type declarations\ntype CellStatus is variant {\n    case Alive {}\n    case Dead  {}\n}\n\ntype Cell is record {\n    field status  # CellStatus\n    field color   # Color\n}\n\n\n-----------------------------------------------------------\n--                  PROGRAM DEFINITION                   --\n-----------------------------------------------------------\ninteractive program {\n    # Map key press to actions\n    K_UP     -> { PrepareNextTick()  }\n    K_RIGHT  -> { CompleteNextTick() }\n    K_RETURN -> { SimulateNextTick() }\n}\n\n/*\nprogram {\n    return ( numberOfNeighbors())\n}\n*/\n-----------------------------------------------------------\n--                      FUNCTIONS                        --\n-----------------------------------------------------------\nfunction isCellAlive() {\n    return (hayBolitas(Verde))\n}\n\nfunction cellStatus() {\n    return (\n        choose\n            Alive when (isCellAlive())\n            Dead otherwise\n    )\n}\n\nfunction readCell() {\n    return (\n        Cell(color <- Verde, status <- cellStatus())\n    )\n}\n\nfunction numberOfNeighbors() {\n    amountOfNeighbors := 0\n    foreach dir in [minDir() .. maxDir()] {\n        amountOfNeighbors := amountOfNeighbors + aliveCellsAt(dir)\n    }\n    return (amountOfNeighbors)\n}\n\nfunction aliveCellsAt(dir) {\n    firstCompare := puedeMover(dir) && hasAliveCellAt(dir)\n    secondCompare := puedeMover(dir) && puedeMover(siguiente(dir)) && hasAliveCellAtD(dir)\n    value :=\n        matching (firstCompare) select\n            1 on True\n            0 otherwise\n        +\n        matching (secondCompare) select\n            1 on True\n            0 otherwise\n    return (value)\n}\n\nfunction hasAliveCellAt(dir) {\n    Mover(dir)\n    return (isCellAlive())\n}\n\nfunction hasAliveCellAtD(dir) {\n    Mover(dir)\n    Mover(siguiente(dir))\n    return (isCellAlive())\n}\n\n-----------------------------------------------------------\n--              ROCEDURES DECLARATIONS                   --\n-----------------------------------------------------------\nprocedure TagAsReanimated() {\n    Poner(Azul)\n}\n\nprocedure TagAsDead() {\n    Poner(Rojo)\n}\n\nprocedure ProcessAction() {\n    switch (hayBolitas(Rojo)) {\n        True -> { Sacar(Verde); Sacar(Rojo) }\n        _ -> {}\n    }\n    switch (hayBolitas(Azul)) {\n        True -> { Poner(Verde); Sacar(Azul) }\n        _ -> {}\n    }\n}\n\nprocedure TagCell(numNeighbors) {\n    if     (    isCellAlive() && numNeighbors < 2)  { TagAsDead() }\n    elseif (    isCellAlive() && numNeighbors > 3)  { TagAsDead() }\n    elseif ((not isCellAlive()) && numNeighbors == 3) { TagAsReanimated() }\n}\n\nprocedure SimulateTicks(amount) {\n    repeat(amount) {\n        SimulateNextTick()\n    }\n}\n\nprocedure SimulateNextTick() {\n    PrepareNextTick()\n    CompleteNextTick()\n}\n\nprocedure PrepareNextTick() {\n    GoToStartOfBoard(Norte, Este)\n    while (not isEndOfBoard(Norte, Este)) {\n        TagCell(numberOfNeighbors())\n        NextCellOfTheBoard(Norte, Este)\n    }\n    TagCell(numberOfNeighbors())\n}\n\nprocedure CompleteNextTick() {\n    GoToStartOfBoard(Norte, Este)\n    while (not isEndOfBoard(Norte, Este)) {\n        ProcessAction()\n        NextCellOfTheBoard(Norte, Este)\n    }\n    ProcessAction()\n}\n"
  },
  {
    "path": "src/mode/_test/text_html.txt",
    "content": "<html>\n<scripts>\n<script a='a'>var \"</scripts></script>'123'\n</scripts>\n<a href=\"abc\n  def\">\n<a href='abc\ndef\\'>\n\n</html>"
  },
  {
    "path": "src/mode/_test/text_javascript.txt",
    "content": "//test: tokenize 'standard' functions\nstring.charCodeAt(23); document.getElementById('test'); console.log('Here it is');\";\ntest: /**tokenize doc*/ comment\n/**tokenize doc comment with @tag {}*/\n//test: tokenize parens\n    var $line$ = \"[{( )}]\";\n//test tokenize arithmetic expression which looks like a regexp\na/b/c\na/=b/c\n//test tokenize reg exps\na=/b/g\na+/b/g\na = 1 + /2 + 1/gimyxk\na=/a/ / /a/\ncase /a/.test(c)\n//test tokenize multi-line comment containing a single line comment\nnoRegex\n/* foo // bar */\ncanBeRegex;\n/* foo // bar */\n// test tokenize identifier with umlauts\nfu?e\n// test // is not a regexp\n{ // 123\n//test skipping escaped chars\n'Meh\\\\nNeh'\nconsole.log('\\\\u1232Feh'\n\"test multiline\\\n strings\"\na='\nb=\"\\\nstill a string\n\n\nfunction foo(items, nada) {\n    for (var i=0; i<items.length; i++) {\n        alert(items[i] + \"juhu\\n\");\n    }\t// Real Tab.\n}\n\nregexp = /p|p/ // ends here\n\nr = /d{1,2}?f{e}++r*?\\d+?[]r[^r-o\\f\\f[\\f]?r{7}+r\\{7}+rr--rr$^(?:d|s)(?=a|)(?!y)[]|$?|^*/ o\na=/a/ jk = / / / / /\n /************************************/\n/** total mess, tricky to highlight**/\n\nfunction () {\n\t/**\n\t * docComment\n\t **/\n\tr = /u\\t*/\n\tg = 1.00E^1, y = 1.2 + 1. + .2 + 052 + 0O7 + 0x25\n\tt = ['d', '']\n}\nfunction () {\n\t/* eee */\n}\n\n\"s\\\ns\\u7824sss\\u1\"\n\n'\\\nstring'\n\n'\nstring'\n\n\"trailing space\\\n\"         \"    /not a regexp/g\n\n/**\n *doc\n */\n\na = {\n\t'a': b,\n\t'g': function(t)\n\tgta:function(a,b)\n}\n\nz>>=t<<f>>r>>>s>=0b1\n\nfoo.prototype.d = function(a, b,\n                          c, d)\nfoo.d =function(a,     b)\nfoo.d =function(a,  /*****/ d\"string\"\n\n<div\nz=<div {...this.props} x={1 + 2} y=\"z{a}b&amp;\" t={\n        1 + <a>{2}</a>\n    }>\n1 <a> { ++x  } </a>\n</div>\n\nvar o = {\n    t:`${[].map(x => {\n        return x\n    })}`\n};\n\n//test generator function\nfunction* range (start, end, step) {\n    while (start < end) {\n        yield start\n        start += step\n    }\n}\n//test ES6 new built-in methods\n\"hello\".startsWith(\"ello\", 1) // true\n\"hello\".endsWith(\"hell\", 4)   // true\n\"hello\".includes(\"ell\")       // true\n[ 1, 3, 4, 2 ].find(x => x > 3) // 4\n[ 1, 3, 4, 2 ].findIndex(x => x > 3) // 2\n\"foo\".repeat(3)\nNumber.isSafeInteger(42) === true\n\nlet x = Number.MAX_SAFE_INTEGER;\nlet x = Number.MIN_SAFE_INTEGER;\nlet x = Number.EPSILON;\n//test Promises\nnew Promise(tetheredGetNumber)\n  .then(determineParity, troubleWithGetNumber)\n  .then(promiseGetWord)\n  .then((info) => {\n    console.log(`Got: ${info.value}, ${info.wordEvenOdd}`);\n    return info;\n  })\n  .catch((reason) => {\n    if (reason.cause) {\n      console.error(\"Had previously handled error\");\n    } else {\n      console.error(`Trouble with promiseGetWord(): ${reason}`);\n    }\n  })\n  .finally((info) => console.log(\"All done\"));\n//test ES6 arrow functions\nparam => expression;\n\n(param) => expression;\n\n(param1 = 123, paramN = \"test\") => expression;\n\nparam => {\n  statements;\n};\n(param1, paramN) => {\n  statements\n}\n\n(a, b, ...r) => expression;\n\n(a = 400, b = 20, c) => expression;\n\nasync param => expression;\n\n//test JSX functions arguments in arrow functions\n<Component onclick={(param1, param2 = \"Test\", ...paramN) => {\n    console.log(\"Test\")\n}}/>\n<Component onclick={param1 => {\n    console.log(\"Test\")\n}}/>\n\n//test different generator functions use cases\nfunction* generator() {}\nfunction*generator() {}\nSound.play = function* play() {  }\nfoobar: function   *   () { }\n\n//func's args shouldn't be determined as arrow function\nfunc (a,b,1,2,3, async () => {})\nfunc(a,b,innerCall(c,d), () => {})\n\n//async arrow function with default params\nasync (param1, param2, ...paramN) => {\n  statements\n}\n\n\n//all should be constant.numeric\n1_000_000_000_000\n1_050.95\n0b1010_0001_1000_0101\n0o2_2_5_6\n0xA0_B0_C0\n1_000_000_000_000_000_000_000n\n1.0_1322323_33\n1.\n0.4_3223_32"
  },
  {
    "path": "src/mode/_test/text_livescript.txt",
    "content": "# comment\n"
  },
  {
    "path": "src/mode/_test/text_lucene.txt",
    "content": " foo\nfoo: foo AND bar\nfoo AND bar\nfoo OR bar\nfoo NOT bar\n\"foo bar\"\nbar \"foo bar\"\nbar -foo\nbar -\"foo bar\"\n-foo\n-\"foo bar\"\nbar foo~100\nfoo~100\nfoo~100 bar\n\"foo bar\"~10\nfoo~\nbar foo~\nfoo~ bar\nfoo~0.8\nfield:foo\nfield:foo bar\nfield:\"foo bar\"\n(foo AND bar)\n(field:foo AND field:\"bar baz\")\nfoo*\nf?o\nf*o\n+foo\n+\"foo bar\"\nfoo?\n?oo\nfoo\nfield:(-foo +bar +\"foo bar\")\nfield:{foo TO bar}\nfield:[foo TO bar]\nfield:[\"a b c\" TO def]\nfield:{\"a b c\" TO def}\nfield:{foo TO \"bar\"}\nfield:{20180101 TO 20190202}\nfield:{\"2018-01-01\" TO \"2019-02-02\"}\n\\+escaped\n\\-escaped\nesc\\&aped\nesc\\|aped\n\\!escaped\n\\(escaped\\)\n\\{escaped\\}\n\\[escaped\\]\nescaped\\^4\n\\\"escaped\\\"\nescaped\\~0.4\nescaped\\*\nescaped\\?\nesc\\:aped\nesc\\\\aped\nesc\\ aped:foo\n\"foo\\\"bar\"\nfoo:/bar/\n"
  },
  {
    "path": "src/mode/_test/text_markdown.txt",
    "content": "test: header 1 \n#f\n# f\ntest: header 2\n## foo\ntest: header ends with ' #'\n# # # \ntest: header ends with '#'\n# foo# \ntest: 6+ #s is not a valid header\n####### foo\ntest: # followed be only space is a valid header\n# \ntest: only space between #s is a valid header\n#  #\n\n# test links  [Cloud9 IDE](http://www.c9.io/) #\n* [demo](http://ajaxorg.github.com/ace/) [+](escape(\\) ) [+](a \"title\") [+](a \"space\" )\n* usually *work* fine (_em_)\nin lists\n\nin plain text <b>http://ace.ajaxorg.com<b>\n\n"
  },
  {
    "path": "src/mode/_test/text_php.txt",
    "content": "<?php\n$bar = <<<EOD\nhighlightingWithNoSpaces\ndoesn't break\nEOD;\n\nlorem('ipsum', <<<TEST\nfoo bar\nTEST\n);\n\nfunction nfact($n) {\n    if ($n == 0) {\n        return 1;\n    }\n    else {\n        return $n * nfact($n - 1);\n    }\n}\n\necho \"\\n\\nPlease enter a whole number ... \";\n$num = trim(fgets(STDIN));\n\n// ===== PROCESS - Determing the factorial of the input number =====\n$output = \"\\n\\nFactorial \" . $num . \" = \" . nfact($num) . \"\\n\\n\";\necho $output;\n\n?> <script>  <?php\necho '\n';\n\n1_000_000;\n6.62_607_004e-34;\n0.300_000_000_000_000_04;\n0b1111_0000_1001_1111_1001_0010_1010_1001;\n0123_7264;\n0xBEEF_BABE;\n0o123;\n?>\n/*this is js <?php echo ':)'; ?>\n</script> not &js;\n"
  },
  {
    "path": "src/mode/_test/text_prisma.txt",
    "content": "generator photon {\n  provider = \"photonjs\"\n}\n\nmodel User {\n  id                 String           @default(cuid()) @id\n  createdAt          DateTime         @default(now())\n  updatedAt          DateTime         @updatedAt\n  firstName          String\n  lastName           String\n  email              String           @unique\n  password           String\n  phone              String\n  responseRate       Float?\n  responseTime       Int?\n  ReportsTo  User?  @relation(\"EmployeeToEmployee_ReportsTo\")\n  employees         User[] @relation(\"EmployeeToEmployee_ReportsTo\")\n  isSuperHost        Boolean\n  ownedPlaces        Place[]\n  location           Location?\n  bookings           Booking[]\n  paymentAccount     PaymentAccount[]\n  sentMessages       Message[]        @relation(\"SentMessages\")\n  receivedMessages   Message[]        @relation(\"ReceivedMessages\")\n  notifications      Notification[]\n  profilePicture     Picture?\n  hostingExperiences Experience[]\n}\n\nmodel Place {\n  id                String             @default(cuid()) @id\n  name              String\n  size              PLACE_SIZES?\n  shortDescription  String\n  description       String\n  slug              String\n  maxGuests         Int\n  numBedrooms       Int\n  numBeds           Int\n  numBaths          Int\n  reviews           Review[]\n  amenities         Amenities\n  host              User\n  pricing           Pricing\n  location          Location\n  views             Views\n  guestRequirements GuestRequirements?\n  policies          Policies?\n  houseRules        HouseRules?\n  bookings          Booking[]\n  pictures          Picture[]\n  popularity        Int\n}\n\nmodel Pricing {\n  id              String    @default(cuid()) @id\n  place           Place\n  monthlyDiscount Int?\n  weeklyDiscount  Int?\n  perNight        Int\n  smartPricing    Boolean\n  basePrice       Int\n  averageWeekly   Int\n  averageMonthly  Int\n  cleaningFee     Int?\n  securityDeposit Int?\n  extraGuests     Int?\n  weekendPricing  Int?\n  currency        CURRENCY?\n}\n\nmodel GuestRequirements {\n  id                            String  @default(cuid()) @id\n  govIssuedId                   Boolean\n  recommendationsFromOtherHosts Boolean\n  guestTripInformation          Boolean\n  place                         Place\n}\n\nmodel Policies {\n  id               String   @default(cuid()) @id\n  createdAt        DateTime @default(now())\n  updatedAt        DateTime @updatedAt\n  checkInStartTime Float\n  checkInEndTime   Float\n  checkoutTime     Float\n  place            Place\n}\n\nmodel HouseRules {\n  id                      String   @default(cuid()) @id\n  createdAt               DateTime @default(now())\n  updatedAt               DateTime @updatedAt\n  suitableForChildren     Boolean?\n  suitableForInfants      Boolean?\n  petsAllowed             Boolean?\n  smokingAllowed          Boolean?\n  partiesAndEventsAllowed Boolean?\n  additionalRules         String?\n}\n\nmodel Views {\n  id       String @default(cuid()) @id\n  lastWeek Int\n  place    Place\n}\n\nmodel Location {\n  id            String         @default(cuid()) @id\n  lat           Float\n  lng           Float\n  neighbourHood Neighbourhood?\n  user          User?\n  place         Place?\n  address       String\n  directions    String\n  experience    Experience?\n  restaurant    Restaurant?\n}\n\nmodel Neighbourhood {\n  id          String     @default(cuid()) @id\n  locations   Location[]\n  name        String\n  slug        String\n  homePreview Picture?\n  city        City\n  featured    Boolean\n  popularity  Int\n}\n\nmodel City {\n  id             String          @default(cuid()) @id\n  name           String\n  neighbourhoods Neighbourhood[]\n}\n\nmodel Picture {\n  id  String @default(cuid()) @id\n  url String\n}\n\nmodel Experience {\n  id             String              @default(cuid()) @id\n  category       ExperienceCategory?\n  title          String\n  host           User\n  location       Location\n  pricePerPerson Int\n  reviews        Review[]\n  preview        Picture\n  popularity     Int\n}\n\nmodel ExperienceCategory {\n  id         String      @default(cuid()) @id\n  mainColor  String\n  name       String\n  experience Experience?\n}\n\nmodel Amenities {\n  id                        String  @default(cuid()) @id\n  place                     Place\n  elevator                  Boolean\n  petsAllowed               Boolean\n  internet                  Boolean\n  kitchen                   Boolean\n  wirelessInternet          Boolean\n  familyKidFriendly         Boolean\n  freeParkingOnPremises     Boolean\n  hotTub                    Boolean\n  pool                      Boolean\n  smokingAllowed            Boolean\n  wheelchairAccessible      Boolean\n  breakfast                 Boolean\n  cableTv                   Boolean\n  suitableForEvents         Boolean\n  dryer                     Boolean\n  washer                    Boolean\n  indoorFireplace           Boolean\n  tv                        Boolean\n  heating                   Boolean\n  hangers                   Boolean\n  iron                      Boolean\n  hairDryer                 Boolean\n  doorman                   Boolean\n  paidParkingOffPremises    Boolean\n  freeParkingOnStreet       Boolean\n  gym                       Boolean\n  airConditioning           Boolean\n  shampoo                   Boolean\n  essentials                Boolean\n  laptopFriendlyWorkspace   Boolean\n  privateEntrance           Boolean\n  buzzerWirelessIntercom    Boolean\n  babyBath                  Boolean\n  babyMonitor               Boolean\n  babysitterRecommendations Boolean\n  bathtub                   Boolean\n  changingTable             Boolean\n  childrensBooksAndToys     Boolean\n  childrensDinnerware       Boolean\n  crib                      Boolean\n}\n\nmodel Review {\n  id            String      @default(cuid()) @id\n  createdAt     DateTime    @default(now())\n  text          String\n  stars         Int\n  accuracy      Int\n  location      Int\n  checkIn       Int\n  value         Int\n  cleanliness   Int\n  communication Int\n  place         Place\n  experience    Experience?\n}\n\nmodel Booking {\n  id        String   @default(cuid()) @id\n  createdAt DateTime @default(now())\n  bookee    User\n  place     Place\n  startDate DateTime\n  endDate   DateTime\n  payment   Payment?\n}\n\nmodel Payment {\n  id            String         @default(cuid()) @id\n  createdAt     DateTime       @default(now())\n  serviceFee    Float\n  placePrice    Float\n  totalPrice    Float\n  booking       Booking\n  paymentMethod PaymentAccount\n}\n\nmodel PaymentAccount {\n  id         String                 @default(cuid()) @id\n  createdAt  DateTime               @default(now())\n  type       PAYMENT_PROVIDER?\n  user       User\n  payments   Payment[]\n  paypal     PaypalInformation?\n  creditcard CreditCardInformation?\n}\n\nmodel PaypalInformation {\n  id             String         @default(cuid()) @id\n  createdAt      DateTime       @default(now())\n  email          String\n  paymentAccount PaymentAccount\n}\n\nmodel CreditCardInformation {\n  id             String          @default(cuid()) @id\n  createdAt      DateTime        @default(now())\n  cardNumber     String\n  expiresOnMonth Int\n  expiresOnYear  Int\n  securityCode   String\n  firstName      String\n  lastName       String\n  postalCode     String\n  country        String\n  paymentAccount PaymentAccount?\n}\n\nmodel Message {\n  id          String   @default(cuid()) @id\n  createdAt   DateTime @default(now())\n  from        User     @relation(\"SentMessages\")\n  to          User     @relation(\"ReceivedMessages\")\n  deliveredAt DateTime\n  readAt      DateTime\n}\n\nmodel Notification {\n  id        String             @default(cuid()) @id\n  createdAt DateTime           @default(now())\n  type      NOTIFICATION_TYPE?\n  user      User\n  link      String\n  readDate  DateTime\n}\n\nmodel Restaurant {\n  id                String    @default(cuid()) @id\n  createdAt         DateTime  @default(now())\n  title             String\n  avgPricePerPerson Int\n  pictures          Picture[]\n  location          Location\n  isCurated         Boolean\n  slug              String\n  popularity        Int\n}\n\nenum CURRENCY {\n  CAD\n  CHF\n  EUR\n  JPY\n  USD\n  ZAR\n}\n\nenum PLACE_SIZES {\n  ENTIRE_HOUSE\n  ENTIRE_APARTMENT\n  ENTIRE_EARTH_HOUSE\n  ENTIRE_CABIN\n  ENTIRE_VILLA\n  ENTIRE_PLACE\n  ENTIRE_BOAT\n  PRIVATE_ROOM\n}\n\nenum PAYMENT_PROVIDER {\n  PAYPAL\n  CREDIT_CARD\n}\n\nenum NOTIFICATION_TYPE {\n  OFFER\n  INSTANT_BOOK\n  RESPONSIVENESS\n  NEW_AMENITIES\n  HOUSE_RULES\n}"
  },
  {
    "path": "src/mode/_test/text_razor.txt",
    "content": "@{\n\tLayout = \"~/layout\"\n}\n@code{\n\tprivate int count = 0;\n}\n@code {\n\tprivate string name = \"Test\";\n}\n@functions{\n\tpublic void DoSomething() { }\n}\n@model MyApp.Models.User\n@inject IUserService UserService\n@inherits CustomBasePage\n@implements IDisposable\n@attribute [Authorize]\n@layout MainLayout\n@namespace MyApp.Pages\n@rendermode InteractiveServer\n@using System.Collections.Generic\n@page \"/counter\"\n"
  },
  {
    "path": "src/mode/_test/text_ruby.txt",
    "content": " #test: symbol tokenizer\n  [:@thing, :$thing, :_thing, :thing, :Thing, :thing1, :thing_a,\n              :THING, :thing!, :thing=, :thing?, :t?,\n              :, :@, :$, :1, :1thing, :th?ing, :thi=ng, :1thing,\n            :th!ing, :thing#\n    ]\n\n #test: namespaces aren't symbols\" : function() {\n   Namespaced::Class\n #test: hex tokenizer \n    0x9a, 0XA1, 0x9_a, 0x, 0x_9a, 0x9a_,\n #test: float tokenizer\n    [1, +1, -1, 12_345, 0.000_1,\n    _, 3_1, 1_2, 1_.0, 0._1];\n \n{:id => ?\", :key => \"value\", anotherKey: [x, y?]}\n\n=begin\n=end\n\n=begin x\n=end-\n=end   x\n\n    herDocs = [<<'FOO', <<BAR, <<-BAZ, <<-`EXEC`] #comment\n  FOO #{literal}\nFOO\n  BAR #{fact(10)}\nBAR\n  BAZ indented\n    BAZ\n        echo hi\n    EXEC\nputs herDocs"
  },
  {
    "path": "src/mode/_test/text_rust.txt",
    "content": "use core::rand::RngUtil;\n\nfn main() {\n    for [\"Alice\", \"Bob\", \"Carol\"].each |&name| {\n        do spawn {\n            let v = rand::Rng().shuffle([1, 2, 3]);\n            for v.each |&num| {\n                print(fmt!(\"%s says: '%d'\\n\", name, num + 1))\n            }\n        }\n    }\n\n    let _: i128 = -42i128;\n    let _: u128 = 42u128;\n}\n\n/* nested /* \n    comments */ */\n\nfn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {\n    let mut accumulator = ~[];\n    for vec::each(vector) |element| {\n        accumulator.push(function(element));\n    }\n    return accumulator;\n}\n\n\n// numbers\n14E-111_f64; 45isize 0x1i32 0o777u32 0b01 14f32 1_2.78f32 1_2.3E+7f32\n\n// not numbers\n14._E-111_f64; 0xi32; 0b777u\n\n// identifiers ending in constant.numeric\nfoo1; foo1u32; foo1f32; foo0xF; foo1.0\n\n\npub fn g<T>() -> std::mem::MaybeUninit<[T; 1 << 2]> {\n    std::mem::MaybeUninit::uninit()\n}\n\nlet multiline = r##\"\n    This is a raw string.\n    r#\"nested string\"#\n\"##;\nlet empty = br##\"\"##;\nlet _strings = [r\"hello\\\", br\"hello\\\", cr\"hello\\\" ];"
  },
  {
    "path": "src/mode/_test/text_verilog.txt",
    "content": "always @(negedge reset or posedge clk) begin\n  if (reset == 0) begin\n    d_out <= 16'h0000;\n    d_out_mem[resetcount] <= d_out;\n    laststoredvalue <= d_out;\n  end else begin\n    d_out <= d_out + 1'b1; \n  end\nend\n\nalways @(bufreadaddr)\n  bufreadval = d_out_mem[bufreadaddr];\n\nmodule test;\n    assign a = \"1\";\n    initial begin\n        $display(\"Hello \\778\\xaa\\\n                  \\n world\")\n        $finish;\n    end\nendmodule"
  },
  {
    "path": "src/mode/_test/text_wollok.txt",
    "content": "class Actividad {\n\tmethod calcularMejora()\n}\n\nclass EstudiarMateria inherits Actividad {\n\tvar materia\n\tvar puntos = 0\n\t\n\tnew(m, p) {\n\t\tmateria = m\n\t\tpuntos = p\n\t}\n\t\n\toverride method calcularMejora() = puntos\n}\n\nclass EjercitarEnSimulador inherits Actividad {\n\tvar horas = 0\n\tnew(h) { horas = h }\n\toverride method calcularMejora() = 10 * horas\n}\n\nobject pepita {\n\tvar energia = 100\n\tmethod volar(m) {\n\t\tenergia -= m\n\t}\n}"
  },
  {
    "path": "src/mode/_test/text_xml.txt",
    "content": "<Juhu>//Juhu Kinners</Kinners>\ntest: two tags in the same lines should be in separate tokens\"\n<Juhu><Kinners>\ntest: multiline attributes\"\n<copy set=\"{\n}\" undo=\"{\n}\"/>"
  },
  {
    "path": "src/mode/_test/text_yaml.txt",
    "content": "# This sample document was taken from wikipedia:\n# http://en.wikipedia.org/wiki/YAML#Sample_document\n---\nreceipt:     Oz-Ware Purchase Invoice\ndate:        2007-08-06\ncustomer:\n    given:   Dorothy\n    family:  Gale\n\nitems:\n    - part_no:   'A4786'\n      descrip:   Water Bucket (Filled)\n      price:     1.47\n      quantity:  4\n\n    - part_no:   'E1628'\n      descrip:   High Heeled \"Ruby\" Slippers\n      size:      8\n      price:     100.27\n      quantity:  1\n      version:   1.2.3.4\n\nbill-to:  &id001\n    street: |\n            123 Tornado Alley\n            Suite 16\n    ref-id: id123  \n    city:   East Centerville\n    state:  KS\n\nship-to:  *id001\n\nspecialDelivery:  >\n    Follow the Yellow Brick\n    Road to the Emerald City.\n    Pay no attention to the\n    man behind the curtain.\n\n?        |\n block key #1\n kkk\n: - |\n   one \n  - |\n   tw #o \n  - ? |- \n\n     as #d\n\n     q\n    b\n  - \n     x: xx\n     r: xx\n     z: sss\n     zdd: dddd\n     \"block key 2\" : \n       - two # block value\n       - ? | \n          as #d\n         : |\n          asdadas #d\n          asd\n         a: 2\n       - ? | \n          asdas #d\n         :  |\n          xx\n         s: |4+ #comment\n               7\n\n             a \n           a\n"
  },
  {
    "path": "src/mode/_test/tokens_abap.json",
    "content": "[[\n   \"start\",\n  [\"doc.comment\",\"***************************************\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"** Program: EXAMPLE                  **\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"** Author: Joe Byte, 07-Jul-2007     **\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"***************************************\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"keyword\",\"REPORT\"],\n  [\"text\",\" BOOKINGS\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"doc.comment\",\"* Read flight bookings from the database\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"keyword.operator\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" FLIGHTINFO\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"CLASS\"],\n  [\"keyword.operator\",\" = \"],\n  [\"string\",\"'Y'\"],\n  [\"text\",\"       \"],\n  [\"comment\",\"\\\"Y = economy\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"OR\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"CLASS\"],\n  [\"keyword.operator\",\" = \"],\n  [\"string\",\"'C'\"],\n  [\"keyword.operator\",\".\"],\n  [\"text\",\"      \"],\n  [\"comment\",\"\\\"C = business\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"invalid\",\"...\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"REPORT\"],\n  [\"text\",\" TEST\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"keyword\",\"WRITE\"],\n  [\"text\",\" \"],\n  [\"string\",\"'Hello World'\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"USERPROMPT\"],\n  [\"keyword.operator\",\" = \"],\n  [\"string\",\"'Please double-click on a line in the output list '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"]\n],[\n   \"start\",\n  [\"text\",\"             \"],\n  [\"string\",\"'to see the complete details of the transaction.'\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"DATA\"],\n  [\"text\",\" LAST_EOM    \"],\n  [\"keyword\",\"TYPE\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"D\"],\n  [\"keyword.operator\",\".\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"\\\"last end-of-month date\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"doc.comment\",\"* Start from today's date\"]\n],[\n   \"start\",\n  [\"text\",\"  LAST_EOM\"],\n  [\"keyword.operator\",\" = \"],\n  [\"variable.parameter\",\"SY\"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\"DATUM\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"* Set characters 6 and 7 (0-relative) of the YYYYMMDD string to \\\"01\\\",\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"* giving the first day of the current month\"]\n],[\n   \"start\",\n  [\"text\",\"  LAST_EOM\"],\n  [\"constant.numeric\",\"+6\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\" = \"],\n  [\"string\",\"'01'\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"doc.comment\",\"* Subtract one day\"]\n],[\n   \"start\",\n  [\"text\",\"  LAST_EOM\"],\n  [\"keyword.operator\",\" = \"],\n  [\"text\",\"LAST_EOM\"],\n  [\"keyword.operator\",\" - \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"WRITE\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"'Last day of previous month was'\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" LAST_EOM\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"keyword\",\"DATA\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BEGIN OF\"],\n  [\"text\",\" I_VBRK \"],\n  [\"keyword\",\"OCCURS\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"         VBELN \"],\n  [\"keyword\",\"LIKE\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"VBRK-VBELN\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"         ZUONR \"],\n  [\"keyword\",\"LIKE\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"VBRK-ZUONR\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"END OF\"],\n  [\"text\",\" I_VBRK\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"SORT\"],\n  [\"text\",\" i_vbrk \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" vbeln \"],\n  [\"keyword\",\"ASCENDING\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\",\n  [\"keyword\",\"SORT\"],\n  [\"text\",\" i_vbrk \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" vbeln \"],\n  [\"keyword\",\"DESCENDING\"],\n  [\"keyword.operator\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"RETURN\"],\n  [\"keyword.operator\",\".\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_abc.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.percentage\",\"%abc-2.1\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"H:\"],\n  [\"information.argument.string.unquoted\",\"This file contains some example English tunes\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% note that the comments (like this one) are to highlight usages\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"%  and would not normally be included in such detail\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"O:\"],\n  [\"information.argument.string.unquoted\",\"England             \"],\n  [\"comment.line.percentage\",\"% the origin of all tunes is England\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"1                   \"],\n  [\"comment.line.percentage\",\"% tune no 1\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Dusty Miller, The   \"],\n  [\"comment.line.percentage\",\"% title\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Binny's Jig         \"],\n  [\"comment.line.percentage\",\"% an alternative title\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\"Trad.               \"],\n  [\"comment.line.percentage\",\"% traditional\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"R:\"],\n  [\"information.argument.string.unquoted\",\"DH                  \"],\n  [\"comment.line.percentage\",\"% double hornpipe\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"3/4                 \"],\n  [\"comment.line.percentage\",\"% meter\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G                   \"],\n  [\"comment.line.percentage\",\"% key\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"/2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"/2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"/2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"/2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"W:\"],\n  [\"information.argument.string.unquoted\",\"Hey, the dusty miller, and his dusty coat;\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"W:\"],\n  [\"information.argument.string.unquoted\",\"He will win a shilling, or he spend a groat.\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"W:\"],\n  [\"information.argument.string.unquoted\",\"Dusty was the coat, dusty was the colour;\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"W:\"],\n  [\"information.argument.string.unquoted\",\"Dusty was the kiss, that I got frae the miller.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"2\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Old Sir Simon the King\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\"Trad.\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"S:\"],\n  [\"information.argument.string.unquoted\",\"Offord MSS          \"],\n  [\"comment.line.percentage\",\"% from Offord manuscript\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"N:\"],\n  [\"information.argument.string.unquoted\",\"see also Playford   \"],\n  [\"comment.line.percentage\",\"% reference note\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"9/8\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"R:\"],\n  [\"information.argument.string.unquoted\",\"SJ                  \"],\n  [\"comment.line.percentage\",\"% slip jig\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"N:\"],\n  [\"information.argument.string.unquoted\",\"originally in C     \"],\n  [\"comment.line.percentage\",\"% transcription note\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|[1\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"[\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"] \"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"],\n  [\"text\",\"\\\\ \"],\n  [\"comment.line.percentage\",\"% no line-break in score\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"12/8                \"],\n  [\"comment.line.percentage\",\"% change of meter\"]\n],[\n   \"start\",\n  [\"barline.keyword.operator\",\"[2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"\\\\  \"],\n  [\"comment.line.percentage\",\"% no line-break in score\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"9/8                 \"],\n  [\"comment.line.percentage\",\"% change of meter\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"3\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"William and Nancy\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"New Mown Hay\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Legacy, The\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\"Trad.\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"O:\"],\n  [\"information.argument.string.unquoted\",\"England; Gloucs; Bledington \"],\n  [\"comment.line.percentage\",\"% place of origin\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"B:\"],\n  [\"information.argument.string.unquoted\",\"Sussex Tune Book            \"],\n  [\"comment.line.percentage\",\"% can be found in these books\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"B:\"],\n  [\"information.argument.string.unquoted\",\"Mally's Cotswold Morris vol.1 2\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"D:\"],\n  [\"information.argument.string.unquoted\",\"Morris On                   \"],\n  [\"comment.line.percentage\",\"% can be heard on this record\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"P:\"],\n  [\"information.argument.string.unquoted\",\"(AB)2(AC)2A                 \"],\n  [\"comment.line.percentage\",\"% play the parts in this order\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"6/8\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G                        \"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[P:\"],\n  [\"information.argument.string.unquoted\",\"A]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[P:\"],\n  [\"information.argument.string.unquoted\",\"B]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"    \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"    \"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% changes of meter, using inline fields\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[T:\"],\n  [\"information.argument.string.unquoted\",\"Slows]\"],\n  [\"information.keyword.embedded\",\"[M:\"],\n  [\"information.argument.string.unquoted\",\"4/4]\"],\n  [\"information.keyword.embedded\",\"[L:\"],\n  [\"information.argument.string.unquoted\",\"1/4]\"],\n  [\"information.keyword.embedded\",\"[P:\"],\n  [\"information.argument.string.unquoted\",\"C]\"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"Em\\\"\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"A7\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"\\\\\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"information.keyword.embedded\",\"[M:\"],\n  [\"information.argument.string.unquoted\",\"3/8]\"],\n  [\"information.keyword.embedded\",\"[L:\"],\n  [\"information.argument.string.unquoted\",\"1/8]\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"information.keyword.embedded\",\"[M:\"],\n  [\"information.argument.string.unquoted\",\"6/8]\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"string.quoted\",\"\\\"C\\\"\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"\\\"D7\\\"\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"string.quoted\",\"\\\"G\\\"\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"4\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"South Downs Jig\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"R:\"],\n  [\"information.argument.string.unquoted\",\"jig\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"S:\"],\n  [\"information.argument.string.unquoted\",\"Robert Harbron\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\"6/8\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"L:\"],\n  [\"information.argument.string.unquoted\",\"1/8\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G\"]\n],[\n   \"start\",\n  [\"barline.keyword.operator\",\"|:\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"information.keyword.embedded\",\"[M:\"],\n  [\"information.argument.string.unquoted\",\"9/8]\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[M:\"],\n  [\"information.argument.string.unquoted\",\"6/8]\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|1\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\":|2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"5\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Atholl Brose\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% in this example, which reproduces Highland Bagpipe gracing,\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"%  the large number of grace notes mean that it is more convenient to be specific about\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"%  score line-breaks (using the $ symbol), rather than using code line breaks to indicate them\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"I:\"],\n  [\"information.argument.string.unquoted\",\"linebreak $\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"D\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\":|\"],\n  [\"text\",\"$\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"<\"],\n  [\"text\",\"{\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" {\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"}\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"6\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Untitled Reel\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\"Trad.\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"D\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"b\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"b\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"],\n  [\"text\",\"\\\\\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\"7\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\"Kitchen Girl\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\"Trad.\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"D\"]\n],[\n   \"start\",\n  [\"text\",\"[\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"] [\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"]\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"b\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\"G\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\":|\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"%abc-2.1\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"pagewidth      21cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"pageheight     29.7cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"topspace       0.5cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"topmargin      1cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"botmargin      0cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"leftmargin     1cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"rightmargin    1cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"titlespace     0cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"titlefont      Times-Bold 32\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"subtitlefont   Times-Bold 24\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"composerfont   Times 16\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"vocalfont      Times-Roman 14\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"staffsep       60pt\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"sysstaffsep    20pt\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"musicspace     1cm\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"vocalspace     5pt\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"measurenb      0\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"barsperstaff   5\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"scale          0.7\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"X:\"],\n  [\"information.argument.string.unquoted\",\" 1\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"T:\"],\n  [\"information.argument.string.unquoted\",\" Canzonetta a tre voci\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"C:\"],\n  [\"information.argument.string.unquoted\",\" Claudio Monteverdi (1567-1643)\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"M:\"],\n  [\"information.argument.string.unquoted\",\" C\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"L:\"],\n  [\"information.argument.string.unquoted\",\" 1/4\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"Q:\"],\n  [\"information.argument.string.unquoted\",\" \\\"Andante mosso\\\" 1/4 = 110\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"score [1 2 3]\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"V:\"],\n  [\"information.argument.string.unquoted\",\" 1 clef=treble name=\\\"Soprano\\\"sname=\\\"A\\\"\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"V:\"],\n  [\"information.argument.string.unquoted\",\" 2 clef=treble name=\\\"Alto\\\"   sname=\\\"T\\\"\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"V:\"],\n  [\"information.argument.string.unquoted\",\" 3 clef=bass middle=d name=\\\"Tenor\\\"  sname=\\\"B\\\"\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"MIDI program 1 75 % recorder\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"MIDI program 2 75\"]\n],[\n   \"start\",\n  [\"information.comment.line.percentage\",\"%%\"],\n  [\"information.keyword.embedded\",\"MIDI program 3 75\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"K:\"],\n  [\"information.argument.string.unquoted\",\" Eb\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% 1 - 4\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 1]\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|:\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"  \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"  \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"         \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\"        \"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Son que-sti~i cre-spi cri-ni~e\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Que-sti son gli~oc-chi che mi-\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 2]\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|:\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"(\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"text\",\")\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\"         \"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 3]\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|:\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"  \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"text\",\"        \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"(\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"text\",\")\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Son que-sti~i cre-spi cri-ni~e que - - - - sto~il\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" Que-sti son~gli oc-chi che mi-ran - - - - do\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% 5 - 9\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 1]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\"     \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"!fermata!\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"::\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" ran-do fi-so, tut-to re-stai con-qui-so.\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 2]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\"     \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"!fermata!\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"barline.keyword.operator\",\"::\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" ran-do fi-so tut-to re-stai con-qui-so.\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 3]\"],\n  [\"text\",\" (\"],\n  [\"pitch.constant.numeric\",\"a\"],\n  [\"pitch.constant.numeric\",\"g\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"duration.constant.numeric\",\"/\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\")\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"3\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"string.quoted\",\"!fermata!\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"::\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"barline.keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" vi - - - so ond' io ti-man-go~uc-ci-so. Deh,\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" fi - - - so tut-to re-stai con-qui-so.\"]\n],[\n   \"start\",\n  [\"comment.line.percentage\",\"% 10 - 15\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 1]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"f\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\"  \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"\\\\\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" dim-me-lo ben mi-o, che que-sto\"],\n  [\"text\",\"\\\\\"]\n],[\n   \"start\",\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"text\",\"          \"],\n  [\"barline.keyword.operator\",\"|1\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|2\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"8\"],\n  [\"barline.keyword.operator\",\"|]\"],\n  [\"text\",\" \"],\n  [\"comment.line.percentage\",\"% more notes\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" sol de-si-o_. \"],\n  [\"comment.line.percentage\",\"% more lyrics\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 2]\"],\n  [\"text\",\" \"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"text\",\"  \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"text\",\" \"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"text\",\"(\"],\n  [\"pitch.constant.numeric\",\"G\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"3/2\"],\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"duration.constant.numeric\",\"//\"],\n  [\"pitch.constant.numeric\",\"D\"],\n  [\"duration.constant.numeric\",\"//\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"text\",\")\"],\n  [\"barline.keyword.operator\",\"|1\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|2\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"8\"],\n  [\"barline.keyword.operator\",\"|]\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_.\"]\n],[\n   \"start\",\n  [\"information.keyword.embedded\",\"[V:\"],\n  [\"information.argument.string.unquoted\",\" 3]\"],\n  [\"text\",\" \"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"pitch.constant.numeric\",\"B\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\">\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"e\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"A\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"accent.constant.language\",\"=\"],\n  [\"pitch.constant.numeric\",\"E\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"accent.constant.language\",\"_\"],\n  [\"pitch.constant.numeric\",\"d\"],\n  [\"barline.keyword.operator\",\"|\"],\n  [\"pitch.constant.numeric\",\"c\"],\n  [\"duration.constant.numeric\",\"4\"],\n  [\"text\",\"             \"],\n  [\"barline.keyword.operator\",\"|1\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"pitch.constant.numeric\",\"z\"],\n  [\"duration.constant.numeric\",\"2\"],\n  [\"barline.keyword.operator\",\":|2\"],\n  [\"pitch.constant.numeric\",\"F\"],\n  [\"duration.constant.numeric\",\"8\"],\n  [\"barline.keyword.operator\",\"|]\"]\n],[\n   \"start\",\n  [\"information.keyword\",\"w:\"],\n  [\"information.argument.string.unquoted\",\" dim-me-lo ben mi-o, che que-sto sol de-si-o_.\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_actionscript.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"package code\"]\n],[\n   \"start\",\n  [\"text\",\"{\"]\n],[\n   \"punctuation.definition.comment.actionscript.2\",\n  [\"text\",\"    \"],\n  [\"punctuation.definition.comment.actionscript.2\",\"/*\"],\n  [\"comment.block.actionscript.2\",\"****************************************\"]\n],[\n   \"punctuation.definition.comment.actionscript.2\",\n  [\"comment.block.actionscript.2\",\"\\t * based on textmate actionscript bundle\"]\n],[\n   \"start\",\n  [\"comment.block.actionscript.2\",\"\\t ***************************************\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"*/\"]\n],[\n   \"start\",\n  [\"text\",\"\\t \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.actionscript.2\",\"import\"],\n  [\"text\",\" fl.events.SliderEvent;\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.actionscript.2\",\"public\"],\n  [\"text\",\" \"],\n  [\"storage.type.class.actionscript.2\",\"class\"],\n  [\"meta.class.actionscript.2\",\" \"],\n  [\"entity.name.type.class.actionscript.2\",\"Foo\"],\n  [\"meta.class.actionscript.2\",\" \"],\n  [\"storage.modifier.extends.actionscript.2\",\"extends\"],\n  [\"meta.class.actionscript.2\",\" \"],\n  [\"entity.other.inherited-class.actionscript.2\",\"MovieClip\"]\n],[\n   \"start\",\n  [\"text\",\"\\t{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"//*************************\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Properties:\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.control.actionscript.2\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword.control.actionscript.2\",\"var\"],\n  [\"text\",\" activeSwatch\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\":\"],\n  [\"support.class.actionscript.2\",\"MovieClip\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Color offsets\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.control.actionscript.2\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword.control.actionscript.2\",\"var\"],\n  [\"text\",\" c1\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\":\"],\n  [\"storage.type.actionscript.2\",\"Number\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\";\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// R\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"//*************************\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Constructor:\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.control.actionscript.2\",\"public\"],\n  [\"text\",\" \"],\n  [\"storage.type.function.actionscript.2\",\"function\"],\n  [\"meta.function.actionscript.2\",\" \"],\n  [\"entity.name.function.actionscript.2\",\"Foo\"],\n  [\"punctuation.definition.parameters.begin.actionscript.2\",\"(\"],\n  [\"punctuation.definition.parameters.end.actionscript.2\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Respond to mouse events\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tswatch1_btn.\"],\n  [\"support.function.actionscript.2\",\"addEventListener\"],\n  [\"text\",\"(MouseEvent.CLICK,swatchHandler,\"],\n  [\"constant.language.actionscript.2\",\"false\"],\n  [\"text\",\",\"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.language.actionscript.2\",\"false\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tpreviewBox_btn.\"],\n  [\"support.function.actionscript.2\",\"addEventListener\"],\n  [\"text\",\"(MouseEvent.MOUSE_DOWN,dragPressHandler);\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Respond to drag events\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tred_slider.\"],\n  [\"support.function.actionscript.2\",\"addEventListener\"],\n  [\"text\",\"(SliderEvent.THUMB_DRAG,sliderHandler);\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"punctuation.definition.comment.actionscript.2\",\"// Draw a frame later\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"support.function.actionscript.2\",\"addEventListener\"],\n  [\"text\",\"(Event.ENTER_FRAME,\"],\n  [\"support.function.actionscript.2\",\"draw\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tprotected \"],\n  [\"storage.type.function.actionscript.2\",\"function\"],\n  [\"meta.function.actionscript.2\",\" \"],\n  [\"entity.name.function.actionscript.2\",\"clickHandler\"],\n  [\"punctuation.definition.parameters.begin.actionscript.2\",\"(\"],\n  [\"variable.parameter.function.actionscript.2\",\"event:MouseEvent\"],\n  [\"punctuation.definition.parameters.end.actionscript.2\",\")\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\":\"],\n  [\"support.function.actionscript.2\",\"void\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tcar.transform.colorTransform \"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.actionscript.2\",\"new\"],\n  [\"text\",\" ColorTransform(\"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric.actionscript.2\",\"1\"],\n  [\"text\",\",c1,c2,c3);\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tprotected \"],\n  [\"storage.type.function.actionscript.2\",\"function\"],\n  [\"meta.function.actionscript.2\",\" \"],\n  [\"entity.name.function.actionscript.2\",\"changeRGBHandler\"],\n  [\"punctuation.definition.parameters.begin.actionscript.2\",\"(\"],\n  [\"variable.parameter.function.actionscript.2\",\"event:Event\"],\n  [\"punctuation.definition.parameters.end.actionscript.2\",\")\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\":\"],\n  [\"support.function.actionscript.2\",\"void\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tc1 \"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type.actionscript.2\",\"Number\"],\n  [\"text\",\"(c1_txt.\"],\n  [\"support.function.actionscript.2\",\"text\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"            \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword.control.actionscript.2\",\"if\"],\n  [\"text\",\"(\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"!\"],\n  [\"text\",\"(c1>\"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"=\"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\")){\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\tc1 \"],\n  [\"keyword.operator.symbolic.actionscript.2\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.actionscript.2\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t}\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\tupdateSliders();\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t}\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ada.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"with\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ada\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Text_IO\"],\n  [\"text\",\"; \"],\n  [\"keyword\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ada\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Text_IO\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Hello\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"]\n],[\n   \"start\",\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Put_Line\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Hello, world!\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Hello\"],\n  [\"text\",\";\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_alda.json",
    "content": "[[\n   \"start\",\n  [\"constant.language.instrument.alda\",\"vibraphone\"],\n  [\"meta.part.call.alda\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.inline.clojure.alda\",\"(quant 200)\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.inline.clojure.alda\",\"(key-signature \\\"f+ c+ g+\\\")\"]\n],[\n   \"start\",\n  [\"text\",\"  a\"],\n  [\"string.quoted.operator.timing.alda\",\"8\"],\n  [\"text\",\" b \"],\n  [\"keyword.operator.octave-shift.alda\",\">\"],\n  [\"text\",\" c d e f g a \"],\n  [\"keyword.operator.octave-shift.alda\",\"<\"]\n],[\n   \"start\",\n  [\"text\",\"  a b \"],\n  [\"keyword.operator.octave-shift.alda\",\">\"],\n  [\"text\",\" c_ d e f_ g_ a \"],\n  [\"keyword.operator.octave-shift.alda\",\"<\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.inline.clojure.alda\",\"(key-signature [:g :minor])\"]\n],[\n   \"start\",\n  [\"text\",\"  g a b \"],\n  [\"keyword.operator.octave-shift.alda\",\">\"],\n  [\"text\",\" c\"],\n  [\"variable.parameter.operator.pitch.alda\",\"+\"],\n  [\"text\",\" d e f\"],\n  [\"variable.parameter.operator.pitch.alda\",\"+\"],\n  [\"text\",\" g \"],\n  [\"keyword.operator.octave-shift.alda\",\"<\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.inline.clojure.alda\",\"(key-signature {:e [:flat] :b [:flat]})\"]\n],[\n   \"pitch\",\n  [\"text\",\"  g\"],\n  [\"string.quoted.operator.timing.alda\",\"1~1\"],\n  [\"constant.numeric.subchord.alda\",\"/\"],\n  [\"text\",\"b\"],\n  [\"constant.numeric.subchord.alda\",\"/\"],\n  [\"text\",\"d\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_apex.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"testBlockDuplicatesLeadTrigger\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"static\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"testMethod\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"void\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"testDuplicateTrigger\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Email\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"homer@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Simpson\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Company\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"fox\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l1\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"\\t\\t\"],\n  [\"comment\",\"// add a known lead\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Email\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"homer@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Simpson\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Company\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"fox\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"comment\",\"// try to add a matching lead\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"try\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l2\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"catch\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"System\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"DmlException\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"support.function\",\"system\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"assert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"contains\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t \"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"comment\",\"// test duplicates in the same batch\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l3\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Email\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"marge@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Simpson\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Company\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"fox\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Email\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"marge@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Simpson\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Company\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"fox\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"try\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"l3\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"catch\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"System\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"DmlException\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"support.function\",\"system\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"assert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"contains\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Another new lead has the same email\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"comment\",\"// test update also\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lup\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Lead\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Email\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"marge@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"LastName\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Simpson\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Company\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"fox\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lup\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Lead\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"marge\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"select\"],\n  [\"text\",\" id\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"Email \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" lead \"],\n  [\"keyword\",\"where\"],\n  [\"text\",\" Email \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"marge@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"limit\"],\n  [\"text\",\" 1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function\",\"system\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"assert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"marge\"],\n  [\"keyword.operator\",\"!=\"],\n  [\"constant.language\",\"null\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"marge\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Email\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"homer@fox.tv\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"try\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"update\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"marge\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"catch\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"System\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"DmlException\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"support.function\",\"system\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"assert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"contains\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"irst error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"getMessage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_aql.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"FILTER\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"olivier\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"RETURN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_asciidoc.json",
    "content": "[[\n   \"literalBlock\",\n  [\"support.function\",\"------------------------------------\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"-----------------------------------\"]\n],[\n   \"text\",\n  [\"string.italic\",\"_ita_lic_\"],\n  [\"text\",\", \"],\n  [\"keyword.bold\",\"*bo*ld*\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"+mo+no+\"],\n  [\"text\",\", normal. \"]\n],[\n   \"text\",\n  [\"keyword\",\"``\"],\n  [\"text\",\"double quoted\"],\n  [\"keyword\",\"''\"],\n  [\"text\",\", `single quoted'.\"]\n],[\n   \"text\",\n  [\"text\",\"  normal, ^super^, \"],\n  [\"keyword\",\"~sub~\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n],[\n   \"text\",\n  [\"text\",\"''''\"]\n],[\n   \"text\",\n  [\"text\",\"Escaped:\"]\n],[\n   \"text\",\n  [\"constant.language.escape\",\"\\\\_\"],\n  [\"text\",\"italic_, \"],\n  [\"support.function\",\"+++\"],\n  [\"text\",\"_italic_\"],\n  [\"support.function\",\"+++\"],\n  [\"text\",\",\"]\n],[\n   \"smallPassthrough\",\n  [\"text\",\"t\"],\n  [\"constant.language.escape\",\"\\\\_\"],\n  [\"text\",\"_e\"],\n  [\"string.italic\",\"__st, +++t__\"],\n  [\"text\",\"e__st\"],\n  [\"support.function\",\"+++\"],\n  [\"text\",\",\"]\n],[\n   \"smallPassthrough\",\n  [\"support.function\",\"+++\"],\n  [\"text\",\"<b>bold</b>\"],\n  [\"support.function\",\"+++\"],\n  [\"text\",\", $$<\"],\n  [\"support.function\",\"b\"],\n  [\"text\",\">\"],\n  [\"support.function\",\"normal\"],\n  [\"text\",\"</\"],\n  [\"support.function\",\"b\"],\n  [\"text\",\">$$\"]\n],[\n   \"smallPassthrough\",\n  [\"text\",\"\\\\&#\"],\n  [\"support.function\",\"182\"],\n  [\"text\",\"; &#\"],\n  [\"support.function\",\"182\"],\n  [\"text\",\";\"]\n],[\n   \"smallPassthrough\",\n  [\"text\",\"\\\\`\"],\n  [\"support.function\",\"not\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"single\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"quoted\"],\n  [\"text\",\"'\"]\n],[\n   \"smallPassthrough\",\n  [\"text\",\"\\\\`\\\\`\"],\n  [\"support.function\",\"not\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"double\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"quoted\"],\n  [\"text\",\"''\"]\n],[\n   \"dissallowDelimitedBlock\"\n],[\n   \"text\"\n],[\n   \"start\",\n  [\"string.regexp\",\"[fffff]\"]\n],[\n   \"passthroughBlock\",\n  [\"string\",\"+++++++++++++++++++++++++++++++++++++\"]\n],[\n   \"passthroughBlock\",\n  [\"support.function\",\"(C) \"],\n  [\"constant.character\",\"{ss}\"],\n  [\"support.function\",\" ss\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"+++++++++++++++++++++++++++++++++++++\"]\n],[\n   \"text\"\n],[\n   \"listingBlock\",\n  [\"support.function\",\".............\"]\n],[\n   \"listingBlock\",\n  [\"support.function\",\"callout \"],\n  [\"constant.numeric\",\"<1>\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"..............\"]\n],[\n   \"text\"\n],[\n   \"text\",\n  [\"text\",\"> 1\"]\n],[\n   \"text\",\n  [\"text\",\"1> 2\"]\n],[\n   \"text\",\n  [\"text\",\"<2> 3\"]\n],[\n   \"start\"\n],[\n   \"text\",\n  [\"text\",\"Escaped:\"]\n],[\n   \"text\",\n  [\"constant.language.escape\",\"\\\\_\"],\n  [\"text\",\"italic_,\"]\n],[\n   \"text\",\n  [\"text\",\"t\"],\n  [\"constant.language.escape\",\"\\\\_\"],\n  [\"text\",\"_e\"],\n  [\"string.italic\",\"__st, o__\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.numeric\",\".optional title\"]\n],[\n   \"listingBlock\",\n  [\"support.function\",\".............\"]\n],[\n   \"listingBlock\",\n  [\"support.function\",\"callout \"],\n  [\"constant.numeric\",\"<1>\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"..............\"]\n],[\n   \"text\"\n],[\n   \"start\"\n],[\n   \"text\",\n  [\"keyword\",\":macro:\"],\n  [\"text\",\" dddd\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.numeric\",\".lists\"]\n],[\n   \"listText\",\n  [\"keyword\",\". \"],\n  [\"text\",\"1\"]\n],[\n   \"listText\",\n  [\"keyword\",\".. \"],\n  [\"text\",\"2\"]\n],[\n   \"listText\",\n  [\"keyword\",\"... \"],\n  [\"text\",\"d\"]\n],[\n   \"listText\",\n  [\"keyword\",\"..... \"],\n  [\"text\",\"big\"]\n],[\n   \"start\",\n  [\"keyword\",\"+\"]\n],[\n   \"text\",\n  [\"text\",\"continue\"],\n  [\"keyword\",\" +\"]\n],[\n   \"text\",\n  [\"text\",\"next line\"]\n],[\n   \"text\",\n  [\"text\",\"xi) no \"],\n  [\"support.function\",\"++la+tin++\"]\n],[\n   \"start\"\n],[\n   \"listText\",\n  [\"keyword\",\"xi) \"],\n  [\"text\",\"la\"],\n  [\"support.function\",\"++tin++\"]\n],[\n   \"listText\",\n  [\"keyword\",\"2. \"],\n  [\"text\",\"num\"],\n  [\"string.italic\",\"__ber__\"],\n  [\"text\",\"  [red]\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\"red\"],\n  [\"keyword\",\"#\"]\n],[\n   \"start\",\n  [\"keyword\",\"--\"]\n],[\n   \"listText\",\n  [\"keyword\",\"  5. \"],\n  [\"text\",\"f \"],\n  [\"keyword\",\"<<x6,\"],\n  [\"string\",\"ssss\"],\n  [\"keyword\",\">>\"],\n  [\"text\",\" \"],\n  [\"constant.character\",\"{macro}\"]\n],[\n   \"start\",\n  [\"keyword\",\"--\"]\n],[\n   \"text\",\n  [\"markup.list.macro\",\"image::\"],\n  [\"keyword\",\"path\"],\n  [\"string\",\"[beauty]\"],\n  [\"text\",\" \"],\n  [\"constant.language.escape\",\"->\"],\n  [\"text\",\"--\"],\n  [\"constant.language.escape\",\"<= --\"],\n  [\"text\",\" replacements\"]\n],[\n   \"start\"\n],[\n   \"indentedBlock\",\n  [\"support.function\",\" image::s\"]\n],[\n   \"indentedBlock\",\n  [\"support.function\",\"sssss\"]\n],[\n   \"indentedBlock\",\n  [\"support.function\",\"sss \"]\n],[\n   \"indentedBlock\",\n  [\"support.function\",\"sssss\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"== 1\"]\n],[\n   \"indentedBlock\",\n  [\"support.function\",\"  heading\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"=== not a heading\"]\n],[\n   \"start\",\n  [\"keyword\",\"====================================\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"==================================\"]\n],[\n   \"text\",\n  [\"text\",\"====4 \"]\n],[\n   \"text\",\n  [\"text\",\"NOTE: above\"]\n],[\n   \"start\"\n],[\n   \"text\",\n  [\"keyword\",\"NOTE:\"],\n  [\"text\",\" above\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.regexp\",\"[[x6]]\"]\n],[\n   \"text\",\n  [\"keyword\",\"WARNING:\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.regexp\",\"[options[]]\"]\n],[\n   \"literalBlock\",\n  [\"support.function\",\"---------------------------\"]\n],[\n   \"literalBlock\",\n  [\"support.function\",\"literal\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"---------------------------\"]\n],[\n   \"text\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"= Tables\"]\n],[\n   \"tableBlock\",\n  [\"doc.comment\",\"|====================================\"]\n],[\n   \"tableBlock\",\n  [\"doc.comment\",\"|\"],\n  [\"text\",\" \"],\n  [\"string.italic\",\"_italic_\"],\n  [\"text\",\" \"],\n  [\"doc.comment\",\"|\"],\n  [\"text\",\"  \"],\n  [\"keyword.bold\",\"*bold*\"],\n  [\"text\",\" \"],\n  [\"doc.comment\",\"|\"],\n  [\"text\",\" text \"],\n  [\"doc.comment\",\"|\"],\n  [\"text\",\" \"],\n  [\"constant.language.escape\",\"(R)\"]\n],[\n   \"tableBlock\"\n],[\n   \"dissallowDelimitedBlock\",\n  [\"doc.comment\",\"|====================================\"]\n],[\n   \"text\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.regexp\",\"[more, options]\"]\n],[\n   \"commentBlock\",\n  [\"doc.comment\",\"///////////\"]\n],[\n   \"commentBlock\",\n  [\"doc.comment\",\"comment\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"doc.comment\",\"///////////\"]\n],[\n   \"text\",\n  [\"comment\",\"// one line comment\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"text\",\n  [\"text\",\"[red]\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\"red text\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\" [yellow-background]\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\"on yellow\"],\n  [\"keyword\",\"#\"]\n],[\n   \"text\",\n  [\"text\",\"[big]\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\"large\"],\n  [\"keyword\",\"#\"],\n  [\"text\",\" [red yellow-background big]\"],\n  [\"keyword.bold\",\"*all bold*\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"text\",\n  [\"markup.underline.list\",\"https://site\"],\n  [\"text\",\" text <\"],\n  [\"markup.underline.list\",\"mail@i.am\"],\n  [\"text\",\"> \"],\n  [\"markup.underline.list\",\"callto:ace\"],\n  [\"text\",\" \"],\n  [\"link\",\"http://ace.ajaxorg.com\"],\n  [\"variable.language\",\"[awesome]\"]\n],[\n   \"text\",\n  [\"text\",\"  .still normal text\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\".break out thoug should not\"]\n],[\n   \"literalBlock\",\n  [\"support.function\",\"---------------------------\"]\n],[\n   \"literalBlock\",\n  [\"support.function\",\"///////////////////////////\"]\n],[\n   \"dissallowDelimitedBlock\",\n  [\"support.function\",\"---------------------------\"]\n],[\n   \"text\"\n],[\n   \"start\"\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_asl.json",
    "content": "[[\n   \"comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment\",\" * Intel ACPI Component Architecture\"]\n],[\n   \"comment\",\n  [\"comment\",\" * AML/ASL+ Disassembler version 20180105\"]\n],[\n   \"comment\",\n  [\"comment\",\" *\"]\n],[\n   \"comment\",\n  [\"comment\",\" * ASL example\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\",\n  [\"keyword\",\"DefinitionBlock\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"SSDT\\\"\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"PmRef\\\"\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Cpu0Ist\\\"\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0x00003000\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"External\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"_PR_\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"CPU0\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DeviceObj\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"External\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"_SB_\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"CPUP\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"UnknownObj\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Scope\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\"\\\\\"],\n  [\"identifier\",\"_PR\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"CPU0\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"Method\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"_PCT\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.library\",\"NotSerialized\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"// _PCT: Performance Control\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"If\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(((\"],\n  [\"identifier\",\"CFGD\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"One\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"PDC0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"One\"],\n  [\"rparen\",\")))\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"Return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword\",\"Package\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"0x02\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"keyword\",\"ResourceTemplate\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"keyword\",\"Register\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.library\",\"FFixedHW\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Width\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Offset\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x0000000000000000\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// Address\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"keyword.operator\",\",\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"rparen\",\"}\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"keyword\",\"ResourceTemplate\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"keyword\",\"Register\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.library\",\"FFixedHW\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Width\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Offset\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"constant.numeric\",\"0x0000000000000000\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// Address\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"keyword.operator\",\",\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"})\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"Return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword\",\"Package\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"0x02\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"ResourceTemplate\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"keyword\",\"Register\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.library\",\"SystemIO\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x10\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Width\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Offset\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x0000000000001000\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// Address\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"keyword.operator\",\",\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"}\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"ResourceTemplate\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"keyword\",\"Register\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.library\",\"SystemIO\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x08\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Width\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x00\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\"               \"],\n  [\"comment\",\"// Bit Offset\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"constant.numeric\",\"0x00000000000000B3\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// Address\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"keyword.operator\",\",\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"})\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"Name\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"PSDF\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"Zero\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"Method\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"_PSD\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.library\",\"NotSerialized\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"// _PSD: Power State Dependencies\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"If\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator\",\"!\"],\n  [\"identifier\",\"PSDF\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword.operator\",\"DerefOf\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"HPSD\"],\n  [\"text\",\" \"],\n  [\"comment\",\"[Zero]\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"[0x04]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"TCNT\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* External reference */\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword.operator\",\"DerefOf\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"SPSD\"],\n  [\"text\",\" \"],\n  [\"comment\",\"[Zero]\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"[0x04]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"TCNT\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* External reference */\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"PSDF\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"Ones\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"If\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"((\"],\n  [\"identifier\",\"PDC0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0x0800\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"Return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"HPSD\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* \\\\_PR_.CPU0.HPSD */\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"Return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"SPSD\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* \\\\_PR_.CPU0.SPSD */\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_assembly_x86.json",
    "content": "[[\n   \"start\",\n  [\"support.function.directive.assembly\",\"section\"],\n  [\"text\",\"\\t.text\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.directive.assembly\",\"global\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.assembly\",\"main\"],\n  [\"text\",\"         \"],\n  [\"comment.assembly\",\";must be declared for using gcc\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function.assembly\",\"main:\"],\n  [\"text\",\"\\t                \"],\n  [\"comment.assembly\",\";tell linker entry point\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"mov\"],\n  [\"text\",\"\\t\"],\n  [\"variable.parameter.register.assembly\",\"edx\"],\n  [\"text\",\", len\\t    \"],\n  [\"comment.assembly\",\";message length\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"mov\"],\n  [\"text\",\"\\t\"],\n  [\"variable.parameter.register.assembly\",\"ecx\"],\n  [\"text\",\", msg\\t    \"],\n  [\"comment.assembly\",\";message to write\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"mov\"],\n  [\"text\",\"\\t\"],\n  [\"variable.parameter.register.assembly\",\"ebx\"],\n  [\"text\",\", \"],\n  [\"constant.character.decimal.assembly\",\"1\"],\n  [\"text\",\"\\t        \"],\n  [\"comment.assembly\",\";file descriptor (stdout)\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"mov\"],\n  [\"text\",\"\\t\"],\n  [\"variable.parameter.register.assembly\",\"eax\"],\n  [\"text\",\", \"],\n  [\"constant.character.decimal.assembly\",\"4\"],\n  [\"text\",\"\\t        \"],\n  [\"comment.assembly\",\";system call number (sys_write)\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"int\"],\n  [\"text\",\"\\t\"],\n  [\"constant.character.hexadecimal.assembly\",\"0x80\"],\n  [\"text\",\"\\t        \"],\n  [\"comment.assembly\",\";call kernel\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"mov\"],\n  [\"text\",\"\\t\"],\n  [\"variable.parameter.register.assembly\",\"eax\"],\n  [\"text\",\", \"],\n  [\"constant.character.decimal.assembly\",\"1\"],\n  [\"text\",\"\\t        \"],\n  [\"comment.assembly\",\";system call number (sys_exit)\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.assembly\",\"int\"],\n  [\"text\",\"\\t\"],\n  [\"constant.character.hexadecimal.assembly\",\"0x80\"],\n  [\"text\",\"\\t        \"],\n  [\"comment.assembly\",\";call kernel\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.directive.assembly\",\"section\"],\n  [\"text\",\"\\t.data\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function.assembly\",\"msg\"],\n  [\"text\",\"\\t\"],\n  [\"support.function.directive.assembly\",\"db\"],\n  [\"text\",\"\\t\"],\n  [\"string.assembly\",\"'Hello, world!'\"],\n  [\"text\",\",\"],\n  [\"constant.character.hexadecimal.assembly\",\"0xa\"],\n  [\"text\",\"\\t\"],\n  [\"comment.assembly\",\";our dear string\"]\n],[\n   \"start\",\n  [\"entity.name.function.assembly\",\"len\"],\n  [\"text\",\"\\t\"],\n  [\"support.function.directive.assembly\",\"equ\"],\n  [\"text\",\"\\t$ - msg\\t\\t\\t\"],\n  [\"comment.assembly\",\";length of our dear string\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_autohotkey.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.ahk\",\"#\"],\n  [\"keyword.command.ahk\",\"NoEnv\"]\n],[\n   \"start\",\n  [\"keyword.command.ahk\",\"SetBatchLines\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-1\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.command.ahk\",\"CoordMode\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"Mouse\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"Screen\"]\n],[\n   \"start\",\n  [\"keyword.command.ahk\",\"OnExit\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"GuiClose\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"zoom \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" 9\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"computeSize\"],\n  [\"paren\",\"(){\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.ahk\",\"global\"],\n  [\"text\",\" as_x\"]\n],[\n   \"start\",\n  [\"text\",\"\\tas_x \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" \"],\n  [\"support.function.ahk\",\"Round\"],\n  [\"paren\",\"(\"],\n  [\"text\",\"ws_x\"],\n  [\"keyword.operator.ahk\",\"/\"],\n  [\"text\",\"zoom\"],\n  [\"keyword.operator.ahk\",\"/\"],\n  [\"text\",\"2 \"],\n  [\"keyword.operator.ahk\",\"-\"],\n  [\"text\",\" 0.5\"],\n  [\"paren\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control.ahk\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren\",\"(\"],\n  [\"text\",\"zoom\"],\n  [\"keyword.operator.ahk\",\">\"],\n  [\"text\",\"1\"],\n  [\"paren\",\")\"],\n  [\"text\",\" \"],\n  [\"paren\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tpix \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" \"],\n  [\"support.function.ahk\",\"Round\"],\n  [\"paren\",\"(\"],\n  [\"text\",\"zoom\"],\n  [\"paren\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren\",\"}\"],\n  [\"text\",\" ele \"],\n  [\"paren\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tpix \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" 1\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.command.ahk\",\"ToolTip\"],\n  [\"text\",\" Message \"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\"as_x\"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\" \"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\"zoom\"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\" \"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\"ws_x\"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\" \"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\"hws_x\"],\n  [\"punctuation.ahk\",\"%\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"paren\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"hdc_frame \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" \"],\n  [\"support.function.ahk\",\"DllCall\"],\n  [\"paren\",\"(\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"string.quoted.ahk\",\"GetDC\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" UInt\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" MagnifierID\"],\n  [\"paren\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.ahk\",\"; comment\"]\n],[\n   \"start\",\n  [\"text\",\"DrawCross\"],\n  [\"paren\",\"(\"],\n  [\"keyword.control.ahk\",\"byRef\"],\n  [\"text\",\" x\"],\n  [\"keyword.operator.ahk\",\"=\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" rX\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\"rY\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\"z\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" dc\"],\n  [\"paren\",\"){\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"comment.line.ahk\",\" ;specify the style, thickness and color of the cross lines\"]\n],[\n   \"start\",\n  [\"text\",\"    h_pen \"],\n  [\"keyword.operator.ahk\",\":=\"],\n  [\"text\",\" \"],\n  [\"support.function.ahk\",\"DllCall\"],\n  [\"paren\",\"(\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"string.quoted.ahk\",\"gdi32.dll\\\\CreatePen\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"Int\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" 0\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"Int\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" 1\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" UInt\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\" 0x0000FF\"],\n  [\"paren\",\")\"]\n],[\n   \"start\",\n  [\"paren\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.ahk\",\";Ctrl ^; Shift +; Win #; Alt !\"]\n],[\n   \"start\",\n  [\"text\",\"^\"],\n  [\"support.constant.ahk\",\"NumPadAdd\"],\n  [\"keyword.operator.ahk\",\"::\"]\n],[\n   \"start\",\n  [\"text\",\"^\"],\n  [\"support.constant.ahk\",\"WheelUp\"],\n  [\"keyword.operator.ahk\",\"::\"],\n  [\"text\",\"   \"]\n],[\n   \"start\",\n  [\"text\",\"^;\"],\n  [\"keyword.operator.ahk\",\"::\"],\n  [\"text\",\"  \"],\n  [\"comment.line.ahk\",\" ;comment\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.ahk\",\"If\"],\n  [\"paren\",\"(\"],\n  [\"text\",\"zoom \"],\n  [\"keyword.operator.ahk\",\"<\"],\n  [\"text\",\" ws_x \"],\n  [\"variable.parameter\",\"and\"],\n  [\"text\",\" \"],\n  [\"paren\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable.predefined.ahk\",\"A_ThisHotKey\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.ahk\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"string.quoted.ahk\",\"^WheelUp\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"or\"],\n  [\"text\",\" \"],\n  [\"variable.predefined.ahk\",\"A_ThisHotKey\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.ahk\",\"=\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"string.quoted.ahk\",\"^NumPadAdd\"],\n  [\"punctuation.quote.double\",\"\\\"\"],\n  [\"paren\",\")\"],\n  [\"text\",\" \"],\n  [\"paren\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tzoom \"],\n  [\"keyword.operator.ahk\",\"*=\"],\n  [\"text\",\" 1.189207115        \"],\n  [\"comment.line.ahk\",\" ; sqrt(sqrt(2))\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.command.ahk\",\"Gosub\"],\n  [\"punctuation.ahk\",\",\"],\n  [\"text\",\"setZoom\"]\n],[\n   \"start\",\n  [\"keyword.control.ahk\",\"return\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_basic.json",
    "content": "[[\n   \"start\",\n  [\"constant.numeric\",\"120\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"OPEN\"],\n  [\"string\",\"\\\"R\\\"\"],\n  [\"text\",\" #\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"INVEN.DAT\\\"\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"39\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"125\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"FIELD\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"F\"],\n  [\"text\",\"$\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"30\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"D\"],\n  [\"text\",\"$\"],\n  [\"punctiation\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"$\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"R\"],\n  [\"text\",\"$\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PH\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"130\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\":\"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"FUNCTIONS:\\\"\"],\n  [\"text\",\":\"],\n  [\"entity.name\",\"PRINT\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"135\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctiation\",\",\"],\n  [\"string\",\"\\\"INITIALIZE FILE\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"140\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"CREATE A NEW ENTRY\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"150\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctiation\",\",\"],\n  [\"string\",\"\\\"DISPLAY INVENTORY FOR ONE PART\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"160\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"ADD TO STOCK\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"170\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"punctiation\",\",\"],\n  [\"string\",\"\\\"SUBTRACT FROM STOCK\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"180\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"6\"],\n  [\"punctiation\",\",\"],\n  [\"string\",\"\\\"DISPLAY ALL ITEMS BELOW REORDER LEVEL\\\"\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"220\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\":\"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\":\"],\n  [\"entity.name\",\"INPUT\"],\n  [\"string\",\"\\\"FUNCTION\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"FUNCTION\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"225\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"FUNCTION\"],\n  [\"keyword.operator\",\"<\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"OR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"FUNCTION\"],\n  [\"keyword.operator\",\">\"],\n  [\"constant.numeric\",\"6\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"BAD FUNCTION NUMBER\\\"\"],\n  [\"text\",\":\"],\n  [\"keyword.control\",\"GOTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"130\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"230\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"ON\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FUNCTION\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"GOSUB\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"900\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"250\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"390\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"480\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"560\"],\n  [\"punctiation\",\",\"],\n  [\"constant.numeric\",\"680\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"240\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"GOTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"220\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"560\"],\n  [\"text\",\" \"],\n  [\"comment\",\"REM REMOVE FROM STOCK\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"570\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"GOSUB\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"840\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"580\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"ASC\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"F\"],\n  [\"text\",\"$\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"255\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"NULL ENTRY\\\"\"],\n  [\"text\",\":\"],\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"590\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DH\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"600\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"INPUT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"QUANTITY TO SUBTRACT\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"S\"],\n  [\"text\",\"%\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"610\"],\n  [\"text\",\" \"],\n  [\"variable\",\"Q%\"],\n  [\"keyword.operator\",\"=\"],\n  [\"support.function\",\"CVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"$\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"620\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"%\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"S\"],\n  [\"text\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"<\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"ONIY\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"%\"],\n  [\"punctiation\",\";\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"IN STOCK\\\"\"],\n  [\"text\",\":\"],\n  [\"keyword.control\",\"GOTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"600\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"630\"],\n  [\"text\",\" \"],\n  [\"variable\",\"Q%\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"%\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"S\"],\n  [\"text\",\"%\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"640\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"variable\",\"Q%\"],\n  [\"keyword.operator\",\"=<\"],\n  [\"identifier\",\"CVT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"R\"],\n  [\"text\",\"$\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"QUANTITY NOW\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"%\"],\n  [\"punctiation\",\";\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"44\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"REORDER\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LEVEL\"],\n  [\"text\",\"\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"support.function\",\"CVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"RH\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"entity.name\",\"LSET\"],\n  [\"text\",\" \"],\n  [\"variable\",\"Q$\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"MKU\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"Q\"],\n  [\"text\",\"%\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"entity.name\",\"PUT\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctiation\",\",\"],\n  [\"identifier\",\"PART\"],\n  [\"text\",\"%\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\",\n  [\"identifier\",\"DISPLAY\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ITEMS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"BELOW\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"REORDER\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LEVEL\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"TO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"entity.name\",\"GET\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"identifier\",\"J\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"OVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tzH\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"OVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"RH\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Dtz\"],\n  [\"punctiation\",\";\"],\n  [\"string\",\"\\\" QUANTITY\\\"\"],\n  [\"punctiation\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"OVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"Qtz\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"TAB\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"50\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"REORDER LEVEL\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"support.function\",\"CVI\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"R\"],\n  [\"text\",\"$\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"NEXT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"I\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\",\n  [\"entity.name\",\"INPUT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"PART NUMBER\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"PART\"],\n  [\"text\",\"%\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"IF\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"PART\"],\n  [\"text\",\"%\"],\n  [\"keyword.operator\",\"<\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"OR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"PART\"],\n  [\"text\",\"%\"],\n  [\"keyword.operator\",\">\"],\n  [\"constant.numeric\",\"100\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"PRINT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"BAD PART NUMBER\\\"\"],\n  [\"text\",\": \"],\n  [\"keyword.control\",\"GOTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"840\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"GET\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"J\"],\n  [\"keyword.operator\",\">\"],\n  [\"identifier\",\"ART\"],\n  [\"text\",\"%:\"],\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\",\n  [\"entity.name\",\"END\"]\n],[\n   \"start\",\n  [\"comment\",\"REM INITIALIZE FILE\"]\n],[\n   \"start\",\n  [\"entity.name\",\"INPUT\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"ARE YOU SURE\\\"\"],\n  [\"punctiation\",\";\"],\n  [\"identifier\",\"B\"],\n  [\"text\",\"$:\"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"text\",\"$\"],\n  [\"keyword.operator\",\"<=\"],\n  [\"string\",\"\\\"Y\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\",\n  [\"entity.name\",\"LSET\"],\n  [\"text\",\" \"],\n  [\"variable\",\"F$\"],\n  [\"keyword.operator\",\"=\"],\n  [\"support.function\",\"CHR$\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"255\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"variable\",\"O\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"TO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"entity.name\",\"PUT\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"identifier\",\"J\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"NEXT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"I\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"RETURN\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_batchfile.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.colons.dosbatch\",\":: batch file highlighting in Ace!\"]\n],[\n   \"start\",\n  [\"text\",\"@\"],\n  [\"keyword.command.dosbatch\",\"echo\"],\n  [\"text\",\" off\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.statement.dosbatch\",\"CALL\"],\n  [\"text\",\" \"],\n  [\"keyword.command.dosbatch\",\"set\"],\n  [\"text\",\" var1=\"],\n  [\"constant.numeric\",\"%cd%\"]\n],[\n   \"start\",\n  [\"keyword.command.dosbatch\",\"echo\"],\n  [\"text\",\" unhide everything in \"],\n  [\"constant.numeric\",\"%var1%\"],\n  [\"text\",\"!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.colons.dosbatch\",\":: FOR loop in bat is super strange!\"]\n],[\n   \"start\",\n  [\"keyword.control.repeat.dosbatch\",\"FOR\"],\n  [\"text\",\" /f \"],\n  [\"punctuation.definition.string.begin.shell\",\"\\\"\"],\n  [\"string.quoted.double.dosbatch\",\"tokens=*\"],\n  [\"punctuation.definition.string.end.shell\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"%%G\"],\n  [\"text\",\" IN ('\"],\n  [\"keyword.command.dosbatch\",\"dir\"],\n  [\"text\",\" /A:D /b') DO (\"]\n],[\n   \"start\",\n  [\"keyword.command.dosbatch\",\"echo\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"%var1%%%G\"]\n],[\n   \"start\",\n  [\"keyword.command.dosbatch\",\"attrib\"],\n  [\"text\",\" -r -a -h -s \"],\n  [\"punctuation.definition.string.begin.shell\",\"\\\"\"],\n  [\"constant.numeric\",\"%var1%%%G\"],\n  [\"punctuation.definition.string.end.shell\",\"\\\"\"],\n  [\"text\",\" /D /S\"]\n],[\n   \"start\",\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.command.dosbatch\",\"pause\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"doc.comment\",\"REM\"],\n  [\"comment\",\" that's all\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_bibtex.json",
    "content": "[[\n   \"bibtexComment\",\n  [\"comment\",\"@Comment{\"]\n],[\n   [\"bibtexComment\",\"bibtexComment\"],\n  [\"comment\",\"  @Book{tes03,\"]\n],[\n   [\"bibtexComment\",\"bibtexComment\"],\n  [\"comment\",\"    author =\\t {John Smith},\"]\n],[\n   [\"bibtexComment\",\"bibtexComment\"],\n  [\"comment\",\"    title =\\t {Cooking},\"]\n],[\n   [\"bibtexComment\",\"bibtexComment\"],\n  [\"comment\",\"    publisher =\\t {Culinary Expert},\"]\n],[\n   [\"bibtexComment\",\"bibtexComment\"],\n  [\"comment\",\"    year =\\t 1890\"]\n],[\n   \"bibtexComment\",\n  [\"comment\",\"  }\"]\n],[\n   \"start\",\n  [\"comment\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"@String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"mar\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"march\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"keyword3\",\n  [\"keyword\",\"@Book\"],\n  [\"paren.lparen\",\"{\"],\n  [\"support.class\",\"sweig-42\"],\n  [\"punctuation\",\",\"]\n],[\n   \"keyword3\",\n  [\"text\",\"  \"],\n  [\"variable\",\"Author\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"\\t \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\" Stefan Sweig \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation\",\",\"]\n],[\n   \"keyword3\",\n  [\"text\",\"  \"],\n  [\"variable\",\"title\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"\\t \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\" The impossible book \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation\",\",\"]\n],[\n   \"keyword3\",\n  [\"text\",\"  \"],\n  [\"variable\",\"publisher\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"\\t \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\" Dead Poet Society\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation\",\",\"]\n],[\n   \"keyword3\",\n  [\"text\",\"  \"],\n  [\"variable\",\"year\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"\\t \"],\n  [\"constant.numeric.bibtex\",\"1942\"],\n  [\"punctuation\",\",\"]\n],[\n   [\"variable\",\"keyword3\"],\n  [\"text\",\"  \"],\n  [\"variable\",\"month\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"        mar\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"@String\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"firstname\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"John\\\"\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"@String\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"lastname\"],\n  [\"text\",\"  \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Smith\\\"\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"@String\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"email\"],\n  [\"text\",\"      \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" firstname \"],\n  [\"keyword.operator\",\"#\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\".\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"#\"],\n  [\"text\",\" lastname \"],\n  [\"keyword.operator\",\"#\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"@imag.en\\\"\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"keyword3\",\n  [\"keyword\",\"@Article\"],\n  [\"paren.lparen\",\"{\"],\n  [\"support.class\",\"key01\"],\n  [\"punctuation\",\",\"]\n],[\n   [\"variable\",\"keyword3\"],\n  [\"text\",\"  \"],\n  [\"variable\",\"title\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\" The history of \"],\n  [\"invalid.illegal\",\"@\"],\n  [\"string\",\" sign \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"Everything \\\" \\\" outside {entries} is treated as comment in BibTeX.\"]\n],[\n   \"start\"\n],[\n   \"keyword3\",\n  [\"keyword\",\"@Article\"],\n  [\"paren.lparen\",\"{\"],\n  [\"support.class\",\"key03\"],\n  [\"punctuation\",\",\"]\n],[\n   [\"variable\",\"keyword3\"],\n  [\"text\",\"  \"],\n  [\"variable\",\"title\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"A \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"bunch \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"of\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\" braces \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"in\"],\n  [\"paren.rparen\",\"}}\"],\n  [\"string\",\" title\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"@preamble\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"\\\"This bibliography was generated on \\\\today\\\"\"],\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_c9search.json",
    "content": "[[\n   [\"start\",{}],\n  [\"text\",\"Searching for '\"],\n  [\"text\",\"var\"],\n  [\"text\",\"' in\"],\n  [\"text\",\" /.c9/metadata/workspace/plugins \"],\n  [\"text\",\"(regexp, case sensitive, whole word)\"],\n  \"Searching for \\u0001var\\u0001 in\\u0001/.c9/metadata/workspace/plugins\\u0001\\u0001regexp, case sensitive, whole word\\u0001\"\n],[\n   [\"start\",{}]\n],[\n   [\"start\",{}],\n  [\"string\",\"configs/default.js\"],\n  [\"text\",\":\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"    1\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" fs = require(\\\"fs\\\");\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t2\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" argv = require('optimist').argv;\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t3\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" path = require(\\\"path\\\");\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t5\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" clientExtensions = {};\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t6\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" clientDirs = fs.readdirSync(__dirname + \\\"/../plugins-client\\\");\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t7\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.text\",\"for (\"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" i = 0; i < clientDirs.length; i++) {\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t8\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.text\",\"    \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" dir = clientDirs[i];\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t12\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.text\",\"    \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" name = dir.split(\\\".\\\")[1];\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t16\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" projectDir = (argv.w && path.resolve(process.cwd(), argv.w)) || process.cwd();\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t17\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" fsUrl = \\\"/workspace\\\";\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t19\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" port = argv.p || process.env.PORT || 3131;\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t20\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" host = argv.l || \\\"localhost\\\";\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t22\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" config = {\"]\n],[\n   [\"start\",{}]\n],[\n   [\"start\",{}],\n  [\"string\",\"configs/local.js\"],\n  [\"text\",\":\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t2\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" config = require(\\\"./default\\\");\"]\n],[\n   [\"start\",{}]\n],[\n   [\"start\",{}],\n  [\"string\",\"configs/packed.js\"],\n  [\"text\",\":\"]\n],[\n   [\"start\",{}],\n  [\"c9searchresults.constant.numeric\",\"\\t1\"],\n  [\"c9searchresults.text\",\": \"],\n  [\"c9searchresults.keyword\",\"var\"],\n  [\"c9searchresults.text\",\" config = require(\\\"./default\\\");\"]\n],[\n   [\"start\",{}]\n],[\n   [\"start\",{}]\n],[\n   [\"start\",{}],\n  [\"text\",\"Found \"],\n  [\"constant.numeric\",\"15\"],\n  [\"text\",\" matches in \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" files\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_c_cpp.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// compound assignment operators\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other\",\" <iostream>\"]\n],[\n   \"start\"\n],[\n   \"directive\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other.multiline\",\" \\\\\"]\n],[\n   \"start\",\n  [\"constant.other\",\"   <iostream>\"]\n],[\n   \"start\"\n],[\n   \"directive\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other.multiline\",\" \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"   \\\\\"]\n],[\n   \"start\",\n  [\"constant.other\",\"   <iostream>\"]\n],[\n   \"start\"\n],[\n   \"directive\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other.multiline\",\" \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"   \\\\\"]\n],[\n   \"start\",\n  [\"constant.other\",\"   \\\"iostream\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other\",\" <boost/asio/io_service.hpp>\"]\n],[\n   \"start\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other\",\" \\\"boost/asio/io_service.hpp\\\"\"]\n],[\n   \"start\"\n],[\n   \"directive\",\n  [\"keyword\",\"#include\"],\n  [\"constant.other.multiline\",\" \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"   \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"   \\\"iostream\\\" \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"   \\\"string\\\" \\\\\"]\n],[\n   \"start\",\n  [\"constant.other\",\"   <vector>\"]\n],[\n   \"start\",\n  [\"text\",\"   \"]\n],[\n   \"start\",\n  [\"keyword.control\",\"using\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"namespace\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"std\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"//\"]\n],[\n   \"start\",\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* foobar */\"]\n],[\n   \"singleLineComment\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// single line comment\\\\\"]\n],[\n   \"start\",\n  [\"comment\",\"        continued\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"+=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// equivalent to a=a+2\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"cout\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<<\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"#if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"VERBOSE\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"prints\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"trace message\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string.end\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"/* Print an error message and get out */\"]\n],[\n   \"directive\",\n  [\"keyword\",\"#define\"],\n  [\"constant.other.multiline\",\" ABORT                             \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"    do {                                  \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"        print( \\\"Abort\\\\n\\\" );                \\\\\"]\n],[\n   \"directive\",\n  [\"constant.other.multiline\",\"        exit(8);                          \\\\\"]\n],[\n   \"start\",\n  [\"constant.other\",\"} while (0)                      \"],\n  [\"comment\",\"/* Note: No semicolon */\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_cirru.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.double-dash\",\"-- https://github.com/Cirru/cirru-gopher/blob/master/code/scope.cr,\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"a\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"self\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"child\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"under\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"support.function\",\"under\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"parent\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"    \"],\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"a\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"a\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"x\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"x\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"just-print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"code\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"a\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"just-print\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"eval\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"self\"],\n  [\"storage.modifier\",\")\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"just-print\"]\n],[\n   \"line\",\n  [\"support.function\",\"eval\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"just-print\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"string\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"string with space\\\"\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"string\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"escapes \"],\n  [\"constant.character.escape\",\"\\\\n\"],\n  [\"string.quoted.double\",\" \"],\n  [\"constant.character.escape\",\"\\\\\\\"\\\\\\\\\"],\n  [\"string.quoted.double\",\"\\\"\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"brackets\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"((((()))))\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"string.quoted.double\",\"\\\"eval\\\"\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"string\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"eval\\\"\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"add\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"storage.modifier\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"storage.modifier\",\"))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"unwrap\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"]\n],[\n   \"line\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"map\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"a\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"storage.modifier\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"(\"],\n  [\"support.function\",\"b\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"$\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"storage.modifier\",\")\"]\n],[\n   \"start\"\n],[\n   \"line\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"a\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"storage.modifier\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"b\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"line\",\n  [\"markup.raw\",\"  \"],\n  [\"storage.modifier\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"d\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_clojure.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"defn\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"parting\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string\",\"\\\"returns a String parting in a given language\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"([]\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"World\\\"\"],\n  [\"keyword\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"([\"],\n  [\"support.function\",\"name\"],\n  [\"keyword\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"name\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"keyword\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"([\"],\n  [\"support.function\",\"name\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"language\"],\n  [\"keyword\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"; condp is similar to a case statement in other languages.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"; It is described in more detail later.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"; It is used here to take different actions based on whether the\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"; parameter \\\"language\\\" is set to \\\"en\\\", \\\"es\\\" or something else.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"condp\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"language\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"str\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Goodbye, \\\"\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"name\"],\n  [\"keyword\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"string\",\"\\\"es\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"str\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Adios, \\\"\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"name\"],\n  [\"keyword\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"(throw\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"IllegalArgumentException\"],\n  [\"text\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"str\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"unsupported language \\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"language\"],\n  [\"keyword\",\"))))))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"println\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"keyword\",\"))\"],\n  [\"text\",\" \"],\n  [\"comment\",\"; -> Goodbye, World\"]\n],[\n   \"start\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"println\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Mark\\\"\"],\n  [\"keyword\",\"))\"],\n  [\"text\",\" \"],\n  [\"comment\",\"; -> Goodbye, Mark\"]\n],[\n   \"start\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"println\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Mark\\\"\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"es\\\"\"],\n  [\"keyword\",\"))\"],\n  [\"text\",\" \"],\n  [\"comment\",\"; -> Adios, Mark\"]\n],[\n   \"start\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"println\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"identifier\",\"parting\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Mark\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"xy\\\"\"],\n  [\"keyword\",\"))\"],\n  [\"text\",\" \"],\n  [\"comment\",\"; -> java.lang.IllegalArgumentException: unsupported language xy\"]\n],[\n   \"start\"\n],[\n   \"regex\",\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"(\"],\n  [\"support.function\",\"re-matches\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"#\\\"abc\"],\n  [\"constant.language.escape\",\"(.*)\"]\n],[\n   \"string\",\n  [\"string.regexp\",\"            \"],\n  [\"constant.language.escape\",\"(\"],\n  [\"string.regexp\",\"r\"],\n  [\"constant.language.escape\",\")\"],\n  [\"string.regexp\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"abcxyz\"]\n],[\n   \"start\",\n  [\"string\",\"            r\\\"\"],\n  [\"keyword\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\")\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_cobol.json",
    "content": "[[\n   \"start\",\n  [\"identifier\",\"TODO\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_coffee.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#test: tokenize keyword\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\"..\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"comment\",\"#test: tokenize regexp\"]\n],[\n   \"start\",\n  [\"string.regex\",\"/\\\"[a]/\"]\n],[\n   \"start\",\n  [\"comment\",\"#test: tokenize functions\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{args}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{a1, a2}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{@a1, a2}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{args}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{args}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{0abc}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren\",\"{\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"abc\"],\n  [\"paren\",\"}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren\",\"{\"],\n  [\"identifier\",\"abc\"],\n  [\"keyword.operator\",\"/\"],\n  [\"paren\",\"}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{#abc}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{abc#}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren\",\"{\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"abc\"],\n  [\"paren\",\"}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren\",\"{\"],\n  [\"identifier\",\"abc\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren\",\"}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{a{bc}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{ }\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"{}\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"args\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"arg1, arg2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"arg1 = 1, arg2 = 'name'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"@arg1 = /abc/, arg2 = 'name'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"#test: tokenize function: invalid case:\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"args\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language\",\"window\"],\n  [\"punctuation.operator\",\".\"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"args\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"#test: tokenize callback function\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"bar\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"args\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"x\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"start\",\n  [\"comment\",\"#test: tokenize class\"]\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"language.support.class\",\"Foo\"]\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"language.support.class\",\"Foo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"language.support.class\",\"Bar\"]\n],[\n   \"start\",\n  [\"comment\",\"#test: tokenize illegal name property\"]\n],[\n   \"start\",\n  [\"identifier\",\"foo\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"static\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"function\"]\n],[\n   \"start\",\n  [\"comment\",\"#!test tokenize string with interpolation\"]\n],[\n   \"start\",\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"paren.string\",\"#{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"22\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"paren\",\"{\"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"paren.string\",\"#{\"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"paren.string\",\"}\"],\n  [\"string.end\",\"\\\"\"],\n  [\"paren\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.string\",\"}\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\" \"],\n  [\"paren.string\",\"#{\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"paren\",\"{}\"],\n  [\"text\",\" \"],\n  [\"paren.string\",\"}\"],\n  [\"string\",\" )\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\"  \"]\n],[\n   \"qqdoc\",\n  [\"string\",\"\\\"\\\"\\\"heredoc\"]\n],[\n   \"start\",\n  [\"string\",\"   \\\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"do\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"->\"]\n],[\n   \"comment\",\n  [\"text\",\"    \"],\n  [\"comment\",\"###\"]\n],[\n   \"comment\",\n  [\"comment\",\"    herecomment\"]\n],[\n   \"start\",\n  [\"comment\",\"    ###\"]\n],[\n   \"heregex\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"re\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regex\",\"/regex/imgy\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"test\"],\n  [\"text\",\" \"],\n  [\"string.regex\",\"///\"]\n],[\n   \"heregex\",\n  [\"comment.regex\",\"        \"],\n  [\"string.regex\",\"heregex\"],\n  [\"comment.regex\",\"  # comment\"]\n],[\n   \"start\",\n  [\"string.regex\",\"    ///imgy\"]\n],[\n   \"js\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"this\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"isnt\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"`just \"]\n],[\n   \"start\",\n  [\"string\",\"       JavaScript`\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.language\",\"undefined\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_coldfusion.json",
    "content": "[[\n   \"start\",\n  [\"comment.start\",\"<!---\"],\n  [\"comment\",\" hello world \"],\n  [\"comment.end\",\"--->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"keyword.tag-name.xml\",\"cfset\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"comment.start\",\"<!---\"],\n  [\"comment\",\" x \"],\n  [\"comment.start\",\"<!---\"],\n  [\"comment\",\" y \"],\n  [\"comment.end\",\"--->\"],\n  [\"comment\",\"  z \"],\n  [\"comment.end\",\"--->\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"welcome\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Hello World!\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" x \"],\n  [\"comment.start\",\"<!---\"],\n  [\"comment\",\" y \"],\n  [\"comment.end\",\"--->\"],\n  [\"comment.xml\",\"  z \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"keyword.tag-name.xml\",\"cfoutput\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"#welcome#\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"keyword.tag-name.xml\",\"cfoutput\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"cfjs-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.cfscript.tag-name.xml\",\"cfscript\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"cfjs-no_regex\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Dateformat\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"now\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.cfscript.tag-name.xml\",\"cfscript\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_crystal.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# crystal comment\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"require\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"llvm\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.class\",\"NUM_CELLS\"],\n  [\"text\",\"          \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"30000\"]\n],[\n   \"start\",\n  [\"support.class\",\"CELL_SIZE_IN_BYTES\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"     \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"abstract\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"Instruction\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"abstract\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"compile\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"program\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"bb\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"Increment\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"Instruction\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"initialize\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.instance\",\"@amount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"Int32\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"compile\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"program\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"bb\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"cell_val_is_zero\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"builder\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"icmp\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"LLVM\"],\n  [\"text\",\"::\"],\n  [\"support.class\",\"IntPredicate\"],\n  [\"text\",\"::\"],\n  [\"support.class\",\"EQ\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cell_val\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"zero\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"call_args\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable.instance\",\"@ctx\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"int32\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"const_int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.class\",\"NUM_CELLS\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"@ctx\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"int32\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"const_int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.class\",\"CELL_SIZE_IN_BYTES\"],\n  [\"paren.rparen\",\")]\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"builder\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"cond\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cell_val_is_zero\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop_after\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop_body_block\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.instance\",\"@body\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"each\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"identifier\",\"instruction\"],\n  [\"keyword.operator\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"loop_body_block\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"instruction\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"compile\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"program\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop_body_block\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"builder\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"position_at_end\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop_body_block\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"unless\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"matching_close_index\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"error\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Unmatched '[' at position \"],\n  [\"paren.start\",\"#{\"],\n  [\"identifier\",\"i\"],\n  [\"paren.end\",\"}\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"bb\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_csharp.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"void\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"HelloWorld\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"//Say Hello!\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"WriteLine\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Hello World\"],\n  [\"string.end\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_csound_document.json",
    "content": "[[\n   \"start\",\n  [\"text.csound-document\",\"/*\"]\n],[\n   \"start\",\n  [\"text.csound-document\",\" * comment\"]\n],[\n   \"start\",\n  [\"text.csound-document\",\" */\"]\n],[\n   \"start\",\n  [\"text.csound-document\",\"; comment\"]\n],[\n   \"start\",\n  [\"text.csound-document\",\"// comment\"]\n],[\n   \"start\",\n  [\"text.csound-document\",\"/\"]\n],[\n   \"synthesizer\",\n  [\"meta.tag.punctuation.tag-open.csound-document\",\"<\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsoundSynthesizer\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"csound-start\",\n  [\"meta.tag.punctuation.tag-open.csound-document\",\"<\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsInstruments\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"csound-start\",\n  [\"variable.language.csound\",\"0dbfs\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"1\"]\n],[\n   \"csound-start\",\n  [\"support.function.csound\",\"prints\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"\\\"\"],\n  [\"string.quoted.csound\",\"hello, world\"],\n  [\"constant.character.escape.csound\",\"\\\\n\"],\n  [\"punctuation.definition.string.end.csound\",\"\\\"\"]\n],[\n   \"synthesizer\",\n  [\"meta.tag.punctuation.end-tag-open.csound-document\",\"</\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsInstruments\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"csound-score-start\",\n  [\"meta.tag.punctuation.tag-open.csound-document\",\"<\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsScore\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"csound-score-start\",\n  [\"keyword.control.csound-score\",\"i\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"]\n],[\n   \"synthesizer\",\n  [\"meta.tag.punctuation.end-tag-open.csound-document\",\"</\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsScore\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"html-start\",\n  [\"meta.tag.punctuation.tag-open.csound-document\",\"<\"],\n  [\"entity.name.tag.begin.csound-document\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"html-start\",\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"DOCTYPE\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"synthesizer\",\n  [\"meta.tag.punctuation.end-tag-open.csound-document\",\"</\"],\n  [\"entity.name.tag.begin.csound-document\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.csound-document\",\"</\"],\n  [\"entity.name.tag.begin.csound-document\",\"CsoundSynthesizer\"],\n  [\"meta.tag.punctuation.tag-close.csound-document\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_csound_orchestra.json",
    "content": "[[\n   \"punctuation.definition.comment.begin.csound\",\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"]\n],[\n   \"punctuation.definition.comment.begin.csound\",\n  [\"comment.block.csound\",\" * comment\"]\n],[\n   \"start\",\n  [\"comment.block.csound\",\" \"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"start\",\n  [\"comment.line.semicolon.csound\",\"; comment\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.csound\",\"// comment\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.function.csound\",\"instr\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"entity.name.function.csound\",\"1\"],\n  [\"text\",\",\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"entity.name.function.csound\",\"N_a_M_e_\"],\n  [\"text\",\",\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"text\",\"+\"],\n  [\"entity.name.function.csound\",\"Name\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"comment.line.double-slash.csound\",\"//\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text.csound\",\"iDuration\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.variable.csound\",\"p3\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function.csound\",\"outc\"],\n  [\"punctuation.type-annotation.csound\",\":\"],\n  [\"type-annotation.storage.type.csound\",\"a\"],\n  [\"text\",\"(\"],\n  [\"text.csound\",\"aSignal\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"keyword.other.csound\",\"endin\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.function.csound\",\"opcode\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"entity.name.function.opcode.csound\",\"aUDO\"],\n  [\"text\",\",\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"storage.type.csound\",\"i[]\"],\n  [\"text\",\",\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"storage.type.csound\",\"aik\"],\n  [\"comment.line.double-slash.csound\",\"//\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text.csound\",\"aUDO\"]\n],[\n   \"start\",\n  [\"keyword.other.csound\",\"endop\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.numeric.integer.decimal.csound\",\"123\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0123456789\"]\n],[\n   \"start\",\n  [\"storage.type.number.csound\",\"0x\"],\n  [\"constant.numeric.integer.hexadecimal.csound\",\"abcdef0123456789\"],\n  [\"text\",\" \"],\n  [\"storage.type.number.csound\",\"0X\"],\n  [\"constant.numeric.integer.hexadecimal.csound\",\"ABCDEF\"]\n],[\n   \"start\",\n  [\"constant.numeric.float.csound\",\"1e2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"3e+4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"5e-6\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"7E8\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"9E+0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"1E-2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"3.\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"4.56\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\".789\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.string.begin.csound\",\"\\\"\"],\n  [\"string.quoted.csound\",\"characters\"],\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO.\"],\n  [\"punctuation.definition.string.end.csound\",\"\\\"\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.begin.csound\",\"\\\"\"],\n  [\"constant.character.escape.csound\",\"\\\\\\\\\\\\a\\\\b\\\\n\\\\r\\\\t\\\\012\\\\345\\\\67\\\\\\\"\"],\n  [\"punctuation.definition.string.end.csound\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   [\"#tmp\",\"braced string\",\"start\",\"braced string\"],\n  [\"punctuation.definition.string.begin.csound\",\"{{\"]\n],[\n   [\"#tmp\",\"braced string\",\"start\",\"braced string\"],\n  [\"string.braced.csound\",\"characters$MACRO.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.csound\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.begin.csound\",\"{{\"],\n  [\"constant.character.escape.csound\",\"\\\\\\\\\\\\a\\\\b\\\\n\\\\r\\\\t\\\\\\\"\\\\012\\\\345\\\\67\"],\n  [\"punctuation.definition.string.end.csound\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.operator.csound\",\"+\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"-\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"~\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"¬\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"!\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"*\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"/\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"^\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"%\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"<<\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\">>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"<\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\">\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"<=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\">=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"==\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"!=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"&\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"#\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"|\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"&&\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"||\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"?\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"+=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"-=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"*=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.csound\",\"/=\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language.csound\",\"0dbfs\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"A4\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"kr\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"ksmps\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"nchnls\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"nchnls_i\"],\n  [\"text\",\" \"],\n  [\"variable.language.csound\",\"sr\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"do\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"else\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"elseif\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"endif\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"enduntil\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"fi\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"if\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"ithen\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"kthen\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"od\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"then\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"until\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"while\"]\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"return\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound\",\"rireturn\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.label.csound\",\"aLabel\"],\n  [\"entity.punctuation.label.csound\",\":\"]\n],[\n   \"start\",\n  [\"text.csound\",\" \"],\n  [\"entity.name.label.csound\",\"label2\"],\n  [\"entity.punctuation.label.csound\",\":\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"goto\"],\n  [\"text.csound\",\" \"],\n  [\"entity.name.label.csound\",\"aLabel\"]\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"reinit\"],\n  [\"text.csound\",\" \"],\n  [\"entity.name.label.csound\",\"aLabel\"]\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"cggoto\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"1\"],\n  [\"keyword.operator.csound\",\"==\"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\", \"],\n  [\"entity.name.label.csound\",\"aLabel\"]\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"timout\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\", \"],\n  [\"entity.name.label.csound\",\"aLabel\"]\n],[\n   \"start\",\n  [\"keyword.control.csound\",\"loop_ge\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text.csound\",\", \"],\n  [\"entity.name.label.csound\",\"aLabel\"]\n],[\n   \"start\"\n],[\n   [\"#tmp\",\"csound-score-start\",\"start\",\"Csound score opcode\"],\n  [\"support.function.csound\",\"readscore\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"{{\"]\n],[\n   [\"#tmp\",\"csound-score-start\",\"start\",\"Csound score opcode\"],\n  [\"keyword.control.csound-score\",\"i\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.csound\",\"}}\"]\n],[\n   [\"#tmp\",\"python-start\",\"start\",\"Python opcode\"],\n  [\"support.function.csound\",\"pyrun\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"{{\"]\n],[\n   [\"#tmp\",\"python-start\",\"start\",\"Python opcode\"],\n  [\"comment\",\"# Python\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.csound\",\"}}\"]\n],[\n   [\"#tmp\",\"lua-start\",\"start\",\"Lua opcode\"],\n  [\"support.function.csound\",\"lua_exec\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"{{\"]\n],[\n   [\"#tmp\",\"lua-start\",\"start\",\"Lua opcode\"],\n  [\"comment\",\"-- Lua\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.csound\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#include\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"string.csound\",\"\\\"file.udo\\\"\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#include\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"string.csound\",\"|file.udo|\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#ifdef\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#else\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#ifndef\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#endif\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#undef\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#   define\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"],\n  [\"punctuation.definition.macro.begin.csound\",\"#\"],\n  [\"text.csound\",\"macro_body\"],\n  [\"punctuation.definition.macro.end.csound\",\"#\"]\n],[\n   \"define directive\",\n  [\"keyword.preprocessor.csound\",\"#define\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"define directive\",\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"macro body\",\n  [\"punctuation.definition.macro.begin.csound\",\"#\"],\n  [\"constant.character.escape.csound\",\"\\\\#\"],\n  [\"text.csound\",\"macro\"]\n],[\n   \"start\",\n  [\"text.csound\",\"body\"],\n  [\"constant.character.escape.csound\",\"\\\\#\"],\n  [\"punctuation.definition.macro.end.csound\",\"#\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#define\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"],\n  [\"punctuation.definition.macro-parameter-name-list.begin.csound\",\"(\"],\n  [\"variable.parameter.preprocessor.csound\",\"ARG1\"],\n  [\"text\",\"#\"],\n  [\"variable.parameter.preprocessor.csound\",\"ARG2\"],\n  [\"punctuation.definition.macro-parameter-name-list.end.csound\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.macro.begin.csound\",\"#\"],\n  [\"text.csound\",\"macro_body\"],\n  [\"punctuation.definition.macro.end.csound\",\"#\"]\n],[\n   \"define directive\",\n  [\"keyword.preprocessor.csound\",\"#define\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"define directive\",\n  [\"entity.name.function.preprocessor.csound\",\"MACRO\"],\n  [\"punctuation.definition.macro-parameter-name-list.begin.csound\",\"(\"],\n  [\"variable.parameter.preprocessor.csound\",\"ARG1\"],\n  [\"text\",\"'\"],\n  [\"variable.parameter.preprocessor.csound\",\"ARG2\"],\n  [\"text\",\"'\"],\n  [\"variable.parameter.preprocessor.csound\",\"ARG3\"],\n  [\"punctuation.definition.macro-parameter-name-list.end.csound\",\")\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"macro body\",\n  [\"punctuation.definition.macro.begin.csound\",\"#\"],\n  [\"constant.character.escape.csound\",\"\\\\#\"],\n  [\"text.csound\",\"macro\"]\n],[\n   \"start\",\n  [\"text.csound\",\"body\"],\n  [\"constant.character.escape.csound\",\"\\\\#\"],\n  [\"punctuation.definition.macro.end.csound\",\"#\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO.\"]\n],[\n   \"start\",\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO\"],\n  [\"punctuation.definition.macro-parameter-value-list.begin.csound\",\"(\"],\n  [\"text\",\"x\"],\n  [\"punctuation.definition.macro-parameter-value-list.end.csound\",\")\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"@0\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"@@ 1\"]\n],[\n   \"start\",\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO.\"],\n  [\"punctuation.definition.macro-parameter-value-list.begin.csound\",\"(\"],\n  [\"punctuation.macro-parameter-value-parenthetical.begin.csound\",\"((\"],\n  [\"text.csound\",\"x\"],\n  [\"keyword.operator.csound\",\"#\"],\n  [\"text.csound\",\"y\"],\n  [\"constant.character.escape.csound\",\"\\\\)\"],\n  [\"punctuation.macro-parameter-value-parenthetical.end.csound\",\"))\"],\n  [\"punctuation.macro-parameter-value-separator.csound\",\"'\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"\\\"\"],\n  [\"invalid.illegal.csound\",\"(#'\"],\n  [\"string.quoted.csound\",\"x\"],\n  [\"invalid.illegal.csound\",\")\"],\n  [\"constant.character.escape.csound\",\"\\\\)\"],\n  [\"string.quoted.csound\",\"x\"],\n  [\"constant.character.escape.csound\",\"\\\\)\"],\n  [\"invalid.illegal.csound\",\")\"],\n  [\"punctuation.definition.string.end.csound\",\"\\\"\"],\n  [\"punctuation.macro-parameter-value-separator.csound\",\"#\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.csound\",\"{{\"],\n  [\"string.braced.csound\",\"x\"],\n  [\"constant.character.escape.csound\",\"\\\\)\"],\n  [\"invalid.illegal.csound.csound\",\")\"],\n  [\"string.braced.csound\",\"x\"],\n  [\"invalid.illegal.csound.csound\",\")\"],\n  [\"constant.character.escape.csound\",\"\\\\)\"],\n  [\"invalid.illegal.csound.csound\",\"(#'\"],\n  [\"punctuation.definition.string.end.csound\",\"}}\"],\n  [\"punctuation.definition.macro-parameter-value-list.end.csound\",\")\"],\n  [\"comment.line.semicolon.csound\",\";\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_csound_score.json",
    "content": "[[\n   \"punctuation.definition.comment.begin.csound\",\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"]\n],[\n   \"punctuation.definition.comment.begin.csound\",\n  [\"comment.block.csound\",\" * comment\"]\n],[\n   \"start\",\n  [\"comment.block.csound\",\" \"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"]\n],[\n   \"start\",\n  [\"comment.line.semicolon.csound\",\"; comment\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.csound\",\"// comment\"]\n],[\n   \"start\",\n  [\"keyword.control.csound-score\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"B\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"b\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"C\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"d\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"e\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"f\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"q\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"s\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"t\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"y\"]\n],[\n   \"start\",\n  [\"constant.numeric.language.csound-score\",\"z\"]\n],[\n   \"start\",\n  [\"keyword.control.csound-score\",\"np\"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"nP\"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"Np\"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"2\"],\n  [\"text\",\" \"],\n  [\"keyword.control.csound-score\",\"NP\"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"3\"]\n],[\n   \"start\",\n  [\"keyword.other.csound-score\",\"m\"],\n  [\"punctuation.definition.comment.begin.csound\",\"/*\"],\n  [\"punctuation.definition.comment.end.csound\",\"*/\"],\n  [\"entity.name.label.csound-score\",\"label\"],\n  [\"comment.line.semicolon.csound\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.csound-score\",\"n\"],\n  [\"text\",\" \"],\n  [\"entity.name.label.csound-score\",\"label\"]\n],[\n   \"start\",\n  [\"constant.numeric.integer.decimal.csound\",\"123\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound\",\"0123456789\"]\n],[\n   \"start\",\n  [\"storage.type.number.csound\",\"0x\"],\n  [\"constant.numeric.integer.hexadecimal.csound\",\"abcdef0123456789\"],\n  [\"text\",\" \"],\n  [\"storage.type.number.csound\",\"0X\"],\n  [\"constant.numeric.integer.hexadecimal.csound\",\"ABCDEF\"]\n],[\n   \"start\",\n  [\"constant.numeric.float.csound\",\"1e2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"3e+4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"5e-6\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"7E8\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"9E+0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"1E-2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"3.\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\"4.56\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.csound\",\".789\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.begin.csound-score\",\"\\\"\"],\n  [\"string.quoted.csound-score\",\"characters\"],\n  [\"entity.name.function.preprocessor.csound\",\"$MACRO.\"],\n  [\"punctuation.definition.string.end.csound-score\",\"\\\"\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\"],\n  [\"punctuation.braced-loop.begin.csound-score\",\"{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"1\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound-score\",\"I\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\",\"loop after macro name\"],\n  [\"text\",\"  \"],\n  [\"punctuation.braced-loop.begin.csound-score\",\"{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"2\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound-score\",\"J\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\",\"loop after macro name\",\"loop after macro name\"],\n  [\"text\",\"    \"],\n  [\"punctuation.braced-loop.begin.csound-score\",\"{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal.csound-score\",\"3\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound-score\",\"K\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\",\"loop after macro name\",\"loop after macro name\"],\n  [\"text\",\"      \"],\n  [\"entity.name.function.preprocessor.csound\",\"$I\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"$J\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.preprocessor.csound\",\"$K\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\",\"loop after macro name\"],\n  [\"text\",\"    \"],\n  [\"punctuation.braced-loop.end.csound-score\",\"}\"]\n],[\n   [\"#tmp\",\"loop after macro name\",\"start\",\"loop after macro name\"],\n  [\"text\",\"  \"],\n  [\"punctuation.braced-loop.end.csound-score\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.braced-loop.end.csound-score\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.preprocessor.csound\",\"#include\"],\n  [\"text\",\" \"],\n  [\"string.csound\",\"\\\"score.sco\\\"\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_csp.json",
    "content": "[[\n   \"start\",\n  [\"constant.language\",\"child-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"connect-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"default-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"font-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"frame-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"img-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"manifest-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"media-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"object-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"script-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"style-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"worker-src\"]\n],[\n   \"start\",\n  [\"constant.language\",\"base-uri\"]\n],[\n   \"start\",\n  [\"constant.language\",\"plugin-types\"]\n],[\n   \"start\",\n  [\"constant.language\",\"sandbox\"]\n],[\n   \"start\",\n  [\"constant.language\",\"disown-opener\"]\n],[\n   \"start\",\n  [\"constant.language\",\"form-action\"]\n],[\n   \"start\",\n  [\"constant.language\",\"frame-ancestors\"]\n],[\n   \"start\",\n  [\"constant.language\",\"report-uri\"]\n],[\n   \"start\",\n  [\"constant.language\",\"report-to\"]\n],[\n   \"start\",\n  [\"constant.language\",\"upgrade-insecure-requests\"]\n],[\n   \"start\",\n  [\"constant.language\",\"block-all-mixed-content\"]\n],[\n   \"start\",\n  [\"constant.language\",\"require-sri-for\"]\n],[\n   \"start\",\n  [\"constant.language\",\"reflected-xss\"]\n],[\n   \"start\",\n  [\"constant.language\",\"referrer\"]\n],[\n   \"start\",\n  [\"constant.language\",\"policy-uri\"]\n],[\n   \"start\",\n  [\"variable\",\"'self'\"]\n],[\n   \"start\",\n  [\"variable\",\"'unsafe-inline'\"]\n],[\n   \"start\",\n  [\"variable\",\"'unsafe-eval'\"]\n],[\n   \"start\",\n  [\"variable\",\"'strict-dynamic'\"]\n],[\n   \"start\",\n  [\"variable\",\"'unsafe-hashed-attributes'\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_css.json",
    "content": "[[\n   \"ruleset\",\n  [\"variable\",\".text-layer\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"font\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12\"],\n  [\"keyword\",\"px\"],\n  [\"text\",\" Monaco, \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Courier New\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"support.constant.fonts\",\"monospace\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"cursor\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"text\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"ruleset\",\n  [\"variable\",\".blinker\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"animation\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" blink \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword\",\"s\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"linear\"],\n  [\"text\",\" infinite alternate\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"@\"],\n  [\"keyword\",\"keyframes\"],\n  [\"text\",\" blink \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword\",\"%\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"40\"],\n  [\"keyword\",\"%\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"comment\",\"ruleset\"],\n  [\"text\",\"        \"],\n  [\"support.type\",\"opacity\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/*\"]\n],[\n   \"ruleset\",\n  [\"comment\",\"        */\"]\n],[\n   \"ruleset\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"opacity\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"constant.numeric\",\"40.5\"],\n  [\"keyword\",\"%\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"100\"],\n  [\"keyword\",\"%\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"ruleset\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"opacity\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"media\",\n  [\"string\",\"@\"],\n  [\"keyword\",\"document\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"http://c9.io/\"],\n  [\"support.function\",\")\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"url-prefix(\"],\n  [\"string\",\"http://ace.c9.io/build/\"],\n  [\"support.function\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"media\",\n  [\"text\",\"   \"],\n  [\"support.function\",\"domain(\"],\n  [\"string\",\"c9.io\"],\n  [\"support.function\",\")\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"regexp(\"],\n  [\"string\",\"\\\"https:.*\\\"\"],\n  [\"support.function\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/**/\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"/**/\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant\",\"img\"],\n  [\"text\",\"[\"],\n  [\"constant\",\"title\"],\n  [\"text\",\"]\"],\n  [\"string\",\":before\"],\n  [\"text\",\" \"]\n],[\n   \"ruleset\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"string.start0\",\"ruleset\"],\n  [\"text\",\"        \"],\n  [\"support.type\",\"content\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"attr\"],\n  [\"text\",\"(title) \"],\n  [\"string.start\",\"\\\"\"],\n  [\"constant.language.escape\",\"\\\\A\"],\n  [\"string\",\"Image \"],\n  [\"constant.language.escape\",\"\\\\\"]\n],[\n   \"ruleset\",\n  [\"string\",\"            retrieved from\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   [\"comment\",\"ruleset\"],\n  [\"text\",\"            \"],\n  [\"support.function\",\"attr\"],\n  [\"text\",\"(src)\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/*\"]\n],[\n   \"ruleset\",\n  [\"comment\",\"            */\"]\n],[\n   \"ruleset\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"white-space\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"pre\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"ruleset\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"display\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"block\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"ruleset\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"background\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"asdasd\"],\n  [\"support.function\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"err\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_csv.json",
    "content": "[[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2 long\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"keyword.csv_0\",\"col1\"],\n  [\"keyword.csv_0\",\",\"],\n  [\"keyword.csv_0\",\"with quotes\"],\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"co\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"l4\"],\n  [\"variable.csv_4.csv_separator\",\",\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"broken\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"-\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"],\n  [\"variable.csv_4\",\"col5\"]\n],[\n   \"string-1\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"text.csv_1\",\"col2\"]\n],[\n   \"string-2\",\n  [\"text.csv_1\",\"multiline\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"col3\"]\n],[\n   \"string-2\",\n  [\"string.csv_2\",\"multiline\"],\n  [\"string.csv_2\",\"\\\"\\\"\"],\n  [\"string.csv_2\",\"string\"]\n],[\n   \"string-3\",\n  [\"string.csv_2\",\"3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"col4\"]\n],[\n   \"string-3\",\n  [\"string.regex.csv_3\",\"multiline string\"]\n],[\n   \"string-3\"\n],[\n   \"start\",\n  [\"string.regex.csv_3\",\"4\"],\n  [\"string.regex.csv_3\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"c\"],\n  [\"string.csv_2\",\",\"],\n  [\"string.csv_2\",\"o\"],\n  [\"string.csv_2\",\",\"],\n  [\"string.csv_2\",\"l\"],\n  [\"string.csv_2\",\"\\\"\\\"\"],\n  [\"string.csv_2\",\"3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\",\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\",\"],\n  [\"keyword.csv_6\",\"col7\"],\n  [\"text.csv_7.csv_separator\",\",\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\",\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\",\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\",\"],\n  [\"variable.csv_10\",\"col11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\",\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\",\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\",\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\",\"],\n  [\"keyword.csv_6\",\"col7\"],\n  [\"text.csv_7.csv_separator\",\",\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\",\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\",\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\",\"],\n  [\"variable.csv_10\",\"col11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\",\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\",\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\",\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\",\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\",\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\",\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\",\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\",\"],\n  [\"keyword.csv_6\",\"co\"],\n  [\"keyword.csv_6\",\"\\\"\"],\n  [\"keyword.csv_6\",\"l7\"],\n  [\"text.csv_7.csv_separator\",\",\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\",\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\",\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\",\"],\n  [\"variable.csv_10\",\"11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\",\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\",\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_curly.json",
    "content": "[[\n   \"start\",\n  [\"text.xml\",\"tokenize Curly template\"],\n  [\"variable\",\"{{\"],\n  [\"text\",\"test\"],\n  [\"variable\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"tokenize embedded script\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"a\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"'a'\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"storage.type\",\"var\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"'123'\"]\n],[\n   \"start\",\n  [\"text.xml\",\"tokenize multiline attribute value with double quotes\"]\n],[\n   [\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"abc{{xyz}}\"]\n],[\n   \"start\",\n  [\"string.attribute-value.xml\",\"def\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"tokenize multiline attribute value with single quotes\"]\n],[\n   [\"string.attribute-value.xml\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"'abc\"]\n],[\n   \"start\",\n  [\"string.attribute-value.xml\",\"def\\\\\\\"'\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_d.json",
    "content": "[[\n   \"start\",\n  [\"comment.shebang\",\"#!/usr/bin/env rdmd\"]\n],[\n   \"start\",\n  [\"comment\",\"// Computes average line length for standard input.\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"variable.module\",\"std.stdio\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.type\",\"void\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.type\",\"ulong\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lines\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.type\",\"double\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sumLength\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"foreach\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"line\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stdin\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"byLine\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.operator\",\"++\"],\n  [\"identifier\",\"lines\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"sumLength\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"line\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"length\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"writeln\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Average line length: \\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"lines\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"?\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sumLength\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lines\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_dart.json",
    "content": "[[\n   \"start\",\n  [\"identifier\",\"main\"],\n  [\"text\",\"() {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"print\"],\n  [\"text\",\"(\"],\n  [\"string\",\"'Hello World!'\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.primitive.dart\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"fib\"],\n  [\"text\",\"(\"],\n  [\"storage.type.primitive.dart\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"keyword.operator.comparison.dart\",\">\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.comparison.dart\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\") \"],\n  [\"keyword.control.ternary.dart\",\"?\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"fib\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.arithmetic.dart\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"fib\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\")) \"],\n  [\"keyword.control.ternary.dart\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"main\"],\n  [\"text\",\"() {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"print\"],\n  [\"text\",\"(\"],\n  [\"string\",\"'fib(20) = \"],\n  [\"text\",\"${fib(20)}\"],\n  [\"string\",\"'\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"comment\",\n  [\"comment\",\"/*asd\"]\n],[\n   \"comment\",\n  [\"comment\",\"asdad\"]\n],[\n   \"start\",\n  [\"comment\",\"*/\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"0.67\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"77\"]\n],[\n   \"start\",\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"86\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.import.dart\",\"import\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"http://dartwatch.com/myOtherLibrary.dart\\\"\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"keyword.other.import.dart\",\"import\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"myOtherLibrary.dart\\\"\"],\n  [\"text\",\", \"],\n  [\"keyword.other.import.dart\",\"prefix\"],\n  [\"text\",\":\"],\n  [\"string\",\"\\\"lib1\\\"\"],\n  [\"text\",\");\"]\n],[\n   \"start\"\n],[\n   \"qqdoc\",\n  [\"string\",\"\\\"\\\"\\\"asdasdads\"]\n],[\n   \"qqdoc\",\n  [\"string\",\"asdadsadsasd\"]\n],[\n   \"start\",\n  [\"string\",\"asdasdasdad\\\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"string\",\"'23424'\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.numeric\",\"0x234\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.dart\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"bar\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.primitive.dart\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.bitwise.dart\",\"<<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"comment\",\"// Create a class for Point.\"]\n],[\n   \"start\",\n  [\"keyword.declaration.dart\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// Final variables cannot be changed once they are assigned.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// Create two instance variables.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier.dart\",\"final\"],\n  [\"text\",\" \"],\n  [\"storage.type.primitive.dart\",\"num\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// A constructor, with syntactic sugar for setting instance variables.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\"(\"],\n  [\"variable.language.dart\",\"this\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"variable.language.dart\",\"this\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"y\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// A named constructor with an initializer list.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"origin\"],\n  [\"text\",\"() \"],\n  [\"keyword.control.ternary.dart\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// A method.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type.primitive.dart\",\"num\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"distanceTo\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"text\",\") {\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.primitive.dart\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dx\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.primitive.dart\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dy\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"y\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.dart\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sqrt\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"dx\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dx\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dy\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.dart\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dy\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"  }\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"// Check for null.\"]\n],[\n   \"start\",\n  [\"storage.type.primitive.dart\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"unicorn\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword.control.dart\",\"assert\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"unicorn\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.comparison.dart\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.language.dart\",\"null\"],\n  [\"text\",\");\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"// Check for NaN.\"]\n],[\n   \"start\",\n  [\"storage.type.primitive.dart\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"iMeantToDoThis\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.dart\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.operator.arithmetic.dart\",\"/\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword.control.dart\",\"assert\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"iMeantToDoThis\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"isNaN\"],\n  [\"text\",\"());\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_diff.json",
    "content": "[[\n   \"start\",\n  [\"variable\",\"diff\"],\n  [\"variable\",\" --git\"],\n  [\"keyword\",\" a/lib/ace/edit_session.js\"],\n  [\"variable\",\" b/lib/ace/edit_session.js\"]\n],[\n   \"start\",\n  [\"variable\",\"index 23fc3fc..ed3b273 100644\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"---\"],\n  [\"meta.tag\",\" a/lib/ace/edit_session.js\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"+++\"],\n  [\"meta.tag\",\" b/lib/ace/edit_session.js\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -51,6 +51,7 \"],\n  [\"constant\",\"@@\"],\n  [\"comment.doc.tag\",\" var TextMode = require(\\\"./mode/text\\\").Mode;\"]\n],[\n   \"start\",\n  [\"invisible\",\" var Range = require(\\\"./range\\\").Range;\"]\n],[\n   \"start\",\n  [\"invisible\",\" var Document = require(\\\"./document\\\").Document;\"]\n],[\n   \"start\",\n  [\"invisible\",\" var BackgroundTokenizer = require(\\\"./background_tokenizer\\\").BackgroundTokenizer;\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"var SearchHighlight = require(\\\"./search_highlight\\\").SearchHighlight;\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"invisible\",\" /**\"]\n],[\n   \"start\",\n  [\"invisible\",\"  * class EditSession\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -307,6 +308,13 \"],\n  [\"constant\",\"@@\"],\n  [\"comment.doc.tag\",\" var EditSession = function(text, mode) {\"]\n],[\n   \"start\",\n  [\"invisible\",\"         return token;\"]\n],[\n   \"start\",\n  [\"invisible\",\"     };\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"    this.highlight = function(re) {\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"        if (!this.$searchHighlight) {\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"            var highlight = new SearchHighlight(null, \\\"ace_selected-word\\\", \\\"text\\\");\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"            this.$searchHighlight = this.addDynamicMarker(highlight);\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"        }\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"        this.$searchHighlight.setRegexp(re);\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"    }\"]\n],[\n   \"start\",\n  [\"invisible\",\"     /**\"]\n],[\n   \"start\",\n  [\"invisible\",\"     * EditSession.setUndoManager(undoManager)\"]\n],[\n   \"start\",\n  [\"invisible\",\"     * - undoManager (UndoManager): The new undo manager\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -556,7 +564,8 \"],\n  [\"constant\",\"@@\"],\n  [\"comment.doc.tag\",\" var EditSession = function(text, mode) {\"]\n],[\n   \"start\",\n  [\"invisible\",\"             type : type || \\\"line\\\",\"]\n],[\n   \"start\",\n  [\"invisible\",\"             renderer: typeof type == \\\"function\\\" ? type : null,\"]\n],[\n   \"start\",\n  [\"invisible\",\"             clazz : clazz,\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"            inFront: !!inFront\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"            inFront: !!inFront,\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"            id: id\"]\n],[\n   \"start\",\n  [\"invisible\",\"         }\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"invisible\",\"         if (inFront) {\"]\n],[\n   \"start\",\n  [\"variable\",\"diff\"],\n  [\"variable\",\" --git\"],\n  [\"keyword\",\" a/lib/ace/editor.js\"],\n  [\"variable\",\" b/lib/ace/editor.js\"]\n],[\n   \"start\",\n  [\"variable\",\"index 834e603..b27ec73 100644\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"---\"],\n  [\"meta.tag\",\" a/lib/ace/editor.js\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"+++\"],\n  [\"meta.tag\",\" b/lib/ace/editor.js\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -494,7 +494,7 \"],\n  [\"constant\",\"@@\"],\n  [\"comment.doc.tag\",\" var Editor = function(renderer, session) {\"]\n],[\n   \"start\",\n  [\"invisible\",\"      * Emitted when a selection has changed.\"]\n],[\n   \"start\",\n  [\"invisible\",\"      **/\"]\n],[\n   \"start\",\n  [\"invisible\",\"     this.onSelectionChange = function(e) {\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"        var session = this.getSession();\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"        var session = this.session;\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"invisible\",\"         if (session.$selectionMarker) {\"]\n],[\n   \"start\",\n  [\"invisible\",\"             session.removeMarker(session.$selectionMarker);\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -509,12 +509,40 \"],\n  [\"constant\",\"@@\"],\n  [\"comment.doc.tag\",\" var Editor = function(renderer, session) {\"]\n],[\n   \"start\",\n  [\"invisible\",\"             this.$updateHighlightActiveLine();\"]\n],[\n   \"start\",\n  [\"invisible\",\"         }\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"        var self = this;\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"        if (this.$highlightSelectedWord && !this.$wordHighlightTimer)\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"            this.$wordHighlightTimer = setTimeout(function() {\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"                self.session.$mode.highlightSelection(self);\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"                self.$wordHighlightTimer = null;\"]\n],[\n   \"start\",\n  [\"support.function\",\"-\"],\n  [\"string\",\"            }, 30, this);\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()\"]\n],[\n   \"start\",\n  [\"invisible\",\"     };\"]\n],[\n   \"start\",\n  [\"variable\",\"diff\"],\n  [\"variable\",\" --git\"],\n  [\"keyword\",\" a/lib/ace/search_highlight.js\"],\n  [\"variable\",\" b/lib/ace/search_highlight.js\"]\n],[\n   \"start\",\n  [\"invisible\",\"new file mode 100644\"]\n],[\n   \"start\",\n  [\"variable\",\"index 0000000..b2df779\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"---\"],\n  [\"meta.tag\",\" /dev/null\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"+++\"],\n  [\"meta.tag\",\" b/lib/ace/search_highlight.js\"]\n],[\n   \"start\",\n  [\"constant\",\"@@\"],\n  [\"constant.numeric\",\" -0,0 +1,3 \"],\n  [\"constant\",\"@@\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"new\"]\n],[\n   \"start\",\n  [\"support.constant\",\"+\"],\n  [\"text\",\"empty file\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_django.json",
    "content": "[[\n   \"start\",\n  [\"constant.language\",\"{%\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"extends\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"base.html\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language\",\"{%\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"title\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%}\"],\n  [\"text.xml\",\"Ace Django Template\"],\n  [\"constant.language\",\"{%\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language\",\"{%\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"content\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Hello, \"],\n  [\"constant.language\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"default:\"],\n  [\"string\",\"\\\"World\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"}}\"],\n  [\"text.xml\",\"!\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"constant.language\",\"{%\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"formatted\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"test-class-1 \"],\n  [\"constant.language\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"variable_class\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"}}\"],\n  [\"string.attribute-value.xml\",\" test-class-2\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"data-attribute\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"unformatted\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"comment.block\",\n  [\"comment.block\",\"{% comment %}\"]\n],[\n   \"comment.block\",\n  [\"comment.block\",\"    This content should be green.\"]\n],[\n   \"start\",\n  [\"comment.block\",\"{% endcomment %}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"comment.line\",\"{#line comment#}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_dot.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// Original source: http://www.graphviz.org/content/lion_share\"]\n],[\n   \"start\",\n  [\"comment\",\"##\\\"A few people in the field of genetics are using dot to draw \\\"marriage node diagram\\\"  pedigree drawings.  Here is one I have done of a test pedigree from the FTREE pedigree drawing package (Lion Share was a racehorse).\\\" Contributed by David Duffy.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"##Command to get the layout: \\\"dot -Tpng thisfile > thisfile.png\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"digraph\"],\n  [\"text\",\" Ped_Lion_Share           \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"comment\",\"# page = \\\"8.2677165,11.692913\\\" ;\"]\n],[\n   \"start\",\n  [\"variable\",\"ratio\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"auto\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"mincross \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2.0\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"variable\",\"label\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Pedigree Lion_Share\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"\\\"001\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"002\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"003\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"004\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"005\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"006\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"007\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"009\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"014\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"015\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"016\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"ZZ01\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"ZZ02\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"017\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"012\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"008\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"011\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"013\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"010\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"023\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"020\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"021\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"018\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"025\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"019\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"022\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"024\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"027\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"circle  \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"026\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"white   \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"028\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"box     \"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"regular\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"fillcolor\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"grey    \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0001\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"001\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0001\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"007\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0001\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0001\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"017\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0002\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"001\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0002\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"ZZ02\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0002\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0002\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"012\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0003\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"002\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0003\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"003\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0003\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0003\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"008\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0004\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"002\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0004\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"006\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0004\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0004\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"011\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0005\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"002\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0005\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"ZZ01\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0005\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0005\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"013\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0006\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"004\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0006\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"009\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0006\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0006\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"010\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0007\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"005\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0007\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"015\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0007\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0007\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"023\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0008\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"005\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0008\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"016\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0008\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0008\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"020\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0009\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"005\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0009\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"012\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0009\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0009\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"021\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0010\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"008\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0010\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"017\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0010\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0010\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"018\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0011\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"011\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0011\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"023\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0011\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0011\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"025\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0012\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"013\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0012\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"014\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0012\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0012\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"019\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0013\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"010\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0013\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"021\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0013\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0013\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"022\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0014\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"019\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0014\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"020\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0014\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0014\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"024\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0015\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"022\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0015\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"025\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0015\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0015\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"027\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0016\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"024\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0016\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"018\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0016\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0016\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"026\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0017\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"shape\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"diamond\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"style\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"filled\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"label\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"height\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"width\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\".\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"026\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0017\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"027\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"marr0017\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"marr0017\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"028\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable\",\"dir\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"none\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"weight\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_drools.json",
    "content": "[[\n   \"block.comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * Copyright 2010 JBoss Inc\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" *\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * you may not use this file except in compliance with the License.\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * You may obtain a copy of the License at\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" *\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" *      http://www.apache.org/licenses/LICENSE-2.0\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" *\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * Unless required by applicable law or agreed to in writing, software\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * See the License for the specific language governing permissions and\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" * limitations under the License.\"]\n],[\n   \"start\",\n  [\"comment.block\",\" */\"]\n],[\n   \"start\"\n],[\n   \"block.comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" Original source\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" https://github.com/droolsjbpm/drools/blob/master/drools-examples/\"]\n],[\n   \"block.comment\",\n  [\"comment.block\",\" http://docs.jboss.org/drools/\"]\n],[\n   \"start\",\n  [\"comment.block\",\"*/\"]\n],[\n   \"start\",\n  [\"keyword\",\"package\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"com.example.ace\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"java.math.BigDecimal\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"my.package.Foo.hello\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"declare\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"FactType\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"entity.name.type\",\"@author\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Bob\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.other\",\"id\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.other\",\"name\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"@maxLength\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"100\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"@notnull\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.other\",\"value\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"BigDecimal\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"declare\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"FactType2\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"AnotherType\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"declare\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"trait\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"TraitType\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"com.package.AnotherType\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"declare\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"trait\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"GoldenCustomer\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other\",\"balance\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"long\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"@Alias\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"org.acme.foo.accountBalance\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"global\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"org.slf4j.Logger\"],\n  [\"text\",\" \"],\n  [\"variable\",\"logger\"]\n],[\n   \"start\"\n],[\n   \"doc-start\",\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\"comment.doc.body\",\" * \"],\n  [\"comment.doc.tag\",\"@param\"],\n  [\"comment.doc.body\",\" name who we'll salute?\"]\n],[\n   \"start\",\n  [\"comment.doc.body\",\" \"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hello\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.class\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"name\"],\n  [\"keyword.operator\",\"+\"],\n  [\"string\",\"\\\"!\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"\\\"Trim all strings\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"dialect\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"java\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"no\"],\n  [\"keyword.operator\",\"-\"],\n  [\"keyword\",\"loop\"]\n],[\n   \"start\",\n  [\"keyword\",\"when\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// fdsfds\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.other\",\"$s\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"||\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"empty\\\"\"],\n  [\"text\",\", \"],\n  [\"variable.other\",\"$g\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Cheese\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"matches\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"(Buffalo)?\\\\\\\\S*Mozarella\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"CheeseCounter\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cheeses\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"contains\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$var\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// contains with a variable\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"CheeseCounter\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cheese\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"memberof\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$matureCheeses\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Cheese\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"soundslike\"],\n  [\"text\",\" \"],\n  [\"string\",\"'foobar'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Message\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"routingValue\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"str\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"startsWith\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"R1\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Cheese\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"stilton\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"cheddar\\\"\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"$cheese\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"Person\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"eval\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"age\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"girlAge\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"sex\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'M'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   [\"java-doc-start\",\"java-start\"],\n  [\"text\",\"  \"],\n  [\"comment.doc\",\"/**\"]\n],[\n   [\"java-doc-start\",\"java-start\"],\n  [\"comment.doc.body\",\"   * \"],\n  [\"comment.doc.tag.storage.type\",\"TODO\"],\n  [\"comment.doc.body\",\" There mus be better way\"]\n],[\n   \"java-start\",\n  [\"comment.doc.body\",\"   \"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"java-start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"retract\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$s\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"java-start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"fd\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"java-start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"toString\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"java-start\"\n],[\n   \"java-start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"insert\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$s\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"trim\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"query\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"isContainedIn\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"support.class\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Location\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"or\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Location\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"z\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"isContainedIn\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"z\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"\\\"go\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"salience\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"]\n],[\n   \"start\",\n  [\"keyword\",\"when\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other\",\"$s\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"System\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$s\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"\\\"When all English buses are not red\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"when\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"not\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"forall\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable.other\",\"$bus\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Bus\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"nationality\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"'english'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"Bus\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"this\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$bus\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"color\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'red'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// What if all english buses are not red?\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"\\\"go1\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"when\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.class\",\"String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"this\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"go1\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"isContainedIn\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Office\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"House\\\"\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"System\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"office is in the house\\\"\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"\\\"go2\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"when\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.class\",\"String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"this\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"go2\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"isContainedIn\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Draw\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"House\\\"\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"System\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Draw in the House\\\"\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"doc-start\",\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\"comment.doc.body\",\" * Go Right\"]\n],[\n   \"start\",\n  [\"comment.doc.body\",\" \"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"start\",\n  [\"keyword\",\"rule\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"GoRight\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"dialect\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"mvel\\\"\"],\n  [\"text\",\"  \"],\n  [\"keyword\",\"salience\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.class\",\"Math\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"abs\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"colDiff\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\"  \"],\n  [\"keyword\",\"when\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other\",\"$df\"],\n  [\"text\",\"   \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DirectionDiff\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"colDiff\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other\",\"$target\"],\n  [\"text\",\" \"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Cell\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"row\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"row\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"col\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"col\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"CellContents\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cell\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$target\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"cellType\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CellType\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"WALL\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Direction\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"character\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"fromChar\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"horizontal\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Direction\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"RIGHT\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"java-start\",\n  [\"keyword\",\"then\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"System\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"monster right\\\"\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"retract\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"java-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"insert\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"Direction\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$df\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"fromChar\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"Direction\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"RIGHT\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"Direction\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"NONE\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_edifact.json",
    "content": "[[\n   \"start\",\n  [\"entity.name.segment\",\"UNB\"],\n  [\"keyword.operator\",\"+\"],\n  [\"keyword\",\"UNOA\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"005435656\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"006415160\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"060515\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1434\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"00000000000778\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.header\",\"UNH\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"00000000000117\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"INVnrOIC\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"D\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"97\"],\n  [\"identifier\",\"B\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"UN\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"BGM\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"380\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"342459\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"9\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"DTM\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"3\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"20060515\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"102\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"RFF\"],\n  [\"keyword.operator\",\"+\"],\n  [\"keyword\",\"ON\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"521052\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"NAD\"],\n  [\"keyword.operator\",\"+\"],\n  [\"keyword\",\"BY\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"792820524\"],\n  [\"punctuation.operator\",\"::\"],\n  [\"text\",\"16\"],\n  [\"keyword.operator\",\"++\"],\n  [\"identifier\",\"CUMMINS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MID\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"RANGE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ENGINE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PLANT\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"NAD\"],\n  [\"keyword.operator\",\"+\"],\n  [\"keyword\",\"SE\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"005435656\"],\n  [\"punctuation.operator\",\"::\"],\n  [\"text\",\"16\"],\n  [\"keyword.operator\",\"++\"],\n  [\"identifier\",\"GENERAL\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"WIDGET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"COMPANY\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"CUX\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"1\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"USD\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"LIN\"],\n  [\"punctuation.operator\",\"+1+\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"157870\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"IN\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"IMD\"],\n  [\"punctuation.operator\",\"+F+\"],\n  [\"keyword.operator\",\"+\"],\n  [\"punctuation.operator\",\":::\"],\n  [\"identifier\",\"WIDGET\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"QTY\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"47\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1020\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"EA\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"ALI\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"US\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"MOA\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"203\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1202.58\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"PRI\"],\n  [\"keyword.operator\",\"+\"],\n  [\"entity.name.segment\",\"INV\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1.179\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"LIN\"],\n  [\"punctuation.operator\",\"+2+\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"157871\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"IN\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"IMD\"],\n  [\"punctuation.operator\",\"+F+\"],\n  [\"keyword.operator\",\"+\"],\n  [\"punctuation.operator\",\":::\"],\n  [\"identifier\",\"DIFFERENT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"WIDGET\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"QTY\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"47\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"20\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"EA\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"ALI\"],\n  [\"keyword.operator\",\"+\"],\n  [\"keyword\",\"JP\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"MOA\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"203\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"410\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"PRI\"],\n  [\"keyword.operator\",\"+\"],\n  [\"entity.name.segment\",\"INV\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"20.5\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"UNS\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"S\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"MOA\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"39\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"2137.58\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"ALC\"],\n  [\"punctuation.operator\",\"+C+\"],\n  [\"identifier\",\"ABG\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"MOA\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"8\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"525\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"UNT\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"23\"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\"00000000000117\"],\n  [\"punctuation.operator\",\"'\"]\n],[\n   \"start\",\n  [\"entity.name.segment\",\"UNZ\"],\n  [\"punctuation.operator\",\"+1+\"],\n  [\"text\",\"00000000000778\"],\n  [\"punctuation.operator\",\"'\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_eiffel.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"note\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"description\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"Represents a person.\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"entity.name.type\",\"PERSON\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"create\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"make\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"make_unknown\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"feature\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"entity.name.type\",\"NONE\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"comment.line.double-dash\",\"-- Creation\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"make\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"a_name\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"like\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"comment.line.double-dash\",\"-- Create a person with `a_name' as `name'.\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"do\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a_name\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"ensure\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a_name\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"make_unknown\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"do\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ensure\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"Void\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"feature\"],\n  [\"text\",\" \"],\n  [\"comment.line.double-dash\",\"-- Access\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"name\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"detachable\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"STRING\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"comment.line.double-dash\",\"-- Full name or Void if unknown.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ejs.json",
    "content": "[[\n   \"start\",\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"DOCTYPE\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Cloud9 Rocks!\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"table\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Name\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Size\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"markup.list.meta.tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword.operator\",\"!\"],\n  [\"identifier\",\"isRoot\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"..\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"..\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"markup.list.meta.tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"markup.list.meta.tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"entries\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"forEach\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"entry\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"span\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"glyphicon \"],\n  [\"markup.list.meta.tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"entry\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"mime\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"'directory'\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\"?\"],\n  [\"text\",\" \"],\n  [\"string\",\"'folder'\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"'file'\"],\n  [\"markup.list.meta.tag\",\"%>\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"span\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"markup.list.meta.tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"entry\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"markup.list.meta.tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"entry\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"markup.list.meta.tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"entry\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"markup.list.meta.tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"})\"],\n  [\"text\",\" \"],\n  [\"markup.list.meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_elixir.json",
    "content": "[[\n   \"start\",\n  [\"keyword.control.module.elixir\",\"defmodule\"],\n  [\"meta.module.elixir\",\" \"],\n  [\"entity.name.type.module.elixir\",\"HelloModule\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"do\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"text\",\"  \"],\n  [\"comment.documentation.heredoc\",\"@moduledoc \\\"\\\"\\\"\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    This is supposed to be `markdown`.\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    __Yes__ this is [mark](http://down.format)\"]\n],[\n   \"comment.documentation.heredoc\"\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    # Truly\"]\n],[\n   \"comment.documentation.heredoc\"\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    ## marked\"]\n],[\n   \"comment.documentation.heredoc\"\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    * with lists\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    * more\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    * and more\"]\n],[\n   \"comment.documentation.heredoc\"\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"        Even.with(code)\"]\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"        blocks |> with |> samples\"]\n],[\n   \"comment.documentation.heredoc\"\n],[\n   \"comment.documentation.heredoc\",\n  [\"comment.documentation.heredoc\",\"    _Docs are first class citizens in Elixir_ (Jose Valim)\"]\n],[\n   \"start\",\n  [\"comment.documentation.heredoc\",\"  \\\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.elixir\",\"#\"],\n  [\"comment.line.number-sign.elixir\",\" A \\\"Hello world\\\" function\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"def\"],\n  [\"text\",\" some_fun \"],\n  [\"keyword.control.elixir\",\"do\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other.constant.elixir\",\"IO\"],\n  [\"punctuation.separator.method.elixir\",\".\"],\n  [\"text\",\"puts \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"Juhu Kinners!\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"end\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.elixir\",\"#\"],\n  [\"comment.line.number-sign.elixir\",\" A private function\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"defp\"],\n  [\"text\",\" priv \"],\n  [\"keyword.control.elixir\",\"do\"]\n],[\n   \"punctuation.definition.string.begin.elixir7\",\n  [\"text\",\"    is_regex \"],\n  [\"punctuation.definition.string.begin.elixir\",\"~r\\\"\\\"\\\"\"]\n],[\n   \"punctuation.definition.string.begin.elixir7\",\n  [\"string.quoted.double.heredoc.elixir\",\"       This is a regex\"]\n],[\n   \"punctuation.definition.string.begin.elixir7\",\n  [\"string.quoted.double.heredoc.elixir\",\"       spanning several\"]\n],[\n   \"punctuation.definition.string.begin.elixir7\",\n  [\"string.quoted.double.heredoc.elixir\",\"       lines.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.elixir\",\"    \\\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    x \"],\n  [\"keyword.operator.assignment.elixir\",\"=\"],\n  [\"text\",\" elem\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"punctuation.section.scope.elixir\",\"{\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"a\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"b\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"c\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.elixir\",\"}\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.elixir\",\"0\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.elixir\",\"#\"],\n  [\"comment.line.number-sign.elixir\",\"=> :a\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"end\"]\n],[\n   \"start\",\n  [\"keyword.control.elixir\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"test_fun \"],\n  [\"keyword.operator.assignment.elixir\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"fn\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"text\",\"x\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.elixir\",\"-\"],\n  [\"keyword.operator.comparison.elixir\",\">\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"cond\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"do\"]\n],[\n   \"start\",\n  [\"text\",\"    x \"],\n  [\"keyword.operator.comparison.elixir\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.elixir\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.elixir\",\"-\"],\n  [\"keyword.operator.comparison.elixir\",\">\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"greater_than_ten\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.language.elixir\",\"true\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.elixir\",\"-\"],\n  [\"keyword.operator.comparison.elixir\",\">\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"maybe_ten\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.elixir\",\"end\"]\n],[\n   \"start\",\n  [\"keyword.control.elixir\",\"end\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_elm.json",
    "content": "[[\n   \"start\",\n  [\"comment.start\",\"{-\"],\n  [\"comment\",\" Ace \"],\n  [\"comment.start\",\"{-\"],\n  [\"comment\",\" 4 \"],\n  [\"comment.end\",\"-}\"],\n  [\"comment\",\" Elm \"],\n  [\"comment.end\",\"-}\"]\n],[\n   \"start\",\n  [\"constant.language\",\"main\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lift\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clock\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"every\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"second\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language\",\"clock\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"collage\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"400\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"400\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"filled\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"lightGrey\"],\n  [\"text\",\"   \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"ngon\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"110\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                          \"],\n  [\"operator.punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"outlined\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"solid\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"grey\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"ngon\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"110\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                          \"],\n  [\"operator.punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hand\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"orange\"],\n  [\"text\",\"   \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"t\"]\n],[\n   \"start\",\n  [\"text\",\"                          \"],\n  [\"operator.punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hand\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"charcoal\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"                          \"],\n  [\"operator.punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hand\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"charcoal\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"60\"],\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric\",\"720\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language\",\"hand\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clr\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"len\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"time\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"angle\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"degrees\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"90\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"6\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"inSeconds\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"time\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"traced\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"solid\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clr\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"segment\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"operator.punctuation\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"len\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cos\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"angle\"],\n  [\"operator.punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"len\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sin\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"angle\"],\n  [\"paren.rparen\",\")\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_erlang.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.erlang\",\"%% A process whose only job is to keep a counter.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.erlang\",\"%% First version\"]\n],[\n   \"start\",\n  [\"meta.directive.module.erlang\",\"  \"],\n  [\"punctuation.section.directive.begin.erlang\",\"-\"],\n  [\"keyword.control.directive.module.erlang\",\"module\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"entity.name.type.class.module.definition.erlang\",\"counter\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.section.directive.end.erlang\",\".\"]\n],[\n   \"start\",\n  [\"meta.directive.export.erlang\",\"  \"],\n  [\"punctuation.section.directive.begin.erlang\",\"-\"],\n  [\"keyword.control.directive.export.erlang\",\"export\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"punctuation.definition.list.begin.erlang\",\"[\"],\n  [\"entity.name.function.erlang\",\"start\"],\n  [\"punctuation.separator.function-arity.erlang\",\"/\"],\n  [\"constant.numeric.integer.decimal.erlang\",\"0\"],\n  [\"punctuation.separator.list.erlang\",\",\"],\n  [\"meta.structure.list.function.erlang\",\" \"],\n  [\"entity.name.function.erlang\",\"codeswitch\"],\n  [\"punctuation.separator.function-arity.erlang\",\"/\"],\n  [\"constant.numeric.integer.decimal.erlang\",\"1\"],\n  [\"punctuation.definition.list.end.erlang\",\"]\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.section.directive.end.erlang\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"meta.function.erlang\",\"  \"],\n  [\"entity.name.function.definition.erlang\",\"start\"],\n  [\"punctuation.section.expression.begin.erlang\",\"(\"],\n  [\"punctuation.section.expression.end.erlang\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.erlang\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.erlang\",\"loop\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"constant.numeric.integer.decimal.erlang\",\"0\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.terminator.function.erlang\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   [\"text6\",\"meta.function.erlang\"],\n  [\"meta.function.erlang\",\"  \"],\n  [\"entity.name.function.definition.erlang\",\"loop\"],\n  [\"punctuation.section.expression.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.section.expression.end.erlang\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.erlang\",\"->\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"text\",\"    \"],\n  [\"keyword.control.receive.erlang\",\"receive\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"       \"],\n  [\"punctuation.definition.tuple.begin.erlang\",\"{\"],\n  [\"constant.other.symbol.unquoted.erlang\",\"increment\"],\n  [\"punctuation.separator.tuple.erlang\",\",\"],\n  [\"meta.structure.tuple.erlang\",\" \"],\n  [\"variable.other.erlang\",\"Count\"],\n  [\"punctuation.definition.tuple.end.erlang\",\"}\"],\n  [\"meta.expression.receive.erlang\",\" \"],\n  [\"punctuation.separator.clause-head-body.erlang\",\"->\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"          \"],\n  [\"entity.name.function.erlang\",\"loop\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"keyword.operator.symbolic.erlang\",\"+\"],\n  [\"variable.other.erlang\",\"Count\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.separator.clauses.erlang\",\";\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"       \"],\n  [\"punctuation.definition.tuple.begin.erlang\",\"{\"],\n  [\"constant.other.symbol.unquoted.erlang\",\"counter\"],\n  [\"punctuation.separator.tuple.erlang\",\",\"],\n  [\"meta.structure.tuple.erlang\",\" \"],\n  [\"variable.other.erlang\",\"Pid\"],\n  [\"punctuation.definition.tuple.end.erlang\",\"}\"],\n  [\"meta.expression.receive.erlang\",\" \"],\n  [\"punctuation.separator.clause-head-body.erlang\",\"->\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"          \"],\n  [\"variable.other.erlang\",\"Pid\"],\n  [\"meta.expression.receive.erlang\",\" \"],\n  [\"keyword.operator.symbolic.erlang\",\"!\"],\n  [\"meta.expression.receive.erlang\",\" \"],\n  [\"punctuation.definition.tuple.begin.erlang\",\"{\"],\n  [\"constant.other.symbol.unquoted.erlang\",\"counter\"],\n  [\"punctuation.separator.tuple.erlang\",\",\"],\n  [\"meta.structure.tuple.erlang\",\" \"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.definition.tuple.end.erlang\",\"}\"],\n  [\"punctuation.separator.expressions.erlang\",\",\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"          \"],\n  [\"entity.name.function.erlang\",\"loop\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.separator.clauses.erlang\",\";\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"       \"],\n  [\"constant.other.symbol.unquoted.erlang\",\"code_switch\"],\n  [\"meta.expression.receive.erlang\",\" \"],\n  [\"punctuation.separator.clause-head-body.erlang\",\"->\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"          \"],\n  [\"keyword.operator.macro.erlang\",\"?\"],\n  [\"entity.name.function.macro.erlang\",\"MODULE\"],\n  [\"meta.expression.receive.erlang\",\":\"],\n  [\"entity.name.function.erlang\",\"codeswitch\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"]\n],[\n   [\"keyword.control.receive.erlang\",\"text6\",\"text6\",\"meta.function.erlang\"],\n  [\"meta.expression.receive.erlang\",\"          \"],\n  [\"punctuation.definition.comment.erlang\",\"% Force the use of 'codeswitch/1' from the latest MODULE version\"]\n],[\n   \"start\",\n  [\"meta.expression.receive.erlang\",\"    \"],\n  [\"keyword.control.end.erlang\",\"end\"],\n  [\"punctuation.terminator.function.erlang\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"meta.function.erlang\",\"  \"],\n  [\"entity.name.function.definition.erlang\",\"codeswitch\"],\n  [\"punctuation.section.expression.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.section.expression.end.erlang\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.erlang\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.erlang\",\"loop\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"variable.other.erlang\",\"Sum\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"punctuation.terminator.function.erlang\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.erlang\",\"% Print the data using the pretty print specifier\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"entity.name.type.class.module.erlang\",\"io\"],\n  [\"punctuation.separator.module-function.erlang\",\":\"],\n  [\"entity.name.function.erlang\",\"format\"],\n  [\"punctuation.definition.parameters.begin.erlang\",\"(\"],\n  [\"punctuation.definition.string.begin.erlang\",\"\\\"\"],\n  [\"string.quoted.double.erlang\",\"Here is the data: \"],\n  [\"punctuation.definition.erlang\",\"~\"],\n  [\"constant.other.erlang\",\"p\"],\n  [\"punctuation.definition.erlang\",\"~\"],\n  [\"constant.other.erlang\",\"n\"],\n  [\"punctuation.definition.string.end.erlang\",\"\\\"\"],\n  [\"punctuation.separator.parameters.erlang\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.list.begin.erlang\",\"[\"],\n  [\"variable.other.erlang\",\"Data\"],\n  [\"punctuation.definition.list.end.erlang\",\"]\"],\n  [\"punctuation.definition.parameters.end.erlang\",\")\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_flix.json",
    "content": "[[\n   \"start\",\n  [\"comment.line\",\"/// Mooo's `n` times on channel `c`.\"]\n],[\n   \"start\",\n  [\"storage.type\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"mooo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Sender\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.type\",\"String\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"r\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Int32\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Unit\"],\n  [\"text\",\" \\\\ \"],\n  [\"identifier\",\"IO\"],\n  [\"text\",\" =\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"match\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"send\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Mooo!\\\"\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"tx\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"mooo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" - \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"/// Meow's `n` times on channel `c`.\"]\n],[\n   \"start\",\n  [\"storage.type\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"meow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Sender\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.type\",\"String\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"r\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Int32\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Unit\"],\n  [\"text\",\" \\\\ \"],\n  [\"identifier\",\"IO\"],\n  [\"text\",\" =\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"match\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"send\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Meow!\\\"\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"tx\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"meow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" - \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"/// Hiss'es `n` times on channel `c`.\"]\n],[\n   \"start\",\n  [\"storage.type\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hiss\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Sender\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.type\",\"String\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"r\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Int32\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Unit\"],\n  [\"text\",\" \\\\ \"],\n  [\"identifier\",\"IO\"],\n  [\"text\",\" =\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"match\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"send\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Hiss!\\\"\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"tx\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"hiss\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" - \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"/// Start the animal farm...\"]\n],[\n   \"start\",\n  [\"storage.type\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"Unit\"],\n  [\"text\",\" \\\\ \"],\n  [\"identifier\",\"IO\"],\n  [\"text\",\" = \"],\n  [\"keyword\",\"region\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx1\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"rx1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" = \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"buffered\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx2\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"rx2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" = \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"buffered\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx3\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"rx3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" = \"],\n  [\"identifier\",\"Channel\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"buffered\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"spawn\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"mooo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" @ \"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"spawn\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"meow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx2\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" @ \"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"spawn\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hiss\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tx3\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"7\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" @ \"],\n  [\"identifier\",\"rc\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"select\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"recv\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rx1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" |> \"],\n  [\"identifier\",\"println\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"recv\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rx2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" |> \"],\n  [\"identifier\",\"println\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"recv\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rx3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" |> \"],\n  [\"identifier\",\"println\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_forth.json",
    "content": "[[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"HELLO\"],\n  [\"meta.block.forth\",\" \"],\n  [\"comment.line.parentheses.forth\",\" ( -- )\"],\n  [\"meta.block.forth\",\"  CR \"],\n  [\"string.quoted.double.forth\",\".\\\" Hello, world!\\\"\"],\n  [\"meta.block.forth\",\" \"],\n  [\"keyword.other.compile-only.forth\",\";\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"HELLO <cr>\"]\n],[\n   \"start\",\n  [\"text\",\"Hello, world!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"[CHAR]\"],\n  [\"meta.block.forth\",\"  \"],\n  [\"keyword.other.non-immediate.forth\",\" CHAR\"],\n  [\"meta.block.forth\",\" \"],\n  [\"keyword.other.compile-only.forth\",\" POSTPONE\"],\n  [\"meta.block.forth\",\" LITERAL \"],\n  [\"keyword.other.compile-only.forth\",\";\"],\n  [\"keyword.other.immediate.forth\",\" IMMEDIATE\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.numeric.forth\",\"0\"],\n  [\"storage.type.forth\",\" value\"],\n  [\"text\",\" ii       \"],\n  [\"constant.numeric.forth\",\" 0\"],\n  [\"storage.type.forth\",\" value\"],\n  [\"text\",\" jj\"]\n],[\n   \"start\",\n  [\"constant.numeric.forth\",\"0\"],\n  [\"storage.type.forth\",\" value\"],\n  [\"text\",\" KeyAddr  \"],\n  [\"constant.numeric.forth\",\" 0\"],\n  [\"storage.type.forth\",\" value\"],\n  [\"text\",\" KeyLen\"]\n],[\n   \"start\",\n  [\"storage.type.forth\",\"create\"],\n  [\"text\",\" SArray  \"],\n  [\"constant.numeric.forth\",\" 256\"],\n  [\"text\",\" allot  \"],\n  [\"comment.line.backslash.forth\",\" \\\\ state array of 256 bytes\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"KeyArray\"],\n  [\"meta.block.forth\",\"      KeyLen mod   KeyAddr \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"get_byte\"],\n  [\"meta.block.forth\",\"      + c@ \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"set_byte\"],\n  [\"meta.block.forth\",\"      + c! \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"as_byte\"],\n  [\"meta.block.forth\",\"      \"],\n  [\"constant.numeric.forth\",\" 255\"],\n  [\"meta.block.forth\",\" and \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"reset_ij\"],\n  [\"meta.block.forth\",\"     \"],\n  [\"constant.numeric.forth\",\" 0\"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" ii  \"],\n  [\"constant.numeric.forth\",\" 0\"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" jj \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"i_update\"],\n  [\"meta.block.forth\",\"     \"],\n  [\"constant.numeric.forth\",\" 1\"],\n  [\"meta.block.forth\",\" +   as_byte\"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" ii \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"j_update\"],\n  [\"meta.block.forth\",\"      ii SArray get_byte +   as_byte\"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" jj \"],\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"swap_s_ij\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    jj SArray get_byte\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"       ii SArray get_byte  jj SArray set_byte\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    ii SArray set_byte\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"start\"\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"rc4_init\"],\n  [\"comment.line.parentheses.forth\",\" ( KeyAddr KeyLen -- )\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"   \"],\n  [\"constant.numeric.forth\",\" 256\"],\n  [\"meta.block.forth\",\" min\"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" KeyLen  \"],\n  [\"keyword.other.immediate.forth\",\" TO\"],\n  [\"meta.block.forth\",\" KeyAddr\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"   \"],\n  [\"constant.numeric.forth\",\" 256 0\"],\n  [\"keyword.control.compile-only.forth\",\" DO\"],\n  [\"meta.block.forth\",\"   \"],\n  [\"variable.language.forth\",\"i\"],\n  [\"meta.block.forth\",\" \"],\n  [\"variable.language.forth\",\"i\"],\n  [\"meta.block.forth\",\" SArray set_byte  \"],\n  [\"keyword.control.compile-only.forth\",\" LOOP\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    reset_ij\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"   \"],\n  [\"keyword.control.compile-only.forth\",\" BEGIN\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"        ii KeyArray get_byte   jj +  j_update\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"        swap_s_ij\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"        ii\"],\n  [\"constant.numeric.forth\",\" 255\"],\n  [\"meta.block.forth\",\" <\"],\n  [\"keyword.control.compile-only.forth\",\" WHILE\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"        ii i_update\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"   \"],\n  [\"keyword.control.compile-only.forth\",\" REPEAT\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    reset_ij\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\";\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"keyword.other.compile-only.forth\",\":\"],\n  [\"meta.block.forth\",\" \"],\n  [\"entity.name.function.forth\",\"rc4_byte\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    ii i_update   jj j_update\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    swap_s_ij\"]\n],[\n   \"keyword.other.compile-only.forth\",\n  [\"meta.block.forth\",\"    ii SArray get_byte   jj SArray get_byte +   as_byte SArray get_byte  xor\"]\n],[\n   \"start\",\n  [\"keyword.other.compile-only.forth\",\";\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_fortran.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"#include\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"globalDefines.h\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"!=========================================================\"]\n],[\n   \"start\",\n  [\"keyword\",\"program\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"]\n],[\n   \"start\",\n  [\"comment\",\"!========================================================= \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"params_module\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"only\"],\n  [\"text\",\" : \"],\n  [\"identifier\",\"nx\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"ny\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"nz\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"implicit\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"none\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"integer\"],\n  [\"text\",\", \"],\n  [\"storage.modifier\",\"parameter\"],\n  [\"text\",\" :: \"],\n  [\"identifier\",\"g\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"9.81\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"real\"],\n  [\"text\",\", \"],\n  [\"storage.modifier\",\"allocatable\"],\n  [\"text\",\", \"],\n  [\"storage.modifier\",\"dimension\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\":,:,:\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" :: \"],\n  [\"identifier\",\"array\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"integer\"],\n  [\"text\",\" :: \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"b\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"c\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"real\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"8\"],\n  [\"text\",\" :: \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"z\"]\n],[\n   \"start\",\n  [\"text\",\"      \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"b\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"c\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#ifdef\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ARRAY_COMP\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"allocate\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"array\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"status\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"a\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"write\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"c\"],\n  [\"text\",\",\"],\n  [\"string\",\"'(i5.5)'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\".\"],\n  [\"keyword.operator\",\"lt\"],\n  [\"constant.numeric\",\".5.0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"array\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\":,:,:\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"g\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"array\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\":,:,:\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"]\n],[\n   \"start\",\n  [\"comment\",\"!========================================================    \"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"program\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"]\n],[\n   \"start\",\n  [\"comment\",\"!========================================================\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_fsharp.json",
    "content": "[[\n   \"start\",\n  [\"comment.start\",\"(*\"],\n  [\"comment\",\" fsharp \"],\n  [\"comment.start\",\"(*\"],\n  [\"comment\",\" example \"],\n  [\"comment.end\",\"*)\"],\n  [\"comment\",\" \"],\n  [\"comment.end\",\"*)\"]\n],[\n   \"start\",\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Test\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"func1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"constant.integer\",\"100\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"x\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.integer\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"list\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.integer\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.integer\",\"42\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" :: \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.integer\",\"0\"],\n  [\"text\",\" .. \"],\n  [\"constant.integer\",\"99\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"func1\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"verbatim\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"verbatim.string\",\"@\"],\n  [\"string\",\"\\\"\"],\n  [\"string\",\"c:\\\\Program \"],\n  [\"constant.language.escape\",\"\\\"\\\"\"],\n  [\"string\",\" Files\\\\\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"trippleQuote\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\\\" \\\"hello world\\\" \\\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// print\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"printfn\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"The table of squares from 0 to 99 is:\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"%A\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"list\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_fsl.json",
    "content": "[[\n   \"start\",\n  [\"constant.language.fslLanguage\",\"machine_name      :\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.fslLabel.doublequoted\",\"\\\"BGP\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"constant.language.fslLanguage\",\"machine_version   :\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.0.0\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language.fslLanguage\",\"machine_author    :\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.fslLabel.doublequoted\",\"\\\"John Haugeland <stonecypher@gmail.com>\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"constant.language.fslLanguage\",\"machine_license   :\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"MIT\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language.fslLanguage\",\"graph_layout      :\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"dot\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Idle\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Invite'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Invite, 1xx'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'3xx'\"],\n  [\"text\",\"         \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Redirecting\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Cancel'\"],\n  [\"text\",\"      \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Cancelling\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'200'\"],\n  [\"text\",\"         \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Accepted\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'407'\"],\n  [\"text\",\"         \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"AuthRequested\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'4xx-6xx'\"],\n  [\"text\",\"     \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Failed\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"AuthRequested\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Redirecting\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Act'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Redirected\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Cancelling\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'200 (Invite)'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"LateCancel\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Cancelling\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'200 (Cancel)'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Cancelled\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Accepted\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Cancel'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"LateCancel\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Accepted\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\"    \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Failed\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Terminated\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Redirected\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Invite'\"],\n  [\"text\",\"  \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Invited\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Redirected\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Timeout'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Terminated\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"LateCancel\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Cancelled\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'487'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Failed\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Invite'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModifying\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Bye'\"],\n  [\"text\",\"    \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Closing\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModifying\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'488'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModificationRefused\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModifying\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'200'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModified\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Closing\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Bye,Ack,200 (Invite)'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Closing\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"Closing\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'200 (Bye)'\"],\n  [\"text\",\"            \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Terminated\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModificationRefused\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModified\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Ack'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Established\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.fslLabel.atom\",\"SessionModified\"],\n  [\"text\",\" \"],\n  [\"constant.character.fslAction\",\"'Bye'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.fslArrow\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.fslLabel.atom\",\"Closing\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ftl.json",
    "content": "[[\n   \"start\",\n  [\"keyword.function\",\"<#ftl\"],\n  [\"text\",\" \"],\n  [\"entity.other.attribute-name\",\"encoding\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"utf-8\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"/>\"]\n],[\n   \"start\",\n  [\"keyword.function\",\"<#setting\"],\n  [\"text\",\" \"],\n  [\"entity.other.attribute-name\",\"locale\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"en_US\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"/>\"]\n],[\n   \"start\",\n  [\"keyword.function\",\"<#import\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"library\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"as\"],\n  [\"text\",\" \"],\n  [\"variable\",\"lib\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"/>\"]\n],[\n   \"ftl-dcomment\",\n  [\"comment\",\"<#--\"]\n],[\n   \"ftl-dcomment\",\n  [\"comment\",\"    FreeMarker comment\"]\n],[\n   \"ftl-dcomment\",\n  [\"comment\",\"    ${abc} <#assign a=12 />\"]\n],[\n   \"start\",\n  [\"comment\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"DOCTYPE\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"lang\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"en-us\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"meta\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"charset\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"utf-8\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\"!\"],\n  [\"string\",\"\\\"FreeMarker\\\"\"],\n  [\"string.interpolated\",\"}\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Hello \"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"name\"],\n  [\"keyword.operator\",\"!\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"string.interpolated\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Today is: \"],\n  [\"string.interpolated\",\"${\"],\n  [\"language.variable\",\".now\"],\n  [\"support.function\",\"?date\"],\n  [\"string.interpolated\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"<#assign\"],\n  [\"text\",\" \"],\n  [\"variable\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"13\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"<#if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"x\"],\n  [\"text\",\" \"],\n  [\"constant.character.entity\",\"&gt;\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"variable\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"lt\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"14\"],\n  [\"keyword\",\">\"],\n  [\"text.xml\",\"x equals 13: \"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"x\"],\n  [\"string.interpolated\",\"}\"],\n  [\"keyword.function\",\"</#if\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"keyword.function\",\"<#list\"],\n  [\"text\",\" \"],\n  [\"variable\",\"items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"as\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"item_index\"],\n  [\"string.interpolated\",\"}\"],\n  [\"text.xml\",\": \"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"item.name\"],\n  [\"keyword.operator\",\"!\"],\n  [\"support.function\",\"?split\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\"],\n  [\"constant.character.escape\",\"\\\\n\"],\n  [\"string\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\"]\"],\n  [\"string.interpolated\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"keyword.function\",\"</#list\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        User directive: \"],\n  [\"keyword.other\",\"<@lib.function\"],\n  [\"text\",\" \"],\n  [\"variable\",\"attr1\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.language\",\"true\"],\n  [\"text\",\" \"],\n  [\"variable\",\"attr2\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"'value'\"],\n  [\"text\",\" \"],\n  [\"variable\",\"attr3\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"-42.12\"],\n  [\"keyword\",\">\"],\n  [\"text.xml\",\"Test\"],\n  [\"keyword.other\",\"</@lib.function\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.other\",\"<@anotherOne\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"<#if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"variable\"],\n  [\"support.function.deprecated\",\"?exists\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            Deprecated\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"<#elseif\"],\n  [\"text\",\" \"],\n  [\"variable\",\"variable\"],\n  [\"support.function\",\"??\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            Better\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"<#else\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            Default\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"keyword.function\",\"</#if\"],\n  [\"keyword\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.image.tag-name.xml\",\"img\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"src\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"images/\"],\n  [\"string.interpolated\",\"${\"],\n  [\"variable\",\"user.id\"],\n  [\"string.interpolated\",\"}\"],\n  [\"string.attribute-value.xml\",\".png\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_gcode.json",
    "content": "[[\n   \"start\",\n  [\"identifier\",\"O\"],\n  [\"constant.numeric\",\"003\"],\n  [\"text\",\" \"],\n  [\"comment\",\"(DIAMOND SQUARE)\"]\n],[\n   \"start\",\n  [\"comment\",\"N2\"],\n  [\"text\",\" \"],\n  [\"string\",\"G54\"],\n  [\"text\",\" \"],\n  [\"string\",\"G90\"],\n  [\"text\",\" \"],\n  [\"string\",\"G49\"],\n  [\"text\",\" \"],\n  [\"string\",\"G80\"]\n],[\n   \"start\",\n  [\"comment\",\"N3\"],\n  [\"text\",\" \"],\n  [\"string\",\"M6\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"T\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"comment\",\"(1.ENDMILL)\"]\n],[\n   \"start\",\n  [\"comment\",\"N4\"],\n  [\"text\",\" \"],\n  [\"string\",\"M3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"S\"],\n  [\"constant.numeric\",\"1800\"]\n],[\n   \"start\",\n  [\"comment\",\"N5\"],\n  [\"text\",\" \"],\n  [\"string\",\"G0\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"-.6\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"2.050\"]\n],[\n   \"start\",\n  [\"comment\",\"N6\"],\n  [\"text\",\" \"],\n  [\"string\",\"G43\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"H\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"  \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\".1\"]\n],[\n   \"start\",\n  [\"comment\",\"N7\"],\n  [\"text\",\" \"],\n  [\"string\",\"G1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\"-.3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"F\"],\n  [\"constant.numeric\",\"50.\"]\n],[\n   \"start\",\n  [\"comment\",\"N8\"],\n  [\"text\",\" \"],\n  [\"string\",\"G41\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"D\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"1.45\"]\n],[\n   \"start\",\n  [\"comment\",\"N9\"],\n  [\"text\",\" \"],\n  [\"string\",\"G1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"F\"],\n  [\"constant.numeric\",\"20.\"]\n],[\n   \"start\",\n  [\"comment\",\"N10\"],\n  [\"text\",\" \"],\n  [\"string\",\"G2\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"J\"],\n  [\"constant.numeric\",\"-1.45\"]\n],[\n   \"start\",\n  [\"comment\",\"(CUTTER COMP CANCEL)\"]\n],[\n   \"start\",\n  [\"comment\",\"N11\"],\n  [\"text\",\" \"],\n  [\"string\",\"G1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\"-.2\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"F\"],\n  [\"constant.numeric\",\"50.\"]\n],[\n   \"start\",\n  [\"comment\",\"N12\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"-.990\"]\n],[\n   \"start\",\n  [\"comment\",\"N13\"],\n  [\"text\",\" \"],\n  [\"string\",\"G40\"]\n],[\n   \"start\",\n  [\"comment\",\"N14\"],\n  [\"text\",\" \"],\n  [\"string\",\"G0\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"-.6\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"1.590\"]\n],[\n   \"start\",\n  [\"comment\",\"N15\"],\n  [\"text\",\" \"],\n  [\"string\",\"G0\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\".1\"]\n],[\n   \"start\",\n  [\"comment\",\"N16\"],\n  [\"text\",\" \"],\n  [\"string\",\"M5\"],\n  [\"text\",\" \"],\n  [\"string\",\"G49\"],\n  [\"text\",\" \"],\n  [\"string\",\"G28\"],\n  [\"text\",\" \"],\n  [\"string\",\"G91\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"comment\",\"N17\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CALL\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"O\"],\n  [\"constant.numeric\",\"9456\"]\n],[\n   \"start\",\n  [\"comment\",\"N18\"],\n  [\"text\",\" #\"],\n  [\"constant.numeric\",\"500\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"0.004\"]\n],[\n   \"start\",\n  [\"comment\",\"N19\"],\n  [\"text\",\" #\"],\n  [\"constant.numeric\",\"503\"],\n  [\"text\",\"=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"500\"],\n  [\"text\",\"+#\"],\n  [\"constant.numeric\",\"501\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"comment\",\"N20\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"VC\"],\n  [\"constant.numeric\",\"45\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"0.0006\"]\n],[\n   \"start\",\n  [\"identifier\",\"VS\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"0.0007\"]\n],[\n   \"start\",\n  [\"comment\",\"N21\"],\n  [\"text\",\" \"],\n  [\"string\",\"G90\"],\n  [\"text\",\" \"],\n  [\"string\",\"G10\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"L\"],\n  [\"constant.numeric\",\"20\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"P\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"5.\"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"4.\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Z\"],\n  [\"constant.numeric\",\"6.567\"]\n],[\n   \"start\",\n  [\"comment\",\"N22\"],\n  [\"text\",\" \"],\n  [\"string\",\"G0\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"5000\"]\n],[\n   \"start\",\n  [\"comment\",\"N23\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IF\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\"#\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.370\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"GOTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"49\"]\n],[\n   \"start\",\n  [\"comment\",\"N24\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"-0.678\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Y\"],\n  [\"constant.numeric\",\"+.990\"]\n],[\n   \"start\",\n  [\"comment\",\"N25\"],\n  [\"text\",\" \"],\n  [\"string\",\"G84.3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"X\"],\n  [\"constant.numeric\",\"-0.1\"]\n],[\n   \"start\",\n  [\"comment\",\"N26\"],\n  [\"text\",\" #\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\"=#\"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\"*\"],\n  [\"identifier\",\"COS\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"45\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"comment\",\"N27\"],\n  [\"text\",\" #\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\"=#\"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\"*\"],\n  [\"identifier\",\"SIN\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"45\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"comment\",\"N28\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"VZOFZ\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"652.9658\"]\n],[\n   \"start\",\n  [\"text\",\"%\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_gherkin.json",
    "content": "[[\n   \"start\",\n  [\"variable.parameter\",\"@these\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"@_are_\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"@tags\"]\n],[\n   \"start\",\n  [\"keyword\",\"Feature:\"],\n  [\"text\",\" Serve coffee\"]\n],[\n   \"start\",\n  [\"text\",\"  Coffee should not be served until paid for\"]\n],[\n   \"start\",\n  [\"text\",\"  Coffee should not be served until the button has been pressed\"]\n],[\n   \"start\",\n  [\"text\",\"  If there is no coffee left then money should be refunded\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Scenario Outline:\"],\n  [\"text\",\" Eating\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Given\"],\n  [\"text\",\" there are \"],\n  [\"comment\",\"<start>\"],\n  [\"text\",\" cucumbers\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"When\"],\n  [\"text\",\" I eat \"],\n  [\"comment\",\"<eat>\"],\n  [\"text\",\" cucumbers\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Then\"],\n  [\"text\",\" I should have \"],\n  [\"comment\",\"<left>\"],\n  [\"text\",\" cucumbers\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Examples:\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"|\"],\n  [\"string\",\" start \"],\n  [\"comment\",\"|\"],\n  [\"string\",\" eat \"],\n  [\"comment\",\"|\"],\n  [\"string\",\" left \"],\n  [\"comment\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  12   \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  5  \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  7   \"],\n  [\"comment\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  @20  \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  5  \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"  15  \"],\n  [\"comment\",\"|\"],\n  [\"string\",\"    \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Scenario:\"],\n  [\"text\",\" Buy last coffee\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Given\"],\n  [\"text\",\" there are \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" coffees left in the machine\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"And\"],\n  [\"text\",\" I have deposited \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"$ \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"When\"],\n  [\"text\",\" I press the coffee button\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Then\"],\n  [\"text\",\" I should be served a \"],\n  [\"string\",\"\\\"coffee\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"# this a comment\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"qqstring3\",\n  [\"text\",\"  \"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"qqstring3\",\n  [\"string\",\"  this is a \"]\n],[\n   \"qqstring3\",\n  [\"string\",\"  pystring\"]\n],[\n   \"start\",\n  [\"string\",\"  \\\"\\\"\\\"\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_gitignore.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# A sample .gitignore file.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\".buildlog\"]\n],[\n   \"start\",\n  [\"text\",\".DS_Store\"]\n],[\n   \"start\",\n  [\"text\",\".svn\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Negated patterns:\"]\n],[\n   \"start\",\n  [\"keyword\",\"!foo.bar\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Also ignore user settings...\"]\n],[\n   \"start\",\n  [\"text\",\"/.settings\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_glsl.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"uniform\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"float\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"amplitude\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"attribute\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"float\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"displacement\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"varying\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"vec3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"vNormal\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"void\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"vNormal\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"normal\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// multiply our displacement by the\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// amplitude. The amp will get animated\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// so we'll have animated displacement\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"vec3\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"newPosition\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"position\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                       \"],\n  [\"identifier\",\"normal\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                       \"],\n  [\"keyword\",\"vec3\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"displacement\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"]\n],[\n   \"start\",\n  [\"text\",\"                            \"],\n  [\"identifier\",\"amplitude\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.language\",\"gl_Position\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"projectionMatrix\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"]\n],[\n   \"start\",\n  [\"text\",\"                  \"],\n  [\"identifier\",\"modelViewMatrix\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"]\n],[\n   \"start\",\n  [\"text\",\"                  \"],\n  [\"keyword\",\"vec4\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"newPosition\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"1.0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_gobstones.json",
    "content": "[[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\"/*\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\" * A Gobstones implementation of Conwey's Game of Life\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\" * that tries to use most of Gobstones syntax.\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\" *\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\" * Check out more about Gobstones at http://gobstones.org\"]\n],[\n   \"start\",\n  [\"comment.block.dash-asterisc.gobstones\",\" */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"--         HELPERS TO MOVE AROUND ALL THE BOARD          --\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.gobstones\",\"// This helpers allow the user to move around the board\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.gobstones\",\"// one cell at a time\"]\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"GoToStartOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"IrAlBorde\"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"opuesto\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"IrAlBorde\"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"opuesto\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"isEndOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator.boolean.gobstones\",\"not\"],\n  [\"text\",\" \"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"not\"],\n  [\"text\",\" \"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"NextCellOfTheBoard\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.gobstones\",\"Mover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"else\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.gobstones\",\"IrAlBorde\"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"opuesto\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstDir\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.gobstones\",\"Mover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"secondDir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"--                   TYPE DECLARATIONS                   --\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.gobstones\",\"// The cell type declarations\"]\n],[\n   \"start\",\n  [\"storage.type.types.gobstones\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"CellStatus\"],\n  [\"text\",\" \"],\n  [\"storage.type.types.gobstones\",\"is\"],\n  [\"text\",\" \"],\n  [\"storage.type.types.gobstones\",\"variant\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.types.gobstones\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"Alive\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.types.gobstones\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"Dead\"],\n  [\"text\",\"  \"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.types.gobstones\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"Cell\"],\n  [\"text\",\" \"],\n  [\"storage.type.types.gobstones\",\"is\"],\n  [\"text\",\" \"],\n  [\"storage.type.types.gobstones\",\"record\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.types.gobstones\",\"field\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"status\"],\n  [\"text\",\"  \"],\n  [\"comment.line.number-sign.gobstones\",\"# CellStatus\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.types.gobstones\",\"field\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"color\"],\n  [\"text\",\"   \"],\n  [\"comment.line.number-sign.gobstones\",\"# Color\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"--                  PROGRAM DEFINITION                   --\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"interactive\"],\n  [\"text\",\" \"],\n  [\"storage.type.definitions.gobstones\",\"program\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment.line.number-sign.gobstones\",\"# Map key press to actions\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language.gobstones\",\"K_UP\"],\n  [\"text\",\"     \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"PrepareNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language.gobstones\",\"K_RIGHT\"],\n  [\"text\",\"  \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"CompleteNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language.gobstones\",\"K_RETURN\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"SimulateNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\"/*\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\"program {\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\"    return ( numberOfNeighbors())\"]\n],[\n   \"block_comment_end\",\n  [\"comment.block.dash-asterisc.gobstones\",\"}\"]\n],[\n   \"start\",\n  [\"comment.block.dash-asterisc.gobstones\",\"*/\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"--                      FUNCTIONS                        --\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"hayBolitas\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Verde\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"cellStatus\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"choose\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier.gobstones\",\"Alive\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"when\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier.gobstones\",\"Dead\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"otherwise\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"readCell\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"Cell\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"color\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"<-\"],\n  [\"text\",\" \"],\n  [\"constant.language.colors.gobstones\",\"Verde\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"status\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"<-\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"cellStatus\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"numberOfNeighbors\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"amountOfNeighbors\"],\n  [\"text\",\" := \"],\n  [\"constant.numeric.gobstones\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.repetitions.gobstones\",\"foreach\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"text\",\" \"],\n  [\"keyword.control.commands.repetitions.gobstones\",\"in\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"[\"],\n  [\"support.variable.gobstones\",\"minDir\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" .. \"],\n  [\"support.variable.gobstones\",\"maxDir\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"keyword.operator.other.gobstones\",\"]\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"amountOfNeighbors\"],\n  [\"text\",\" := \"],\n  [\"identifier.gobstones\",\"amountOfNeighbors\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.numeric.gobstones\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"aliveCellsAt\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"amountOfNeighbors\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"aliveCellsAt\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"firstCompare\"],\n  [\"text\",\" := \"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"hasAliveCellAt\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"secondCompare\"],\n  [\"text\",\" := \"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"support.variable.gobstones\",\"puedeMover\"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"siguiente\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"hasAliveCellAtD\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"value\"],\n  [\"text\",\" :=\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"matching\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"firstCompare\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"select\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"constant.numeric.gobstones\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"on\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean.gobstones\",\"True\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"constant.numeric.gobstones\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"otherwise\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.operator.numeric.gobstones\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"matching\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"secondCompare\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"select\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"constant.numeric.gobstones\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"on\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean.gobstones\",\"True\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"constant.numeric.gobstones\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.control.expressions.alternatives.gobstones\",\"otherwise\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"value\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"hasAliveCellAt\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"Mover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"hasAliveCellAtD\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"Mover\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"Mover\"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"siguiente\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"dir\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.definitions.gobstones\",\"return\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"--              ROCEDURES DECLARATIONS                   --\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.gobstones\",\"-----------------------------------------------------------\"]\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagAsReanimated\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"Poner\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Azul\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagAsDead\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.gobstones\",\"Poner\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Rojo\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"ProcessAction\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"switch\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"hayBolitas\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Rojo\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"constant.language.boolean.gobstones\",\"True\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.function.gobstones\",\"Sacar\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Verde\"],\n  [\"rparen\",\")\"],\n  [\"semicolon.gobstones\",\";\"],\n  [\"text\",\" \"],\n  [\"support.function.gobstones\",\"Sacar\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Rojo\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.operator.other.gobstones\",\"_\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"switch\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"support.variable.gobstones\",\"hayBolitas\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Azul\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"constant.language.boolean.gobstones\",\"True\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.function.gobstones\",\"Poner\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Verde\"],\n  [\"rparen\",\")\"],\n  [\"semicolon.gobstones\",\";\"],\n  [\"text\",\" \"],\n  [\"support.function.gobstones\",\"Sacar\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.colors.gobstones\",\"Azul\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.operator.other.gobstones\",\"_\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.other.gobstones\",\"->\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagCell\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"numNeighbors\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"if\"],\n  [\"text\",\"     \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"numNeighbors\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.compare.gobstones\",\"<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.gobstones\",\"2\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagAsDead\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"elseif\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"numNeighbors\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.compare.gobstones\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.gobstones\",\"3\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagAsDead\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.alternatives.gobstones\",\"elseif\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"((\"],\n  [\"keyword.operator.boolean.gobstones\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"isCellAlive\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.boolean.gobstones\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"numNeighbors\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.compare.gobstones\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.gobstones\",\"3\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"TagAsReanimated\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"SimulateTicks\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"amount\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.repetitions.gobstones\",\"repeat\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"amount\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"SimulateNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"SimulateNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"PrepareNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"CompleteNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"PrepareNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"GoToStartOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.repetitions.gobstones\",\"while\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator.boolean.gobstones\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"isEndOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"TagCell\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"numberOfNeighbors\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"NextCellOfTheBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"TagCell\"],\n  [\"lparen\",\"(\"],\n  [\"identifier.gobstones\",\"numberOfNeighbors\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.definitions.gobstones\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"CompleteNextTick\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"GoToStartOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.commands.repetitions.gobstones\",\"while\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator.boolean.gobstones\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier.gobstones\",\"isEndOfBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"ProcessAction\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier.gobstones\",\"NextCellOfTheBoard\"],\n  [\"lparen\",\"(\"],\n  [\"constant.language.cardinals.gobstones\",\"Norte\"],\n  [\"comma.gobstones\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.cardinals.gobstones\",\"Este\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier.gobstones\",\"ProcessAction\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_golang.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// Concurrent computation of pi.\"]\n],[\n   \"start\",\n  [\"comment\",\"// See http://goo.gl/ZuTZM.\"]\n],[\n   \"start\",\n  [\"comment\",\"//\"]\n],[\n   \"start\",\n  [\"comment\",\"// This demonstrates Go's ability to handle\"]\n],[\n   \"start\",\n  [\"comment\",\"// large numbers of concurrent processes.\"]\n],[\n   \"start\",\n  [\"comment\",\"// It is an unreasonable way to calculate pi.\"]\n],[\n   \"start\",\n  [\"keyword\",\"package\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"\\\"fmt\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"\\\"math\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"func\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"fmt\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"Println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"pi\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5000\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"// pi launches n goroutines to compute an\"]\n],[\n   \"start\",\n  [\"comment\",\"// approximation of pi.\"]\n],[\n   \"start\",\n  [\"keyword\",\"func\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"pi\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"int\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"float64\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"ch\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"make\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"chan\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"float64\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"go\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"term\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"ch\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"float64\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"k\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"f\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.0\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"f\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<-\"],\n  [\"identifier\",\"ch\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"f\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"func\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"term\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"ch\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"chan\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"float64\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"float64\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"ch\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"math\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"Pow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"-1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" / \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"k\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_graphqlschema.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# Main Schema\"]\n],[\n   \"start\",\n  [\"keyword\",\"schema\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"query\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Query\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"scalar\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Simple type to contain all scalar types\"]\n],[\n   \"start\",\n  [\"keyword\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"AllTypes\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Field Description for String\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testString\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Field Description for Int\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testInt\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"Int\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Field Description for ID\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testID\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"ID\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Field Description for Boolean\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testBoolean\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"Boolean\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Field Description for Float\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testFloat\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"Float\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"interface\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ISearchable\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"searchPreview\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"union\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ProductTypes\"],\n  [\"text\",\" = \"],\n  [\"identifier\",\"Movie\"],\n  [\"text\",\" | \"],\n  [\"identifier\",\"Book\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Testing enum\"]\n],[\n   \"start\",\n  [\"keyword\",\"enum\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MovieGenere\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"ACTION\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"COMEDY\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"THRILLER\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"DRAMA\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Testing Input\"]\n],[\n   \"start\",\n  [\"keyword\",\"input\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SearchByGenere\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"before\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"after\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"genere\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"MovieGenere\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Testing Interface\"]\n],[\n   \"start\",\n  [\"keyword\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Movie\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"implements\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ISearchable\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"id\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"ID\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"searchPreview\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"rentPrice\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"Float\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"publishDate\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"genere\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"MovieGenere\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"cast\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"storage.type\",\"String\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Testing Interface\"]\n],[\n   \"start\",\n  [\"keyword\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Book\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"implements\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ISearchable\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"id\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"ID\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"searchPreview\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\"!;\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"price\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"Float\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"publishDate\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"authors\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"storage.type\",\"String\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Query\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testString\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"testDate\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"Date\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"allTypes\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"AllTypes\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"allProducts\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"ProductTypes\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# searches only movies by genere with sophisticated argument\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"searchMovieByGenere\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"searchObject\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"SearchByGenere\"],\n  [\"text\",\"!\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"Movie\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Searchs all products by text string\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"searchProduct\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"text\"],\n  [\"text\",\": \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\"!\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"ISearchable\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_groovy.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"//http://groovy.codehaus.org/Martin+Fowler%27s+closure+examples+in+Groovy\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"salary\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"boolean\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"manager\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"toString\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"emps\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"[\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\":\"],\n  [\"string\",\"'Guillaume'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"manager\"],\n  [\"text\",\":\"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"200\"],\n  [\"rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\":\"],\n  [\"string\",\"'Graeme'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"manager\"],\n  [\"text\",\":\"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"200\"],\n  [\"rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\":\"],\n  [\"string\",\"'Dierk'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"manager\"],\n  [\"text\",\":\"],\n  [\"constant.language.boolean\",\"false\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"151\"],\n  [\"rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\":\"],\n  [\"string\",\"'Bernd'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"manager\"],\n  [\"text\",\":\"],\n  [\"constant.language.boolean\",\"false\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"50\"],\n  [\"rparen\",\")]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"managers\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"emps\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"emps\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"findAll\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"isManager\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"emps\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\"..\"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"managers\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"emps\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// [Guillaume, Graeme]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"highPaid\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"emps\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"threshold\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"150\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"emps\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"findAll\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"threshold\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"emps\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\"..\"],\n  [\"constant.numeric\",\"2\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"highPaid\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"emps\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// [Guillaume, Graeme, Dierk]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"paidMore\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"amount\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"e\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"amount\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"highPaid\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"paidMore\"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"150\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"highPaid\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"emps\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\"])\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// true\"]\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"emps\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\"..\"],\n  [\"constant.numeric\",\"2\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"emps\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"findAll\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"highPaid\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"filename\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'test.txt'\"]\n],[\n   \"start\",\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"File\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"filename\"],\n  [\"rparen\",\")\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"withReader\"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"reader\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"doSomethingWith\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"reader\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"readersText\"]\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"doSomethingWith\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"reader\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"readersText\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"reader\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"text\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"File\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"filename\"],\n  [\"rparen\",\")\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"text\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"readersText\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_haml.json",
    "content": "[[\n   \"start\",\n  [\"keyword.other.doctype\",\"!!!5\"]\n],[\n   \"start\"\n],[\n   \"embedded_ruby\",\n  [\"text\",\"# <!--[\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lt\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"IE\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\"]> <\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"no-js lt-ie9 lt-ie8 lt-ie7\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lang\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"text\",\"> <![\"],\n  [\"identifier\",\"endif\"],\n  [\"text\",\"]-->\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"# <!--[\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"IE\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\"]>    <\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"no-js lt-ie9 lt-ie8\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lang\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"text\",\"> <![\"],\n  [\"identifier\",\"endif\"],\n  [\"text\",\"]-->\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"# <!--[\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"IE\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"8\"],\n  [\"text\",\"]>    <\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"no-js lt-ie9\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lang\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"text\",\"> <![\"],\n  [\"identifier\",\"endif\"],\n  [\"text\",\"]-->\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"# <!--[\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"gt\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"IE\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"8\"],\n  [\"text\",\"]><!--> <\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"no-js\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lang\"],\n  [\"text\",\"=\"],\n  [\"string\",\"\\\"en\\\"\"],\n  [\"text\",\"> <!--<![\"],\n  [\"identifier\",\"endif\"],\n  [\"text\",\"]-->\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"/adasdasdad\"]\n],[\n   \"embedded_ruby\",\n  [\"meta.tag.haml\",\"%div\"],\n  [\"text\",\"{\"],\n  [\"constant.other.symbol.ruby\",\":id\"],\n  [\"text\",\" => \"],\n  [\"string\",\"\\\"#{@item.type}_#{@item.number}\\\"\"],\n  [\"text\",\", :\"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" => \"],\n  [\"string\",\"'#{@item.type} #{@item.urgency}'\"],\n  [\"text\",\", :\"],\n  [\"identifier\",\"phoney\"],\n  [\"text\",\" => \"],\n  [\"string\",\"`asdasdasd`\"],\n  [\"text\",\"}\"]\n],[\n   \"start\",\n  [\"comment.line\",\"/ file: app/views/movies/index.html.haml\"]\n],[\n   \"start\",\n  [\"text\",\"\\\\d\"]\n],[\n   \"embedded_ruby\",\n  [\"meta.tag.haml\",\"%ads:\"],\n  [\"text\",\"{\"],\n  [\"constant.other.symbol.ruby\",\":bleh\"],\n  [\"text\",\" => \"],\n  [\"constant.numeric\",\"33\"],\n  [\"text\",\"}\"]\n],[\n   \"embedded_ruby\",\n  [\"meta.tag.haml\",\"%p\"],\n  [\"text\",\"==\"],\n  [\"identifier\",\"ddd\"],\n  [\"text\",\"==\"]\n],[\n   \"start\",\n  [\"text\",\"  Date\"],\n  [\"comment.line\",\"/Time:\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"  - \"],\n  [\"identifier\",\"now\"],\n  [\"text\",\" = \"],\n  [\"support.class\",\"DateTime\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"now\"],\n  [\"text\",\" \"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"  \"],\n  [\"meta.tag.haml\",\"%strong\"],\n  [\"text\",\"= \"],\n  [\"identifier\",\"now\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"   = \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"now\"],\n  [\"text\",\"  \"],\n  [\"support.class\",\"DateTime\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"parse\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"December 31, 2006\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"    = \"],\n  [\"string\",\"\\\"Happy new \\\"\"],\n  [\"text\",\" + \"],\n  [\"string\",\"\\\"year!\\\"\"]\n],[\n   \"start\",\n  [\"meta.tag.haml\",\"%sfd\"],\n  [\"keyword.attribute-name.class.haml\",\".dfdfg\"]\n],[\n   \"element_class\",\n  [\"keyword.attribute-name.id.haml\",\"#content\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword.attribute-name.class.haml\",\".title\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"   \"],\n  [\"meta.tag.haml\",\"%h1\"],\n  [\"text\",\"= \"],\n  [\"variable.instance\",\"@title\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"   = \"],\n  [\"support.function\",\"link_to\"],\n  [\"text\",\" \"],\n  [\"string\",\"'Home'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"home_url\"]\n],[\n   \"start\"\n],[\n   \"element_class\",\n  [\"text\",\"   \"],\n  [\"keyword.attribute-name.id.haml\",\"#contents\"]\n],[\n   \"element_class\",\n  [\"meta.tag.haml\",\"%div\"],\n  [\"keyword.attribute-name.id.haml\",\"#content\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.tag.haml\",\"%div\"],\n  [\"keyword.attribute-name.class.haml\",\".articles\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag.haml\",\"%div\"],\n  [\"keyword.attribute-name.class.haml\",\".article.title\"],\n  [\"text\",\" Blah\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag.haml\",\"%div\"],\n  [\"keyword.attribute-name.class.haml\",\".article.date\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2006-11-05\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag.haml\",\"%div\"],\n  [\"keyword.attribute-name.class.haml\",\".article.entry\"]\n],[\n   \"start\",\n  [\"text\",\"      Neil Patrick Harris \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.haml\",\"%div\"],\n  [\"text\",\"[@user, \"],\n  [\"constant.other.symbol.ruby\",\":greeting\"],\n  [\"text\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.tag.haml\",\"%bar\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric\",\"290\"],\n  [\"text\",\"]\"],\n  [\"comment.line\",\"/\"]\n],[\n   \"embedded_ruby\",\n  [\"text\",\"  ==\"],\n  [\"support.class\",\"Hello\"],\n  [\"text\",\"!==\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_handlebars.json",
    "content": "[[\n   \"start\",\n  [\"comment.start\",\"{{!--\"],\n  [\"comment\",\" Ace + :-}} \"],\n  [\"comment.end\",\"--}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"comments\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"storage.type.start\",\"{{#\"],\n  [\"variable.parameter\",\"each\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"comments\"],\n  [\"storage.type.end\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"/posts/\"],\n  [\"storage.type.start\",\"{{\"],\n  [\"text\",\"../\"],\n  [\"variable.parameter\",\"permalink\"],\n  [\"storage.type.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"#\"],\n  [\"storage.type.start\",\"{{\"],\n  [\"variable.parameter\",\"id\"],\n  [\"storage.type.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"storage.type.start\",\"{{\"],\n  [\"variable.parameter\",\"title\"],\n  [\"storage.type.end\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.function\",\"{{{\"],\n  [\"variable.parameter\",\"body\"],\n  [\"support.function\",\"}}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"storage.type.start\",\"{{/\"],\n  [\"variable.parameter\",\"each\"],\n  [\"storage.type.end\",\"}}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_haskell.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.definition.comment.haskell\",\"-- Type annotation (optional)\"]\n],[\n   \"start\",\n  [\"entity.name.function.haskell\",\"fib\"],\n  [\"meta.function.type-declaration.haskell\",\" \"],\n  [\"keyword.other.double-colon.haskell\",\"::\"],\n  [\"meta.function.type-declaration.haskell\",\" \"],\n  [\"support.type.prelude.haskell\",\"Int\"],\n  [\"meta.function.type-declaration.haskell\",\" \"],\n  [\"keyword.other.arrow.haskell\",\"->\"],\n  [\"meta.function.type-declaration.haskell\",\" \"],\n  [\"support.type.prelude.haskell\",\"Integer\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.haskell\",\"-- With self-referencing data\"]\n],[\n   \"start\",\n  [\"text\",\"fib n \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"!!\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.haskell\",\"where\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function.prelude.haskell\",\"scanl\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.infix.haskell\",\"(+)\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"1\"],\n  [\"text\",\" fibs\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment.haskell\",\"-- 0,1,1,2,3,5,...\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.haskell\",\"-- Same, coded directly\"]\n],[\n   \"start\",\n  [\"text\",\"fib n \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"!!\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.haskell\",\"where\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" next fibs\"]\n],[\n   \"start\",\n  [\"text\",\"              next (a \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" t@(b\"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\"_)) \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" (a\"],\n  [\"keyword.operator.haskell\",\"+\"],\n  [\"text\",\"b) \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" next t\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.haskell\",\"-- Similar idea, using zipWith\"]\n],[\n   \"start\",\n  [\"text\",\"fib n \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"!!\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.haskell\",\"where\"],\n  [\"text\",\" fibs \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.haskell\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function.prelude.haskell\",\"zipWith\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.infix.haskell\",\"(+)\"],\n  [\"text\",\" fibs (\"],\n  [\"support.function.prelude.haskell\",\"tail\"],\n  [\"text\",\" fibs)\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.haskell\",\"-- Using a generator function\"]\n],[\n   \"start\",\n  [\"text\",\"fib n \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" fibs (\"],\n  [\"constant.numeric.haskell\",\"0\"],\n  [\"punctuation.separator.comma.haskell\",\",\"],\n  [\"constant.numeric.haskell\",\"1\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.haskell\",\"!!\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.haskell\",\"where\"],\n  [\"text\",\" fibs (a\"],\n  [\"punctuation.separator.comma.haskell\",\",\"],\n  [\"text\",\"b) \"],\n  [\"keyword.operator.haskell\",\"=\"],\n  [\"text\",\" a \"],\n  [\"keyword.operator.haskell\",\":\"],\n  [\"text\",\" fibs (b\"],\n  [\"punctuation.separator.comma.haskell\",\",\"],\n  [\"text\",\"a\"],\n  [\"keyword.operator.haskell\",\"+\"],\n  [\"text\",\"b)\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_haskell_cabal.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"name:                \"],\n  [\"text\",\"reload\"]\n],[\n   \"start\",\n  [\"keyword\",\"version:             \"],\n  [\"constant.numeric\",\"0.1.0.0\"]\n],[\n   \"start\",\n  [\"keyword\",\"synopsis:            \"],\n  [\"text\",\"Initial project template from stack\"]\n],[\n   \"start\",\n  [\"keyword\",\"Description:\"]\n],[\n   \"start\",\n  [\"text\",\"    The \\\\'cabal\\\\' command-line program simplifies the process of managing\"]\n],[\n   \"start\",\n  [\"text\",\"    Haskell software by automating the fetching, configuration, compilation\"]\n],[\n   \"start\",\n  [\"text\",\"    and installation of Haskell libraries and programs.\"]\n],[\n   \"start\",\n  [\"keyword\",\"homepage:            \"],\n  [\"text\",\"https://github.com/jpmoresmau/dbIDE/reload#readme\"]\n],[\n   \"start\",\n  [\"keyword\",\"license:             \"],\n  [\"text\",\"BSD\"],\n  [\"constant.numeric\",\"3\"]\n],[\n   \"start\",\n  [\"keyword\",\"license-file:        \"],\n  [\"text\",\"LICENSE\"]\n],[\n   \"start\",\n  [\"keyword\",\"author:              \"],\n  [\"text\",\"JP Moresmau\"]\n],[\n   \"start\",\n  [\"keyword\",\"maintainer:          \"],\n  [\"text\",\"jpmoresmau@gmail.com\"]\n],[\n   \"start\",\n  [\"keyword\",\"copyright:           \"],\n  [\"constant.numeric\",\"2016\"],\n  [\"text\",\" JP Moresmau\"]\n],[\n   \"start\",\n  [\"keyword\",\"category:            \"],\n  [\"text\",\"Web\"]\n],[\n   \"start\",\n  [\"keyword\",\"build-type:          \"],\n  [\"text\",\"Simple\"]\n],[\n   \"start\",\n  [\"comment\",\"-- extra-source-files:\"]\n],[\n   \"start\",\n  [\"keyword\",\"cabal-version:       \"],\n  [\"text\",\">=\"],\n  [\"constant.numeric\",\"1.10\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"Flag network-uri\"]\n],[\n   \"start\",\n  [\"keyword\",\"  description:  \"],\n  [\"text\",\"Get Network.URI from the network-uri package\"]\n],[\n   \"start\",\n  [\"keyword\",\"  default:      \"],\n  [\"constant.language.boolean\",\"True\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"library\"]\n],[\n   \"start\",\n  [\"keyword\",\"  hs-source-dirs:      \"],\n  [\"text\",\"src\"]\n],[\n   \"start\",\n  [\"keyword\",\"  exposed-modules:     \"],\n  [\"text\",\"Language.Haskell.Reload\"]\n],[\n   \"start\",\n  [\"keyword\",\"  build-depends:       \"],\n  [\"text\",\"base >= \"],\n  [\"constant.numeric\",\"4.7\"],\n  [\"text\",\" && < \"],\n  [\"constant.numeric\",\"5\"]\n],[\n   \"start\",\n  [\"text\",\"                     , aeson\"]\n],[\n   \"start\",\n  [\"text\",\"                     , scotty\"]\n],[\n   \"start\",\n  [\"text\",\"                     , wai\"]\n],[\n   \"start\",\n  [\"text\",\"                     , text\"]\n],[\n   \"start\",\n  [\"text\",\"                     , directory\"]\n],[\n   \"start\",\n  [\"text\",\"                     , filepath\"]\n],[\n   \"start\",\n  [\"text\",\"                     , bytestring\"]\n],[\n   \"start\",\n  [\"text\",\"                     , containers\"]\n],[\n   \"start\",\n  [\"text\",\"                     , mime-types\"]\n],[\n   \"start\",\n  [\"text\",\"                     , transformers\"]\n],[\n   \"start\",\n  [\"text\",\"                     , wai-handler-launch\"]\n],[\n   \"start\",\n  [\"text\",\"                     , wai-middleware-static\"]\n],[\n   \"start\",\n  [\"text\",\"                     , wai-extra\"]\n],[\n   \"start\",\n  [\"text\",\"                     , http-types\"]\n],[\n   \"start\",\n  [\"keyword\",\"  default-language:    \"],\n  [\"text\",\"Haskell\"],\n  [\"constant.numeric\",\"2010\"]\n],[\n   \"start\",\n  [\"keyword\",\"  other-modules:       \"],\n  [\"text\",\"Language.Haskell.Reload.FileBrowser\"]\n],[\n   \"start\",\n  [\"keyword\",\"  ghc-options:         \"],\n  [\"text\",\"-Wall -O\"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"executable reload-exe\"]\n],[\n   \"start\",\n  [\"keyword\",\"  hs-source-dirs:      \"],\n  [\"text\",\"app\"]\n],[\n   \"start\",\n  [\"keyword\",\"  main-is:             \"],\n  [\"text\",\"Main.hs\"]\n],[\n   \"start\",\n  [\"keyword\",\"  ghc-options:         \"],\n  [\"text\",\"-threaded -O\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" -rtsopts -with-rtsopts=-N\"]\n],[\n   \"start\",\n  [\"keyword\",\"  build-depends:       \"],\n  [\"text\",\"base\"]\n],[\n   \"start\",\n  [\"text\",\"                     , reload\"]\n],[\n   \"start\",\n  [\"keyword\",\"  default-language:    \"],\n  [\"text\",\"Haskell\"],\n  [\"constant.numeric\",\"2010\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"test-suite reload-test\"]\n],[\n   \"start\",\n  [\"keyword\",\"  type:                \"],\n  [\"text\",\"exitcode-stdio-\"],\n  [\"constant.numeric\",\"1.0\"]\n],[\n   \"start\",\n  [\"keyword\",\"  hs-source-dirs:      \"],\n  [\"text\",\"test\"]\n],[\n   \"start\",\n  [\"keyword\",\"  main-is:             \"],\n  [\"text\",\"Spec.hs\"]\n],[\n   \"start\",\n  [\"keyword\",\"  build-depends:       \"],\n  [\"text\",\"base\"]\n],[\n   \"start\",\n  [\"text\",\"                     , reload\"]\n],[\n   \"start\",\n  [\"text\",\"                     , hspec\"]\n],[\n   \"start\",\n  [\"text\",\"                     , hspec-wai\"]\n],[\n   \"start\",\n  [\"text\",\"                     , hspec-wai-json\"]\n],[\n   \"start\",\n  [\"text\",\"                     , aeson\"]\n],[\n   \"start\",\n  [\"text\",\"                     , directory\"]\n],[\n   \"start\",\n  [\"text\",\"                     , filepath\"]\n],[\n   \"start\",\n  [\"text\",\"                     , text\"]\n],[\n   \"start\",\n  [\"text\",\"                     , containers\"]\n],[\n   \"start\",\n  [\"text\",\"                     , unordered-containers\"]\n],[\n   \"start\",\n  [\"text\",\"                     , bytestring\"]\n],[\n   \"start\",\n  [\"text\",\"                     , wai-extra\"]\n],[\n   \"start\",\n  [\"keyword\",\"  ghc-options:         \"],\n  [\"text\",\"-threaded -O\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" -rtsopts -with-rtsopts=-N\"]\n],[\n   \"start\",\n  [\"keyword\",\"  default-language:    \"],\n  [\"text\",\"Haskell\"],\n  [\"constant.numeric\",\"2010\"]\n],[\n   \"start\",\n  [\"keyword\",\"  other-modules:       \"],\n  [\"text\",\"Language.Haskell.Reload.FileBrowserSpec\"]\n],[\n   \"start\",\n  [\"text\",\"                       Language.Haskell.ReloadSpec\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"source-repository head\"]\n],[\n   \"start\",\n  [\"keyword\",\"  type:     \"],\n  [\"text\",\"git\"]\n],[\n   \"start\",\n  [\"keyword\",\"  location: \"],\n  [\"text\",\"https://github.com/jpmoresmau/dbIDE/reload\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_haxe.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Haxe\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"static\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// Say Hello!\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"greeting\"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"String\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello World\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"trace\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"greeting\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"targets\"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"Array\"],\n  [\"keyword.operator\",\"<\"],\n  [\"keyword\",\"String\"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"Flash\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"Javascript\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"PHP\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"Neko\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"C++\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"iOS\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"Android\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"string\",\"\\\"webOS\\\"\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"trace\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Haxe is a great language that can target:\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"target\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"targets\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"trace\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\" - \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"target\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"trace\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"And many more!\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_hjson.json",
    "content": "[[\n   \"paren.lparen0\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"#\"],\n  [\"comment.line\",\" specify rate in requests/second (because comments are helpful!)\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"keyword\",\"rate\"],\n  [\"text\",\":\"],\n  [\"paren\",\" \"],\n  [\"constant.numeric\",\"1000\"]\n],[\n   \"paren.lparen0\"\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"//\"],\n  [\"comment.line\",\" prefer c-style comments?\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"/*\"],\n  [\"comment.block\",\" feeling old fashioned? \"],\n  [\"comment.punctuation\",\"*/\"]\n],[\n   \"paren.lparen0\"\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"#\"],\n  [\"comment.line\",\" did you notice that rate doesn't need quotes?\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"keyword\",\"hey\"],\n  [\"text\",\":\"],\n  [\"paren\",\" \"],\n  [\"string\",\"look ma, no quotes for strings either!\"]\n],[\n   \"paren.lparen0\"\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"#\"],\n  [\"comment.line\",\" best of all\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"keyword\",\"notice\"],\n  [\"text\",\":\"],\n  [\"paren\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"keyword\",\"anything\"],\n  [\"text\",\":\"],\n  [\"paren\",\" ?\"]\n],[\n   \"paren.lparen0\"\n],[\n   \"paren.lparen0\",\n  [\"paren\",\"  \"],\n  [\"comment.punctuation\",\"#\"],\n  [\"comment.line\",\" yes, commas are optional!\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_html.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"scripts\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"a\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"'a'\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"</scripts>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"'123'\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"scripts\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"abc\"]\n],[\n   \"start\",\n  [\"string.attribute-value.xml\",\"  def\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"string.attribute-value.xml\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"'abc\"]\n],[\n   \"start\",\n  [\"string.attribute-value.xml\",\"def\\\\'\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_html_elixir.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Listing Books\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Title\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Summary\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"for\"],\n  [\"text\",\" book \"],\n  [\"keyword.operator.comparison.elixir\",\"<\"],\n  [\"keyword.operator.arithmetic.elixir\",\"-\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.variable.elixir\",\"@\"],\n  [\"variable.other.readwrite.module.elixir\",\"books\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"do\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.eex\",\"<%#\"],\n  [\"comment\",\" comment \"],\n  [\"comment.end.eex\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" book\"],\n  [\"punctuation.separator.method.elixir\",\".\"],\n  [\"text\",\"title \"],\n  [\"support.elixir_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" book\"],\n  [\"punctuation.separator.method.elixir\",\".\"],\n  [\"text\",\"content \"],\n  [\"support.elixir_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" link \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"Show\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"to:\"],\n  [\"text\",\" book_path\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"punctuation.definition.variable.elixir\",\"@\"],\n  [\"variable.other.readwrite.module.elixir\",\"conn\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"show\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" book\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" link \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"Edit\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"to:\"],\n  [\"text\",\" book_path\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"punctuation.definition.variable.elixir\",\"@\"],\n  [\"variable.other.readwrite.module.elixir\",\"conn\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"edit\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" book\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" link \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"Delete\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"to:\"],\n  [\"text\",\" book_path\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"punctuation.definition.variable.elixir\",\"@\"],\n  [\"variable.other.readwrite.module.elixir\",\"conn\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"delete\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" book\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"method:\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"delete\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"data:\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.array.elixir\",\"[\"],\n  [\"punctuation.definition.constant.elixir\",\"confirm:\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"Are you sure?\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"],\n  [\"punctuation.section.array.elixir\",\"]\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"support.elixir_tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.elixir\",\"end\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"br\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"support.elixir_tag\",\"<%=\"],\n  [\"text\",\" link \"],\n  [\"punctuation.definition.string.begin.elixir\",\"\\\"\"],\n  [\"string.quoted.double.elixir\",\"New book\"],\n  [\"punctuation.definition.string.end.elixir\",\"\\\"\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\"to:\"],\n  [\"text\",\" book_path\"],\n  [\"punctuation.section.function.elixir\",\"(\"],\n  [\"punctuation.definition.variable.elixir\",\"@\"],\n  [\"variable.other.readwrite.module.elixir\",\"conn\"],\n  [\"punctuation.separator.object.elixir\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.elixir\",\":\"],\n  [\"constant.other.symbol.elixir\",\"new\"],\n  [\"punctuation.section.function.elixir\",\")\"],\n  [\"text\",\" \"],\n  [\"support.elixir_tag\",\"%>\"]\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_html_ruby.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Listing Books\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Title\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Summary\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"th\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"support.ruby_tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"@books\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"each\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"identifier\",\"book\"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.erb\",\"<%#\"],\n  [\"comment\",\" comment \"],\n  [\"comment.end.erb\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"book\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"title\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"book\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"content\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"link_to\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Show\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"book\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"link_to\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Edit\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"edit_book_path\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"book\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"link_to\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Remove\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"book\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":confirm\"],\n  [\"text\",\" \"],\n  [\"punctuation.separator.key-value\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Are you sure?\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":method\"],\n  [\"text\",\" \"],\n  [\"punctuation.separator.key-value\",\"=>\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":delete\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"support.ruby_tag\",\"<%\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"br\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"support.ruby_tag\",\"<%=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"link_to\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"New book\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"new_book_path\"],\n  [\"text\",\" \"],\n  [\"support.ruby_tag\",\"%>\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ini.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.definition.entity.ini\",\"[\"],\n  [\"constant.section.group-title.ini\",\".ShellClassInfo\"],\n  [\"punctuation.definition.entity.ini\",\"]\"]\n],[\n   \"start\",\n  [\"keyword.other.definition.ini\",\"IconResource\"],\n  [\"punctuation.separator.key-value.ini\",\"=\"],\n  [\"text\",\"..\\\\logo.png\"]\n],[\n   \"start\",\n  [\"punctuation.definition.entity.ini\",\"[\"],\n  [\"constant.section.group-title.ini\",\"ViewState\"],\n  [\"punctuation.definition.entity.ini\",\"]\"]\n],[\n   \"start\",\n  [\"keyword.other.definition.ini\",\"FolderType\"],\n  [\"punctuation.separator.key-value.ini\",\"=\"],\n  [\"text\",\"Generic\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_io.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.definition.comment.io\",\"//\"],\n  [\"comment.line.double-slash.io\",\" computes factorial of a number\"]\n],[\n   \"start\",\n  [\"text\",\"factorial \"],\n  [\"keyword.operator.io\",\":=\"],\n  [\"text\",\" \"],\n  [\"support.function.io\",\"method\"],\n  [\"text\",\"(n,\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.io\",\"if\"],\n  [\"text\",\"(n \"],\n  [\"keyword.operator.io\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.io\",\"0\"],\n  [\"text\",\", \"],\n  [\"keyword.control.io\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.io\",\"1\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    res \"],\n  [\"keyword.operator.io\",\":=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.io\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.class.io\",\"Range\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.io\",\"1\"],\n  [\"text\",\" \"],\n  [\"support.function.io\",\"to\"],\n  [\"text\",\"(n) \"],\n  [\"keyword.control.io\",\"foreach\"],\n  [\"text\",\"(i, res \"],\n  [\"keyword.operator.io\",\"=\"],\n  [\"text\",\" res \"],\n  [\"keyword.operator.io\",\"*\"],\n  [\"text\",\" i)\"]\n],[\n   \"start\",\n  [\"text\",\")\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ion.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.ion\",\"// Comment\"]\n],[\n   \"comment.block.ion\",\n  [\"comment.block.ion\",\"/*\"]\n],[\n   \"comment.block.ion\",\n  [\"comment.block.ion\",\"Multi\"]\n],[\n   \"comment.block.ion\",\n  [\"comment.block.ion\",\"Line\"]\n],[\n   \"comment.block.ion\",\n  [\"comment.block.ion\",\"Comment\"]\n],[\n   \"start\",\n  [\"comment.block.ion\",\"*/\"]\n],[\n   \"start\",\n  [\"punctuation.definition.list.begin.ion\",\"[\"],\n  [\"constant.numeric.integer.ion\",\"1\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"constant.numeric.integer.ion\",\"2\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"constant.numeric.integer.ion\",\"3\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"constant.numeric.integer.ion\",\"45\"],\n  [\"text.ion\",\" \"],\n  [\"comment.block.ion\",\"/*TODO: should be 42, obviously*/\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.timestamp.ion\",\"2016-04-21T08:10:46Z\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.timestamp.ion\",\"2016-04-21T08:10:46-08:00\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.timestamp.ion\",\"2016-04-21\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"2016\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.hex.ion\",\"0x5\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.binary.ion\",\"0b0110\"],\n  [\"punctuation.definition.list.end.ion\",\"]\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"punctuation.definition.sexp.begin.ion\",\"(\"],\n  [\"constant.numeric.integer.ion\",\"5\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"7\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"1\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"3\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"storage.type.symbol.quoted.ion\",\"'a'\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'b'\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"constant.language.null.ion\",\"null\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.language.null.ion\",\"null.int\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.language.null.ion\",\"null.bool\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.language.null.ion\",\"null.list\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"constant.language.bool.ion\",\"true\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.language.bool.ion\",\"false\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"constant.numeric.float.ion\",\"nan\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.float.ion\",\"-inf\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.float.ion\",\"+inf\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"str\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"str with embedded \\\\\\\" \"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.string.begin.ion\",\"'''\"],\n  [\"string.quoted.triple.ion\",\"str with embedded \\\\''' \"],\n  [\"punctuation.definition.string.end.ion\",\"'''\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.clob.begin.ion\",\"{{\"],\n  [\"string.other.clob.ion\",\"\\\"clob content\\\"\"],\n  [\"punctuation.definition.clob.end.ion\",\"}}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.sexp.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.blob.begin.ion\",\"{{\"],\n  [\"string.other.blob.ion\",\" AB/ \"],\n  [\"punctuation.definition.blob.end.ion\",\"}}\"]\n],[\n   \"start\",\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.list.end.ion\",\"]\"],\n  [\"punctuation.definition.sexp.end.ion\",\")\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.string.begin.ion\",\n  [\"punctuation.definition.string.begin.ion\",\"'''\"]\n],[\n   \"punctuation.definition.string.begin.ion\"\n],[\n   \"punctuation.definition.string.begin.ion\",\n  [\"string.quoted.triple.ion\",\"multi\"]\n],[\n   \"punctuation.definition.string.begin.ion\",\n  [\"string.quoted.triple.ion\",\"line\"]\n],[\n   \"punctuation.definition.string.begin.ion\",\n  [\"string.quoted.triple.ion\",\"string\"]\n],[\n   \"punctuation.definition.string.begin.ion\"\n],[\n   \"start\",\n  [\"punctuation.definition.string.end.ion\",\"'''\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"variable.language.annotation.ion\",\"states\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"text.ion\",\"    \"],\n  [\"comment.line.ion\",\"// https://amzn.github.io/ion-docs/docs/spec.html\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"constant.other.symbol.identifier.ion\",\"root\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"variable.language.annotation.ion\",\"rules\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"        \"],\n  [\"variable.language.annotation.ion\",\"include\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"storage.type.symbol.quoted.ion\",\"'value'\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.list.end.ion\",\"]\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   \"punctuation.definition.struct.begin.ion\"\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"text.ion\",\"    \"],\n  [\"comment.line.ion\",\"// https://amzn.github.io/ion-docs/docs/spec.html#string\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"constant.other.symbol.identifier.ion\",\"string\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"variable.language.annotation.ion\",\"rules\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"        \"],\n  [\"variable.language.annotation.ion\",\"match\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"constant.other.symbol.identifier.ion\",\"regex\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"(\\\\\\\\\\\\\\\")((?:\\\\\\\\\\\\\\\\\\\\\\\"|[^\\\\\\\"])*)(\\\\\\\\\\\\\\\")\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"constant.other.symbol.identifier.ion\",\"token\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.dblq.punc.start'\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.dblq'\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.dblq.punc.end'\"],\n  [\"punctuation.definition.list.end.ion\",\"]\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"        \"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"        \"],\n  [\"variable.language.annotation.ion\",\"push\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"constant.other.symbol.identifier.ion\",\"regex\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"\\\\'{3}\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"constant.other.symbol.identifier.ion\",\"token\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.trpq.punc.start'\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"constant.other.symbol.identifier.ion\",\"states\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"variable.language.annotation.ion\",\"rules\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                \"],\n  [\"variable.language.annotation.ion\",\"pop\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                    \"],\n  [\"constant.other.symbol.identifier.ion\",\"regex\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"\\\\'{3}\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                    \"],\n  [\"constant.other.symbol.identifier.ion\",\"token\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.trpq.punc.end'\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                \"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                \"],\n  [\"variable.language.annotation.ion\",\"match\"],\n  [\"punctuation.definition.annotation.ion\",\"::\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                    \"],\n  [\"constant.other.symbol.identifier.ion\",\"regex\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"(?:\\\\\\\\\\\\\\\\'*|.|[^']*)\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                    \"],\n  [\"constant.other.symbol.identifier.ion\",\"token\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'string.trpq'\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"                \"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"            \"],\n  [\"punctuation.definition.list.end.ion\",\"]\"]\n],[\n   [\"punctuation.definition.list.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"        \"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"text.ion\",\"    \"],\n  [\"punctuation.definition.list.end.ion\",\"]\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   \"punctuation.definition.struct.begin.ion\"\n],[\n   [\"comment.block.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"    \"],\n  [\"comment.block.ion\",\"/*\"]\n],[\n   [\"comment.block.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"comment.block.ion\",\"    ...\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"comment.block.ion\",\"    */\"]\n],[\n   \"start\",\n  [\"punctuation.definition.struct.end.ion\",\"}\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"json\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"      \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"compatibility\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"constant.language.bool.ion\",\"true\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"      \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"open sourced\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"2016-04-21T08:10:46Z\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"      \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"foo\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"9\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"      \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"bar\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.decimal.ion\",\"1.1\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"]\n],[\n   [\"punctuation.definition.struct.begin.ion\",\"punctuation.definition.struct.begin.ion\"],\n  [\"text.ion\",\"      \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"baz\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"id\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"text.ion\",\" \"],\n  [\"constant.numeric.integer.ion\",\"1\"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"id\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"constant.numeric.integer.ion\",\"2\"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.end.ion\",\"]\"]\n],[\n   \"punctuation.definition.struct.begin.ion\",\n  [\"text.ion\",\"  \"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.struct.end.ion\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jack.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"vars\"],\n  [\"text\",\" \"],\n  [\"variable\",\"it\"],\n  [\"text\",\", \"],\n  [\"variable\",\"p\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"label\"],\n  [\"text\",\", \"],\n  [\"variable\",\"value\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"label\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"language.builtin\",\"inspect\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"value\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"comment\",\"-- Create an array from 0 to 15\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"range\\\"\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"i-collect\"],\n  [\"paren.lparen\",\"(\"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Create an array from 0 to 15 and break up in chunks of 4\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"chunked range\\\"\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"i-collect\"],\n  [\"paren.lparen\",\"(\"],\n  [\"language.builtin\",\"i-chunk\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"16\"],\n  [\"paren.rparen\",\"))))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Check if all or none items in stream pass test.\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"all < 60 in range(60)\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"i-all?\"],\n  [\"paren.lparen\",\"({\"],\n  [\"variable\",\"i\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"i\"],\n  [\"keyword.operator\",\"<\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"any < 60 in range(60)\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"i-any?\"],\n  [\"paren.lparen\",\"({\"],\n  [\"variable\",\"i\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"i\"],\n  [\"keyword.operator\",\">\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"all < 60 in range(70)\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"i-all?\"],\n  [\"paren.lparen\",\"({\"],\n  [\"variable\",\"i\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"i\"],\n  [\"keyword.operator\",\"<\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"70\"],\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"any < 60 in range(70)\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"i-any?\"],\n  [\"paren.lparen\",\"({\"],\n  [\"variable\",\"i\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"i\"],\n  [\"keyword.operator\",\">\"],\n  [\"constant.numeric\",\"60\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"70\"],\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Zip three different collections together\"]\n],[\n   \"start\",\n  [\"variable\",\"p\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"zipped\\\"\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"i-collect\"],\n  [\"paren.lparen\",\"(\"],\n  [\"language.builtin\",\"i-zip\"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"i-map\"],\n  [\"paren.lparen\",\"({\"],\n  [\"variable\",\"i\"],\n  [\"text\",\"|\"],\n  [\"variable\",\"i\"],\n  [\"keyword.operator\",\"*\"],\n  [\"variable\",\"i\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\", \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"vars\"],\n  [\"text\",\" \"],\n  [\"variable\",\"names\"],\n  [\"text\",\", \"],\n  [\"variable\",\"person\"],\n  [\"text\",\", \"],\n  [\"variable\",\"i\"],\n  [\"text\",\", \"],\n  [\"variable\",\"doubles\"],\n  [\"text\",\", \"],\n  [\"variable\",\"lengths\"],\n  [\"text\",\", \"],\n  [\"variable\",\"cubeRange\"]\n],[\n   \"start\",\n  [\"variable\",\"names\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"Thorin\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Dwalin\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Balin\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Bifur\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Bofur\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Bombur\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Oin\\\"\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"         \"],\n  [\"string\",\"\\\"Gloin\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Ori\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Nori\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Dori\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Fili\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Kili\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Bilbo\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Gandalf\\\"\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"names\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Bilbo\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Gandalf\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"person\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"name\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"Tim\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"age\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"30\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"key\"],\n  [\"text\",\", \"],\n  [\"variable\",\"value\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"person\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" = \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"value\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"i\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"keyword\",\"while\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" = \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"i\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"range\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Dynamic object that gives the first 10 doubles\"]\n],[\n   \"start\",\n  [\"variable\",\"doubles\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.form\",\"@len\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"| \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.form\",\"@get\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"key\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"Integer\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"#doubles\\\"\"],\n  [\"text\",\", \"],\n  [\"keyword.operator\",\"#\"],\n  [\"variable\",\"doubles\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Doubles\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"doubles\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Dynamic object that has names list as keys and string lenth as values\"]\n],[\n   \"start\",\n  [\"variable\",\"lengths\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.form\",\"@keys\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"| \"],\n  [\"variable\",\"names\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.form\",\"@get\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"key\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"String\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"#\"],\n  [\"variable\",\"key\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Lengths\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"lengths\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"cubeRange\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"n\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"vars\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.form\",\"@call\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" = \"],\n  [\"variable\",\"i\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" = \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"variable\",\"n\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Cubes\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"cubeRange\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"String\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello World\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"k\"],\n  [\"text\",\", \"],\n  [\"variable\",\"v\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")])\"]\n],[\n   \"start\",\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"([\"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"20\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Example showing how to do parallel work using split..and\"]\n],[\n   \"start\",\n  [\"variable\",\"base\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"bootstrap\"],\n  [\"text\",\", \"],\n  [\"variable\",\"target-dir\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"split\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"copy\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"res\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"target-dir\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"newer\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"src/*.less\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"target-dir\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"/style.css\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"lessc\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"src/\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"bootstrap\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\".less\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"target-dir\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"/style.css\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"build\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"src/\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"bootstrap\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\".js\\\"\"],\n  [\"text\",\", \"],\n  [\"variable\",\"target-dir\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"/app.js\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"vars\"],\n  [\"text\",\" \"],\n  [\"variable\",\"Dragon\"],\n  [\"text\",\", \"],\n  [\"variable\",\"pet\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"Dragon\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"name\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"vars\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\", \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\", \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"variable\",\"feed\"],\n  [\"text\",\", \"],\n  [\"variable\",\"walk\"],\n  [\"text\",\", \"],\n  [\"variable\",\"put-to-bed\"],\n  [\"text\",\", \"],\n  [\"variable\",\"toss\"],\n  [\"text\",\", \"],\n  [\"variable\",\"rock\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"variable\",\"hungry?\"],\n  [\"text\",\", \"],\n  [\"variable\",\"poopy?\"],\n  [\"text\",\", \"],\n  [\"variable\",\"passage-of-time\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\"     = \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- He's full.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" =  \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- He doesn't need to go.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' is born.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"feed\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'You feed '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"'.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric\",\"10\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"passage-of-time\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"walk\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'You walk '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\".\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"passage-of-time\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"put-to-bed\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'You put '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' to bed.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"true\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"language.builtin\",\"range\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable\",\"passage-of-time\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' snores, filling the room with smoke.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' wakes up slowly.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"toss\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'You toss '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' up into the air.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'He giggles, which singes your eyebrows.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"passage-of-time\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"rock\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'You rock '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' gently.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"true\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'He briefly dozes off...'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"passage-of-time\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'...but wakes when you stop.'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"hungry?\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"poopy?\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"8\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"passage-of-time\"],\n  [\"text\",\" = \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"|\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"-- Move food from belly to intestine\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\"     = \"],\n  [\"variable\",\"stuff-in-belly\"],\n  [\"text\",\"     \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" = \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- Our dragon is starving!\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'He wakes up suddenly!'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' is starving! In desperation, he ate YOU!'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"abort\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"died\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"stuff-in-intestine\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'Whoops! '\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' had an accident...'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"hungry?\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'He wakes up suddenly!'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"'s stomach grumbles...\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"poopy?\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable\",\"asleep\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"false\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'He wakes up suddenly!'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.builtin\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"' does the potty dance...'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"-- Export the public interface to this closure object.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"feed\"],\n  [\"text\",\": \"],\n  [\"variable\",\"feed\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"walk\"],\n  [\"text\",\": \"],\n  [\"variable\",\"walk\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"put-to-bed\"],\n  [\"text\",\": \"],\n  [\"variable\",\"put-to-bed\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"toss\"],\n  [\"text\",\": \"],\n  [\"variable\",\"toss\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"rock\"],\n  [\"text\",\": \"],\n  [\"variable\",\"rock\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\" = \"],\n  [\"variable\",\"Dragon\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'Norbert'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"feed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"toss\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"walk\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"put-to-bed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"rock\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"put-to-bed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"put-to-bed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"put-to-bed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"variable\",\"pet\"],\n  [\"text\",\".\"],\n  [\"variable\",\"put-to-bed\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jade.json",
    "content": "[[\n   \"start\",\n  [\"keyword.other.doctype.jade\",\"!!!doctype\"]\n],[\n   \"start\",\n  [\"keyword.other.doctype.jade\",\"!!!5\"]\n],[\n   \"start\",\n  [\"keyword.other.doctype.jade\",\"!!!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.import.include.jade\",\"include\"],\n  [\"text\",\" something\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.import.include.jade\",\"         include\"],\n  [\"text\",\" another_thing\"]\n],[\n   \"start\"\n],[\n   [\"comment_block\",2,\"start\"],\n  [\"comment\",\"  // let's talk about it\"]\n],[\n   \"start\"\n],[\n   [\"comment_block\",0,\"start\"],\n  [\"comment\",\"// \"]\n],[\n   [\"comment_block\",0,\"start\"],\n  [\"comment\",\"  here it is. a block comment!\"]\n],[\n   [\"comment_block\",0,\"start\"],\n  [\"comment\",\" and another row!\"]\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"but\"],\n  [\"text\",\" not here.\"]\n],[\n   \"start\"\n],[\n   [\"comment_block\",5,\"start\"],\n  [\"comment\",\"     // \"]\n],[\n   [\"comment_block\",5,\"start\"],\n  [\"comment\",\"        a far spaced\"]\n],[\n   \"start\",\n  [\"text\",\"    should be lack of block\"]\n],[\n   \"start\"\n],[\n   [\"comment_block\",3,\"start\"],\n  [\"comment\",\"   // also not a comment\"]\n],[\n   [\"comment_block\",3,\"start\"],\n  [\"comment\",\"     div.attemptAtBlock\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"  span\"],\n  [\"entity.other.attribute-name.id.jade\",\"#myName\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string.interpolated.jade\",\"#{implicit}\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"string.interpolated.jade\",\"!{more_explicit}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"suport.type.attribute.id.jade\",\"#idDiv\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"suport.type.attribute.class.jade\",\".idDiv\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"    test\"],\n  [\"punctuation\",\"(\"],\n  [\"entity.other.attribute-name.jade\",\"id\"],\n  [\"punctuation\",\"=\"],\n  [\"string\",\"\\\"tag\\\"\"],\n  [\"punctuation\",\")\"]\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"    header\"],\n  [\"punctuation\",\"(\"],\n  [\"entity.other.attribute-name.jade\",\"id\"],\n  [\"punctuation\",\"=\"],\n  [\"string\",\"\\\"tag\\\"\"],\n  [\"text\",\", \"],\n  [\"entity.other.attribute-name.jade\",\"blah\"],\n  [\"punctuation\",\"=\"],\n  [\"string\",\"\\\"foo\\\"\"],\n  [\"text\",\", \"],\n  [\"entity.other.attribute-name.jade\",\"meh\"],\n  [\"punctuation\",\"=\"],\n  [\"string\",\"\\\"aads\\\"\"],\n  [\"punctuation\",\")\"]\n],[\n   \"start\",\n  [\"storage.type.function.jade\",\"mixin\"],\n  [\"entity.name.function.jade\",\" article\"],\n  [\"punctuation.definition.parameters.begin.jade\",\"(\"],\n  [\"variable.parameter.function.jade\",\"obj, parents\"],\n  [\"punctuation.definition.parameters.end.jade\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.function.jade\",\"  mixin\"],\n  [\"entity.name.function.jade\",\" bleh\"],\n  [\"punctuation.definition.parameters.begin.jade\",\"(\"],\n  [\"punctuation.definition.parameters.end.jade\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.function.jade\",\"    mixin\"],\n  [\"entity.name.function.jade\",\" clever-name\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"source.js.embedded.jade\",\" -\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"source.js.embedded.jade\",\" -\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"each\"],\n  [\"text\",\" z\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"source.js.embedded.jade\",\" -\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"one\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"two\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"three\\\"\"],\n  [\"text\",\"]\"]\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"   each\"],\n  [\"text\",\" item in items\"]\n],[\n   \"start\",\n  [\"meta.tag.any.jade\",\"    li\"],\n  [\"text\",\"= item\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_java.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"java\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"util\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"ArrayList\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"java\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"util\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Vector\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"InfiniteLoop\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"text\",\"    \"],\n  [\"comment\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment\",\"     * This will cause the program to hang...\"]\n],[\n   \"comment\",\n  [\"comment\",\"     *\"]\n],[\n   \"comment\",\n  [\"comment\",\"     * Taken from:\"]\n],[\n   \"comment\",\n  [\"comment\",\"     * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/\"]\n],[\n   \"start\",\n  [\"comment\",\"     */\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.annotation\",\"@Override\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"static\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"void\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"main\"],\n  [\"lparen\",\"(\"],\n  [\"support.function\",\"String\"],\n  [\"lparen\",\"[\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"args\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"double\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"Double\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"parseDouble\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"2.2250738585072012e-308\\\"\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// unreachable code\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"System\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"Value: \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Joan\\\"\"],\n  [\"text\",\"; \"],\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"info\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"STR\"],\n  [\"punctuation\",\".\"],\n  [\"string\",\"\\\"\"],\n  [\"string\",\"My name is \"],\n  [\"lparen\",\"\\\\{\"],\n  [\"identifier\",\"name\"],\n  [\"rparen\",\"}\"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"STR\"],\n  [\"punctuation\",\".\"],\n  [\"string\",\"\\\"\"],\n  [\"string\",\"Today's weather is \"],\n  [\"lparen\",\"\\\\{\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"getFeelsLike\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"],\n  [\"string\",\", with a temperature of \"],\n  [\"lparen\",\"\\\\{\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"getTemperature\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"],\n  [\"string\",\" degrees \"],\n  [\"lparen\",\"\\\\{\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"getUnit\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"nestedMultilineTemplates\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"punctuation\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"STR\"],\n  [\"punctuation\",\".\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"punctuation\",\n  [\"string\",\"        {\"]\n],[\n   \"punctuation\",\n  [\"string\",\"            \\\"outerKey1\\\": \\\"outerValue1\\\",\"]\n],[\n   [\"lparen\",\"punctuation\"],\n  [\"string\",\"            \\\"nestedTemplate\\\": \\\"\"],\n  [\"lparen\",\"\\\\{\"]\n],[\n   [\"punctuation\",\"lparen\",\"lparen\",\"punctuation\"],\n  [\"text\",\"                \"],\n  [\"identifier\",\"STR\"],\n  [\"punctuation\",\".\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   [\"punctuation\",\"lparen\",\"lparen\",\"punctuation\"],\n  [\"string\",\"                {\"]\n],[\n   [\"punctuation\",\"lparen\",\"lparen\",\"punctuation\"],\n  [\"string\",\"                    \\\"innerKey\\\": \\\"\"],\n  [\"lparen\",\"\\\\{\"],\n  [\"identifier\",\"innerValue\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"get\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")}\"],\n  [\"string\",\"\\\"\"]\n],[\n   [\"punctuation\",\"lparen\",\"lparen\",\"punctuation\"],\n  [\"string\",\"                }\"]\n],[\n   [\"lparen\",\"punctuation\"],\n  [\"string\",\"                \\\"\\\"\\\"\"]\n],[\n   \"punctuation\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"}\"],\n  [\"string\",\"\\\",\"]\n],[\n   \"punctuation\",\n  [\"string\",\"            \\\"outerKey2\\\": \\\"outerValue2\\\"\"]\n],[\n   \"punctuation\",\n  [\"string\",\"        }\"]\n],[\n   \"start\",\n  [\"string\",\"        \\\"\\\"\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"to\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"working\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"com\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"example\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"myapp\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"doc-start\",\"paren.lparen\",\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"comment.doc\",\"/**\"]\n],[\n   [\"doc-start\",\"paren.lparen\",\"paren.lparen\",\"keyword\"],\n  [\"comment.doc.body\",\"     * Test doc comment\"]\n],[\n   [\"doc-start\",\"paren.lparen\",\"paren.lparen\",\"keyword\"],\n  [\"comment.doc.body\",\"     * \"],\n  [\"comment.doc.tag\",\"@property\"],\n  [\"comment.doc.body\",\" test\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"comment.doc.body\",\"     \"],\n  [\"comment.doc\",\"*/\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"requires\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"transitive\"],\n  [\"text\",\" java.base;\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"comment\",\"//comment\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"exports\"],\n  [\"text\",\" com.example.myapp.api;\"]\n],[\n   [\"comment\",\"paren.lparen\",\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"comment\",\"/*\"]\n],[\n   [\"comment\",\"paren.lparen\",\"paren.lparen\",\"keyword\"],\n  [\"comment\",\"        multiline comment\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"comment\",\"    */\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"opens\"],\n  [\"text\",\" com.example.myapp.internal \"],\n  [\"keyword\",\"to\"],\n  [\"text\",\" other.module;\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"uses\"],\n  [\"text\",\" com.example.myapp.service.MyService;\"]\n],[\n   [\"paren.lparen\",\"keyword\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"provides\"],\n  [\"text\",\" com.example.myapp.service.MyService \"],\n  [\"keyword\",\"with\"],\n  [\"text\",\" com.example.myapp.impl.MyServiceImpl;\"]\n],[\n   \"keyword\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_javascript.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"//test: tokenize 'standard' functions\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"string\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"charCodeAt\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"23\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"document\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"getElementById\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'test'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'Here it is'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"string\",\"\\\";\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"test\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"comment.doc\",\"/**\"],\n  [\"comment.doc.body\",\"tokenize doc\"],\n  [\"comment.doc\",\"*/\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"comment\"]\n],[\n   \"no_regex\",\n  [\"comment.doc\",\"/**\"],\n  [\"comment.doc.body\",\"tokenize doc comment with \"],\n  [\"comment.doc.tag\",\"@tag\"],\n  [\"comment.doc.body\",\" {}\"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"//test: tokenize parens\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$line$\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"[{( )}]\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"comment\",\"//test tokenize arithmetic expression which looks like a regexp\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"b\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"c\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"/=\"],\n  [\"identifier\",\"b\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"c\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"//test tokenize reg exps\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.regexp\",\"/b/g\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"+\"],\n  [\"string.regexp\",\"/b/g\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/2 \"],\n  [\"constant.language.escape\",\"+\"],\n  [\"string.regexp\",\" 1/gimyx\"],\n  [\"identifier\",\"k\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.regexp\",\"/a/\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/a/\"]\n],[\n   \"no_regex\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/a/\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"test\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"c\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"//test tokenize multi-line comment containing a single line comment\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"noRegex\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"/* foo // bar */\"]\n],[\n   \"start\",\n  [\"identifier\",\"canBeRegex\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"comment\",\"/* foo // bar */\"]\n],[\n   \"start\",\n  [\"comment\",\"// test tokenize identifier with umlauts\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"fu\"],\n  [\"punctuation.operator\",\"?\"],\n  [\"identifier\",\"e\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"// test // is not a regexp\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// 123\"]\n],[\n   \"start\",\n  [\"comment\",\"//test skipping escaped chars\"]\n],[\n   \"no_regex\",\n  [\"string\",\"'Meh\"],\n  [\"constant.language.escape\",\"\\\\\\\\\"],\n  [\"string\",\"nNeh'\"]\n],[\n   \"no_regex\",\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'\"],\n  [\"constant.language.escape\",\"\\\\\\\\\"],\n  [\"string\",\"u1232Feh'\"]\n],[\n   \"qqstring\",\n  [\"string\",\"\\\"test multiline\\\\\"]\n],[\n   \"no_regex\",\n  [\"string\",\" strings\\\"\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"'\"]\n],[\n   \"qqstring\",\n  [\"identifier\",\"b\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"\\\\\"]\n],[\n   \"no_regex\",\n  [\"string\",\"still a string\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"items\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"nada\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"items\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.constant\",\"length\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"++\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"items\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"juhu\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\"\\t\"],\n  [\"comment\",\"// Real Tab.\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"identifier\",\"regexp\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/p\"],\n  [\"constant.language.delimiter\",\"|\"],\n  [\"string.regexp\",\"p/\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// ends here\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"identifier\",\"r\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/d\"],\n  [\"constant.language.escape\",\"{1,2}?\"],\n  [\"string.regexp\",\"f{e}\"],\n  [\"invalid\",\"++\"],\n  [\"string.regexp\",\"r\"],\n  [\"constant.language.escape\",\"*?\"],\n  [\"regexp.keyword.operator\",\"\\\\d\"],\n  [\"constant.language.escape\",\"+?[]\"],\n  [\"string.regexp\",\"r\"],\n  [\"constant.language.escape\",\"[^\"],\n  [\"string.regexp.charachterclass\",\"r\"],\n  [\"constant.language.escape\",\"-\"],\n  [\"string.regexp.charachterclass\",\"o\"],\n  [\"regexp.charclass.keyword.operator\",\"\\\\f\\\\f\"],\n  [\"string.regexp.charachterclass\",\"[\"],\n  [\"regexp.charclass.keyword.operator\",\"\\\\f\"],\n  [\"constant.language.escape\",\"]?\"],\n  [\"string.regexp\",\"r\"],\n  [\"invalid\",\"{7}+\"],\n  [\"string.regexp\",\"r\"],\n  [\"regexp.keyword.operator\",\"\\\\{\"],\n  [\"string.regexp\",\"7}\"],\n  [\"constant.language.escape\",\"+\"],\n  [\"string.regexp\",\"rr--rr\"],\n  [\"constant.language.escape\",\"$^(?:\"],\n  [\"string.regexp\",\"d\"],\n  [\"constant.language.delimiter\",\"|\"],\n  [\"string.regexp\",\"s\"],\n  [\"constant.language.escape\",\")(?=\"],\n  [\"string.regexp\",\"a\"],\n  [\"constant.language.delimiter\",\"|\"],\n  [\"constant.language.escape\",\")(?!\"],\n  [\"string.regexp\",\"y\"],\n  [\"constant.language.escape\",\")[]\"],\n  [\"constant.language.delimiter\",\"|\"],\n  [\"invalid\",\"$?\"],\n  [\"constant.language.delimiter\",\"|\"],\n  [\"invalid\",\"^*\"],\n  [\"string.regexp\",\"/\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"a\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.regexp\",\"/a/\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"jk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/ /\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/ /\"]\n],[\n   \"no_regex\",\n  [\"text\",\" \"],\n  [\"comment.doc\",\"/**\"],\n  [\"comment.doc.body\",\"*********************************\"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"no_regex\",\n  [\"comment.doc\",\"/**\"],\n  [\"comment.doc.body\",\" total mess, tricky to highlight*\"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"doc-start\",\n  [\"text\",\"\\t\"],\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\"comment.doc.body\",\"\\t * docComment\"]\n],[\n   \"no_regex\",\n  [\"comment.doc.body\",\"\\t *\"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"r\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/u\"],\n  [\"regexp.keyword.operator\",\"\\\\t\"],\n  [\"constant.language.escape\",\"*\"],\n  [\"string.regexp\",\"/\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"g\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.00\"],\n  [\"identifier\",\"E\"],\n  [\"keyword.operator\",\"^\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\".2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"052\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0O7\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0x25\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"'d'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"''\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"/* eee */\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"qqstring\",\n  [\"string\",\"\\\"s\\\\\"]\n],[\n   \"no_regex\",\n  [\"string\",\"s\"],\n  [\"constant.language.escape\",\"\\\\u7824\"],\n  [\"string\",\"sss\"],\n  [\"constant.language.escape\",\"\\\\u\"],\n  [\"string\",\"1\\\"\"]\n],[\n   \"no_regex\"\n],[\n   \"qstring\",\n  [\"string\",\"'\\\\\"]\n],[\n   \"no_regex\",\n  [\"string\",\"string'\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"text\",\"'\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"string\"],\n  [\"text\",\"'\"]\n],[\n   \"no_regex\"\n],[\n   \"qqstring\",\n  [\"string\",\"\\\"trailing space\\\\\"]\n],[\n   \"no_regex\",\n  [\"string\",\"\\\"\"],\n  [\"text\",\"         \"],\n  [\"string\",\"\\\"    /not a regexp/g\"]\n],[\n   \"no_regex\"\n],[\n   \"doc-start\",\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\"comment.doc.body\",\" *doc\"]\n],[\n   \"no_regex\",\n  [\"comment.doc.body\",\" \"],\n  [\"comment.doc\",\"*/\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"string\",\"'a'\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"string\",\"'g'\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"t\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"entity.name.function\",\"gta\"],\n  [\"punctuation.operator\",\":\"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"variable.parameter\",\"b\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"identifier\",\"z\"],\n  [\"keyword.operator\",\">>=\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\"<<\"],\n  [\"identifier\",\"f\"],\n  [\"keyword.operator\",\">>\"],\n  [\"identifier\",\"r\"],\n  [\"keyword.operator\",\">>>\"],\n  [\"identifier\",\"s\"],\n  [\"keyword.operator\",\">=\"],\n  [\"constant.numeric\",\"0b1\"]\n],[\n   \"no_regex\"\n],[\n   \"function_arguments\",\n  [\"identifier\",\"foo\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"prototype\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"b\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"no_regex\",\n  [\"text\",\"                          \"],\n  [\"variable.parameter\",\"c\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"d\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"foo\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\"     \"],\n  [\"variable.parameter\",\"b\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"foo\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"/*****/\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"d\"],\n  [\"string\",\"\\\"string\\\"\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"div\"]\n],[\n   [\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"identifier\",\"z\"],\n  [\"keyword.operator\",\"=\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"keyword.operator\",\"...\"],\n  [\"variable.language\",\"this\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"props\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"x\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"y\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"z{a}b\"],\n  [\"constant.language.escape.reference.xml\",\"&amp;\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"t\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"paren.quasi.start\",\"{\"]\n],[\n   [\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"text\",\"        \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"jsx\",1],\n  [\"text\",\"    \"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"jsx\",1],\n  [\"string.xml\",\"1 \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"string.xml\",\" \"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"++\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\"  \"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.xml\",\" \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"start\",\"no_regex\",\"start\",\"string.quasi.start\",\"string.quasi.start\",\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"t\"],\n  [\"punctuation.operator\",\":\"],\n  [\"string.quasi.start\",\"`\"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"map\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"no_regex\",\"start\",\"no_regex\",\"start\",\"string.quasi.start\",\"string.quasi.start\",\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"]\n],[\n   \"no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"})\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.quasi.end\",\"`\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"//test generator function\"]\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"storage.type\",\"*\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"range\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"start\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"end\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"step\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"while\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"end\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"no_regex\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"yield\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"start\"]\n],[\n   \"no_regex\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"step\"]\n],[\n   \"no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"comment\",\"//test ES6 new built-in methods\"]\n],[\n   \"no_regex\",\n  [\"string\",\"\\\"hello\\\"\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"startsWith\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"ello\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// true\"]\n],[\n   \"no_regex\",\n  [\"string\",\"\\\"hello\\\"\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"endsWith\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"hell\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"   \"],\n  [\"comment\",\"// true\"]\n],[\n   \"no_regex\",\n  [\"string\",\"\\\"hello\\\"\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"includes\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"ell\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"       \"],\n  [\"comment\",\"// true\"]\n],[\n   \"no_regex\",\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"find\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// 4\"]\n],[\n   \"no_regex\",\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"findIndex\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// 2\"]\n],[\n   \"no_regex\",\n  [\"string\",\"\\\"foo\\\"\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"repeat\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"variable.language\",\"Number\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"isSafeInteger\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"42\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"===\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean\",\"true\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"Number\"],\n  [\"punctuation.operator\",\".\"],\n  [\"constant.language\",\"MAX_SAFE_INTEGER\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"Number\"],\n  [\"punctuation.operator\",\".\"],\n  [\"constant.language\",\"MIN_SAFE_INTEGER\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"storage.type\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"Number\"],\n  [\"punctuation.operator\",\".\"],\n  [\"constant.language\",\"EPSILON\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"comment\",\"//test Promises\"]\n],[\n   \"no_regex\",\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"Promise\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"tetheredGetNumber\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"then\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"determineParity\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"troubleWithGetNumber\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"then\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"promiseGetWord\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"then\"],\n  [\"paren.lparen\",\"((\"],\n  [\"variable.parameter\",\"info\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.quasi.start\",\"`\"],\n  [\"string.quasi\",\"Got: \"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"identifier\",\"info\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"value\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.quasi\",\", \"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"identifier\",\"info\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"wordEvenOdd\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.quasi.end\",\"`\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"info\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"catch\"],\n  [\"paren.lparen\",\"((\"],\n  [\"variable.parameter\",\"reason\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"reason\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"cause\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"error\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Had previously handled error\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"error\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.quasi.start\",\"`\"],\n  [\"string.quasi\",\"Trouble with promiseGetWord(): \"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"identifier\",\"reason\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.quasi.end\",\"`\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"finally\"],\n  [\"paren.lparen\",\"((\"],\n  [\"variable.parameter\",\"info\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"All done\\\"\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"comment\",\"//test ES6 arrow functions\"]\n],[\n   \"start\",\n  [\"variable.parameter\",\"param\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"123\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"paramN\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"test\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.parameter\",\"param\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"statements\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"paramN\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"statements\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"b\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"...\"],\n  [\"variable.parameter\",\"r\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"400\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"b\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"c\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"async\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"param\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"expression\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"//test JSX functions arguments in arrow functions\"]\n],[\n   [\"start\",\"no_regex\",\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"Component\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"onclick\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"param2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Test\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"...\"],\n  [\"variable.parameter\",\"paramN\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"no_regex\",\"start\",\"no_regex\",\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Test\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   [\"start\",\"no_regex\",\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"Component\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"onclick\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"paren.quasi.start\",\"{\"],\n  [\"variable.parameter\",\"param1\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"no_regex\",\"start\",\"no_regex\",\"start\",\"jsxAttributes\",\"jsxAttributes\",\"jsx\",1],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Test\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"//test different generator functions use cases\"]\n],[\n   \"no_regex\",\n  [\"storage.type\",\"function\"],\n  [\"storage.type\",\"*\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"generator\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"storage.type\",\"function\"],\n  [\"storage.type\",\"*\"],\n  [\"entity.name.function\",\"generator\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"Sound\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"play\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"storage.type\",\"*\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"play\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"entity.name.function\",\"foobar\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\"   \"],\n  [\"storage.type\",\"*\"],\n  [\"text\",\"   \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"comment\",\"//func's args shouldn't be determined as arrow function\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"func\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"identifier\",\"b\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"async\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"no_regex\",\n  [\"identifier\",\"func\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"identifier\",\"b\"],\n  [\"punctuation.operator\",\",\"],\n  [\"identifier\",\"innerCall\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"c\"],\n  [\"punctuation.operator\",\",\"],\n  [\"identifier\",\"d\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"comment\",\"//async arrow function with default params\"]\n],[\n   \"start\",\n  [\"keyword\",\"async\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"param2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"...\"],\n  [\"variable.parameter\",\"paramN\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"no_regex\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"statements\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"comment\",\"//all should be constant.numeric\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"1_000_000_000_000\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"1_050.95\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"0b1010_0001_1000_0101\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"0o2_2_5_6\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"0xA0_B0_C0\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"1_000_000_000_000_000_000_000\"],\n  [\"identifier\",\"n\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"1.0_1322323_33\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"1.\"]\n],[\n   \"no_regex\",\n  [\"constant.numeric\",\"0.4_3223_32\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jexl.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#pragma\"],\n  [\"text\",\" execution.option 42\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"##\"]\n],[\n   \"start\",\n  [\"comment\",\"## This is a test script\"]\n],[\n   \"start\",\n  [\"comment\",\"##\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/* This is\"]\n],[\n   \"comment\",\n  [\"comment\",\"a multi-line\"]\n],[\n   \"comment\",\n  [\"comment\",\"comment\"]\n],[\n   \"start\",\n  [\"comment\",\"*/\"]\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"result\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"out\"],\n  [\"punctuation\",\".\"],\n  [\"identifier\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"The result is \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"result\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"~/\\\\w+\"],\n  [\"constant.language.escape\",\"\\\\/\"],\n  [\"string.regexp\",\"test/\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"result\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"out\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"out\"],\n  [\"punctuation\",\".\"],\n  [\"identifier\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"The result is \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"result\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.annotation\",\"@lenient\"],\n  [\"text\",\" \"],\n  [\"storage.type.annotation\",\"@silent\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"punctuation\",\".\"],\n  [\"identifier\",\"someMethod\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"string\",\n  [\"string\",\"`multi-line string\"]\n],[\n   \"start\",\n  [\"string\",\"with \"],\n  [\"lparen\",\"${\"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"interpolation\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hey!\\\"\"],\n  [\"rparen\",\"}\"],\n  [\"string\",\" and \"],\n  [\"constant.language.escape\",\"\\\\\"],\n  [\"string\",\"escap\"],\n  [\"constant.language.escape\",\"\\\\u00E9\"],\n  [\"string\",\" chars`\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_json.json",
    "content": "[[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"variable\",\"\\\"query\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"count\\\"\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"10\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"created\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"2011-06-21T08:10:46Z\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"lang\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"en-US\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"results\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"variable\",\"\\\"photo\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"farm\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"6\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"id\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5855620975\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfamily\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfriend\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"ispublic\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"1\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"owner\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"32021554@N04\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"secret\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"f1f5e8515d\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"server\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5110\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"title\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"7087 bandit cat\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"farm\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"4\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"id\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5856170534\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfamily\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfriend\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"ispublic\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"1\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"owner\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"32021554@N04\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"secret\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"ff1efb2a6f\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"server\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"3217\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"title\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"6975 rusty cat\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"farm\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"6\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"id\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5856172972\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfamily\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfriend\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"ispublic\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"1\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"owner\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"51249875@N03\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"secret\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"6c6887347c\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"server\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5192\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"title\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"watermarked-cats\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"farm\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"6\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"id\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5856168328\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfamily\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfriend\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"ispublic\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"1\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"owner\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"32021554@N04\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"secret\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0c1cfdf64c\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"server\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5078\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"title\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"7020 mandy cat\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"farm\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"3\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"id\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"5856171774\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfamily\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"isfriend\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"ispublic\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"1\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"owner\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"32021554@N04\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"secret\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"7f5a3180ab\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"server\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"2696\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"variable\",\"\\\"title\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"7448 bobby cat\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_json5.json",
    "content": "[[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"foo\"],\n  [\"text\",\": \"],\n  [\"string\",\"'bar'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"while\"],\n  [\"text\",\": \"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\"\n],[\n   \"string0\",\n  [\"text\",\"  \"],\n  [\"variable\",\"this\"],\n  [\"text\",\": \"],\n  [\"string\",\"'is a \"],\n  [\"constant.language.escape\",\"\\\\\"]\n],[\n   \"start\",\n  [\"string\",\"multi-line string'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// this is an inline comment\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"here\"],\n  [\"text\",\": \"],\n  [\"string\",\"'is another'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// inline comment\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"text\",\"  \"],\n  [\"comment.start\",\"/*\"],\n  [\"comment\",\" this is a block comment\"]\n],[\n   \"start\",\n  [\"comment\",\"     that continues on another line \"],\n  [\"comment.end\",\"*/\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"hex\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0xDEADbeef\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"half\"],\n  [\"text\",\": .\"],\n  [\"constant.numeric\",\"5\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"delta\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"+10\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"to\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"Infinity\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\"   \"],\n  [\"comment\",\"// and beyond!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"finally\"],\n  [\"text\",\": \"],\n  [\"string\",\"'a trailing comma'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"oh\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"\\\"we shouldn't forget\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"'arrays can have'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"'trailing commas too'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jsp.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"abc\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"css-start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"        \"],\n  [\"variable\",\".class\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"            \"],\n  [\"support.type\",\"background\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#124356\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"css-start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        Today's date: \"],\n  [\"meta.tag\",\"<%\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"java\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"util\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"Date\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\"))\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"toLocaleString\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag\",\"<%\"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\"; \"],\n  [\"meta.tag\",\"%>\"]\n],[\n   \"jsp-start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag\",\"<jsp:declaration>\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag\",\"</jsp:declaration>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment\",\"<%-- This is JSP comment --%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag\",\"<%@\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"directive\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"attribute\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\"\\\"value\\\"\"],\n  [\"text\",\" \"],\n  [\"meta.tag\",\"%>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Select Languages:\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"form\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"ACTION\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"jspCheckBox.jsp\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"checkbox\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"id\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Java\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" Java\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"BR\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"checkbox\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"id\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\".NET\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" .NET\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"BR\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"checkbox\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"id\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"PHP\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" PHP\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"BR\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"checkbox\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"id\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"C/C++\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" C/C++\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"BR\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"checkbox\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"id\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"PERL\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" PERL \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"BR\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"submit\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Submit\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.form.tag-name.xml\",\"form\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"jsp-start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag\",\"<%\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"String\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"select\"],\n  [\"lparen\",\"[\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"request\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"getParameterValues\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"id\\\"\"],\n  [\"rparen\",\")\"],\n  [\"text\",\"; \"]\n],[\n   \"jsp-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"select\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"select\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"length\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"        \"],\n  [\"variable.language\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"string\",\"\\\"You have selected: \\\"\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"select\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"length\"],\n  [\"text\",\"; \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"++\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"           \"],\n  [\"variable.language\",\"out\"],\n  [\"text\",\".\"],\n  [\"entity.name.function\",\"println\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"select\"],\n  [\"lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"rparen\",\"])\"],\n  [\"text\",\"; \"]\n],[\n   \"jsp-start\",\n  [\"text\",\"        \"],\n  [\"rparen\",\"}\"]\n],[\n   \"jsp-start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"meta.tag\",\"%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jssm.json",
    "content": "[[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language.jssmLanguage\",\"machine_name    :\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.doublequoted\",\"\\\"Three-state traffic light, plus off and flash-red\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"constant.language.jssmLanguage\",\"machine_version :\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.2.1\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"constant.language.jssmLanguage\",\"jssm_version    :\"],\n  [\"text\",\" >= \"],\n  [\"constant.numeric\",\"5.0.0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"constant.language.jssmLanguage\",\"graph_layout    :\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"dot\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.tag.jssmLabel.atom\",\"on_init\"],\n  [\"text\",\"         : \"],\n  [\"entity.name.function\",\"${\"],\n  [\"keyword.other\",\"setup\"],\n  [\"entity.name.function\",\"}\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.jssmLabel.atom\",\"on_halt\"],\n  [\"text\",\"         : \"],\n  [\"entity.name.function\",\"${\"],\n  [\"keyword.other\",\"finalize\"],\n  [\"entity.name.function\",\"}\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.mn\",\"/*\"],\n  [\"comment.block.jssm\",\" turn on \"],\n  [\"punctuation.definition.comment.mn\",\"*/\"]\n],[\n   \"start\",\n  [\"entity.name.tag.jssmLabel.atom\",\"Off\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Enable'\"],\n  [\"text\",\" { \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"follow\"],\n  [\"text\",\": \"],\n  [\"entity.name.function\",\"${\"],\n  [\"keyword.other\",\"turned_on\"],\n  [\"entity.name.function\",\"}\"],\n  [\"text\",\"; } \"],\n  [\"keyword.control.transition.jssmArrow.none_legal\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.jssm\",\"// main sequence\"]\n],[\n   \"start\",\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Proceed'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.jssmArrow.none_main\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Green\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Proceed'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.jssmArrow.none_main\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Yellow\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Proceed'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.jssmArrow.none_main\",\"=>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.jssm\",\"// emergency flash red\"]\n],[\n   \"start\",\n  [\"text\",\"[\"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Yellow\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Green\"],\n  [\"text\",\"] \"],\n  [\"constant.character.jssmAction\",\"'Flash'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.jssmArrow.none_legal\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Flash\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"entity.name.tag.jssmLabel.atom\",\"Flash\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Proceed'\"],\n  [\"text\",\" { \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"label\"],\n  [\"text\",\": \"],\n  [\"constant.character.jssmAction\",\"'no change'\"],\n  [\"text\",\"; } \"],\n  [\"keyword.control.transition.jssmArrow.none_legal\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Flash\"],\n  [\"text\",\" \"],\n  [\"constant.character.jssmAction\",\"'Exit'\"],\n  [\"text\",\" \"],\n  [\"keyword.control.transition.jssmArrow.none_legal\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.jssm\",\"// turn off\"]\n],[\n   \"start\",\n  [\"text\",\"[\"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Red\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Yellow\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Green\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Flash\"],\n  [\"text\",\"] \"],\n  [\"constant.character.jssmAction\",\"'Disable'\"],\n  [\"text\",\" { \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"follow\"],\n  [\"text\",\": \"],\n  [\"entity.name.function\",\"${\"],\n  [\"keyword.other\",\"turned_off\"],\n  [\"entity.name.function\",\"}\"],\n  [\"text\",\"; } \"],\n  [\"keyword.control.transition.jssmArrow.none_forced\",\"~>\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.jssmLabel.atom\",\"Off\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_jsx.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"as\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"React\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"react\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"export\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"default\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   [\"jsx\",1],\n  [\"text\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"variant\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"p\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"jsx\",1],\n  [\"string.xml\",\"      Keywords here are not highlighted, for example class or instance.\"]\n],[\n   \"start\",\n  [\"string.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_julia.json",
    "content": "[[\n   \"start\",\n  [\"keyword.control.julia\",\"for\"],\n  [\"text\",\" op \"],\n  [\"keyword.operator.update.julia\",\"=\"],\n  [\"text\",\" (\"],\n  [\"keyword.operator.ternary.julia\",\":\"],\n  [\"keyword.operator.arithmetic.julia\",\"+\"],\n  [\"text\",\", \"],\n  [\"keyword.operator.ternary.julia\",\":\"],\n  [\"keyword.operator.arithmetic.julia\",\"*\"],\n  [\"text\",\", \"],\n  [\"keyword.operator.ternary.julia\",\":\"],\n  [\"keyword.operator.bitwise.julia\",\"&\"],\n  [\"text\",\", \"],\n  [\"keyword.operator.ternary.julia\",\":\"],\n  [\"keyword.operator.bitwise.julia\",\"|\"],\n  [\"text\",\", \"],\n  [\"keyword.operator.ternary.julia\",\":\"],\n  [\"keyword.operator.interpolation.julia\",\"$\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.macro.julia\",\"@eval\"],\n  [\"text\",\" (\"],\n  [\"keyword.operator.interpolation.julia\",\"$\"],\n  [\"text\",\"op)(a,b,c) \"],\n  [\"keyword.operator.update.julia\",\"=\"],\n  [\"text\",\" (\"],\n  [\"keyword.operator.interpolation.julia\",\"$\"],\n  [\"text\",\"op)((\"],\n  [\"keyword.operator.interpolation.julia\",\"$\"],\n  [\"text\",\"op)(a,b),c)\"]\n],[\n   \"start\",\n  [\"keyword.control.julia\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"v \"],\n  [\"keyword.operator.update.julia\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable\",\"α\"],\n  [\"keyword.operator.transposed-variable.julia\",\"'\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword.other.julia\",\"function\"],\n  [\"meta.function.julia\",\" \"],\n  [\"entity.name.function.julia\",\"g\"],\n  [\"text\",\"(\"],\n  [\"text\",\"x,y)\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.julia\",\"return\"],\n  [\"text\",\" x \"],\n  [\"keyword.operator.arithmetic.julia\",\"*\"],\n  [\"text\",\" y\"]\n],[\n   \"start\",\n  [\"text\",\"  x \"],\n  [\"keyword.operator.arithmetic.julia\",\"+\"],\n  [\"text\",\" y\"]\n],[\n   \"start\",\n  [\"keyword.control.julia\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.julia\",\"cd\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.julia\",\"\\\"\"],\n  [\"string.quoted.double.julia\",\"data\"],\n  [\"punctuation.definition.string.end.julia\",\"\\\"\"],\n  [\"text\",\") \"],\n  [\"keyword.control.julia\",\"do\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.julia\",\"open\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.julia\",\"\\\"\"],\n  [\"string.quoted.double.julia\",\"outfile\"],\n  [\"punctuation.definition.string.end.julia\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"punctuation.definition.string.begin.julia\",\"\\\"\"],\n  [\"string.quoted.double.julia\",\"w\"],\n  [\"punctuation.definition.string.end.julia\",\"\\\"\"],\n  [\"text\",\") \"],\n  [\"keyword.control.julia\",\"do\"],\n  [\"text\",\" f\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.julia\",\"write\"],\n  [\"text\",\"(\"],\n  [\"text\",\"f, data)\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.julia\",\"end\"]\n],[\n   \"start\",\n  [\"keyword.control.julia\",\"end\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_kotlin.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#!/usr/bin/env kotlinc -script\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"/*Taken from http://try.kotlinlang.org/#/Examples/Longer%20examples/Life/Life.kt*/\"]\n],[\n   \"comment\",\n  [\"comment\",\"/**\"]\n],[\n   \"comment\",\n  [\"comment\",\" * This is a straightforward implementation of The Game of Life\"]\n],[\n   \"comment\",\n  [\"comment\",\" * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"package\"],\n  [\"text\",\" \"],\n  [\"entity.name.package.kotlin\",\"life\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment\",\" * A field where cells live. Effectively immutable\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Field\"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"width\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation.kotlin\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"height\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation.kotlin\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// This function tells the constructor which cells are alive\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// if init(i, j) is true, the cell (i, j) is alive\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"init\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.declaration.kotlin\",\"->\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Boolean\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.modifier.kotlin\",\"private\"],\n  [\"text\",\" \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"live\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Array\"],\n  [\"punctuation\",\"<\"],\n  [\"storage.type.generic.kotlin\",\"Array\"],\n  [\"punctuation\",\"<\"],\n  [\"storage.type.generic.kotlin\",\"Boolean\"],\n  [\"punctuation\",\">>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Array\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"height\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Array\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"width\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"init\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.modifier.kotlin\",\"private\"],\n  [\"text\",\" \"],\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"i\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.function.kotlin\",\"j\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"0\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"identifier\",\"height\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.logical.kotlin\",\"&&\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"0\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"identifier\",\"width\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.logical.kotlin\",\"&&\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"live\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\"])\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"0\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// How many neighbors of (i, j) are alive?\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"liveNeighbors\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"i\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.function.kotlin\",\"j\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"liveCount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// You can say field[i, j], and this function gets called\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.modifier.kotlin\",\"operator\"],\n  [\"text\",\" \"],\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"get\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"i\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.function.kotlin\",\"j\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"live\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Test\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"constructor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"var\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"test\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"test\\\"\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/**\"]\n],[\n   \"comment\",\n  [\"comment\",\" * This function takes the present state of the field\"]\n],[\n   \"comment\",\n  [\"comment\",\" * and returns a new field representing the next moment of time\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"next\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"field\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" Field\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" Field \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Field\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"field\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"width\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"field\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"height\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"field\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"liveNeighbors\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"field\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\"])\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// (i, j) is alive\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"2\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"constant.numeric.kotlin\",\"3\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// It remains alive iff it has 2 or 3 neighbors\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// (i, j) is dead\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"3\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// A new cell is born if there are 3 neighbors alive\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"/** A few colony examples here */\"]\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"args\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Array\"],\n  [\"punctuation\",\"<\"],\n  [\"storage.type.generic.kotlin\",\"String\"],\n  [\"punctuation\",\">\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// Simplistic demo\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"***\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"3\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// \\\"Star burst\\\"\"]\n],[\n   \"string\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"string\",\n  [\"string\",\"        _______\"]\n],[\n   \"string\",\n  [\"string\",\"        ___*___\"]\n],[\n   \"string\",\n  [\"string\",\"        __***__\"]\n],[\n   \"string\",\n  [\"string\",\"        ___*___\"]\n],[\n   \"string\",\n  [\"string\",\"        _______\"]\n],[\n   \"start\",\n  [\"string\",\"    \\\"\\\"\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"10\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// Stable colony\"]\n],[\n   \"string\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"string\",\n  [\"string\",\"        _____\"]\n],[\n   \"string\",\n  [\"string\",\"        __*__\"]\n],[\n   \"string\",\n  [\"string\",\"        _*_*_\"]\n],[\n   \"string\",\n  [\"string\",\"        __*__\"]\n],[\n   \"string\",\n  [\"string\",\"        _____\"]\n],[\n   \"start\",\n  [\"string\",\"    \\\"\\\"\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"3\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// Stable from the step 2\"]\n],[\n   \"string\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"string\",\n  [\"string\",\"        __**__\"]\n],[\n   \"string\",\n  [\"string\",\"        __**__\"]\n],[\n   \"string\",\n  [\"string\",\"        __**__\"]\n],[\n   \"start\",\n  [\"string\",\"    \\\"\\\"\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"3\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// Oscillating colony\"]\n],[\n   \"string\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"string\",\n  [\"string\",\"        __**____\"]\n],[\n   \"string\",\n  [\"string\",\"        __**____\"]\n],[\n   \"string\",\n  [\"string\",\"        ____**__\"]\n],[\n   \"string\",\n  [\"string\",\"        ____**__\"]\n],[\n   \"start\",\n  [\"string\",\"    \\\"\\\"\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"6\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// A fancier oscillating colony\"]\n],[\n   \"string\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"string\",\n  [\"string\",\"        -------------------\"]\n],[\n   \"string\",\n  [\"string\",\"        -------***---***---\"]\n],[\n   \"string\",\n  [\"string\",\"        -------------------\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -------***---***---\"]\n],[\n   \"string\",\n  [\"string\",\"        -------------------\"]\n],[\n   \"string\",\n  [\"string\",\"        -------***---***---\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -----*----*-*----*-\"]\n],[\n   \"string\",\n  [\"string\",\"        -------------------\"]\n],[\n   \"string\",\n  [\"string\",\"        -------***---***---\"]\n],[\n   \"string\",\n  [\"string\",\"        -------------------\"]\n],[\n   \"start\",\n  [\"string\",\"    \\\"\\\"\\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"10\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"// UTILITIES\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"runGameOfLife\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"fieldText\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"String\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.function.kotlin\",\"steps\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"Int\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other.kotlin\",\"var\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"field\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"makeField\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"fieldText\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"step\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"identifier\",\"steps\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Step: \"],\n  [\"variable.parameter.template.kotlin\",\"$step\"],\n  [\"string\",\"\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"0\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"identifier\",\"field\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"height\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"0\"],\n  [\"keyword.operator.dot.kotlin\",\"..\"],\n  [\"identifier\",\"field\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"width\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.arithmetic.kotlin\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.kotlin\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"field\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\"])\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"*\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" \\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"field\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"next\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"field\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.kotlin\",\"fun\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"makeField\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter.function.kotlin\",\"s\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.buildin.kotlin\",\"String\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator.declaration.kotlin\",\":\"],\n  [\"text\",\" Field \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"lines\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"s\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"replace\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\" \\\"\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"split\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'\"],\n  [\"constant.character.escape.kotlin\",\"\\\\n\"],\n  [\"string\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"filter\"],\n  [\"paren.lparen\",\"({\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"it\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"isNotEmpty\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other.kotlin\",\"val\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.kotlin\",\"longestLine\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.kotlin\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lines\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"toList\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"maxBy\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"it\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"length\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"?:\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Field\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"longestLine\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"length\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lines\"],\n  [\"keyword.operator.dot.kotlin\",\".\"],\n  [\"identifier\",\"size\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.kotlin\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lines\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.kotlin\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"'*'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_latex.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"\\\\usepackage\"],\n  [\"lparen\",\"{\"],\n  [\"storage.type\",\"amsmath\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type\",\"\\\\title\"],\n  [\"lparen\",\"{\"],\n  [\"storage.type\",\"\\\\LaTeX\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type\",\"\\\\date\"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type\",\"\\\\begin\"],\n  [\"lparen\",\"{\"],\n  [\"variable.parameter\",\"document\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"\\\\maketitle\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"\\\\LaTeX\"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" is a document preparation system for the \"],\n  [\"storage.type\",\"\\\\TeX\"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  typesetting program. It offers programmable desktop publishing\"]\n],[\n   \"start\",\n  [\"text\",\"  features and extensive facilities for automating most aspects of\"]\n],[\n   \"start\",\n  [\"text\",\"  typesetting and desktop publishing, including numbering and\"]\n],[\n   \"start\",\n  [\"text\",\"  cross-referencing, tables and figures, page layout, bibliographies,\"]\n],[\n   \"start\",\n  [\"text\",\"  and much more. \"],\n  [\"storage.type\",\"\\\\LaTeX\"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" was originally written in 1984 by Leslie\"]\n],[\n   \"start\",\n  [\"text\",\"  Lamport and has become the dominant method for using \"],\n  [\"storage.type\",\"\\\\TeX\"],\n  [\"text\",\"; few\"]\n],[\n   \"start\",\n  [\"text\",\"  people write in plain \"],\n  [\"storage.type\",\"\\\\TeX\"],\n  [\"lparen\",\"{\"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" anymore. The current version  is\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"\\\\LaTeXe\"],\n  [\"text\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"% This is a comment; it will not be shown in the final output.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"% The following shows a little of the typesetting power of LaTeX:\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"\\\\begin\"],\n  [\"lparen\",\"{\"],\n  [\"variable.parameter\",\"align\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    E &= mc^2                              \"],\n  [\"constant.character.escape\",\"\\\\\\\\\"]\n],[\n   \"start\",\n  [\"text\",\"    m &= \"],\n  [\"storage.type\",\"\\\\frac\"],\n  [\"lparen\",\"{\"],\n  [\"text\",\"m_0\"],\n  [\"rparen\",\"}\"],\n  [\"lparen\",\"{\"],\n  [\"storage.type\",\"\\\\sqrt\"],\n  [\"lparen\",\"{\"],\n  [\"text\",\"1-\"],\n  [\"storage.type\",\"\\\\frac\"],\n  [\"lparen\",\"{\"],\n  [\"text\",\"v^2\"],\n  [\"rparen\",\"}\"],\n  [\"lparen\",\"{\"],\n  [\"text\",\"c^2\"],\n  [\"rparen\",\"}}}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"\\\\end\"],\n  [\"lparen\",\"{\"],\n  [\"variable.parameter\",\"align\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type\",\"\\\\end\"],\n  [\"lparen\",\"{\"],\n  [\"variable.parameter\",\"document\"],\n  [\"rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_latte.json",
    "content": "[[\n   \"start\",\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"doctype\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$title\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"comment.start.latte\",\n  [\"text.xml\",\"        \"],\n  [\"comment.start.latte\",\"{*\"],\n  [\"comment\",\" \"]\n],[\n   \"comment.start.latte\",\n  [\"comment\",\"        \\tcomment\"]\n],[\n   \"start\",\n  [\"comment.end.latte\",\"        *}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.attribute.latte\",\"n:inner-if\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"constant.numeric\",\"0\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"entity.other.attribute-name.xml\",\"My\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"Webpage\"],\n  [\"text\",\"</\"],\n  [\"entity.other.attribute-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.attribute.latte\",\"n:if\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"string.unquoted\",\"count\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$navigation\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\" > \"],\n  [\"constant.numeric\",\"0\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"navigation\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"meta.tag.latte\",\"foreach\"],\n  [\"keyword.operator\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string.unquoted\",\"a\"],\n  [\"keyword.operator\",\", \"],\n  [\"string.unquoted\",\"b\"],\n  [\"keyword.operator\",\", \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"x\"],\n  [\"string.end\",\"'\"],\n  [\"keyword.operator\",\", \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\" \"],\n  [\"keyword.control\",\"as\"],\n  [\"keyword.operator\",\" \"],\n  [\"variable\",\"$item\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$item\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"meta.tag.latte\",\"test\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$item\"],\n  [\"keyword.operator\",\"->\"],\n  [\"string.unquoted\",\"caption\"],\n  [\"paren.rparen\",\")\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{/\"],\n  [\"meta.tag.latte\",\"foreach\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$variable\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"meta.tag.latte\",\"=\"],\n  [\"variable\",\"$variable\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$variable\"],\n  [\"keyword.operator\",\"|\"],\n  [\"string.unquoted\",\"filter\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$variable\"],\n  [\"keyword.operator\",\"|\"],\n  [\"string.unquoted\",\"filter\"],\n  [\"keyword.operator\",\":\"],\n  [\"constant.numeric\",\"10\"],\n  [\"keyword.operator\",\",\"],\n  [\"constant.numeric\",\"20\"],\n  [\"keyword.operator\",\"|\"],\n  [\"string.unquoted\",\"filter2\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"]\n],[\n   \"start\"\n],[\n   \"js-start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"text\",\"\\t        \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$a\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"'a'\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"c\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"'a'\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"\\t        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"\\t        \\t\"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"\\t        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"css-start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"css-start\",\n  [\"text\",\"        \\t\"],\n  [\"constant\",\"body\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"color\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-open.latte\",\"{\"],\n  [\"variable\",\"$color\"],\n  [\"meta.tag.punctuation.tag-close.latte\",\"}\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_less.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"/* styles.less */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"@base\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"#f938ab\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\".box-shadow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@style\"],\n  [\"text\",\", \"],\n  [\"variable\",\"@c\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"when\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"iscolor\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@c\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type.property\",\"box-shadow\"],\n  [\"text\",\":\"],\n  [\"text\",\"         \"],\n  [\"variable\",\"@style\"],\n  [\"text\",\" \"],\n  [\"variable\",\"@c\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type.unknownProperty\",\"-webkit-box-shadow\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"variable\",\"@style\"],\n  [\"text\",\" \"],\n  [\"variable\",\"@c\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type.unknownProperty\",\"-moz-box-shadow\"],\n  [\"text\",\":\"],\n  [\"text\",\"    \"],\n  [\"variable\",\"@style\"],\n  [\"text\",\" \"],\n  [\"variable\",\"@c\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"variable.language\",\".box-shadow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@style\"],\n  [\"text\",\", \"],\n  [\"variable\",\"@alpha\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"50\"],\n  [\"keyword\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"when\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"isnumber\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@alpha\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language\",\".box-shadow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@style\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"rgba\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"variable\",\"@alpha\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"// Box styles\"]\n],[\n   \"start\",\n  [\"variable.language\",\".box\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type.property\",\"color\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"saturate\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@base\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"5\"],\n  [\"keyword\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type.property\",\"border-color\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@base\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"30\"],\n  [\"keyword\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"div\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\".box-shadow\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"keyword\",\"px\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"30\"],\n  [\"keyword\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type.property\",\"color\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"variable\",\"@base\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"&\"],\n  [\"variable.language\",\":hover\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"support.type.property\",\"color\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"@base\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"50\"],\n  [\"keyword\",\"%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_liquid.json",
    "content": "[[\n   \"start\",\n  [\"text.xml\",\"There are a couple of different Liquid variations in circulation. This grammars supports\"]\n],[\n   \"start\",\n  [\"text.xml\",\"both the Standard and Shopify Liquid variations. The following examples can be found in full at:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"Standard Variation: https://shopify.github.io/liquid\"]\n],[\n   \"start\",\n  [\"text.xml\",\"Shopify Variation: https://shopify.dev/docs/api/liquid\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"Liquid is an extraction from the e-commerce system Shopify.\"]\n],[\n   \"start\",\n  [\"text.xml\",\"Shopify powers many thousands of e-commerce stores which all call for unique designs.\"]\n],[\n   \"start\",\n  [\"text.xml\",\"For this we developed Liquid which allows our customers complete design freedom while\"]\n],[\n   \"start\",\n  [\"text.xml\",\"maintaining the integrity of our servers.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"Liquid has been in production use since June 2006 and is now used by many other\"]\n],[\n   \"start\",\n  [\"text.xml\",\"hosted web applications.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"It was developed for usage in Ruby on Rails web applications and integrates seamlessly\"]\n],[\n   \"start\",\n  [\"text.xml\",\"as a plugin but it also works excellently as a stand alone library.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"Here's what it looks like:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"products\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" for\"],\n  [\"text\",\" product\"],\n  [\"keyword.operator\",\" in \"],\n  [\"text\",\"products \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"product\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"title\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        Only \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"product\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"price\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"format_as_money\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"product\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"description\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"prettyprint\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"truncate\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"200\"],\n  [\"text\",\"  \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"      \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endfor\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"Some more features include:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Filters\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" The word \\\"tobi\\\" in uppercase: \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"string\",\"'tobi'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"upcase\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"text.xml\",\" \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"The word \\\"tobi\\\" has \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"string\",\"'tobi'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"size\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"text.xml\",\" letters! \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Change \\\"Hello world\\\" to \\\"Hi world\\\": \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"string\",\"'Hello world'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"replace\"],\n  [\"text\",\": \"],\n  [\"string\",\"'Hello'\"],\n  [\"text\",\", \"],\n  [\"string\",\"'Hi'\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"text.xml\",\" \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"The date today is \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"string\",\"'now'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"date\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"%Y %b %d\\\"\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"text.xml\",\" \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"If\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" if\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"user\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"'tobi'\"],\n  [\"text\",\" or \"],\n  [\"support.class\",\"user\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"'marc'\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    hi marc or tobi\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endif\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Comments\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"{% #\"],\n  [\"comment\",\" Line Comment  \"],\n  [\"comment.line\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"comment.block\",\n  [\"comment.block\",\"{% comment %}\"]\n],[\n   \"comment.block\",\n  [\"comment\",\"  Block Comment\"]\n],[\n   \"start\",\n  [\"comment.block\",\"{% endcomment %}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Case\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" case\"],\n  [\"text\",\" template \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" when\"],\n  [\"text\",\" \"],\n  [\"string\",\"'index'\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"       Welcome\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" when\"],\n  [\"text\",\" \"],\n  [\"string\",\"'product'\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"       \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"product\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"vendor\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"| \"],\n  [\"support.function\",\"link_to_vendor\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"],\n  [\"text.xml\",\" / \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"product\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"title\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" else\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"       \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" page_title \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endcase\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"For Loops\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" for\"],\n  [\"text\",\" item\"],\n  [\"keyword.operator\",\" in \"],\n  [\"text\",\"array \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" item \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endfor\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Tables\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" tablerow\"],\n  [\"text\",\" item\"],\n  [\"keyword.operator\",\" in \"],\n  [\"text\",\"items\"],\n  [\"support.function\",\" cols\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" if\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"tablerowloop\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"col_first\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      First column: \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"item\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"variable\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" else\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      Different column: \"],\n  [\"meta.tag.punctuation.ouput-open\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.class\",\"item\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.object\",\"variable\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.ouput-close\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endif\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"keyword.block\",\" endtablerow\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Embedded Code Blocks\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"This support Shopify Liquid variation JSON schema code blocks\"]\n],[\n   \"start\"\n],[\n   \"schema-start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagschema.tag-name\",\"schema\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"schema-start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"schema-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"\\\"string\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"bar\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"schema-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"\\\"boolean\\\"\"],\n  [\"text\",\": \"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"schema-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"\\\"number\\\"\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"100\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"schema-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"\\\"object\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"schema-start\",\n  [\"text\",\"      \"],\n  [\"variable\",\"\\\"array\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"100\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean\",\"false\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"string\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"schema-start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"schema-start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagendschema.tag-name\",\"endschema\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"This support Shopify Liquid variation Stylesheet and Style code blocks\"]\n],[\n   \"start\"\n],[\n   \"style-start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagstyle.tag-name\",\"style\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"style-ruleset\",\n  [\"text\",\" \"],\n  [\"variable\",\".class\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"style-ruleset\",\n  [\"text\",\"   \"],\n  [\"support.type\",\"font-size\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"keyword\",\"px\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* comment */\"]\n],[\n   \"style-start\",\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagendstyle.tag-name\",\"endstyle\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"stylesheet-start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagstylesheet.tag-name\",\"stylesheet\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"stylesheet-ruleset\",\n  [\"text\",\" \"],\n  [\"variable\",\".class\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"stylesheet-ruleset\",\n  [\"text\",\"   \"],\n  [\"support.type\",\"font-size\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"keyword\",\"px\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"/* comment */\"]\n],[\n   \"stylesheet-start\",\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagendstylesheet.tag-name\",\"endstylesheet\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"This support Shopify Liquid variation JavaScript code blocks\"]\n],[\n   \"start\"\n],[\n   \"javascript-start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagjavascript.tag-name\",\"javascript\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"javascript-start\"\n],[\n   \"javascript-start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"param\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"javascript-start\"\n],[\n   \"javascript-no_regex\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"string\",\"'something'\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// comment\"]\n],[\n   \"javascript-no_regex\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"javascript-no_regex\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.tagendjavascript.tag-name\",\"endjavascript\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-close\",\"%}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_lisp.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"storage.type.function-type.lisp\",\"defun\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.lisp\",\"prompt-for-cd\"],\n  [\"text\",\" ()\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"string\",\"\\\"Prompts\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CD\"],\n  [\"text\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"identifier\",\"prompt\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Title\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.53\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\"/\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.7\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.7e0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2.9E-4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"+42\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-7\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"b001\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"b001/100\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"o777\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"O777\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"xabc55\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"c\"],\n  [\"text\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-5.6\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"identifier\",\"prompt\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Artist\\\"\"],\n  [\"text\",\" &\"],\n  [\"identifier\",\"rest\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"keyword.operator\",\"or\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"parse\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"integer\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"prompt\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Rating\\\"\"],\n  [\"text\",\") :\"],\n  [\"identifier\",\"junk\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"allowed\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"t\"],\n  [\"text\",\") \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" (\"],\n  [\"support.function\",\"format\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"t\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"yes\\\"\"],\n  [\"text\",\") (\"],\n  [\"support.function\",\"format\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"t\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"no\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"nil\"],\n  [\"text\",\") \"],\n  [\"comment\",\";and here comment\"]\n],[\n   \"start\",\n  [\"text\",\"  ) \"],\n  [\"constant.numeric\",\"0xFFLL\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-23ull\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\";; second line comment\"]\n],[\n   \"start\",\n  [\"text\",\"  '(+ \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"identifier\",\"defvar\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.variable.lisp\",\"*\"],\n  [\"variable.other.global.lisp\",\"lines\"],\n  [\"punctuation.definition.variable.lisp\",\"*\"],\n  [\"text\",\")                \"],\n  [\"comment\",\"; list of all lines\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"identifier\",\"position\"],\n  [\"text\",\"-\"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\"-\"],\n  [\"identifier\",\"not\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.lisp\",\"#\"],\n  [\"constant.character.lisp\",\"'sys::whitespacep\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"line\"],\n  [\"text\",\" :\"],\n  [\"identifier\",\"start\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"beg\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"support.function\",\"quote\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"privet\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  '(\"],\n  [\"identifier\",\"hello\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"world\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (* \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"34\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (:\"],\n  [\"identifier\",\"use\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"aaaa\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"keyword.control\",\"let\"],\n  [\"text\",\" ((\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\") (\"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    (\"],\n  [\"identifier\",\"print\"],\n  [\"text\",\" (+ \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  ) \"],\n  [\"support.function\",\"LAmbDa\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string\",\"\\\"asdad\"],\n  [\"constant.character.escape.lisp\",\"\\\\0\"],\n  [\"string\",\"eqweqe\\\"\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_livescript.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# comment\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_logiql.json",
    "content": "[[\n   \"start\",\n  [\"comment.single\",\"// ancestors\"]\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"douglas\\\"\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"john\\\"\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"john\\\"\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"bob\\\"\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"bob\\\"\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"ebbon\\\"\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"douglas\\\"\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"jane\\\"\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"jane\\\"\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"jan\\\"\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name\",\"ancestorof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\") \"],\n  [\"keyword.start\",\"<-\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\",\n  [\"entity.name\",\"ancestorof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"C\"],\n  [\"text\",\") \"],\n  [\"keyword.start\",\"<-\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"ancestorof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\")\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"B\"],\n  [\"keyword.other\",\",\"],\n  [\"variable.parameter\",\"C\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name\",\"grandparentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\") \"],\n  [\"keyword.start\",\"<-\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"C\"],\n  [\"text\",\")\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"C\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name\",\"cousins\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\") \"],\n  [\"keyword.start\",\"<-\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"grandparentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"C\"],\n  [\"keyword.other\",\",\"],\n  [\"variable.parameter\",\"A\"],\n  [\"text\",\")\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"grandparentof\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"C\"],\n  [\"keyword.other\",\",\"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name\",\"parentof\"],\n  [\"text\",\"[\"],\n  [\"entity.name.type.logicblox\",\"`arg\"],\n  [\"text\",\"](\"],\n  [\"variable.parameter\",\"A\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\") \"],\n  [\"keyword.start\",\"->\"],\n  [\"text\",\" \"],\n  [\"entity.name\",\"int\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric\",\"32\"],\n  [\"text\",\"](\"],\n  [\"variable.parameter\",\"A\"],\n  [\"text\",\")\"],\n  [\"keyword.other\",\",\"],\n  [\"text\",\" \"],\n  [\"keyword.other\",\"!\"],\n  [\"entity.name\",\"string\"],\n  [\"text\",\"(\"],\n  [\"variable.parameter\",\"B\"],\n  [\"text\",\")\"],\n  [\"keyword.end\",\".\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_logtalk.json",
    "content": "[[\n   \"start\",\n  [\"storage.type.opening.logtalk\",\":- object\"],\n  [\"text\",\"(bottles)\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"storage.modifier.others.logtalk\",\":- initialization\"],\n  [\"text\",\"(sing(\"],\n  [\"constant.numeric.logtalk\",\"99\"],\n  [\"text\",\"))\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\tsing(\"],\n  [\"constant.numeric.logtalk\",\"0\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.message-sending.logtalk\",\":\"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\"No more bottles of beer on the wall, no more bottles of beer.\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\"Go to the store and buy some more, 99 bottles of beer on the wall.\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"\\tsing(\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.message-sending.logtalk\",\":\"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.comparison.arithmetic.logtalk\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.logtalk\",\"0\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"variable.other.logtalk\",\"N2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.misc.logtalk\",\"is\"],\n  [\"text\",\" \"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.logtalk\",\"1\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tbeers(\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\" of beer on the wall, \"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" beers(\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\" of beer.\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\"Take one down and pass it around, \"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" beers(\"],\n  [\"variable.other.logtalk\",\"N2\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\" of beer on the wall.\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.chars-and-bytes-io.logtalk\",\"nl\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\tsing(\"],\n  [\"variable.other.logtalk\",\"N2\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\tbeers(\"],\n  [\"constant.numeric.logtalk\",\"0\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.message-sending.logtalk\",\":\"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\"no more bottles\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"\\tbeers(\"],\n  [\"constant.numeric.logtalk\",\"1\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.message-sending.logtalk\",\":\"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\"1 bottle\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"\\tbeers(\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.message-sending.logtalk\",\":\"],\n  [\"keyword.operator.evaluable.logtalk\",\"-\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.comparison.arithmetic.logtalk\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.logtalk\",\"1\"],\n  [\"keyword.operator.misc.logtalk\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"variable.other.logtalk\",\"N\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function.term-io.logtalk\",\"write\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.logtalk\",\"'\"],\n  [\"string.quoted.single.logtalk\",\" bottles\"],\n  [\"punctuation.definition.string.end.logtalk\",\"'\"],\n  [\"text\",\")\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.closing.logtalk\",\":- end_object\"],\n  [\"keyword.operator.misc.logtalk\",\".\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_lsl.json",
    "content": "[[\n   \"comment\",\n  [\"comment.block.begin.lsl\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment.block.lsl\",\"    Testing syntax highlighting\"]\n],[\n   \"comment\",\n  [\"comment.block.lsl\",\"    of Ace Editor\"]\n],[\n   \"comment\",\n  [\"comment.block.lsl\",\"    for the Linden Scripting Language\"]\n],[\n   \"start\",\n  [\"comment.block.end.lsl\",\"*/\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someIntNormal\"],\n  [\"text.lsl\",\"       \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"3672\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someIntHex\"],\n  [\"text.lsl\",\"          \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"0x00000000\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someIntMath\"],\n  [\"text.lsl\",\"         \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.float.lsl\",\"PI_BY_TWO\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"invalid.illegal.lsl\",\"event\"],\n  [\"text.lsl\",\"               \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"5673\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\"                                             \"],\n  [\"comment.line.double-slash.lsl\",\"// invalid.illegal\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"key\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someKeyTexture\"],\n  [\"text.lsl\",\"          \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.string.lsl\",\"TEXTURE_DEFAULT\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"string\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someStringSpecial\"],\n  [\"text.lsl\",\"    \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.string.lsl\",\"EOF\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"some_user_defined_function_without_return_type\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"storage.type.lsl\",\"string\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"inputAsString\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"support.function.lsl\",\"llSay\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"constant.language.integer.lsl\",\"PUBLIC_CHANNEL\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"inputAsString\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.lsl\",\"string\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"user_defined_function_returning_a_string\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"storage.type.lsl\",\"key\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"inputAsKey\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"keyword.control.lsl\",\"return\"],\n  [\"text.lsl\",\" \"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"storage.type.lsl\",\"string\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"identifier\",\"inputAsKey\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.state.lsl\",\"default\"]\n],[\n   \"start\",\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"support.function.event.lsl\",\"state_entry\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"storage.type.lsl\",\"key\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someKey\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.string.lsl\",\"NULL_KEY\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someKey\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"support.function.lsl\",\"llGetOwner\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"storage.type.lsl\",\"string\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"someString\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"user_defined_function_returning_a_string\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"identifier\",\"someKey\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"some_user_defined_function_without_return_type\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"identifier\",\"someString\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"support.function.event.lsl\",\"touch_start\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"num_detected\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"storage.type.lsl\",\"list\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"agentsInRegion\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"support.function.lsl\",\"llGetAgentList\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"constant.language.integer.lsl\",\"AGENT_LIST_REGION\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"paren.lparen.lsl\",\"[\"],\n  [\"paren.rparen.lsl\",\"])\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"numOfAgents\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"support.function.lsl\",\"llGetListLength\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"identifier\",\"agentsInRegion\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"index\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\"                                                          \"],\n  [\"comment.line.double-slash.lsl\",\"// defaults to 0\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"keyword.control.lsl\",\"for\"],\n  [\"text.lsl\",\" \"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"index\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"<=\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"numOfAgents\"],\n  [\"text.lsl\",\" \"],\n  [\"keyword.operator.lsl\",\"-\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"1\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"index\"],\n  [\"keyword.operator.lsl\",\"++\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"text.lsl\",\"                               \"],\n  [\"comment.line.double-slash.lsl\",\"// for each agent in region\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"            \"],\n  [\"support.function.lsl\",\"llRegionSayTo\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"support.function.lsl\",\"llList2Key\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"identifier\",\"agentsInRegion\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"index\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.integer.lsl\",\"PUBLIC_CHANNEL\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"string.quoted.double.lsl.start\",\"\\\"\"],\n  [\"string.quoted.double.lsl\",\"Hello, Avatar!\"],\n  [\"string.quoted.double.lsl.end\",\"\\\"\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"support.function.event.lsl\",\"touch_end\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"storage.type.lsl\",\"integer\"],\n  [\"text.lsl\",\" \"],\n  [\"identifier\",\"num_detected\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someIntNormal\"],\n  [\"text.lsl\",\"       \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"3672\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someIntHex\"],\n  [\"text.lsl\",\"          \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"0x00000000\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someIntMath\"],\n  [\"text.lsl\",\"         \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.float.lsl\",\"PI_BY_TWO\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"invalid.illegal.lsl\",\"event\"],\n  [\"text.lsl\",\"               \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.numeric.lsl\",\"5673\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\"                                             \"],\n  [\"comment.line.double-slash.lsl\",\"// invalid.illegal\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someKeyTexture\"],\n  [\"text.lsl\",\"      \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.string.lsl\",\"TEXTURE_DEFAULT\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"identifier\",\"someStringSpecial\"],\n  [\"text.lsl\",\"   \"],\n  [\"keyword.operator.lsl\",\"=\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.string.lsl\",\"EOF\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"reserved.godmode.lsl\",\"llSetInventoryPermMask\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"string.quoted.double.lsl.start\",\"\\\"\"],\n  [\"string.quoted.double.lsl\",\"some item\"],\n  [\"string.quoted.double.lsl.end\",\"\\\"\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.integer.lsl\",\"MASK_NEXT\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"constant.language.integer.lsl\",\"PERM_ALL\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"],\n  [\"text.lsl\",\"               \"],\n  [\"comment.line.double-slash.lsl\",\"// reserved.godmode\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"support.function.lsl\",\"llWhisper\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"constant.language.integer.lsl\",\"PUBLIC_CHANNEL\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"string.quoted.double.lsl.start\",\"\\\"\"],\n  [\"string.quoted.double.lsl\",\"Leaving \"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\"default\"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\" now...\"],\n  [\"string.quoted.double.lsl.end\",\"\\\"\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"entity.name.state.lsl\",\"state other\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.state.lsl\",\"state other\"]\n],[\n   \"start\",\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"support.function.event.lsl\",\"state_entry\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"paren.rparen.lsl\",\")\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.lparen.lsl\",\"{\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"support.function.lsl\",\"llWhisper\"],\n  [\"paren.lparen.lsl\",\"(\"],\n  [\"constant.language.integer.lsl\",\"PUBLIC_CHANNEL\"],\n  [\"punctuation.operator.lsl\",\",\"],\n  [\"text.lsl\",\" \"],\n  [\"string.quoted.double.lsl.start\",\"\\\"\"],\n  [\"string.quoted.double.lsl\",\"Entered \"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\"state other\"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\", returning to \"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\"default\"],\n  [\"constant.character.escape.lsl\",\"\\\\\\\"\"],\n  [\"string.quoted.double.lsl\",\" again...\"],\n  [\"string.quoted.double.lsl.end\",\"\\\"\"],\n  [\"paren.rparen.lsl\",\")\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"        \"],\n  [\"entity.name.state.lsl\",\"state default\"],\n  [\"punctuation.operator.lsl\",\";\"]\n],[\n   \"start\",\n  [\"text.lsl\",\"    \"],\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen.lsl\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_lua.json",
    "content": "[[\n   [\"bracketedComment\",2,\"start\"],\n  [\n    \"comment\",\n    \"--[[\"\n  ],\n  [\n    \"comment.body\",\n    \"--\"\n  ]\n],[\n   [\"bracketedComment\",2,\"start\"],\n  [\n    \"comment.body\",\n    \"num_args takes in 5.1 byte code and extracts the number of arguments\"\n  ]\n],[\n   [\"bracketedComment\",2,\"start\"],\n  [\n    \"comment.body\",\n    \"from its function header.\"\n  ]\n],[\n   \"start\",\n  [\n    \"comment.body\",\n    \"--\"\n  ],\n  [\n    \"comment\",\n    \"]]--\"\n  ]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"t\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"0x100\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"0x10000\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"0x1000000\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"num_args\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"func\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"local\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"dump\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.library\",\"string\"],\n  [\"text\",\".\"],\n  [\"support.function\",\"dump\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"func\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"local\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"offset\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"cursor\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"dump\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"sub\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"13\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"offset\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"26\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"--Get the params and var flag (whether there's a ... in the param)\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"dump\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"sub\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"cursor\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"dump\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"sub\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"cursor\"],\n  [\"keyword.operator\",\"+\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"byte\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Usage:\"]\n],[\n   \"start\",\n  [\"identifier\",\"num_args\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"a\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"b\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"c\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\", \"],\n  [\"keyword.operator\",\"...\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"end\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- return 4, 7\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Python styled string format operator\"]\n],[\n   \"start\",\n  [\"keyword\",\"local\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"gm\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.library\",\"debug\"],\n  [\"text\",\".\"],\n  [\"support.function\",\"getmetatable\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"gm\"],\n  [\"text\",\".\"],\n  [\"support.function\",\"__mod\"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.language\",\"self\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"other\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"type\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"other\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"~=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"table\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"other\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"ipairs\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"other\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"tostring\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"v\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"self\"],\n  [\"keyword.operator\",\":\"],\n  [\"support.function\",\"format\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"unpack\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"other\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   [\"bracketedString\",5,\"start\"],\n  [\"support.function\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"[===[\"]\n],[\n   [\"bracketedString\",5,\"start\"],\n  [\"string\",\"    blah blah %s, (%d %d)\"]\n],[\n   \"start\",\n  [\"string.end\",\"]===]\"],\n  [\"keyword.operator\",\"%\"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"\\\"blah\\\"\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"num_args\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"int\"],\n  [\"paren.rparen\",\")})\"]\n],[\n   \"start\"\n],[\n   [\"bracketedComment\",3,\"start\"],\n  [\n    \"comment\",\n    \"--[=[\"\n  ],\n  [\n    \"comment.body\",\n    \"--\"\n  ]\n],[\n   [\"bracketedComment\",3,\"start\"],\n  [\n    \"comment.body\",\n    \"table.maxn is deprecated, use # instead.\"\n  ]\n],[\n   \"start\",\n  [\n    \"comment.body\",\n    \"--\"\n  ],\n  [\n    \"comment\",\n    \"]=]--\"\n  ]\n],[\n   \"start\",\n  [\"support.function\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.library\",\"table\"],\n  [\"text\",\".\"],\n  [\"keyword.deprecated\",\"maxn\"],\n  [\"paren.lparen\",\"{\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"8\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"8\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- outputs 8 instead of 2\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\" \"],\n  [\n    \"comment\",\n    \"--[[\"\n  ],\n  [\n    \"comment.body\",\n    \" blah \"\n  ],\n  [\n    \"comment\",\n    \"]]\"\n  ],\n  [\"paren.rparen\",\")\"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_luapage.json",
    "content": "[[\n   \"doctype\",\n  [\"text.xml\",\"﻿\"],\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"DOCTYPE\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"PUBLIC\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"string.xml\",\"\\\"-//W3C//DTD XHTML 1.0 Strict//EN\\\"\"]\n],[\n   \"start\",\n  [\"text.whitespace.xml\",\"   \"],\n  [\"string.xml\",\"\\\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\\\"\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"lua-bracketedComment\",2,\"lua-start\"],\n  [\"keyword\",\"<%\"],\n  [\"text\",\" \"],\n  [\n    \"comment\",\n    \"--[[\"\n  ],\n  [\n    \"comment.body\",\n    \"--\"\n  ]\n],[\n   [\"lua-bracketedComment\",2,\"lua-start\"],\n  [\n    \"comment.body\",\n    \"    index.lp from the Kepler Project's LuaDoc HTML doclet.\"\n  ]\n],[\n   [\"lua-bracketedComment\",2,\"lua-start\"],\n  [\n    \"comment.body\",\n    \"    http://keplerproject.github.com/luadoc/\"\n  ]\n],[\n   \"start\",\n  [\n    \"comment.body\",\n    \"--\"\n  ],\n  [\n    \"comment\",\n    \"]]\"\n  ],\n  [\"text\",\" \"],\n  [\"keyword\",\"%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Reference\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"link\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"rel\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"stylesheet\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"luadoc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"doclet\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"link\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"luadoc.css\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword\",\"%>\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"text/css\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\"meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=UTF-8\\\"/\"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"container\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"product\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"product_logo\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"product_name\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"big\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"big\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"product_description\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"product\\\" \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"main\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"navigation\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"luadoc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"doclet\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"include\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"menu.lp\\\"\"],\n  [\"text\",\", \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"doc\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"})\"],\n  [\"keyword\",\"%>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"navigation\\\" \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"content\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"<%if\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"options\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"nomodules\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"#\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"modules\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Modules\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"module_list\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\"<tr><td colspan=\\\"2\\\">Modules</td></tr>\"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"_\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"modulename\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"ipairs\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"modules\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"name\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"luadoc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"doclet\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"module_link\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"modulename\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"doc\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword\",\"%>\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"modulename\"],\n  [\"keyword\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"summary\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"modules\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"modulename\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"summary\"],\n  [\"keyword\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%end%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%end%>\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"<%if\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"not\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"options\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"nofiles\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"#\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"files\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Files\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h2\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"file_list\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\"<tr><td colspan=\\\"2\\\">Files</td></tr>\"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"_\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"filepath\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"ipairs\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"doc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"files\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do%>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"name\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"luadoc\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"doclet\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"html\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"file_link\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"filepath\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword\",\"%>\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"keyword\",\"<%=\"],\n  [\"identifier\",\"filepath\"],\n  [\"keyword\",\"%>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"summary\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"td\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"tr\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%end%>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.table.tag-name.xml\",\"table\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"<%end%>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"content\\\" \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"main\\\" \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"about\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"\\t\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"http://validator.w3.org/check?uri=referer\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.image.tag-name.xml\",\"img\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"src\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"http://www.w3.org/Icons/valid-xhtml10\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"alt\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Valid XHTML 1.0!\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"height\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"31\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"width\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"88\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"about\\\" \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" id=\\\"container\\\" \"],\n  [\"comment.end.xml\",\"-->\"],\n  [\"text.xml\",\"\\t\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_lucene.json",
    "content": "[[\n   \"start\",\n  [\"text\",\" \"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"keyword\",\"foo:\"],\n  [\"text\",\" \"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"AND\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"AND\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"OR\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"constant.character.negation\",\"-\"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"constant.character.negation\",\"-\"],\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"constant.character.negation\",\"-\"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"constant.character.negation\",\"-\"],\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~100\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~100\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~100\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"foo bar\\\"\"],\n  [\"constant.character.proximity\",\"~10\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~\"]\n],[\n   \"start\",\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.proximity\",\"~0.8\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"AND\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"field:\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"AND\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"field:\"],\n  [\"string\",\"\\\"bar baz\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.asterisk\",\"*\"]\n],[\n   \"start\",\n  [\"term\",\"f\"],\n  [\"constant.character.interro\",\"?\"],\n  [\"term\",\"o\"]\n],[\n   \"start\",\n  [\"term\",\"f\"],\n  [\"constant.character.asterisk\",\"*\"],\n  [\"term\",\"o\"]\n],[\n   \"start\",\n  [\"constant.character.required\",\"+\"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"constant.character.required\",\"+\"],\n  [\"string\",\"\\\"foo bar\\\"\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"],\n  [\"constant.character.interro\",\"?\"]\n],[\n   \"start\",\n  [\"constant.character.interro\",\"?\"],\n  [\"term\",\"oo\"]\n],[\n   \"start\",\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.character.negation\",\"-\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"constant.character.required\",\"+\"],\n  [\"term\",\"bar\"],\n  [\"text\",\" \"],\n  [\"constant.character.required\",\"+\"],\n  [\"string\",\"\\\"foo bar\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"{\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"[\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"term\",\"bar\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"a b c\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"term\",\"def\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"\\\"a b c\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"term\",\"def\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"{\"],\n  [\"term\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"bar\\\"\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"{\"],\n  [\"constant.numeric\",\"20180101\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20190202\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"field:\"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"\\\"2018-01-01\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"TO\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"2019-02-02\\\"\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\+\"],\n  [\"term\",\"escaped\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\-\"],\n  [\"term\",\"escaped\"]\n],[\n   \"start\",\n  [\"term\",\"esc\"],\n  [\"constant.language.escape\",\"\\\\&\"],\n  [\"term\",\"aped\"]\n],[\n   \"start\",\n  [\"term\",\"esc\"],\n  [\"constant.language.escape\",\"\\\\|\"],\n  [\"term\",\"aped\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\!\"],\n  [\"term\",\"escaped\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\(\"],\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\)\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\{\"],\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\}\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\[\"],\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\]\"]\n],[\n   \"start\",\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\^\"],\n  [\"constant.numeric\",\"4\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"\\\\\\\"\"],\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\\\\"\"]\n],[\n   \"start\",\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\~\"],\n  [\"constant.numeric\",\"0.4\"]\n],[\n   \"start\",\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\*\"]\n],[\n   \"start\",\n  [\"term\",\"escaped\"],\n  [\"constant.language.escape\",\"\\\\?\"]\n],[\n   \"start\",\n  [\"term\",\"esc\"],\n  [\"constant.language.escape\",\"\\\\:\"],\n  [\"term\",\"aped\"]\n],[\n   \"start\",\n  [\"term\",\"esc\"],\n  [\"constant.language.escape\",\"\\\\\\\\\"],\n  [\"term\",\"aped\"]\n],[\n   \"start\",\n  [\"keyword\",\"esc\\\\ aped:\"],\n  [\"term\",\"foo\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"foo\\\\\\\"bar\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"foo:\"],\n  [\"string.regexp.start\",\"/\"],\n  [\"string.regexp\",\"bar\"],\n  [\"string.regexp.end\",\"/\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_markdown.json",
    "content": "[[\n   \"start\",\n  [\"text.xml\",\"test: header 1 \"]\n],[\n   \"start\",\n  [\"text.xml\",\"#f\"]\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\" f\"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: header 2\"]\n],[\n   \"start\",\n  [\"markup.heading.2\",\"##\"],\n  [\"heading\",\" foo\"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: header ends with ' #'\"]\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\" # # \"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: header ends with '#'\"]\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\" foo# \"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: 6+ #s is not a valid header\"]\n],[\n   \"start\",\n  [\"text.xml\",\"####### foo\"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: # followed be only space is a valid header\"]\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\" \"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: only space between #s is a valid header\"]\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\"  #\"]\n],[\n   \"allowBlock\"\n],[\n   \"start\",\n  [\"markup.heading.1\",\"#\"],\n  [\"heading\",\" test links  \"],\n  [\"text\",\"[\"],\n  [\"string\",\"Cloud9 IDE\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"http://www.c9.io/\"],\n  [\"text\",\")\"],\n  [\"heading\",\" #\"]\n],[\n   \"listblock\",\n  [\"markup.list\",\"* \"],\n  [\"text\",\"[\"],\n  [\"string\",\"demo\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"http://ajaxorg.github.com/ace/\"],\n  [\"text\",\")\"],\n  [\"list\",\" \"],\n  [\"text\",\"[\"],\n  [\"string\",\"+\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"escape(\\\\) \"],\n  [\"text\",\")\"],\n  [\"list\",\" \"],\n  [\"text\",\"[\"],\n  [\"string\",\"+\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"a\"],\n  [\"string\",\" \\\"title\\\"\"],\n  [\"text\",\")\"],\n  [\"list\",\" \"],\n  [\"text\",\"[\"],\n  [\"string\",\"+\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"a\"],\n  [\"string\",\" \\\"space\\\" \"],\n  [\"text\",\")\"]\n],[\n   \"listblock\",\n  [\"markup.list\",\"* \"],\n  [\"list\",\"usually \"],\n  [\"string.emphasis\",\"*work*\"],\n  [\"list\",\" fine (\"],\n  [\"string.emphasis\",\"_em_\"],\n  [\"list\",\")\"]\n],[\n   \"listblock\",\n  [\"list\",\"in lists\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"in plain text \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"http://ace.ajaxorg.com\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"allowBlock\"\n],[\n   \"allowBlock\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mask.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"/* Mask Syntax Demo */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.support.constant.language\",\"div\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\" Test \"],\n  [\"paren.lparen.markup.italic\",\"~[\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen.markup.italic\",\"]\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"define\"],\n  [\"text\",\" :\"],\n  [\"support.variable.class\",\"userProfile\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.support.constant.language\",\"header\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.support.constant.language\",\"h4\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"support.function.markup.bold\",\"@title\"],\n  [\"paren.lparen\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.support.constant.language\",\"button\"],\n  [\"support.variable.class\",\".close\"],\n  [\"paren.lparen\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.markup.bold\",\":userProfile\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"support.function.markup.bold\",\"@title\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\" Hello \"],\n  [\"paren.lparen.markup.italic\",\"~[\"],\n  [\"keyword.control.markup.italic\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"username\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"toUpperCase\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.rparen.markup.italic\",\"]\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   [\"paren.lparen52\",\"constant.language40\"],\n  [\"constant.language\",\"style\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"css-block-ruleset\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"    \"],\n  [\"constant\",\"html\"],\n  [\"text\",\", \"],\n  [\"constant\",\"body\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"css-block-ruleset\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"        \"],\n  [\"support.type\",\"background\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"'name.png'\"],\n  [\"support.function\",\")\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"no-repeat\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"#tmp\",\"css-block-start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"#tmp\",\"css-block-end\",\"paren.lparen52\",\"constant.language40\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"keyword.support.constant.language\",\"button\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"\\t\"],\n  [\"constant.language\",\"event\"],\n  [\"text\",\" \"],\n  [\"support.variable.class\",\"click\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"e\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"js-block-start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"\\t    \"],\n  [\"variable.language\",\"this\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"textContent\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.quasi.start\",\"`\"],\n  [\"string.quasi\",\"name \"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"identifier\",\"e\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"clientX\"],\n  [\"paren.quasi.end\",\"}\"],\n  [\"string.quasi\",\" !\"],\n  [\"string.quasi.end\",\"`\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"#tmp\",\"js-block-end\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"constant.language\",\"md\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"\\\"\\\"\\\"\"]\n],[\n   [\"#tmp\",\"md-multiline-allowBlock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"md-multiline-listblock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"markup.list\",\"- \"],\n  [\"list\",\"div\"]\n],[\n   [\"#tmp\",\"md-multiline-listblock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"markup.list\",\"- \"],\n  [\"list\",\"span\"]\n],[\n   [\"#tmp\",\"md-multiline-listblock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"list\",\" \"]\n],[\n   [\"#tmp\",\"md-multiline-listblock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"list\",\"Hello\"]\n],[\n   [\"#tmp\",\"md-multiline-start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"md-multiline-start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"[\"],\n  [\"string\",\"one\"],\n  [\"text\",\"](\"],\n  [\"markup.underline\",\"http://google.com\"],\n  [\"text\",\")\"]\n],[\n   [\"#tmp\",\"md-multiline-allowBlock\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"paren.rparen\",\"\\\"\\\"\\\";\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"keyword.support.constant.language\",\"header\"],\n  [\"text\",\" \"],\n  [\"support.variable.class\",\".foo\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Heading\"],\n  [\"string.end\",\"'\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"string.start2\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"keyword.support.constant.language\",\"button\"],\n  [\"text\",\" \"],\n  [\"support.variable.class\",\".baz\"],\n  [\"text\",\" \"],\n  [\"support.variable.class.markup.bold\",\"x-signal\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"click: test\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"support.variable.class\",\"disabled\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"]\n],[\n   [\"string.start2\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"string\",\"\\tHello,\"]\n],[\n   [\"string.start2\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"string\",\"\\tworld \"]\n],[\n   [\"string.start2\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"string\",\"\\t\"],\n  [\"string.escape\",\"\\\\\\\"\"],\n  [\"string\",\"Buddy\"],\n  [\"string.escape\",\"\\\\\\\"\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"js-statement-start\",\"start\",\"js-statement-no_regex\",\"constant.language53\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"constant.language\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"#tmp\",\"js-statement-no_regex\",\"start\",\"js-statement-no_regex\",\"constant.language53\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"name\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string.quasi.start\",\"`\"],\n  [\"string.quasi\",\"name \"],\n  [\"paren.quasi.start\",\"${\"],\n  [\"variable.language\",\"window\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.constant\",\"innerWidth\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string.quasi.end\",\"`\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"paren.rparen\",\"};\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"]\n],[\n   [\"#tmp\",\"start\",\"paren.lparen13\",\"constant.language\",\"constant.language\",\"start\",\"paren.lparen39\",\"constant.language27\",\"constant.language27\",\"start\",\"paren.lparen52\",\"constant.language40\"],\n  [\"keyword.support.constant.language\",\"span\"],\n  [\"text\",\" \"],\n  [\"support.variable.class\",\".foo\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\">\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"paren.lparen.markup.italic\",\"~[\"],\n  [\"keyword.control.markup.italic\",\"bind:\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen.markup.italic\",\"]\"],\n  [\"string.end\",\"\\\"\"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_matlab.json",
    "content": "[[\n   [\"blockComment\",\"noQstring\"],\n  [\"comment.start\",\"%{\"]\n],[\n   [\"blockComment\",\"blockComment\",\"blockComment\",\"noQstring\"],\n  [\"comment.start\",\"   %{\"]\n],[\n   [\"blockComment\",\"blockComment\",\"blockComment\",\"noQstring\"],\n  [\"comment\",\"      Ace Matlab demo\"]\n],[\n   [\"blockComment\",\"noQstring\"],\n  [\"comment.end\",\"   %}\"]\n],[\n   \"noQstring\",\n  [\"comment.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"classdef\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hello\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"support.function\",\"methods\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"greet\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"this\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"         \"],\n  [\"support.function\",\"disp\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'Hello!'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"% say hi\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"noQstring\"\n],[\n   \"start\",\n  [\"comment\",\"% transpose \"]\n],[\n   \"qqstring\",\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"string\",\"'x\"],\n  [\"constant.language.escape\",\"''\"],\n  [\"string\",\"y'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"x\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"\\\\\"]\n],[\n   \"start\",\n  [\"string\",\"      y\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"' \"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\"' \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\"'\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_maze.json",
    "content": "[[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"()\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"^^\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"H1\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"C2\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"S1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"<>\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"S2\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"H2\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"DN\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%U\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"<>\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%D\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"*2\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%L\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"IZ\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"..\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"..\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"DN\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"*3\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%R\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"C1\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"IZ\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"()\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"support.function\",\">/\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"*1\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"##\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"()\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"*3\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag\",\"*1\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"%L\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"()\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash\",\"// Set divisor and dividend\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"S1\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.numeric\",\"9\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"S2\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.numeric\",\"24\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash\",\"// Holding cells\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"H1\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.control\",\"IF\"],\n  [\"keyword.other\",\" \"],\n  [\"entity.name.tag\",\"*1\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%R\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%N\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"H2\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.control\",\"IF\"],\n  [\"keyword.other\",\" \"],\n  [\"entity.name.tag\",\"*2\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%R\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%N\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash\",\"// Arithmetic\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"DN\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.operator\",\"-=\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"IZ\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.control\",\"IF\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%D\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%U\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function\",\"C1\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.control\",\"IF\"],\n  [\"keyword.other\",\" \"],\n  [\"entity.name.tag\",\"*3\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%D\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%R\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"C2\"],\n  [\"keyword.other\",\"-> \"],\n  [\"keyword.control\",\"IF\"],\n  [\"keyword.other\",\" \"],\n  [\"entity.name.tag\",\"*3\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%U\"],\n  [\"keyword.other\",\" \"],\n  [\"keyword.control\",\"ELSE\"],\n  [\"keyword.other\",\" \"],\n  [\"constant.language\",\"%D\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mediawiki.json",
    "content": "[[\n   \"start\",\n  [\"storage.type.function\",\"{{\"],\n  [\"entity.name.function\",\"Languages\"],\n  [\"storage.type.function\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin\",\"'''\"],\n  [\"markup.bold\",\"Ace\"],\n  [\"punctuation.definition.tag.end\",\"'''\"],\n  [\"text\",\" is a standalone code editor written in \"],\n  [\"punctuation.definition.tag.begin\",\"[[\"],\n  [\"entity.name.tag\",\"wikipedia\"],\n  [\"meta.tag.link.internal\",\":\"],\n  [\"string.other.link.title\",\"JavaScript\"],\n  [\"punctuation.definition.tag\",\"|\"],\n  [\"meta.tag.link.internal\",\"JavaScript\"],\n  [\"punctuation.definition.tag.end\",\"]]\"],\n  [\"text\",\". Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be \"],\n  [\"punctuation.definition.tag.begin\",\"''\"],\n  [\"markup.italic\",\"easily\"],\n  [\"punctuation.definition.tag.end\",\"''\"],\n  [\"text\",\" embedded in any web page or JavaScript application. Ace is developed as the primary editor for \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"http://www.cloud9ide.com/\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"Cloud9 IDE\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\" and the successor of the Mozilla Skywriter (Bespin) Project.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.heading\",\"==\"],\n  [\"entity.name.section\",\" Features \"],\n  [\"punctuation.definition.heading\",\"==\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Syntax highlighting\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Automatic indent and outdent\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" An optional command line\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Handles huge documents (100,000 lines and more are no problem)\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Fully customizable key bindings including VI and Emacs modes\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Themes (TextMate themes can be imported)\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Search and replace with regular expressions\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Highlight matching parentheses\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Toggle between soft tabs and real tabs\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Displays hidden characters\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Drag and drop text using the mouse\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Line wrapping\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Unstructured / user code folding\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"*\"],\n  [\"markup.list\",\" Live syntax checker (currently JavaScript/CoffeeScript)\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.heading\",\"==\"],\n  [\"entity.name.section\",\" Take Ace for a spin! \"],\n  [\"punctuation.definition.heading\",\"==\"]\n],[\n   \"start\",\n  [\"text\",\"Check out the Ace live \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"http://ajaxorg.github.com/ace/\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"demo\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\" or get a \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"http://run.cloud9ide.com\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"Cloud9 IDE account\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\" to experience Ace while editing one of your own GitHub projects.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"If you want, you can use Ace as a textarea replacement thanks to the \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"http://ajaxorg.github.com/ace/build/textarea/editor.html\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"Ace Bookmarklet\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.heading\",\"==\"],\n  [\"entity.name.section\",\" Documentation \"],\n  [\"punctuation.definition.heading\",\"==\"]\n],[\n   \"start\",\n  [\"text\",\"You find a lot more sample code in the \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"https://github.com/ajaxorg/ace/blob/master/demo/demo.js\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"demo app\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"There is also some documentation on the \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"https://github.com/ajaxorg/ace/wiki\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"wiki page\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"If you still need help, feel free to drop a mail on the \"],\n  [\"punctuation.definition.tag.begin\",\"[\"],\n  [\"meta.tag.link.external\",\"http://groups.google.com/group/ace-discuss\"],\n  [\"meta.tag.link.external\",\" \"],\n  [\"string.unquoted\",\"ace mailing list\"],\n  [\"punctuation.definition.tag.end\",\"]\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mel.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.double-slash.mel\",\"//\"],\n  [\"punctuation.definition.comment.mel\",\" animated duplicates, instances script\"]\n],[\n   \"start\",\n  [\"keyword.other.mel\",\"proc\"],\n  [\"storage.type.mel\",\" \"],\n  [\"entity.name.function.mel\",\"animatedDuplication\"],\n  [\"punctuation.section.function.mel\",\" (\"],\n  [\"storage.type.mel\",\"int\"],\n  [\"meta.function.mel\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"rangeStart\"],\n  [\"meta.function.mel\",\", \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"meta.function.mel\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"rangeEnd\"],\n  [\"meta.function.mel\",\", \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"meta.function.mel\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"numOfDuplicates\"],\n  [\"meta.function.mel\",\", \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"meta.function.mel\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"duplicateOrInstance\"],\n  [\"punctuation.section.function.mel\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"rangeStart\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_end\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"rangeEnd\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"num_of_duplicates\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"numOfDuplicates\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"step_size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" (\"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_end\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"-\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_start\"],\n  [\"text\",\") \"],\n  [\"keyword.operator.symbolic.mel\",\"/\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"num_of_duplicates\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.mel\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"int\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"temp\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.mel\",\"currentTime\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_start\"],\n  [\"text\",\";     \"],\n  [\"comment.line.double-slash.mel\",\"//\"],\n  [\"punctuation.definition.comment.mel\",\" set to range start\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.mel\",\"string\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"selectedObjects\"],\n  [\"text\",\"[];    \"],\n  [\"comment.line.double-slash.mel\",\"//\"],\n  [\"punctuation.definition.comment.mel\",\" to store selected objects\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"selectedObjects\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" `\"],\n  [\"support.function.mel\",\"ls\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"-\"],\n  [\"text\",\"sl`;  \"],\n  [\"comment.line.double-slash.mel\",\"//\"],\n  [\"punctuation.definition.comment.mel\",\" store selected objects\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.mel\",\"select\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"selectedObjects\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.mel\",\"while\"],\n  [\"text\",\" (\"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"i\"],\n  [\"text\",\" <\"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"num_of_duplicates\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    {\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"temp\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"range_start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"+\"],\n  [\"text\",\" (\"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"step_size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"*\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"i\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.mel\",\"currentTime\"],\n  [\"text\",\" (\"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"temp\"],\n  [\"text\",\");\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment.line.double-slash.mel\",\"//\"],\n  [\"punctuation.definition.comment.mel\",\" seleced the objects to duplicate or instance\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.mel\",\"select\"],\n  [\"text\",\" \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"selectedObjects\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control.mel\",\"if\"],\n  [\"text\",\"(\"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"duplicateOrInstance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.symbolic.mel\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.mel\",\"0\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        {\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"support.function.mel\",\"duplicate\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        }\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control.mel\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"        {\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"support.function.mel\",\"instance\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        }\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"variable.other.mel\",\"$\"],\n  [\"punctuation.definition.variable.mel\",\"i\"],\n  [\"keyword.operator.symbolic.mel\",\"++\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    }\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mips.json",
    "content": "[[\n   \"start\",\n  [\"comment.assembly\",\"# Original source from https://eng.libretexts.org\"]\n],[\n   \"start\",\n  [\"comment.assembly\",\"# Kann, Charles W., \\\"Introduction To MIPS Assembly Language Programming\\\" (2015). Open Textbooks. 2.\"]\n],[\n   \"start\",\n  [\"comment.assembly\",\"# https://cupola.gettysburg.edu/oer/2\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.assembly\",\"# Program File: Program2-1.asm\"]\n],[\n   \"start\",\n  [\"comment.assembly\",\"# Author: Charles Kann\"]\n],[\n   \"start\",\n  [\"comment.assembly\",\"# Purpose: First program, Hello World\"]\n],[\n   \"start\",\n  [\"entity.name.section.mips\",\".text\"],\n  [\"text\",\"                   \"],\n  [\"comment.assembly\",\"# Define the program instructions.\"]\n],[\n   \"start\",\n  [\"entity.name.tag.mips\",\"main:\"],\n  [\"text\",\"                   \"],\n  [\"comment.assembly\",\"# Label to define the main program.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.other.mips\",\"li\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.mips\",\"$v0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric.mips\",\"4\"],\n  [\"text\",\"            \"],\n  [\"comment.assembly\",\"# Load 4 into $v0 to indicate a print string.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.other.mips\",\"la\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.mips\",\"$a0\"],\n  [\"text\",\", greeting    \"],\n  [\"comment.assembly\",\"# Load the address of the greeting into $a0.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function.mips\",\"syscall\"],\n  [\"text\",\"             \"],\n  [\"comment.assembly\",\"# Print greeting. The print is indicated by\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"comment.assembly\",\"# $v0 having a value of 4, and the string to\"]\n],[\n   \"start\",\n  [\"text\",\"                        \"],\n  [\"comment.assembly\",\"# print is stored at the address in $a0.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.other.mips\",\"li\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.mips\",\"$v0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric.mips\",\"10\"],\n  [\"text\",\"          \"],\n  [\"comment.assembly\",\"# Load a 10 (halt) into $v0.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function.mips\",\"syscall\"],\n  [\"text\",\"             \"],\n  [\"comment.assembly\",\"# The program ends.\"]\n],[\n   \"start\",\n  [\"entity.name.section.mips\",\".data\"],\n  [\"text\",\"                   \"],\n  [\"comment.assembly\",\"# Define the program data.\"]\n],[\n   \"start\",\n  [\"entity.name.tag.mips\",\"greeting:\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.mips\",\".asciiz\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Hello World\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"comment.assembly\",\"#The string to print.\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mixal.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.character\",\"* PROGRAM START\"]\n],[\n   \"start\",\n  [\"variable.other\",\"ΔSTART\"],\n  [\"text\",\"     \"],\n  [\"keyword.control\",\"LDA\"],\n  [\"text\",\"  \"],\n  [\"text\",\"2000\"],\n  [\"comment.line.character\",\" LOAD A FROM CELL 2000\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"invalid.illegal\",\"CMP7\"],\n  [\"text\",\" \"],\n  [\"text\",\"=15=\"]\n],[\n   \"start\",\n  [\"invalid.illegal\",\"12345\"],\n  [\"text\",\"      \"],\n  [\"keyword.control\",\"HLT\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"keyword.control\",\"END\"],\n  [\"text\",\"  \"],\n  [\"text\",\"START\"]\n],[\n   \"start\",\n  [\"variable.other\",\"ABC\"],\n  [\"text\",\"        \"],\n  [\"keyword.control\",\"ALF\"],\n  [\"text\",\" \"],\n  [\"invalid.illegal\",\"abc\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mushcode.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"@\"],\n  [\"support.function\",\"create\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"]\n],[\n   \"start\",\n  [\"text\",\"&\"],\n  [\"identifier\",\"pickup\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"$pick\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\":@\"],\n  [\"support.function\",\"ifelse\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"is\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"mode\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"ICC\"],\n  [\"paren.rparen\",\")]\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"pemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"identifier\",\"You\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"pick\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"fullname\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\".\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"PHONER\"],\n  [\"text\",\":\"],\n  [\"keyword.operator\",\"%#\"],\n  [\"paren.rparen\",\")]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"MODE\"],\n  [\"text\",\":\"],\n  [\"identifier\",\"CIP\"],\n  [\"paren.rparen\",\")]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"([\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"INCOMING\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"CONNECTED\"],\n  [\"text\",\":\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"num\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"CONNECTED\"],\n  [\"text\",\":\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"INCOMING\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"variable\",\"%r\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"showpicture\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"PICPICKUP\"],\n  [\"paren.rparen\",\")]\"],\n  [\"variable\",\"%r\"],\n  [\"identifier\",\"Use\"],\n  [\"text\",\" '\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"color\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"green\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"black\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"psay\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"message\"],\n  [\"keyword.operator\",\">\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\"' \"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"or\"],\n  [\"text\",\" '\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"color\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"green\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"black\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"p\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"message\"],\n  [\"keyword.operator\",\">\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"to\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"talk\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"into\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"text\",\".;@\"],\n  [\"support.function\",\"oemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"variable\",\"%N\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"picks\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"fullname\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\".\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"pemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"identifier\",\"You\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"pick\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"but\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"no\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"one\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"there\"],\n  [\"text\",\". \"],\n  [\"identifier\",\"You\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hear\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dialtone\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"and\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"then\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hang\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\". \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"play\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"DIALTONE\"],\n  [\"paren.rparen\",\"))]\"],\n  [\"text\",\";@\"],\n  [\"support.function\",\"oemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"variable\",\"%N\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"picks\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"up\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"but\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"no\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"one\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"on\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"the\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"other\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"end\"],\n  [\"text\",\".\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"&\"],\n  [\"identifier\",\"ringfun\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"ifelse\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"eq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"comp\"],\n  [\"paren.lparen\",\"([\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"off\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"color\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"black\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"cyan\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"INCOMING\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CALL\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"variable\",\"%1\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"play\"],\n  [\"paren.lparen\",\"([\"],\n  [\"support.function\",\"switch\"],\n  [\"paren.lparen\",\"([\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone1\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone2\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone3\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone4\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone5\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"6\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone6\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone7\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"8\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone8\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"9\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringtone9\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"custom\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"customtone\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"vibrate\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"vibrate\"],\n  [\"paren.rparen\",\")])])]\"]\n],[\n   \"start\",\n  [\"text\",\"&\"],\n  [\"identifier\",\"ringloop\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"switch\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"ringstate\"],\n  [\"paren.rparen\",\")]\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"emit\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"q\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"connecting\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"rangs\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"mode\"],\n  [\"text\",\":\"],\n  [\"identifier\",\"WFC\"],\n  [\"paren.rparen\",\")]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"INCOMING\"],\n  [\"text\",\":\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\";@\"],\n  [\"support.function\",\"ifelse\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"HASVMB\"],\n  [\"paren.rparen\",\")]\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"tr\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"me\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ROUTEVMB\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"connecting\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\";\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"pemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"MSGCNC\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\";\"],\n  [\"paren.rparen\",\"}}\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"pemit\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%#=\"],\n  [\"identifier\",\"The\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"call\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"connected\"],\n  [\"text\",\".\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"q\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"CONNECTING\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"CONNECTED\"],\n  [\"text\",\":\"],\n  [\"variable\",\"%qq\"],\n  [\"paren.rparen\",\")]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"CONNECTED\"],\n  [\"text\",\":\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"num\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"set\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"MODE\"],\n  [\"text\",\":\"],\n  [\"identifier\",\"CIP\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\";@\"],\n  [\"support.function\",\"tr\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"me\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ciploop\"],\n  [\"text\",\";@\"],\n  [\"support.function\",\"tr\"],\n  [\"text\",\" \"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ciploop\"],\n  [\"text\",\";\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"emit\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"On\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"fullname\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")]\"],\n  [\"text\",\"'\"],\n  [\"support.function\",\"s\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"earpiece\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"you\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hear\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ringing\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sound\"],\n  [\"text\",\".\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"play\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"LINETONE\"],\n  [\"paren.rparen\",\"))]\"],\n  [\"text\",\";@\"],\n  [\"support.function\",\"tr\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"me\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringhere\"],\n  [\"text\",\";@\"],\n  [\"identifier\",\"increment\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"connecting\"],\n  [\"paren.rparen\",\")]\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"RANGS\"],\n  [\"text\",\";@\"],\n  [\"identifier\",\"wait\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\"@\"],\n  [\"support.function\",\"tr\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"me\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"ringloop\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\";\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"&\"],\n  [\"identifier\",\"ringstate\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"phone\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"q\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"connecting\"],\n  [\"paren.rparen\",\"))]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"gt\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"rangs\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"sub\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"rings\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"))])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"and\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"is\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"MODE\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"CIP\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"is\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"INCOMING\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"num\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"me\"],\n  [\"paren.rparen\",\")]))]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"setq\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\",\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"is\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"u\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%qq\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"MODE\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"ICC\"],\n  [\"paren.rparen\",\")])]\"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"ifelse\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%q1\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"ifelse\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%q2\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"support.function\",\"ifelse\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"%q3\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rparen\",\")))]\"]\n],[\n   \"start\",\n  [\"text\",\";\"],\n  [\"identifier\",\"comment\"]\n],[\n   \"start\",\n  [\"text\",\"@@\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"comment\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"say\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"support.function\",\"time\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")]\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_mysql.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"-- Single line comment\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment\",\" * Multi-line comment block\"]\n],[\n   \"comment\",\n  [\"comment\",\" *\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Hash-style comment (MySQL specific)\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Database and Table Operations\"]\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DATABASE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IF\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"EXISTS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"demo_db\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"CHARACTER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"utf8mb4\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"COLLATE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"utf8mb4_unicode_ci\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"USE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"demo_db\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"TABLE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"INT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AUTO_INCREMENT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"PRIMARY\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"KEY\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"username\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"VARCHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"50\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"constant\",\"NULL\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"UNIQUE\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"email\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"VARCHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"100\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"constant\",\"NULL\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"password_hash\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"CHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"64\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DECIMAL\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DEFAULT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.00\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"is_active\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"BOOLEAN\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DEFAULT\"],\n  [\"text\",\" \"],\n  [\"constant\",\"TRUE\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"created_at\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"TIMESTAMP\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DEFAULT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"CURRENT_TIMESTAMP\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"updated_at\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DATETIME\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"UPDATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"CURRENT_TIMESTAMP\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"profile_data\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"JSON\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"INDEX\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"idx_email\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"email\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"FULLTEXT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INDEX\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"idx_username\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"username\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ENGINE\"],\n  [\"keyword.operator\",\"=\"],\n  [\"keyword\",\"InnoDB\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Insert Statements\"]\n],[\n   \"start\",\n  [\"keyword\",\"INSERT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"email\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"password_hash\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"VALUES\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"john_doe\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"john@example.com\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"SHA2\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"password123\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"256\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"jane_smith\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"jane@example.com\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"SHA2\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"secure456\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"256\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Select with Various Clauses\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"id\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"CONCAT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"UPPER\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"LEFT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"LOWER\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"SUBSTRING\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")))\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"formatted_name\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"COALESCE\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"DATE_FORMAT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"created_at\"],\n  [\"text\",\", \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"%Y-%m-%d\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"join_date\"]\n],[\n   \"start\",\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"is_active\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant\",\"TRUE\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"created_at\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"2024-01-01\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"email\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"LIKE\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"%@example.com\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BETWEEN\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1000\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IN\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"john_doe\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"jane_smith\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"profile_data\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IS\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"constant\",\"NULL\"]\n],[\n   \"start\",\n  [\"keyword\",\"GROUP\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"id\"]\n],[\n   \"start\",\n  [\"keyword\",\"HAVING\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"COUNT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"*\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"keyword\",\"ORDER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"created_at\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DESC\"]\n],[\n   \"start\",\n  [\"keyword\",\"LIMIT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"OFFSET\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Update Statement\"]\n],[\n   \"start\",\n  [\"keyword\",\"UPDATE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100.50\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"updated_at\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"NOW\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"username\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"john_doe\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Delete Statement\"]\n],[\n   \"start\",\n  [\"keyword\",\"DELETE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is_active\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant\",\"FALSE\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"created_at\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"DATE_SUB\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"NOW\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"INTERVAL\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"YEAR\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Join Example\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"username\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"order_id\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"total_amount\"]\n],[\n   \"start\",\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"]\n],[\n   \"start\",\n  [\"keyword\",\"INNER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"JOIN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"orders\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"user_id\"]\n],[\n   \"start\",\n  [\"keyword\",\"LEFT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"JOIN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"order_items\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"oi\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"order_id\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"oi\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"order_id\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\".\"],\n  [\"variable.language\",\"status\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"cancelled\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Subquery and EXISTS\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"EXISTS\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"orders\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"orders\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"user_id\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"id\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"orders\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"total_amount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"500\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- CASE Expression\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"username\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"CASE\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"WHEN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1000\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Premium\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"WHEN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Standard\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"ELSE\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"Basic\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"END\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"tier\"]\n],[\n   \"start\",\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Window Functions\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"username\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"ROW_NUMBER\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"OVER\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"ORDER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DESC\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"rank\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"SUM\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"balance\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"OVER\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"PARTITION\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is_active\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"total_by_status\"]\n],[\n   \"start\",\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Variables\"]\n],[\n   \"start\",\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"constant.class\",\"@user_count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"COUNT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"*\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"constant.class\",\"@tax_rate\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.08\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"constant.class\",\"@user_count\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"total_users\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Stored Procedure\"]\n],[\n   \"start\",\n  [\"keyword\",\"DELIMITER\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"//\"]\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"PROCEDURE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"GetUserByEmail\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"IN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_email\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"VARCHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"100\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"DECLARE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_exists\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"INT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DEFAULT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"COUNT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"*\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_exists\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"email\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_email\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"IF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_exists\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"THEN\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"email\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"user_email\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"ELSE\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"User not found\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"message\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"END\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IF\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"//\"]\n],[\n   \"start\",\n  [\"keyword\",\"DELIMITER\"],\n  [\"text\",\" ;\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Function\"]\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FUNCTION\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CalculateDiscount\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"price\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DECIMAL\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"discount_pct\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"INT\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"RETURNS\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DECIMAL\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"DETERMINISTIC\"]\n],[\n   \"start\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"RETURN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"price\"],\n  [\"text\",\" * \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"discount_pct\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Trigger\"]\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"TRIGGER\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"before_user_update\"]\n],[\n   \"start\",\n  [\"keyword\",\"BEFORE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"UPDATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"keyword\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"EACH\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ROW\"]\n],[\n   \"start\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NEW\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"updated_at\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"NOW\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Transaction\"]\n],[\n   \"start\",\n  [\"keyword\",\"START\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"TRANSACTION\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"UPDATE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"UPDATE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"COMMIT\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Common Table Expression (CTE)\"]\n],[\n   \"start\",\n  [\"keyword\",\"WITH\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"active_users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"is_active\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant\",\"TRUE\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"active_users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"balance\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- EXPLAIN for query analysis\"]\n],[\n   \"start\",\n  [\"keyword\",\"EXPLAIN\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"email\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"test@example.com\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Numeric literals\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"42\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"3.14159\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1e10\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0x1A2B\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"b'101010'\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- String literals\"]\n],[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"single quotes\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\", \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"double quotes\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.buildin\",\"`backtick identifiers`\"],\n  [\"text\",\";\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nasal.json",
    "content": "[[\n   \"start\",\n  [\"storage.type.nasal\",\"var\"],\n  [\"text\",\" sayHello \"],\n  [\"keyword.operator.nasal\",\"=\"],\n  [\"text\",\" func(names, favorite) {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.nasal\",\"foreach\"],\n  [\"text\",\" (\"],\n  [\"storage.type.nasal\",\"var\"],\n  [\"text\",\" name\"],\n  [\"punctuation.terminator.statement.nasal\",\";\"],\n  [\"text\",\" names) {\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language.nasal\",\"printf\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.nasal\",\"\\\"\"],\n  [\"string.quoted.double.nasal\",\"Hello \"],\n  [\"constant.character.escape.nasal\",\"%s\"],\n  [\"string.quoted.double.nasal\",\", \"],\n  [\"constant.character.escape.nasal\",\"%s\"],\n  [\"string.quoted.double.nasal\",\" is the best!\"],\n  [\"punctuation.definition.string.end.nasal\",\"\\\"\"],\n  [\"text\",\", name, favorite)\"],\n  [\"punctuation.terminator.statement.nasal\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  }\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"sayHello([\"],\n  [\"punctuation.definition.string.begin.nasal\",\"\\\"\"],\n  [\"string.quoted.double.nasal\",\"World\"],\n  [\"punctuation.definition.string.end.nasal\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"punctuation.definition.string.begin.nasal\",\"\\\"\"],\n  [\"string.quoted.double.nasal\",\"FlightGear\"],\n  [\"punctuation.definition.string.end.nasal\",\"\\\"\"],\n  [\"text\",\"], \"],\n  [\"punctuation.definition.string.begin.nasal\",\"\\\"\"],\n  [\"string.quoted.double.nasal\",\"Nasal\"],\n  [\"punctuation.definition.string.end.nasal\",\"\\\"\"],\n  [\"text\",\")\"],\n  [\"punctuation.terminator.statement.nasal\",\";\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nginx.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"user\"],\n  [\"text\",\"       www www\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"## Default: nobody\"]\n],[\n   \"start\",\n  [\"keyword\",\"worker_processes\"],\n  [\"text\",\"  5\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"## Default: 1\"]\n],[\n   \"start\",\n  [\"keyword\",\"error_log\"],\n  [\"text\",\"  logs/error.log\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"pid\"],\n  [\"text\",\"        logs/nginx.pid\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"worker_rlimit_nofile\"],\n  [\"text\",\" 8192\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"events\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"worker_connections\"],\n  [\"text\",\"  4096\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"## Default: 1024\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"http\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"include\"],\n  [\"text\",\"    conf/mime.types\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"include\"],\n  [\"text\",\"    /etc/nginx/proxy.conf\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"include\"],\n  [\"text\",\"    /etc/nginx/fastcgi.conf\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"index\"],\n  [\"text\",\"    index.html index.htm index.php\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"default_type\"],\n  [\"text\",\" application/octet-stream\"],\n  [\"punctuation\",\";\"]\n],[\n   \"keyword\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"log_format\"],\n  [\"text\",\"   \"],\n  [\"constant.language\",\"main\"],\n  [\"text\",\" \"],\n  [\"string\",\"'\"],\n  [\"variable\",\"$remote_addr\"],\n  [\"string\",\" - \"],\n  [\"variable\",\"$remote_user\"],\n  [\"string\",\" [\"],\n  [\"variable\",\"$time_local\"],\n  [\"string\",\"]  \"],\n  [\"variable\",\"$status\"],\n  [\"string\",\" '\"]\n],[\n   \"keyword\",\n  [\"text\",\"    \"],\n  [\"string\",\"'\\\"\"],\n  [\"variable\",\"$request\"],\n  [\"string\",\"\\\" \"],\n  [\"variable\",\"$body_bytes_sent\"],\n  [\"string\",\" \\\"\"],\n  [\"variable\",\"$http_referer\"],\n  [\"string\",\"\\\" '\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"string\",\"'\\\"\"],\n  [\"variable\",\"$http_user_agent\"],\n  [\"string\",\"\\\" \\\"\"],\n  [\"variable\",\"$http_x_forwarded_for\"],\n  [\"string\",\"\\\"'\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"access_log\"],\n  [\"text\",\"   logs/access.log  \"],\n  [\"constant.language\",\"main\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"sendfile\"],\n  [\"text\",\"     \"],\n  [\"constant.language\",\"on\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"tcp_nopush\"],\n  [\"text\",\"   \"],\n  [\"constant.language\",\"on\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"server_names_hash_bucket_size\"],\n  [\"text\",\" 128\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"comment\",\"# this seems to be required for some vhosts\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"server\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"comment\",\"# php/fastcgi\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"listen\"],\n  [\"text\",\"       80\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server_name\"],\n  [\"text\",\"  domain1.com www.domain1.com\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"access_log\"],\n  [\"text\",\"   logs/domain1.access.log  \"],\n  [\"constant.language\",\"main\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"root\"],\n  [\"text\",\"         html\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"location\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"~ \\\\.php$ \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"fastcgi_pass\"],\n  [\"text\",\"   127.0.0.1:1025\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"server\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"comment\",\"# simple reverse-proxy\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"listen\"],\n  [\"text\",\"       80\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server_name\"],\n  [\"text\",\"  domain2.com www.domain2.com\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"access_log\"],\n  [\"text\",\"   logs/domain2.access.log  \"],\n  [\"constant.language\",\"main\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# serve static files\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"location\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"~ ^/(images|javascript|js|css|flash|media|static)/  \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"root\"],\n  [\"text\",\"    /var/www/virtual/big.server.com/htdocs\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"expires\"],\n  [\"text\",\" 30d\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# pass requests for dynamic content to rails/turbogears/zope, et al\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"location\"],\n  [\"text\",\" \"],\n  [\"text\",\"/ \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"proxy_pass\"],\n  [\"text\",\"      http://127.0.0.1:8080\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"upstream\"],\n  [\"text\",\" \"],\n  [\"text\",\"big_server_com \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server\"],\n  [\"text\",\" 127.0.0.3:8000 weight=5\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server\"],\n  [\"text\",\" 127.0.0.3:8001 weight=5\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server\"],\n  [\"text\",\" 192.168.0.1:8000\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server\"],\n  [\"text\",\" 192.168.0.1:8001\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"server\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"comment\",\"# simple load balancing\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"listen\"],\n  [\"text\",\"          80\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"server_name\"],\n  [\"text\",\"     big.server.com\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"access_log\"],\n  [\"text\",\"      logs/big.server.access.log \"],\n  [\"constant.language\",\"main\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"location\"],\n  [\"text\",\" \"],\n  [\"text\",\"/ \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"proxy_pass\"],\n  [\"text\",\"      http://big_server_com\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nim.json",
    "content": "[[\n   [\"blockComment\",\"blockComment\"],\n  [\"comment.start\",\"#[\"],\n  [\"comment\",\"  \"],\n  [\"comment.start\",\"#[\"],\n  [\"comment\",\" Multiline comment in already\"]\n],[\n   \"blockComment\",\n  [\"comment\",\"   commented out code. \"],\n  [\"comment.end\",\"]#\"]\n],[\n   \"blockComment\",\n  [\"comment\",\"proc p[T](x: T) = discard\"]\n],[\n   \"start\",\n  [\"comment.end\",\"]#\"]\n],[\n   \"start\",\n  [\"keyword\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"This is code\\\"\"]\n],[\n   \"start\",\n  [\"variable\",\"var\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"p\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.float\",\"0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"proc\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"getAlphabet\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accm\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"letter\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"string\",\"'a'\"],\n  [\"keyword.operator\",\"..\"],\n  [\"string\",\"'z'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"# see iterators\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"accm\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"add\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"letter\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accm\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"assert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"a\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.integer\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"aaaaaaaaaa\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nix.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"# Name of our deployment\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"network\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"description\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"HelloWorld\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"# Enable rolling back to previous versions of our infrastructure\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"network\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"enableRollback\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language.nix\",\"true\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"# It consists of a single server named 'helloserver'\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"helloserver\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# Every server gets passed a few arguments, including a reference\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# to nixpkgs (pkgs)\"]\n],[\n   \"start\",\n  [\"text\",\"    { \"],\n  [\"identifier\",\"config\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"pkgs\"],\n  [\"text\",\", ... }:\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.declaration.nix\",\"let\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# We import our custom packages from ./default passing pkgs as argument\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"packages\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.nix\",\"import\"],\n  [\"text\",\" ./\"],\n  [\"identifier\",\"default\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"nix\"],\n  [\"text\",\" { \"],\n  [\"identifier\",\"pkgs\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pkgs\"],\n  [\"text\",\"; };\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# This is the nodejs version specified in default.nix\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"nodejs\"],\n  [\"text\",\"   \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"packages\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"nodejs\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# And this is the application we'd like to deploy\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"app\"],\n  [\"text\",\"      \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"packages\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"app\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.declaration.nix\",\"in\"]\n],[\n   \"start\",\n  [\"text\",\"    {\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# We'll be running our application on port 8080, because a regular\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# user cannot bind to port 80\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# Then, using some iptables magic we'll forward traffic designated to port 80 to 8080\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"networking\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"firewall\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"enable\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language.nix\",\"true\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# We will open up port 22 (SSH) as well otherwise we're locking ourselves out\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"networking\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"firewall\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"allowedTCPPorts\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" [ \"],\n  [\"constant.numeric\",\"80\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"8080\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"22\"],\n  [\"text\",\" ];\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"networking\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"firewall\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"allowPing\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language.nix\",\"true\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# Port forwarding using iptables\"]\n],[\n   \"qqdoc\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"networking\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"firewall\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"extraCommands\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"''\"]\n],[\n   \"qqdoc\",\n  [\"string\",\"        iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080\"]\n],[\n   \"start\",\n  [\"string\",\"      ''\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# To run our node.js program we're going to use a systemd service\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# We can configure the service to automatically start on boot and to restart\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# the process in case it crashes\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"systemd\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"services\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"helloserver\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"description\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello world application\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"# Start the service after the network is available\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"after\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" [ \"],\n  [\"string\",\"\\\"network.target\\\"\"],\n  [\"text\",\" ];\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"# We're going to run it on port 8080 in production\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"environment\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" { \"],\n  [\"identifier\",\"PORT\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"8080\\\"\"],\n  [\"text\",\"; };\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"serviceConfig\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"comment\",\"# The actual command to run\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"ExecStart\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\"],\n  [\"constant.language.escape\",\"${\"],\n  [\"identifier\",\"nodejs\"],\n  [\"constant.language.escape\",\"}\"],\n  [\"string\",\"/bin/node \"],\n  [\"constant.language.escape\",\"${\"],\n  [\"identifier\",\"app\"],\n  [\"constant.language.escape\",\"}\"],\n  [\"string\",\"/server.js\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"comment\",\"# For security reasons we'll run this process as a special 'nodejs' user\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"User\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"nodejs\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"Restart\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"always\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        };\"]\n],[\n   \"start\",\n  [\"text\",\"      };\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"comment\",\"# And lastly we ensure the user we run our application as is created\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"users\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"extraUsers\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"nodejs\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.nix\",\"=\"],\n  [\"text\",\" { };\"]\n],[\n   \"start\",\n  [\"text\",\"      };\"]\n],[\n   \"start\",\n  [\"text\",\"    };\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nsis.json",
    "content": "[[\n   \"punctuation.definition.comment.nsis\",\n  [\"punctuation.definition.comment.nsis\",\"/*\"]\n],[\n   \"punctuation.definition.comment.nsis\",\n  [\"comment.block.nsis\",\"  NSIS Mode\"]\n],[\n   \"punctuation.definition.comment.nsis\",\n  [\"comment.block.nsis\",\"  for Ace\"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\"*/\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\";\"],\n  [\"comment.line.nsis\",\" Includes\"]\n],[\n   \"start\",\n  [\"keyword.compiler.nsis\",\"!include\"],\n  [\"text\",\" MUI2.nsh\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\";\"],\n  [\"comment.line.nsis\",\" Settings\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"Name\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"installer_name\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"OutFile\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"installer_name.exe\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"RequestExecutionLevel\"],\n  [\"text\",\" \"],\n  [\"constant.language.option.nsis\",\"user\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"CRCCheck\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean.true.nsis\",\"on\"]\n],[\n   \"start\",\n  [\"keyword.control.nsis\",\"!ifdef\"],\n  [\"text\",\" x64\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"  InstallDir\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"$PROGRAMFILES64\\\\installer_name\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.control.nsis\",\"!else\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"  InstallDir\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"$PROGRAMFILES\\\\installer_name\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.control.nsis\",\"!endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\";\"],\n  [\"comment.line.nsis\",\" Pages\"]\n],[\n   \"start\",\n  [\"keyword.compiler.nsis\",\"!insertmacro\"],\n  [\"text\",\" MUI_PAGE_INSTFILES\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\";\"],\n  [\"comment.line.nsis\",\" Sections\"]\n],[\n   \"start\",\n  [\"support.function.nsis\",\"Section\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"section_name\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"],\n  [\"text\",\" section_index\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.definition.comment.nsis\",\"#\"],\n  [\"comment.line.nsis\",\" your code here\"]\n],[\n   \"start\",\n  [\"support.function.nsis\",\"SectionEnd\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.nsis\",\";\"],\n  [\"comment.line.nsis\",\" Functions\"]\n],[\n   \"start\",\n  [\"support.function.nsis\",\"Function\"],\n  [\"text\",\" .onInit\"]\n],[\n   \"start\",\n  [\"keyword.command.nsis\",\"  MessageBox\"],\n  [\"text\",\" \"],\n  [\"constant.nsis\",\"MB_OK\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.nsis\",\"\\\"\"],\n  [\"string.quoted.double.nsis\",\"Here comes a\"],\n  [\"constant.character.escape.nsis\",\"$\\\\n$\\\\r\"],\n  [\"string.quoted.double.nsis\",\"line-break!\"],\n  [\"punctuation.definition.string.end.nsis\",\"\\\"\"]\n],[\n   \"start\",\n  [\"support.function.nsis\",\"FunctionEnd\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_nunjucks.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"foo\"],\n  [\"punctuation\",\".\"],\n  [\"variable.parameter\",\"bar\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"foo\"],\n  [\"paren.lpar\",\"[\"],\n  [\"string\",\"\\\"bar\\\"\"],\n  [\"paren.rpar\",\"]\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"foo\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"title\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"foo\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"join\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"\\\",\\\"\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"foo\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"replace\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"\\\"foo\\\"\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"bar\\\"\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"capitalize\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"header\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"This is the default content\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"section\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"left\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"left\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"section\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"section\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"right\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"right\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  This is more content\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"section\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"extends\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"parent.html\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"left\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"This is the left side!\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"right\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"This is the right side!\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"block\"],\n  [\"text\",\" \"],\n  [\"variable\",\"right\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"super\"],\n  [\"paren.lpar\",\"(\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"Right side!\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endblock\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"variable\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  It is true\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endif\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"hungry\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  I am hungry\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"elif\"],\n  [\"text\",\" \"],\n  [\"variable\",\"tired\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  I am tired\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"else\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  I am good!\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endif\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Posts\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"items\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"punctuation\",\".\"],\n  [\"variable.parameter\",\"title\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"else\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"This would display if the 'item' collection were empty\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"ingredient\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"amount\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"food\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  Use \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"amount\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"text.xml\",\" of \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"ingredient\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"fruit\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"color\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"fruits\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  Did you know that \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"fruit\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"text.xml\",\" is \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"color\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"text.xml\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"x\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"y\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"z\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"points\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  Point: \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"x\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"text.xml\",\", \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"y\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"text.xml\",\", \"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"z\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Posts\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"asyncEach\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"items\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"include\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"item-template.html\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endeach\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Posts\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"asyncAll\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"items\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"item\"],\n  [\"punctuation\",\".\"],\n  [\"variable.parameter\",\"id\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"lookup\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endall\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"macro\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"field\"],\n  [\"paren.lpar\",\"(\"],\n  [\"variable\",\"name\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"value\"],\n  [\"text\",\"=\"],\n  [\"string\",\"''\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"type\"],\n  [\"text\",\"=\"],\n  [\"string\",\"'text'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"field\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"tag_stuff\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"input\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"type\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"name\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"name\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"         \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"value\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"escape\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endmacro\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"username\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable\",\"username\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"joe\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"username\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable\",\"standardModal\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"include\"],\n  [\"text\",\" \"],\n  [\"string\",\"'standardModalData.html'\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endset\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"js-modal\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"data-modal\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"variable\",\"standardModal\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"e\"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable\",\"standardModal\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"include\"],\n  [\"text\",\" \"],\n  [\"string\",\"'standardModalData.html'\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endset\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"js-modal\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"data-modal\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"variable\",\"standardModal\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"|\"],\n  [\"text\",\" \"],\n  [\"support.other\",\"e\"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"include\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"missing.html\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"ignore missing\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"import\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"forms.html\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"as\"],\n  [\"text\",\" \"],\n  [\"variable\",\"forms\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"forms\"],\n  [\"punctuation\",\".\"],\n  [\"support.function\",\"label\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'Username'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"forms\"],\n  [\"punctuation\",\".\"],\n  [\"support.function\",\"field\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'user'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"forms\"],\n  [\"punctuation\",\".\"],\n  [\"support.function\",\"label\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'Password'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"forms\"],\n  [\"punctuation\",\".\"],\n  [\"support.function\",\"field\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'pass'\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"type\"],\n  [\"text\",\"=\"],\n  [\"string\",\"'password'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"from\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"forms.html\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"import\"],\n  [\"text\",\" \"],\n  [\"variable\",\"field\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"label\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"as\"],\n  [\"text\",\" \"],\n  [\"variable\",\"description\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"description\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'Username'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"field\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'user'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"description\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'Password'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"field\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"'pass'\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"type\"],\n  [\"text\",\"=\"],\n  [\"string\",\"'password'\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"foo\"],\n  [\"paren.lpar\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"bar\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"variable\",\"baz\"],\n  [\"text\",\"=\"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.begin\",\"{#\"],\n  [\"comment\",\" Loop through all the users \"],\n  [\"comment.end\",\"#}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"user\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"users\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"],\n  [\"text.xml\",\"...\"],\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable\",\"cls\"],\n  [\"text\",\" = \"],\n  [\"support.function\",\"cycler\"],\n  [\"paren.lpar\",\"(\"],\n  [\"string\",\"\\\"odd\\\"\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"even\\\"\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable\",\"row\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"rows\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"cls\"],\n  [\"punctuation\",\".\"],\n  [\"support.function\",\"next\"],\n  [\"paren.lpar\",\"(\"],\n  [\"paren.rpar\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.begin\",\"{{\"],\n  [\"text\",\" \"],\n  [\"variable\",\"row\"],\n  [\"punctuation\",\".\"],\n  [\"variable.parameter\",\"name\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.begin\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"punctuation.end\",\"%}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_objectivec.json",
    "content": "[[\n   \"start\",\n  [\"storage.type.objc\",\"@\"],\n  [\"punctuation.definition.storage.type.objc\",\"protocol\"],\n  [\"entity.name.type.objc\",\" Printing\"],\n  [\"text\",\": \"],\n  [\"entity.other.inherited-class.objc\",\"someParent\"]\n],[\n   \"start\",\n  [\"meta.function.objc\",\"-\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"void\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"print\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"storage.type.objc\",\"@end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.objc\",\"@\"],\n  [\"punctuation.definition.storage.type.objc\",\"interface\"],\n  [\"entity.name.type.objc\",\" Fraction\"],\n  [\"text\",\": \"],\n  [\"entity.other.inherited-class.objc\",\"NSObject\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"Printing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"support.class.cocoa\",\"NSCopying\"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"numerator\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"denominator\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.objc\",\"@end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"blah\"],\n  [\"invalid.illegal.unknown-escape.objc\",\"\\\\8\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"a\"],\n  [\"constant.character.escape.objc\",\"\\\\222\"],\n  [\"string\",\"sd\"],\n  [\"invalid.illegal.unknown-escape.objc\",\"\\\\d\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"constant.character.escape.objc\",\"\\\\f\"],\n  [\"string\",\"aw\"],\n  [\"constant.character.escape.objc\",\"\\\\\\\"\\\\?\"],\n  [\"string\",\" \"],\n  [\"constant.character.escape.objc\",\"\\\\'\"],\n  [\"string\",\" \"],\n  [\"constant.character.escape.objc\",\"\\\\4\"],\n  [\"string\",\" n\"],\n  [\"constant.character.escape.objc\",\"\\\\\\\\\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"constant.character.escape.objc\",\"\\\\56\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"constant.character.escape.objc\",\"\\\\xSF42\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.function.objc\",\"-\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.class.cocoa\",\"NSDecimalNumber\"],\n  [\"keyword.operator\",\"*\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"addCount\"],\n  [\"punctuation.operator\",\":\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type.id.objc\",\"id\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"addObject\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"decimalNumberByAdding:\"],\n  [\"identifier\",\"addObject\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"count\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.macro.objc\",\"NS_DURING\"],\n  [\"text\",\"  \"],\n  [\"keyword.control.macro.objc\",\"NS_HANDLER\"],\n  [\"text\",\" \"],\n  [\"keyword.control.macro.objc\",\"NS_ENDHANDLER\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.control.exception.objc\",\"try\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"argc\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.control.exception.objc\",\"throw\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSException\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"exceptionWithName:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"Throwing a test exception\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"reason\"],\n  [\"punctuation.operator\",\":\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"Testing the @throw directive.\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"userInfo\"],\n  [\"punctuation.operator\",\":\"],\n  [\"constant.language.objc\",\"nil\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.control.exception.objc\",\"catch\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type.id.objc\",\"id\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"theException\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.cocoa\",\"NSLog\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"%@\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"theException\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"result\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"  \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.control.exception.objc\",\"finally\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.cocoa\",\"NSLog\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"This always happens.\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"result\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.definition.storage.modifier.objc\",\"@\"],\n  [\"storage.modifier.objc\",\"synchronized\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"lock\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.cocoa\",\"NSLog\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"Hello World\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"struct\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.other.objc\",\"defs\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.class.cocoa\",\"NSObject\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"char\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"enc1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.keyword.objc\",\"@\"],\n  [\"keyword.other.objc\",\"encode\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"int\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"         \"],\n  [\"storage.type.objc\",\"IBOutlet\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"IBAction\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"BOOL\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"SEL\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.id.objc\",\"id\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"unichar\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"IMP\"],\n  [\"keyword.operator\",\"|\"],\n  [\"storage.type.objc\",\"Class\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"punctuation.definition.storage.type.objc\",\"@\"],\n  [\"storage.type.objc\",\"class\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.storage.type.objc\",\"@\"],\n  [\"storage.type.objc\",\"protocol\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.storage.modifier.objc\",\"@\"],\n  [\"storage.modifier.objc\",\"public\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// instance variables\"]\n],[\n   \"start\",\n  [\"punctuation.definition.storage.modifier.objc\",\"@\"],\n  [\"storage.modifier.objc\",\"package\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// instance variables\"]\n],[\n   \"start\",\n  [\"punctuation.definition.storage.modifier.objc\",\"@\"],\n  [\"storage.modifier.objc\",\"protected\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// instance variables\"]\n],[\n   \"start\",\n  [\"punctuation.definition.storage.modifier.objc\",\"@\"],\n  [\"storage.modifier.objc\",\"private\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"// instance variables\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"constant.language.objc\",\"YES\"],\n  [\"text\",\" \"],\n  [\"constant.language.objc\",\"NO\"],\n  [\"text\",\" \"],\n  [\"constant.language.objc\",\"Nil\"],\n  [\"text\",\" \"],\n  [\"constant.language.objc\",\"nil\"]\n],[\n   \"start\",\n  [\"support.variable.foundation\",\"NSApp\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"support.function.cocoa.leopard\",\"NSRectToCGRect\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"Protocol\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ProtocolFromString\"],\n  [\"punctuation.operator\",\":\"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"NSTableViewDelegate\"],\n  [\"string.end\",\"\\\"\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"identifier\",\"SPPoint\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"pointFromCGPoint:\"],\n  [\"identifier\",\"self\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"position\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.cocoa\",\"NSRoundDownToMultipleOfPageSize\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#import\"],\n  [\"constant.other\",\" <stdio.h>\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"argc\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"storage.modifier\",\"const\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"char\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"argv\"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"punctuation.section.scope.end.objc\",\"]\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.C99.c\",\"printf\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"hello world\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.class.cocoa\",\"NSChangeSpelling\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.storage.type.objc\",\"@selector\"],\n  [\"punctuation\",\"(\"],\n  [\"support.function.any-method.name-of-parameter.objc\",\"lowercaseString\"],\n  [\"punctuation\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.storage.type.objc\",\"@selector\"],\n  [\"punctuation\",\"(\"],\n  [\"support.function.any-method.name-of-parameter.objc\",\"uppercaseString:\"],\n  [\"punctuation\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"NSFetchRequest\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"localRequest\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[[\"],\n  [\"identifier\",\"NSFetchRequest\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"alloc\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"init\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"identifier\",\"localRequest\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"entity\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"identifier\",\"NSEntityDescription\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"entityForName:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"VNSource\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"inManagedObjectContext\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"context\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"identifier\",\"localRequest\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"sortDescriptors\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSArray\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"arrayWithObject:\"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSSortDescriptor\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"sortDescriptorWithKey:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"resolution\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ascending\"],\n  [\"punctuation.operator\",\":\"],\n  [\"constant.language.objc\",\"YES\"],\n  [\"paren.rparen\",\"]]\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"predicate\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"predicateWithFormat:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"predicateWithFormat:\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"support.class.cocoa\",\"NSString\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"predicateString\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSString\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"stringWithFormat:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"SELF beginsWith[cd] %@\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"searchString\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"pred\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"predicateWithFormat:\"],\n  [\"identifier\",\"predicateString\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"support.class.cocoa\",\"NSArray\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"filteredKeys\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[[\"],\n  [\"identifier\",\"myMutableDictionary\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"allKeys\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"filteredArrayUsingPredicate\"],\n  [\"punctuation.operator\",\":\"],\n  [\"identifier\",\"pred\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"localRequest\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"predicate\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"support.class.cocoa\",\"NSPredicate\"],\n  [\"text\",\" \"],\n  [\"support.function.any-method.objc\",\"predicateWithFormat:\"],\n  [\"string.begin.objc\",\"@\\\"\"],\n  [\"string\",\"whichChart = %@\"],\n  [\"punctuation.definition.string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"argumentArray\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"listChartToDownload\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"localRequest\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"fetchBatchSize\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"arrayRequest\"],\n  [\"text\",\"    \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"identifier\",\"context\"],\n  [\"text\",\"  \"],\n  [\"support.function.any-method.objc\",\"executeFetchRequest:\"],\n  [\"identifier\",\"localRequest\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"error\"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"&\"],\n  [\"identifier\",\"error1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.section.scope.begin.objc\",\"[\"],\n  [\"identifier\",\"localRequest\"],\n  [\"text\",\"   \"],\n  [\"support.function.any-method.objc\",\"release\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#ifndef\"],\n  [\"text\",\" \"],\n  [\"constant.language.objc\",\"Nil\"]\n],[\n   \"start\",\n  [\"keyword\",\"#define\"],\n  [\"constant.other\",\" Nil __DARWIN_NULL   \"],\n  [\"comment\",\"/* id of Nil class */\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type.objc\",\"@implementation\"],\n  [\"entity.name.type.objc\",\" MyObject\"]\n],[\n   \"start\",\n  [\"meta.function.objc\",\"- \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"unsigned\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"int\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"areaOfWidth\"],\n  [\"punctuation.operator\",\":\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"unsigned\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"int\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"width\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"height\"],\n  [\"punctuation.operator\",\":\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"unsigned\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"int\"],\n  [\"paren.rparen\",\")\"],\n  [\"identifier\",\"height\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"width\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"height\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.objc\",\"@end\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ocaml.json",
    "content": "[[\n   \"comment\",\n  [\"comment\",\"(*\"]\n],[\n   \"comment\",\n  [\"comment\",\" * Example of early return implementation taken from\"]\n],[\n   \"comment\",\n  [\"comment\",\" * http://ocaml.janestreet.com/?q=node/91\"]\n],[\n   \"start\",\n  [\"comment\",\" *)\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"with_return\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"type\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"f\"],\n  [\"text\",\" : \"],\n  [\"identifier\",\"_\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"M\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"keyword\",\"struct\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"exception\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Return\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"of\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"in\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"return\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"return\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"fun\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"raise\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"M\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\"; \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"try\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"f\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"return\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"with\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"M\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"(* Function that uses the 'early return' functionality provided by `with_return` *)\"]\n],[\n   \"start\",\n  [\"keyword\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sum_until_first_negative\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"list\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"with_return\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"fun\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"r\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"List\"],\n  [\"text\",\".\"],\n  [\"support.function\",\"fold\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"list\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"~\"],\n  [\"support.function\",\"init\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"~\"],\n  [\"identifier\",\"f\"],\n  [\"text\",\":\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"fun\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"acc\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"acc\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"r\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"acc\"],\n  [\"paren.rparen\",\"))\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_odin.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"package\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"core:fmt\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function\",\"main\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"::\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"proc\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"program\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"+ + * 😃 - /\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"token\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"program\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"switch\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"token\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"'+'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"'-'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"'*'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"'/'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"'😃'\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"case\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"comment\",\"// Ignore everything else\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"fmt\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function\",\"printf\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"The program \\\\\\\"%s\\\\\\\" calculates the value %d\\\\n\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"program\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_partiql.json",
    "content": "[[\n   \"start\",\n  [\"comment.line.partiql\",\"-- comment\"]\n],[\n   \"comment__1\",\n  [\"comment.block.partiql\",\"/* multi\"]\n],[\n   \"comment__1\",\n  [\"comment.block.partiql\",\"   line\"]\n],[\n   \"start\",\n  [\"comment.block.partiql\",\"   comment */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"a\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"b\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"c\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"stuff\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"INNER\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"CROSS\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"JOIN\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.at.partiql\",\"@s\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"WHERE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"f\"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"punctuation.partiql\",\")\"],\n  [\"text.partiql\",\"  \"],\n  [\"comment.line.partiql\",\"-- comment\"]\n],[\n   \"start\",\n  [\"comment.line.partiql\",\"-- comment\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.quoted.partiql\",\"\\\"a\\\"\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"b\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"stuff\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.at.partiql\",\"@s\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"WHERE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"f\"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"punctuation.partiql\",\")\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.tuple.begin.partiql\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"VALUE\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"sensor\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"sensor\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"]\n],[\n   \"punctuation.definition.tuple.begin.partiql\",\n  [\"text.partiql\",\"              \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"readings\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"VALUE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"l\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"co\"]\n],[\n   \"punctuation.definition.tuple.begin.partiql\",\n  [\"text.partiql\",\"                           \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"logs\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"l\"]\n],[\n   \"punctuation.definition.tuple.begin.partiql\",\n  [\"text.partiql\",\"                           \"],\n  [\"keyword.other.partiql\",\"WHERE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"l\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"sensor\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.operator.partiql\",\"=\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"s\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"sensor\"]\n],[\n   \"punctuation.definition.tuple.begin.partiql\",\n  [\"text.partiql\",\"                          \"],\n  [\"punctuation.partiql\",\")\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"             \"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"sensors\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"s\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"VALUE\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"keyword.other.partiql\",\"PIVOT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"g\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"              \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"UNPIVOT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"r\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"At\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"g\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"              \"],\n  [\"keyword.other.partiql\",\"WHERE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"g\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"LIKE\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"co%\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.partiql\",\")\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"sensors\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"r\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"x\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"keyword.operator.partiql\",\"*\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.array.begin.partiql\",\"[\"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"1\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"b\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"1\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.array.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"2\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.array.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"foo\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.array.end.partiql\",\"]\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"x\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.partiql\",\"-- NOTE: the embedded ion values parse as ion (inside the backticks \\\"`\\\")\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"x\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"keyword.operator.partiql\",\"*\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.ion.begin.partiql\",\"`\"],\n  [\"punctuation.definition.list.begin.ion\",\"[\"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"],\n  [\"storage.type.symbol.quoted.ion\",\"'a'\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"constant.numeric.integer.ion\",\"1\"],\n  [\"punctuation.definition.struct.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"storage.type.symbol.quoted.ion\",\"'b'\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"constant.numeric.integer.ion\",\"1\"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.struct.begin.ion\",\"{\"],\n  [\"storage.type.symbol.quoted.ion\",\"'a'\"],\n  [\"punctuation.definition.struct.separator.ion\",\":\"],\n  [\"constant.numeric.integer.ion\",\"2\"],\n  [\"punctuation.definition.struct.end.ion\",\"}\"],\n  [\"punctuation.definition.list.separator.ion\",\",\"],\n  [\"text.ion\",\" \"],\n  [\"punctuation.definition.string.begin.ion\",\"\\\"\"],\n  [\"string.quoted.double.ion\",\"foo\"],\n  [\"punctuation.definition.string.end.ion\",\"\\\"\"],\n  [\"punctuation.definition.list.end.ion\",\"]\"],\n  [\"punctuation.definition.ion.end.partiql\",\"`\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"x\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"VALUE\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"a\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"b\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"c\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"d\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.bag.begin.partiql\",\"<<\"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"same\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"b\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"1\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"c\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"same\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"d\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"2\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.bag.end.partiql\",\">>\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"id\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedbackId\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"commentId\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvoteId\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"users\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"feedbacks\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedback\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"at\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedbackId\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"LEFT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"CROSS\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"JOIN\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedback\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"comments\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"comment\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"commentId\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"LEFT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"CROSS\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"JOIN\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"UNPIVOT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"comment\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"upvotes\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvote\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"at\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvoteId\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.partiql\",\"(\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"        \"],\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"numRec\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"tabulated\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"        \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"committed\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"changes\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"changes\"],\n  [\"punctuation.partiql\",\",\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"          \"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"id\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedbackId\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"commentId\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvoteId\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"            \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"changes\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"tabulated\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\",\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"            \"],\n  [\"variable.language.identifier.partiql\",\"u\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"feedbacks\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedback\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"at\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedbackId\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"LEFT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"CROSS\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"JOIN\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"feedback\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"comments\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"comment\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"commentId\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"            \"],\n  [\"keyword.other.partiql\",\"LEFT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"CROSS\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"JOIN\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"UNPIVOT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"comment\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"upvotes\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvote\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"at\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"upvoteId\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"          \"],\n  [\"punctuation.partiql\",\")\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"tabulated\"],\n  [\"punctuation.partiql\",\",\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"          \"],\n  [\"variable.language.identifier.partiql\",\"changes\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"numRec\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"numRec\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"        \"],\n  [\"punctuation.partiql\",\")\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"    \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"changes\"]\n],[\n   \"start\",\n  [\"text.partiql\",\"    \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"incoming_committed\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"committed\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"support.function.aggregation.partiql\",\"SUM\"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"support.function.aggregation.partiql\",\"AVG\"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"variable.language.identifier.partiql\",\"n\"],\n  [\"punctuation.partiql\",\"))\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.bag.begin.partiql\",\"<<\"],\n  [\"variable.language.identifier.partiql\",\"numbers\"],\n  [\"punctuation.definition.bag.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"numbers\"],\n  [\"punctuation.definition.bag.end.partiql\",\">>\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"n\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"VALUES\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"a\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.array.begin.partiql\",\"[\"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"1\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"b\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.language.partiql\",\"true\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.array.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"2\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"b\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.language.partiql\",\"null\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.array.separator.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"punctuation.definition.tuple.begin.partiql\",\"{\"],\n  [\"punctuation.definition.string.begin.partiql\",\"'\"],\n  [\"string.quoted.single.partiql\",\"a\"],\n  [\"punctuation.definition.string.end.partiql\",\"'\"],\n  [\"punctuation.definition.tuple.separator.partiql\",\":\"],\n  [\"constant.numeric.partiql\",\"3\"],\n  [\"punctuation.definition.tuple.end.partiql\",\"}\"],\n  [\"punctuation.definition.array.end.partiql\",\"]\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"WHERE\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"v\"],\n  [\"punctuation.partiql\",\".\"],\n  [\"variable.language.identifier.partiql\",\"b\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"SELECT\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"attributeId\"],\n  [\"punctuation.partiql\",\",\"],\n  [\"text.partiql\",\" \"],\n  [\"support.function.aggregation.partiql\",\"COUNT\"],\n  [\"punctuation.partiql\",\"(\"],\n  [\"keyword.operator.partiql\",\"*\"],\n  [\"punctuation.partiql\",\")\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"as\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"the_count\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"FROM\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"repeating_things\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"GROUP\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"BY\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"attributeId\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"GROUP\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.other.partiql\",\"AS\"],\n  [\"text.partiql\",\" \"],\n  [\"variable.language.identifier.partiql\",\"g\"]\n],[\n   \"start\",\n  [\"keyword.other.partiql\",\"HAVING\"],\n  [\"text.partiql\",\" \"],\n  [\"constant.numeric.partiql\",\"1\"],\n  [\"text.partiql\",\" \"],\n  [\"keyword.operator.partiql\",\"=\"],\n  [\"text.partiql\",\" \"],\n  [\"constant.numeric.partiql\",\"0\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_pascal.json",
    "content": "[[\n   \"punctuation.definition.comment\",\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\"****************************************************************************\"]\n],[\n   \"punctuation.definition.comment\",\n  [\"comment.block.one\",\" * A simple bubble sort program.  Reads integers, one per line, and prints   *\"]\n],[\n   \"punctuation.definition.comment\",\n  [\"comment.block.one\",\" * them out in sorted order.  Blows up if there are more than 49.            *\"]\n],[\n   \"start\",\n  [\"comment.block.one\",\" ****************************************************************************\"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"PROGRAM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Sort\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"input\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"output\"],\n  [\"text\",\")\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"CONST\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Max array size. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"MaxElts\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"TYPE\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Type of the element array. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"IntArrType\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"ARRAY\"],\n  [\"text\",\" [\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"..\"],\n  [\"identifier\",\"MaxElts\"],\n  [\"text\",\"] \"],\n  [\"keyword.control\",\"OF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Integer\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"VAR\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Indexes, exchange temp, array size. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"tmp\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"integer\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Array of ints \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"IntArrType\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Read in the integers. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"PROCEDURE\"],\n  [\"text\",\" \"],\n  [\"storage.type.function\",\"ReadArr\"],\n  [\"text\",\"(\"],\n  [\"keyword.control\",\"VAR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Integer\"],\n  [\"keyword.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"VAR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"IntArrType\"],\n  [\"text\",\")\"],\n  [\"keyword.operator\",\";\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.control\",\"WHILE\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"eof\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"DO\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"readln\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"a\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"size\"],\n  [\"text\",\"])\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"eof\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.control\",\"END\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control\",\"END\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Read \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"ReadArr\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"size\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\")\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Sort using bubble sort. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DOWNTO\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"DO\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.control\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"TO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"DO\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword.control\",\"IF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\"] > \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"] \"],\n  [\"keyword.control\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"tmp\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\"]\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\"] \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"]\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"j\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"] \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"tmp\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword.control\",\"END\"],\n  [\"keyword.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"punctuation.definition.comment\",\"(*\"],\n  [\"comment.block.one\",\" Print. \"],\n  [\"punctuation.definition.comment\",\"*)\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.control\",\"FOR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"TO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"DO\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"writeln\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"arr\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\"])\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"END\"],\n  [\"text\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"            \"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_perl.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#!/usr/bin/perl\"]\n],[\n   \"block_comment\",\n  [\"comment.doc\",\"=begin\"]\n],[\n   \"block_comment\",\n  [\"comment.doc\",\" perl example code for Ace\"]\n],[\n   \"start\",\n  [\"comment.doc\",\"=cut\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"strict\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"warnings\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$num_primes\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"my\"],\n  [\"text\",\" @\"],\n  [\"identifier\",\"primes\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Put 2 as the first prime so we won't have an empty array\"]\n],[\n   \"start\",\n  [\"identifier\",\"$primes\"],\n  [\"lparen\",\"[\"],\n  [\"identifier\",\"$num_primes\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"$num_primes\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"MAIN_LOOP\"],\n  [\"text\",\":\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$number_to_check\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"..\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"200\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$p\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"..\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$num_primes\"],\n  [\"constant.numeric\",\"-1\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$number_to_check\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$primes\"],\n  [\"lparen\",\"[\"],\n  [\"identifier\",\"$p\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"next\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MAIN_LOOP\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# If we reached this point it means $number_to_check is not\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# divisable by any prime number that came before it.\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"$primes\"],\n  [\"lparen\",\"[\"],\n  [\"identifier\",\"$num_primes\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$number_to_check\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"$num_primes\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$p\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"..\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$num_primes\"],\n  [\"constant.numeric\",\"-1\"],\n  [\"rparen\",\"))\"]\n],[\n   \"start\",\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$primes\"],\n  [\"lparen\",\"[\"],\n  [\"identifier\",\"$p\"],\n  [\"rparen\",\"]\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\", \\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"support.function\",\"print\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\\n\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_pgsql.json",
    "content": "[[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"BEGIN\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"doc-start\",\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \"* Samples from PostgreSQL src/tutorial/basics.source\"\n  ]\n],[\n   \"start\",\n  [\"comment.doc\",\"*/\"]\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"TABLE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"city\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"varchar\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"80\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"temp_lo\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"int\"],\n  [\"text\",\",\\t\\t\"],\n  [\"comment\",\"-- low temperature\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"temp_hi\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"int\"],\n  [\"text\",\",\\t\\t\"],\n  [\"comment\",\"-- high temperature\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"prcp\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"real\"],\n  [\"text\",\",\\t\\t\"],\n  [\"comment\",\"-- precipitation\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"variable.language\",\"\\\"date\\\"\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"date\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"TABLE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cities\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"name\"],\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"varchar\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"80\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"statement\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"location\"],\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"point\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"INSERT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"VALUES\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'San Francisco'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"46\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.25\"],\n  [\"text\",\", \"],\n  [\"string\",\"'1994-11-27'\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"INSERT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cities\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"VALUES\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'San Francisco'\"],\n  [\"text\",\", \"],\n  [\"string\",\"'(-194.0, 53.0)'\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"INSERT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"city\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_lo\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_hi\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"prcp\"],\n  [\"text\",\", \"],\n  [\"variable.language\",\"\\\"date\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"VALUES\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'San Francisco'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"43\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"57\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.0\"],\n  [\"text\",\", \"],\n  [\"string\",\"'1994-11-29'\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"INSERT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"INTO\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"date\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"city\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_hi\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_lo\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"VALUES\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'1994-11-29'\"],\n  [\"text\",\", \"],\n  [\"string\",\"'Hayward'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"54\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"37\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"city\"],\n  [\"text\",\", \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"temp_hi\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"temp_lo\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"temp_avg\"],\n  [\"text\",\", \"],\n  [\"variable.language\",\"\\\"date\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"city\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_lo\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"temp_hi\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"prcp\"],\n  [\"text\",\", \"],\n  [\"variable.language\",\"\\\"date\\\"\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"location\"]\n],[\n   \"statement\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"weather\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"cities\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"city\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"name\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"doc-start\",\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \"* Dollar quotes starting at the end of the line are colored as SQL unless\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \"* a special language tag is used. Dollar quote syntax coloring is implemented\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \"* for Perl, Python, JavaScript, and Json.\"\n  ]\n],[\n   \"start\",\n  [\"comment.doc\",\"*/\"]\n],[\n   \"statement\",\n  [\"keyword.statementBegin\",\"create\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"or\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"replace\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"blob_content_chunked\"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"statement\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p_data\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"bytea\"],\n  [\"text\",\", \"]\n],[\n   \"statement\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p_chunk\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"integer\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"returns\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"setof\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"bytea\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"as\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$\"]\n],[\n   \"dollarSql\",\n  [\"comment\",\"-- Still SQL comments\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"declare\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"v_size\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"integer\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"octet_length\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"p_data\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"begin\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"..\"],\n  [\"identifier\",\"v_size\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"by\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p_chunk\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"return\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"next\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"substring\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"p_data\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p_chunk\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"loop\"],\n  [\"text\",\";\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"end\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"$$\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"language\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plpgsql\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"stable\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- pl/perl\"]\n],[\n   \"perl-start\",\n  [\"keyword.statementBegin\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FUNCTION\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"perl_max\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"integer\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"integer\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"RETURNS\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"integer\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"string\",\"$perl$\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# perl comment...\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$x\"],\n  [\"keyword.operator\",\",\"],\n  [\"identifier\",\"$y\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" @\"],\n  [\"identifier\",\"_\"],\n  [\"text\",\";\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"defined\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$x\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"perl-start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"defined\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$y\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"undef\"],\n  [\"text\",\"; \"],\n  [\"rparen\",\"}\"]\n],[\n   \"perl-start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$y\"],\n  [\"text\",\";\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"defined\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$y\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$x\"],\n  [\"text\",\"; \"],\n  [\"rparen\",\"}\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"$x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$y\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$x\"],\n  [\"text\",\"; \"],\n  [\"rparen\",\"}\"]\n],[\n   \"perl-start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"$y\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"$perl$\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"LANGUAGE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plperl\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- pl/python\"]\n],[\n   \"python-start\",\n  [\"keyword.statementBegin\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FUNCTION\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"usesavedplan\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"RETURNS\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"trigger\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"string\",\"$python$\"]\n],[\n   \"python-start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# python comment...\"]\n],[\n   \"python-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SD\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"has_key\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"plan\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\":\"]\n],[\n   \"python-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"plan\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SD\"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"plan\\\"\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"python-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"else\"],\n  [\"punctuation\",\":\"]\n],[\n   \"python-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"plan\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plpy\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"prepare\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"SELECT 1\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"python-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"SD\"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"plan\\\"\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plan\"]\n],[\n   \"start\",\n  [\"string\",\"$python$\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"LANGUAGE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plpythonu\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- pl/v8 (javascript)\"]\n],[\n   \"javascript-start\",\n  [\"keyword.statementBegin\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"FUNCTION\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plv8_test\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"keys\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"text\"],\n  [\"text\",\"[], \"],\n  [\"identifier\",\"vals\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"text\"],\n  [\"text\",\"[]\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"RETURNS\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"text\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"string\",\"$javascript$\"]\n],[\n   \"javascript-start\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"javascript-start\",\n  [\"keyword\",\"for\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"keys\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.constant\",\"length\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"++\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"javascript-start\",\n  [\"text\",\" \"],\n  [\"identifier\",\"o\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"keys\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"vals\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"javascript-no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"javascript-start\",\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"JSON\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"stringify\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"o\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"string\",\"$javascript$\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"LANGUAGE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plv8\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"IMMUTABLE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"STRICT\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- json\"]\n],[\n   \"json-start\",\n  [\"keyword.statementBegin\",\"select\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"json_object_keys\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"$json$\"]\n],[\n   \"json-start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"json-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"f1\\\"\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"5\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"json-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"f2\\\"\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"test\\\"\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"json-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"\\\"f3\\\"\"],\n  [\"text\",\": \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"json-start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"string\",\"$json$\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- psql commands\"]\n],[\n   \"start\",\n  [\"support.buildin\",\"\\\\df cash*\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Some string samples.\"]\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"select\"],\n  [\"text\",\" \"],\n  [\"string\",\"'don''t do it now;'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"||\"],\n  [\"text\",\" \"],\n  [\"string\",\"'maybe later'\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"select\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"E\"],\n  [\"string\",\"'dont\\\\'t do it'\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"select\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"length\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'some other''s stuff'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"||\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$cat in hat's stuff $$\"],\n  [\"paren.rparen\",\")\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"dollarStatementString\",\n  [\"keyword.statementBegin\",\"select\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$ strings\"]\n],[\n   \"dollarStatementString\",\n  [\"string\",\"over multiple \"]\n],[\n   \"dollarStatementString\",\n  [\"string\",\"lines - use dollar quotes\"]\n],[\n   \"start\",\n  [\"string\",\"$$\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.statementBegin\",\"END\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"-- Anonymous code block\"]\n],[\n   \"dollarSql\",\n  [\"keyword.statementBegin\",\"DO\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"LANGUAGE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plpgsql\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"    \"],\n  [\"comment\",\"-- code block\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n],[\n   \"dollarSql\",\n  [\"keyword.statementBegin\",\"DO\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$\"]\n],[\n   \"dollarSql\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"dollarSql\",\n  [\"text\",\"    \"],\n  [\"comment\",\"-- code block\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"],\n  [\"statementEnd\",\";\"],\n  [\"text\",\" \"],\n  [\"string\",\"$$\"],\n  [\"statementEnd\",\";\"]\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_php.json",
    "content": "[[\n   \"php-start\",\n  [\"support.php_tag\",\"<?php\"]\n],[\n   [\"php-heredoc\",\"EOD\"],\n  [\"variable\",\"$bar\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"markup.list\",\"<<<EOD\"]\n],[\n   [\"php-heredoc\",\"EOD\"],\n  [\"string\",\"highlightingWithNoSpaces\"]\n],[\n   [\"php-heredoc\",\"EOD\"],\n  [\"string\",\"doesn't break\"]\n],[\n   \"php-start\",\n  [\"markup.list\",\"EOD\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\"\n],[\n   [\"php-heredoc\",\"TEST\"],\n  [\"identifier\",\"lorem\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'ipsum'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"markup.list\",\"<<<TEST\"]\n],[\n   [\"php-heredoc\",\"TEST\"],\n  [\"string\",\"foo bar\"]\n],[\n   \"php-start\",\n  [\"markup.list\",\"TEST\"]\n],[\n   \"php-start\",\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\"\n],[\n   \"php-start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"nfact\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$n\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"php-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"php-start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"php-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"php-start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"return\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"nfact\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"php-start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"php-start\"\n],[\n   \"php-start\",\n  [\"support.function\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\"],\n  [\"constant.language.escape\",\"\\\\n\\\\n\"],\n  [\"string\",\"Please enter a whole number ... \\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\",\n  [\"variable\",\"$num\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"trim\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"fgets\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.language\",\"STDIN\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\"\n],[\n   \"php-start\",\n  [\"comment\",\"// ===== PROCESS - Determing the factorial of the input number =====\"]\n],[\n   \"php-start\",\n  [\"variable\",\"$output\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\"],\n  [\"constant.language.escape\",\"\\\\n\\\\n\"],\n  [\"string\",\"Factorial \\\"\"],\n  [\"text\",\" . \"],\n  [\"variable\",\"$num\"],\n  [\"text\",\" . \"],\n  [\"string\",\"\\\" = \\\"\"],\n  [\"text\",\" . \"],\n  [\"identifier\",\"nfact\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$num\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" . \"],\n  [\"string\",\"\\\"\"],\n  [\"constant.language.escape\",\"\\\\n\\\\n\"],\n  [\"string\",\"\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\",\n  [\"support.function\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$output\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"php-start\"\n],[\n   [\"php-start\",\"js-start\"],\n  [\"support.php_tag\",\"?>\"],\n  [\"text.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text\",\"  \"],\n  [\"support.php_tag\",\"<?php\"]\n],[\n   [\"#tmp\",\"php-qstring\",\"php-start\",\"js-start\"],\n  [\"support.function\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string\",\"'\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"string\",\"'\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"1_000_000\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"6.62_607_004e-34\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"0.300_000_000_000_000_04\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"0b1111_0000_1001_1111_1001_0010_1010_1001\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"0123_7264\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"0xBEEF_BABE\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"php-start\",\"js-start\"],\n  [\"constant.numeric\",\"0o123\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"support.php_tag\",\"?>\"]\n],[\n   \"js-comment1\",\n  [\"comment\",\"/*this is js \"],\n  [\"support.php_tag\",\"<?php\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string\",\"':)'\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"support.php_tag\",\"?>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" not \"],\n  [\"constant.language.escape.reference.xml\",\"&js;\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_php_laravel_blade.json",
    "content": "[[\n   \"start\",\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" Stored in resources/views/layouts/app.blade.php \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"App Name - \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"yield\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"title\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"app\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"json\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$array\"],\n  [\"parenthesis.end.blade\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"extends\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"layouts.app\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"section\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"sidebar\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"parent\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"This is appended to the master sidebar.\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"endsection\"]\n],[\n   \"start\",\n  [\"text.xml\",\" \"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"if\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"source.blade\",\"count\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$records\"],\n  [\"parenthesis.end.blade\",\")\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"===\"],\n  [\"source.blade\",\" 1\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            I have one record!\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"else\"],\n  [\"text.xml\",\"if \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"source.blade\",\"count\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$records\"],\n  [\"parenthesis.end.blade\",\")\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\">\"],\n  [\"source.blade\",\" 1\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            I have multiple records!\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"else\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            I don't have any records!\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"foreach\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$users\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"as\"],\n  [\"source.blade\",\" \"],\n  [\"variable.blade\",\"$user\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"if\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"type\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"==\"],\n  [\"source.blade\",\" 1\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"continue\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"injections.begin.blade\",\"{{\"],\n  [\"source.blade\",\" \"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"name\"],\n  [\"source.blade\",\" \"],\n  [\"injections.end.blade\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"if\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"number\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"==\"],\n  [\"source.blade\",\" 5\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"break\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endif\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endforeach\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"foreach\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$users\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"as\"],\n  [\"source.blade\",\" \"],\n  [\"variable.blade\",\"$user\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"continue\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"type\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"==\"],\n  [\"source.blade\",\" 1\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"injections.begin.blade\",\"{{\"],\n  [\"source.blade\",\" \"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"name\"],\n  [\"source.blade\",\" \"],\n  [\"injections.end.blade\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"break\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"number\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"==\"],\n  [\"source.blade\",\" 5\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endforeach\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"include\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"shared.errors\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.form.tag-name.xml\",\"form\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"                \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" Form Contents \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.form.tag-name.xml\",\"form\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"includeIf\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"view.name\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"keyword.operator.blade\",\",\"],\n  [\"source.blade\",\" [\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"some\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"=>\"],\n  [\"source.blade\",\" \"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"data\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"source.blade\",\"]\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"env\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"local\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            // The application is in the local environment...\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"elseenv\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"testing\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            // The application is in the testing environment...\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"else\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            // The application is not in the local or testing environment...\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"endenv\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"class\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"container\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.directives.blade\",\"yield\"],\n  [\"parenthesis.begin.blade\",\"(\"],\n  [\"punctuation.definition.string.begin.blade\",\"'\"],\n  [\"string.quoted.double.blade\",\"content\"],\n  [\"punctuation.definition.string.end.blade\",\"'\"],\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.begin.blade\",\"{{--\"],\n  [\"comment.block.blade\",\" comment \"],\n  [\"punctuation.definition.comment.end.blade\",\"--}}\"]\n],[\n   \"start\"\n],[\n   \"parenthesis.begin.blade\",\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"if\"],\n  [\"text.xml\",\" \"],\n  [\"parenthesis.begin.blade\",\"(\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"punctuation.definition.comment.begin.blade\",\"{{--\"],\n  [\"comment.block.blade\",\" comment \"],\n  [\"punctuation.definition.comment.end.blade\",\"--}}\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"punctuation.definition.comment.begin.php\",\"/*\"],\n  [\"comment.block.blade\",\"block comment\"],\n  [\"punctuation.definition.comment.end.php\",\"*/\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"punctuation.definition.comment.blade\",\"#another comment\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"variable.blade\",\"$user\"],\n  [\"keyword.operator.blade\",\"->\"],\n  [\"constant.other.property.blade\",\"type\"],\n  [\"source.blade\",\" \"],\n  [\"keyword.operator.blade\",\"==\"],\n  [\"source.blade\",\" 1\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"punctuation.definition.comment.blade\",\"// c comment\"]\n],[\n   \"parenthesis.begin.blade\",\n  [\"source.blade\",\"    \"],\n  [\"punctuation.definition.comment.begin.php\",\"/*\"],\n  [\"comment.block.blade\",\" comment\"],\n  [\"punctuation.definition.comment.end.php\",\"*/\"]\n],[\n   \"start\",\n  [\"parenthesis.end.blade\",\")\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    # not a comment \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"#//x\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"directive.declaration.blade\",\"@\"],\n  [\"keyword.control.blade\",\"endif\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_pig.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"A = \"],\n  [\"keyword.control.pig\",\"load\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single.pig\",\"'mobydick.txt'\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"B = \"],\n  [\"keyword.control.pig\",\"foreach\"],\n  [\"text\",\" A \"],\n  [\"keyword.control.pig\",\"generate\"],\n  [\"text\",\" \"],\n  [\"support.function.udf.pig\",\"flatten\"],\n  [\"text\",\"(\"],\n  [\"support.function.udf.string.pig\",\"TOKENIZE\"],\n  [\"text\",\"((\"],\n  [\"storage.datatypes.pig\",\"chararray\"],\n  [\"text\",\")\"],\n  [\"variable.pig\",\"$0\"],\n  [\"text\",\")) \"],\n  [\"keyword.control.pig\",\"as\"],\n  [\"text\",\" word;\"]\n],[\n   \"start\",\n  [\"text\",\"C = \"],\n  [\"keyword.control.pig\",\"filter\"],\n  [\"text\",\" B \"],\n  [\"keyword.control.pig\",\"by\"],\n  [\"text\",\" word \"],\n  [\"keyword.operator.comparison.pig\",\"matches\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single.pig\",\"'\"],\n  [\"constant.character.escape.pig\",\"\\\\\\\\\"],\n  [\"string.quoted.single.pig\",\"w+'\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"D = \"],\n  [\"keyword.control.pig\",\"group\"],\n  [\"text\",\" C \"],\n  [\"keyword.control.pig\",\"by\"],\n  [\"text\",\" word;\"]\n],[\n   \"start\",\n  [\"text\",\"E = \"],\n  [\"keyword.control.pig\",\"foreach\"],\n  [\"text\",\" D \"],\n  [\"keyword.control.pig\",\"generate\"],\n  [\"text\",\" \"],\n  [\"support.function.udf.math.pig\",\"COUNT\"],\n  [\"text\",\"(C) \"],\n  [\"keyword.control.pig\",\"as\"],\n  [\"text\",\" \"],\n  [\"support.function.udf.math.pig\",\"count\"],\n  [\"text\",\", \"],\n  [\"keyword.control.pig\",\"group\"],\n  [\"text\",\" \"],\n  [\"keyword.control.pig\",\"as\"],\n  [\"text\",\" word;\"]\n],[\n   \"start\",\n  [\"text\",\"F = \"],\n  [\"keyword.control.pig\",\"order\"],\n  [\"text\",\" E \"],\n  [\"keyword.control.pig\",\"by\"],\n  [\"text\",\" \"],\n  [\"support.function.udf.math.pig\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.control.pig\",\"desc\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"comment.line.double-dash.asciidoc\",\"-- one comment\"]\n],[\n   \"start\",\n  [\"comment.block.pig\",\"/* another comment */\"]\n],[\n   \"start\",\n  [\"keyword.control.pig\",\"dump\"],\n  [\"text\",\" F;\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_plsql.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"create\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"table\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"id\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"integer\"],\n  [\"text\",\", \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"month\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"varchar\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\", \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"value\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"integer\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"into\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"month\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"value\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"values\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'jan'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"into\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"month\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"value\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"values\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'jan'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"into\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"month\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"value\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"values\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'oct'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"insert\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"into\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"month\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"value\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"values\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'dec'\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"96\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"select\"],\n  [\"text\",\" * \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"select\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"month\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"value\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"identifier\",\"pivot\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"sum\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"value\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"month\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'jan'\"],\n  [\"text\",\", \"],\n  [\"string\",\"'oct'\"],\n  [\"text\",\", \"],\n  [\"string\",\"'dec'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_powershell.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# This is a simple comment\"]\n],[\n   \"start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Hello\"],\n  [\"lparen\",\"(\"],\n  [\"variable.instance\",\"$name\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"Write-host\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello \"],\n  [\"variable.instance\",\"$name\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"add\"],\n  [\"lparen\",\"(\"],\n  [\"variable.instance\",\"$left\"],\n  [\"text\",\", \"],\n  [\"variable.instance\",\"$right\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"4\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"variable.instance\",\"$right\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-ne\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$left\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"elseif\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"variable.instance\",\"$left\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-eq\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$null\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-and\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$right\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-eq\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.instance\",\"$number\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$number\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"Write-Host\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Hello\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"World\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.instance\",\"$an_array\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"3\"],\n  [\"keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$a_hash\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"string\",\"\\\"something\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"something else\\\"\"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.operator\",\"&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"notepad\"],\n  [\"text\",\" .\\\\\"],\n  [\"identifier\",\"readme\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"md\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.instance\",\"$h1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FirstName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Anderson\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"123\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$last\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Anderson\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"120\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$h2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FirstName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$last\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$h3\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"variable.instance\",\"$h4\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20.5\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Anderson\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$true\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"123\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.braced\",\"${Maximum_Count_26}\"]\n],[\n   \"start\",\n  [\"variable.braced\",\"${Name with\"],\n  [\"constant.language.escape\",\"`t\"],\n  [\"variable.braced\",\"white space and \"],\n  [\"constant.language.escape\",\"`{\"],\n  [\"variable.braced\",\"punctuation\"],\n  [\"constant.language.escape\",\"`}\"],\n  [\"variable.braced\",\"}\"]\n],[\n   \"start\",\n  [\"variable.braced\",\"${E:\\\\\\\\File.txt}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"\\\"C:\\\\Temp\\\\\\\"\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"identifier\",\"mkdir\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"C:\\\\Temp\\\\\\\"\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"C:\\\\Temp\\\\\\\"\"]\n],[\n   \"start\"\n],[\n   \"string0\",\n  [\"string\",\"@\\\"\"]\n],[\n   \"string0\",\n  [\"string\",\"This is a here string\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$h1\"],\n  [\"string\",\" = \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FirstName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Anderson\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"123\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$last\"],\n  [\"string\",\" = \\\"Anderson\\\"; \"],\n  [\"variable.instance\",\"$IDNum\"],\n  [\"string\",\" = 120\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$h2\"],\n  [\"string\",\" = \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FirstName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LastName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$last\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$IDNum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$h3\"],\n  [\"string\",\" = \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$h4\"],\n  [\"string\",\" = \"],\n  [\"keyword.operator\",\"@{\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"James\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20.5\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Anderson\\\"\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$true\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"123\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"}\"]\n],[\n   \"string0\",\n  [\"variable.instance\",\"$j\"],\n  [\"string\",\" = 20\"]\n],[\n   \"string0\"\n],[\n   \"string0\",\n  [\"string\",\"still string\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets nothing\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets int 10\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$j\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets int 20\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$j\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets [object[]](10,20)\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"++\"],\n  [\"variable.instance\",\"$j\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets int 10\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword.operator\",\"++\"],\n  [\"variable.instance\",\"$j\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets [object[]](10,22)\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"variable.instance\",\"$i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"punctuation\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"++\"],\n  [\"variable.instance\",\"$j\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets nothing\"]\n],[\n   \"string0\",\n  [\"keyword.operator\",\"$(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"6\"],\n  [\"keyword.operator\",\")\"],\n  [\"string\",\" # pipeline gets [object[]](2,4,6)\"]\n],[\n   \"start\",\n  [\"string\",\"\\\"@\"]\n],[\n   \"start\"\n],[\n   \"string\",\n  [\"string\",\"@'\"]\n],[\n   \"string\",\n  [\"string\",\"Expressions inside should be recognised as string\"]\n],[\n   \"string\",\n  [\"string\",\"$h1 = @{ FirstName = \\\"James\\\"; LastName = \\\"Anderson\\\"; IDNum = 123 }\"]\n],[\n   \"string\",\n  [\"string\",\"$last = \\\"Anderson\\\"; $IDNum = 120\"]\n],[\n   \"string\",\n  [\"string\",\"$h2 = @{ FirstName = \\\"James\\\"; LastName = $last; IDNum = $IDNum + 3 }\"]\n],[\n   \"string\",\n  [\"string\",\"$h3 = @{ }\"]\n],[\n   \"string\",\n  [\"string\",\"$h4 = @{ 10 = \\\"James\\\"; 20.5 = \\\"Anderson\\\"; $true = 123 }\"]\n],[\n   \"start\",\n  [\"string\",\"'@\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_praat.json",
    "content": "[[\n   \"form\",\n  [\"keyword\",\"form\"],\n  [\"text\",\" \"],\n  [\"entity.name.section\",\"Highlighter test\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"sentence \"],\n  [\"text\",\"My_sentence \"],\n  [\"string\",\"This should all be a string\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"text \"],\n  [\"text\",\"My_text \"],\n  [\"string\",\"This should also all be a string\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"word \"],\n  [\"text\",\"My_word \"],\n  [\"string\",\"Only\"],\n  [\"invalid.illegal\",\" the first word is a string, the rest is invalid\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"boolean \"],\n  [\"text\",\"Binary \"],\n  [\"constant.language\",\"1\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"boolean \"],\n  [\"text\",\"Text \"],\n  [\"constant.language\",\"no\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"boolean \"],\n  [\"text\",\"Quoted \"],\n  [\"constant.language\",\"\\\"yes\\\"\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"comment \"],\n  [\"string\",\"This should be a string\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"real \"],\n  [\"text\",\"left_Range \"],\n  [\"constant.numeric\",\"-123.6\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"positive \"],\n  [\"text\",\"right_Range_max \"],\n  [\"constant.numeric\",\"3.3\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"integer \"],\n  [\"text\",\"Int \"],\n  [\"constant.numeric\",\"4\"]\n],[\n   \"form\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"natural \"],\n  [\"text\",\"Nat \"],\n  [\"constant.numeric\",\"4\"]\n],[\n   \"start\",\n  [\"keyword\",\"endform\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# External scripts\"]\n],[\n   \"start\",\n  [\"keyword\",\"include\"],\n  [\"text\",\" \"],\n  [\"string\",\"/path/to/file\"]\n],[\n   \"start\",\n  [\"support.function\",\"runScript\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"/path/to/file\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"execute\"],\n  [\"text\",\" \"],\n  [\"string\",\"/path/to/file\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"stopwatch\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# old-style procedure call\"]\n],[\n   \"start\",\n  [\"keyword\",\"call\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"oldStyle\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"quoted\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" unquoted string\"]\n],[\n   \"start\",\n  [\"keyword\",\"assert\"],\n  [\"text\",\" oldStyle.local\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# New-style procedure call with parens\"]\n],[\n   \"start\",\n  [\"entity.name.function\",\"@newStyle\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"quoted\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"quoted string\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"praatVersion\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5364\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"comment\",\"  # New-style procedure call with colon\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"entity.name.function\",\"@newStyle\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"quoted\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"quoted string\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# if-block with built-in variables\"]\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"windows\"]\n],[\n   \"start\",\n  [\"comment\",\"  # We are on Windows\"]\n],[\n   \"start\",\n  [\"keyword\",\"elsif\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"unix\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"or\"],\n  [\"text\",\" \"],\n  [\"text\",\"!\"],\n  [\"variable.language\",\"macintosh\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"exitScript\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"We are on Linux\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"macintosh\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"exit\"],\n  [\"text\",\" \"],\n  [\"string\",\"We are on Mac\"]\n],[\n   \"start\",\n  [\"keyword\",\"endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# inline if with inline comment\"]\n],[\n   \"start\",\n  [\"text\",\"var\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"macintosh\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"fi\"],\n  [\"text\",\" \"],\n  [\"comment\",\"; This is an inline comment\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# for-loop with explicit from using local variable\"]\n],[\n   \"start\",\n  [\"comment\",\"# and paren-style function calls and variable interpolation\"]\n],[\n   \"start\",\n  [\"text\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"numberOfSelected\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Sound\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" i \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" newStyle.local \"],\n  [\"keyword\",\"to\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"text\",\"  sound\"],\n  [\"string.interpolated\",\"'i'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"selected\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Sound\\\"\"],\n  [\"text\",\", i)\"]\n],[\n   \"start\",\n  [\"text\",\"  sound[i]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"text\",\"sound\"],\n  [\"string.interpolated\",\"'i'\"]\n],[\n   \"start\",\n  [\"keyword\",\"endfor\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" i \"],\n  [\"keyword\",\"from\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"to\"],\n  [\"text\",\" n\"]\n],[\n   \"start\",\n  [\"comment\",\"  # Different styles of object selection\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"select\"],\n  [\"text\",\" sound\"],\n  [\"string.interpolated\",\"'i'\"]\n],[\n   \"start\",\n  [\"text\",\"  sound\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"selected\"],\n  [\"text\",\"(\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  sound$\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"selected$\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Sound\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"select\"],\n  [\"text\",\" \"],\n  [\"entity.name.type\",\"Sound\"],\n  [\"text\",\" \"],\n  [\"string.interpolated\",\"'sound$'\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"selectObject\"],\n  [\"text\",\"(\"],\n  [\"text\",\"sound[i])\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"selectObject\"],\n  [\"text\",\":\"],\n  [\"text\",\" sound\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"comment\",\"  # Pause commands\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"beginPause\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Viewing \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"text\",\"sound$)\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    button\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"endPause\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Stop\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Previous\\\"\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      ...\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"text\",\"total_sounds \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Finish\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Next\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"fi\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      ...\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"    button\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"endPause\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Stop\\\"\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      ...\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"text\",\"total_sounds \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Finish\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Next\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"fi\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      ...\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\")  \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"endif\"]\n],[\n   \"start\",\n  [\"text\",\"  editor_name$\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" total_textgrids \"],\n  [\"keyword\",\"then\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"TextGrid \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Sound \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"fi\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"text\",\"name$\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"nocheck\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"editor\"],\n  [\"text\",\" \"],\n  [\"string.interpolated\",\"'editor_name$'\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"nocheck\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Close\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"nocheck\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"endeditor\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"comment\",\"  # New-style standalone command call\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Rename:\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"SomeName\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"  # Command call with assignment\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text\",\"duration \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Get total duration\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"comment\",\"  # Multi-line command with modifier\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text\",\"pitch \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"noprogress\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"To Pitch (ac):\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"75\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"15\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"no\\\"\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    ...\"],\n  [\"constant.numeric\",\"0.03\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.45\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.01\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.35\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.14\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"600\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"comment\",\"  # do-style command with assignment\"]\n],[\n   \"start\",\n  [\"text\",\"  minimum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"do\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Get minimum...\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Hertz\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Parabolic\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"  # New-style multi-line command call with broken strings\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text\",\"table \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Create Table with column names:\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"table\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"]\n],[\n   \"brokenstring\",\n  [\"text\",\"    ...\"],\n  [\"string\",\"\\\"file subject speaker\"]\n],[\n   \"start\",\n  [\"text\",\"    ...\"],\n  [\"string\",\"f0 f1 f2 f3 \"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\" +\"]\n],[\n   \"start\",\n  [\"text\",\"    ...\"],\n  [\"string\",\"\\\"duration response\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"removeObject\"],\n  [\"text\",\":\"],\n  [\"text\",\" pitch, table\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"comment\",\"  # Picture window commands\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"selectObject\"],\n  [\"text\",\":\"],\n  [\"text\",\" sound\"]\n],[\n   \"start\",\n  [\"comment\",\"  # do-style command\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"do\"],\n  [\"text\",\"(\"],\n  [\"string\",\"\\\"Select inner viewport...\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"6\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.5\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1.5\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Black\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Draw...\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"no\\\"\"],\n  [\"text\",\" Curve\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Draw inner box\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Text bottom:\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"yes\\\"\"],\n  [\"text\",\", sound$\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Erase all\"]\n],[\n   \"start\",\n  [\"text\",\"  \"]\n],[\n   \"start\",\n  [\"comment\",\"  # Demo window commands\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Erase all\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Select inner viewport...\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Axes...\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Paint rectangle...\"],\n  [\"text\",\" white \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Text...\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\" centre \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\" half Click to finish\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function\",\"demoWaitForInput\"],\n  [\"text\",\" (\"],\n  [\"text\",\" )\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Erase all\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"demo\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Text:\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"centre\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"50\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"half\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"Finished\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"endfor\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# An old-style sendpraat block\"]\n],[\n   \"start\",\n  [\"keyword\",\"sendpraat\"],\n  [\"text\",\" \"],\n  [\"string\",\"Praat\"]\n],[\n   \"start\",\n  [\"text\",\"  ...\"],\n  [\"string.interpolated\",\"'newline$'\"],\n  [\"text\",\" Create \"],\n  [\"entity.name.type\",\"Sound\"],\n  [\"text\",\" as pure tone... \"],\n  [\"string\",\"\\\"tone\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"44100\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"440\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.01\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.01\"]\n],[\n   \"start\",\n  [\"text\",\"  ...\"],\n  [\"string.interpolated\",\"'newline$'\"],\n  [\"text\",\" Play\"]\n],[\n   \"start\",\n  [\"text\",\"  ...\"],\n  [\"string.interpolated\",\"'newline$'\"],\n  [\"text\",\" Remove\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# A new-style sendpraat block\"]\n],[\n   \"start\",\n  [\"support.function\",\"beginSendPraat\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Praat\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Create Sound as pure tone:\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"tone\\\"\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.4\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"44100\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"440\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.2\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.01\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.01\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"text\",\"duration \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"Get total duration\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"Remove\"]\n],[\n   \"start\",\n  [\"support.function\",\"endSendPraat\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"duration\\\"\"]\n],[\n   \"start\",\n  [\"support.function\",\"appendInfoLine\"],\n  [\"text\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"The generated sound lasted for \\\"\"],\n  [\"text\",\", duration, \"],\n  [\"string\",\"\\\"seconds\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"time \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"stopwatch\"]\n],[\n   \"start\",\n  [\"keyword\",\"clearinfo\"]\n],[\n   \"start\",\n  [\"keyword\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string\",\"This script took \"]\n],[\n   \"start\",\n  [\"keyword\",\"print\"],\n  [\"text\",\" \"],\n  [\"string\",\"'time' seconds to \"]\n],[\n   \"start\",\n  [\"keyword\",\"printline\"],\n  [\"text\",\" \"],\n  [\"string\",\"execute.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Old-style procedure declaration\"]\n],[\n   \"start\",\n  [\"keyword\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"oldStyle\"],\n  [\"text\",\" .str1$ .num .str2$\"]\n],[\n   \"start\",\n  [\"text\",\"  .local\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"keyword\",\"endproc\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# New-style procedure declaration\"]\n],[\n   \"start\",\n  [\"keyword\",\"procedure\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"newStyle\"],\n  [\"text\",\" (.str1$, .num, .str2$)\"]\n],[\n   \"start\",\n  [\"text\",\"  .local\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"keyword\",\"endproc\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_prisma.json",
    "content": "[[\n   \"source.prisma.embedded.source1\",\n  [\"storage.type.config.prisma\",\"generator\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.config.prisma\",\"photon\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   [\"text\",\"source.prisma.embedded.source1\"],\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"provider\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.terraform\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.start.prisma\",\"\\\"\"],\n  [\"string.quoted.double.prisma\",\"photonjs\"],\n  [\"string.quoted.double.end.prisma\",\"\\\"\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"text\",\"}\"]\n],[\n   \"source.prisma.embedded.source1\"\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"model User {\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  id                 String           @default(cuid()) @id\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  createdAt          DateTime         @default(now())\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  updatedAt          DateTime         @updatedAt\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  firstName          String\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  lastName           String\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  email              String           @unique\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  password           String\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  phone              String\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  responseRate       Float?\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  responseTime       Int?\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  ReportsTo  User?  @relation(\\\"EmployeeToEmployee_ReportsTo\\\")\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  employees         User[] @relation(\\\"EmployeeToEmployee_ReportsTo\\\")\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  isSuperHost        Boolean\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  ownedPlaces        Place[]\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  location           Location?\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  bookings           Booking[]\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  paymentAccount     PaymentAccount[]\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  sentMessages       Message[]        @relation(\\\"SentMessages\\\")\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  receivedMessages   Message[]        @relation(\\\"ReceivedMessages\\\")\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  notifications      Notification[]\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  profilePicture     Picture?\"]\n],[\n   \"source.prisma.embedded.source1\",\n  [\"source.prisma.embedded.source\",\"  hostingExperiences Experience[]\"]\n],[\n   \"start\",\n  [\"source.prisma.embedded.source\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Place\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"                \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"             \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"name\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"size\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"PLACE_SIZES\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"shortDescription\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"description\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"slug\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"maxGuests\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"numBedrooms\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"numBeds\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"numBaths\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"reviews\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Review\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"amenities\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Amenities\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"host\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"User\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"pricing\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Pricing\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"location\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Location\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"views\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"Views\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"guestRequirements\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"GuestRequirements\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"policies\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Policies\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"houseRules\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"HouseRules\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"bookings\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Booking\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"pictures\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Picture\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"popularity\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Pricing\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"    \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"monthlyDiscount\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"weeklyDiscount\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"perNight\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"smartPricing\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"basePrice\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"averageWeekly\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"averageMonthly\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"cleaningFee\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"securityDeposit\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"extraGuests\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"weekendPricing\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"Int\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"currency\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"CURRENCY\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"GuestRequirements\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"                            \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"  \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"govIssuedId\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"recommendationsFromOtherHosts\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"guestTripInformation\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"                         \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Policies\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"               \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"   \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"updatedAt\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@updatedAt\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"checkInStartTime\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"checkInEndTime\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"checkoutTime\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"            \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"HouseRules\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"                      \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"   \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"               \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"updatedAt\"],\n  [\"text\",\"               \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@updatedAt\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"suitableForChildren\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"suitableForInfants\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"petsAllowed\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"smokingAllowed\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"partiesAndEventsAllowed\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"additionalRules\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Views\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"lastWeek\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Location\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"            \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"         \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"lat\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"lng\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"neighbourHood\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Neighbourhood\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"user\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"User\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Place\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"address\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"directions\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"experience\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Experience\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"restaurant\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Restaurant\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Neighbourhood\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"     \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"locations\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Location\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"name\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"slug\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"homePreview\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Picture\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"city\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"City\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"featured\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"popularity\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"City\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"          \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"name\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"neighbourhoods\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Neighbourhood\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Picture\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"url\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Experience\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"              \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"category\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"ExperienceCategory\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"title\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"host\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"User\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"location\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Location\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"pricePerPerson\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"reviews\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"Review\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"preview\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"Picture\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"popularity\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"ExperienceCategory\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"      \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"mainColor\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"name\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"experience\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Experience\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Amenities\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"                        \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"  \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"                     \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"elevator\"],\n  [\"text\",\"                  \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"petsAllowed\"],\n  [\"text\",\"               \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"internet\"],\n  [\"text\",\"                  \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"kitchen\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"wirelessInternet\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"familyKidFriendly\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"freeParkingOnPremises\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"hotTub\"],\n  [\"text\",\"                    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"pool\"],\n  [\"text\",\"                      \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"smokingAllowed\"],\n  [\"text\",\"            \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"wheelchairAccessible\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"breakfast\"],\n  [\"text\",\"                 \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"cableTv\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"suitableForEvents\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"dryer\"],\n  [\"text\",\"                     \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"washer\"],\n  [\"text\",\"                    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"indoorFireplace\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"tv\"],\n  [\"text\",\"                        \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"heating\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"hangers\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"iron\"],\n  [\"text\",\"                      \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"hairDryer\"],\n  [\"text\",\"                 \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"doorman\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"paidParkingOffPremises\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"freeParkingOnStreet\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"gym\"],\n  [\"text\",\"                       \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"airConditioning\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"shampoo\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"essentials\"],\n  [\"text\",\"                \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"laptopFriendlyWorkspace\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"privateEntrance\"],\n  [\"text\",\"           \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"buzzerWirelessIntercom\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"babyBath\"],\n  [\"text\",\"                  \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"babyMonitor\"],\n  [\"text\",\"               \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"babysitterRecommendations\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"bathtub\"],\n  [\"text\",\"                   \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"changingTable\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"childrensBooksAndToys\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"childrensDinnerware\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"crib\"],\n  [\"text\",\"                      \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Review\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"            \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"      \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"    \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"text\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"stars\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"accuracy\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"location\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"checkIn\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"value\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"cleanliness\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"communication\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"experience\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Experience\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Booking\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"   \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"bookee\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"User\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"place\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"Place\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"startDate\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"endDate\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"payment\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Payment\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Payment\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"            \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"         \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"       \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"serviceFee\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"placePrice\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"totalPrice\"],\n  [\"text\",\"    \"],\n  [\"support.type.primitive.prisma\",\"Float\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"booking\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"Booking\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"paymentMethod\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"PaymentAccount\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"PaymentAccount\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"                 \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"               \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"type\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"PAYMENT_PROVIDER\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"user\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"User\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"payments\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"Payment\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"paypal\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"PaypalInformation\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"creditcard\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"CreditCardInformation\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"PaypalInformation\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"         \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"       \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"email\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"paymentAccount\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"PaymentAccount\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"CreditCardInformation\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"          \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"        \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"cardNumber\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"expiresOnMonth\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"expiresOnYear\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"securityCode\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"firstName\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"lastName\"],\n  [\"text\",\"       \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"postalCode\"],\n  [\"text\",\"     \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"country\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"paymentAccount\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"PaymentAccount\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Message\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"   \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"   \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"from\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"User\"],\n  [\"source.prisma.embedded.source\",\"     \"],\n  [\"entity.name.function.attribute.prisma\",\"@relation\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"string.quoted.double.start.prisma\",\"\\\"\"],\n  [\"string.quoted.double.prisma\",\"SentMessages\"],\n  [\"string.quoted.double.end.prisma\",\"\\\"\"],\n  [\"punctuation.definition.tag.prisma\",\")\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"to\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"User\"],\n  [\"source.prisma.embedded.source\",\"     \"],\n  [\"entity.name.function.attribute.prisma\",\"@relation\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"string.quoted.double.start.prisma\",\"\\\"\"],\n  [\"string.quoted.double.prisma\",\"ReceivedMessages\"],\n  [\"string.quoted.double.end.prisma\",\"\\\"\"],\n  [\"punctuation.definition.tag.prisma\",\")\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"deliveredAt\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"readAt\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Notification\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"             \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"           \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"type\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"NOTIFICATION_TYPE\"],\n  [\"keyword.operator.optional_type.prisma\",\"?\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"user\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"User\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"link\"],\n  [\"text\",\"      \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"readDate\"],\n  [\"text\",\"  \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source\",\n  [\"storage.type.model.prisma\",\"model\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.model.prisma\",\"Restaurant\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"id\"],\n  [\"text\",\"                \"],\n  [\"support.type.primitive.prisma\",\"String\"],\n  [\"source.prisma.embedded.source\",\"    \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"cuid\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.function.attribute.prisma\",\"@id\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"createdAt\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"DateTime\"],\n  [\"source.prisma.embedded.source\",\"  \"],\n  [\"entity.name.function.attribute.prisma\",\"@default\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"support.function.functional.prisma\",\"now\"],\n  [\"punctuation.definition.tag.prisma\",\"(\"],\n  [\"punctuation.definition.tag.prisma\",\"))\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"title\"],\n  [\"text\",\"             \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"avgPricePerPerson\"],\n  [\"text\",\" \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"pictures\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Picture\"],\n  [\"keyword.operator.list_type.prisma\",\"[]\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"location\"],\n  [\"text\",\"          \"],\n  [\"support.type.primitive.prisma\",\"Location\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"isCurated\"],\n  [\"text\",\"         \"],\n  [\"support.type.primitive.prisma\",\"Boolean\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"slug\"],\n  [\"text\",\"              \"],\n  [\"support.type.primitive.prisma\",\"String\"]\n],[\n   \"source.prisma.embedded.source\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"popularity\"],\n  [\"text\",\"        \"],\n  [\"support.type.primitive.prisma\",\"Int\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source2\",\n  [\"storage.type.enum.prisma\",\"enum\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.enum.prisma\",\"CURRENCY\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"CAD\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"CHF\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"EUR\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"JPY\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"USD\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ZAR\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source2\",\n  [\"storage.type.enum.prisma\",\"enum\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.enum.prisma\",\"PLACE_SIZES\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_HOUSE\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_APARTMENT\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_EARTH_HOUSE\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_CABIN\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_VILLA\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_PLACE\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"ENTIRE_BOAT\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"PRIVATE_ROOM\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source2\",\n  [\"storage.type.enum.prisma\",\"enum\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.enum.prisma\",\"PAYMENT_PROVIDER\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"PAYPAL\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"CREDIT_CARD\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n],[\n   \"start\"\n],[\n   \"source.prisma.embedded.source2\",\n  [\"storage.type.enum.prisma\",\"enum\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"entity.name.type.enum.prisma\",\"NOTIFICATION_TYPE\"],\n  [\"source.prisma.embedded.source\",\" \"],\n  [\"punctuation.definition.tag.prisma\",\"{\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"OFFER\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"INSTANT_BOOK\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"RESPONSIVENESS\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"NEW_AMENITIES\"]\n],[\n   \"source.prisma.embedded.source2\",\n  [\"text\",\"  \"],\n  [\"variable.other.assignment.prisma\",\"HOUSE_RULES\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.prisma\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_prolog.json",
    "content": "[[\n   \"start\",\n  [\"entity.name.function.fact.prolog\",\"partition\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"variable.language.anonymous.prolog\",\"_\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"punctuation.end.fact.prolog\",\".\"]\n],[\n   [\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"entity.name.function.rule.prolog\",\"partition\"],\n  [\"punctuation.rule.parameters.begin.prolog\",\"(\"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"variable.other.prolog\",\"X\"],\n  [\"punctuation.concat.list.prolog\",\"|\"],\n  [\"variable.other.prolog\",\"Xs\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.rule.parameters.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"Pivot\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.rule.parameters.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"Smalls\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.rule.parameters.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"Bigs\"],\n  [\"punctuation.rule.parameters.end.prolog\",\")\"],\n  [\"meta.rule.signature.prolog\",\" \"],\n  [\"keyword.operator.definition.prolog\",\":-\"]\n],[\n   [\"meta.expression.prolog\",\"keyword.operator.definition.prolog\",\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.rule.definition.prolog\",\"    \"],\n  [\"meta.expression.prolog\",\"(   \"],\n  [\"variable.other.prolog\",\"X\"],\n  [\"meta.expression.prolog\",\" @\"],\n  [\"keyword.operator.prolog\",\"<\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Pivot\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"keyword.operator.prolog\",\"->\"]\n],[\n   [\"meta.expression.prolog\",\"keyword.operator.definition.prolog\",\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.expression.prolog\",\"        \"],\n  [\"variable.other.prolog\",\"Smalls\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"keyword.operator.prolog\",\"=\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"variable.other.prolog\",\"X\"],\n  [\"punctuation.concat.list.prolog\",\"|\"],\n  [\"variable.other.prolog\",\"Rest\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.control.and.prolog\",\",\"]\n],[\n   [\"meta.expression.prolog\",\"keyword.operator.definition.prolog\",\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.expression.prolog\",\"        \"],\n  [\"constant.other.atom.prolog\",\"partition\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"variable.other.prolog\",\"Xs\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Pivot\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Rest\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Bigs\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"]\n],[\n   [\"meta.expression.prolog\",\"keyword.operator.definition.prolog\",\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.expression.prolog\",\"    \"],\n  [\"punctuation.control.or.prolog\",\";\"],\n  [\"meta.expression.prolog\",\"   \"],\n  [\"variable.other.prolog\",\"Bigs\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"keyword.operator.prolog\",\"=\"],\n  [\"meta.expression.prolog\",\" \"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"variable.other.prolog\",\"X\"],\n  [\"punctuation.concat.list.prolog\",\"|\"],\n  [\"variable.other.prolog\",\"Rest\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.control.and.prolog\",\",\"]\n],[\n   [\"meta.expression.prolog\",\"keyword.operator.definition.prolog\",\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.expression.prolog\",\"        \"],\n  [\"constant.other.atom.prolog\",\"partition\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"variable.other.prolog\",\"Xs\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Pivot\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Smalls\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Rest\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"]\n],[\n   \"start\",\n  [\"meta.expression.prolog\",\"    )\"],\n  [\"punctuation.rule.end.prolog\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"entity.name.function.fact.prolog\",\"quicksort\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"text\",\"     --> [].\"]\n],[\n   \"start\",\n  [\"entity.name.function.fact.prolog\",\"quicksort\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"punctuation.begin.list.prolog\",\"[\"],\n  [\"variable.other.prolog\",\"X\"],\n  [\"punctuation.concat.list.prolog\",\"|\"],\n  [\"variable.other.prolog\",\"Xs\"],\n  [\"punctuation.end.list.prolog\",\"]\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"text\",\" -->\"]\n],[\n   \"start\",\n  [\"text\",\"    { \"],\n  [\"entity.name.function.fact.prolog\",\"partition\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"variable.parameter.prolog\",\"Xs\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"X\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"Smaller\"],\n  [\"punctuation.separator.parameters.prolog\",\",\"],\n  [\"meta.fact.prolog\",\" \"],\n  [\"variable.parameter.prolog\",\"Bigger\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"text\",\" },\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.function.fact.prolog\",\"quicksort\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"variable.parameter.prolog\",\"Smaller\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"text\",\", [X], \"],\n  [\"entity.name.function.fact.prolog\",\"quicksort\"],\n  [\"punctuation.begin.fact.parameters.prolog\",\"(\"],\n  [\"variable.parameter.prolog\",\"Bigger\"],\n  [\"punctuation.end.fact.parameters.prolog\",\")\"],\n  [\"punctuation.end.fact.prolog\",\".\"]\n],[\n   \"start\"\n],[\n   [\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"entity.name.function.rule.prolog\",\"perfect\"],\n  [\"punctuation.rule.parameters.begin.prolog\",\"(\"],\n  [\"variable.parameter.prolog\",\"N\"],\n  [\"punctuation.rule.parameters.end.prolog\",\")\"],\n  [\"meta.rule.signature.prolog\",\" \"],\n  [\"keyword.operator.definition.prolog\",\":-\"]\n],[\n   [\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.rule.definition.prolog\",\"    \"],\n  [\"constant.other.atom.prolog\",\"between\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"constant.numeric.prolog\",\"1\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"constant.other.atom.prolog\",\"inf\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"N\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"],\n  [\"punctuation.control.and.prolog\",\",\"],\n  [\"meta.rule.definition.prolog\",\" \"],\n  [\"variable.other.prolog\",\"U\"],\n  [\"meta.rule.definition.prolog\",\" \"],\n  [\"keyword.operator.prolog\",\"is\"],\n  [\"meta.rule.definition.prolog\",\" \"],\n  [\"variable.other.prolog\",\"N\"],\n  [\"meta.rule.definition.prolog\",\" // \"],\n  [\"constant.numeric.prolog\",\"2\"],\n  [\"punctuation.control.and.prolog\",\",\"]\n],[\n   [\"keyword.operator.definition.prolog\",\"meta.rule.prolog\"],\n  [\"meta.rule.definition.prolog\",\"    \"],\n  [\"constant.other.atom.prolog\",\"findall\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"variable.other.prolog\",\"D\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" (\"],\n  [\"constant.other.atom.prolog\",\"between\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"constant.numeric.prolog\",\"1\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"variable.other.prolog\",\"U\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"variable.other.prolog\",\"D\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"N\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"constant.other.atom.prolog\",\"mod\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"D\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"keyword.operator.prolog\",\"=:=\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"constant.numeric.prolog\",\"0\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"],\n  [\"punctuation.control.and.prolog\",\",\"],\n  [\"meta.rule.definition.prolog\",\" \"],\n  [\"variable.other.prolog\",\"Ds\"],\n  [\"meta.rule.definition.prolog\",\")\"],\n  [\"punctuation.control.and.prolog\",\",\"]\n],[\n   \"start\",\n  [\"meta.rule.definition.prolog\",\"    \"],\n  [\"constant.other.atom.prolog\",\"sumlist\"],\n  [\"punctuation.begin.statement.parameters.prolog\",\"(\"],\n  [\"variable.other.prolog\",\"Ds\"],\n  [\"punctuation.separator.statement.prolog\",\",\"],\n  [\"meta.statement.parameters.prolog\",\" \"],\n  [\"variable.other.prolog\",\"N\"],\n  [\"punctuation.end.statement.parameters.prolog\",\")\"],\n  [\"punctuation.rule.end.prolog\",\".\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_properties.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# You are reading the \\\".properties\\\" entry.\"]\n],[\n   \"start\",\n  [\"comment\",\"! The exclamation mark can also mark text as comments.\"]\n],[\n   \"start\",\n  [\"comment\",\"# The key and element characters #, !, =, and : are written with a preceding backslash to ensure that they are properly loaded.\"]\n],[\n   \"start\",\n  [\"variable\",\"website \"],\n  [\"keyword\",\"=\"],\n  [\"string\",\" http\"],\n  [\"constant.language.escape\",\"\\\\\"],\n  [\"string\",\"://en.wikipedia.org/\"]\n],[\n   \"start\",\n  [\"variable\",\"language \"],\n  [\"keyword\",\"=\"],\n  [\"string\",\" English\"]\n],[\n   \"start\",\n  [\"comment\",\"# The backslash below tells the application to continue reading\"]\n],[\n   \"start\",\n  [\"comment\",\"# the value onto the next line.\"]\n],[\n   \"value\",\n  [\"variable\",\"message \"],\n  [\"keyword\",\"=\"],\n  [\"string\",\" Welcome to \\\\\"]\n],[\n   \"start\",\n  [\"string\",\"          Wikipedia!\"]\n],[\n   \"start\",\n  [\"comment\",\"# Add spaces to the key\"]\n],[\n   \"start\",\n  [\"variable\",\"key\"],\n  [\"constant.language.escape\",\"\\\\\"],\n  [\"variable\",\" with\"],\n  [\"constant.language.escape\",\"\\\\\"],\n  [\"variable\",\" spaces \"],\n  [\"keyword\",\"=\"],\n  [\"string\",\" This is the value that could be looked up with the key \\\"key with spaces\\\".\"]\n],[\n   \"start\",\n  [\"comment\",\"# Unicode\"]\n],[\n   \"start\",\n  [\"variable\",\"tab \"],\n  [\"keyword\",\":\"],\n  [\"string\",\" \"],\n  [\"constant.language.escape\",\"\\\\u0009\"]\n],[\n   \"start\",\n  [\"variable\",\"empty-key\"],\n  [\"keyword\",\"=\"]\n],[\n   \"start\",\n  [\"variable\",\"last.line\"],\n  [\"keyword\",\"=\"],\n  [\"string\",\"value\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_protobuf.json",
    "content": "[[\n   \"start\",\n  [\"keyword.declaration.protobuf\",\"message\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"required\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"int32\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"required\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"int32\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"optional\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"label\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.declaration.protobuf\",\"message\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Line\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"required\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"required\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"optional\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"label\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.declaration.protobuf\",\"message\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Polyline\"],\n  [\"text\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"repeated\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Point\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"point\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.declaration.protobuf\",\"optional\"],\n  [\"text\",\" \"],\n  [\"support.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"label\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment.protobuf\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_puppet.json",
    "content": "[[\n   \"start\",\n  [\"storage.function.puppet\",\"define\"],\n  [\"name.function.puppet\",\" apache::vhost \"],\n  [\"punctuation.lpar\",\"(\"],\n  [\"variable.puppet\",\"$port\"],\n  [\"keyword.operator\",\",\"],\n  [\"string\",\" \"],\n  [\"variable.puppet\",\"$docroot\"],\n  [\"keyword.operator\",\",\"],\n  [\"string\",\" \"],\n  [\"variable.puppet\",\"$servername\"],\n  [\"string\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\" \"],\n  [\"variable.puppet\",\"$title\"],\n  [\"keyword.operator\",\",\"],\n  [\"string\",\" \"],\n  [\"variable.puppet\",\"$vhost_name\"],\n  [\"string\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"string\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"*\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"punctuation.rpar.puppet\",\")\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.puppet\",\"include\"],\n  [\"text\",\" apache\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.puppet\",\"include\"],\n  [\"text\",\" apache\"],\n  [\"keyword.operator\",\"::\"],\n  [\"text\",\"params\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.puppet\",\"$vhost_dir\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"qualified.variable.puppet\",\"$apache::params::vhost_dir\"]\n],[\n   \"start\",\n  [\"keyword.name.resource.puppet\",\"  file\"],\n  [\"paren.lparen\",\" {\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"\\\"\"],\n  [\"variable.puppet\",\"${vhost_dir\"],\n  [\"string\",\"}/\"],\n  [\"variable.puppet\",\"${servername\"],\n  [\"string\",\"}.conf\"],\n  [\"punctuation.quote.puppet\",\"\\\"\"],\n  [\"text\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"content\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"support.function.puppet\",\"template\"],\n  [\"paren.lparen\",\"(\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"apache/vhost-default.conf.erb\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"owner\"],\n  [\"keyword.operator\",\"   =>\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"www\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"group\"],\n  [\"keyword.operator\",\"   =>\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"www\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"mode\"],\n  [\"keyword.operator\",\"    =>\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"644\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"require\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"Package\"],\n  [\"paren.lparen\",\"[\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"httpd\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"language.support.class\",\"notify\"],\n  [\"keyword.operator\",\"  =>\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"Service\"],\n  [\"paren.lparen\",\"[\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"httpd\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.puppet\",\"type\"],\n  [\"text\",\" MyModule\"],\n  [\"keyword.operator\",\"::\"],\n  [\"text\",\"Tree \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"Array\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.types.puppet\",\"Variant\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.types.puppet\",\"Data\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" Tree\"],\n  [\"paren.rparen\",\"]]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.puppet\",\"function\"],\n  [\"text\",\" apache\"],\n  [\"keyword.operator\",\"::\"],\n  [\"text\",\"bool2http\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.types.puppet\",\"Variant\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.types.puppet\",\"String\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"Boolean\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.puppet\",\"$arg\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">>\"],\n  [\"keyword.name.resource.puppet\",\" String\"],\n  [\"paren.lparen\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.puppet\",\"case \"],\n  [\"variable.puppet\",\"$arg\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.language.puppet\",\"false\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language.puppet\",\"undef\"],\n  [\"keyword.operator\",\",\"],\n  [\"regexp.begin.string.puppet\",\" /(?i:false)/\"],\n  [\"text\",\" :\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"Off\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.language.puppet\",\"true\"],\n  [\"keyword.operator\",\",\"],\n  [\"regexp.begin.string.puppet\",\" /(?i:true)/\"],\n  [\"text\",\"          :\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"On\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.puppet\",\"default\"],\n  [\"text\",\"               :\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"\\\"\"],\n  [\"variable.puppet\",\"$arg\"],\n  [\"punctuation.quote.puppet\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"singleline.comment.puppet\",\"# A class with parameters\"]\n],[\n   \"start\",\n  [\"keyword.type.puppet\",\"class\"],\n  [\"constant.class.puppet\",\" apache \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.types.puppet\",\"String\"],\n  [\"text\",\" \"],\n  [\"variable.puppet\",\"$version\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"latest\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"keyword.name.resource.puppet\",\"  package\"],\n  [\"paren.lparen\",\" {\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"httpd\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"ensure\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"variable.puppet\",\"$version\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"singleline.comment.puppet\",\"# Using the class parameter from above\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"before\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"File\"],\n  [\"paren.lparen\",\"[\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"/etc/httpd.conf\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.name.resource.puppet\",\"  file\"],\n  [\"paren.lparen\",\" {\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"/etc/httpd.conf\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"ensure\"],\n  [\"keyword.operator\",\"  =>\"],\n  [\"text\",\" \"],\n  [\"support.function.puppet\",\"file\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"owner\"],\n  [\"keyword.operator\",\"   =>\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"httpd\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"content\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"support.function.puppet\",\"template\"],\n  [\"paren.lparen\",\"(\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"apache/httpd.conf.erb\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"singleline.comment.puppet\",\"# Template from a module\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.name.resource.puppet\",\"  service\"],\n  [\"paren.lparen\",\" {\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"httpd\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"ensure\"],\n  [\"keyword.operator\",\"    =>\"],\n  [\"text\",\" \"],\n  [\"constant.language.puppet\",\"running\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"enable\"],\n  [\"keyword.operator\",\"    =>\"],\n  [\"text\",\" \"],\n  [\"constant.language.puppet\",\"true\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"language.support.class\",\"subscribe\"],\n  [\"keyword.operator\",\" =>\"],\n  [\"text\",\" \"],\n  [\"constant.types.puppet\",\"File\"],\n  [\"paren.lparen\",\"[\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"/etc/httpd.conf\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.puppet\",\"if \"],\n  [\"variable.puppet\",\"$is_virtual\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function.puppet\",\"warning\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"Tried to include class ntp on virtual machine; this node might be misclassified.\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword.control.puppet\",\"elsif \"],\n  [\"variable.puppet\",\"$operatingsystem\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"Darwin\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"keyword.name.resource.puppet\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.function.puppet\",\"warning\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"string\",\"This NTP module does not yet work on our Mac laptops.\"],\n  [\"punctuation.quote.puppet\",\"'\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"keyword.name.resource.puppet\",\"else\"],\n  [\"paren.lparen\",\" {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.puppet\",\"include\"],\n  [\"text\",\" ntp\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_python.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#!/usr/local/bin/python\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"string\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sys\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# If no arguments were given, print a helpful message\"]\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"len\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"sys\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"argv\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"==\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\":\"]\n],[\n   \"qstring3\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"print\"],\n  [\"text\",\" \"],\n  [\"string\",\"'''Usage:\"]\n],[\n   \"start\",\n  [\"string\",\"celsius temp1 temp2 ...'''\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"sys\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"exit\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"identifier\",\"a\"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"x\\\"\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\",\n  [\"comment\",\"# Loop over the arguments\"]\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sys\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"argv\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\":\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"try\"],\n  [\"punctuation\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"fahrenheit\"],\n  [\"keyword.operator\",\"=\"],\n  [\"support.function\",\"float\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"string\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"atoi\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"except\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"string\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"atoi_error\"],\n  [\"punctuation\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"print\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"repr\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"not a numeric value\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"else\"],\n  [\"punctuation\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"celsius\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"fahrenheit\"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"32\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"5.0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric\",\"9.0\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"print\"],\n  [\"text\",\" \"],\n  [\"string\",\"'%i\"],\n  [\"constant.language.escape\",\"\\\\260\"],\n  [\"string\",\"F = %i\"],\n  [\"constant.language.escape\",\"\\\\260\"],\n  [\"string\",\"C'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"fahrenheit\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"int\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"celsius\"],\n  [\"keyword.operator\",\"+\"],\n  [\"constant.numeric\",\".5\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Fred\\\"\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"He said his name is \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"name\"],\n  [\"function.support\",\"!r\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\".\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"f\\\"He said his name is \"],\n  [\"paren.lparen\",\"{\"],\n  [\"support.function\",\"repr\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"text\",\"+\"],\n  [\"constant.numeric\",\"12\"],\n  [\"paren.rparen\",\")}\"],\n  [\"string\",\".\\\"\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"# repr() is equivalent to !r\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"width\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"]\n],[\n   \"start\",\n  [\"identifier\",\"precision\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"]\n],[\n   \"start\",\n  [\"identifier\",\"value\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"decimal\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"Decimal\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"12.34567\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"result: \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"value\"],\n  [\"text\",\":\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"width\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\".\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"precision\"],\n  [\"paren.rparen\",\"}}\"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"# nested fields\"]\n],[\n   \"start\",\n  [\"string\",\"'result:      12.35'\"]\n],[\n   \"start\",\n  [\"identifier\",\"today\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"datetime\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"year\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"2017\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"month\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"day\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"27\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"today\"],\n  [\"text\",\":%\"],\n  [\"identifier\",\"B\"],\n  [\"string\",\" \"],\n  [\"text\",\"%\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\",\"],\n  [\"string\",\" \"],\n  [\"text\",\"%\"],\n  [\"identifier\",\"Y\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"# using date format specifier\"]\n],[\n   \"start\",\n  [\"string\",\"'January 27, 2017'\"]\n],[\n   \"start\",\n  [\"identifier\",\"number\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1024\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"number\"],\n  [\"text\",\":#0\"],\n  [\"identifier\",\"x\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"# using integer format specifier\"]\n],[\n   \"start\",\n  [\"string\",\"'0x400'\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"F\\\"Hello, \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\". You are \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"age\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\".\\\"\"]\n],[\n   \"start\",\n  [\"string\",\"'Hello, Eric. You are 74.'\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"constant.numeric\",\"2\"],\n  [\"string\",\" \"],\n  [\"text\",\"*\"],\n  [\"string\",\" \"],\n  [\"constant.numeric\",\"37\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\",\n  [\"string\",\"'74'\"]\n],[\n   \"start\",\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"to_lowercase\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"input\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"input\"],\n  [\"punctuation\",\".\"],\n  [\"function.support\",\"lower\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Eric Idle\\\"\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"to_lowercase\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\")}\"],\n  [\"string\",\" is funny.\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"'Eric Idle'\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"f'\"],\n  [\"paren.lparen\",\"{\"],\n  [\"string\",\"\\\"Eric Idle\\\"\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"'\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"f\\\"\\\"\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"Eric\"],\n  [\"string\",\" \"],\n  [\"identifier\",\"Idle\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\\\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\"f'''\"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"Eric\"],\n  [\"string\",\" \"],\n  [\"identifier\",\"Idle\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"'''\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"The \"],\n  [\"constant.language.escape\",\"\\\\\\\"\"],\n  [\"string\",\"comedian\"],\n  [\"constant.language.escape\",\"\\\\\\\"\"],\n  [\"string\",\" is \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\", aged \"],\n  [\"paren.lparen\",\"{\"],\n  [\"identifier\",\"age\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\".\\\"\"]\n],[\n   \"start\",\n  [\"string\",\"f\\\"\"],\n  [\"paren.lparen\",\"{{\"],\n  [\"constant.numeric\",\"74\"],\n  [\"paren.rparen\",\"}}\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_qml.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// A simple example\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"QtQuick\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2.7\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"QtQuick\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Controls\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2.3\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"Rectangle\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"color\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"red\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"anchors\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"fill\"],\n  [\"text\",\": \"],\n  [\"keyword\",\"parent\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"Text\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"text\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"WEEEEEEEEEE\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"font\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"pixelSize\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"50\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"color\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"white\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"anchors\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"centerIn\"],\n  [\"text\",\": \"],\n  [\"keyword\",\"parent\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"RotationAnimator\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"on\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"rotation\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"running\"],\n  [\"text\",\": \"],\n  [\"constant.language.boolean\",\"true\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"loops\"],\n  [\"text\",\": \"],\n  [\"keyword\",\"Animation\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Infinite\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"from\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"to\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"360\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"duration\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"1500\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_r.json",
    "content": "[[\n   \"start\",\n  [\"identifier\",\"Call\"],\n  [\"keyword.operator\",\":\"]\n],[\n   \"start\",\n  [\"identifier\",\"lm\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"formula\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"~\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"identifier\",\"Residuals\"],\n  [\"keyword.operator\",\":\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"       \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\"       \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\"       \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\"       \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\"       \"],\n  [\"constant.numeric\",\"6\"]\n],[\n   \"start\",\n  [\"constant.numeric\",\"3.3333\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"0.6667\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"2.6667\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"2.6667\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"0.6667\"],\n  [\"text\",\"  \"],\n  [\"constant.numeric\",\"3.3333\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"identifier\",\"Coefficients\"],\n  [\"keyword.operator\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"Estimate\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Std\"],\n  [\"text\",\". \"],\n  [\"identifier\",\"Error\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"t\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"value\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pr\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"keyword.operator\",\">|\"],\n  [\"identifier\",\"t\"],\n  [\"keyword.operator\",\"|\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"Intercept\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\"  \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"9.3333\"],\n  [\"text\",\"     \"],\n  [\"constant.numeric\",\"2.8441\"],\n  [\"text\",\"  \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"3.282\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.030453\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"]\n],[\n   \"start\",\n  [\"identifier\",\"x\"],\n  [\"text\",\"             \"],\n  [\"constant.numeric\",\"7.0000\"],\n  [\"text\",\"     \"],\n  [\"constant.numeric\",\"0.7303\"],\n  [\"text\",\"   \"],\n  [\"constant.numeric\",\"9.585\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.000662\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"***\"]\n],[\n   \"start\",\n  [\"keyword.operator\",\"---\"]\n],[\n   \"start\",\n  [\"identifier\",\"Signif\"],\n  [\"text\",\". \"],\n  [\"identifier\",\"codes\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\"  \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" ‘\"],\n  [\"keyword.operator\",\"***\"],\n  [\"text\",\"’ \"],\n  [\"constant.numeric\",\"0.001\"],\n  [\"text\",\" ‘\"],\n  [\"keyword.operator\",\"**\"],\n  [\"text\",\"’ \"],\n  [\"constant.numeric\",\"0.01\"],\n  [\"text\",\" ‘\"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\"’ \"],\n  [\"constant.numeric\",\"0.05\"],\n  [\"text\",\" ‘.’ \"],\n  [\"constant.numeric\",\"0.1\"],\n  [\"text\",\" ‘ ’ \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"identifier\",\"Residual\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"standard\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"error\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3.055\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"on\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"degrees\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"of\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"freedom\"]\n],[\n   \"start\",\n  [\"identifier\",\"Multiple\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"R\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"squared\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.9583\"],\n  [\"text\",\",     \"],\n  [\"identifier\",\"Adjusted\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"R\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"squared\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.9478\"]\n],[\n   \"start\",\n  [\"constant.language.boolean\",\"F\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"statistic\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"91.88\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"on\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"and\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DF\"],\n  [\"text\",\",  \"],\n  [\"identifier\",\"p\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"value\"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.000662\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"par\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"mfrow\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"c\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.keyword.operator\",\"))\"],\n  [\"text\",\"     \"],\n  [\"comment\",\"# Request 2x2 plot layout\"]\n],[\n   \"start\",\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"plot\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"lm_1\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\"             \"],\n  [\"comment\",\"# Diagnostic plot of regression model\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_raku.json",
    "content": "[[\n   \"block_comment\",\n  [\"comment.doc\",\"=begin comment\"]\n],[\n   \"block_comment\",\n  [\"comment.doc\",\"Raku example for ace\"]\n],[\n   \"start\",\n  [\"comment.doc\",\"=end comment\"]\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Cook\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Employee\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"has\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"@.utensils\"],\n  [\"text\",\"  \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"rw\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"has\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"@.cookbooks\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"rw\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cook\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$food\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"Cooking \"],\n  [\"variable.language\",\"$food\"],\n  [\"string.quoted.double\",\"\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clean_utensils\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"Cleaning \"],\n  [\"variable.language\",\"$_\"],\n  [\"string.quoted.double\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"@.utensils\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Baker\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Cook\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"cook\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$confection\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"Baking a tasty \"],\n  [\"variable.language\",\"$confection\"],\n  [\"string.quoted.double\",\"\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$cook\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Cook\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"new\"],\n  [\"lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"utensils\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single\",\"<spoon ladle knife pan>\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"cookbooks\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single\",\"'The Joy of Cooking'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"40000\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\"$cook\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"cook\"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single\",\"'pizza'\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"],\n  [\"text\",\";       \"],\n  [\"comment\",\"# OUTPUT: «Cooking pizza␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$cook\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"utensils\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"perl\"],\n  [\"text\",\";     \"],\n  [\"comment\",\"# OUTPUT: «[\\\"spoon\\\", \\\"ladle\\\", \\\"knife\\\", \\\"pan\\\"]␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$cook\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"cookbooks\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"perl\"],\n  [\"text\",\";    \"],\n  [\"comment\",\"# OUTPUT: «[\\\"The Joy of Cooking\\\"]␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$cook\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\";            \"],\n  [\"comment\",\"# OUTPUT: «40000␤»\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"my\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$baker\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Baker\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"new\"],\n  [\"lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"utensils\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.quoted.single\",\"'self cleaning oven'\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"cookbooks\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double\",\"\\\"The Baker's Apprentice\\\"\"],\n  [\"keyword.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"50000\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\"$baker\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"cook\"],\n  [\"lparen\",\"(\"],\n  [\"string.quoted.single\",\"'brioche'\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";      \"],\n  [\"comment\",\"# OUTPUT: «Baking a tasty brioche␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$baker\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"utensils\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"perl\"],\n  [\"text\",\";    \"],\n  [\"comment\",\"# OUTPUT: «[\\\"self cleaning oven\\\"]␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$baker\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"cookbooks\"],\n  [\"keyword.operator\",\".\"],\n  [\"support.function\",\"perl\"],\n  [\"text\",\";   \"],\n  [\"comment\",\"# OUTPUT: «[\\\"The Baker's Apprentice\\\"]␤»\"]\n],[\n   \"start\",\n  [\"support.function\",\"say\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$baker\"],\n  [\"keyword.operator\",\".\"],\n  [\"identifier\",\"salary\"],\n  [\"text\",\";           \"],\n  [\"comment\",\"# OUTPUT: «50000␤» \"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_razor.json",
    "content": "[[\n   [\"razor-block-start\",\"@{\"],\n  [\"punctuation.block.razor\",\"@{\"]\n],[\n   [\"razor-block-start\",\"@{\"],\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"Layout\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"~/layout\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"punctuation.block.razor\",\"}\"]\n],[\n   [\"razor-block-start\",\"@code{\"],\n  [\"punctuation.block.razor\",\"@code{\"]\n],[\n   [\"razor-block-start\",\"@code{\"],\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"private\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"punctuation.block.razor\",\"}\"]\n],[\n   [\"razor-block-start\",\"@code {\"],\n  [\"punctuation.block.razor\",\"@code {\"]\n],[\n   [\"razor-block-start\",\"@code {\"],\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"private\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"string\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Test\"],\n  [\"string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"punctuation.block.razor\",\"}\"]\n],[\n   [\"razor-block-start\",\"@functions{\"],\n  [\"punctuation.block.razor\",\"@functions{\"]\n],[\n   [\"razor-block-start\",\"@functions{\"],\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"void\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DoSomething\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.block.razor\",\"}\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@model\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MyApp.Models.User\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@inject\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IUserService UserService\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@inherits\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CustomBasePage\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@implements\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IDisposable\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@attribute\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"[Authorize]\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@layout\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MainLayout\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@namespace\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"MyApp.Pages\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@rendermode\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"InteractiveServer\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@using\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"System.Collections.Generic\"]\n],[\n   \"start\",\n  [\"meta.directive.razor\",\"@page\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"/counter\\\"\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_rdoc.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"\\\\name\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"picker\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"\\\\alias\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"picker\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"\\\\title\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"text\",\"Create a picker control\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"\\\\description\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  Create a picker control to enable manipulation of plot variables based on a set of fixed choices.\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"nospell\",\n  [\"keyword\",\"\\\\usage\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"picker\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"...,\"],\n  [\"nospell.text\",\" initial \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" NULL\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" label \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" NULL\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"\\\\arguments\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"\\\\item\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\dots\"],\n  [\"paren.keyword.operator\",\"}{\"]\n],[\n   \"start\",\n  [\"text\",\"    Arguments containing objects to be presented as choices for the picker \"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"or a list containing the choices\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\". If an element is named then the name is used to display it within the picker. If an element is not named then it is displayed within the picker using \"],\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"as\"],\n  [\"text\",\".\"],\n  [\"nospell.text\",\"character\"],\n  [\"paren.keyword.operator\",\"}}\"],\n  [\"text\",\". \"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"\\\\item\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"initial\"],\n  [\"paren.keyword.operator\",\"}{\"]\n],[\n   \"start\",\n  [\"text\",\"    Initial value for picker. Value must be present in the list of choices specified. If not specified defaults to the first choice.\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"\\\\item\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"label\"],\n  [\"paren.keyword.operator\",\"}{\"]\n],[\n   \"start\",\n  [\"text\",\"    Display label for picker. Defaults to the variable name if not specified.\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"\\\\value\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  An object of class \\\"manipulator.picker\\\" which can be passed to the \"],\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"}}\"],\n  [\"text\",\" function.\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"\\\\seealso\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"start\",\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"}}\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"slider\"],\n  [\"paren.keyword.operator\",\"}}\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"checkbox\"],\n  [\"paren.keyword.operator\",\"}}\"],\n  [\"text\",\", \"],\n  [\"keyword\",\"\\\\code\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\link\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"button\"],\n  [\"paren.keyword.operator\",\"}}\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"nospell\",\n  [\"keyword\",\"\\\\examples\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"nospell\",\n  [\"keyword\",\"\\\\dontrun\"],\n  [\"paren.keyword.operator\",\"{\"]\n],[\n   \"nospell\"\n],[\n   \"nospell\",\n  [\"text\",\"##\"],\n  [\"nospell.text\",\" Filtering data with a picker\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"(\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  barplot\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"as\"],\n  [\"text\",\".\"],\n  [\"nospell.text\",\"matrix\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"longley\"],\n  [\"paren.keyword.operator\",\"[\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\"factor\"],\n  [\"paren.keyword.operator\",\"])\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" \"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"          beside \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" TRUE\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" main \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" factor\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  factor \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" picker\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"GNP\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"Unemployed\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"Employed\"],\n  [\"text\",\"\\\"\"],\n  [\"paren.keyword.operator\",\"))\"]\n],[\n   \"nospell\"\n],[\n   \"nospell\",\n  [\"text\",\"##\"],\n  [\"nospell.text\",\" Create a picker with labels\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"(\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  plot\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"pressure\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" type \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" type\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" \"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  type \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" picker\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"points\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"p\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"line\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"l\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"step\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"s\"],\n  [\"text\",\"\\\"\"],\n  [\"paren.keyword.operator\",\"))\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  \"]\n],[\n   \"nospell\",\n  [\"text\",\"##\"],\n  [\"nospell.text\",\" Picker with groups\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"(\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  barplot\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"as\"],\n  [\"text\",\".\"],\n  [\"nospell.text\",\"matrix\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"mtcars\"],\n  [\"paren.keyword.operator\",\"[\"],\n  [\"nospell.text\",\"group\"],\n  [\"text\",\",\\\"\"],\n  [\"nospell.text\",\"mpg\"],\n  [\"text\",\"\\\"\"],\n  [\"paren.keyword.operator\",\"])\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" beside\"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\"TRUE\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  group \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" picker\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"Group 1\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" 1\"],\n  [\"text\",\":\"],\n  [\"nospell.text\",\"11\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" \"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"                 \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"Group 2\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" 12\"],\n  [\"text\",\":\"],\n  [\"nospell.text\",\"22\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" \"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"                 \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"Group 3\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" 23\"],\n  [\"text\",\":\"],\n  [\"nospell.text\",\"32\"],\n  [\"paren.keyword.operator\",\"))\"]\n],[\n   \"nospell\"\n],[\n   \"nospell\",\n  [\"text\",\"##\"],\n  [\"nospell.text\",\" Histogram w\"],\n  [\"text\",\"/\"],\n  [\"nospell.text\",\" picker to select type\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"require\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"lattice\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"require\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"nospell.text\",\"stats\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"manipulate\"],\n  [\"paren.keyword.operator\",\"(\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  histogram\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"~\"],\n  [\"nospell.text\",\" height \"],\n  [\"text\",\"|\"],\n  [\"nospell.text\",\" voice\"],\n  [\"text\",\".\"],\n  [\"nospell.text\",\"part\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" \"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"            data \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" singer\"],\n  [\"text\",\",\"],\n  [\"nospell.text\",\" type \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" type\"],\n  [\"paren.keyword.operator\",\")\"],\n  [\"text\",\",\"]\n],[\n   \"nospell\",\n  [\"nospell.text\",\"  type \"],\n  [\"text\",\"=\"],\n  [\"nospell.text\",\" picker\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"percent\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"count\"],\n  [\"text\",\"\\\",\"],\n  [\"nospell.text\",\" \"],\n  [\"text\",\"\\\"\"],\n  [\"nospell.text\",\"density\"],\n  [\"text\",\"\\\"\"],\n  [\"paren.keyword.operator\",\"))\"]\n],[\n   \"nospell\"\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"paren.keyword.operator\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_red.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"Red\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"variable.set-word\",\"info:\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"func\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.lit-word\",\"'fn\"],\n  [\"text\",\"  \"],\n  [\"variable.refinement\",\"/name\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/intro\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/args\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/refinements\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"/local\"],\n  [\"text\",\"s \"],\n  [\"variable.refinement\",\"/return\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/spec\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"variable.refinement\",\"/arg-num\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/arg-names\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/arg-types\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/ref-names\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/ref-types\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/ref-num\"],\n  [\"text\",\" \"],\n  [\"variable.refinement\",\"/type\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"/local\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"intr\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ars\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"locs\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ret\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"arg\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"typ\"]\n],[\n   \"start\",\n  [\"paren.block-end\",\"]\"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"variable.set-word\",\"intr:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"ars:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"make\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"map!\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"refs:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"make\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"map!\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"locs:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"ret:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"typ:\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"ref-arg:\"],\n  [\"text\",\" \"],\n  [\"variable.set-word\",\"ref-arg-type:\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"none\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"lit-word?\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.set-word\",\"fn:\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"to-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.control\",\"unless\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"find\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"constant.datatype!\",\"op!\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"native!\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"function!\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"action!\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"type?\"],\n  [\"variable.refinement\",\"/word\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.function\",\"cause-error\"],\n  [\"text\",\" \"],\n  [\"variable.lit-word\",\"'user\"],\n  [\"text\",\" \"],\n  [\"variable.lit-word\",\"'message\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"string\",\"\\\"Only function types accepted!\\\"\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"variable.set-word\",\"out:\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"make\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"map!\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"variable.set-word\",\"specs:\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"spec-of\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword.native\",\"parse\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"specs\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"intr\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"string!\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.native\",\"any\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"arg\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"constant.datatype!\",\"word!\"],\n  [\"text\",\" | \"],\n  [\"constant.datatype!\",\"lit-word!\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"typ\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"block!\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"string!\"],\n  [\"text\",\" \"],\n  [\"paren.parens-start\",\"(\"],\n  [\"keyword.action\",\"put\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ars\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"arg\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"either\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"typ\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"typ\"],\n  [\"paren.block-end\",\"]\"],\n  [\"paren.block-start\",\"[[\"],\n  [\"constant.datatype!\",\"any-type!\"],\n  [\"paren.block-end\",\"]]\"],\n  [\"paren.parens-end\",\")\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword.native\",\"any\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"refinement!\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.parens-start\",\"(\"],\n  [\"variable.word\",\"ref\"],\n  [\"keyword.operator\",\" <> \"],\n  [\"keyword\",\"/local\"],\n  [\"paren.parens-end\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.parens-start\",\"(\"],\n  [\"keyword.action\",\"put\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"to-lit-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"make\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"map!\"],\n  [\"text\",\" \"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"paren.block-end\",\"]\"],\n  [\"paren.parens-end\",\")\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"string!\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"keyword.native\",\"any\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref-arg\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"word!\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref-arg-type\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"block!\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"paren.parens-start\",\"(\"],\n  [\"keyword.action\",\"put\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"text\",\"/\"],\n  [\"paren.parens-start\",\"(\"],\n  [\"keyword.function\",\"to-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref\"],\n  [\"paren.parens-end\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"to-lit-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref-arg\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"either\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ref-arg-type\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"ref-arg-type\"],\n  [\"paren.block-end\",\"]\"],\n  [\"paren.block-start\",\"[[\"],\n  [\"constant.datatype!\",\"any-type!\"],\n  [\"paren.block-end\",\"]]\"],\n  [\"paren.parens-end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t|\\t\"],\n  [\"keyword.native\",\"any\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"loc\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"word!\"],\n  [\"text\",\" \"],\n  [\"paren.parens-start\",\"(\"],\n  [\"keyword.action\",\"append\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"locs\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"loc\"],\n  [\"paren.parens-end\",\")\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"string!\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"variable.word\",\"opt\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"constant.datatype!\",\"set-word!\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"set\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ret\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"block!\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-end\",\"]]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.parens-start\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"variable.set-word\",\"out:\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"case\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword.view.option\",\"name\"],\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.function\",\"to-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"intro\"],\n  [\"text\",\" \\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"intr\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"args\"],\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"ars\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"arg-num\"],\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"length?\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ars\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"arg-names\"],\n  [\"text\",\" \\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"keys-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ars\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"arg-types\"],\n  [\"text\",\"\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"values-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"ars\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"refinements\"],\n  [\"text\",\" \"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"refs\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"ref-names\"],\n  [\"text\",\"\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"keys-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"ref-types\"],\n  [\"text\",\"\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"values-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"ref-num\"],\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"keyword.action\",\"length?\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"locals\"],\n  [\"text\",\" \\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"locs\"],\n  [\"paren.block-end\",\"]\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"ret\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"variable.word\",\"spec\"],\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-start\",\"[\"],\n  [\"variable.word\",\"specs\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"constant.language\",\"true\"],\n  [\"text\",\" \\t\\t\"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"keyword.action\",\"make\"],\n  [\"text\",\" \"],\n  [\"constant.datatype!\",\"object!\"],\n  [\"text\",\"  \"],\n  [\"paren.block-start\",\"[\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"keyword.view.option\",\"name\"],\n  [\"text\",\": \\t\\t\"],\n  [\"keyword.function\",\"to-word\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"intro:\"],\n  [\"text\",\" \\t\\t\"],\n  [\"variable.word\",\"intr\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"args:\"],\n  [\"text\",\" \\t\\t\"],\n  [\"variable.word\",\"ars\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"refinements:\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refs\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"locals:\"],\n  [\"text\",\" \\t\"],\n  [\"variable.word\",\"locs\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\": \\t\"],\n  [\"variable.word\",\"ret\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"spec:\"],\n  [\"text\",\" \\t\\t\"],\n  [\"variable.word\",\"specs\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"type:\"],\n  [\"text\",\" \\t\\t\"],\n  [\"keyword.native\",\"type?\"],\n  [\"text\",\" \"],\n  [\"keyword.native\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"fn\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"arg-num:\"],\n  [\"text\",\" \\t\"],\n  [\"keyword.action\",\"length?\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"args\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"arg-names:\"],\n  [\"text\",\" \\t\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"keys-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"args\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"arg-types:\"],\n  [\"text\",\" \\t\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"values-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"args\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"ref-names:\"],\n  [\"text\",\" \\t\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"keys-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refinements\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"ref-types:\"],\n  [\"text\",\" \\t\"],\n  [\"keyword.action\",\"copy\"],\n  [\"text\",\" \"],\n  [\"keyword.function\",\"values-of\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refinements\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"variable.set-word\",\"ref-num:\"],\n  [\"text\",\"\\t\"],\n  [\"keyword.action\",\"length?\"],\n  [\"text\",\" \"],\n  [\"variable.word\",\"refinements\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.block-end\",\"]\"],\n  [\"paren.parens-end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"variable.word\",\"out\"]\n],[\n   \"start\",\n  [\"paren.block-end\",\"]\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_rhtml.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Title\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"This is an R HTML document. When you click the \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Knit HTML\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\" button a web page will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"r-start\",\n  [\"support.function.codebegin\",\"<!--begin.rcode\"]\n],[\n   \"r-start\",\n  [\"identifier\",\"summary\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"cars\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"support.function.codeend\",\"end.rcode-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"You can also embed plots, for example:\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"p\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"r-start\",\n  [\"support.function.codebegin\",\"<!--begin.rcode fig.width=7, fig.height=6\"]\n],[\n   \"r-start\",\n  [\"identifier\",\"plot\"],\n  [\"paren.keyword.operator\",\"(\"],\n  [\"identifier\",\"cars\"],\n  [\"paren.keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"support.function.codeend\",\"end.rcode-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_robot.json",
    "content": "[[\n   \"start\",\n  [\"string.robot.header\",\"*** Settings ***\"]\n],[\n   \"comment\",\n  [\"comment\",\"Documentation     Robot Framework 4 syntax recipes cheat sheet robot.\"]\n],[\n   \"comment\",\n  [\"comment\",\"...               Demonstrates Robot Framework syntax in a concise format.\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Library\"],\n  [\"text\",\"           MyLibrary\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Library\"],\n  [\"text\",\"           MyLibrary\"],\n  [\"keyword\",\"    WITH NAME    \"],\n  [\"text\",\"HelloLibrary\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Library\"],\n  [\"text\",\"           MyLibrary    greeting=Howdy!\"],\n  [\"keyword\",\"    WITH NAME    \"],\n  [\"text\",\"HowdyLibrary\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Resource\"],\n  [\"text\",\"          keywords.robot\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Suite Setup\"],\n  [\"text\",\"       Log    Suite Setup!\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Suite Teardown\"],\n  [\"text\",\"    Log    Suite Teardown!\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Test Setup\"],\n  [\"text\",\"        Log    Test Setup!\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Test Teardown\"],\n  [\"text\",\"     Log    Test Teardown!\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Test Timeout\"],\n  [\"text\",\"      \"],\n  [\"constant.numeric.robot\",\"2\"],\n  [\"text\",\" minutes\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Variables\"],\n  [\"text\",\"         variables.py\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.robot.header\",\"*** Variables ***\"]\n],[\n   \"start\",\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"STRING\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"        cat\"]\n],[\n   \"start\",\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"NUMBER\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"        \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"LIST\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"          one    two    three\"]\n],[\n   \"start\",\n  [\"entity.name.variable.wrapper\",\"&{\"],\n  [\"entity.name.variable\",\"DICTIONARY\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    string=\"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"STRING\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"    number=\"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"NUMBER\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"    list=\"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"LIST\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"ENVIRONMENT_VARIABLE\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"%{\"],\n  [\"entity.name.variable\",\"PATH=Default value\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.robot.header\",\"*** Keywords ***\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword without arguments\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    No arguments.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword with a required argument\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Arguments]\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    Required argument: \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword with an optional argument\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Arguments]\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"Default value\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    Optional argument: \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    ...    Another arg\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword with any number of arguments\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Arguments]\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"varargs\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    Any number of arguments: \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"varargs\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword with one or more arguments\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Arguments]\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"varargs\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    One or more arguments: \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"argument\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\" \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"varargs\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword that returns a value\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Return]\"],\n  [\"text\",\"    Return value\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"A keyword with documentation\"]\n],[\n   \"comment\",\n  [\"comment\",\"    [Documentation]    This is keyword documentation.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    No Operation\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.robot.header\",\"*** Test Cases ***\"]\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Call keywords with a varying number of arguments\"]\n],[\n   \"storage.type.method.robot\",\n  [\"text\",\"    \"],\n  [\"storage.type.method.robot\",\"[Tags]    Test    Another Tag\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword without arguments\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with a required argument\"],\n  [\"text\",\"    Argument\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with a required argument\"],\n  [\"text\",\"    argument=Argument\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with an optional argument\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with an optional argument\"],\n  [\"text\",\"    Argument\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with an optional argument\"],\n  [\"text\",\"    argument=Argument\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with any number of arguments\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with any number of arguments\"],\n  [\"text\",\"    arg1    arg2    arg3    arg4    arg5\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with one or more arguments\"],\n  [\"text\",\"    arg1\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with one or more arguments\"],\n  [\"text\",\"    arg1    arg2    arg3\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Call a keyword that returns a value\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"value\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    A keyword that returns a value\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"value\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # Return value\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Do conditional IF - ELSE IF - ELSE execution\"]\n],[\n   \"start\",\n  [\"keyword\",\"    IF    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"NUMBER\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\" > \"],\n  [\"constant.numeric.robot\",\"1\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    Greater than one.\"]\n],[\n   \"start\",\n  [\"keyword\",\"    ELSE IF    \"],\n  [\"text\",\"\\\"\"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"STRING\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"\\\" == \\\"dog\\\"\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    It's a dog!\"]\n],[\n   \"start\",\n  [\"keyword\",\"    ELSE\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    Probably a cat. 🤔\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Loop a list\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"LIST\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # ['one', 'two', 'three']\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"item\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"LIST\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"item\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # one, two, three\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"item\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"text\",\"one    two    three\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"item\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # one, two, three\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Loop a dictionary\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"DICTIONARY\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"    # {'string': 'cat', 'number': 1, 'list': ['one', 'two', 'three']}\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"key_value_tuple\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"entity.name.variable.wrapper\",\"&{\"],\n  [\"entity.name.variable\",\"DICTIONARY\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"key_value_tuple\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"        # ('string', 'cat'), ('number', 1), ('list', ['one', 'two', 'three'])\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"key\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"DICTIONARY\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"key\"],\n  [\"entity.name.variable.wrapper\",\"}=${\"],\n  [\"entity.name.variable\",\"DICTIONARY\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"key\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"]\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"        # string=cat, number=1, list=['one', 'two', 'three']\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Loop a range from 0 to end index\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN RANGE    \"],\n  [\"constant.numeric.robot\",\"10\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 0-9\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Loop a range from start to end index\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN RANGE    \"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"text\",\"    \"],\n  [\"constant.numeric.robot\",\"10\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 1-9\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Loop a range from start to end index with steps\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN RANGE    \"],\n  [\"constant.numeric.robot\",\"0\"],\n  [\"text\",\"    \"],\n  [\"constant.numeric.robot\",\"10\"],\n  [\"text\",\"    \"],\n  [\"constant.numeric.robot\",\"2\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"index\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 0, 2, 4, 6, 8\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Nest loops\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"alphabets\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Create List    a    b    c\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"alphabets\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # ['a', 'b', 'c']\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"numbers\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Create List    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"constant.numeric.robot\",\"2\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"constant.numeric.robot\",\"3\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"numbers\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # [1, 2, 3]\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"alphabet\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"alphabets\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"        FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"number\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"numbers\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"            Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"alphabet\"],\n  [\"entity.name.variable.wrapper\",\"}${\"],\n  [\"entity.name.variable\",\"number\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"            # a1, a2, a3, b1, b2, b3, c1, c2, c3\"]\n],[\n   \"start\",\n  [\"keyword\",\"        END\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Exit a loop on condition\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN RANGE    \"],\n  [\"constant.numeric.robot\",\"5\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Exit For Loop If\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"} =\"],\n  [\"text\",\"= \"],\n  [\"constant.numeric.robot\",\"2\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 0, 1\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Continue a loop from the next iteration on condition\"]\n],[\n   \"start\",\n  [\"keyword\",\"    FOR    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"keyword\",\"    IN RANGE    \"],\n  [\"constant.numeric.robot\",\"3\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Continue For Loop If\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"} =\"],\n  [\"text\",\"= \"],\n  [\"constant.numeric.robot\",\"1\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"        Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"i\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 0, 2\"]\n],[\n   \"start\",\n  [\"keyword\",\"    END\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Create a scalar variable\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animal\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Set Variable    dog\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animal\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # dog\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animal\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric.robot\",\"0\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # d\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animal\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[-\"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # g\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Create a number variable\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"π\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Set Variable    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"constant.numeric.robot\",\"3.14\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"π\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # 3.14\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Create a list variable\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"animals\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Create List    dog    cat    bear\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animals\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # ['dog', 'cat', 'bear']\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animals\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric.robot\",\"0\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # dog\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"animals\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[-\"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # bear\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Create a dictionary variable\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"&{\"],\n  [\"entity.name.variable\",\"dictionary\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Create Dictionary    key1=value1    key2=value2\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"dictionary\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # {'key1': 'value1', 'key2': 'value2'}\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"dictionary\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[key1]\"],\n  [\"comment.robot\",\"    # value1\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"dictionary.key2\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # value2\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Access the items in a sequence (list, string)\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"string\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Set Variable    Hello world!\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"string\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric.robot\",\"0\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # H\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"string\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[:\"],\n  [\"constant.numeric.robot\",\"5\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # Hello\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"string\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric.robot\",\"6\"],\n  [\"text\",\":]\"],\n  [\"comment.robot\",\"    # world!\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"string\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[-\"],\n  [\"constant.numeric.robot\",\"1\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # !\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"@{\"],\n  [\"entity.name.variable\",\"list\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Create List    one    two    three    four    five\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"list\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # ['one', 'two', 'three', 'four', 'five']\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"list\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"text\",\"[\"],\n  [\"constant.numeric.robot\",\"0\"],\n  [\"text\",\":\"],\n  [\"constant.numeric.robot\",\"6\"],\n  [\"text\",\":\"],\n  [\"constant.numeric.robot\",\"2\"],\n  [\"text\",\"]\"],\n  [\"comment.robot\",\"    # ['one', 'three', 'five']\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Call a custom Python library\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    MyLibrary.Get Greeting\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # Hello!\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    HelloLibrary.Get Greeting\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # Hello!\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    HowdyLibrary.Get Greeting\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"greeting\"],\n  [\"entity.name.variable.wrapper\",\"}\"],\n  [\"comment.robot\",\"    # Howdy!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Call a keyword from a separate resource file\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    My keyword in a separate resource file\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Access a variable in a separate variable file\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"MY_VARIABLE_FROM_A_SEPARATE_VARIABLE_FILE\"],\n  [\"entity.name.variable.wrapper\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Split arguments to multiple lines\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    A keyword with any number of arguments\"]\n],[\n   \"start\",\n  [\"text\",\"    ...    arg1\"]\n],[\n   \"start\",\n  [\"text\",\"    ...    arg2\"]\n],[\n   \"start\",\n  [\"text\",\"    ...    arg3\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Log available variables\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log Variables\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"    # ${/} = /\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"    # &{DICTIONARY} = { string=cat | number=1 | list=['one', 'two', 'three'] }\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"    # ${OUTPUT_DIR} = /Users/<username>/...\"]\n],[\n   \"start\",\n  [\"comment.robot\",\"    # ...\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Evaluate Python expressions\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"path\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Evaluate    os.environ.get(\\\"PATH\\\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.variable.wrapper\",\"${\"],\n  [\"entity.name.variable\",\"path\"],\n  [\"entity.name.variable.wrapper\",\"}=\"],\n  [\"text\",\"    Set Variable    \"],\n  [\"entity.name.variable.wrapper\",\"${{\"],\n  [\"entity.name.variable\",\"os.environ.get(\\\"PATH\\\")\"],\n  [\"entity.name.variable.wrapper\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.robot\",\"Use special variables\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${EMPTY}\"],\n  [\"comment.robot\",\"    # Like the ${SPACE}, but without the space.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${False}\"],\n  [\"comment.robot\",\"    # Boolean False.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${None}\"],\n  [\"comment.robot\",\"    # Python None\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${null}\"],\n  [\"comment.robot\",\"    # Java null.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${SPACE}\"],\n  [\"comment.robot\",\"    # ASCII space (\\\\x20).\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${SPACE * 4}\"],\n  [\"comment.robot\",\"    # Four spaces.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \\\"\"],\n  [\"constant.language\",\"${SPACE}\"],\n  [\"text\",\"\\\"\"],\n  [\"comment.robot\",\"    # Quoted space (\\\" \\\").\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    Log\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${True}\"],\n  [\"comment.robot\",\"    # Boolean True.\"]\n],[\n   \"start\",\n  [\"storage.type.function\",\"    LOG\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"${CURDIR}\"],\n  [\"comment.robot\",\"  # Current directory\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_rst.json",
    "content": "[[\n   \"start\",\n  [\"markup.heading\",\"==========================================\"]\n],[\n   \"start\",\n  [\"markup.italic\",\"*\"],\n  [\"markup.italic\",\"reStructuredText*\"],\n  [\"text\",\" Highlighter for\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"Ace**\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"==========================================\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\".. \"],\n  [\"keyword.operator\",\"seealso::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"   http://docutils.sourceforge.net/docs/user/rst/quickstart.html\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"ReStructuredText Primer\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"=======================\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\":Author: Richard Jones\"]\n],[\n   \"start\",\n  [\"text\",\":Version: $Revision: 5801 $\"]\n],[\n   \"start\",\n  [\"text\",\":Copyright: This document has been placed in the public domain.\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\".. \"],\n  [\"keyword.operator\",\"contents::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"The text below contains links that look like \\\"(\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\\\".  These\"]\n],[\n   \"start\",\n  [\"text\",\"are relative links that point to the\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"Quick reStructuredText`_\"],\n  [\"text\",\" user\"]\n],[\n   \"link\",\n  [\"text\",\"reference.  If these links don't work, please refer to the\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"master\"]\n],[\n   \"start\",\n  [\"markup.underline.list\",\"quick reference`_\"],\n  [\"text\",\" document.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__\"]\n],[\n   \"start\",\n  [\"string\",\".. _Quick reStructuredText:\"],\n  [\"markup.underline.list\",\" quickref.html\"]\n],[\n   \"start\",\n  [\"string\",\".. _master quick reference:\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"markup.underline.list\",\"http://docutils.sourceforge.net/docs/user/rst/quickref.html\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\".. \"],\n  [\"keyword.operator\",\"Note::\"],\n  [\"support.function\",\" This document is an informal introduction to\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   reStructuredText.  The `What Next?`_ section below has links to\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   further resources, including a formal reference.\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Structure\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"---------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"From the outset, let me say that \\\"Structured Text\\\" is probably a bit\"]\n],[\n   \"start\",\n  [\"text\",\"of a misnomer.  It's more like \\\"Relaxed Text\\\" that uses certain\"]\n],[\n   \"start\",\n  [\"text\",\"consistent patterns.  These patterns are interpreted by a HTML\"]\n],[\n   \"start\",\n  [\"text\",\"converter to produce \\\"Very Structured Text\\\" that can be used by a web\"]\n],[\n   \"start\",\n  [\"text\",\"browser.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"The most basic pattern recognised is a\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"paragraph**\"],\n  [\"text\",\" (\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\").\"]\n],[\n   \"start\",\n  [\"text\",\"That's a chunk of text that is separated by blank lines (one is\"]\n],[\n   \"start\",\n  [\"text\",\"enough).  Paragraphs must have the same indentation -- that is, line\"]\n],[\n   \"start\",\n  [\"text\",\"up at their left edge.  Paragraphs that start indented will result in\"]\n],[\n   \"codeblock\",\n  [\"text\",\"indented quote paragraphs. For example\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  This is a paragraph.  It's quite\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  short.\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"     This paragraph will result in an indented block of\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     text, typically used for quoting other text.\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  This is another one.\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  This is a paragraph.  It's quite\"]\n],[\n   \"start\",\n  [\"text\",\"  short.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"     This paragraph will result in an indented block of\"]\n],[\n   \"start\",\n  [\"text\",\"     text, typically used for quoting other text.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  This is another one.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#paragraphs\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Text styles\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"-----------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#inline-markup\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Inside paragraphs and other bodies of text, you may additionally mark\"]\n],[\n   \"start\",\n  [\"text\",\"text for\"],\n  [\"text\",\" \"],\n  [\"markup.italic\",\"*\"],\n  [\"markup.italic\",\"italics*\"],\n  [\"text\",\" with \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"*italics*``\"],\n  [\"text\",\"\\\" or\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"bold**\"],\n  [\"text\",\" with\"]\n],[\n   \"start\",\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"**bold**``\"],\n  [\"text\",\"\\\".  This is called \\\"inline markup\\\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"If you want something to appear as a fixed-space literal, use\"]\n],[\n   \"start\",\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"``double back-quotes````\"],\n  [\"text\",\"\\\".  Note that no further fiddling is done\"]\n],[\n   \"start\",\n  [\"text\",\"inside the double back-quotes -- so asterisks \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"*``\"],\n  [\"text\",\"\\\" etc. are left\"]\n],[\n   \"start\",\n  [\"text\",\"alone.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"If you find that you want to use one of the \\\"special\\\" characters in\"]\n],[\n   \"start\",\n  [\"text\",\"text, it will generally be OK -- reStructuredText is pretty smart.\"]\n],[\n   \"start\",\n  [\"text\",\"For example, this lone asterisk * is handled just fine, as is the\"]\n],[\n   \"start\",\n  [\"text\",\"asterisk in this equation: 5*6=30.  If you actually\"]\n],[\n   \"start\",\n  [\"text\",\"want text \\\\*surrounded by asterisks* to\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"not**\"],\n  [\"text\",\" be italicised, then\"]\n],[\n   \"start\",\n  [\"text\",\"you need to indicate that the asterisk is not special.  You do this by\"]\n],[\n   \"start\",\n  [\"text\",\"placing a backslash just before it, like so \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"\\\\*``\"],\n  [\"text\",\"\\\" (\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\"), or\"]\n],[\n   \"codeblock\",\n  [\"text\",\"by enclosing it in double back-quotes (inline literals), like this\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ``*``\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#escaping\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\".. \"],\n  [\"keyword.operator\",\"Tip::\"],\n  [\"support.function\",\" Think of inline markup as a form of (parentheses) and use it\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   the same way: immediately before and after the text being marked\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   up.  Inline markup by itself (surrounded by whitespace) or in the\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   middle of a word won't be recognized.  See the `markup spec`__ for\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"   full details.\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"__ ../../ref/rst/restructuredtext.html#inline-markup\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Lists\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"-----\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Lists of items come in three main flavours:\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"enumerated**\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"bulleted**\"],\n  [\"text\",\" and\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"definitions**\"],\n  [\"text\",\".  In all list cases, you may have as\"]\n],[\n   \"start\",\n  [\"text\",\"many paragraphs, sublists, etc. as you want, as long as the left-hand\"]\n],[\n   \"start\",\n  [\"text\",\"side of the paragraph or whatever aligns with the first line of text\"]\n],[\n   \"start\",\n  [\"text\",\"in the list item.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Lists must always start a new paragraph -- that is, they must appear\"]\n],[\n   \"start\",\n  [\"text\",\"after a blank line.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"enumerated**\"],\n  [\"text\",\" lists (numbers, letters or roman numerals; \"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#enumerated-lists\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Start a line off with a number or letter followed by a period \\\".\\\",\"]\n],[\n   \"start\",\n  [\"text\",\"right bracket \\\")\\\" or surrounded by brackets \\\"( )\\\" -- whatever you're\"]\n],[\n   \"codeblock\",\n  [\"text\",\"comfortable with.  All of the following forms are recognised\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  1. numbers\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  A. upper-case letters\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     and it goes over many lines\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"     with two paragraphs and all!\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  a. lower-case letters\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"     3. with a sub-list starting at a different number\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     4. make sure the numbers are in the correct sequence though!\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  I. upper-case roman numerals\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  i. lower-case roman numerals\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  (1) numbers again\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  1) and again\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in (note: the different enumerated list styles are not\"]\n],[\n   \"start\",\n  [\"text\",\"always supported by every web browser, so you may not get the full\"]\n],[\n   \"start\",\n  [\"text\",\"effect here):\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"1. \"],\n  [\"text\",\"numbers\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"A. \"],\n  [\"text\",\"upper-case letters\"]\n],[\n   \"start\",\n  [\"text\",\"   and it goes over many lines\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"   with two paragraphs and all!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"a. \"],\n  [\"text\",\"lower-case letters\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"   3. \"],\n  [\"text\",\"with a sub-list starting at a different number\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"   4. \"],\n  [\"text\",\"make sure the numbers are in the correct sequence though!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"I. \"],\n  [\"text\",\"upper-case roman numerals\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"i. \"],\n  [\"text\",\"lower-case roman numerals\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"(1) \"],\n  [\"text\",\"numbers again\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"1) \"],\n  [\"text\",\"and again\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"bulleted**\"],\n  [\"text\",\" lists (\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#bullet-lists\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Just like enumerated lists, start the line off with a bullet point\"]\n],[\n   \"codeblock\",\n  [\"text\",\"character - either \\\"-\\\", \\\"+\\\" or \\\"\\\\*\\\"\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  * a bullet point using \\\"\\\\*\\\"\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    - a sub-list using \\\"-\\\"\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"      + yet another sub-list\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    - another item\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"* \"],\n  [\"text\",\"a bullet point using \\\"\\\\*\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"  - \"],\n  [\"text\",\"a sub-list using \\\"-\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"    + \"],\n  [\"text\",\"yet another sub-list\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"  - \"],\n  [\"text\",\"another item\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"definition**\"],\n  [\"text\",\" lists (\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#definition-lists\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Unlike the other two, the definition lists consist of a term, and\"]\n],[\n   \"codeblock\",\n  [\"text\",\"the definition of that term.  The format of a definition list is\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  what\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    Definition lists associate a term with a definition.\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  *how*\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    The term is a one-line phrase, and the definition is one or more\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    paragraphs or body elements, indented relative to the term.\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    Blank lines are not allowed between term and definition.\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in:\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"what\"]\n],[\n   \"start\",\n  [\"text\",\"  Definition lists associate a term with a definition.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.italic\",\"*\"],\n  [\"markup.italic\",\"how*\"]\n],[\n   \"start\",\n  [\"text\",\"  The term is a one-line phrase, and the definition is one or more\"]\n],[\n   \"start\",\n  [\"text\",\"  paragraphs or body elements, indented relative to the term.\"]\n],[\n   \"start\",\n  [\"text\",\"  Blank lines are not allowed between term and definition.\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Preformatting (code samples)\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"----------------------------\"]\n],[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#literal-blocks\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"To just include a chunk of preformatted, never-to-be-fiddled-with\"]\n],[\n   \"start\",\n  [\"text\",\"text, finish the prior paragraph with \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"::``\"],\n  [\"text\",\"\\\".  The preformatted\"]\n],[\n   \"start\",\n  [\"text\",\"block is finished when the text falls back to the same indentation\"]\n],[\n   \"codeblock\",\n  [\"text\",\"level as a paragraph prior to the preformatted block.  For example\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  An example::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"      Whitespace, newlines, blank lines, and all kinds of markup\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"        (like *this* or \\\\this) is preserved by literal blocks.\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    Lookie here, I've dropped an indentation level\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    (but not far enough)\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  no more example\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in:\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\"An example\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    Whitespace, newlines, blank lines, and all kinds of markup\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"      (like *this* or \\\\this) is preserved by literal blocks.\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Lookie here, I've dropped an indentation level\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  (but not far enough)\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"no more example\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Note that if a paragraph consists only of \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"::``\"],\n  [\"text\",\"\\\", then it's removed\"]\n],[\n   \"codeblock\",\n  [\"text\",\"from the output\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  ::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"      This is preformatted text, and the\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"      last \\\"::\\\" paragraph is removed\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Results in:\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    This is preformatted text, and the\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    last \\\"::\\\" paragraph is removed\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Sections\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"--------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#section-structure\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"To break longer text up into sections, you use\"],\n  [\"text\",\" \"],\n  [\"markup.bold\",\"**\"],\n  [\"markup.bold\",\"section headers**\"],\n  [\"text\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"These are a single line of text (one or more words) with adornment: an\"]\n],[\n   \"start\",\n  [\"text\",\"underline alone, or an underline and an overline together, in dashes\"]\n],[\n   \"start\",\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"-----``\"],\n  [\"text\",\"\\\", equals \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"======``\"],\n  [\"text\",\"\\\", tildes \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"~~~~~~``\"],\n  [\"text\",\"\\\" or any of the\"]\n],[\n   \"start\",\n  [\"text\",\"non-alphanumeric characters\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"= - ` : ' \\\" ~ ^ _ * + # < >``\"],\n  [\"text\",\" that you\"]\n],[\n   \"start\",\n  [\"text\",\"feel comfortable with.  An underline-only adornment is distinct from\"]\n],[\n   \"start\",\n  [\"text\",\"an overline-and-underline adornment using the same character.  The\"]\n],[\n   \"start\",\n  [\"text\",\"underline/overline must be at least as long as the title text.  Be\"]\n],[\n   \"start\",\n  [\"text\",\"consistent, since all sections marked with the same adornment style\"]\n],[\n   \"codeblock\",\n  [\"text\",\"are deemed to be at the same level\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Chapter 1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  ===============\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Section 1.1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  -----------------\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Subsection 1.1.1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  ~~~~~~~~~~~~~~~~~~~~~~\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Section 1.2 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  -----------------\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  Chapter 2 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"  ===============\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"This results in the following structure, illustrated by simplified\"]\n],[\n   \"codeblock\",\n  [\"text\",\"pseudo-XML\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    <section>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"        <title>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"            Chapter 1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"        <section>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"            <title>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"                Section 1.1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"            <section>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"                <title>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"                    Subsection 1.1.1 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"        <section>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"            <title>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"                Section 1.2 Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    <section>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"        <title>\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"            Chapter 2 Title\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"(Pseudo-XML uses indentation for nesting and has no end-tags.  It's\"]\n],[\n   \"start\",\n  [\"text\",\"not possible to show actual processed output, as in the other\"]\n],[\n   \"start\",\n  [\"text\",\"examples, because sections cannot exist inside block quotes.  For a\"]\n],[\n   \"start\",\n  [\"text\",\"concrete example, compare the section structure of this document's\"]\n],[\n   \"start\",\n  [\"text\",\"source text and processed output.)\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Note that section headers are available as link targets, just using\"]\n],[\n   \"start\",\n  [\"text\",\"their name.  To link to the \"],\n  [\"markup.underline.list\",\"Lists_\"],\n  [\"text\",\" heading, I write \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"Lists_``\"],\n  [\"text\",\"\\\".  If\"]\n],[\n   \"start\",\n  [\"text\",\"the heading has a space in it like\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"text styles`_\"],\n  [\"text\",\", we need to quote\"]\n],[\n   \"start\",\n  [\"text\",\"the heading \"],\n  [\"text\",\"\\\"\"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"`text styles`_``\"],\n  [\"text\",\"\\\".\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Document Title / Subtitle\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"`````````````````````````\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"The title of the whole document is distinct from section titles and\"]\n],[\n   \"start\",\n  [\"text\",\"may be formatted somewhat differently (e.g. the HTML writer by default\"]\n],[\n   \"start\",\n  [\"text\",\"shows it as a centered heading).\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"To indicate the document title in reStructuredText, use a unique adornment\"]\n],[\n   \"start\",\n  [\"text\",\"style at the beginning of the document.  To indicate the document subtitle,\"]\n],[\n   \"start\",\n  [\"text\",\"use another unique adornment style immediately after the document title.  For\"]\n],[\n   \"codeblock\",\n  [\"text\",\"example\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ================\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     Document Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ================\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ----------\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     Subtitle\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ----------\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    Section Title\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"    =============\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"    ...\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"Note that \\\"Document Title\\\" and \\\"Section Title\\\" above both use equals\"]\n],[\n   \"start\",\n  [\"text\",\"signs, but are distict and unrelated styles.  The text of\"]\n],[\n   \"start\",\n  [\"text\",\"overline-and-underlined titles (but not underlined-only) may be inset\"]\n],[\n   \"start\",\n  [\"text\",\"for aesthetics.\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Images\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"markup.underline.list\",\"quickref__\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ quickref.html#directives\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"To include an image in your document, you use the the\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"image``\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"directive__\"],\n  [\"text\",\".\"]\n],[\n   \"codeblock\",\n  [\"text\",\"For example\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  .. image:: images/biohazard.png\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"results in:\"]\n],[\n   \"start\"\n],[\n   \"codeblock\",\n  [\"text\",\".. \"],\n  [\"keyword.operator\",\"image::\"],\n  [\"support.function\",\" images/biohazard.png\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"The\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"``\"],\n  [\"support.function\",\"images/biohazard.png``\"],\n  [\"text\",\" part indicates the filename of the image\"]\n],[\n   \"start\",\n  [\"text\",\"you wish to appear in the document. There's no restriction placed on\"]\n],[\n   \"start\",\n  [\"text\",\"the image (format, size etc).  If the image is to appear in HTML and\"]\n],[\n   \"codeblock\",\n  [\"text\",\"you wish to supply additional information, you may\"],\n  [\"keyword.operator\",\"::\"]\n],[\n   \"codeblock\"\n],[\n   \"codeblock\",\n  [\"support.function\",\"  .. image:: images/biohazard.png\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     :height: 100\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     :width: 200\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     :scale: 50\"]\n],[\n   \"codeblock\",\n  [\"support.function\",\"     :alt: alternate text\"]\n],[\n   \"codeblock\"\n],[\n   \"start\",\n  [\"text\",\"See the full\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"image directive documentation`__\"],\n  [\"text\",\" for more info.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"__ ../../ref/rst/directives.html\"]\n],[\n   \"start\",\n  [\"text\",\"__ ../../ref/rst/directives.html#images\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"What Next?\"]\n],[\n   \"start\",\n  [\"markup.heading\",\"----------\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"This primer introduces the most common features of reStructuredText,\"]\n],[\n   \"start\",\n  [\"text\",\"but there are a lot more to explore.  The\"],\n  [\"text\",\" \"],\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"Quick reStructuredText`_\"]\n],[\n   \"start\",\n  [\"text\",\"user reference is a good place to go next.  For complete details, the\"]\n],[\n   \"start\",\n  [\"markup.underline.list\",\"`\"],\n  [\"markup.underline.list\",\"reStructuredText Markup Specification`_\"],\n  [\"text\",\" is the place to go \"],\n  [\"markup.underline.list\",\"[#]_\"],\n  [\"text\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Users who have questions or need assistance with Docutils or\"]\n],[\n   \"start\",\n  [\"text\",\"reStructuredText should post a message to the \"],\n  [\"markup.underline.list\",\"Docutils-users_\"],\n  [\"text\",\" mailing\"]\n],[\n   \"start\",\n  [\"text\",\"list.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\".. [#] \"],\n  [\"text\",\"If that relative link doesn't work, try the master document:\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"markup.underline.list\",\"http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string\",\".. _reStructuredText Markup Specification:\"]\n],[\n   \"start\",\n  [\"text\",\"   ../../ref/rst/restructuredtext.html\"]\n],[\n   \"start\",\n  [\"string\",\".. _Docutils-users:\"],\n  [\"markup.underline.list\",\" ../mailing-lists.html#docutils-users\"]\n],[\n   \"start\",\n  [\"string\",\".. _Docutils project web site:\"],\n  [\"markup.underline.list\",\" http://docutils.sourceforge.net/\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_ruby.json",
    "content": "[[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"#test: symbol tokenizer\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.other.symbol.ruby\",\":@thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":$thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":_thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":Thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing_a\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"              \"],\n  [\"constant.other.symbol.ruby\",\":THING\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing!\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing=\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing?\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":t?\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"              \"],\n  [\"punctuation.operator\",\":,\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"@\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword.operator\",\"$\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1\"],\n  [\"identifier\",\"thing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":th?\"],\n  [\"identifier\",\"ing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thi=\"],\n  [\"identifier\",\"ng\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"1\"],\n  [\"identifier\",\"thing\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"constant.other.symbol.ruby\",\":th!\"],\n  [\"identifier\",\"ing\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":thing\"],\n  [\"comment\",\"#\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"#test: namespaces aren't symbols\\\" : function() {\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"support.class\",\"Namespaced\"],\n  [\"punctuation\",\"::\"],\n  [\"support.class\",\"Class\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"#test: hex tokenizer \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"constant.numeric\",\"0x9a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0XA1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0x9_a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"x\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"x_9a\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"x9a_\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"#test: float tokenizer\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"+1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12_345\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.000_1\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"_\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3_1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1_2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" 1\"],\n  [\"identifier\",\"_\"],\n  [\"punctuation.operator\",\".\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"_1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"],\n  [\"constant.other.symbol.ruby\",\":id\"],\n  [\"text\",\" \"],\n  [\"punctuation.separator.key-value\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.character\",\"?\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.other.symbol.ruby\",\":key\"],\n  [\"text\",\" \"],\n  [\"punctuation.separator.key-value\",\"=>\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"value\"],\n  [\"string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"anotherKey\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"punctuation.operator\",\"?\"],\n  [\"paren.rparen\",\"]}\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment.multiline\",\"=begin\"]\n],[\n   \"start\",\n  [\"comment.multiline\",\"=end\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment.multiline\",\"=begin\"],\n  [\"comment\",\" x\"]\n],[\n   \"comment\",\n  [\"comment\",\"=end-\"]\n],[\n   \"start\",\n  [\"comment.multiline\",\"=end\"],\n  [\"text\",\"   \"],\n  [\"identifier\",\"x\"]\n],[\n   \"start\"\n],[\n   [\"heredoc\",\"FOO\",\"heredoc\",\"BAR\",\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"herDocs\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant\",\"<<\"],\n  [\"string\",\"'\"],\n  [\"support.class\",\"FOO\"],\n  [\"string\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant\",\"<<\"],\n  [\"string\",\"\"],\n  [\"support.class\",\"BAR\"],\n  [\"string\",\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant\",\"<<-\"],\n  [\"string\",\"\"],\n  [\"support.class\",\"BAZ\"],\n  [\"string\",\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant\",\"<<-\"],\n  [\"string\",\"`\"],\n  [\"support.class\",\"EXEC\"],\n  [\"string\",\"`\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"comment\",\"#comment\"]\n],[\n   [\"heredoc\",\"FOO\",\"heredoc\",\"BAR\",\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"string\",\"  FOO #{literal}\"]\n],[\n   [\"heredoc\",\"BAR\",\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"support.class\",\"FOO\"]\n],[\n   [\"heredoc\",\"BAR\",\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"string\",\"  BAR #{fact(10)}\"]\n],[\n   [\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"support.class\",\"BAR\"]\n],[\n   [\"indentedHeredoc\",\"BAZ\",\"indentedHeredoc\",\"EXEC\"],\n  [\"string\",\"  BAZ indented\"]\n],[\n   [\"indentedHeredoc\",\"EXEC\"],\n  [\"string\",\"    \"],\n  [\"support.class\",\"BAZ\"]\n],[\n   [\"indentedHeredoc\",\"EXEC\"],\n  [\"string\",\"        echo hi\"]\n],[\n   \"start\",\n  [\"string\",\"    \"],\n  [\"support.class\",\"EXEC\"]\n],[\n   \"start\",\n  [\"support.function\",\"puts\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"herDocs\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_rust.json",
    "content": "[[\n   \"start\",\n  [\"keyword.source.rust\",\"use\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"core::rand::\"],\n  [\"identifier\",\"RngUtil\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.source.rust\",\"fn\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.source.rust\",\"main\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string.quoted.double.source.rust\",\"\\\"Alice\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.source.rust\",\"\\\"Bob\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.source.rust\",\"\\\"Carol\\\"\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"each\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|&\"],\n  [\"identifier\",\"name\"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword.source.rust\",\"do\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"spawn\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"rand::\"],\n  [\"identifier\",\"Rng\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"shuffle\"],\n  [\"paren.lparen\",\"([\"],\n  [\"constant.numeric.source.rust\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"3\"],\n  [\"paren.rparen\",\"])\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword.source.rust\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"v\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"each\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|&\"],\n  [\"identifier\",\"num\"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"fmt\"],\n  [\"keyword.operator\",\"!\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.quoted.double.source.rust\",\"\\\"%s says: '%d'\"],\n  [\"constant.character.escape.source.rust\",\"\\\\n\"],\n  [\"string.quoted.double.source.rust\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"num\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"1\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"_\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.source.rust\",\"i128\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric.source.rust\",\"42i128\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"_\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.source.rust\",\"u128\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"42u128\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   [\"comment\",\"comment\"],\n  [\"comment.start.block.source.rust\",\"/*\"],\n  [\"comment.block.source.rust\",\" nested \"],\n  [\"comment.start.block.source.rust\",\"/*\"],\n  [\"comment.block.source.rust\",\" \"]\n],[\n   \"start\",\n  [\"comment.block.source.rust\",\"    comments \"],\n  [\"comment.end.block.source.rust\",\"*/\"],\n  [\"comment.block.source.rust\",\" \"],\n  [\"comment.end.block.source.rust\",\"*/\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.source.rust\",\"fn\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.source.rust\",\"map\"],\n  [\"punctuation\",\"<\"],\n  [\"identifier\",\"T\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"U\"],\n  [\"punctuation\",\">\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"vector\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"T\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"function\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"identifier\",\"fn\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"v\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"identifier\",\"T\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"U\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" ~\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"U\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"keyword.source.rust\",\"mut\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" ~\"],\n  [\"paren.lparen\",\"[\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"for\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"vec::\"],\n  [\"identifier\",\"each\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"vector\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"identifier\",\"element\"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"accumulator\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"push\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"element\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.source.rust\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"accumulator\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.source.rust\",\"// numbers\"]\n],[\n   \"start\",\n  [\"constant.numeric.source.rust\",\"14E-111_f64\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"45isize\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"0x1i32\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"0o777u32\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"0b01\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"14f32\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"1_2.78f32\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"1_2.3E+7f32\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.source.rust\",\"// not numbers\"]\n],[\n   \"start\",\n  [\"constant.numeric.source.rust\",\"14\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"_E\"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric.source.rust\",\"111_f64\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"xi32\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"b777u\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-dash.source.rust\",\"// identifiers ending in constant.numeric\"]\n],[\n   \"start\",\n  [\"identifier\",\"foo1\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"foo1u32\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"foo1f32\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"foo0xF\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"foo1\"],\n  [\"punctuation.operator\",\".\"],\n  [\"constant.numeric.source.rust\",\"0\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.source.rust\",\"pub\"],\n  [\"text\",\" \"],\n  [\"keyword.source.rust\",\"fn\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.source.rust\",\"g\"],\n  [\"punctuation\",\"<\"],\n  [\"identifier\",\"T\"],\n  [\"punctuation\",\">\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"std::mem::\"],\n  [\"identifier\",\"MaybeUninit\"],\n  [\"punctuaction\",\"<\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"T\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.source.rust\",\"2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation\",\">\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.constant\",\"std::mem::MaybeUninit::\"],\n  [\"identifier\",\"uninit\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   [\"bracketedComment\",3,\"start\"],\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"multiline\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.quoted.raw.source.rust\",\"r##\\\"\"]\n],[\n   [\"bracketedComment\",3,\"start\"],\n  [\"string.quoted.raw.source.rust\",\"    This is a raw string.\"]\n],[\n   [\"bracketedComment\",3,\"start\"],\n  [\"string.quoted.raw.source.rust\",\"    r#\\\"nested string\\\"#\"]\n],[\n   \"start\",\n  [\"string.quoted.raw.source.rust\",\"\\\"##\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword.source.rust\",\"let\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"_strings\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string.quoted.raw.source.rust\",\"br##\\\"\\\"##\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.raw.source.rust\",\"r\\\"hello\\\\\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.raw.source.rust\",\"br\\\"hello\\\\\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.raw.source.rust\",\"cr\\\"hello\\\\\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sac.json",
    "content": "[[\n   \"doc-start\",\n  [\n    \"comment.doc\",\n    \"/**\"\n  ],\n  [\n    \"comment.doc.body\",\n    \"***************************************************************************\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   SAC demo program\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   This SAC demo program implements 2-dimensional relaxation on double\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   precision floating point numbers applying a 4-point stencil and fixed\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   boundary conditions.\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   The vertical (SIZE1) and the horizontal (SIZE2) array size as well as\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   the number of iterations to be performed (LOOP) may be set at compile\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *   time.\"\n  ]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \" *\"\n  ]\n],[\n   \"start\",\n  [\n    \"comment.doc.body\",\n    \" ****************************************************************************\"\n  ],\n  [\n    \"comment.doc\",\n    \"*/\"\n  ]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#ifndef\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LOOP\"]\n],[\n   \"start\",\n  [\"keyword\",\"#define\"],\n  [\"constant.other\",\" LOOP 100\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#ifndef\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SIZE1\"]\n],[\n   \"start\",\n  [\"keyword\",\"#define\"],\n  [\"constant.other\",\" SIZE1 1000\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#ifndef\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SIZE2\"]\n],[\n   \"start\",\n  [\"keyword\",\"#define\"],\n  [\"constant.other\",\" SIZE2 1000\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Array\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"all\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword.control\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"StdIO\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"all\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.modifier\",\"inline\"]\n],[\n   \"start\",\n  [\"storage.type\",\"double\"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"onestep\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"double\"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"A\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"with\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\".\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\".\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.25\"],\n  [\"keyword.operator\",\"*\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"B\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\"]]\"]\n],[\n   \"start\",\n  [\"text\",\"                              \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"-\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\"]]\"]\n],[\n   \"start\",\n  [\"text\",\"                              \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]]\"]\n],[\n   \"start\",\n  [\"text\",\"                              \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"keyword.operator\",\"-\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]])\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"modarray\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"B\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.modifier\",\"inline\"]\n],[\n   \"start\",\n  [\"storage.type\",\"double\"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"relax\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"double\"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword.operator\",\"+\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"A\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"steps\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"k\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"steps\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"k\"],\n  [\"keyword.operator\",\"++\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"A\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"onestep\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"main\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"A\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"with\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\".\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\".\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.\"],\n  [\"text\",\"0\"],\n  [\"identifier\",\"d\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"genarray\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"SIZE1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"identifier\",\"SIZE2\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"A\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"modarray\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"500.\"],\n  [\"text\",\"0\"],\n  [\"identifier\",\"d\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"A\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"relax\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"A\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LOOP\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"z\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control\",\"with\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"shape\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"shape\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"A\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"A\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"x\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"fold\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" 0\"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#if\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"printf\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"\\\"\"],\n  [\"constant.language.escape\",\"%.10g\\\\n\"],\n  [\"string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"z\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"#else\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"print\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"z\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"#endif\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_sass.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// sass ace mode;\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"@import\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"http://fonts.googleapis.com/css?family=Ace:700\"],\n  [\"support.function\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\"html\"],\n  [\"text\",\", \"],\n  [\"variable.language\",\"body\"]\n],[\n   \"start\",\n  [\"support.type\",\"  :background-color \"],\n  [\"constant.numeric\",\"#ace\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"text-align\"],\n  [\"text\",\": \"],\n  [\"constant.language\",\"center\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"height\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"100%\"]\n],[\n   [\"comment\",-1,2,\"start\"],\n  [\"comment\",\"  /*;*********;\"]\n],[\n   [\"comment\",3,2,\"start\"],\n  [\"comment\",\"    ;comment  ;\"]\n],[\n   [\"comment\",3,2,\"start\"],\n  [\"comment\",\"    ;*********;\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\".toggle\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"$size\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"14px\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.type\",\"  :background \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"http://subtlepatterns.com/patterns/dark_stripes.png\"],\n  [\"support.function\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"border-radius\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"8px\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"height\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$size\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  &\"],\n  [\"variable.language\",\":before\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$radius\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.845\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.125\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\" / \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#fff\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"border-radius\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$radius\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"text\",\"    &\"],\n  [\"variable.language\",\":active\"]\n],[\n   \"start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".button\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"15px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"25px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-4px\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"rgba\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0.4\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\"      \"]\n],[\n   \"start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".label\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"font-size\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"40px\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"rgba\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0.45\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    &\"],\n  [\"variable.language\",\":checked\"],\n  [\"text\",\"      \"]\n],[\n   \"start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".button\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"15px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"25px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-4px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#ace\"]\n],[\n   \"start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".label\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"font-size\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"40px\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"color\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"#c9c9c9\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_scad.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// ace can highlight scad!\"]\n],[\n   \"start\",\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Element\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"xpos\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"ypos\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"zpos\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"translate\"],\n  [\"paren.lparen\",\"([\"],\n  [\"identifier\",\"xpos\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"ypos\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"zpos\"],\n  [\"paren.rparen\",\"])\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"union\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"cube\"],\n  [\"paren.lparen\",\"([\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"4\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"true\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"cylinder\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"15\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\"],\n  [\"identifier\",\"translate\"],\n  [\"paren.lparen\",\"([\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\"])\"],\n  [\"identifier\",\"sphere\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"union\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"for\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"=\"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\":\"],\n  [\"constant.numeric\",\"30\"],\n  [\"paren.rparen\",\"])\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t# \"],\n  [\"identifier\",\"Element\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"Element\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"15\"],\n  [\"keyword.operator\",\"*\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"11\"],\n  [\"paren.rparen\",\"])\"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"rotate\"],\n  [\"paren.lparen\",\"([\"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\"])\"],\n  [\"identifier\",\"scale\"],\n  [\"paren.lparen\",\"([\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\",\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"])\"],\n  [\"identifier\",\"cube\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_scala.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// http://www.scala-lang.org/node/54\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"package\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"examples\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"actors\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"scala\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"actors\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Actor\"]\n],[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"scala\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"actors\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Actor\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"_\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"abstract\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PingMessage\"]\n],[\n   \"start\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Start\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PingMessage\"]\n],[\n   \"start\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SendPing\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PingMessage\"]\n],[\n   \"start\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pong\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PingMessage\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"abstract\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PongMessage\"]\n],[\n   \"start\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PongMessage\"]\n],[\n   \"start\",\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Stop\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"PongMessage\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pingpong\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"Application\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"val\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pong\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"val\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ping\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"100000\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"pong\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"ping\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"start\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"start\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"ping\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Start\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"count\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"Int\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\": \"],\n  [\"identifier\",\"Actor\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Actor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"act\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Ping: Initializing with count \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"count\"],\n  [\"keyword.operator\",\"+\"],\n  [\"string\",\"\\\": \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"pong\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"loop\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"react\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Start\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Ping: starting.\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SendPing\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pong\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1000\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Ping: pong from: \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"sender\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"pingsLeft\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"self\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"SendPing\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Ping: Stop.\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"pong\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Stop\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"exit\"],\n  [\"paren.lparen\",\"(\"],\n  [\"symbol.constant\",\"'stop\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pong\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Actor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"def\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"act\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pongCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"loop\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"react\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ping\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"pongCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"%\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1000\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Pong: ping \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"pongCount\"],\n  [\"keyword.operator\",\"+\"],\n  [\"string\",\"\\\" from \\\"\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"sender\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"sender\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Pong\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"pongCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pongCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"case\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Stop\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=>\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"keyword\",\"println\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Pong: Stop.\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"identifier\",\"exit\"],\n  [\"paren.lparen\",\"(\"],\n  [\"symbol.constant\",\"'stop\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_scheme.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"(\"],\n  [\"storage.type.function-type.scheme\",\"define\"],\n  [\"text\",\" \"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"prompt-for-cd\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"string\",\"\\\"Prompts\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CD\"],\n  [\"text\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"identifier\",\"prompt-read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Title\\\"\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.53\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\"/\"],\n  [\"constant.numeric\",\"4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.7\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1.7e0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2.9E-4\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"+42\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-7\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#b001\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#b001\"],\n  [\"text\",\"/\"],\n  [\"constant.numeric\",\"100\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#o777\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#O777\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#xabc55\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"#c\"],\n  [\"text\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-5.6\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"identifier\",\"prompt-read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Artist\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"   (\"],\n  [\"keyword.operator\",\"or\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"parse-integer\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"prompt-read\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Rating\\\"\"],\n  [\"text\",\") \"],\n  [\"punctuation.definition.constant.character.scheme\",\"#:junk-allowed\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"#t\"],\n  [\"text\",\") \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"keyword.control\",\"if\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" (\"],\n  [\"support.function\",\"format\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"#t\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"yes\\\"\"],\n  [\"text\",\") (\"],\n  [\"support.function\",\"format\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"#f\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"no\\\"\"],\n  [\"text\",\") \"],\n  [\"comment\",\";and here comment\"]\n],[\n   \"start\",\n  [\"text\",\"  ) \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\";; second line comment\"]\n],[\n   \"start\",\n  [\"text\",\"  '(+ \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"identifier\",\"position-if-not\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"char-set\"],\n  [\"text\",\":\"],\n  [\"identifier\",\"whitespace\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"line\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.constant.character.scheme\",\"#:start\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"beg\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"support.function\",\"quote\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"privet\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  '(\"],\n  [\"identifier\",\"hello\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"world\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (* \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"7\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"34\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"punctuation.definition.constant.character.scheme\",\"#:use\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"aaaa\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  (\"],\n  [\"keyword.control\",\"let\"],\n  [\"text\",\" ((\"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\") (\"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"20\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"    (\"],\n  [\"identifier\",\"display\"],\n  [\"text\",\" (+ \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"  ) \"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string\",\"\\\"asdad\"],\n  [\"constant.character.escape.scheme\",\"\\\\0\"],\n  [\"string\",\"eqweqe\\\"\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_scrypt.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// https://github.com/sCrypt-Inc/boilerplate/blob/master/contracts/ackermann.scrypt\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"contract\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Ackermann\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\"; \"],\n  [\"comment\",\"// a = 2\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"b\"],\n  [\"text\",\"; \"],\n  [\"comment\",\"// b = 1\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"static\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"const\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"LOOPCOUNT\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"14\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ackermann\"],\n  [\"lparen\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function\",\"bytes\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"num2bin\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// run this function off chain to get the loop count and set it here\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// e.g., (2, 1) requires 14 loops, (3, 5) 42438\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"loop\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"LOOPCOUNT\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"support.function.math.scrypt\",\"len\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"stk\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"support.function\",\"bytes\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"top\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"unpack\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"top\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"comment\",\"// pop\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"len\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"stk\"],\n  [\"rparen\",\")]\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"n\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"n\"],\n  [\"keyword.operator\",\"++\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"m\"],\n  [\"keyword.operator\",\"--\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"comment\",\"// push\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"num2bin\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"num2bin\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.math.scrypt\",\"num2bin\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"1\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stk\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                    \"],\n  [\"identifier\",\"n\"],\n  [\"keyword.operator\",\"--\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"n\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"// y = 5\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"function\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"unlock\"],\n  [\"lparen\",\"(\"],\n  [\"support.function\",\"int\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"y\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"require\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"y\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"this\"],\n  [\"punctuation.separator.period.scrypt\",\".\"],\n  [\"entity.name.function.scrypt\",\"ackermann\"],\n  [\"punctuation.definition.parameters.begin.bracket.round.scrypt\",\"(\"],\n  [\"start\",\"this.a, this.b\"],\n  [\"punctuation.definition.parameters.end.bracket.round.scrypt\",\")\"],\n  [\"rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_scss.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"/* style.scss */\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.language\",\"#navbar\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"800px\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$items\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"#ce4dd6\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"width\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"border-bottom\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"2px\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"solid\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.language\",\"li\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"float\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"left\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"width\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\"/\"],\n  [\"variable\",\"$items\"],\n  [\"text\",\" \"],\n  [\"constant\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10px\"],\n  [\"text\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"background-color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"20%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        &\"],\n  [\"variable.language\",\":hover\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"support.type\",\"background-color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"10%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sh.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"#!/bin/sh\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"# Script to open a browser to current branch\"]\n],[\n   \"start\",\n  [\"comment\",\"# Repo formats:\"]\n],[\n   \"start\",\n  [\"comment\",\"# ssh   git@github.com:richo/gh_pr.git\"]\n],[\n   \"start\",\n  [\"comment\",\"# http  https://richoH@github.com/richo/gh_pr.git\"]\n],[\n   \"start\",\n  [\"comment\",\"# git   git://github.com/richo/gh_pr.git\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable\",\"username\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"identifier\",\"git\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"config\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"--\"],\n  [\"identifier\",\"get\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"github\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"user\"],\n  [\"keyword.operator\",\"`\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function\",\"get_repo()\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"git\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"remote\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"v\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"grep\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$\"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"@\"],\n  [\"keyword.operator\",\":-\"],\n  [\"variable\",\"$username\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"while\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"read\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"remote\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"do\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"repo\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$remote\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"grep\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"E\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"git@github.com:[^ ]*\"],\n  [\"string.end\",\"\\\"\"],\n  [\"keyword.operator\",\"`\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$repo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sed\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s/^git@github\\\\.com://\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s/\\\\.git$//\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"exit\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"fi\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"repo\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$remote\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"grep\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"E\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"https?://([^@]*@)?github.com/[^ ]*\\\\.git\"],\n  [\"string.end\",\"\\\"\"],\n  [\"keyword.operator\",\"`\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$repo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sed\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s|^https?://||\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s/^.*github\\\\.com\\\\///\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s/\\\\.git$//\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"exit\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"fi\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"repo\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$remote\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"grep\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"E\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"o\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"git://github.com/[^ ]*\\\\.git\"],\n  [\"string.end\",\"\\\"\"],\n  [\"keyword.operator\",\"`\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$repo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sed\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s|^git://github.com/||\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"e\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"s/\\\\.git$//\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"          \"],\n  [\"support.function.builtin\",\"exit\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"keyword\",\"fi\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"done\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$?\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"eq\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Couldn't find a valid remote\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"support.function\",\"&2\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"support.function.builtin\",\"exit\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"fi\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$\"],\n  [\"paren.lparen\",\"{\"],\n  [\"keyword.operator\",\"#\"],\n  [\"variable\",\"x\"],\n  [\"paren.lparen\",\"[\"],\n  [\"text\",\"@\"],\n  [\"paren.rparen\",\"]}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"variable\",\"repo\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"identifier\",\"get_repo\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$@\"],\n  [\"keyword.operator\",\"`\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"branch\"],\n  [\"keyword.operator\",\"=`\"],\n  [\"identifier\",\"git\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"symbolic\"],\n  [\"keyword.operator\",\"-\"],\n  [\"identifier\",\"ref\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"HEAD\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"keyword.operator\",\">/\"],\n  [\"identifier\",\"dev\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"null\"],\n  [\"keyword.operator\",\"`\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.builtin\",\"echo\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"http://github.com/\"],\n  [\"variable\",\"$repo\"],\n  [\"string\",\"/pull/new/\"],\n  [\"variable\",\"$\"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable\",\"branch\"],\n  [\"keyword.operator\",\"##\"],\n  [\"identifier\",\"refs\"],\n  [\"keyword.operator\",\"/\"],\n  [\"identifier\",\"heads\"],\n  [\"keyword.operator\",\"/\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.function.builtin\",\"exit\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"keyword\",\"fi\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sjs.json",
    "content": "[[\n   \"start\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"each\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"map\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"require\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'sjs:sequence'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"get\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"require\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'sjs:http'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"items\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"nada\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"component\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"name\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Ace\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"role\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Editor\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"qqstring\",\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"\"]\n],[\n   [\"qqstring\",\"no_regex\"],\n  [\"string\",\"        Welcome, \"],\n  [\"paren.lparen\",\"#{\"],\n  [\"identifier\",\"component\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"name\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"no_regex\"],\n  [\"string\",\"    \\\"\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"trim\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"logging\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"debug\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"`Component added: \"],\n  [\"paren.lparen\",\"$\"],\n  [\"identifier\",\"String\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"component\"],\n  [\"paren.rparen\",\")\"],\n  [\"string\",\" (\"],\n  [\"paren.lparen\",\"${\"],\n  [\"identifier\",\"component\"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\")`\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"]\n],[\n   [\"bstring\",\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"console\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.firebug\",\"log\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"`\"]\n],[\n   [\"string_interp\",\"string_interp\",\"bstring\",\"no_regex\"],\n  [\"string\",\"        Welcome, {\"],\n  [\"paren.lparen\",\"${\"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\"() \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"string_interp\",\"string_interp\",\"bstring\",\"no_regex\"],\n  [\"text\",\"            \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\", \"],\n  [\"identifier\",\"y\"],\n  [\"text\",\": \"],\n  [\"string\",\"\\\"why?}\\\"\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\";\"]\n],[\n   [\"bstring\",\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\"()\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"no_regex\"],\n  [\"string\",\"    `\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"trim\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"keyword\",\"waitfor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"identifier\",\"items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"..\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"each\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"par\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"|\"],\n  [\"variable.parameter\",\"item\"],\n  [\"paren.rparen\",\"|\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"            \"],\n  [\"keyword\",\"get\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"item\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"and\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"lengths\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"..\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"map\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"i\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"->\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.constant\",\"length\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"or\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"variable.language\",\"hold\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1500\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"        \"],\n  [\"keyword\",\"throw\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"Error\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"timed out\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   [\"no_regex\"],\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   [\"no_regex\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\"\\t\"],\n  [\"comment\",\"// Real Tab.\"]\n],[\n   [\"no_regex\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_slim.json",
    "content": "[[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"doctype html\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"html\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"  head\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    title\"],\n  [\"text\",\" Slim Examples\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    meta\"],\n  [\"text\",\" name\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"keywords\\\"\"],\n  [\"text\",\" content\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"template language\\\"\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    meta\"],\n  [\"text\",\" name\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"author\\\"\"],\n  [\"text\",\" content\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"text\",\"author\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    link\"],\n  [\"text\",\" rel\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"icon\\\"\"],\n  [\"text\",\" type\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"image/png\\\"\"],\n  [\"text\",\" href\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"text\",\"file_path\"],\n  [\"paren\",\"(\"],\n  [\"string\",\"\\\"favicon.png\\\"\"],\n  [\"paren\",\")\"]\n],[\n   [\"language-embed\",[],[\"    \",\"javascript\"],\"start\"],\n  [\"keyword\",\"    javascript:\"]\n],[\n   [\"language-embed\",\"no_regex\",[\"    \",\"javascript\"],\"start\"],\n  [\"text\",\"    \"],\n  [\"text\",\"    \"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'Slim supports embedded javascript!'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"  body\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    h1\"],\n  [\"text\",\" Markup examples\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.slim\",\"    #content\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"      p\"],\n  [\"text\",\" This example shows you how a basic Slim file looks.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"    ==\"],\n  [\"text\",\" \"],\n  [\"list.ruby.operators.slim\",\"yield\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"    -\"],\n  [\"text\",\" \"],\n  [\"list.ruby.operators.slim\",\"if\"],\n  [\"text\",\" items.any?\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"      table#items\"]\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"        -\"],\n  [\"text\",\" \"],\n  [\"list.ruby.operators.slim\",\"for\"],\n  [\"text\",\" item \"],\n  [\"list.ruby.operators.slim\",\"in\"],\n  [\"text\",\" items\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"          tr\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"            td.name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"text\",\" item.name\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"            td.price\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"text\",\" item.price\"]\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"    -\"],\n  [\"text\",\" \"],\n  [\"list.ruby.operators.slim\",\"else\"]\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"      p\"],\n  [\"text\",\" No items found. Please add some inventory.\"]\n],[\n   \"start\",\n  [\"text\",\"        Thank you!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.html.tags.slim\",\"    div\"],\n  [\"text\",\" id\"],\n  [\"keyword.operator.equals.slim\",\"=\"],\n  [\"string\",\"\\\"footer\\\"\"]\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"      ==\"],\n  [\"text\",\" render \"],\n  [\"string\",\"'footer'\"]\n],[\n   [\"mlString\",6],\n  [\"string\",\"      | Copyright &copy; #{@year} #{@author}\"]\n],[\n   [\"mlString\",6],\n  [\"indent\",\"        \"],\n  [\"string\",\"indenting test\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.control.slim\",\"    -\"],\n  [\"text\",\" \"],\n  [\"class.variable.slim\",\"@page_current\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.ruby.embedded.slim\",\"=\"],\n  [\"text\",\" \"],\n  [\"list.meta.slim\",\"true\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_smarty.json",
    "content": "[[\n   \"start\",\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"keyword.control.smarty\",\"foreach\"],\n  [\"source.smarty\",\" \"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"foo\"],\n  [\"source.smarty\",\" as \"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zig\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zag\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zig2\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zag2\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zig3\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"punctuation.definition.variable.smarty\",\"$\"],\n  [\"variable.other.smarty\",\"bar\"],\n  [\"source.smarty\",\".zag3\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"keyword.control.smarty\",\"foreachelse\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  There were no rows found.\"]\n],[\n   \"start\",\n  [\"punctuation.section.embedded.begin.smarty\",\"{\"],\n  [\"source.smarty\",\"/\"],\n  [\"keyword.control.smarty\",\"foreach\"],\n  [\"punctuation.section.embedded.end.smarty\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_smithy.json",
    "content": "[[\n   \"start\",\n  [\"keyword.statement.smithy\",\"namespace\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.namespace.smithy\",\"example.weather\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.block.documentation.smithy\",\"/// Provides weather forecasts.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"paginated\"],\n  [\"text\",\"(\"],\n  [\"support.type.property-name.smithy\",\"inputToken\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\":\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"nextToken\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"support.type.property-name.smithy\",\"outputToken\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\":\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"nextToken\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"support.type.property-name.smithy\",\"pageSize\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\":\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"pageSize\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"service\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"Weather\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"version\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"2006-03-01\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"resources\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.array.begin.smithy\",\"[\"],\n  [\"storage.type.smithy\",\"City\"],\n  [\"punctuation.definition.array.end.smithy\",\"]\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"operations\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.array.begin.smithy\",\"[\"],\n  [\"storage.type.smithy\",\"GetCurrentTime\"],\n  [\"punctuation.definition.array.end.smithy\",\"]\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"resource\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"City\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"identifiers\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"],\n  [\"meta.structure.dictionary.smithy\",\" \"],\n  [\"support.type.property-name.smithy\",\"cityId\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityId\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"read\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetCity\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"list\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"ListCities\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"resources\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.array.begin.smithy\",\"[\"],\n  [\"storage.type.smithy\",\"Forecast\"],\n  [\"punctuation.definition.array.end.smithy\",\"]\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"resource\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"Forecast\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"identifiers\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"],\n  [\"meta.structure.dictionary.smithy\",\" \"],\n  [\"support.type.property-name.smithy\",\"cityId\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityId\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"read\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetForecast\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// \\\"pattern\\\" is a trait.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"pattern\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"^[A-Za-z0-9 ]+$\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"keyword.statement.smithy\",\"string\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"CityId\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"readonly\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"storage.type.smithy\",\"operation\"],\n  [\"text\",\" \"],\n  [\"storage.type.smithy\",\"GetCity\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"input\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetCityInput\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"output\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetCityOutput\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"errors\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"punctuation.definition.array.begin.smithy\",\"[\"],\n  [\"storage.type.smithy\",\"NoSuchResource\"],\n  [\"punctuation.definition.array.end.smithy\",\"]\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"GetCityInput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"comment.line.double-slash.smithy\",\"// \\\"cityId\\\" provides the identifier for the resource and\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"comment.line.double-slash.smithy\",\"// has to be marked as required.\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"cityId\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityId\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"GetCityOutput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"comment.line.double-slash.smithy\",\"// \\\"required\\\" is used on output to indicate if the service\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"comment.line.double-slash.smithy\",\"// will always provide a value for the member.\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"name\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"String\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"coordinates\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityCoordinates\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// This structure is nested within GetCityOutput.\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"CityCoordinates\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"latitude\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"Float\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"longitude\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"Float\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// \\\"error\\\" is a trait that is used to specialize\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// a structure as an error.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"error\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"client\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"NoSuchResource\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"resourceType\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"String\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// The paginated trait indicates that the operation may\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// return truncated results.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"readonly\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"paginated\"],\n  [\"text\",\"(\"],\n  [\"support.type.property-name.smithy\",\"items\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\":\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.smithy\",\"\\\"\"],\n  [\"string.quoted.double.smithy\",\"items\"],\n  [\"punctuation.definition.string.end.smithy\",\"\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"storage.type.smithy\",\"operation\"],\n  [\"text\",\" \"],\n  [\"storage.type.smithy\",\"ListCities\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"input\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"ListCitiesInput\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"output\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"ListCitiesOutput\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"ListCitiesInput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"nextToken\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"String\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"pageSize\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"Integer\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"ListCitiesOutput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"nextToken\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"String\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"items\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CitySummaries\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// CitySummaries is a list of CitySummary structures.\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"list\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"CitySummaries\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"member\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CitySummary\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// CitySummary contains a reference to a City.\"]\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"references\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.array.begin.smithy\",\"[\"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"],\n  [\"support.type.property-name.smithy\",\"resource\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"City\"],\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"],\n  [\"punctuation.definition.array.end.smithy\",\"]\"],\n  [\"text\",\")\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"CitySummary\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"cityId\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityId\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"name\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"String\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"readonly\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"storage.type.smithy\",\"operation\"],\n  [\"text\",\" \"],\n  [\"storage.type.smithy\",\"GetCurrentTime\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"output\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetCurrentTimeOutput\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"GetCurrentTimeOutput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"time\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"Timestamp\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"readonly\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"storage.type.smithy\",\"operation\"],\n  [\"text\",\" \"],\n  [\"storage.type.smithy\",\"GetForecast\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"input\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetForecastInput\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"output\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"GetForecastOutput\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// \\\"cityId\\\" provides the only identifier for the resource since\"]\n],[\n   \"start\",\n  [\"comment.line.double-slash.smithy\",\"// a Forecast doesn't have its own.\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"GetForecastInput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"punctuation.definition.annotation.smithy\",\"@\"],\n  [\"storage.type.annotation.smithy\",\"required\"]\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"cityId\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"CityId\"],\n  [\"punctuation.separator.dictionary.pair.smithy\",\",\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.dictionary.begin.smithy\",\n  [\"keyword.statement.smithy\",\"structure\"],\n  [\"text\",\" \"],\n  [\"entity.name.type.smithy\",\"GetForecastOutput\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.dictionary.begin.smithy\",\"{\"]\n],[\n   [\"punctuation.separator.dictionary.key-value.smithy\",\"punctuation.definition.dictionary.begin.smithy\"],\n  [\"meta.structure.dictionary.smithy\",\"    \"],\n  [\"support.type.property-name.smithy\",\"chanceOfRain\"],\n  [\"punctuation.separator.dictionary.key-value.smithy\",\":\"],\n  [\"meta.structure.dictionary.value.smithy\",\" \"],\n  [\"storage.type.smithy\",\"Float\"]\n],[\n   \"start\",\n  [\"punctuation.definition.dictionary.end.smithy\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_snippets.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# Function\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"snippet\"],\n  [\"text\",\" fun\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\tfunction \"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"?:function_name\"],\n  [\"markup.list\",\"}\"],\n  [\"text\",\"(\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"argument\"],\n  [\"markup.list\",\"}\"],\n  [\"text\",\") {\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\\t\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"3\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"// body...\"],\n  [\"markup.list\",\"}\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t}\"]\n],[\n   \"start\",\n  [\"comment\",\"# Anonymous Function\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"regex \"],\n  [\"keyword\",\"/\"],\n  [\"text\",\"((=)\\\\s*|(:)\\\\s*|(\\\\()|\\\\b)\"],\n  [\"keyword\",\"/\"],\n  [\"text\",\"f\"],\n  [\"keyword\",\"/\"],\n  [\"text\",\"(\\\\))?\"],\n  [\"keyword\",\"/\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"name\"],\n  [\"text\",\" f\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\tfunction\"],\n  [\"markup.list\",\"${\"],\n  [\"variable\",\"M1\"],\n  [\"text\",\"?: \"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"functionName\"],\n  [\"markup.list\",\"}}\"],\n  [\"text\",\"(\"],\n  [\"variable\",\"$2\"],\n  [\"text\",\") {\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\\t\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"$TM_SELECTED_TEXT\"],\n  [\"markup.list\",\"}\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t}\"],\n  [\"markup.list\",\"${\"],\n  [\"variable\",\"M2\"],\n  [\"text\",\"?;\"],\n  [\"markup.list\",\"}${\"],\n  [\"variable\",\"M3\"],\n  [\"text\",\"?,\"],\n  [\"markup.list\",\"}${\"],\n  [\"variable\",\"M4\"],\n  [\"text\",\"?)\"],\n  [\"markup.list\",\"}\"]\n],[\n   \"start\",\n  [\"comment\",\"# Immediate function\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"trigger\"],\n  [\"text\",\" \\\\(?f\\\\(\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"endTrigger\"],\n  [\"text\",\" \\\\)?\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"snippet\"],\n  [\"text\",\" f(\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t(function(\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"1\"],\n  [\"markup.list\",\"}\"],\n  [\"text\",\") {\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\\t\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\":\"],\n  [\"markup.list\",\"${\"],\n  [\"keyword\",\"TM_SELECTED_TEXT\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"/* code */\"],\n  [\"markup.list\",\"}}\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t}(\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"1\"],\n  [\"markup.list\",\"}\"],\n  [\"text\",\"));\"]\n],[\n   \"start\",\n  [\"comment\",\"# if\"]\n],[\n   \"start\",\n  [\"constant.language.escape\",\"snippet\"],\n  [\"text\",\" if\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\tif (\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\"true\"],\n  [\"markup.list\",\"}\"],\n  [\"text\",\") {\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\\t\"],\n  [\"markup.list\",\"${\"],\n  [\"constant.numeric\",\"0\"],\n  [\"markup.list\",\"}\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t}\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\"]\n],[\n   \"sn-start\",\n  [\"text\",\"\\t\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_soy_template.json",
    "content": "[[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"punctuation.definition.comment.begin.soy\",\"/**\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * Greets a person using \\\"Hello\\\" by default.\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * \"],\n  [\"support.type.soy\",\"@param\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.soy\",\"name\"],\n  [\"comment.block.documentation.soy\",\" The name of the person.\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * \"],\n  [\"support.type.soy\",\"@param?\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.soy\",\"greetingWord\"],\n  [\"comment.block.documentation.soy\",\" Optional greeting word to use instead of \\\"Hello\\\".\"]\n],[\n   \"start\",\n  [\"comment.block.documentation.soy\",\" \"],\n  [\"punctuation.definition.comment.end.soy\",\"*/\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"template\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.soy\",\".helloName\"],\n  [\"meta.tag.template.soy\",\" #eee\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"if\"],\n  [\"meta.tag.if.soy\",\" \"],\n  [\"keyword.operator.soy\",\"not\"],\n  [\"meta.tag.if.soy\",\" \"],\n  [\"variable.other.soy\",\"$greetingWord\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    Hello \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"variable.other.soy\",\"$name\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"],\n  [\"text.xml\",\"!\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"text\",\"else\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"variable.other.soy\",\"$greetingWord\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"],\n  [\"text.xml\",\" \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"variable.other.soy\",\"$name\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"],\n  [\"text.xml\",\"!\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"entity.name.tag.soy\",\"if\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"meta.tag.template.soy\",\"template\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"punctuation.definition.comment.begin.soy\",\"/**\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * Greets a person and optionally a list of other people.\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * \"],\n  [\"support.type.soy\",\"@param\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.soy\",\"name\"],\n  [\"comment.block.documentation.soy\",\" The name of the person.\"]\n],[\n   \"punctuation.definition.comment.begin.soy1\",\n  [\"comment.block.documentation.soy\",\" * \"],\n  [\"support.type.soy\",\"@param\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.soy\",\"additionalNames\"],\n  [\"comment.block.documentation.soy\",\" The additional names to greet. May be an empty list.\"]\n],[\n   \"start\",\n  [\"comment.block.documentation.soy\",\" \"],\n  [\"punctuation.definition.comment.end.soy\",\"*/\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"template\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.soy\",\".helloNames\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"comment.line.double-slash.soy\",\"//\"],\n  [\"comment.line.double-slash.soy\",\" Greet the person.\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"call\"],\n  [\"variable.parameter.soy\",\" .helloName\"],\n  [\"meta.tag.call.soy\",\" \"],\n  [\"entity.other.attribute-name.soy\",\"data\"],\n  [\"keyword.operator.soy\",\"=\"],\n  [\"string.quoted.double\",\"\\\"all\\\"\"],\n  [\"meta.tag.call.soy\",\" /\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"br\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"comment.line.double-slash.soy\",\"//\"],\n  [\"comment.line.double-slash.soy\",\" Greet the additional people.\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"foreach\"],\n  [\"meta.tag.foreach.soy\",\" \"],\n  [\"variable.other.soy\",\"$additionalName\"],\n  [\"meta.tag.foreach.soy\",\" \"],\n  [\"keyword.operator.soy\",\"in\"],\n  [\"meta.tag.foreach.soy\",\" \"],\n  [\"variable.other.soy\",\"$additionalNames\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"call\"],\n  [\"variable.parameter.soy\",\" .helloName\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"param\"],\n  [\"meta.tag.param.soy\",\" \"],\n  [\"entity.other.attribute-name.soy\",\"name\"],\n  [\"keyword.operator.soy\",\":\"],\n  [\"meta.tag.param.soy\",\" \"],\n  [\"variable.other.soy\",\"$additionalName\"],\n  [\"meta.tag.param.soy\",\" /\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"meta.tag.call.soy\",\"call\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"if\"],\n  [\"meta.tag.if.soy\",\" \"],\n  [\"keyword.operator.soy\",\"not\"],\n  [\"meta.tag.if.soy\",\" \"],\n  [\"support.function.soy\",\"isLast\"],\n  [\"meta.tag.if.soy\",\"(\"],\n  [\"variable.other.soy\",\"$additionalName\"],\n  [\"meta.tag.if.soy\",\")\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"br\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"  \"],\n  [\"comment.line.double-slash.soy\",\"//\"],\n  [\"comment.line.double-slash.soy\",\" break after every line except the last\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"entity.name.tag.soy\",\"if\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"text\",\"ifempty\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    No additional people to greet.\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"entity.name.tag.soy\",\"foreach\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"meta.tag.template.soy\",\"template\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"entity.name.tag.soy\",\"foreach\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"if\"],\n  [\"meta.tag.if.soy\",\" \"],\n  [\"support.function.soy\",\"length\"],\n  [\"meta.tag.if.soy\",\"(\"],\n  [\"variable.other.soy\",\"$items\"],\n  [\"meta.tag.if.soy\",\") > 5\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"msg\"],\n  [\"meta.tag.msg.soy\",\" \"],\n  [\"entity.other.attribute-name.soy\",\"desc\"],\n  [\"keyword.operator.soy\",\"=\"],\n  [\"string.quoted.double\",\"\\\"Says hello to the user.\\\"\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"namespace\"],\n  [\"text\",\" \"],\n  [\"variable.parameter.soy\",\"ns\"],\n  [\"text\",\" autoescape=\\\"contextual\\\"\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.begin.soy\",\"/**\"],\n  [\"comment.block.documentation.soy\",\" Example. \"],\n  [\"punctuation.definition.comment.end.soy\",\"*/\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"entity.name.tag.soy\",\"template\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.soy\",\".example\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  foo is \"],\n  [\"punctuation.definition.tag.begin.soy\",\"{\"],\n  [\"variable.other.soy\",\"$ij.foo\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n],[\n   \"start\",\n  [\"punctuation.definition.tag.begin.soy\",\"{/\"],\n  [\"meta.tag.template.soy\",\"template\"],\n  [\"punctuation.definition.tag.end.soy\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_space.json",
    "content": "[[\n   \"start\",\n  [\"variable\",\"query\"]\n],[\n   \"start\",\n  [\"empty_line\",\" \"],\n  [\"variable\",\"count\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"10\"]\n],[\n   \"start\",\n  [\"empty_line\",\" \"],\n  [\"variable\",\"created\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"2011-06-21T08:10:46Z\"]\n],[\n   \"start\",\n  [\"empty_line\",\" \"],\n  [\"variable\",\"lang\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"en-US\"]\n],[\n   \"start\",\n  [\"empty_line\",\" \"],\n  [\"variable\",\"results\"]\n],[\n   \"start\",\n  [\"empty_line\",\"  \"],\n  [\"variable\",\"photo\"]\n],[\n   \"start\",\n  [\"empty_line\",\"   \"],\n  [\"variable\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"farm\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"6\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"id\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5855620975\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfamily\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfriend\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"ispublic\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"owner\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"32021554@N04\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"secret\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"f1f5e8515d\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"server\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5110\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"7087 bandit cat\"]\n],[\n   \"start\",\n  [\"empty_line\",\"   \"],\n  [\"variable\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"farm\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"4\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"id\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5856170534\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfamily\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfriend\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"ispublic\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"owner\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"32021554@N04\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"secret\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"ff1efb2a6f\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"server\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"3217\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"6975 rusty cat\"]\n],[\n   \"start\",\n  [\"empty_line\",\"   \"],\n  [\"variable\",\"2\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"farm\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"6\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"id\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5856172972\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfamily\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfriend\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"ispublic\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"owner\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"51249875@N03\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"secret\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"6c6887347c\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"server\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5192\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"watermarked-cats\"]\n],[\n   \"start\",\n  [\"empty_line\",\"   \"],\n  [\"variable\",\"3\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"farm\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"6\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"id\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5856168328\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfamily\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfriend\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"ispublic\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"owner\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"32021554@N04\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"secret\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0c1cfdf64c\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"server\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5078\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"7020 mandy cat\"]\n],[\n   \"start\",\n  [\"empty_line\",\"   \"],\n  [\"variable\",\"4\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"farm\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"3\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"id\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"5856171774\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfamily\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"isfriend\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"0\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"ispublic\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"1\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"owner\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"32021554@N04\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"secret\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"7f5a3180ab\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"server\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"2696\"]\n],[\n   \"start\",\n  [\"empty_line\",\"    \"],\n  [\"variable\",\"title\"],\n  [\"keyword.operator\",\" \"],\n  [\"string\",\"7448 bobby cat\"]\n],[\n   \"key\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sparql.json",
    "content": "[[\n   \"start\",\n  [\"keyword.other.sparql\",\"PREFIX\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.sparql\",\"dbpedia-owl:\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.logical.sparql\",\"<\"],\n  [\"entity.name.other.qname.sparql\",\"http:\"],\n  [\"keyword.operator.logical.sparql\",\"//\"],\n  [\"text\",\"dbpedia\"],\n  [\"keyword.operator.punctuation.sparql\",\".\"],\n  [\"text\",\"org\"],\n  [\"keyword.operator.logical.sparql\",\"/\"],\n  [\"text\",\"on\"],\n  [\"keyword.other.sparql\",\"to\"],\n  [\"text\",\"logy\"],\n  [\"keyword.operator.logical.sparql\",\"/>\"]\n],[\n   \"start\",\n  [\"keyword.other.sparql\",\"PREFIX\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.sparql\",\"rdfs:\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.logical.sparql\",\"<\"],\n  [\"entity.name.other.qname.sparql\",\"http:\"],\n  [\"keyword.operator.logical.sparql\",\"//\"],\n  [\"text\",\"www\"],\n  [\"keyword.operator.punctuation.sparql\",\".\"],\n  [\"text\",\"w3\"],\n  [\"keyword.operator.punctuation.sparql\",\".\"],\n  [\"text\",\"org\"],\n  [\"keyword.operator.logical.sparql\",\"/\"],\n  [\"text\",\"2000\"],\n  [\"keyword.operator.logical.sparql\",\"/\"],\n  [\"text\",\"01\"],\n  [\"keyword.operator.logical.sparql\",\"/\"],\n  [\"text\",\"rdf\"],\n  [\"keyword.operator.logical.sparql\",\"-\"],\n  [\"text\",\"schema\"],\n  [\"punctuation.definition.comment.sparql\",\"#\"],\n  [\"comment.line.hash.sparql\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"punctuation.definition.comment.sparql\",\"#\"],\n  [\"comment.line.hash.sparql\",\" 1. Directors of movies starring Brad Pitt\"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.sparql\",\"#\"],\n  [\"comment.line.hash.sparql\",\" Datasource: http://fragments.dbpedia.org/*/en\"]\n],[\n   \"start\",\n  [\"keyword.other.sparql\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"variable.other.sparql\",\"?movie\"],\n  [\"text\",\" \"],\n  [\"variable.other.sparql\",\"?title\"],\n  [\"text\",\" \"],\n  [\"variable.other.sparql\",\"?name\"]\n],[\n   \"start\",\n  [\"keyword.other.sparql\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.sparql\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.other.sparql\",\"?movie\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.sparql\",\"dbpedia-owl:starring\"],\n  [\"text\",\" [ \"],\n  [\"support.type.datatype.rdf.schema.sparql\",\"rdfs:label\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.sparql\",\"\\\"Brad Pitt\\\"\"],\n  [\"keyword.operator.language.suffix.sparql\",\"@\"],\n  [\"constant.language.suffix.sparql\",\"en\"],\n  [\"text\",\" ]\"],\n  [\"keyword.operator.punctuation.sparql\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"         \"],\n  [\"support.type.datatype.rdf.schema.sparql\",\"rdfs:label\"],\n  [\"text\",\" \"],\n  [\"variable.other.sparql\",\"?title\"],\n  [\"keyword.operator.punctuation.sparql\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"         \"],\n  [\"entity.name.other.qname.sparql\",\"dbpedia-owl:director\"],\n  [\"text\",\" [ \"],\n  [\"support.type.datatype.rdf.schema.sparql\",\"rdfs:label\"],\n  [\"text\",\" \"],\n  [\"variable.other.sparql\",\"?name\"],\n  [\"text\",\" ]\"],\n  [\"keyword.operator.punctuation.sparql\",\".\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other.sparql\",\"FILTER\"],\n  [\"text\",\" \"],\n  [\"support.function.sparql\",\"LANG\"],\n  [\"text\",\"MATCHES\"],\n  [\"keyword.operator.punctuation.sparql\",\"(\"],\n  [\"support.function.sparql\",\"LANG\"],\n  [\"keyword.operator.punctuation.sparql\",\"(\"],\n  [\"variable.other.sparql\",\"?title\"],\n  [\"keyword.operator.punctuation.sparql\",\"),\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.sparql\",\"\\\"EN\\\"\"],\n  [\"keyword.operator.punctuation.sparql\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other.sparql\",\"FILTER\"],\n  [\"text\",\" \"],\n  [\"support.function.sparql\",\"LANG\"],\n  [\"text\",\"MATCHES\"],\n  [\"keyword.operator.punctuation.sparql\",\"(\"],\n  [\"support.function.sparql\",\"LANG\"],\n  [\"keyword.operator.punctuation.sparql\",\"(\"],\n  [\"variable.other.sparql\",\"?name\"],\n  [\"keyword.operator.punctuation.sparql\",\"),\"],\n  [\"text\",\"  \"],\n  [\"string.quoted.double.sparql\",\"\\\"EN\\\"\"],\n  [\"keyword.operator.punctuation.sparql\",\")\"]\n],[\n   \"start\",\n  [\"keyword.operator.punctuation.sparql\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sql.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"city\"],\n  [\"text\",\", \"],\n  [\"support.function\",\"COUNT\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"id\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users_count\"]\n],[\n   \"start\",\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"users\"]\n],[\n   \"start\",\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"group_name\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'salesman'\"]\n],[\n   \"start\",\n  [\"keyword\",\"AND\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"created\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"string\",\"'2011-05-21'\"]\n],[\n   \"start\",\n  [\"keyword\",\"GROUP\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"keyword\",\"ORDER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"BY\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"DESC\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_sqlserver.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"-- =============================================\"]\n],[\n   \"start\",\n  [\"comment\",\"-- Author:\\t\\tMorgan Yarbrough\"]\n],[\n   \"start\",\n  [\"comment\",\"-- Create date: 4/27/2015\"]\n],[\n   \"start\",\n  [\"comment\",\"-- Description:\\tTest procedure that shows off language features.\"]\n],[\n   \"start\",\n  [\"comment\",\"-- \\t\\t\\t\\tIncludes non-standard folding with region comments using either\"]\n],[\n   \"start\",\n  [\"comment\",\"-- \\t\\t\\t\\tline comments or block comments (both are demonstrated below).\"]\n],[\n   \"start\",\n  [\"comment\",\"--\\t\\t\\t\\tThis mode imitates SSMS and it designed to be used with SQL Server theme.\"]\n],[\n   \"start\",\n  [\"comment\",\"-- =============================================\"]\n],[\n   \"start\",\n  [\"keyword\",\"CREATE\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"PROCEDURE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dbo\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"TestProcedure\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"comment\",\"--#region parameters\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"@vint\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"INT\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"punctuation\",\",\"],\n  [\"identifier\",\"@vdate\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DATE\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"NULL\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"punctuation\",\",\"],\n  [\"identifier\",\"@vdatetime\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"DATETIME\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"DATEADD\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"dd\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"GETDATE\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"punctuation\",\",\"],\n  [\"identifier\",\"@vvarchar\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"VARCHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"MAX\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"comment\",\"--#endregion\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"AS\"]\n],[\n   \"start\",\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment.start\",\"/*\"],\n  [\"comment\",\"#region set statements \"],\n  [\"comment.end\",\"*/\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"set.statement\",\"SET NOCOUNT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"set.statement\",\"SET XACT_ABORT\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"set.statement\",\"SET QUOTED_IDENTIFIER\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"ON\"],\n  [\"punctuation\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment.start\",\"/*\"],\n  [\"comment\",\"#endregion\"],\n  [\"comment.end\",\"*/\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"doc-start\",\n  [\"text\",\"\\t\"],\n  [\"comment.doc\",\"/**\"]\n],[\n   \"doc-start\",\n  [\n    \"comment.doc.body\",\n    \"\\t * These comments will produce a fold widget\"\n  ]\n],[\n   \"start\",\n  [\n    \"comment.doc.body\",\n    \"\\t \"\n  ],\n  [\n    \"comment.doc\",\n    \"*/\"\n  ]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- folding demonstration\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vint\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"CASE\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"keyword\",\"WHEN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vdate\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"IS\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"NULL\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\\t\"],\n  [\"keyword\",\"THEN\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\"],\n  [\"keyword\",\"ELSE\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\"],\n  [\"keyword\",\"END\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- another folding demonstration\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"IF\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vint\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"BEGIN\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vvarchar\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"one\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"SET\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vint\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"DATEDIFF\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"dd\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vdate\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@vdatetime\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"END\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- this mode handles strings properly\"]\n],[\n   \"string.start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"DECLARE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@sql\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"NVARCHAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"4000\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"N\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"SELECT TOP(1) OrderID \"]\n],[\n   \"string.start\",\n  [\"string\",\"\\t\\t\\t\\t\\t\\t\\t\\t\\tFROM Orders\"]\n],[\n   \"start\",\n  [\"string\",\"\\t\\t\\t\\t\\t\\t\\t\\t\\tWHERE @OrderDate > GETDATE()\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\\t\\t\\t\\t\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- this mode is aware of built in stored procedures \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"EXECUTE\"],\n  [\"text\",\" \"],\n  [\"support.storedprocedure\",\"sp_executesql\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"@sql\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- demonstrating some syntax highlighting\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"SELECT\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Orders\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"OrderID\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation\",\",\"],\n  [\"identifier\",\"Customers\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"CompanyName\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"punctuation\",\",\"],\n  [\"support.function\",\"DATEFROMPARTS\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"YEAR\"],\n  [\"paren.lparen\",\"(\"],\n  [\"support.function\",\"GETDATE\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"AS\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FirstDayOfYear\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"FROM\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Orders\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"constant.language\",\"INNER\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"JOIN\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Customers\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"ON\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Orders\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"CustomerID\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Customers\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"CustomerID\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"WHERE\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CompanyName\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"NOT\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"LIKE\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"%something\"],\n  [\"string.end\",\"'\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"constant.language\",\"OR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CompanyName\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"IS\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"NULL\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"constant.language\",\"OR\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"CompanyName\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"IN\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"bla\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation\",\",\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"nothing\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- this mode includes snippets\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- place your cusor at the end of the line below and trigger auto complete (Ctrl+Space)\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"createpr\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"-- SQL Server allows using keywords as object names (not recommended) as long as they are wrapped in brackets\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"DATABASE\"],\n  [\"text\",\" \"],\n  [\"comment\",\"-- keyword\"]\n],[\n   \"start\",\n  [\"text\",\"\\t[DATABASE] \"],\n  [\"comment\",\"-- not a keyword\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"keyword\",\"END\"]\n],[\n   \"start\"\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_stylus.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"// I'm a comment!\"]\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/*\"]\n],[\n   \"comment\",\n  [\"comment\",\" * Adds the given numbers together.\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"comment\",\n  [\"comment\",\"/*!\"]\n],[\n   \"comment\",\n  [\"comment\",\" * Adds the given numbers together.\"]\n],[\n   \"start\",\n  [\"comment\",\" */\"]\n],[\n   \"start\"\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function.stylus\",\"asdasdasdad\"],\n  [\"text\",\"(\"],\n  [\"text\",\"df, ad\"],\n  [\"keyword.operator.stylus\",\"=\"],\n  [\"constant.numeric\",\"23\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.name.function.stylus\",\"add\"],\n  [\"text\",\"(\"],\n  [\"entity.name.tag.stylus\",\"a\"],\n  [\"text\",\", \"],\n  [\"entity.name.tag.stylus\",\"b\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.stylus\",\"=\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.stylus\",\"a\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"entity.name.tag.stylus\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.stylus\",\"+\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.stylus\",\"b\"]\n],[\n   \"start\",\n  [\"entity.name.function.stylus\",\"green\"],\n  [\"text\",\"(\"],\n  [\"constant.numeric\",\"#0c0\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\" add(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"// => 15\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\" add(\"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"text\",\" add(\"],\n  [\"entity.name.tag.stylus\",\"a\"],\n  [\"text\",\", \"],\n  [\"entity.name.tag.stylus\",\"b\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"entity.language.stylus\",\"    &\"],\n  [\"text\",\"asdasd\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    (\"],\n  [\"variable.language.stylus\",\"arguments\"],\n  [\"text\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.stylus\",\"@sdfsdf\"]\n],[\n   \"start\",\n  [\"entity.other.attribute-name.class.stylus\",\".signatures\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"background-color\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#e0e8e0\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"border\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"keyword\",\"px\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"solid\"],\n  [\"text\",\" grayLighter\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"keyword\",\"px\"],\n  [\"text\",\" grayLightest\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"border-radius\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"keyword\",\"px\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"padding\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"keyword\",\"px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"keyword\",\"px\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string\",\"\\\"adsads\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"margin-left\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"list-style\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"none\"]\n],[\n   \"start\",\n  [\"entity.other.attribute-name.class.stylus\",\".signature\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"list-style\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"none\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"display\"],\n  [\"text\",\": \"],\n  [\"support.constant\",\"inline\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"margin-left\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.operator.stylus\",\">\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.stylus\",\"li\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"display\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"inline\"]\n],[\n   \"start\",\n  [\"keyword.operator.stylus\",\"is\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.stylus\",\"not\"]\n],[\n   \"start\",\n  [\"entity.other.attribute-name.class.stylus\",\".signature-values\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"list-style\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"none\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"display\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"inline\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"margin-left\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"entity.language.stylus\",\"  &\"],\n  [\"punctuation\",\":\"],\n  [\"entity.other.attribute-name.pseudo-element.css\",\"before\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"content\"],\n  [\"text\",\" \"],\n  [\"string\",\"'→'\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"margin\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"5\"],\n  [\"keyword\",\"px\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.operator.stylus\",\">\"],\n  [\"text\",\" \"],\n  [\"entity.name.tag.stylus\",\"li\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.stylus\",\"!important\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.stylus\",\"unless\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_svg.json",
    "content": "[[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"svg\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"  \"],\n  [\"entity.other.attribute-name.xml\",\"width\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"800\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"height\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"600\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"  \"],\n  [\"entity.other.attribute-name.xml\",\"xmlns\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"http://www.w3.org/2000/svg\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"  \"],\n  [\"entity.other.attribute-name.xml\",\"onload\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"StartAnimation(evt)\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Test Tube Progress Bar\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"desc\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"Created for the Web Directions SVG competition\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"desc\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"js-no_regex\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"type\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"text/ecmascript\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"string.cdata.xml\",\"<![CDATA[\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timer_increment\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"max_time\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"hickory\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dickory\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dock\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\"\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"StartAnimation\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"evt\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"hickory\"],\n  [\"text\",\"  \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"evt\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"target\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"ownerDocument\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"getElementById\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"hickory\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"dickory\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"evt\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"target\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"ownerDocument\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"getElementById\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"dickory\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"dock\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"evt\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"target\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"ownerDocument\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"getElementById\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"dock\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\"\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"ShowAndGrowElement\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"ShowAndGrowElement\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timer_increment\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"max_time\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"return\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// Scale the text string gradually until it is 20 times larger\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"scalefactor\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"650\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"max_time\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\"\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"30\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"hickory\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"display\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"hickory\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"transform\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"translate(\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"600\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"scalefactor\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"3\"],\n  [\"keyword.operator\",\"*-\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\", -144 )\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-no_regex\"\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"30\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"66\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"dickory\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"display\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"dickory\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"transform\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"translate(\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword.operator\",\"-\"],\n  [\"constant.numeric\",\"795\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"scalefactor\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"2\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\", 0 )\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"timevalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"66\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"dock\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"display\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"dock\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"setAttribute\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"transform\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"translate(\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1450\"],\n  [\"keyword.operator\",\"+\"],\n  [\"identifier\",\"scalefactor\"],\n  [\"keyword.operator\",\"*\"],\n  [\"constant.numeric\",\"2\"],\n  [\"keyword.operator\",\"*-\"],\n  [\"constant.numeric\",\"1\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\", 144 )\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-no_regex\"\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"comment\",\"// Call ShowAndGrowElement again <timer_increment> milliseconds later.\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"setTimeout\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"ShowAndGrowElement()\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"timer_increment\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"    \"],\n  [\"variable.language\",\"window\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"ShowAndGrowElement\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"ShowAndGrowElement\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"string.cdata.xml\",\"]]>\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"rect\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"fill\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"#2e3436\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"fill-rule\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"nonzero\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"stroke-width\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"3\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"y\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"0\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"x\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"0\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"height\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"600\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"width\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"800\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"    \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"rect3590\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\"\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"text\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"style\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"x\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"50\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"y\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"350\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"hickory\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"display\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"none\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        Hickory,\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"text\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"text\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"style\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"x\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"50\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"y\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"350\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"dickory\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"display\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"none\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        dickory,\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"text\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"text\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"style\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"x\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"50\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"y\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"350\\\"\"]\n],[\n   \"meta.tag.punctuation.tag-open.xml1\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"dock\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"       \"],\n  [\"entity.other.attribute-name.xml\",\"display\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"none\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        dock!\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"text\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"svg\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_swift.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"import\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"UIKit\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"DetailsViewController\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"UIViewController\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"album\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Album\"],\n  [\"punctuation.operator\",\"?\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.parameter\",\"@IBOutlet\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"weak\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"albumCover\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"UIImageView\"],\n  [\"keyword.operator\",\"!\"]\n],[\n   \"start\",\n  [\"text\",\"     \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"required\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"init\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"coder\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"aDecoder\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NSCoder\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"constant.language\",\"super\"],\n  [\"punctuation.operator\",\".\"],\n  [\"keyword\",\"init\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"coder\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"aDecoder\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"     \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"override\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"func\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"viewDidLoad\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"constant.language\",\"super\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"viewDidLoad\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"mLabel\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"text\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"self\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"album\"],\n  [\"punctuation.operator\",\"?.\"],\n  [\"identifier\",\"title\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&&\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Juhu \"],\n  [\"paren.quasi.start\",\"\\\\(\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"kinners\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.quasi.end\",\")\"],\n  [\"string\",\"! \"],\n  [\"string.end\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"albumCover\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"image\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"UIImage\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"data\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NSData\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"contentsOfURL\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NSURL\"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"self\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"album\"],\n  [\"keyword.operator\",\"!\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"largeImageURL\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"!\"],\n  [\"paren.rparen\",\")\"],\n  [\"keyword.operator\",\"!\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_tcl.json",
    "content": "[[\n   \"commandItem\"\n],[\n   \"commandItem\",\n  [\"keyword\",\"proc\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dijkstra\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"keyword\",\"graph\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"origin\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment\",\"# Initialize\"]\n],[\n   \"commandItem\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"keyword\",\"vertex\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"distmap\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$graph\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$vertex\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Inf\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"path\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$vertex\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$origin\"],\n  [\"text\",\" 0\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"path\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$origin\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"list\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$origin\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"commandItem\",\n  [\"text\",\" \"]\n],[\n   \"commandItem\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"while\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"size\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$graph\"],\n  [\"paren.rparen\",\"]}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Find unhandled node with least weight\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Inf\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"keyword\",\"uu\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"-\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$graph\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable.instance\",\"$d\"],\n  [\"text\",\" \"],\n  [\"support.function\",\">\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dd\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$uu\"],\n  [\"paren.rparen\",\"]]}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"u\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$uu\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$dd\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# No such node; graph must be disconnected\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable.instance\",\"$d\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"==\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Inf\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"break\"]\n],[\n   \"commandItem\",\n  [\"text\",\" \"]\n],[\n   \"commentfollow\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Update the weights for nodes\\\\\"]\n],[\n   \"start\",\n  [\"comment\",\"\\t lead to by the node we've picked\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"keyword\",\"v\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dd\"],\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$graph\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$u\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t    \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"exists\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$graph\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$v\"],\n  [\"paren.rparen\",\"]}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"alt\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"expr\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable.instance\",\"$d\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$dd\"],\n  [\"paren.rparen\",\"}]\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"],\n  [\"variable.instance\",\"$alt\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"<\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$v\"],\n  [\"paren.rparen\",\"]}\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t    \"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$v\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$alt\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t    \"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"path\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$v\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"list\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"{*}\"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"get\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$path\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$u\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$v\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"commandItem\",\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"comment\",\"# Remove chosen node from graph still to be handled\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"dict\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"unset\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"graph\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$u\"]\n],[\n   \"commandItem\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"keyword\",\"list\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$dist\"],\n  [\"text\",\" \"],\n  [\"variable.instance\",\"$path\"],\n  [\"paren.rparen\",\"]\"]\n],[\n   \"commandItem\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_terraform.json",
    "content": "[[\n   \"start\",\n  [\"storage.function.terraform\",\"export\"],\n  [\"text\",\" \"],\n  [\"variable.assignment.terraform\",\"TF_LOG\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"TRACE\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"singleline.comment.terraform\",\"# An AMI\"]\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"variable\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"ami\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"description\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"the AMI to use\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"blockComment\",\n  [\"multiline.comment.begin.terraform\",\"/*\"],\n  [\"comment\",\" A multi\"]\n],[\n   \"start\",\n  [\"comment\",\"   line comment. \"],\n  [\"multiline.comment.end.terraform\",\"*/\"]\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"resource\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"aws_instance\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"ami\"],\n  [\"keyword.operator\",\"               =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"variable.terraform\",\"var.ami\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"count\"],\n  [\"keyword.operator\",\"             =\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.terraform\",\"2\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"source_dest_check\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"constant.language.terraform\",\"false\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"language.support.class\",\"connection\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.assignment.terraform\",\"user\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"root\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"resource\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"aws_instance\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"subnet\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"variable.terraform\",\"var.env\"],\n  [\"punctuation\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"punctuation\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"production\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\" \"],\n  [\"keyword.operator\",\"?\"],\n  [\"punctuation\",\" \"],\n  [\"variable.terraform\",\"var.prod_subnet\"],\n  [\"punctuation\",\" \"],\n  [\"keyword.operator\",\":\"],\n  [\"punctuation\",\" \"],\n  [\"variable.terraform\",\"var.dev_subnet\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"variable\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"count\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"default\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.terraform\",\"2\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"variable\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"hostnames\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"default\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"0\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"example1.org\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"1\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"example2.net\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"data\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"template_file\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web_init\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"singleline.comment.terraform\",\"# Render the template once for each instance\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"count\"],\n  [\"keyword.operator\",\"    =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"keyword.function.terraform\",\"length\"],\n  [\"punctuation\",\"(\"],\n  [\"variable.terraform\",\"var.hostnames\"],\n  [\"punctuation\",\")\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"template\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"keyword.function.terraform\",\"file\"],\n  [\"punctuation\",\"(\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"templates/web_init.tpl\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\")\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  vars \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"singleline.comment.terraform\",\"# count.index tells us the index of the instance we are rendering\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.assignment.terraform\",\"hostname\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"variable.terraform\",\"var.hostnames\"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable.terraform\",\"count.index\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"resource\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"aws_instance\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"singleline.comment.terraform\",\"# Create one instance for each hostname\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"count\"],\n  [\"keyword.operator\",\"     =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"keyword.function.terraform\",\"length\"],\n  [\"punctuation\",\"(\"],\n  [\"variable.terraform\",\"var.hostnames\"],\n  [\"punctuation\",\")\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"singleline.comment.terraform\",\"# Pass each instance its corresponding template_file\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"user_data\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"punctuation\",\"data.template_file.web_init.\"],\n  [\"keyword.operator\",\"*\"],\n  [\"punctuation\",\".rendered\"],\n  [\"paren.lparen\",\"[\"],\n  [\"variable.terraform\",\"count.index\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"variable\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"count\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"default\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.terraform\",\"2\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"singleline.comment.terraform\",\"# Define the common tags for all resources\"]\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"locals {\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"common_tags\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.assignment.terraform\",\"Component\"],\n  [\"keyword.operator\",\"   =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"awesome-app\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.assignment.terraform\",\"Environment\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"production\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"singleline.comment.terraform\",\"# Create a resource that blends the common tags with instance-specific tags.\"]\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"resource\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"aws_instance\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"server\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"ami\"],\n  [\"keyword.operator\",\"           =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"ami-123456\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"instance_type\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"t2.micro\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"tags\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"keyword.function.terraform\",\"merge\"],\n  [\"punctuation\",\"(\"]\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"punctuation\",\"    \"],\n  [\"variable.terraform\",\"local.common_tags\"],\n  [\"punctuation\",\",\"]\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"punctuation\",\"    \"],\n  [\"keyword.function.terraform\",\"map\"],\n  [\"punctuation\",\"(\"]\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"punctuation\",\"      \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"Name\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\", \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"awesome-app-server\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\",\"]\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"punctuation\",\"      \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"Role\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\", \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"server\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   [\"punctuation.interpolated.begin.terraform\",\"punctuation.quote.terraform0\"],\n  [\"punctuation\",\"    )\"]\n],[\n   \"start\",\n  [\"punctuation\",\"  )\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.terraform\",\"$ \"],\n  [\"text\",\"terraform apply \"],\n  [\"keyword.terraform\",\"-var\"],\n  [\"text\",\" \"],\n  [\"variable.assignment.terraform\",\"foo\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"bar \"],\n  [\"keyword.terraform\",\"-var\"],\n  [\"text\",\" \"],\n  [\"variable.assignment.terraform\",\"foo\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"baz\"]\n],[\n   \"variable.terraform\",\n  [\"variable.terraform\",\"$ \"],\n  [\"text\",\"terraform apply \"],\n  [\"keyword.terraform\",\"-var\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"'\"],\n  [\"string\",\"foo={quux=\\\"bar\\\"}\"],\n  [\"punctuation.quote.terraform\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword.terraform\",\"-var\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"'\"],\n  [\"string\",\"foo={bar=\\\"baz\\\"}\"],\n  [\"punctuation.quote.terraform\",\"'\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.terraform\",\"$ \"],\n  [\"text\",\"terraform apply \"],\n  [\"keyword.terraform\",\"-var-file\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"foo.tfvars \"],\n  [\"keyword.terraform\",\"-var-file\"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\"bar.tfvars\"]\n],[\n   \"start\",\n  [\"variable.terraform\",\"$ \"],\n  [\"variable.assignment.terraform\",\"TF_VAR_somemap\"],\n  [\"keyword.operator\",\"=\"],\n  [\"punctuation.quote.terraform\",\"'\"],\n  [\"string\",\"{foo = \\\"bar\\\", baz = \\\"qux\\\"}\"],\n  [\"punctuation.quote.terraform\",\"'\"],\n  [\"text\",\" terraform plan\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.function.terraform\",\"resource\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"aws_instance\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"singleline.comment.terraform\",\"# ...\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"variable.assignment.terraform\",\"count\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"variable.terraform\",\"var.count\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"singleline.comment.terraform\",\"# Tag the instance with a counter starting at 1, ie. web-001\"]\n],[\n   \"start\",\n  [\"text\",\"  tags \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"variable.assignment.terraform\",\"Name\"],\n  [\"keyword.operator\",\" =\"],\n  [\"text\",\" \"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation.interpolated.begin.terraform\",\"${\"],\n  [\"keyword.function.terraform\",\"format\"],\n  [\"punctuation\",\"(\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"string\",\"web-%03d\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"],\n  [\"punctuation\",\", \"],\n  [\"variable.terraform\",\"count.index\"],\n  [\"punctuation\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"punctuation\",\" \"],\n  [\"constant.numeric.terraform\",\"1\"],\n  [\"punctuation\",\")\"],\n  [\"punctuation.interpolated.end.terraform\",\"}\"],\n  [\"punctuation.quote.terraform\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_tex.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"The quadratic formula is $$-b \"],\n  [\"keyword\",\"\\\\pm\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\sqrt\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"text\",\"b^2 - 4ac\"],\n  [\"paren.keyword.operator\",\"}\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\over\"],\n  [\"text\",\" 2a$$\"]\n],[\n   \"start\",\n  [\"keyword\",\"\\\\bye\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"\\\\makeatletter\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\newcommand\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\be\"],\n  [\"paren.keyword.operator\",\"}{\"],\n  [\"comment\",\"%\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\begingroup\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"comment\",\"% \\\\setlength{\\\\arraycolsep}{2pt}\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\eqnarray\"],\n  [\"comment\",\"%\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\@\"],\n  [\"text\",\"ifstar\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\nonumber\"],\n  [\"paren.keyword.operator\",\"}{}\"],\n  [\"comment\",\"%\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"\\\\newcommand\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"keyword\",\"\\\\ee\"],\n  [\"paren.keyword.operator\",\"}{\"],\n  [\"keyword\",\"\\\\endeqnarray\\\\endgroup\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"\\\\makeatother\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\begin\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"equation\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\" x=\"],\n  [\"keyword\",\"\\\\left\"],\n  [\"text\", \"\\\\{ \"],\n  [\"keyword\",\"\\\\begin\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"array\"],\n  [\"paren.keyword.operator\",\"}{\"],\n  [\"text\",\"cl\"],\n  [\"paren.keyword.operator\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\" 0 & \"],\n  [\"keyword\",\"\\\\textrm\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"text\",\"if \"],\n  [\"paren.keyword.operator\",\"}\"],\n  [\"text\",\"A=\"],\n  [\"keyword\",\"\\\\ldots\\\\\\\\\"]\n],[\n   \"start\",\n  [\"text\",\" 1 & \"],\n  [\"keyword\",\"\\\\textrm\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"text\",\"if \"],\n  [\"paren.keyword.operator\",\"}\"],\n  [\"text\",\"B=\"],\n  [\"keyword\",\"\\\\ldots\\\\\\\\\"]\n],[\n   \"start\",\n  [\"text\",\" x & \"],\n  [\"keyword\",\"\\\\textrm\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"text\",\"this runs with as much text as you like, but without an raggeright text\"]\n],[\n   \"start\",\n  [\"text\",\".\"],\n  [\"paren.keyword.operator\",\"}\"],\n  [\"keyword\",\"\\\\end\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"array\"],\n  [\"paren.keyword.operator\",\"}\"],\n  [\"keyword\",\"\\\\right\"],\n  [\"text\",\".\"]\n],[\n   \"start\",\n  [\"text\",\" \"],\n  [\"keyword\",\"\\\\end\"],\n  [\"paren.keyword.operator\",\"{\"],\n  [\"nospell.text\",\"equation\"],\n  [\"paren.keyword.operator\",\"}\"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_text.json",
    "content": "[[\n   \"start\",\n  [\"text\",\"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_textile.json",
    "content": "[[\n   \"start\",\n  [\"markup.heading.1\",\"h1\"],\n  [\"keyword\",\". \"],\n  [\"text\",\"Textile document\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading.2\",\"h2\"],\n  [\"keyword\",\". \"],\n  [\"text\",\"Heading Two\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading.3\",\"h3\"],\n  [\"keyword\",\". \"],\n  [\"text\",\"A two-line\"]\n],[\n   \"start\",\n  [\"text\",\"    header\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading.2\",\"h2\"],\n  [\"keyword\",\". \"],\n  [\"text\",\"Another two-line\"]\n],[\n   \"start\",\n  [\"text\",\"header\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"Paragraph:\"]\n],[\n   \"start\",\n  [\"text\",\"one, two,\"]\n],[\n   \"start\",\n  [\"text\",\"thee lines!\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"p\"],\n  [\"keyword\",\"(\"],\n  [\"string\",\"classone\"],\n  [\"text\",\" \"],\n  [\"string\",\"two\"],\n  [\"text\",\" \"],\n  [\"string\",\"three\"],\n  [\"keyword\",\"). \"],\n  [\"text\",\"This is a paragraph with classes\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"p\"],\n  [\"keyword\",\"(#\"],\n  [\"string\",\"id\"],\n  [\"keyword\",\"). \"],\n  [\"text\",\"(one with an id)\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"markup.heading\",\"p\"],\n  [\"keyword\",\"(\"],\n  [\"string\",\"one\"],\n  [\"text\",\" \"],\n  [\"string\",\"two\"],\n  [\"text\",\" \"],\n  [\"string\",\"three\"],\n  [\"keyword\",\"#\"],\n  [\"string\",\"my_id\"],\n  [\"keyword\",\"). \"],\n  [\"text\",\"..classes + id\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"*\"],\n  [\"text\",\" Unordered list\"]\n],[\n   \"start\",\n  [\"keyword\",\"**\"],\n  [\"text\",\" sublist\"]\n],[\n   \"start\",\n  [\"keyword\",\"*\"],\n  [\"text\",\" back again!\"]\n],[\n   \"start\",\n  [\"keyword\",\"**\"],\n  [\"text\",\" sublist again..\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#\"],\n  [\"text\",\" ordered\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"bg. Blockquote!\"]\n],[\n   \"start\",\n  [\"text\",\"    This is a two-list blockquote..!\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_toml.json",
    "content": "[[\n   \"start\",\n  [\"comment.toml\",\"# This is a TOML document. Boom.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"identifier\",\"title\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"TOML Example\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"[owner]\"]\n],[\n   \"start\",\n  [\"identifier\",\"name\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"Tom Preston-Werner\\\"\"]\n],[\n   \"start\",\n  [\"identifier\",\"organization\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"GitHub\\\"\"]\n],[\n   \"start\",\n  [\"identifier\",\"bio\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"GitHub Cofounder & CEO\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"Likes tater tots and beer.\\\"\"]\n],[\n   \"start\",\n  [\"identifier\",\"dob\"],\n  [\"text\",\" = \"],\n  [\"support.date.toml\",\"1979-05-27T07:32:00Z\"],\n  [\"text\",\" \"],\n  [\"comment.toml\",\"# First class dates? Why not?\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"[database]\"]\n],[\n   \"start\",\n  [\"identifier\",\"server\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"192.168.1.1\\\"\"]\n],[\n   \"start\",\n  [\"identifier\",\"ports\"],\n  [\"text\",\" = [ \"],\n  [\"constant.numeric.toml\",\"8001\"],\n  [\"text\",\", \"],\n  [\"constant.numeric.toml\",\"8001\"],\n  [\"text\",\", \"],\n  [\"constant.numeric.toml\",\"8002\"],\n  [\"text\",\" ]\"]\n],[\n   \"start\",\n  [\"identifier\",\"connection_max\"],\n  [\"text\",\" = \"],\n  [\"constant.numeric.toml\",\"5000\"]\n],[\n   \"start\",\n  [\"identifier\",\"enabled\"],\n  [\"text\",\" = \"],\n  [\"constant.language.boolean\",\"true\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"[servers]\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.toml\",\"# You can indent as you please. Tabs or spaces. TOML don't care.\"]\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"  [servers.alpha]\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"ip\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"10.0.0.1\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"dc\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"eqdc10\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"  [servers.beta]\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"ip\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"10.0.0.2\\\"\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"dc\"],\n  [\"text\",\" = \"],\n  [\"string\",\"\\\"eqdc10\\\"\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"variable.keygroup.toml\",\"[clients]\"]\n],[\n   \"start\",\n  [\"identifier\",\"data\"],\n  [\"text\",\" = [ [\"],\n  [\"string\",\"\\\"gamma\\\"\"],\n  [\"text\",\", \"],\n  [\"string\",\"\\\"delta\\\"\"],\n  [\"text\",\"], [\"],\n  [\"constant.numeric.toml\",\"1\"],\n  [\"text\",\", \"],\n  [\"constant.numeric.toml\",\"2\"],\n  [\"text\",\"] ] \"],\n  [\"comment.toml\",\"# just an update to make sure parsers support it\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_tsv.json",
    "content": "[[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2 long\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"keyword.csv_0\",\"col1\"],\n  [\"keyword.csv_0\",\"\\t\"],\n  [\"keyword.csv_0\",\"with quotes\"],\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"co\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"l4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"broken\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"keyword.csv_0\",\"\\\"\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"-\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"],\n  [\"variable.csv_4\",\"col5\"]\n],[\n   \"string-1\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"text.csv_1\",\"col2\"]\n],[\n   \"string-2\",\n  [\"text.csv_1\",\"multiline\"],\n  [\"text.csv_1\",\"\\\"\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"col3\"]\n],[\n   \"string-2\",\n  [\"string.csv_2\",\"multiline\"],\n  [\"string.csv_2\",\"\\\"\\\"\"],\n  [\"string.csv_2\",\"string\"]\n],[\n   \"string-3\",\n  [\"string.csv_2\",\"3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"\\\"\"],\n  [\"string.regex.csv_3\",\"col4\"]\n],[\n   \"string-3\",\n  [\"string.regex.csv_3\",\"multiline string\"]\n],[\n   \"string-3\"\n],[\n   \"start\",\n  [\"string.regex.csv_3\",\"4\"],\n  [\"string.regex.csv_3\",\"\\\"\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.csv_2\",\"c\"],\n  [\"string.csv_2\",\"\\t\"],\n  [\"string.csv_2\",\"o\"],\n  [\"string.csv_2\",\"\\t\"],\n  [\"string.csv_2\",\"l\"],\n  [\"string.csv_2\",\"\\\"\\\"\"],\n  [\"string.csv_2\",\"3\"],\n  [\"string.csv_2\",\"\\\"\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\"\\t\"],\n  [\"keyword.csv_6\",\"col7\"],\n  [\"text.csv_7.csv_separator\",\"\\t\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\"\\t\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\"\\t\"],\n  [\"variable.csv_10\",\"col11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\"\\t\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\"\\t\"],\n  [\"keyword.csv_6\",\"col7\"],\n  [\"text.csv_7.csv_separator\",\"\\t\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\"\\t\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\"\\t\"],\n  [\"variable.csv_10\",\"col11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\"\\t\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\",\n  [\"keyword.csv_0\",\"col1\"],\n  [\"text.csv_1.csv_separator\",\"\\t\"],\n  [\"text.csv_1\",\"col2\"],\n  [\"string.csv_2.csv_separator\",\"\\t\"],\n  [\"string.csv_2\",\"col3\"],\n  [\"string.regex.csv_3.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_3\",\"col4\"],\n  [\"variable.csv_4.csv_separator\",\"\\t\"],\n  [\"variable.csv_4\",\"col5\"],\n  [\"constant.numeric.csv_5.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_5\",\"col6\"],\n  [\"keyword.csv_6.csv_separator\",\"\\t\"],\n  [\"keyword.csv_6\",\"co\"],\n  [\"keyword.csv_6\",\"\\\"\"],\n  [\"keyword.csv_6\",\"l7\"],\n  [\"text.csv_7.csv_separator\",\"\\t\"],\n  [\"text.csv_7\",\"col8\"],\n  [\"string.csv_8.csv_separator\",\"\\t\"],\n  [\"string.csv_8\",\"col9\"],\n  [\"string.regex.csv_9.csv_separator\",\"\\t\"],\n  [\"string.regex.csv_9\",\"col10\"],\n  [\"variable.csv_10.csv_separator\",\"\\t\"],\n  [\"variable.csv_10\",\"11\"],\n  [\"constant.numeric.csv_11.csv_separator\",\"\\t\"],\n  [\"constant.numeric.csv_11\",\"col12\"],\n  [\"keyword.csv_12.csv_separator\",\"\\t\"],\n  [\"keyword.csv_12\",\"col13\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_tsx.json",
    "content": "[[\n   [\"jsx\",1],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"mode\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\n    \"string.xml\",\n    \" \"\n  ]\n],[\n   [\"jsx\",1],\n  [\n    \"string.xml\",\n    \"    Typescript + \"\n  ],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\n    \"string.xml\",\n    \" JSX \"\n  ],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"b\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\n    \"string.xml\",\n    \" \"\n  ]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"punctuation.operator\",\";\"]\n]]\n"
  },
  {
    "path": "src/mode/_test/tokens_turtle.json",
    "content": "[[\n   \"start\",\n  [\"keyword.other.prefix.turtle\",\"@base\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<http://example.org/>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\",\n  [\"keyword.other.prefix.turtle\",\"@prefix\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.turtle\",\"rdf:\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<http://www.w3.org/1999/02/22-rdf-syntax-ns#>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\",\n  [\"keyword.other.prefix.turtle\",\"@prefix\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.turtle\",\"rdfs:\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<http://www.w3.org/2000/01/rdf-schema#>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\",\n  [\"keyword.other.prefix.turtle\",\"@prefix\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.turtle\",\"foaf:\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<http://xmlns.com/foaf/0.1/>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\",\n  [\"keyword.other.prefix.turtle\",\"@prefix\"],\n  [\"text\",\" \"],\n  [\"entity.name.other.qname.turtle\",\"rel:\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<http://www.perceive.net/schemas/relationship/>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.quoted.other.relative.url.turtle\",\"<#green-goblin>\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.other.qname.turtle\",\"rel:enemyOf\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<#spiderman>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"support.type.datatype.rdf.schema.turtle\",\" a \"],\n  [\"entity.name.other.qname.turtle\",\"foaf:Person\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\";\"],\n  [\"text\",\"    \"],\n  [\"punctuation.definition.comment.turtle\",\"#\"],\n  [\"comment.line.hash.turtle\",\" in the context of the Marvel universe\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.other.qname.turtle\",\"foaf:name\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.turtle\",\"\\\"Green Goblin\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"string.quoted.other.relative.url.turtle\",\"<#spiderman>\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.other.qname.turtle\",\"rel:enemyOf\"],\n  [\"text\",\" \"],\n  [\"string.quoted.other.relative.url.turtle\",\"<#green-goblin>\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"support.type.datatype.rdf.schema.turtle\",\" a \"],\n  [\"entity.name.other.qname.turtle\",\"foaf:Person\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"entity.name.other.qname.turtle\",\"foaf:name\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.turtle\",\"\\\"Spiderman\\\"\"],\n  [\"keyword.operator.punctuation.turtle\",\",\"],\n  [\"text\",\" \"],\n  [\"string.quoted.double.turtle\",\"\\\"Человек-паук\\\"\"],\n  [\"keyword.operator.language.suffix.turtle\",\"@\"],\n  [\"constant.language.suffix.turtle\",\"ru\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.punctuation.turtle\",\".\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_twig.json",
    "content": "[[\n   \"start\",\n  [\"xml-pe.doctype.xml\",\"<!\"],\n  [\"xml-pe.doctype.xml\",\"DOCTYPE\"],\n  [\"text.whitespace.xml\",\" \"],\n  [\"xml-pe.xml\",\"html\"],\n  [\"xml-pe.doctype.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"My Webpage\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"title\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"head\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"navigation\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"for\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"item\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.twig\",\"in\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"navigation\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"href\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"item\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"href\"],\n  [\"keyword.operator.other\",\"|\"],\n  [\"support.function.twig\",\"escape\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"item\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"caption\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.anchor.tag-name.xml\",\"a\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"endfor\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"if\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.twig\",\"not\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.twig\",\"in\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"comment.block.twig\",\"{# is equivalent to #}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"if\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.twig\",\"not\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.twig\",\"in\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"paren.rparen\",\"])\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"autoescape\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"var\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"var\"],\n  [\"keyword.operator.other\",\"|\"],\n  [\"support.function.twig\",\"raw\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"],\n  [\"text.xml\",\"     \"],\n  [\"comment.block.twig\",\"{# var won't be escaped #}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"            \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"var\"],\n  [\"keyword.operator.other\",\"|\"],\n  [\"support.function.twig\",\"escape\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"],\n  [\"text.xml\",\"  \"],\n  [\"comment.block.twig\",\"{# var won't be doubled-escaped #}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.twig\",\"{%\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"endautoescape\"],\n  [\"text\",\" \"],\n  [\"meta.tag.twig\",\"%}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"keyword.control.twig\",\"include\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'twig.html'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"sandboxed\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.assignment\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language.boolean\",\"true\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"string\",\"\\\"string \"],\n  [\"constant.language.escape\",\"#{with}\"],\n  [\"string\",\" \"],\n  [\"constant.language.escape\",\"\\\\\\\"\"],\n  [\"string\",\" escapes\\\"\"],\n  [\"text\",\" \"],\n  [\"string\",\"'another#one'\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"My Webpage\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"h1\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"        \"],\n  [\"variable.other.readwrite.local.twig\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a_variable\"],\n  [\"text\",\" \"],\n  [\"variable.other.readwrite.local.twig\",\"}}\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"body\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"html\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_typescript.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"storage.type.variable.ts\",\" Greeter\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"greeting\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"string\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"constructor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"message\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"string\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"greeting\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"message\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"identifier\",\"greet\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello, \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"greeting\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"],\n  [\"text\",\"   \"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"greeter\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"new\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Greeter\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"world\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"no_regex\",\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"button\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"document\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"createElement\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'button'\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"identifier\",\"button\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"innerText\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"storage.type.variable.ts\",\"string\"],\n  [\"keyword.operator\",\">\"],\n  [\"string\",\"\\\"Say Hello\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"identifier\",\"button\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"onclick\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"no_regex\",\n  [\"text\",\"\\t\"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"greeter\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"greet\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\"))\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"no_regex\",\n  [\"variable.language\",\"document\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"body\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.function.dom\",\"appendChild\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"button\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"storage.type.variable.ts\",\" Snake\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Animal\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"identifier\",\"move\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Slithering...\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"super\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"5\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"   \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"storage.type.variable.ts\",\" Horse\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"extends\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Animal\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"identifier\",\"move\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"\\\"Galloping...\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"super\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"move\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"45\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"   \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Sayings\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"export\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"storage.type.variable.ts\",\" Greeter\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"greeting\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"string\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"constructor\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"message\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"string\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"greeting\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"message\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"greet\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"Hello, \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"greeting\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Mankala\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"   \"],\n  [\"keyword\",\"export\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"class\"],\n  [\"storage.type.variable.ts\",\" Features\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"turnContinues\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"false\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"seedStoredCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"capturedCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"spaceCaptured\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NoSpace\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clear\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"turnContinues\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"false\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"seedStoredCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"capturedCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"spaceCaptured\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"NoSpace\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"       \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\"\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword\",\"public\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"toString\"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stringBuilder\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"turnContinues\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"               \"],\n  [\"identifier\",\"stringBuilder\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" turn continues,\\\"\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"           \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"identifier\",\"stringBuilder\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" stores \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"seedStoredCount\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"capturedCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\">\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"               \"],\n  [\"identifier\",\"stringBuilder\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" captures \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"capturedCount\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\" from space \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"storage.type.variable.ts\",\"this.\"],\n  [\"identifier\",\"spaceCaptured\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"           \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"           \"],\n  [\"keyword\",\"return\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"stringBuilder\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"no_regex\",\n  [\"text\",\"       \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"text\",\"   \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"no_regex\",\n  [\"paren.rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_vala.json",
    "content": "[[\n   \"start\",\n  [\"meta.using.vala\",\"﻿\"],\n  [\"keyword.other.using.vala\",\"using\"],\n  [\"meta.using.vala\",\" \"],\n  [\"storage.modifier.using.vala\",\"Gtk\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"start\",\n  [\"text\",\" \"]\n],[\n   \"text0\",\n  [\"storage.type.primitive.array.vala\",\"int\"],\n  [\"text\",\" main (\"],\n  [\"storage.type.primitive.array.vala\",\"string\"],\n  [\"text\",\"[] args) {\"]\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"storage.type.vala\",\"Gtk\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"init (\"],\n  [\"storage.modifier.vala\",\"ref\"],\n  [\"text\",\" args)\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"storage.type.primitive.vala\",\"var\"],\n  [\"text\",\" foo \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.new.vala\",\"new\"],\n  [\"text\",\" \"],\n  [\"storage.type.generic.vala\",\"MyFoo<string[](), MyBar<string, int>>\"],\n  [\"text\",\"()\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\"\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"storage.type.primitive.vala\",\"var\"],\n  [\"text\",\" window \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.new.vala\",\"new\"],\n  [\"text\",\" \"],\n  [\"storage.type.vala\",\"Window\"],\n  [\"text\",\"()\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"title \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.vala\",\"\\\"\"],\n  [\"string.quoted.double.vala\",\"Hello, World!\"],\n  [\"punctuation.definition.string.end.vala\",\"\\\"\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"border_width \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.vala\",\"10\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"window_position \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type.vala\",\"WindowPosition\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"constant.other.vala\",\"CENTER\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"set_default_size(\"],\n  [\"constant.numeric.vala\",\"350\"],\n  [\"text\",\", \"],\n  [\"constant.numeric.vala\",\"70\"],\n  [\"text\",\")\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"destroy\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"connect(\"],\n  [\"storage.type.vala\",\"Gtk\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"main_quit)\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\" \"]\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"storage.type.primitive.vala\",\"var\"],\n  [\"text\",\" label \"],\n  [\"keyword.operator.assignment.vala\",\"=\"],\n  [\"text\",\" \"],\n  [\"keyword.control.new.vala\",\"new\"],\n  [\"text\",\" \"],\n  [\"storage.type.vala\",\"Label\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.vala\",\"\\\"\"],\n  [\"string.quoted.double.vala\",\"Hello, World!\"],\n  [\"punctuation.definition.string.end.vala\",\"\\\"\"],\n  [\"text\",\")\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\" \"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"add(label)\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    window\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"show_all()\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\" \"]\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"storage.type.vala\",\"Gtk\"],\n  [\"keyword.operator.dereference.vala\",\".\"],\n  [\"text\",\"main()\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"text0\",\n  [\"text\",\"    \"],\n  [\"keyword.control.vala\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.vala\",\"0\"],\n  [\"punctuation.terminator.vala\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_vbscript.json",
    "content": "[[\n   \"start\",\n  [\"identifier\",\"myfilename\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"=\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"C:\\\\Wikipedia - VBScript - Example - Hello World.txt\\\"\"]\n],[\n   \"start\",\n  [\"identifier\",\"MakeHelloWorldFile\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"myfilename\"]\n],[\n   \"state_4\",\n  [\"meta.leading-space\",\" \"]\n],[\n   \"start\",\n  [\"storage.type.function.asp\",\"Sub\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.asp\",\"MakeHelloWorldFile\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.parameters.asp\",\"(\"],\n  [\"variable.parameter.function.asp\",\"FileName\"],\n  [\"punctuation.definition.parameters.asp\",\")\"]\n],[\n   \"start\",\n  [\"punctuation.definition.comment.asp\",\"'\"],\n  [\"comment.line.apostrophe.asp\",\"Create a new file in C: drive or overwrite existing file\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"storage.type.asp\",\"Set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FSO\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.vb.asp\",\"CreateObject\"],\n  [\"text\",\"(\"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"Scripting.FileSystemObject\\\"\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"keyword.control.asp\",\"If\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FSO\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"FileExists\"],\n  [\"text\",\"(\"],\n  [\"identifier\",\"FileName\"],\n  [\"text\",\") \"],\n  [\"keyword.control.asp\",\"Then\"],\n  [\"text\",\" \"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"identifier\",\"Answer\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.vb.asp\",\"MsgBox\"],\n  [\"text\",\" (\"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"File \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FileName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\" exists ... OK to overwrite?\\\"\"],\n  [\"text\",\", \"],\n  [\"support.type.vb.asp\",\"vbOKCancel\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"punctuation.definition.comment.asp\",\"'\"],\n  [\"comment.line.apostrophe.asp\",\"If button selected is not OK, then quit now\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"punctuation.definition.comment.asp\",\"'\"],\n  [\"comment.line.apostrophe.asp\",\"vbOK is a language constant\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"keyword.control.asp\",\"If\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Answer\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"<>\"],\n  [\"text\",\" \"],\n  [\"support.type.vb.asp\",\"vbOK\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Then\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Exit\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Sub\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"keyword.control.asp\",\"Else\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"punctuation.definition.comment.asp\",\"'\"],\n  [\"comment.line.apostrophe.asp\",\"Confirm OK to create\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"identifier\",\"Answer\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"=\"],\n  [\"text\",\" \"],\n  [\"support.function.vb.asp\",\"MsgBox\"],\n  [\"text\",\" (\"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"File \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FileName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\" ... OK to create?\\\"\"],\n  [\"text\",\", \"],\n  [\"support.type.vb.asp\",\"vbOKCancel\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.even-tab.spaces\",\"  \"],\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"keyword.control.asp\",\"If\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Answer\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"<>\"],\n  [\"text\",\" \"],\n  [\"support.type.vb.asp\",\"vbOK\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Then\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Exit\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Sub\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"keyword.control.asp\",\"End\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"If\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"punctuation.definition.comment.asp\",\"'\"],\n  [\"comment.line.apostrophe.asp\",\"Create new file (or replace an existing file)\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"storage.type.asp\",\"Set\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FileObject\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FSO\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"CreateTextFile\"],\n  [\"text\",\" (\"],\n  [\"identifier\",\"FileName\"],\n  [\"text\",\")\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"identifier\",\"FileObject\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"WriteLine\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"Time ... \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"support.function.vb.asp\",\"Now\"],\n  [\"text\",\"()\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"identifier\",\"FileObject\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"WriteLine\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"Hello World\\\"\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"identifier\",\"FileObject\"],\n  [\"text\",\".\"],\n  [\"identifier\",\"Close\"],\n  [\"text\",\"()\"]\n],[\n   \"start\",\n  [\"meta.odd-tab.spaces\",\"  \"],\n  [\"meta.leading-space\",\" \"],\n  [\"support.function.vb.asp\",\"MsgBox\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\"File \\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"FileName\"],\n  [\"text\",\" \"],\n  [\"keyword.operator.asp\",\"&\"],\n  [\"text\",\" \"],\n  [\"punctuation.definition.string.begin.asp\",\"\\\"\"],\n  [\"string.quoted.double.asp\",\" ... updated.\\\"\"]\n],[\n   \"start\",\n  [\"keyword.control.asp\",\"End\"],\n  [\"text\",\" \"],\n  [\"keyword.control.asp\",\"Sub\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_velocity.json",
    "content": "[[\n   \"vm_comment\",\n  [\"comment.block\",\"#*\"]\n],[\n   \"vm_comment\",\n  [\"comment\",\"  This is a sample comment block that\"]\n],[\n   \"vm_comment\",\n  [\"comment\",\"  spans multiple lines.\"]\n],[\n   \"start\",\n  [\"comment\",\"*#\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"#macro\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"outputItem\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$item\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"variable\",\"${\"],\n  [\"identifier\",\"item\"],\n  [\"variable\",\"}\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"li\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword\",\"#end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment\",\"## Define the items to iterate\"]\n],[\n   \"start\",\n  [\"keyword\",\"#set\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"[\"],\n  [\"constant.numeric\",\"1\"],\n  [\"text.xml\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text.xml\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"3\"],\n  [\"text.xml\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"4\"],\n  [\"rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment\",\"## Iterate over the items and output the evens.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"#foreach\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$item\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"in\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$items\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"#if\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"$_MathTool\"],\n  [\"text.xml\",\".\"],\n  [\"identifier\",\"mod\"],\n  [\"lparen\",\"(\"],\n  [\"variable\",\"$item\"],\n  [\"text.xml\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      \"],\n  [\"identifier\",\"#outputItem\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"(\"],\n  [\"variable\",\"$item\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"#end\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"#end\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ul\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"js-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-comment1\",\n  [\"text\",\"  \"],\n  [\"comment\",\"/*\"]\n],[\n   \"js-comment1\",\n  [\"comment\",\"    A sample function to decomstrate\"]\n],[\n   \"js-comment1\",\n  [\"comment\",\"    JavaScript highlighting and folding.\"]\n],[\n   \"js-start\",\n  [\"comment\",\"  */\"]\n],[\n   \"js-start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"foo\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable.parameter\",\"items\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.parameter\",\"nada\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"for\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric\",\"0\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"<\"],\n  [\"identifier\",\"items\"],\n  [\"punctuation.operator\",\".\"],\n  [\"support.constant\",\"length\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"i\"],\n  [\"keyword.operator\",\"++\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"      \"],\n  [\"support.function\",\"alert\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"items\"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"i\"],\n  [\"paren.rparen\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"juhu\"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\"\\\"\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"css-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   [\"css-comment\",\"css-start\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"/*\"]\n],[\n   [\"css-comment\",\"css-start\"],\n  [\"comment\",\"    A sample style to decomstrate\"]\n],[\n   [\"css-comment\",\"css-start\"],\n  [\"comment\",\"    CSS highlighting and folding.\"]\n],[\n   \"css-start\",\n  [\"comment\",\"  */\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"  \"],\n  [\"variable\",\".class\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"font-family\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" Monaco, \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Courier New\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\", \"],\n  [\"support.constant.fonts\",\"monospace\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"font-size\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"12\"],\n  [\"keyword\",\"px\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"cursor\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.constant\",\"text\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"css-start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_verilog.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"always\"],\n  [\"text\",\" @\"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"negedge\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"reset\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"or\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"posedge\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"clk\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"if\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"reset\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"d_out\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"16\"],\n  [\"text\",\"'\"],\n  [\"identifier\",\"h0000\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"d_out_mem\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"resetcount\"],\n  [\"text\",\"] \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d_out\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"laststoredvalue\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d_out\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"else\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"d_out\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d_out\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"text\",\"'\"],\n  [\"identifier\",\"b1\"],\n  [\"text\",\"; \"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"always\"],\n  [\"text\",\" @\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"bufreadaddr\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"bufreadval\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"d_out_mem\"],\n  [\"text\",\"[\"],\n  [\"identifier\",\"bufreadaddr\"],\n  [\"text\",\"];\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"module\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"test\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"assign\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"a\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"1\"],\n  [\"string.end\",\"\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"initial\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"begin\"]\n],[\n   \"string.start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"$display\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Hello \"],\n  [\"constant.language.escape\",\"\\\\77\"],\n  [\"string\",\"8\"],\n  [\"constant.language.escape\",\"\\\\xaa\\\\\"]\n],[\n   \"start\",\n  [\"string\",\"                  \"],\n  [\"constant.language.escape\",\"\\\\n\"],\n  [\"string\",\" world\"],\n  [\"string.end\",\"\\\"\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"$finish\"],\n  [\"text\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"end\"]\n],[\n   \"start\",\n  [\"keyword\",\"endmodule\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_vhdl.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"library\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IEEE\"]\n],[\n   \"start\",\n  [\"identifier\",\"user\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IEEE\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"std_logic_1164\"],\n  [\"punctuation.operator\",\".\"],\n  [\"keyword\",\"all\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"keyword\",\"use\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"IEEE\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"numeric_std\"],\n  [\"punctuation.operator\",\".\"],\n  [\"keyword\",\"all\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"entity\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"COUNT16\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"port\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"cOut\"],\n  [\"text\",\"    \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"out\"],\n  [\"text\",\"    \"],\n  [\"storage.type\",\"std_logic_vector\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"15\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"downto\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"  \"],\n  [\"comment\",\"-- counter output\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"clkEn\"],\n  [\"text\",\"   \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"in\"],\n  [\"text\",\"     \"],\n  [\"storage.type\",\"std_logic\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"                      \"],\n  [\"comment\",\"-- count enable\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"clk\"],\n  [\"text\",\"     \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"in\"],\n  [\"text\",\"     \"],\n  [\"storage.type\",\"std_logic\"],\n  [\"punctuation.operator\",\";\"],\n  [\"text\",\"                      \"],\n  [\"comment\",\"-- clock input\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"identifier\",\"rst\"],\n  [\"text\",\"     \"],\n  [\"punctuation.operator\",\":\"],\n  [\"keyword\",\"in\"],\n  [\"text\",\"     \"],\n  [\"storage.type\",\"std_logic\"],\n  [\"text\",\"                       \"],\n  [\"comment\",\"-- reset input\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"entity\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"architecture\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count_rtl\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"of\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"COUNT16\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"is\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"signal\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"punctuation.operator\",\":\"],\n  [\"storage.type\",\"std_logic_vector\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"15\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"downto\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n],[\n   \"start\",\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"process\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"clk\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"rst\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"begin\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"if\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rst\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'1'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"keyword\",\"others\"],\n  [\"keyword.operator\",\"=>\"],\n  [\"string\",\"'0'\"],\n  [\"paren.rparen\",\")\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"elsif\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"rising_edge\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"clk\"],\n  [\"paren.rparen\",\"))\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"if\"],\n  [\"paren.lparen\",\"(\"],\n  [\"identifier\",\"clkEn\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"'1'\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"then\"]\n],[\n   \"start\",\n  [\"text\",\"                \"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"1\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"            \"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"if\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"        \"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"process\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"cOut\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"count\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"end\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"architecture\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_visualforce.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"apex:stylesheet\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword.start\",\"{!\"],\n  [\"support.function\",\"URLFOR\"],\n  [\"keyword.operator\",\"(\"],\n  [\"variable.language\",\"$Resource\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"BrowserCompatibility\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"css/style.css\"],\n  [\"string.end\",\"'\"],\n  [\"keyword.operator\",\")\"],\n  [\"keyword.end\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\"\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"apex:page\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"action\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword.start\",\"{!\"],\n  [\"support.function\",\"IF\"],\n  [\"keyword.operator\",\"(\"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"JohnDoe\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"||\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"JBloggs\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"||\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"FooBar\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"null\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"text\",\"    \"],\n  [\"identifier\",\"urlFor\"],\n  [\"keyword.operator\",\"(\"],\n  [\"variable.language\",\"$Action\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Account\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Delete\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$CurrentPage\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Parameters\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"id\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"retURL\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"/001\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"true\"],\n  [\"keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"keyword.operator\",\")\"],\n  [\"keyword.end\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"standardController\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Account\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"apex:page\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"apex:page\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"action\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword.start\",\"{!\"],\n  [\"support.function\",\"IF\"],\n  [\"keyword.operator\",\"(\"],\n  [\"support.function\",\"OR\"],\n  [\"keyword.operator\",\"(\"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"JohnDoe\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"JBloggs\"],\n  [\"string.end\",\"'\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$User\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Alias\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"FooBar\"],\n  [\"string.end\",\"'\"],\n  [\"keyword.operator\",\")\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"text\",\"    \"],\n  [\"constant.language\",\"NULL\"],\n  [\"punctuation.operator\",\",\"]\n],[\n   [\"Visualforce\",\"string.attribute-value.xml0\",\"string.attribute-value.xml0\",\"tag_stuff\"],\n  [\"text\",\"    \"],\n  [\"support.function\",\"URLFOR\"],\n  [\"keyword.operator\",\"(\"],\n  [\"variable.language\",\"$Action\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Account\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Delete\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$CurrentPage\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Parameters\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"id\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"identifier\",\"retURL\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"/001\"],\n  [\"string.end\",\"'\"],\n  [\"paren.rparen\",\"]\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"TRUE\"],\n  [\"keyword.operator\",\")\"]\n],[\n   \"start\",\n  [\"keyword.operator\",\")\"],\n  [\"keyword.end\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"standardController\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Account\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"apex:page\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"tag_stuff\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"apex:commandLink\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"action\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"keyword.start\",\"{!\"],\n  [\"support.function\",\"URLFOR\"],\n  [\"keyword.operator\",\"(\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"/apex/\"],\n  [\"string.end\",\"'\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"variable.language\",\"$CurrentPage\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"Name\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string.start\",\"'\"],\n  [\"string\",\"id\"],\n  [\"string.end\",\"'\"],\n  [\"keyword.operator\",\"=\"],\n  [\"identifier\",\"id\"],\n  [\"paren.rparen\",\"]\"],\n  [\"keyword.operator\",\")\"],\n  [\"keyword.end\",\"}\"],\n  [\"string.attribute-value.xml\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"                   \"],\n  [\"entity.other.attribute-name.xml\",\"value\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"Full List\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"ideas:listOutputLink\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"stickyAttributes\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"false\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"ideas:listOutputLink\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"keyword.start\",\"{!\"],\n  [\"support.function\",\"IF\"],\n  [\"keyword.operator\",\"(\"],\n  [\"support.function\",\"AND\"],\n  [\"keyword.operator\",\"(\"],\n  [\"identifier\",\"Price\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" 1\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Quantity\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"<\"],\n  [\"text\",\" 1\"],\n  [\"keyword.operator\",\")\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.start\",\"\\\"\"],\n  [\"string\",\"Small\"],\n  [\"string.end\",\"\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"null\"],\n  [\"keyword.operator\",\")\"],\n  [\"keyword.end\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_vue.json",
    "content": "[[\n   \"comment\",\n  [\"comment.start.xml\",\"<!--\"]\n],[\n   \"comment\",\n  [\"comment.xml\",\"Things to verify:\"]\n],[\n   \"comment\",\n  [\"comment.xml\",\"- comments (this block) are properly highlighted\"]\n],[\n   \"comment\",\n  [\"comment.xml\",\"- expressions are highlighted as JS\"]\n],[\n   \"comment\",\n  [\"comment.xml\",\"- <script> highlights ES2015 syntax\"]\n],[\n   \"comment\",\n  [\"comment.xml\",\"- <style> highlights as CSS\"]\n],[\n   \"start\",\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"template\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"punctuation\",\"{{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"'hi'\"],\n  [\"text\",\" \"],\n  [\"punctuation\",\"}}\"]\n],[\n   \"tag_stuff\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"span\"]\n],[\n   \"tag_stuff\",\n  [\"text.tag-whitespace.xml\",\"        \"],\n  [\"entity.other.attribute-name.xml\",\"v-\"],\n  [\"entity.other.attribute-name.xml\",\"text\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"'hi'\"],\n  [\"string\",\"\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"punctuation.separator.key-value.xml\",\":\"],\n  [\"entity.other.attribute-name.xml\",\"id\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"foo\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+\"],\n  [\"text\",\" \"],\n  [\"string\",\"'baz'\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"tag_stuff\",\n  [\"text.tag-whitespace.xml\",\"        \"],\n  [\"punctuation.separator.key-value.xml\",\"@\"],\n  [\"entity.other.attribute-name.xml\",\"click\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"onClick\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'hello'\"],\n  [\"paren.rparen\",\")\"],\n  [\"string\",\"\\\"\"]\n],[\n   \"start\",\n  [\"text.tag-whitespace.xml\",\"        \"],\n  [\"punctuation.separator.key-value.xml\",\"@\"],\n  [\"entity.other.attribute-name.xml\",\"click.prevent\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"onClick\"],\n  [\"paren.lparen\",\"(\"],\n  [\"string\",\"'hello'\"],\n  [\"paren.rparen\",\")\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"      Hello\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"span\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"router-link\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"v-\"],\n  [\"entity.other.attribute-name.xml\",\"bind\"],\n  [\"entity.other.attribute-name.xml\",\":to\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"item\"],\n  [\"punctuation.operator\",\".\"],\n  [\"identifier\",\"url\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" v-bind with dynamic key \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"v-\"],\n  [\"entity.other.attribute-name.xml\",\"bind\"],\n  [\"entity.other.attribute-name.xml\",\":[key]\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"value\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" v-bind shorthand with dynamic key \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"punctuation.separator.key-value.xml\",\":\"],\n  [\"entity.other.attribute-name.xml\",\"[key]\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"value\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" v-on with dynamic event \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"v-\"],\n  [\"entity.other.attribute-name.xml\",\"on\"],\n  [\"entity.other.attribute-name.xml\",\":[event]\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"handler\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"comment.start.xml\",\"<!--\"],\n  [\"comment.xml\",\" v-on shorthand with dynamic event \"],\n  [\"comment.end.xml\",\"-->\"]\n],[\n   \"start\",\n  [\"text.xml\",\"    \"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"punctuation.separator.key-value.xml\",\"@\"],\n  [\"entity.other.attribute-name.xml\",\"[event]\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"identifier\",\"handler\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"  \"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"div\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"template\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"js-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"js-start\",\n  [\"keyword\",\"export\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"default\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"js-start\",\n  [\"text\",\"  \"],\n  [\"identifier\",\"data\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"(\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"=>\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"({\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"    \"],\n  [\"identifier\",\"foo\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"'bar'\"]\n],[\n   \"js-no_regex\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"})\"]\n],[\n   \"js-start\",\n  [\"paren.rparen\",\"}\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.script.tag-name.xml\",\"script\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"css-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.style.xml\",\">\"]\n],[\n   \"css-ruleset\",\n  [\"constant\",\"div\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"css-ruleset\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"color\"],\n  [\"punctuation.operator\",\":\"],\n  [\"text\",\" \"],\n  [\"support.constant.color\",\"red\"],\n  [\"punctuation.operator\",\";\"]\n],[\n   \"css-start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"sass-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"lang\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"sass\\\"\"],\n  [\"meta.tag.punctuation.tag-close.style.xml\",\">\"]\n],[\n   \"sass-start\",\n  [\"comment\",\"// sass ace mode;\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"keyword\",\"@import\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"url(\"],\n  [\"string\",\"http://fonts.googleapis.com/css?family=Ace:700\"],\n  [\"support.function\",\")\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"variable.language\",\"html\"],\n  [\"text\",\", \"],\n  [\"variable.language\",\"body\"]\n],[\n   \"sass-start\",\n  [\"support.type\",\"  :background-color \"],\n  [\"constant.numeric\",\"#ace\"]\n],[\n   \"sass-start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"text-align\"],\n  [\"text\",\": \"],\n  [\"constant.language\",\"center\"]\n],[\n   \"sass-start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"height\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"100%\"]\n],[\n   [\"sass-comment\",-1,2,\"sass-start\"],\n  [\"comment\",\"  /*;*********;\"]\n],[\n   [\"sass-comment\",3,2,\"sass-start\"],\n  [\"comment\",\"    ;comment  ;\"]\n],[\n   [\"sass-comment\",3,2,\"sass-start\"],\n  [\"comment\",\"    ;*********;\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"  &\"],\n  [\"variable.language\",\":before\"]\n],[\n   \"sass-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$radius\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.845\"]\n],[\n   \"sass-start\",\n  [\"text\",\"    \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$size\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0.125\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$glow\"],\n  [\"text\",\" / \"],\n  [\"constant.numeric\",\"2\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#fff\"]\n],[\n   \"sass-start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"border-radius\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$radius\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"    &\"],\n  [\"variable.language\",\":active\"]\n],[\n   \"sass-start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".button\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"15px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"25px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-4px\"],\n  [\"text\",\" \"],\n  [\"support.function\",\"rgba\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.4\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".label\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"font-size\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"40px\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"rgba\"],\n  [\"paren.lparen\",\"(\"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"0.45\"],\n  [\"paren.rparen\",\")\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"    &\"],\n  [\"variable.language\",\":checked\"]\n],[\n   \"sass-start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".button\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"box-shadow\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"0\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"15px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"25px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"-4px\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"#ace\"]\n],[\n   \"sass-start\"\n],[\n   \"sass-start\",\n  [\"text\",\"      ~ \"],\n  [\"variable.language\",\".label\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"font-size\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"40px\"]\n],[\n   \"sass-start\",\n  [\"text\",\"        \"],\n  [\"support.type\",\"color\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"#c9c9c9\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"scss-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"lang\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"scss\\\"\"],\n  [\"meta.tag.punctuation.tag-close.style.xml\",\">\"]\n],[\n   \"scss-start\",\n  [\"comment\",\"/* style.scss */\"]\n],[\n   \"scss-start\"\n],[\n   \"scss-start\",\n  [\"variable.language\",\"#navbar\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"800px\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"$items\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"5\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"#ce4dd6\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\"\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"width\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"support.type\",\"border-bottom\"],\n  [\"text\",\": \"],\n  [\"constant.numeric\",\"2px\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"solid\"],\n  [\"text\",\" \"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\"\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"variable.language\",\"li\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"scss-start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"float\"],\n  [\"text\",\": \"],\n  [\"support.type\",\"left\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"width\"],\n  [\"text\",\": \"],\n  [\"variable\",\"$navbar-width\"],\n  [\"text\",\"/\"],\n  [\"variable\",\"$items\"],\n  [\"text\",\" \"],\n  [\"constant\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10px\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\"\n],[\n   \"scss-start\",\n  [\"text\",\"    \"],\n  [\"support.type\",\"background-color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"20%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\"\n],[\n   \"scss-start\",\n  [\"text\",\"    &\"],\n  [\"variable.language\",\":hover\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"{\"]\n],[\n   \"scss-start\",\n  [\"text\",\"      \"],\n  [\"support.type\",\"background-color\"],\n  [\"text\",\": \"],\n  [\"support.function\",\"lighten\"],\n  [\"paren.lparen\",\"(\"],\n  [\"variable\",\"$navbar-color\"],\n  [\"text\",\", \"],\n  [\"constant.numeric\",\"10%\"],\n  [\"paren.rparen\",\")\"],\n  [\"text\",\";\"]\n],[\n   \"scss-start\",\n  [\"text\",\"    \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"scss-start\",\n  [\"text\",\"  \"],\n  [\"paren.rparen\",\"}\"]\n],[\n   \"scss-start\",\n  [\"paren.rparen\",\"}\"]\n],[\n   \"scss-start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.style.tag-name.xml\",\"style\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"jade-start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.template.tag-name.xml\",\"template\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"lang\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"jade\\\"\"],\n  [\"meta.tag.punctuation.tag-close.template.xml\",\">\"]\n],[\n   \"jade-start\",\n  [\"storage.type.function.jade\",\"  mixin\"],\n  [\"entity.name.function.jade\",\" article\"],\n  [\"punctuation.definition.parameters.begin.jade\",\"(\"],\n  [\"variable.parameter.function.jade\",\"obj, parents\"],\n  [\"punctuation.definition.parameters.end.jade\",\")\"]\n],[\n   \"jade-start\",\n  [\"source.js.embedded.jade\",\"    -\"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"x\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"0\\\"\"],\n  [\"text\",\";\"]\n],[\n   \"jade-start\"\n],[\n   \"jade-start\",\n  [\"source.js.embedded.jade\",\"  -\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"items\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"paren.lparen\",\"[\"],\n  [\"string\",\"\\\"one\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"two\\\"\"],\n  [\"punctuation.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"string\",\"\\\"three\\\"\"],\n  [\"text\",\"]\"]\n],[\n   \"jade-start\",\n  [\"meta.tag.any.jade\",\"  each\"],\n  [\"text\",\" item in items\"]\n],[\n   \"jade-start\",\n  [\"meta.tag.any.jade\",\"    li\"],\n  [\"text\",\"= item\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.template.tag-name.xml\",\"template\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"template\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"v-\"],\n  [\"entity.other.attribute-name.xml\",\"slot\"],\n  [\"entity.other.attribute-name.xml\",\":item\"],\n  [\"entity.other.attribute-name.xml\",\".parentkey.subkey.subkey.subkey.subkey.subkey\"],\n  [\"punctuation.separator.key-value.xml\",\"=\"],\n  [\"string\",\"\\\"\"],\n  [\"paren.lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"value\"],\n  [\"text\",\" \"],\n  [\"paren.rparen\",\"}\"],\n  [\"string\",\"\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"template\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_wollok.json",
    "content": "[[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Actividad\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"calcularMejora\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"EstudiarMateria\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"inherits\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Actividad\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"materia\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"puntos\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"new\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"keyword.operator\",\",\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"materia\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"puntos\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"p\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"override\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"calcularMejora\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"puntos\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"class\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"EjercitarEnSimulador\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"inherits\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"Actividad\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"horas\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"0\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"new\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"h\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"horas\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"h\"],\n  [\"text\",\" \"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"override\"],\n  [\"text\",\" \"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"calcularMejora\"],\n  [\"lparen\",\"(\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"10\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"*\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"horas\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword\",\"object\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"pepita\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"var\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"energia\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"100\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"keyword\",\"method\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"volar\"],\n  [\"lparen\",\"(\"],\n  [\"identifier\",\"m\"],\n  [\"rparen\",\")\"],\n  [\"text\",\" \"],\n  [\"lparen\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\\t\"],\n  [\"identifier\",\"energia\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"-=\"],\n  [\"text\",\" \"],\n  [\"identifier\",\"m\"]\n],[\n   \"start\",\n  [\"text\",\"\\t\"],\n  [\"rparen\",\"}\"]\n],[\n   \"start\",\n  [\"rparen\",\"}\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_xml.json",
    "content": "[[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"Juhu\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"text.xml\",\"//Juhu Kinners\"],\n  [\"meta.tag.punctuation.end-tag-open.xml\",\"</\"],\n  [\"meta.tag.tag-name.xml\",\"Kinners\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: two tags in the same lines should be in separate tokens\\\"\"]\n],[\n   \"start\",\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"Juhu\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"Kinners\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\">\"]\n],[\n   \"start\",\n  [\"text.xml\",\"test: multiline attributes\\\"\"]\n],[\n   [\"string.attribute-value.xml0\",\"meta.tag.punctuation.tag-open.xml\"],\n  [\"meta.tag.punctuation.tag-open.xml\",\"<\"],\n  [\"meta.tag.tag-name.xml\",\"copy\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"set\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"{\"]\n],[\n   [\"string.attribute-value.xml0\",\"meta.tag.punctuation.tag-open.xml\"],\n  [\"string.attribute-value.xml\",\"}\\\"\"],\n  [\"text.tag-whitespace.xml\",\" \"],\n  [\"entity.other.attribute-name.xml\",\"undo\"],\n  [\"keyword.operator.attribute-equals.xml\",\"=\"],\n  [\"string.attribute-value.xml\",\"\\\"{\"]\n],[\n   \"start\",\n  [\"string.attribute-value.xml\",\"}\\\"\"],\n  [\"meta.tag.punctuation.tag-close.xml\",\"/>\"]\n]]"
  },
  {
    "path": "src/mode/_test/tokens_yaml.json",
    "content": "[[\n   \"start\",\n  [\"comment\",\"# This sample document was taken from wikipedia:\"]\n],[\n   \"start\",\n  [\"comment\",\"# http://en.wikipedia.org/wiki/YAML#Sample_document\"]\n],[\n   \"start\",\n  [\"list.markup\",\"---\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"receipt\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"     Oz-Ware Purchase Invoice\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"date\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"        2007-08-06\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"customer\"],\n  [\"keyword\",\":\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"    given\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   Dorothy\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"    family\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  Gale\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag\",\"items\"],\n  [\"keyword\",\":\"]\n],[\n   \"start\",\n  [\"list.markup\",\"    - \"],\n  [\"meta.tag\",\"part_no\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   \"],\n  [\"string\",\"'A4786'\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      descrip\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   Water Bucket \"],\n  [\"paren.lparen\",\"(\"],\n  [\"text\",\"Filled)\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      price\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"     \"],\n  [\"constant.numeric\",\"1.47\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      quantity\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  \"],\n  [\"constant.numeric\",\"4\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"list.markup\",\"    - \"],\n  [\"meta.tag\",\"part_no\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   \"],\n  [\"string\",\"'E1628'\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      descrip\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   High Heeled \"],\n  [\"string\",\"\\\"Ruby\\\"\"],\n  [\"text\",\" Slippers\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      size\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"      \"],\n  [\"constant.numeric\",\"8\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      price\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"     \"],\n  [\"constant.numeric\",\"100.27\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      quantity\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  \"],\n  [\"constant.numeric\",\"1\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"      version\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   1.2.3.4\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag\",\"bill-to\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  \"],\n  [\"constant.language\",\"&id001\"]\n],[\n   [\"mlStringPre\",4],\n  [\"meta.tag\",\"    street\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",11],\n  [\"indent\",\"            \"],\n  [\"string\",\"123 Tornado Alley\"]\n],[\n   [\"mlString\",11],\n  [\"indent\",\"            \"],\n  [\"string\",\"Suite 16\"]\n],[\n   \"start\",\n  [\"indent\",\"    \"],\n  [\"meta.tag\",\"ref-id\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" id123  \"]\n],[\n   \"start\",\n  [\"meta.tag\",\"    city\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"   East Centerville\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"    state\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  KS\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"meta.tag\",\"ship-to\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  \"],\n  [\"constant.language\",\"*id001\"]\n],[\n   \"start\"\n],[\n   [\"mlStringPre\",0],\n  [\"meta.tag\",\"specialDelivery\"],\n  [\"keyword\",\":\"],\n  [\"text\",\"  \"],\n  [\"string\",\">\"]\n],[\n   [\"mlString\",3],\n  [\"indent\",\"    \"],\n  [\"string\",\"Follow the Yellow Brick\"]\n],[\n   [\"mlString\",3],\n  [\"indent\",\"    \"],\n  [\"string\",\"Road to the Emerald City.\"]\n],[\n   [\"mlString\",3],\n  [\"indent\",\"    \"],\n  [\"string\",\"Pay no attention to the\"]\n],[\n   [\"mlString\",3],\n  [\"indent\",\"    \"],\n  [\"string\",\"man behind the curtain.\"]\n],[\n   [\"mlString\",3]\n],[\n   [\"mlStringPre\",0],\n  [\"list.markup\",\"? \"],\n  [\"text\",\"       \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",0],\n  [\"indent\",\" \"],\n  [\"string\",\"block key #1\"]\n],[\n   [\"mlString\",0],\n  [\"indent\",\" \"],\n  [\"string\",\"kkk\"]\n],[\n   [\"mlStringPre\",2],\n  [\"text\",\": - \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",2],\n  [\"indent\",\"   \"],\n  [\"string\",\"one \"]\n],[\n   [\"mlStringPre\",2],\n  [\"indent\",\"  \"],\n  [\"text\",\"- \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",2],\n  [\"indent\",\"   \"],\n  [\"string\",\"tw #o \"]\n],[\n   [\"mlStringPre\",4],\n  [\"indent\",\"  \"],\n  [\"text\",\"- ? \"],\n  [\"string\",\"|- \"]\n],[\n   [\"mlStringPre\",4]\n],[\n   [\"mlString\",4],\n  [\"indent\",\"     \"],\n  [\"string\",\"as #d\"]\n],[\n   [\"mlString\",4]\n],[\n   [\"mlString\",4],\n  [\"indent\",\"     \"],\n  [\"string\",\"q\"]\n],[\n   \"start\",\n  [\"indent\",\"    \"],\n  [\"text\",\"b\"]\n],[\n   \"start\",\n  [\"list.markup\",\"  - \"]\n],[\n   \"start\",\n  [\"meta.tag\",\"     x\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" xx\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"     r\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" xx\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"     z\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" sss\"]\n],[\n   \"start\",\n  [\"meta.tag\",\"     zdd\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" dddd\"]\n],[\n   \"start\",\n  [\"text\",\"     \"],\n  [\"string\",\"\\\"block key 2\\\"\"],\n  [\"text\",\" : \"]\n],[\n   \"start\",\n  [\"list.markup\",\"       - \"],\n  [\"text\",\"two \"],\n  [\"comment\",\"# block value\"]\n],[\n   [\"mlStringPre\",9],\n  [\"list.markup\",\"       - \"],\n  [\"text\",\"? \"],\n  [\"string\",\"| \"]\n],[\n   [\"mlString\",9],\n  [\"indent\",\"          \"],\n  [\"string\",\"as #d\"]\n],[\n   [\"mlStringPre\",9],\n  [\"indent\",\"         \"],\n  [\"text\",\": \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",9],\n  [\"indent\",\"          \"],\n  [\"string\",\"asdadas #d\"]\n],[\n   [\"mlString\",9],\n  [\"indent\",\"          \"],\n  [\"string\",\"asd\"]\n],[\n   \"start\",\n  [\"indent\",\"         \"],\n  [\"meta.tag\",\"a\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric\",\"2\"]\n],[\n   [\"mlStringPre\",9],\n  [\"list.markup\",\"       - \"],\n  [\"text\",\"? \"],\n  [\"string\",\"| \"]\n],[\n   [\"mlString\",9],\n  [\"indent\",\"          \"],\n  [\"string\",\"asdas #d\"]\n],[\n   [\"mlStringPre\",9],\n  [\"indent\",\"         \"],\n  [\"text\",\":  \"],\n  [\"string\",\"|\"]\n],[\n   [\"mlString\",9],\n  [\"indent\",\"          \"],\n  [\"string\",\"xx\"]\n],[\n   [\"mlString\",12],\n  [\"indent\",\"         \"],\n  [\"meta.tag\",\"s\"],\n  [\"keyword\",\":\"],\n  [\"text\",\" \"],\n  [\"string\",\"|4+ #comment\"]\n],[\n   [\"mlString\",12],\n  [\"indent\",\"               \"],\n  [\"string\",\"7\"]\n],[\n   [\"mlString\",12]\n],[\n   [\"mlString\",12],\n  [\"indent\",\"             \"],\n  [\"string\",\"a \"]\n],[\n   \"start\",\n  [\"indent\",\"           \"],\n  [\"text\",\"a\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/_test/tokens_zeek.json",
    "content": "[[\n   \"start\",\n  [\"comment.line\",\"# An example of the Zeek scripting language.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"##! A Zeekygen-style summmary comment.\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"comment.line\",\"# TODO: just an example of a todo-indicator\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other\",\"@load\"],\n  [\"meta.preprocessor\",\" base/frameworks/notice\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other\",\"@if\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"F\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"keyword.other\",\"@endif\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other\",\"module\"],\n  [\"meta.namespace\",\" \"],\n  [\"entity.name.namespace\",\"Example\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"keyword.other\",\"export\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"type\"],\n  [\"meta.enum\",\" \"],\n  [\"entity.name.enum\",\"SimpleEnum\"],\n  [\"punctuation.separator\",\":\"],\n  [\"meta.enum\",\" \"],\n  [\"storage.type.enum\",\"enum\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"],\n  [\"text\",\" ONE\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" TWO\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" THREE \"],\n  [\"punctuation.section.block.end\",\"}\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"redef\"],\n  [\"meta.enum\",\" \"],\n  [\"storage.type.enum\",\"enum\"],\n  [\"meta.enum\",\" \"],\n  [\"entity.name.enum\",\"SimpleEnum\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"comment.line\",\"## A Zeekygen-style comment.\"]\n],[\n   \"start\",\n  [\"text\",\"    FOUR\"],\n  [\"punctuation.separator\",\",\"]\n],[\n   \"start\",\n  [\"text\",\"    FIVE\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"comment.line\",\"##< A Zeekygen-style comment.\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"type\"],\n  [\"meta.struct.record\",\" \"],\n  [\"entity.name.struct.record\",\"SimpleRecord\"],\n  [\"punctuation.separator\",\":\"],\n  [\"meta.struct.record\",\" \"],\n  [\"storage.type.struct.record\",\"record\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    field1\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    field2\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"bool\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.attribute\",\"&redef\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"redef\"],\n  [\"meta.struct.record\",\" \"],\n  [\"storage.type.struct.record\",\"record\"],\n  [\"meta.struct.record\",\" \"],\n  [\"entity.name.struct.record\",\"SimpleRecord\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    field3\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.attribute\",\"&optional\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    field4\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.attribute\",\"&default\"],\n  [\"keyword.operator\",\"=\"],\n  [\"string.double\",\"\\\"blah\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"const\"],\n  [\"text\",\" init_option\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"bool\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"T\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"option\"],\n  [\"text\",\" runtime_option\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"bool\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"F\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"global\"],\n  [\"text\",\" test_opaque\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"opaque\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"of\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"md5\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"global\"],\n  [\"text\",\" test_vector\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"vector\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"of\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"global\"],\n  [\"text\",\" myfunction\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"function\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"msg\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" c\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.attribute\",\"&default\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"global\"],\n  [\"text\",\" myhook\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"hook\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"tag\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"global\"],\n  [\"text\",\" myevent\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"event\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"tag\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"function\"],\n  [\"text\",\" \"],\n  [\"entity.name.function\",\"myfunction\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"msg\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" c\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"in myfunction\\\"\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" msg\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" c\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"return\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"event\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.event\",\"myevent\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"msg\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"text\",\" \"],\n  [\"storage.modifier.attribute\",\"&priority\"],\n  [\"keyword.operator\",\"=\"],\n  [\"constant.numeric.integer.decimal\",\"1\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"in myevent\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"hook\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.hook\",\"myhook\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\"msg\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"in myevent\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"storage.type\",\"event\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.event\",\"zeek_init\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" b \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"T\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" s \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"\"],\n  [\"constant.character.escape\",\"\\\\x\"],\n  [\"string.double\",\"ff\"],\n  [\"constant.character.escape\",\"\\\\x\"],\n  [\"string.double\",\"af\"],\n  [\"constant.character.escape\",\"\\\\\\\"\"],\n  [\"string.double\",\"and more after the escaped quote\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" p \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.regexp\",\"/foo|bar\"],\n  [\"constant.character.escape\",\"\\\\x\"],\n  [\"string.regexp\",\"be\"],\n  [\"constant.character.escape\",\"\\\\/\"],\n  [\"string.regexp\",\"and more after the escaped slash/\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"10\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" sr \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.call\",\"SimpleRecord\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"punctuation.accessor\",\"$\"],\n  [\"text\",\"field1 \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.accessor\",\"$\"],\n  [\"text\",\"field2 \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"constant.language\",\"T\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"punctuation.accessor\",\"$\"],\n  [\"text\",\"field3 \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"hi\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" sr\"],\n  [\"punctuation.accessor\",\"?$\"],\n  [\"text\",\"field3\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" sr\"],\n  [\"punctuation.accessor\",\"$\"],\n  [\"text\",\"field1\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" myset\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"set\"],\n  [\"punctuation.section.brackets.begin\",\"[\"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.section.brackets.end\",\"]\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"set\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"one\\\"\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"two\\\"\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"three\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"add\"],\n  [\"text\",\" myset\"],\n  [\"punctuation.section.brackets.begin\",\"[\"],\n  [\"string.double\",\"\\\"four\\\"\"],\n  [\"punctuation.section.brackets.end\",\"]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"delete\"],\n  [\"text\",\" myset\"],\n  [\"punctuation.section.brackets.begin\",\"[\"],\n  [\"string.double\",\"\\\"one\\\"\"],\n  [\"punctuation.section.brackets.end\",\"]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"for\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" ms \"],\n  [\"keyword.operator\",\"in\"],\n  [\"text\",\" myset \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" ms \"],\n  [\"keyword.operator\",\"is\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" s \"],\n  [\"keyword.operator\",\"as\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"string\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" s\"],\n  [\"punctuation.section.brackets.begin\",\"[\"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"punctuation.separator\",\":\"],\n  [\"constant.numeric.integer.decimal\",\"3\"],\n  [\"punctuation.section.brackets.end\",\"]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"storage.modifier\",\"local\"],\n  [\"text\",\" tern\"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"storage.type\",\"count\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" s \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"two\\\"\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"?\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"2\"],\n  [\"text\",\" \"],\n  [\"punctuation.separator\",\":\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.conditional\",\"if\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" s \"],\n  [\"keyword.operator\",\"!in\"],\n  [\"text\",\" myset \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"       \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.call\",\"fmt\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"error \"],\n  [\"constant.other.placeholder\",\"%4.2f\"],\n  [\"string.double\",\": \"],\n  [\"constant.other.placeholder\",\"%s\"],\n  [\"string.double\",\"\\\"\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\"3.14159\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"wtf?\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"switch\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" c \"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"punctuation.separator\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"break\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"case\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"2\"],\n  [\"punctuation.separator\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"fallthrough\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"default\"],\n  [\"punctuation.separator\",\":\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control\",\"break\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.conditional\",\"if\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"!\"],\n  [\"text\",\" b \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"here\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control.conditional\",\"else\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"string.double\",\"\\\"there\\\"\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"while\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"!=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.section.block.begin\",\"{\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.conditional\",\"if\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\">=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"5\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      c \"],\n  [\"keyword.operator\",\"+=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"keyword.control.conditional\",\"else\"],\n  [\"text\",\" \"],\n  [\"keyword.control.conditional\",\"if\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"==\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"8\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.parens.end\",\")\"]\n],[\n   \"start\",\n  [\"text\",\"      c \"],\n  [\"keyword.operator\",\"-=\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"    c \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    c \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"/\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    c \"],\n  [\"keyword.operator\",\"=\"],\n  [\"text\",\" c \"],\n  [\"keyword.operator\",\"-\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"    \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"|\"],\n  [\"text\",\"myset\"],\n  [\"keyword.operator\",\"|\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"~\"],\n  [\"constant.numeric.integer.decimal\",\"5\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"1\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"&\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.hexadecimal\",\"0xff\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"2\"],\n  [\"text\",\" \"],\n  [\"keyword.operator\",\"^\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"5\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"entity.name.function.call\",\"myfunction\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"hello function\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"hook\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.hook\",\"myhook\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"hell hook\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"storage.type\",\"event\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.event\",\"myevent\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"hello event\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.control\",\"schedule\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1sec\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.begin\",\"{\"],\n  [\"text\",\" \"],\n  [\"entity.name.function.call\",\"myevent\"],\n  [\"punctuation.section.parens.begin\",\"(\"],\n  [\"string.double\",\"\\\"hello scheduled event\\\"\"],\n  [\"punctuation.section.parens.end\",\")\"],\n  [\"text\",\" \"],\n  [\"punctuation.section.block.end\",\"}\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"0\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.decimal\",\"7\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.hexadecimal\",\"0xff\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.integer.hexadecimal\",\"0xdeadbeef\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\"3.14159\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\"1234.0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\"1234e0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\".003E-23\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal\",\".003E+23\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.port\",\"123/udp\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.port\",\"8000/tcp\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.port\",\"13/icmp\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.port\",\"42/unknown\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.hostname\",\"google.com\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"192.168.50.1\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"255.255.255.255\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"0.0.0.0\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"10.0.0.0\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric.integer.decimal\",\"16\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# test for case insensitivity\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:0DB8:85A3:0000:0000:8A2E:0370:7334]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# any case mixture is allowed\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:0dB8:85a3:0000:0000:8A2E:0370:7334]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# leading zeroes of a 16-bit group may be omitted\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:db8:85a3:0:0:8a2e:370:7334]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# a single occurrence of consecutive groups of zeroes may be replaced by ::\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:db8:85a3::8a2e:370:7334]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# all zeroes should work\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[0:0:0:0:0:0:0:0]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# all zeroes condensed should work\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[::]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# hybrid ipv6-ipv4 address should work\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:db8:0:0:0:FFFF:192.168.0.5]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"comment.line\",\"# hybrid ipv6-ipv4 address with zero ommission should work\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:db8::FFFF:192.168.0.5]\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.addr\",\"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]\"],\n  [\"keyword.operator\",\"/\"],\n  [\"constant.numeric.integer.decimal\",\"64\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\"\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1day\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1days\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0day\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0days\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1hr\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1hrs\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0hr\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0hrs\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1min\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1mins\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0min\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0mins\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1sec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1secs\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0sec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0secs\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1msec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1msecs\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0msec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0msecs\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"keyword.other\",\"print\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1usec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1usecs\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0usec\"],\n  [\"punctuation.separator\",\",\"],\n  [\"text\",\" \"],\n  [\"constant.numeric.float.decimal.interval\",\"1.0usecs\"],\n  [\"punctuation.terminator\",\";\"]\n],[\n   \"start\",\n  [\"text\",\"  \"],\n  [\"punctuation.section.block.end\",\"}\"]\n],[\n   \"start\"\n]]"
  },
  {
    "path": "src/mode/abap.js",
    "content": "\"use strict\";\n\nvar Rules = require(\"./abap_highlight_rules\").AbapHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\nvar Range = require(\"../range\").Range;\nvar TextMode = require(\"./text\").Mode;\nvar oop = require(\"../lib/oop\");\n\nfunction Mode() {\n    this.HighlightRules = Rules;\n    this.foldingRules = new FoldMode();\n}\n\noop.inherits(Mode, TextMode);\n\n(function() {\n    \n    this.lineCommentStart = '\"';\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        return indent;\n    };    \n    \n    this.$id = \"ace/mode/abap\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/abap_highlight_rules.js",
    "content": "/*\n * based on\n * \" Vim ABAP syntax file\n * \"    Language: SAP - ABAP/R4\n * \"    Revision: 2.1\n * \"  Maintainer: Marius Piedallu van Wyk <lailoken@gmail.com>\n * \" Last Change: 2012 Oct 23\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AbapHighlightRules = function() {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": \n            \"ADD ALIAS ALIASES ASCENDING ASSERT ASSIGN ASSIGNING AT BACK\" +\n            \" CALL CASE CATCH CHECK CLASS CLEAR CLOSE CNT COLLECT COMMIT COMMUNICATION COMPUTE CONCATENATE CONDENSE CONSTANTS CONTINUE CONTROLS CONVERT CREATE CURRENCY\" +\n            \" DATA DEFINE DEFINITION DEFERRED DELETE DESCENDING DESCRIBE DETAIL DIVIDE DO\" +\n            \" ELSE ELSEIF ENDAT ENDCASE ENDCLASS ENDDO ENDEXEC ENDFORM ENDFUNCTION ENDIF ENDIFEND ENDINTERFACE ENDLOOP ENDMETHOD ENDMODULE ENDON ENDPROVIDE ENDSELECT ENDTRY ENDWHILE EVENT EVENTS EXEC EXIT EXPORT EXPORTING EXTRACT\" +\n            \" FETCH FIELDS FORM FORMAT FREE FROM FUNCTION\" +\n            \" GENERATE GET\" +\n            \" HIDE\" +\n            \" IF IMPORT IMPORTING INDEX INFOTYPES INITIALIZATION INTERFACE INTERFACES INPUT INSERT IMPLEMENTATION\" +\n            \" LEAVE LIKE LINE LOAD LOCAL LOOP\" +\n            \" MESSAGE METHOD METHODS MODIFY MODULE MOVE MULTIPLY\" +\n            \" ON OVERLAY OPTIONAL OTHERS\" +\n            \" PACK PARAMETERS PERFORM POSITION PROGRAM PROVIDE PUT\" +\n            \" RAISE RANGES READ RECEIVE RECEIVING REDEFINITION REFERENCE REFRESH REJECT REPLACE REPORT RESERVE RESTORE RETURN RETURNING ROLLBACK\" +\n            \" SCAN SCROLL SEARCH SELECT SET SHIFT SKIP SORT SORTED SPLIT STANDARD STATICS STEP STOP SUBMIT SUBTRACT SUM SUMMARY SUPPRESS\" +\n            \" TABLES TIMES TRANSFER TRANSLATE TRY TYPE TYPES\" +\n            \" UNASSIGN ULINE UNPACK UPDATE\" +\n            \" WHEN WHILE WINDOW WRITE\" +\n            \" OCCURS STRUCTURE OBJECT PROPERTY\" +\n            \" CASTING APPEND RAISING VALUE COLOR\" +\n            \" CHANGING EXCEPTION EXCEPTIONS DEFAULT CHECKBOX COMMENT\" +\n            \" ID NUMBER FOR TITLE OUTPUT\" +\n            \" WITH EXIT USING\" +\n            \" INTO WHERE GROUP BY HAVING ORDER BY SINGLE\" +\n            \" APPENDING CORRESPONDING FIELDS OF TABLE\" +\n            \" LEFT RIGHT OUTER INNER JOIN AS CLIENT SPECIFIED BYPASSING BUFFER UP TO ROWS CONNECTING\" +\n            \" EQ NE LT LE GT GE NOT AND OR XOR IN LIKE BETWEEN\",\n        \"constant.language\": \n            \"TRUE FALSE NULL SPACE\",\n        \"support.type\": \n            \"c n i p f d t x string xstring decfloat16 decfloat34\",\n        \"keyword.operator\":\n            \"abs sign ceil floor trunc frac acos asin atan cos sin tan\" +\n            \" abapOperator cosh sinh tanh exp log log10 sqrt\" +\n            \" strlen xstrlen charlen numofchar dbmaxlen lines\" \n    }, \"text\", true, \" \");\n\n    var compoundKeywords = \"WITH\\\\W+(?:HEADER\\\\W+LINE|FRAME|KEY)|NO\\\\W+STANDARD\\\\W+PAGE\\\\W+HEADING|\"+\n        \"EXIT\\\\W+FROM\\\\W+STEP\\\\W+LOOP|BEGIN\\\\W+OF\\\\W+(?:BLOCK|LINE)|BEGIN\\\\W+OF|\"+\n        \"END\\\\W+OF\\\\W+(?:BLOCK|LINE)|END\\\\W+OF|NO\\\\W+INTERVALS|\"+\n        \"RESPECTING\\\\W+BLANKS|SEPARATED\\\\W+BY|USING\\\\W+(?:EDIT\\\\W+MASK)|\"+\n        \"WHERE\\\\W+(?:LINE)|RADIOBUTTON\\\\W+GROUP|REF\\\\W+TO|\"+\n        \"(?:PUBLIC|PRIVATE|PROTECTED)(?:\\\\W+SECTION)?|DELETING\\\\W+(?:TRAILING|LEADING)\"+\n        \"(?:ALL\\\\W+OCCURRENCES)|(?:FIRST|LAST)\\\\W+OCCURRENCE|INHERITING\\\\W+FROM|\"+\n        \"LINE-COUNT|ADD-CORRESPONDING|AUTHORITY-CHECK|BREAK-POINT|CLASS-DATA|CLASS-METHODS|\"+\n        \"CLASS-METHOD|DIVIDE-CORRESPONDING|EDITOR-CALL|END-OF-DEFINITION|END-OF-PAGE|END-OF-SELECTION|\"+\n        \"FIELD-GROUPS|FIELD-SYMBOLS|FUNCTION-POOL|MOVE-CORRESPONDING|MULTIPLY-CORRESPONDING|NEW-LINE|\"+\n        \"NEW-PAGE|NEW-SECTION|PRINT-CONTROL|RP-PROVIDE-FROM-LAST|SELECT-OPTIONS|SELECTION-SCREEN|\"+\n        \"START-OF-SELECTION|SUBTRACT-CORRESPONDING|SYNTAX-CHECK|SYNTAX-TRACE|TOP-OF-PAGE|TYPE-POOL|\"+\n        \"TYPE-POOLS|LINE-SIZE|LINE-COUNT|MESSAGE-ID|DISPLAY-MODE|READ(?:-ONLY)?|\"+\n        \"IS\\\\W+(?:NOT\\\\W+)?(?:ASSIGNED|BOUND|INITIAL|SUPPLIED)\";\n     \n    this.$rules = {\n        \"start\" : [\n            {token : \"string\", regex : \"`\", next  : \"string\"},\n            {token : \"string\", regex : \"'\", next  : \"qstring\"},\n            {token : \"doc.comment\", regex : /^\\*.+/},\n            {token : \"comment\",  regex : /\".+$/},\n            {token : \"invalid\", regex: \"\\\\.{2,}\"},\n            {token : \"keyword.operator\", regex: /\\W[\\-+%=<>*]\\W|\\*\\*|[~:,\\.&$]|->*?|=>/},\n            {token : \"paren.lparen\", regex : \"[\\\\[({]\"},\n            {token : \"paren.rparen\", regex : \"[\\\\])}]\"},\n            {token : \"constant.numeric\", regex: \"[+-]?\\\\d+\\\\b\"},\n            {token : \"variable.parameter\", regex : /sy|pa?\\d\\d\\d\\d\\|t\\d\\d\\d\\.|innnn/}, \n            {token : \"keyword\", regex : compoundKeywords}, \n            {token : \"variable.parameter\", regex : /\\w+-\\w[\\-\\w]*/},\n            {token : keywordMapper, regex : \"\\\\b\\\\w+\\\\b\"},\n            {caseInsensitive: true}\n        ],\n        \"qstring\" : [\n            {token : \"constant.language.escape\",   regex : \"''\"},\n            {token : \"string\", regex : \"'\",     next  : \"start\"},\n            {defaultToken : \"string\"}\n        ],\n        \"string\" : [\n            {token : \"constant.language.escape\",   regex : \"``\"},\n            {token : \"string\", regex : \"`\",     next  : \"start\"},\n            {defaultToken : \"string\"}\n        ]\n    };\n};\noop.inherits(AbapHighlightRules, TextHighlightRules);\n\nexports.AbapHighlightRules = AbapHighlightRules;\n"
  },
  {
    "path": "src/mode/abc.js",
    "content": "/*\n THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n */\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextMode = require(\"./text\").Mode;\n    var ABCHighlightRules = require(\"./abc_highlight_rules\").ABCHighlightRules;\n    var FoldMode = require(\"./folding/cstyle\").FoldMode;\n\n    var Mode = function () {\n        this.HighlightRules = ABCHighlightRules;\n        this.foldingRules = new FoldMode();\n        this.$behaviour = this.$defaultBehaviour;\n    };\n    oop.inherits(Mode, TextMode);\n\n    (function () {\n        this.lineCommentStart = \"%\";\n        \n        this.$id = \"ace/mode/abc\";\n        this.snippetFileId = \"ace/snippets/abc\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/abc_highlight_rules.js",
    "content": "/* This file was partially autogenerated from https://github.com/jimhawkridge/SublimeABC\n\n Modifications\n\n -  more classes to express the abc semantic\n -  added syntax highlighting for Zupfnoter conventions (https://github.com/bwl21/zupfnoter)\n -  separate note pitch and note duration - even if it looks the same\n\n ***********************************************************************************************/\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var ABCHighlightRules = function () {\n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n\n        this.$rules = {\n            start: [\n                {\n                    token: ['zupfnoter.information.comment.line.percentage', 'information.keyword', 'in formation.keyword.embedded'],\n                    regex: '(%%%%)(hn\\\\.[a-z]*)(.*)',\n                    comment: 'Instruction Comment'\n                },\n                {\n                    token: ['information.comment.line.percentage', 'information.keyword.embedded'],\n                    regex: '(%%)(.*)',\n                    comment: 'Instruction Comment'\n                },\n\n                {\n                    token: 'comment.line.percentage',\n                    regex: '%.*',\n                    comment: 'Comments'\n                },\n\n                {\n                    token: 'barline.keyword.operator',\n                    regex: '[\\\\[:]*[|:][|\\\\]:]*(?:\\\\[?[0-9]+)?|\\\\[[0-9]+',\n                    comment: 'Bar lines'\n                },\n                {\n                    token: ['information.keyword.embedded', 'information.argument.string.unquoted'],\n                    regex: '(\\\\[[A-Za-z]:)([^\\\\]]*\\\\])',\n                    comment: 'embedded Header lines'\n                },\n                {\n                    token: ['information.keyword', 'information.argument.string.unquoted'],\n                    regex: '^([A-Za-z]:)([^%\\\\\\\\]*)',\n                    comment: 'Header lines'\n                },\n                {\n                    token: ['text', 'entity.name.function', 'string.unquoted', 'text'],\n                    regex: '(\\\\[)([A-Z]:)(.*?)(\\\\])',\n                    comment: 'Inline fields'\n                },\n                {\n                    token: ['accent.constant.language', 'pitch.constant.numeric', 'duration.constant.numeric'],\n                    regex: '([\\\\^=_]*)([A-Ga-gz][,\\']*)([0-9]*/*[><0-9]*)',\n                    comment: 'Notes'\n                },\n                {\n                    token: 'zupfnoter.jumptarget.string.quoted',\n                    regex: '[\\\\\"!]\\\\^\\\\:.*?[\\\\\"!]',\n                    comment: 'Zupfnoter jumptarget'\n                }, {\n                    token: 'zupfnoter.goto.string.quoted',\n                    regex: '[\\\\\"!]\\\\^\\\\@.*?[\\\\\"!]',\n                    comment: 'Zupfnoter goto'\n                },\n                {\n                    token: 'zupfnoter.annotation.string.quoted',\n                    regex: '[\\\\\"!]\\\\^\\\\!.*?[\\\\\"!]',\n                    comment: 'Zupfnoter annoation'\n                },\n                {\n                    token: 'zupfnoter.annotationref.string.quoted',\n                    regex: '[\\\\\"!]\\\\^\\\\#.*?[\\\\\"!]',\n                    comment: 'Zupfnoter annotation reference'\n                },\n                {\n                    token: 'chordname.string.quoted',\n                    regex: '[\\\\\"!]\\\\^.*?[\\\\\"!]',\n                    comment: 'abc chord'\n                },\n                {\n                    token: 'string.quoted',\n                    regex: '[\\\\\"!].*?[\\\\\"!]',\n                    comment: 'abc annotation'\n                }\n\n            ]\n        };\n\n        //  this.embedRules(JsonHighlightRules, \"json-\")\n\n        this.normalizeRules();\n    };\n\n    ABCHighlightRules.metaData = {\n        fileTypes: ['abc'],\n        name: 'ABC',\n        scopeName: 'text.abcnotation'\n    };\n\n\n    oop.inherits(ABCHighlightRules, TextHighlightRules);\n\n    exports.ABCHighlightRules = ABCHighlightRules;\n"
  },
  {
    "path": "src/mode/actionscript.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ActionScriptHighlightRules = require(\"./actionscript_highlight_rules\").ActionScriptHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ActionScriptHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/actionscript\";\n    this.snippetFileId = \"ace/snippets/actionscript\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/actionscript_highlight_rules.js",
    "content": "/* This file was autogenerated from tm bundles\\actionscript.tmbundle\\Syntaxes\\ActionScript.plist (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ActionScriptHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'support.class.actionscript.2',\n           regex: '\\\\b(?:R(?:ecordset|DBMSResolver|adioButton(?:Group)?)|X(?:ML(?:Socket|Node|Connector)?|UpdateResolverDataHolder)|M(?:M(?:Save|Execute)|icrophoneMicrophone|o(?:use|vieClip(?:Loader)?)|e(?:nu(?:Bar)?|dia(?:Controller|Display|Playback))|ath)|B(?:yName|inding|utton)|S(?:haredObject|ystem|crollPane|t(?:yleSheet|age|ream)|ound|e(?:ndEvent|rviceObject)|OAPCall|lide)|N(?:umericStepper|et(?:stream|S(?:tream|ervices)|Connection|Debug(?:Config)?))|C(?:heckBox|o(?:ntextMenu(?:Item)?|okie|lor|m(?:ponentMixins|boBox))|ustomActions|lient|amera)|T(?:ypedValue|ext(?:Snapshot|Input|F(?:ield|ormat)|Area)|ree|AB)|Object|D(?:ownload|elta(?:Item|Packet)?|at(?:e(?:Chooser|Field)?|a(?:G(?:lue|rid)|Set|Type)))|U(?:RL|TC|IScrollBar)|P(?:opUpManager|endingCall|r(?:intJob|o(?:duct|gressBar)))|E(?:ndPoint|rror)|Video|Key|F(?:RadioButton|GridColumn|MessageBox|BarChart|S(?:croll(?:Bar|Pane)|tyleFormat|plitView)|orm|C(?:heckbox|omboBox|alendar)|unction|T(?:icker|ooltip(?:Lite)?|ree(?:Node)?)|IconButton|D(?:ataGrid|raggablePane)|P(?:ieChart|ushButton|ro(?:gressBar|mptBox))|L(?:i(?:stBox|neChart)|oadingBox)|AdvancedMessageBox)|W(?:indow|SDLURL|ebService(?:Connector)?)|L(?:ist|o(?:calConnection|ad(?:er|Vars)|g)|a(?:unch|bel))|A(?:sBroadcaster|cc(?:ordion|essibility)|S(?:Set(?:Native|PropFlags)|N(?:ew|ative)|C(?:onstructor|lamp(?:2)?)|InstanceOf)|pplication|lert|rray))\\\\b' },\n         { token: 'support.function.actionscript.2',\n           regex: '\\\\b(?:s(?:h(?:ift|ow(?:GridLines|Menu|Border|Settings|Headers|ColumnHeaders|Today|Preferences)?|ad(?:ow|ePane))|c(?:hema|ale(?:X|Mode|Y|Content)|r(?:oll(?:Track|Drag)?|een(?:Resolution|Color|DPI)))|t(?:yleSheet|op(?:Drag|A(?:nimation|llSounds|gent))?|epSize|a(?:tus|rt(?:Drag|A(?:nimation|gent))?))|i(?:n|ze|lence(?:TimeOut|Level))|o(?:ngname|urce|rt(?:Items(?:By)?|On(?:HeaderRelease)?|able(?:Columns)?)?)|u(?:ppressInvalidCalls|bstr(?:ing)?)|p(?:li(?:ce|t)|aceCol(?:umnsEqually|lumnsEqually))|e(?:nd(?:DefaultPushButtonEvent|AndLoad)?|curity|t(?:R(?:GB|o(?:otNode|w(?:Height|Count))|esizable(?:Columns)?|a(?:nge|te))|G(?:ain|roupName)|X(?:AxisTitle)?|M(?:i(?:n(?:imum|utes)|lliseconds)|o(?:nth(?:Names)?|tionLevel|de)|ultilineMode|e(?:ssage|nu(?:ItemEnabled(?:At)?|EnabledAt)|dia)|a(?:sk|ximum))|B(?:u(?:tton(?:s|Width)|fferTime)|a(?:seTabIndex|ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Target|P(?:osition|roperties)|barState|Location)|t(?:yle(?:Property)?|opOnFocus|at(?:us|e))|i(?:ze|lenceLevel)|ort(?:able(?:Columns)?|Function)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)?|Style|Color|ed(?:Node(?:s)?|Cell|I(?:nd(?:ices|ex)|tem(?:s)?))?|able))|kin|m(?:oothness|allScroll))|H(?:ighlight(?:s|Color)|Scroll|o(?:urs|rizontal)|eader(?:Symbol|Height|Text|Property|Format|Width|Location)?|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:ode(?:Properties|ExpansionHandler)|ewTextFormat)|C(?:h(?:ildNodes|a(?:ngeHandler|rt(?:Title|EventHandler)))|o(?:ntent(?:Size)?|okie|lumns)|ell(?:Symbol|Data)|l(?:i(?:ckHandler|pboard)|oseHandler)|redentials)|T(?:ype(?:dVaule)?|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:out(?:Handler)?)?)|oggle|extFormat|ransform)|I(?:s(?:Branch|Open)|n(?:terval|putProperty)|con(?:SymbolName)?|te(?:rator|m(?:ByKey|Symbol)))|Orientation|D(?:i(?:splay(?:Range|Graphics|Mode|Clip|Text|edMonth)|rection)|uration|e(?:pth(?:Below|To|Above)|fault(?:GatewayURL|Mappings|NodeIconSymbolName)|l(?:iveryMode|ay)|bug(?:ID)?)|a(?:yOfWeekNames|t(?:e(?:Filter)?|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Provider|All(?:Height|Property|Format|Width))?))|ra(?:wConnectors|gContent))|U(?:se(?:Shadow|HandCursor|EchoSuppression|rInput|Fade)|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear))|P(?:osition|ercentComplete|an(?:e(?:M(?:inimumSize|aximumSize)|Size|Title))?|ro(?:pert(?:y(?:Data)?|iesAt)|gress))|E(?:nabled|dit(?:Handler|able)|xpand(?:NodeTrigger|erSymbolName))|V(?:Scroll|olume|alue(?:Source)?)|KeyFrameInterval|Quality|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|ocus|ullYear|ps|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:opback|adTarget)|a(?:rgeScroll|bel(?:Source|Placement)?))|A(?:s(?:Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:e(?:State(?:Handler)?|Handler)|ateHandler)|utoH(?:ideScrollBar|eight)))?|paratorBefore|ek|lect(?:ion(?:Disabled|Unfocused)?|ed(?:Node(?:s)?|Child|I(?:nd(?:ices|ex)|tem(?:s)?)|Dat(?:e|a))?|able(?:Ranges)?)|rver(?:String)?)|kip|qrt|wapDepths|lice|aveToSharedObj|moothing)|h(?:scroll(?:Policy)?|tml(?:Text)?|i(?:t(?:Test(?:TextNearPos)?|Area)|de(?:BuiltInItems|Child)?|ghlight(?:2D|3D)?)|orizontal|e(?:ight|ader(?:Re(?:nderer|lease)|Height|Text))|P(?:osition|ageScrollSize)|a(?:s(?:childNodes|MP3|S(?:creen(?:Broadcast|Playback)|treaming(?:Video|Audio)|ort)|Next|OwnProperty|Pr(?:inting|evious)|EmbeddedVideo|VideoEncoder|A(?:ccesibility|udio(?:Encoder)?))|ndlerName)|LineScrollSize)|ye(?:sLabel|ar)|n(?:o(?:t|de(?:Name|Close|Type|Open|Value)|Label)|u(?:llValue|mChild(?:S(?:creens|lides)|ren|Forms))|e(?:w(?:Item|line|Value|LocationDialog)|xt(?:S(?:cene|ibling|lide)|TabIndex|Value|Frame)?)?|ame(?:s)?)|c(?:h(?:ildNodes|eck|a(?:nge(?:sPending)?|r(?:CodeAt|At))|r)|o(?:s|n(?:st(?:ant|ructor)|nect|c(?:urrency|at)|t(?:ent(?:Type|Path)?|ains|rol(?:Placement|lerPolicy))|denseWhite|version)|py|l(?:or|umn(?:Stretch|Name(?:s)?|Count))|m(?:p(?:onent|lete)|ment))|u(?:stomItems|ePoint(?:s)?|r(?:veTo|Value|rent(?:Slide|ChildSlide|Item|F(?:ocused(?:S(?:creen|lide)|Form)|ps))))|e(?:il|ll(?:Renderer|Press|Edit|Focus(?:In|Out)))|l(?:i(?:ck|ents)|o(?:se(?:Button|Pane)?|ne(?:Node)?)|ear(?:S(?:haredObjects|treams)|Timeout|Interval)?)|a(?:ncelLabel|tch|p(?:tion|abilities)|l(?:cFields|l(?:e(?:e|r))?))|reate(?:GatewayConnection|Menu|Se(?:rver|gment)|C(?:hild(?:AtDepth)?|l(?:ient|ass(?:ChildAtDepth|Object(?:AtDepth)?))|all)|Text(?:Node|Field)|Item|Object(?:AtDepth)?|PopUp|E(?:lement|mptyMovieClip)))|t(?:h(?:is|row)|ype(?:of|Name)?|i(?:tle(?:StyleDeclaration)?|me(?:out)?)|o(?:talTime|String|olTipText|p|UpperCase|ggle(?:HighQuality)?|Lo(?:caleString|werCase))|e(?:st|llTarget|xt(?:RightMargin|Bold|S(?:ize|elected)|Height|Color|I(?:ndent|talic)|Disabled|Underline|F(?:ield|ont)|Width|LeftMargin|Align)?)|a(?:n|rget(?:Path)?|b(?:Stops|Children|Index|Enabled|leName))|r(?:y|igger|ac(?:e|k(?:AsMenu)?)))|i(?:s(?:Running|Branch|NaN|Con(?:soleOpen|nected)|Toggled|Installed|Open|D(?:own|ebugger)|P(?:urchased|ro(?:totypeOf|pertyEnumerable))|Empty|F(?:inite|ullyPopulated)|Local|Active)|n(?:s(?:tall|ertBefore)|cludeDeltaPacketInfo|t|it(?:ialize|Component|Pod|A(?:pplication|gent))?|de(?:nt|terminate|x(?:InParent(?:Slide|Form)?|Of)?)|put|validate|finity|LocalInternetCache)?|con(?:F(?:ield|unction))?|t(?:e(?:ratorScrolled|m(?:s|RollO(?:ut|ver)|ClassName))|alic)|d3|p|fFrameLoaded|gnore(?:Case|White))|o(?:s|n(?:R(?:ollO(?:ut|ver)|e(?:s(?:ize|ult)|l(?:ease(?:Outside)?|aseOutside)))|XML|Mouse(?:Move|Down|Up|Wheel)|S(?:ync|croller|tatus|oundComplete|e(?:tFocus|lect(?:edItem)?))|N(?:oticeEvent|etworkChange)|C(?:hanged|onnect|l(?:ipEvent|ose))|ID3|D(?:isconnect|eactivate|ata|ragO(?:ut|ver))|Un(?:install|load)|P(?:aymentResult|ress)|EnterFrame|K(?:illFocus|ey(?:Down|Up))|Fault|Lo(?:ad|g)|A(?:ctiv(?:ity|ate)|ppSt(?:op|art)))?|pe(?:n|ration)|verLayChildren|kLabel|ldValue|r(?:d)?)|d(?:i(?:s(?:connect|play(?:Normal|ed(?:Month|Year)|Full)|able(?:Shader|d(?:Ranges|Days)|CloseBox|Events))|rection)|o(?:cTypeDecl|tall|Decoding|main|LazyDecoding)|u(?:plicateMovieClip|ration)|e(?:stroy(?:ChildAt|Object)|code|fault(?:PushButton(?:Enabled)?|KeydownHandler)?|l(?:ta(?:Packet(?:Changed)?)?|ete(?:PopUp|All)?)|blocking)|a(?:shBoardSave|yNames|ta(?:Provider)?|rkshadow)|r(?:opdown(?:Width)?|a(?:w|gO(?:ut|ver))))|u(?:se(?:Sort|HandCursor|Codepage|EchoSuppression)|n(?:shift|install|derline|escape|format|watch|lo(?:ck|ad(?:Movie(?:Num)?)?))|pdate(?:Results|Mode|I(?:nputProperties|tem(?:ByIndex)?)|P(?:acket|roperties)|View|AfterEvent)|rl)|join|p(?:ixelAspectRatio|o(?:sition|p|w)|u(?:sh|rge|blish)|ercen(?:tComplete|Loaded)|lay(?:head(?:Change|Time)|ing|Hidden|erType)?|a(?:ssword|use|r(?:se(?:XML|CSS|Int|Float)|ent(?:Node|Is(?:S(?:creen|lide)|Form))|ams))|r(?:int(?:Num|AsBitmap(?:Num)?)?|o(?:to(?:type)?|pert(?:y|ies)|gress)|e(?:ss|v(?:ious(?:S(?:ibling|lide)|Value)?|Scene|Frame)|ferred(?:Height|Width))))|e(?:scape|n(?:code(?:r)?|ter(?:Frame)?|dFill|able(?:Shader|d|CloseBox|Events))|dit(?:able|Field|LocationDialog)|v(?:ent|al(?:uate)?)|q|x(?:tended|p|ec(?:ute)?|actSettings)|m(?:phasized(?:StyleDeclaration)?|bedFonts))|v(?:i(?:sible|ewPod)|ScrollPolicy|o(?:id|lume)|ersion|P(?:osition|ageScrollSize)|a(?:l(?:idat(?:ionError|e(?:Property|ActivationKey)?)|ue(?:Of)?)|riable)|LineScrollSize)|k(?:ind|ey(?:Down|Up|Press|FrameInterval))|q(?:sort|uality)|f(?:scommand|i(?:n(?:d(?:Text|First|Last)?|ally)|eldInfo|lter(?:ed|Func)?|rst(?:Slide|Child|DayOfWeek|VisibleNode)?)|o(?:nt|cus(?:In|edCell|Out|Enabled)|r(?:egroundDisabled|mat(?:ter)?))|unctionName|ps|l(?:oor|ush)|ace|romCharCode)|w(?:i(?:th|dth)|ordWrap|atch|riteAccess)|l(?:t|i(?:st(?:Owner)?|ne(?:Style|To))|o(?:c(?:k|a(?:t(?:ion|eByld)|l(?:ToGlobal|FileReadDisable)))|opback|ad(?:Movie(?:Num)?|S(?:crollContent|ound)|ed|Variables(?:Num)?|Application)?|g(?:Changes)?)|e(?:ngth|ft(?:Margin)?|ading)?|a(?:st(?:Slide|Child|Index(?:Of)?)?|nguage|b(?:el(?:Placement|F(?:ield|unction))?|leField)))|a(?:s(?:scociate(?:Controller|Display)|in|pectRatio|function)|nd|c(?:ceptConnection|tiv(?:ityLevel|ePlayControl)|os)|t(?:t(?:ach(?:Movie|Sound|Video|Audio)|ributes)|an(?:2)?)|dd(?:header|RequestHeader|Menu(?:Item(?:At)?|At)?|Sort|Header|No(?:tice|de(?:At)?)|C(?:olumn(?:At)?|uePoint)|T(?:oLocalInternetCache|reeNode(?:At)?)|I(?:con|tem(?:s(?:At)?|At)?)|DeltaItem|P(?:od|age|roperty)|EventListener|View|FieldInfo|Listener|Animation)?|uto(?:Size|Play|KeyNav|Load)|pp(?:endChild|ly(?:Changes|Updates)?)|vHardwareDisable|fterLoaded|l(?:ternateRowColors|ign|l(?:ow(?:InsecureDomain|Domain)|Transitions(?:InDone|OutDone))|bum)|r(?:tist|row|g(?:uments|List))|gent|bs)|r(?:ight(?:Margin)?|o(?:ot(?:S(?:creen|lide)|Form)|und|w(?:Height|Count)|llO(?:ut|ver))|e(?:s(?:yncDepth|t(?:orePane|artAnimation|rict)|iz(?:e|able(?:Columns)?)|olveDelta|ult(?:s)?|ponse)|c(?:o(?:ncile(?:Results|Updates)|rd)|eive(?:Video|Audio))|draw|jectConnection|place(?:Sel|ItemAt|AllItems)?|ve(?:al(?:Child)?|rse)|quest(?:SizeChange|Payment)?|f(?:errer|resh(?:ScrollContent|Destinations|Pane|FromSources)?)|lease(?:Outside)?|ad(?:Only|Access)|gister(?:SkinElement|C(?:olor(?:Style|Name)|lass)|InheritingStyle|Proxy)|move(?:Range|M(?:ovieClip|enu(?:Item(?:At)?|At))|Background|Sort|No(?:tice|de(?:sAt|At)?)|C(?:olum(?:nAt|At)|uePoints)|T(?:extField|reeNode(?:At)?)|Item(?:At)?|Pod|EventListener|FromLocalInternetCache|Listener|All(?:C(?:olumns|uePoints)|Items)?))|a(?:ndom|te|dioDot))|g(?:t|oto(?:Slide|NextSlide|PreviousSlide|FirstSlide|LastSlide|And(?:Stop|Play))|e(?:nre|t(?:R(?:GB|o(?:otNode|wCount)|e(?:sizable|mote))|X(?:AxisTitle)?|M(?:i(?:n(?:imum(?:Size)?|utes)|lliseconds)|onth(?:Names)?|ultilineMode|e(?:ssage|nu(?:ItemAt|EnabledAt|At))|aximum(?:Size)?)|B(?:ytes(?:Total|Loaded)|ounds|utton(?:s|Width)|eginIndex|a(?:ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Position|barState|Location)|t(?:yle(?:Names)?|opOnFocus|ate)|ize|o(?:urce|rtState)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)|Style|ed(?:Node(?:s)?|Cell|Text|I(?:nd(?:ices|ex)|tem(?:s)?))?)|rvice)|moothness|WFVersion)|H(?:ighlight(?:s|Color)|ours|e(?:ight|ader(?:Height|Text|Property|Format|Width|Location)?)|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:o(?:tices|de(?:DisplayedAt|At))|um(?:Children|berAvailable)|e(?:wTextFormat|xtHighestDepth))|C(?:h(?:ild(?:S(?:creen|lide)|Nodes|Form|At)|artTitle)|o(?:n(?:tent|figInfo)|okie|de|unt|lumn(?:Names|Count|Index|At))|uePoint|ellIndex|loseHandler|a(?:ll|retIndex))|T(?:ypedValue|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:stamp|zoneOffset|out(?:State|Handler)|r)?)|oggle|ext(?:Extent|Format)?|r(?:ee(?:NodeAt|Length)|ans(?:form|actionId)))|I(?:s(?:Branch|Open)|n(?:stanceAtDepth|d(?:icesByKey|exByKey))|con(?:SymbolName)?|te(?:rator|m(?:sByKey|By(?:Name|Key)|id|ID|At))|d)|O(?:utput(?:Parameter(?:s|ByName)?|Value(?:s)?)|peration|ri(?:entation|ginalCellData))|D(?:i(?:s(?:play(?:Range|Mode|Clip|Index|edMonth)|kUsage)|rection)|uration|e(?:pth|faultNodeIconSymbolName|l(?:taPacket|ay)|bug(?:Config|ID)?)|a(?:y(?:OfWeekNames)?|t(?:e|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Label|All(?:Height|Property|Format|Width))?))|rawConnectors)|U(?:se(?:Shadow|HandCursor|rInput|Fade)|RL|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear))|P(?:o(?:sition|ds)|ercentComplete|a(?:n(?:e(?:M(?:inimums|aximums)|Height|Title|Width))?|rentNode)|r(?:operty(?:Name|Data)?|efer(?:ences|red(?:Height|Width))))|E(?:n(?:dIndex|abled)|ditingData|x(?:panderSymbolName|andNodeTrigger))|V(?:iewed(?:Pods|Applications)|olume|ersion|alue(?:Source)?)|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|o(?:ntList|cus)|ullYear|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:cal|adTarget)|ength|a(?:stTabIndex|bel(?:Source)?))|A(?:s(?:cii|Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:eState(?:Handler)?|ateHandler)|utoH(?:ideScrollBar|eight)|llItems|gent))?)?|lobal(?:StyleFormat|ToLocal)?|ain|roupName)|x(?:updatePackety|mlDecl)?|m(?:y(?:MethodName|Call)|in(?:imum)?|o(?:nthNames|tion(?:TimeOut|Level)|de(?:lChanged)?|use(?:Move|O(?:ut|ver)|Down(?:Somewhere|Outside)?|Up(?:Somewhere)?|WheelEnabled)|ve(?:To)?)|u(?:ted|lti(?:pleS(?:imultaneousAllowed|elections)|line))|e(?:ssage|nu(?:Show|Hide)?|th(?:od)?|diaType)|a(?:nufacturer|tch|x(?:scroll|hscroll|imum|HPosition|Chars|VPosition)?)|b(?:substring|chr|ord|length))|b(?:ytes(?:Total|Loaded)|indFormat(?:Strings|Function)|o(?:ttom(?:Scroll)?|ld|rder(?:Color)?)|u(?:tton(?:Height|Width)|iltInItems|ffer(?:Time|Length)|llet)|e(?:foreApplyUpdates|gin(?:GradientFill|Fill))|lockIndent|a(?:ndwidth|ckground(?:Style|Color|Disabled)?)|roadcastMessage)|onHTTPStatus)\\\\b' },\n         { token: 'support.constant.actionscript.2',\n           regex: '\\\\b(?:__proto__|__resolve|_accProps|_alpha|_changed|_currentframe|_droptarget|_flash|_focusrect|_framesloaded|_global|_height|_highquality|_level|_listeners|_lockroot|_name|_parent|_quality|_root|_rotation|_soundbuftime|_target|_totalframes|_url|_visible|_width|_x|_xmouse|_xscale|_y|_ymouse|_yscale)\\\\b' },\n         { token: 'keyword.control.actionscript.2',\n           regex: '\\\\b(?:dynamic|extends|import|implements|interface|public|private|new|static|super|var|for|in|break|continue|while|do|return|if|else|case|switch)\\\\b' },\n         { token: 'storage.type.actionscript.2',\n           regex: '\\\\b(?:Boolean|Number|String|Void)\\\\b' },\n         { token: 'constant.language.actionscript.2',\n           regex: '\\\\b(?:null|undefined|true|false)\\\\b' },\n         { token: 'constant.numeric.actionscript.2',\n           regex: '\\\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\\\.?[0-9]*|\\\\.[0-9]+)(?:(?:e|E)(?:\\\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\\\b' },\n         { token: 'punctuation.definition.string.begin.actionscript.2',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.actionscript.2',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.actionscript.2',\n                regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.double.actionscript.2' } ] },\n         { token: 'punctuation.definition.string.begin.actionscript.2',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.actionscript.2',\n                regex: '\\'',\n                next: 'pop' },\n              { token: 'constant.character.escape.actionscript.2',\n                regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.single.actionscript.2' } ] },\n         { token: 'support.constant.actionscript.2',\n           regex: '\\\\b(?:BACKSPACE|CAPSLOCK|CONTROL|DELETEKEY|DOWN|END|ENTER|HOME|INSERT|LEFT|LN10|LN2|LOG10E|LOG2E|MAX_VALUE|MIN_VALUE|NEGATIVE_INFINITY|NaN|PGDN|PGUP|PI|POSITIVE_INFINITY|RIGHT|SPACE|SQRT1_2|SQRT2|UP)\\\\b' },\n         { token: 'punctuation.definition.comment.actionscript.2',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.actionscript.2',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.actionscript.2' } ] },\n         { token: 'punctuation.definition.comment.actionscript.2',\n           regex: '//.*$',\n           push_: \n            [ { token: 'comment.line.double-slash.actionscript.2',\n                regex: '$',\n                next: 'pop' },\n              { defaultToken: 'comment.line.double-slash.actionscript.2' } ] },\n         { token: 'keyword.operator.actionscript.2',\n           regex: '\\\\binstanceof\\\\b' },\n         { token: 'keyword.operator.symbolic.actionscript.2',\n           regex: '[-!%&*+=/?:]' },\n         { token: \n            [ 'meta.preprocessor.actionscript.2',\n              'punctuation.definition.preprocessor.actionscript.2',\n              'meta.preprocessor.actionscript.2' ],\n           regex: '^([ \\\\t]*)(#)([a-zA-Z]+)' },\n         { token: \n            [ 'storage.type.function.actionscript.2',\n              'meta.function.actionscript.2',\n              'entity.name.function.actionscript.2',\n              'meta.function.actionscript.2',\n              'punctuation.definition.parameters.begin.actionscript.2' ],\n           regex: '\\\\b(function)(\\\\s+)([a-zA-Z_]\\\\w*)(\\\\s*)(\\\\()',\n           push: \n            [ { token: 'punctuation.definition.parameters.end.actionscript.2',\n                regex: '\\\\)',\n                next: 'pop' },\n              { token: 'variable.parameter.function.actionscript.2',\n                regex: '[^,)$]+' },\n              { defaultToken: 'meta.function.actionscript.2' } ] },\n         { token: \n            [ 'storage.type.class.actionscript.2',\n              'meta.class.actionscript.2',\n              'entity.name.type.class.actionscript.2',\n              'meta.class.actionscript.2',\n              'storage.modifier.extends.actionscript.2',\n              'meta.class.actionscript.2',\n              'entity.other.inherited-class.actionscript.2' ],\n           regex: '\\\\b(class)(\\\\s+)([a-zA-Z_](?:\\\\w|\\\\.)*)(?:(\\\\s+)(extends)(\\\\s+)([a-zA-Z_](?:\\\\w|\\\\.)*))?' } ] };\n    \n    this.normalizeRules();\n};\n\nActionScriptHighlightRules.metaData = { fileTypes: [ 'as' ],\n      keyEquivalent: '^~A',\n      name: 'ActionScript',\n      scopeName: 'source.actionscript.2' };\n\n\noop.inherits(ActionScriptHighlightRules, TextHighlightRules);\n\nexports.ActionScriptHighlightRules = ActionScriptHighlightRules;\n"
  },
  {
    "path": "src/mode/ada.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AdaHighlightRules = require(\"./ada_highlight_rules\").AdaHighlightRules;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = AdaHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"--\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        //  Indent when line ends with one of the following keywords\n        if (state == \"start\") {\n            var match = line.match(/^.*(begin|loop|then|is|do)\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        var complete_line = line + input;\n\n        // Outdent when the current line contains begin or end, and nothing\n        // else. This ensures that we'll send the signal only once.\n        if (complete_line.match(/^\\s*(begin|end)$/)) {\n            return true;\n        }\n\n        return false;\n    };\n\n    this.autoOutdent = function(state, session, row) {\n\n        var line = session.getLine(row);\n        var prevLine = session.getLine(row - 1);\n        var prevIndent = this.$getIndent(prevLine).length;\n        var indent = this.$getIndent(line).length;\n\n        // Don't outdent if current line is at the same level as the last one,\n        // it means that the user outdented himself\n        if (indent <= prevIndent) {\n            return;\n        }\n\n        session.outdentRows(new Range(row, 0, row + 2, 0));\n    };\n\n\n    this.$id = \"ace/mode/ada\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ada_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AdaHighlightRules = function() {\nvar keywords = \"abort|else|new|return|abs|elsif|not|reverse|abstract|end|null|accept|entry|select|\" +\n\"access|exception|of|separate|aliased|exit|or|some|all|others|subtype|and|for|out|synchronized|\" +\n\"array|function|overriding|at|tagged|generic|package|task|begin|goto|pragma|terminate|\" +\n\"body|private|then|if|procedure|type|case|in|protected|constant|interface|until|\" +\n\"|is|raise|use|declare|range|delay|limited|record|when|delta|loop|rem|while|digits|renames|with|do|mod|requeue|xor\";\n\n    var builtinConstants = (\n        \"true|false|null\"\n    );\n\n    var builtinFunctions = (\n        \"count|min|max|avg|sum|rank|now|coalesce|main\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"--.*$\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\".*?\"'\n        }, {\n            token : \"string\",           // character\n            regex : \"'.'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n};\n\noop.inherits(AdaHighlightRules, TextHighlightRules);\n\nexports.AdaHighlightRules = AdaHighlightRules;\n"
  },
  {
    "path": "src/mode/ada_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar AdaMode = require(\"./ada\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new AdaMode();\n    },\n\n    \"test: auto outdent after 'begin' and 'end'\": function() {\n        assert.ok(this.mode.checkOutdent(\"start\", \"        begi\", \"n\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        en\", \"d\"));\n    },\n\n    \"test: auto outdent\" : function() {\n        var session = new EditSession([\n            \"procedure Pouet is\",\n            \"    begin\"\n        ]);\n        this.mode.autoOutdent(\"start\", session, 1);\n        assert.equal(\"begin\", session.getLine(1));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/alda.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AldaHighlightRules = require(\"./alda_highlight_rules\").AldaHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AldaHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // this.lineCommentStart = \"\"\\\\(comment\\\\b\"\";\n    // this.blockComment = {start: \"\"/*\"\", end: \"\"*/\"\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/alda\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/alda_highlight_rules.js",
    "content": "/* This file was autogenerated from ../../src/alda.JSON-tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n    \"use strict\";\n    \n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n    \n    var AldaHighlightRules = function() {\n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n    \n        this.$rules = {\n            pitch: [{\n                token: \"variable.parameter.operator.pitch.alda\",\n                regex: /(?:[+\\-]+|\\=)/\n            }, {\n                token: \"\",\n                regex: \"\",\n                next: \"timing\"\n            }],\n            timing: [{\n                token: \"string.quoted.operator.timing.alda\",\n                regex: /\\d+(?:s|ms)?/\n            }, {\n                token: \"\",\n                regex: \"\",\n                next: \"start\"\n            }],\n            start: [{\n                token: [\n                    \"constant.language.instrument.alda\",\n                    \"constant.language.instrument.alda\",\n                    \"meta.part.call.alda\",\n                    \"storage.type.nickname.alda\",\n                    \"meta.part.call.alda\"\n                ],\n                regex: /^([a-zA-Z]{2}[\\w\\-+\\'()]*)((?:\\s*\\/\\s*[a-zA-Z]{2}[\\w\\-+\\'()]*)*)(?:(\\s*)(\\\"[a-zA-Z]{2}[\\w\\-+\\'()]*\\\"))?(\\s*:)/\n            }, {\n                token: [\n                    \"text\",\n                    \"entity.other.inherited-class.voice.alda\",\n                    \"text\"\n                ],\n                regex: /^(\\s*)(V\\d+)(:)/\n            }, {\n                token: \"comment.line.number-sign.alda\",\n                regex: /#.*$/\n            }, {\n                token: \"entity.name.function.pipe.measure.alda\",\n                regex: /\\|/\n            }, {\n                token: \"comment.block.inline.alda\",\n                regex: /\\(comment\\b/,\n                push: [{\n                    token: \"comment.block.inline.alda\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"comment.block.inline.alda\"\n                }]\n            }, {\n                token: \"entity.name.function.marker.alda\",\n                regex: /%[a-zA-Z]{2}[\\w\\-+\\'()]*/\n            }, {\n                token: \"entity.name.function.at-marker.alda\",\n                regex: /@[a-zA-Z]{2}[\\w\\-+\\'()]*/\n            }, {\n                token: \"keyword.operator.octave-change.alda\",\n                regex: /\\bo\\d+\\b/\n            }, {\n                token: \"keyword.operator.octave-shift.alda\",\n                regex: /[><]/\n            }, {\n                token: \"keyword.operator.repeat.alda\",\n                regex: /\\*\\s*\\d+/\n            }, {\n                token: \"string.quoted.operator.timing.alda\",\n                regex: /[.]|r\\d*(?:s|ms)?/\n            },{\n                token: \"text\",\n                regex: /([cdefgab])/,\n                next: \"pitch\"\n            }, {\n                token: \"string.quoted.operator.timing.alda\",\n                regex: /~/,\n                next: \"timing\"\n            }, {\n                token: \"punctuation.section.embedded.cram.alda\",\n                regex: /\\}/,\n                next: \"timing\"\n            }, {\n                token: \"constant.numeric.subchord.alda\",\n                regex: /\\//\n            }, {\n                todo: {\n                    token: \"punctuation.section.embedded.cram.alda\",\n                    regex: /\\{/,\n                    push: [{\n                        token: \"punctuation.section.embedded.cram.alda\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    }, {\n                        include: \"$self\"\n                    }]\n                }\n            }, {\n                todo: {\n                    token: \"keyword.control.sequence.alda\",\n                    regex: /\\[/,\n                    push: [{\n                        token: \"keyword.control.sequence.alda\",\n                        regex: /\\]/,\n                        next: \"pop\"\n                    }, {\n                        include: \"$self\"\n                    }]\n                }\n            }, {\n                token: \"meta.inline.clojure.alda\",\n                regex: /\\(/,\n                push: [{\n                    token: \"meta.inline.clojure.alda\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"source.clojure\"\n                }, {\n                    defaultToken: \"meta.inline.clojure.alda\"\n                }]\n            }]\n        };\n        \n        this.normalizeRules();\n    };\n    \n    AldaHighlightRules.metaData = {\n        scopeName: \"source.alda\",\n        fileTypes: [\"alda\"],\n        name: \"Alda\"\n    };\n    \n    \n    oop.inherits(AldaHighlightRules, TextHighlightRules);\n    \n    exports.AldaHighlightRules = AldaHighlightRules;\n"
  },
  {
    "path": "src/mode/apache_conf.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ApacheConfHighlightRules = require(\"./apache_conf_highlight_rules\").ApacheConfHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ApacheConfHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/apache_conf\";\n    // Extra logic goes here.\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/apache_conf_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/colinta/ApacheConf.tmLanguage/master/ApacheConf.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ApacheConfHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: \n            [ 'punctuation.definition.comment.apacheconf',\n              'comment.line.hash.ini',\n              'comment.line.hash.ini' ],\n           regex: '^((?:\\\\s)*)(#)(.*$)' },\n         { token: \n            [ 'punctuation.definition.tag.apacheconf',\n              'entity.tag.apacheconf',\n              'text',\n              'string.value.apacheconf',\n              'punctuation.definition.tag.apacheconf' ],\n           regex: '(<)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost)(?:(\\\\s)(.+?))?(>)' },\n         { token: \n            [ 'punctuation.definition.tag.apacheconf',\n              'entity.tag.apacheconf',\n              'punctuation.definition.tag.apacheconf' ],\n           regex: '(</)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost)(>)' },\n         { token: \n            [ 'keyword.alias.apacheconf', 'text',\n              'string.regexp.apacheconf', 'text',\n              'string.replacement.apacheconf', 'text' ],\n           regex: '(Rewrite(?:Rule|Cond))(\\\\s+)(.+?)(\\\\s+)(.+?)($|\\\\s)' },\n         { token: \n            [ 'keyword.alias.apacheconf', 'text',\n              'entity.status.apacheconf', 'text',\n              'string.regexp.apacheconf', 'text',\n              'string.path.apacheconf', 'text' ],\n           regex: '(RedirectMatch)(?:(\\\\s+)(\\\\d\\\\d\\\\d|permanent|temp|seeother|gone))?(\\\\s+)(.+?)(\\\\s+)(?:(.+?)($|\\\\s))?' },\n         { token: \n            [ 'keyword.alias.apacheconf', 'text', \n              'entity.status.apacheconf', 'text',\n              'string.path.apacheconf', 'text',\n              'string.path.apacheconf', 'text' ],\n           regex: '(Redirect)(?:(\\\\s+)(\\\\d\\\\d\\\\d|permanent|temp|seeother|gone))?(\\\\s+)(.+?)(\\\\s+)(?:(.+?)($|\\\\s))?' },\n         { token: \n            [ 'keyword.alias.apacheconf', 'text',\n              'string.regexp.apacheconf', 'text',\n              'string.path.apacheconf', 'text' ],\n           regex: '(ScriptAliasMatch|AliasMatch)(\\\\s+)(.+?)(\\\\s+)(?:(.+?)(\\\\s))?' },\n         { token: \n            [ 'keyword.alias.apacheconf', 'text',\n              'string.path.apacheconf', 'text',\n              'string.path.apacheconf', 'text' ],\n           regex: '(RedirectPermanent|RedirectTemp|ScriptAlias|Alias)(\\\\s+)(.+?)(\\\\s+)(?:(.+?)($|\\\\s))?' },\n         { token: 'keyword.core.apacheconf',\n           regex: '\\\\b(?:AcceptPathInfo|AccessFileName|AddDefaultCharset|AddOutputFilterByType|AllowEncodedSlashes|AllowOverride|AuthName|AuthType|CGIMapExtension|ContentDigest|DefaultType|DocumentRoot|EnableMMAP|EnableSendfile|ErrorDocument|ErrorLog|FileETag|ForceType|HostnameLookups|IdentityCheck|Include|KeepAlive|KeepAliveTimeout|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|LogLevel|MaxKeepAliveRequests|NameVirtualHost|Options|Require|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScriptInterpreterSource|ServerAdmin|ServerAlias|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|SetHandler|SetInputFilter|SetOutputFilter|TimeOut|TraceEnable|UseCanonicalName)\\\\b' },\n         { token: 'keyword.mpm.apacheconf',\n           regex: '\\\\b(?:AcceptMutex|AssignUserID|BS2000Account|ChildPerUserID|CoreDumpDirectory|EnableExceptionHook|Group|Listen|ListenBacklog|LockFile|MaxClients|MaxMemFree|MaxRequestsPerChild|MaxRequestsPerThread|MaxSpareServers|MaxSpareThreads|MaxThreads|MaxThreadsPerChild|MinSpareServers|MinSpareThreads|NumServers|PidFile|ReceiveBufferSize|ScoreBoardFile|SendBufferSize|ServerLimit|StartServers|StartThreads|ThreadLimit|ThreadsPerChild|ThreadStackSize|User|Win32DisableAcceptEx)\\\\b' },\n         { token: 'keyword.access.apacheconf',\n           regex: '\\\\b(?:Allow|Deny|Order)\\\\b' },\n         { token: 'keyword.actions.apacheconf',\n           regex: '\\\\b(?:Action|Script)\\\\b' },\n         { token: 'keyword.alias.apacheconf',\n           regex: '\\\\b(?:Alias|AliasMatch|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ScriptAlias|ScriptAliasMatch)\\\\b' },\n         { token: 'keyword.auth.apacheconf',\n           regex: '\\\\b(?:AuthAuthoritative|AuthGroupFile|AuthUserFile)\\\\b' },\n         { token: 'keyword.auth_anon.apacheconf',\n           regex: '\\\\b(?:Anonymous|Anonymous_Authoritative|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail)\\\\b' },\n         { token: 'keyword.auth_dbm.apacheconf',\n           regex: '\\\\b(?:AuthDBMAuthoritative|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile)\\\\b' },\n         { token: 'keyword.auth_digest.apacheconf',\n           regex: '\\\\b(?:AuthDigestAlgorithm|AuthDigestDomain|AuthDigestFile|AuthDigestGroupFile|AuthDigestNcCheck|AuthDigestNonceFormat|AuthDigestNonceLifetime|AuthDigestQop|AuthDigestShmemSize)\\\\b' },\n         { token: 'keyword.auth_ldap.apacheconf',\n           regex: '\\\\b(?:AuthLDAPAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPEnabled|AuthLDAPFrontPageHack|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPRemoteUserIsDN|AuthLDAPUrl)\\\\b' },\n         { token: 'keyword.autoindex.apacheconf',\n           regex: '\\\\b(?:AddAlt|AddAltByEncoding|AddAltByType|AddDescription|AddIcon|AddIconByEncoding|AddIconByType|DefaultIcon|HeaderName|IndexIgnore|IndexOptions|IndexOrderDefault|ReadmeName)\\\\b' },\n         { token: 'keyword.cache.apacheconf',\n           regex: '\\\\b(?:CacheDefaultExpire|CacheDisable|CacheEnable|CacheForceCompletion|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheLastModifiedFactor|CacheMaxExpire)\\\\b' },\n         { token: 'keyword.cern_meta.apacheconf',\n           regex: '\\\\b(?:MetaDir|MetaFiles|MetaSuffix)\\\\b' },\n         { token: 'keyword.cgi.apacheconf',\n           regex: '\\\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength)\\\\b' },\n         { token: 'keyword.cgid.apacheconf',\n           regex: '\\\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock)\\\\b' },\n         { token: 'keyword.charset_lite.apacheconf',\n           regex: '\\\\b(?:CharsetDefault|CharsetOptions|CharsetSourceEnc)\\\\b' },\n         { token: 'keyword.dav.apacheconf',\n           regex: '\\\\b(?:Dav|DavDepthInfinity|DavMinTimeout|DavLockDB)\\\\b' },\n         { token: 'keyword.deflate.apacheconf',\n           regex: '\\\\b(?:DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateMemLevel|DeflateWindowSize)\\\\b' },\n         { token: 'keyword.dir.apacheconf',\n           regex: '\\\\b(?:DirectoryIndex|DirectorySlash)\\\\b' },\n         { token: 'keyword.disk_cache.apacheconf',\n           regex: '\\\\b(?:CacheDirLength|CacheDirLevels|CacheExpiryCheck|CacheGcClean|CacheGcDaily|CacheGcInterval|CacheGcMemUsage|CacheGcUnused|CacheMaxFileSize|CacheMinFileSize|CacheRoot|CacheSize|CacheTimeMargin)\\\\b' },\n         { token: 'keyword.dumpio.apacheconf',\n           regex: '\\\\b(?:DumpIOInput|DumpIOOutput)\\\\b' },\n         { token: 'keyword.env.apacheconf',\n           regex: '\\\\b(?:PassEnv|SetEnv|UnsetEnv)\\\\b' },\n         { token: 'keyword.expires.apacheconf',\n           regex: '\\\\b(?:ExpiresActive|ExpiresByType|ExpiresDefault)\\\\b' },\n         { token: 'keyword.ext_filter.apacheconf',\n           regex: '\\\\b(?:ExtFilterDefine|ExtFilterOptions)\\\\b' },\n         { token: 'keyword.file_cache.apacheconf',\n           regex: '\\\\b(?:CacheFile|MMapFile)\\\\b' },\n         { token: 'keyword.headers.apacheconf',\n           regex: '\\\\b(?:Header|RequestHeader)\\\\b' },\n         { token: 'keyword.imap.apacheconf',\n           regex: '\\\\b(?:ImapBase|ImapDefault|ImapMenu)\\\\b' },\n         { token: 'keyword.include.apacheconf',\n           regex: '\\\\b(?:SSIEndTag|SSIErrorMsg|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|XBitHack)\\\\b' },\n         { token: 'keyword.isapi.apacheconf',\n           regex: '\\\\b(?:ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer)\\\\b' },\n         { token: 'keyword.ldap.apacheconf',\n           regex: '\\\\b(?:LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionTimeout|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTrustedCA|LDAPTrustedCAType)\\\\b' },\n         { token: 'keyword.log.apacheconf',\n           regex: '\\\\b(?:BufferedLogs|CookieLog|CustomLog|LogFormat|TransferLog|ForensicLog)\\\\b' },\n         { token: 'keyword.mem_cache.apacheconf',\n           regex: '\\\\b(?:MCacheMaxObjectCount|MCacheMaxObjectSize|MCacheMaxStreamingBuffer|MCacheMinObjectSize|MCacheRemovalAlgorithm|MCacheSize)\\\\b' },\n         { token: 'keyword.mime.apacheconf',\n           regex: '\\\\b(?:AddCharset|AddEncoding|AddHandler|AddInputFilter|AddLanguage|AddOutputFilter|AddType|DefaultLanguage|ModMimeUsePathInfo|MultiviewsMatch|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|TypesConfig)\\\\b' },\n         { token: 'keyword.misc.apacheconf',\n           regex: '\\\\b(?:ProtocolEcho|Example|AddModuleInfo|MimeMagicFile|CheckSpelling|ExtendedStatus|SuexecUserGroup|UserDir)\\\\b' },\n         { token: 'keyword.negotiation.apacheconf',\n           regex: '\\\\b(?:CacheNegotiatedDocs|ForceLanguagePriority|LanguagePriority)\\\\b' },\n         { token: 'keyword.nw_ssl.apacheconf',\n           regex: '\\\\b(?:NWSSLTrustedCerts|NWSSLUpgradeable|SecureListen)\\\\b' },\n         { token: 'keyword.proxy.apacheconf',\n           regex: '\\\\b(?:AllowCONNECT|NoProxy|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyFtpDirCharset|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassReverse|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxyTimeout|ProxyVia)\\\\b' },\n         { token: 'keyword.rewrite.apacheconf',\n           regex: '\\\\b(?:RewriteBase|RewriteCond|RewriteEngine|RewriteLock|RewriteLog|RewriteLogLevel|RewriteMap|RewriteOptions|RewriteRule)\\\\b' },\n         { token: 'keyword.setenvif.apacheconf',\n           regex: '\\\\b(?:BrowserMatch|BrowserMatchNoCase|SetEnvIf|SetEnvIfNoCase)\\\\b' },\n         { token: 'keyword.so.apacheconf',\n           regex: '\\\\b(?:LoadFile|LoadModule)\\\\b' },\n         { token: 'keyword.ssl.apacheconf',\n           regex: '\\\\b(?:SSLCACertificateFile|SSLCACertificatePath|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLEngine|SSLMutex|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLUserName|SSLVerifyClient|SSLVerifyDepth)\\\\b' },\n         { token: 'keyword.usertrack.apacheconf',\n           regex: '\\\\b(?:CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking)\\\\b' },\n         { token: 'keyword.vhost_alias.apacheconf',\n           regex: '\\\\b(?:VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP)\\\\b' },\n         { token: \n            [ 'keyword.php.apacheconf',\n              'text',\n              'entity.property.apacheconf',\n              'text',\n              'string.value.apacheconf',\n              'text' ],\n           regex: '\\\\b(php_value|php_flag)\\\\b(?:(\\\\s+)(.+?)(?:(\\\\s+)(.+?))?)?(\\\\s)' },\n         { token: \n            [ 'punctuation.variable.apacheconf',\n              'variable.env.apacheconf',\n              'variable.misc.apacheconf',\n              'punctuation.variable.apacheconf' ],\n           regex: '(%\\\\{)(?:(HTTP_USER_AGENT|HTTP_REFERER|HTTP_COOKIE|HTTP_FORWARDED|HTTP_HOST|HTTP_PROXY_CONNECTION|HTTP_ACCEPT|REMOTE_ADDR|REMOTE_HOST|REMOTE_PORT|REMOTE_USER|REMOTE_IDENT|REQUEST_METHOD|SCRIPT_FILENAME|PATH_INFO|QUERY_STRING|AUTH_TYPE|DOCUMENT_ROOT|SERVER_ADMIN|SERVER_NAME|SERVER_ADDR|SERVER_PORT|SERVER_PROTOCOL|SERVER_SOFTWARE|TIME_YEAR|TIME_MON|TIME_DAY|TIME_HOUR|TIME_MIN|TIME_SEC|TIME_WDAY|TIME|API_VERSION|THE_REQUEST|REQUEST_URI|REQUEST_FILENAME|IS_SUBREQ|HTTPS)|(.*?))(\\\\})' },\n         { token: [ 'entity.mime-type.apacheconf', 'text' ],\n           regex: '\\\\b((?:text|image|application|video|audio)/.+?)(\\\\s)' },\n         { token: 'entity.helper.apacheconf',\n           regex: '\\\\b(?:from|unset|set|on|off)\\\\b',\n           caseInsensitive: true },\n         { token: 'constant.integer.apacheconf', regex: '\\\\b\\\\d+\\\\b' },\n         { token: \n            [ 'text',\n              'punctuation.definition.flag.apacheconf',\n              'string.flag.apacheconf',\n              'punctuation.definition.flag.apacheconf',\n              'text' ],\n           regex: '(\\\\s)(\\\\[)(.*?)(\\\\])(\\\\s)' } ] };\n    \n    this.normalizeRules();\n};\n\nApacheConfHighlightRules.metaData = { fileTypes: \n       [ 'conf',\n         'CONF',\n         'htaccess',\n         'HTACCESS',\n         'htgroups',\n         'HTGROUPS',\n         'htpasswd',\n         'HTPASSWD',\n         '.htaccess',\n         '.HTACCESS',\n         '.htgroups',\n         '.HTGROUPS',\n         '.htpasswd',\n         '.HTPASSWD' ],\n      name: 'Apache Conf',\n      scopeName: 'source.apacheconf' };\n\n\noop.inherits(ApacheConfHighlightRules, TextHighlightRules);\n\nexports.ApacheConfHighlightRules = ApacheConfHighlightRules;\n"
  },
  {
    "path": "src/mode/apex.js",
    "content": "/* caption: Apex; extensions: apex,cls,trigger,tgr */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"../mode/text\").Mode;\nvar ApexHighlightRules = require(\"./apex_highlight_rules\").ApexHighlightRules;\nvar FoldMode = require(\"../mode/folding/cstyle\").FoldMode;\n\nfunction ApexMode() {\n    TextMode.call(this);\n\n    this.HighlightRules = ApexHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n}\n\noop.inherits(ApexMode, TextMode);\n\nApexMode.prototype.lineCommentStart = \"//\";\n\nApexMode.prototype.blockComment = {\n    start: \"/*\",\n    end: \"*/\"\n};\n\nexports.Mode = ApexMode;\n"
  },
  {
    "path": "src/mode/apex_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"../mode/text_highlight_rules\").TextHighlightRules;\nvar DocCommentHighlightRules = require(\"../mode/doc_comment_highlight_rules\").DocCommentHighlightRules;\n\nvar ApexHighlightRules = function() {\n    var mainKeywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"activate|any|autonomous|begin|bigdecimal|byte|cast|char|collect|const\"\n             + \"|end|exit|export|float|goto|group|having|hint|import|inner|into|join|loop|number|object|of|outer\"\n             + \"|parallel|pragma|retrieve|returning|search|short|stat|synchronized|then|this_month\"\n             + \"|transaction|type|when\",\n        \"keyword\": \"private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final\"\n             + \"|and|array|as|asc|break|bulk|by|catch|class|commit|continue|convertcurrency\"\n             + \"|delete|desc|do|else|enum|extends|false|final|finally|for|from|future|global\"\n             + \"|if|implements|in|insert|instanceof|interface|last_90_days|last_month\"\n             + \"|last_n_days|last_week|like|limit|list|map|merge|new|next_90_days|next_month|next_n_days\"\n             + \"|next_week|not|null|nulls|on|or|override|package|return\"\n             + \"|rollback|savepoint|select|set|sort|super|testmethod|this|this_week|throw|today\"\n             + \"|tolabel|tomorrow|trigger|true|try|undelete|update|upsert|using|virtual|webservice\"\n             + \"|where|while|yesterday|switch|case|default\",\n        \"storage.type\":\n            \"def|boolean|byte|char|short|int|float|pblob|date|datetime|decimal|double|id|integer|long|string|time|void|blob|Object\",\n        \"constant.language\":\n            \"true|false|null|after|before|count|excludes|first|includes|last|order|sharing|with\",\n        \"support.function\":\n            \"system|apex|label|apexpages|userinfo|schema\"\n    }, \"identifier\", true);\n    function keywordMapper(value) {\n        if (value.slice(-3) == \"__c\") return \"support.function\";\n        return mainKeywordMapper(value);\n    }\n    \n    function string(start, options) {\n        return {\n            regex: start + (options.multiline ? \"\" : \"(?=.)\"),\n            token: \"string.start\",\n            next: [{\n                regex: options.escape,\n                token: \"character.escape\"\n            }, {\n                regex: options.error,\n                token: \"error.invalid\"\n            }, {\n                regex: start + (options.multiline ? \"\" : \"|$\"),\n                token: \"string.end\",\n                next: options.next || \"start\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        };\n    }\n    \n    function comments() {\n        return [{\n                token : \"comment\",\n                regex : \"\\\\/\\\\/(?=.)\",\n                next : [\n                    DocCommentHighlightRules.getTagRule(),\n                    {token : \"comment\", regex : \"$|^\", next : \"start\"},\n                    {defaultToken : \"comment\", caseInsensitive: true}\n                ]\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : /\\/\\*/,\n                next : [\n                    DocCommentHighlightRules.getTagRule(),\n                    {token : \"comment\", regex : \"\\\\*\\\\/\", next : \"start\"},\n                    {defaultToken : \"comment\", caseInsensitive: true}\n                ]\n            }\n        ];\n    }\n    \n    this.$rules = {\n        start: [\n            string(\"'\", {\n                escape: /\\\\[nb'\"\\\\]/,\n                error: /\\\\./,\n                multiline: false\n            }),\n            comments(\"c\"),\n            {\n                type: \"decoration\",\n                token: [\n                    \"meta.package.apex\",\n                    \"keyword.other.package.apex\",\n                    \"meta.package.apex\",\n                    \"storage.modifier.package.apex\",\n                    \"meta.package.apex\",\n                    \"punctuation.terminator.apex\"\n                ],\n                regex: /^(\\s*)(package)\\b(?:(\\s*)([^ ;$]+)(\\s*)((?:;)?))?/\n            }, {\n                 regex: /@[a-zA-Z_$][a-zA-Z_$\\d\\u0080-\\ufffe]*/,\n                 token: \"constant.language\"\n            },\n            {\n                regex: /[a-zA-Z_$][a-zA-Z_$\\d\\u0080-\\ufffe]*/,\n                token: keywordMapper\n            },  \n            {\n                regex: \"`#%\",\n                token: \"error.invalid\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : /[+-]?\\d+(?:(?:\\.\\d*)?(?:[LlDdEe][+-]?\\d+)?)\\b|\\.\\d+[LlDdEe]/\n            }, {\n                token : \"keyword.operator\",\n                regex : /--|\\+\\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|[!$%&*+\\-~\\/^]=?/,\n                next  : \"start\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[?:,;.]/,\n                next  : \"start\"\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[]/,\n                next  : \"maybe_soql\",\n                merge : false\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[({]/,\n                next  : \"start\",\n                merge : false\n            }, {\n                token : \"paren.rparen\",\n                regex : /[\\])}]/,\n                merge : false\n            } \n        ], \n        maybe_soql: [{\n            regex: /\\s+/,\n            token: \"text\"\n        }, {\n            regex: /(SELECT|FIND)\\b/,\n            token: \"keyword\",\n            caseInsensitive: true,\n            next: \"soql\"\n        }, {\n            regex: \"\",\n            token: \"none\",\n            next: \"start\"\n        }],\n        soql: [{\n            regex: \"(:?ASC|BY|CATEGORY|CUBE|DATA|DESC|END|FIND|FIRST|FOR|FROM|GROUP|HAVING|IN|LAST\"\n                + \"|LIMIT|NETWORK|NULLS|OFFSET|ORDER|REFERENCE|RETURNING|ROLLUP|SCOPE|SELECT\"\n                + \"|SNIPPET|TRACKING|TYPEOF|UPDATE|USING|VIEW|VIEWSTAT|WHERE|WITH|AND|OR)\\\\b\",\n            token: \"keyword\",\n            caseInsensitive: true\n        }, {\n            regex: \"(:?target_length|toLabel|convertCurrency|count|Contact|Account|User|FIELDS)\\\\b\",\n            token: \"support.function\",\n            caseInsensitive: true\n        }, {\n            token : \"paren.rparen\",\n            regex : /[\\]]/,\n            next  : \"start\",\n            merge : false\n        }, \n        string(\"'\", {\n            escape: /\\\\[nb'\"\\\\]/,\n            error: /\\\\./,\n            multiline: false,\n            next: \"soql\"\n        }),\n        string('\"', {\n            escape: /\\\\[nb'\"\\\\]/,\n            error: /\\\\./,\n            multiline: false,\n            next: \"soql\"\n        }),\n        {\n            regex: /\\\\./,\n            token: \"character.escape\"\n        },\n        {\n            regex : /[\\?\\&\\|\\!\\{\\}\\[\\]\\(\\)\\^\\~\\*\\:\\\"\\'\\+\\-\\,\\.=\\\\\\/]/,\n            token : \"keyword.operator\"\n        }],\n        \n        \"log-start\" : [ {\n            token : \"timestamp.invisible\",\n            regex : /^[\\d:.() ]+\\|/, \n            next: \"log-header\"\n        },  {\n            token : \"timestamp.invisible\",\n            regex : /^  (Number of|Maximum)[^:]*:/,\n            next: \"log-comment\"\n        }, {\n            token : \"invisible\",\n            regex : /^Execute Anonymous:/,\n            next: \"log-comment\"\n        },  {\n            defaultToken: \"text\"\n        }],\n        \"log-comment\": [{\n            token : \"log-comment\",\n            regex : /.*$/,\n            next: \"log-start\"\n        }],\n        \"log-header\": [{\n            token : \"timestamp.invisible\",\n            regex : /((USER_DEBUG|\\[\\d+\\]|DEBUG)\\|)+/\n        },\n        {\n            token : \"keyword\",\n            regex: \"(?:EXECUTION_FINISHED|EXECUTION_STARTED|CODE_UNIT_STARTED\"\n                + \"|CUMULATIVE_LIMIT_USAGE|LIMIT_USAGE_FOR_NS\"\n                + \"|CUMULATIVE_LIMIT_USAGE_END|CODE_UNIT_FINISHED)\"\n        }, {\n            regex: \"\",\n            next: \"log-start\"\n        }]\n    };\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n        \n\n    this.normalizeRules();\n};\n\n\noop.inherits(ApexHighlightRules, TextHighlightRules);\n\nexports.ApexHighlightRules = ApexHighlightRules;\n"
  },
  {
    "path": "src/mode/applescript.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AppleScriptHighlightRules = require(\"./applescript_highlight_rules\").AppleScriptHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AppleScriptHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"(*\", end: \"*)\"};\n    this.$id = \"ace/mode/applescript\";\n    // Extra logic goes here.\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/applescript_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AppleScriptHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    var keywords = (\n        \"about|above|after|against|and|around|as|at|back|before|beginning|\" +\n        \"behind|below|beneath|beside|between|but|by|considering|\" +\n        \"contain|contains|continue|copy|div|does|eighth|else|end|equal|\" +\n        \"equals|error|every|exit|fifth|first|for|fourth|from|front|\" +\n        \"get|given|global|if|ignoring|in|into|is|it|its|last|local|me|\" +\n        \"middle|mod|my|ninth|not|of|on|onto|or|over|prop|property|put|ref|\" +\n        \"reference|repeat|returning|script|second|set|seventh|since|\" +\n        \"sixth|some|tell|tenth|that|the|then|third|through|thru|\" +\n        \"timeout|times|to|transaction|try|until|where|while|whose|with|without\"\n    );\n\n    var builtinConstants = (\n        \"AppleScript|false|linefeed|return|pi|quote|result|space|tab|true\"\n    );\n\n    var builtinFunctions = (\n        \"activate|beep|count|delay|launch|log|offset|read|round|run|say|\" +\n        \"summarize|write\"\n    );\n\n    var builtinTypes = (\n        \"alias|application|boolean|class|constant|date|file|integer|list|\" +\n        \"number|real|record|string|text|character|characters|contents|day|\" +\n        \"frontmost|id|item|length|month|name|paragraph|paragraphs|rest|\" +\n        \"reverse|running|time|version|weekday|word|words|year\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"constant.language\": builtinConstants,\n        \"support.type\": builtinTypes,\n        \"keyword\": keywords\n    }, \"identifier\");\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"comment\",\n                regex: \"--.*$\"\n            },\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\(\\\\*\",\n                next : \"comment\"\n            },\n            {\n                token: \"string\",           // \" string\n                regex: '\".*?\"'\n            },\n            {\n                token: \"support.type\",\n                regex: '\\\\b(POSIX file|POSIX path|(date|time) string|quoted form)\\\\b'\n            },\n            {\n                token: \"support.function\",\n                regex: '\\\\b(clipboard info|the clipboard|info for|list (disks|folder)|' +\n          'mount volume|path to|(close|open for) access|(get|set) eof|' +\n          'current date|do shell script|get volume settings|random number|' +\n          'set volume|system attribute|system info|time to GMT|' +\n          '(load|run|store) script|scripting components|' +\n          'ASCII (character|number)|localized string|' +\n          'choose (application|color|file|file name|' +\n          'folder|from list|remote application|URL)|' +\n          'display (alert|dialog))\\\\b|^\\\\s*return\\\\b'\n            },\n            {\n                token: \"constant.language\",\n                regex: '\\\\b(text item delimiters|current application|missing value)\\\\b'\n            },\n            {\n                token: \"keyword\",\n                regex: '\\\\b(apart from|aside from|instead of|out of|greater than|' +\n          \"isn't|(doesn't|does not) (equal|come before|come after|contain)|\" +\n          '(greater|less) than( or equal)?|(starts?|ends|begins?) with|' +\n          'contained by|comes (before|after)|a (ref|reference))\\\\b'\n            },\n            {\n                token: keywordMapper,\n                regex: \"[a-zA-Z][a-zA-Z0-9_]*\\\\b\"\n            }\n        ],\n        \"comment\": [\n            {\n                token: \"comment\", // closing comment\n                regex: \"\\\\*\\\\)\",\n                next: \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }\n        ]\n    };\n\n    this.normalizeRules();\n};\n\noop.inherits(AppleScriptHighlightRules, TextHighlightRules);\n\nexports.AppleScriptHighlightRules = AppleScriptHighlightRules;\n"
  },
  {
    "path": "src/mode/aql.js",
    "content": "\"use strict\";\n\n  var oop = require(\"../lib/oop\");\n  var TextMode = require(\"./text\").Mode;\n  var AqlHighlightRules = require(\"./aql_highlight_rules\").AqlHighlightRules;\n\n  var Mode = function() {\n      this.HighlightRules = AqlHighlightRules;\n      this.$behaviour = this.$defaultBehaviour;\n  };\n  oop.inherits(Mode, TextMode);\n\n  (function() {\n\n      this.lineCommentStart = \"//\";\n\n      this.$id = \"ace/mode/aql\";\n  }).call(Mode.prototype);\n\n  exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/aql_highlight_rules.js",
    "content": "\"use strict\";\n\n  var oop = require(\"../lib/oop\");\n  var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n  var AqlHighlightRules = function() {\n\n      var keywords = (\n        \"for|return|filter|search|sort|limit|let|collect|asc|desc|in|into|insert|update|remove|replace|upsert|options|with|and|or|not|distinct|graph|shortest_path|outbound|inbound|any|all|none|at least|aggregate|like|k_shortest_paths|k_paths|all_shortest_paths|prune|window\"\n      );\n\n      var builtinConstants = (\n          \"true|false\"\n      );\n\n      var builtinFunctions = (\n        \"to_bool|to_number|to_string|to_array|to_list|is_null|is_bool|is_number|is_string|is_array|is_list|is_object|is_document|is_datestring|\" +\n        \"typename|json_stringify|json_parse|concat|concat_separator|char_length|lower|upper|substring|left|right|trim|reverse|contains|\" +\n        \"log|log2|log10|exp|exp2|sin|cos|tan|asin|acos|atan|atan2|radians|degrees|pi|regex_test|regex_replace|\" +\n        \"like|floor|ceil|round|abs|rand|sqrt|pow|length|count|min|max|average|avg|sum|product|median|variance_population|variance_sample|variance|percentile|\" +\n        \"bit_and|bit_or|bit_xor|bit_negate|bit_test|bit_popcount|bit_shift_left|bit_shift_right|bit_construct|bit_deconstruct|bit_to_string|bit_from_string|\" +\n        \"first|last|unique|outersection|interleave|in_range|jaccard|matches|merge|merge_recursive|has|attributes|keys|values|unset|unset_recursive|keep|keep_recursive|\" +\n        \"near|within|within_rectangle|is_in_polygon|distance|fulltext|stddev_sample|stddev_population|stddev|\" +\n        \"slice|nth|position|contains_array|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value|remove_values|\" +\n        \"remove_nth|replace_nth|date_now|date_timestamp|date_iso8601|date_dayofweek|date_year|date_month|date_day|date_hour|\" +\n        \"date_minute|date_second|date_millisecond|date_dayofyear|date_isoweek|date_isoweekyear|date_leapyear|date_quarter|date_days_in_month|date_trunc|date_round|\" +\n        \"date_add|date_subtract|date_diff|date_compare|date_format|date_utctolocal|date_localtoutc|date_timezone|date_timezones|\" +\n        \"fail|passthru|v8|sleep|schema_get|schema_validate|shard_id|call_greenspun|version|noopt|noeval|not_null|\" +\n        \"first_list|first_document|parse_identifier|current_user|current_database|collection_count|pregel_result|\" +\n        \"collections|document|decode_rev|range|union|union_distinct|minus|intersection|flatten|is_same_collection|check_document|\" +\n        \"ltrim|rtrim|find_first|find_last|split|substitute|ipv4_to_number|ipv4_from_number|is_ipv4|md5|sha1|sha512|crc32|fnv64|hash|random_token|to_base64|\" +\n        \"to_hex|encode_uri_component|soundex|assert|warn|is_key|sorted|sorted_unique|count_distinct|count_unique|\" +\n        \"levenshtein_distance|levenshtein_match|regex_matches|regex_split|ngram_match|ngram_similarity|ngram_positional_similarity|uuid|\" +\n        \"tokens|exists|starts_with|phrase|min_match|bm25|tfidf|boost|analyzer|\" +\n        \"cosine_similarity|decay_exp|decay_gauss|decay_linear|l1_distance|l2_distance|minhash|minhash_count|minhash_error|minhash_match|\" +\n        \"geo_point|geo_multipoint|geo_polygon|geo_multipolygon|geo_linestring|geo_multilinestring|geo_contains|geo_intersects|\" +\n        \"geo_equals|geo_distance|geo_area|geo_in_range\"\n      );\n\n      var keywordMapper = this.createKeywordMapper({\n          \"support.function\": builtinFunctions,\n          \"keyword\": keywords,\n          \"constant.language\": builtinConstants\n      }, \"identifier\", true);\n\n      this.$rules = {\n          \"start\" : [ {\n              token : \"comment\",\n              regex : \"//.*$\"\n          }, {\n              token : \"string\",           // \" string\n              regex : '\".*?\"'\n          }, {\n              token : \"string\",           // ' string\n              regex : \"'.*?'\"\n          }, {\n              token : \"constant.numeric\", // float\n              regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n          }, {\n              token : keywordMapper,\n              regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n          }, {\n              token : \"keyword.operator\",\n              regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n          }, {\n              token : \"paren.lparen\",\n              regex : \"[\\\\(]\"\n          }, {\n              token : \"paren.rparen\",\n              regex : \"[\\\\)]\"\n          }, {\n              token : \"text\",\n              regex : \"\\\\s+\"\n          } ]\n      };\n      this.normalizeRules();\n  };\n\n  oop.inherits(AqlHighlightRules, TextHighlightRules);\n\n  exports.AqlHighlightRules = AqlHighlightRules;\n"
  },
  {
    "path": "src/mode/asciidoc.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AsciidocHighlightRules = require(\"./asciidoc_highlight_rules\").AsciidocHighlightRules;\nvar AsciidocFoldMode = require(\"./folding/asciidoc\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AsciidocHighlightRules;\n    \n    this.foldingRules = new AsciidocFoldMode();    \n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    this.getNextLineIndent = function(state, line, tab) {\n        if (state == \"listblock\") {\n            var match = /^((?:.+)?)([-+*][ ]+)/.exec(line);\n            if (match) {\n                return new Array(match[1].length + 1).join(\" \") + match[2];\n            } else {\n                return \"\";\n            }\n        } else {\n            return this.$getIndent(line);\n        }\n    };\n    this.$id = \"ace/mode/asciidoc\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/asciidoc_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AsciidocHighlightRules = function() {\n    var identifierRe = \"[a-zA-Z\\u00a1-\\uffff]+\\\\b\";\n\n    this.$rules = {\n        \"start\": [\n            {token: \"empty\",   regex: /$/},\n            {token: \"literal\", regex: /^\\.{4,}\\s*$/,  next: \"listingBlock\"},\n            {token: \"literal\", regex: /^-{4,}\\s*$/,   next: \"literalBlock\"},\n            {token: \"string\",  regex: /^\\+{4,}\\s*$/,  next: \"passthroughBlock\"},\n            {token: \"keyword\", regex: /^={4,}\\s*$/},\n            {token: \"text\",    regex: /^\\s*$/},\n            // immediately return to the start mode without matching anything\n            {token: \"empty\", regex: \"\", next: \"dissallowDelimitedBlock\"}\n        ],\n\n        \"dissallowDelimitedBlock\": [\n            {include: \"paragraphEnd\"},\n            {token: \"comment\", regex: '^//.+$'},\n            {token: \"keyword\", regex: \"^(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION):\"},\n\n            {include: \"listStart\"},\n            {token: \"literal\", regex: /^\\s+.+$/, next: \"indentedBlock\"},\n            {token: \"empty\",   regex: \"\", next: \"text\"}\n        ],\n\n        \"paragraphEnd\": [\n            {token: \"doc.comment\", regex: /^\\/{4,}\\s*$/,    next: \"commentBlock\"},\n            {token: \"tableBlock\",  regex: /^\\s*[|!]=+\\s*$/, next: \"tableBlock\"},\n            // open block, ruller\n            {token: \"keyword\",     regex: /^(?:--|''')\\s*$/, next: \"start\"},\n            {token: \"option\",      regex: /^\\[.*\\]\\s*$/,     next: \"start\"},\n            {token: \"pageBreak\",   regex: /^>{3,}$/,         next: \"start\"},\n            {token: \"literal\",     regex: /^\\.{4,}\\s*$/,     next: \"listingBlock\"},\n            {token: \"titleUnderline\",    regex: /^(?:={2,}|-{2,}|~{2,}|\\^{2,}|\\+{2,})\\s*$/, next: \"start\"},\n            {token: \"singleLineTitle\",   regex: /^={1,5}\\s+\\S.*$/, next: \"start\"},\n\n            {token: \"otherBlock\",    regex: /^(?:\\*{2,}|_{2,})\\s*$/, next: \"start\"},\n            // .optional title\n            {token: \"optionalTitle\", regex: /^\\.[^.\\s].+$/,  next: \"start\"}\n        ],\n\n        \"listStart\": [\n            {token: \"keyword\",  regex: /^\\s*(?:\\d+\\.|[a-zA-Z]\\.|[ixvmIXVM]+\\)|\\*{1,5}|-|\\.{1,5})\\s/, next: \"listText\"},\n            {token: \"meta.tag\", regex: /^.+(?::{2,4}|;;)(?: |$)/, next: \"listText\"},\n            {token: \"support.function.list.callout\", regex: /^(?:<\\d+>|\\d+>|>) /, next: \"text\"},\n            // continuation\n            {token: \"keyword\",  regex: /^\\+\\s*$/, next: \"start\"}\n        ],\n\n        \"text\": [\n            {token: [\"link\", \"variable.language\"], regex: /((?:https?:\\/\\/|ftp:\\/\\/|file:\\/\\/|mailto:|callto:)[^\\s\\[]+)(\\[.*?\\])/},\n            {token: \"link\", regex: /(?:https?:\\/\\/|ftp:\\/\\/|file:\\/\\/|mailto:|callto:)[^\\s\\[]+/},\n            {token: \"link\", regex: /\\b[\\w\\.\\/\\-]+@[\\w\\.\\/\\-]+\\b/},\n            {include: \"macros\"},\n            {include: \"paragraphEnd\"},\n            {token: \"literal\", regex:/\\+{3,}/, next:\"smallPassthrough\"},\n            {token: \"escape\", regex: /\\((?:C|TM|R)\\)|\\.{3}|->|<-|=>|<=|&#(?:\\d+|x[a-fA-F\\d]+);|(?: |^)--(?=\\s+\\S)/},\n            {token: \"escape\", regex: /\\\\[_*'`+#]|\\\\{2}[_*'`+#]{2}/},\n            {token: \"keyword\", regex: /\\s\\+$/},\n            // any word\n            {token: \"text\", regex: identifierRe},\n            {token: [\"keyword\", \"string\", \"keyword\"],\n                regex: /(<<[\\w\\d\\-$]+,)(.*?)(>>|$)/},\n            {token: \"keyword\", regex: /<<[\\w\\d\\-$]+,?|>>/},\n            {token: \"constant.character\", regex: /\\({2,3}.*?\\){2,3}/},\n            // Anchor\n            {token: \"keyword\", regex: /\\[\\[.+?\\]\\]/},\n            // bibliography\n            {token: \"support\", regex: /^\\[{3}[\\w\\d =\\-]+\\]{3}/},\n\n            {include: \"quotes\"},\n            // text block end\n            {token: \"empty\", regex: /^\\s*$/, next: \"start\"}\n        ],\n\n        \"listText\": [\n            {include: \"listStart\"},\n            {include: \"text\"}\n        ],\n\n        \"indentedBlock\": [\n            {token: \"literal\", regex: /^[\\s\\w].+$/, next: \"indentedBlock\"},\n            {token: \"literal\", regex: \"\", next: \"start\"}\n        ],\n\n        \"listingBlock\": [\n            {token: \"literal\", regex: /^\\.{4,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"constant.numeric\", regex: '<\\\\d+>'},\n            {token: \"literal\", regex: '[^<]+'},\n            {token: \"literal\", regex: '<'}\n        ],\n        \"literalBlock\": [\n            {token: \"literal\", regex: /^-{4,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"constant.numeric\", regex: '<\\\\d+>'},\n            {token: \"literal\", regex: '[^<]+'},\n            {token: \"literal\", regex: '<'}\n        ],\n        \"passthroughBlock\": [\n            {token: \"literal\", regex: /^\\+{4,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"literal\", regex: identifierRe + \"|\\\\d+\"},\n            {include: \"macros\"},\n            {token: \"literal\", regex: \".\"}\n        ],\n\n        \"smallPassthrough\": [\n            {token: \"literal\", regex: /[+]{3,}/, next: \"dissallowDelimitedBlock\"},\n            {token: \"literal\", regex: /^\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"literal\", regex: identifierRe + \"|\\\\d+\"},\n            {include: \"macros\"}\n        ],\n\n        \"commentBlock\": [\n            {token: \"doc.comment\", regex: /^\\/{4,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"doc.comment\", regex: '^.*$'}\n        ],\n        \"tableBlock\": [\n            {token: \"tableBlock\", regex: /^\\s*\\|={3,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"tableBlock\", regex: /^\\s*!={3,}\\s*$/, next: \"innerTableBlock\"},\n            {token: \"tableBlock\", regex: /\\|/},\n            {include: \"text\", noEscape: true}\n        ],\n        \"innerTableBlock\": [\n            {token: \"tableBlock\", regex: /^\\s*!={3,}\\s*$/, next: \"tableBlock\"},\n            {token: \"tableBlock\", regex: /^\\s*|={3,}\\s*$/, next: \"dissallowDelimitedBlock\"},\n            {token: \"tableBlock\", regex: /!/}\n        ],\n        \"macros\": [\n            {token: \"macro\", regex: /{[\\w\\-$]+}/},\n            {token: [\"text\", \"string\", \"text\", \"constant.character\", \"text\"], regex: /({)([\\w\\-$]+)(:)?(.+)?(})/},\n            {token: [\"text\", \"markup.list.macro\", \"keyword\", \"string\"], regex: /(\\w+)(footnote(?:ref)?::?)([^\\s\\[]+)?(\\[.*?\\])?/},\n            {token: [\"markup.list.macro\", \"keyword\", \"string\"], regex: /([a-zA-Z\\-][\\w\\.\\/\\-]*::?)([^\\s\\[]+)(\\[.*?\\])?/},\n            {token: [\"markup.list.macro\", \"keyword\"], regex: /([a-zA-Z\\-][\\w\\.\\/\\-]+::?)(\\[.*?\\])/},\n            {token: \"keyword\",     regex: /^:.+?:(?= |$)/}\n        ],\n\n        \"quotes\": [\n            {token: \"string.italic\", regex: /__[^_\\s].*?__/},\n            {token: \"string.italic\", regex: quoteRule(\"_\")},\n            \n            {token: \"keyword.bold\", regex: /\\*\\*[^*\\s].*?\\*\\*/},\n            {token: \"keyword.bold\", regex: quoteRule(\"\\\\*\")},\n            \n            {token: \"literal\", regex: quoteRule(\"\\\\+\")},\n            {token: \"literal\", regex: /\\+\\+[^+\\s].*?\\+\\+/},\n            {token: \"literal\", regex: /\\$\\$.+?\\$\\$/},\n            {token: \"literal\", regex: quoteRule(\"`\")},\n\n            {token: \"keyword\", regex: quoteRule(\"^\")},\n            {token: \"keyword\", regex: quoteRule(\"~\")},\n            {token: \"keyword\", regex: /##?/},\n            {token: \"keyword\", regex: /(?:\\B|^)``|\\b''/}\n        ]\n\n    };\n\n    function quoteRule(ch) {\n        var prefix = /\\w/.test(ch) ? \"\\\\b\" : \"(?:\\\\B|^)\";\n        return prefix + ch + \"[^\" + ch + \"].*?\" + ch + \"(?![\\\\w*])\";\n    }\n\n    //addQuoteBlock(\"text\")\n\n    var tokenMap = {\n        macro: \"constant.character\",\n        tableBlock: \"doc.comment\",\n        titleUnderline: \"markup.heading\",\n        singleLineTitle: \"markup.heading\",\n        pageBreak: \"string\",\n        option: \"string.regexp\",\n        otherBlock: \"markup.list\",\n        literal: \"support.function\",\n        optionalTitle: \"constant.numeric\",\n        escape: \"constant.language.escape\",\n        link: \"markup.underline.list\"\n    };\n\n    for (var state in this.$rules) {\n        var stateRules = this.$rules[state];\n        for (var i = stateRules.length; i--; ) {\n            var rule = stateRules[i];\n            if (rule.include || typeof rule == \"string\") {\n                var args = [i, 1].concat(this.$rules[rule.include || rule]);\n                if (rule.noEscape) {\n                    args = args.filter(function(x) {\n                        return !x.next;\n                    });\n                }\n                stateRules.splice.apply(stateRules, args);\n            } else if (rule.token in tokenMap) {\n                rule.token = tokenMap[rule.token];\n            }\n        }\n    }\n};\noop.inherits(AsciidocHighlightRules, TextHighlightRules);\n\nexports.AsciidocHighlightRules = AsciidocHighlightRules;\n"
  },
  {
    "path": "src/mode/asl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ASLHighlightRules = require(\"./asl_highlight_rules\").ASLHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = ASLHighlightRules;\n    this.foldingRules = new FoldMode();\n        this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n    this.$id = \"ace/mode/asl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/asl_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var ASLHighlightRules = function() {\n        var keywords = (\n            \"Default|DefinitionBlock|Device|Method|Else|ElseIf|For|Function|If|Include|Method|Return|\" +\n            \"Scope|Switch|Case|While|Break|BreakPoint|Continue|NoOp|Wait|True|False|\" +\n            \"AccessAs|Acquire|Alias|BankField|Buffer|Concatenate|ConcatenateResTemplate|\" +\n            \"CondRefOf|Connection|CopyObject|CreateBitField|CreateByteField|CreateDWordField|\" +\n            \"CreateField|CreateQWordField|CreateWordField|DataTableRegion|Debug|\" +\n            \"DMA|DWordIO|DWordMemory|DWordSpace|EisaId|EISAID|EndDependentFn|Event|ExtendedIO|\" +\n            \"ExtendedMemory|ExtendedSpace|External|Fatal|Field|FindSetLeftBit|FindSetRightBit|\" +\n            \"FixedDMA|FixedIO|Fprintf|FromBCD|GpioInt|GpioIo|I2CSerialBusV2|IndexField|\" +\n            \"Interrupt|IO|IRQ|IRQNoFlags|Load|LoadTable|Match|Memory32|Memory32Fixed|\" +\n            \"Mid|Mutex|Name|Notify|Offset|ObjectType|OperationRegion|Package|PowerResource|Printf|\" +\n            \"QWordIO|QWordMemory|QWordSpace|RawDataBuffer|Register|Release|Reset|ResourceTemplate|\" +\n            \"Signal|SizeOf|Sleep|SPISerialBusV2|Stall|StartDependentFn|StartDependentFnNoPri|\" +\n            \"Store|ThermalZone|Timer|ToBCD|ToBuffer|ToDecimalString|ToInteger|ToPLD|ToString|\" +\n            \"ToUUID|UARTSerialBusV2|Unicode|Unload|VendorLong|VendorShort|WordBusNumber|WordIO|\" +\n            \"WordSpace\"\n        );\n\n        var keywordOperators = (\n            \"Add|And|Decrement|Divide|Increment|Index|LAnd|LEqual|LGreater|LGreaterEqual|\" +\n            \"LLess|LLessEqual|LNot|LNotEqual|LOr|Mod|Multiply|NAnd|NOr|Not|Or|RefOf|Revision|\" +\n            \"ShiftLeft|ShiftRight|Subtract|XOr|DerefOf\"\n        );\n\n        var flags = (\n            \"AttribQuick|AttribSendReceive|AttribByte|AttribBytes|AttribRawBytes|\" +\n            \"AttribRawProcessBytes|AttribWord|AttribBlock|AttribProcessCall|AttribBlockProcessCall|\" +\n            \"AnyAcc|ByteAcc|WordAcc|DWordAcc|QWordAcc|BufferAcc|\" +\n            \"AddressRangeMemory|AddressRangeReserved|AddressRangeNVS|AddressRangeACPI|\" +\n            \"RegionSpaceKeyword|FFixedHW|PCC|\" +\n            \"AddressingMode7Bit|AddressingMode10Bit|\" +\n            \"DataBitsFive|DataBitsSix|DataBitsSeven|DataBitsEight|DataBitsNine|\" +\n            \"BusMaster|NotBusMaster|\" +\n            \"ClockPhaseFirst|ClockPhaseSecond|ClockPolarityLow|ClockPolarityHigh|\" +\n            \"SubDecode|PosDecode|\" +\n            \"BigEndianing|LittleEndian|\" +\n            \"FlowControlNone|FlowControlXon|FlowControlHardware|\" +\n            \"Edge|Level|ActiveHigh|ActiveLow|ActiveBoth|Decode16|Decode10|\" +\n            \"IoRestrictionNone|IoRestrictionInputOnly|IoRestrictionOutputOnly|\" +\n            \"IoRestrictionNoneAndPreserve|Lock|NoLock|MTR|MEQ|MLE|MLT|MGE|MGT|\" +\n            \"MaxFixed|MaxNotFixed|Cacheable|WriteCombining|Prefetchable|NonCacheable|\" +\n            \"MinFixed|MinNotFixed|\" +\n            \"ParityTypeNone|ParityTypeSpace|ParityTypeMark|ParityTypeOdd|ParityTypeEven|\" +\n            \"PullDefault|PullUp|PullDown|PullNone|PolarityHigh|PolarityLow|\" +\n            \"ISAOnlyRanges|NonISAOnlyRanges|EntireRange|ReadWrite|ReadOnly|\" +\n            \"UserDefRegionSpace|SystemIO|SystemMemory|PCI_Config|EmbeddedControl|\" +\n            \"SMBus|SystemCMOS|PciBarTarget|IPMI|GeneralPurposeIO|GenericSerialBus|\" +\n            \"ResourceConsumer|ResourceProducer|Serialized|NotSerialized|\" +\n            \"Shared|Exclusive|SharedAndWake|ExclusiveAndWake|ControllerInitiated|DeviceInitiated|\" +\n            \"StopBitsZero|StopBitsOne|StopBitsOnePlusHalf|StopBitsTwo|\" +\n            \"Width8Bit|Width16Bit|Width32Bit|Width64Bit|Width128Bit|Width256Bit|\" +\n            \"SparseTranslation|DenseTranslation|TypeTranslation|TypeStatic|\" +\n            \"Preserve|WriteAsOnes|WriteAsZeros|Transfer8|Transfer16|Transfer8_16|\" +\n            \"ThreeWireMode|FourWireMode\"\n        );\n\n        var storageTypes = (\n            \"UnknownObj|IntObj|StrObj|BuffObj|PkgObj|FieldUnitObj|DeviceObj|\" +\n            \"EventObj|MethodObj|MutexObj|OpRegionObj|PowerResObj|ProcessorObj|\" +\n            \"ThermalZoneObj|BuffFieldObj|DDBHandleObj\"\n        );\n\n        var builtinConstants = (\n            \"__FILE__|__PATH__|__LINE__|__DATE__|__IASL__\"\n        );\n\n        var strNumbers = (\n            \"One|Ones|Zero\"\n        );\n\n        var deprecated = (\n            \"Memory24|Processor\"\n        );\n\n        var keywordMapper = this.createKeywordMapper({\n            \"keyword\": keywords,\n            \"constant.numeric\": strNumbers,\n            \"keyword.operator\": keywordOperators,\n            \"constant.language\": builtinConstants,\n            \"storage.type\": storageTypes,\n            \"constant.library\": flags,\n            \"invalid.deprecated\": deprecated\n        }, \"identifier\");\n\n        this.$rules = {\n            \"start\" : [\n                {\n                    token : \"comment\",\n                    regex : \"\\\\/\\\\/.*$\"\n                },\n                DocCommentHighlightRules.getStartRule(\"doc-start\"),\n                {\n                    token : \"comment\", // multi line comment\n                    regex : \"\\\\/\\\\*\",\n                    next : \"comment\"\n                },\n                DocCommentHighlightRules.getStartRule(\"doc-start\"),\n                {\n                    token : \"comment\", // ignored fields / comments\n                    regex : \"\\\\\\[\",\n                    next : \"ignoredfield\"\n                }, {\n                    token : \"variable\",\n                    regex : \"\\\\Local[0-7]|\\\\Arg[0-6]\"\n                }, {\n                    token : \"keyword\", // pre-compiler directives\n                    regex : \"#\\\\s*(?:define|elif|else|endif|error|if|ifdef|ifndef|include|includebuffer|line|pragma|undef|warning)\\\\b\",\n                    next  : \"directive\"\n                }, {\n                    token : \"string\", // single line\n                    regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n                }, {\n                    token : \"constant.character\", // single line\n                    regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n                }, {\n                    token : \"constant.numeric\", // hex\n                    regex : /0[xX][0-9a-fA-F]+\\b/\n                }, {\n                    token : \"constant.numeric\",\n                    regex : /[0-9]+\\b/\n                }, {\n                    token : keywordMapper,\n                    regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                }, {\n                    token : \"keyword.operator\",\n                    regex : /[!\\~\\*\\/%+-<>\\^|=&]/\n                }, {\n                    token : \"lparen\",\n                    regex : \"[[({]\"\n                }, {\n                    token : \"rparen\",\n                    regex : \"[\\\\])}]\"\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }\n            ],\n            \"comment\" : [\n                {\n                    token : \"comment\", // closing comment\n                    regex : \"\\\\*\\\\/\",\n                    next : \"start\"\n                }, {\n                    defaultToken : \"comment\"\n                }\n            ],\n            \"ignoredfield\" : [\n                {\n                    token : \"comment\", // closing ignored fields / comments\n                    regex : \"\\\\\\]\",\n                    next : \"start\"\n                }, {\n                    defaultToken : \"comment\"\n                }\n            ],\n            \"directive\" : [\n                {\n                    token : \"constant.other.multiline\",\n                    regex : /\\\\/\n                },\n                {\n                    token : \"constant.other.multiline\",\n                    regex : /.*\\\\/\n                },\n                {\n                    token : \"constant.other\",\n                    regex : \"\\\\s*<.+?>*s\",\n                    next : \"start\"\n                },\n                {\n                    token : \"constant.other\", // single line\n                    regex : '\\\\s*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]*s',\n                    next : \"start\"\n                },\n                {\n                    token : \"constant.other\", // single line\n                    regex : \"\\\\s*['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\",\n                    next : \"start\"\n                },\n                // \"\\\" implies multiline, while \"/\" implies comment\n                {\n                    token : \"constant.other\",\n                    regex : /[^\\\\\\/]+/,\n                    next : \"start\"\n                }\n            ]\n        };\n\n        this.embedRules(DocCommentHighlightRules, \"doc-\",\n            [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    };\n\n    oop.inherits(ASLHighlightRules, TextHighlightRules);\n\n    exports.ASLHighlightRules = ASLHighlightRules;\n"
  },
  {
    "path": "src/mode/assembly_arm32.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AssemblyARM32HighlightRules = require(\"./assembly_arm32_highlight_rules\").AssemblyARM32HighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AssemblyARM32HighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = [\";\"];\n\tthis.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/assembly_arm32\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/assembly_arm32_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AssemblyARM32HighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { \n        start: [ \n            { \n                token: 'keyword.control.assembly',\n                // should cover every instruction listed in https://pages.cs.wisc.edu/~markhill/restricted/arm_isa_quick_reference.pdf\n                regex: '\\\\b(?:cpsid|cpsie|cps|setend|(?:srs|rfe)(?:ia|ib|da|db|fd|ed|fa|ea)|bkpt|nop|pld|cdp2|mrc2|mrrc2|mcr2|mcrr2|ldc2|stc2|(?:add|adc|sub|sbc|rsb|rsc|mul|mla|umull|umlal|smull|smlal|mvn|and|eor|orr|bic)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?s?|(?:(?:q|qd)?(?:add|sub)|umaal|smul(?:b|t)(?:b|t)|smulw(?:b|t)|smla(?:b|t)(?:b|t)|smlaw(?:b|t)|smlal(?:b|t)(?:b|t)|smuadx?|smladx?|smlaldx?|smusdx?|smlsdx?|smlsldx?|smmulr?|smmlar?|smmlsr?|mia|miaph|mia(?:b|t)(?:b|t)|clz|(?:s|q|sh|u|uq|uh)(?:add16|sub16|add8|sub8|addsubx|subaddx)|usad8|usada8|mrs|msr|mra|mar|cpy|tst|teq|cmp|cmn|ssat|ssat16|usat|usat16|pkhbt|pkhtb|sxth|sxtb16|sxtb|uxth|uxtb16|uxtb|sxtah|sxtab16|sxtab|uxtah|uxtab16|uxtab|rev|rev16|revsh|sel|b|bl|bx|blx|bxj|swi|svc|ldrex|strex|cdp|mrc|mrrc|mcr|mcrr|ldc|stc)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?|ldr(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:t|b|bt|sb|h|sh|d)?|str(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:t|b|bt|h|d)?|(?:ldm|stm)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:ia|ib|da|db|fd|ed|fa|ea)|swp(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?b?|mov(?:t|w)?)\\\\b',\n                caseInsensitive: true\n            },\n            { \n                token: 'variable.parameter.register.assembly', \n                //          first half are actual registers until spsr, where it changes to fields and flexible operands\n                regex: '\\\\b(?:r0|r1|r2|r3|r4|r5|r6|r7|r8|r9|r10|r11|r12|r13|r14|r15|fp|ip|sp|lr|pc|cpsr|spsr|c|f|s|x|lsl|lsr|asr|ror|rrx)\\\\b',\n                caseInsensitive: true \n            },\n            { \n                token: 'constant.character.hexadecimal.assembly',\n                regex: '#0x[A-F0-9]+',\n                caseInsensitive: true \n            },\n            { \n                token: 'constant.character.decimal.assembly',\n                regex: '#[0-9]+' \n            },\n            { \n                token: 'string.assembly', \n                regex: /'([^\\\\']|\\\\.)*'/ \n            },\n            { \n                token: 'string.assembly', \n                regex: /\"([^\\\\\"]|\\\\.)*\"/ \n            },\n            { \n                token: 'support.function.directive.assembly',\n                regex: '(?:\\.section|\\.global|\\.text|\\.asciz|\\.asciiz|\\.ascii|\\.align|\\.byte|\\.end|\\.data|\\.equ|\\.extern|\\.include)'\n            },\n            { \n                token: 'entity.name.function.assembly', \n                regex: '^\\\\s*%%[\\\\w.]+?:$' \n            },\n            { \n                token: 'entity.name.function.assembly', \n                regex: '^\\\\s*%\\\\$[\\\\w.]+?:$' \n            },\n            {\n                token: 'entity.name.function.assembly', \n                regex: '^[\\\\w.]+?:' \n            },\n            { \n                token: 'entity.name.function.assembly', \n                regex: '^[\\\\w.]+?\\\\b'\n            },\n            {\n                token: 'comment.assembly', \n                regex: '\\\\/\\\\*', next: 'comment'\n            },\n            { \n                token: 'comment.assembly', \n                regex: '(?:;|//|@).*$' \n            } \n        ],\n        comment:[\n            {\n                token: 'comment.assembly',\n                regex: '\\\\*\\\\/', next:'start'\n            },\n            {\n                defaultToken:'comment'\n            }\n        ]\n    };\n    \n    this.normalizeRules();\n};\n\nAssemblyARM32HighlightRules.metaData = { fileTypes: [ 's' ],\n      name: 'Assembly ARM32',\n      scopeName: 'source.assembly' };\n\n\noop.inherits(AssemblyARM32HighlightRules, TextHighlightRules);\n\nexports.AssemblyARM32HighlightRules = AssemblyARM32HighlightRules;\n"
  },
  {
    "path": "src/mode/assembly_x86.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AssemblyX86HighlightRules = require(\"./assembly_x86_highlight_rules\").AssemblyX86HighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AssemblyX86HighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = [\";\"];\n    this.$id = \"ace/mode/assembly_x86\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/assembly_x86_highlight_rules.js",
    "content": "/* This file was autogenerated from Assembly x86.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AssemblyX86HighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'keyword.control.assembly',\n           regex: '\\\\b(?:aaa|aad|aam|aas|adc|add|addpd|addps|addsd|addss|addsubpd|addsubps|aesdec|aesdeclast|aesenc|aesenclast|aesimc|aeskeygenassist|and|andpd|andps|andnpd|andnps|arpl|blendpd|blendps|blendvpd|blendvps|bound|bsf|bsr|bswap|bt|btc|btr|bts|cbw|cwde|cdqe|clc|cld|cflush|clts|cmc|cmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|cmp|cmppd|cmpps|cmps|cnpsb|cmpsw|cmpsd|cmpsq|cmpss|cmpxchg|cmpxchg8b|cmpxchg16b|comisd|comiss|cpuid|crc32|cvtdq2pd|cvtdq2ps|cvtpd2dq|cvtpd2pi|cvtpd2ps|cvtpi2pd|cvtpi2ps|cvtps2dq|cvtps2pd|cvtps2pi|cvtsd2si|cvtsd2ss|cvts2sd|cvtsi2ss|cvtss2sd|cvtss2si|cvttpd2dq|cvtpd2pi|cvttps2dq|cvttps2pi|cvttps2dq|cvttps2pi|cvttsd2si|cvttss2si|cwd|cdq|cqo|daa|das|dec|div|divpd|divps|divsd|divss|dppd|dpps|emms|enter|extractps|f2xm1|fabs|fadd|faddp|fiadd|fbld|fbstp|fchs|fclex|fnclex|fcmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|fcom|fcmop|fcompp|fcomi|fcomip|fucomi|fucomip|fcos|fdecstp|fdiv|fdivp|fidiv|fdivr|fdivrp|fidivr|ffree|ficom|ficomp|fild|fincstp|finit|fnint|fist|fistp|fisttp|fld|fld1|fldl2t|fldl2e|fldpi|fldlg2|fldln2|fldz|fldcw|fldenv|fmul|fmulp|fimul|fnop|fpatan|fprem|fprem1|fptan|frndint|frstor|fsave|fnsave|fscale|fsin|fsincos|fsqrt|fst|fstp|fstcw|fnstcw|fstenv|fnstenv|fsts|fnstsw|fsub|fsubp|fisub|fsubr|fsubrp|fisubr|ftst|fucom|fucomp|fucompp|fxam|fxch|fxrstor|fxsave|fxtract|fyl2x|fyl2xp1|haddpd|haddps|husbpd|hsubps|idiv|imul|in|inc|ins|insb|insw|insd|insertps|int|into|invd|invplg|invpcid|iret|iretd|iretq|lahf|lar|lddqu|ldmxcsr|lds|les|lfs|lgs|lss|lea|leave|lfence|lgdt|lidt|llgdt|lmsw|lock|lods|lodsb|lodsw|lodsd|lodsq|lsl|ltr|maskmovdqu|maskmovq|maxpd|maxps|maxsd|maxss|mfence|minpd|minps|minsd|minss|monitor|mov|movapd|movaps|movbe|movd|movq|movddup|movdqa|movdqu|movq2q|movhlps|movhpd|movhps|movlhps|movlpd|movlps|movmskpd|movmskps|movntdqa|movntdq|movnti|movntpd|movntps|movntq|movq|movq2dq|movs|movsb|movsw|movsd|movsq|movsd|movshdup|movsldup|movss|movsx|movsxd|movupd|movups|movzx|mpsadbw|mul|mulpd|mulps|mulsd|mulss|mwait|neg|not|or|orpd|orps|out|outs|outsb|outsw|outsd|pabsb|pabsw|pabsd|packsswb|packssdw|packusdw|packuswbpaddb|paddw|paddd|paddq|paddsb|paddsw|paddusb|paddusw|palignr|pand|pandn|pause|pavgb|pavgw|pblendvb|pblendw|pclmulqdq|pcmpeqb|pcmpeqw|pcmpeqd|pcmpeqq|pcmpestri|pcmpestrm|pcmptb|pcmptgw|pcmpgtd|pcmpgtq|pcmpistri|pcmpisrm|pextrb|pextrd|pextrq|pextrw|phaddw|phaddd|phaddsw|phinposuw|phsubw|phsubd|phsubsw|pinsrb|pinsrd|pinsrq|pinsrw|pmaddubsw|pmadddwd|pmaxsb|pmaxsd|pmaxsw|pmaxsw|pmaxub|pmaxud|pmaxuw|pminsb|pminsd|pminsw|pminub|pminud|pminuw|pmovmskb|pmovsx|pmovzx|pmuldq|pmulhrsw|pmulhuw|pmulhw|pmulld|pmullw|pmuludw|pop|popa|popad|popcnt|popf|popfd|popfq|por|prefetch|psadbw|pshufb|pshufd|pshufhw|pshuflw|pshufw|psignb|psignw|psignd|pslldq|psllw|pslld|psllq|psraw|psrad|psrldq|psrlw|psrld|psrlq|psubb|psubw|psubd|psubq|psubsb|psubsw|psubusb|psubusw|test|ptest|punpckhbw|punpckhwd|punpckhdq|punpckhddq|punpcklbw|punpcklwd|punpckldq|punpckldqd|push|pusha|pushad|pushf|pushfd|pxor|prcl|rcr|rol|ror|rcpps|rcpss|rdfsbase|rdgsbase|rdmsr|rdpmc|rdrand|rdtsc|rdtscp|rep|repe|repz|repne|repnz|roundpd|roundps|roundsd|roundss|rsm|rsqrps|rsqrtss|sahf|sal|sar|shl|shr|sbb|scas|scasb|scasw|scasd|set(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|sfence|sgdt|shld|shrd|shufpd|shufps|sidt|sldt|smsw|sqrtpd|sqrtps|sqrtsd|sqrtss|stc|std|stmxcsr|stos|stosb|stosw|stosd|stosq|str|sub|subpd|subps|subsd|subss|swapgs|syscall|sysenter|sysexit|sysret|teset|ucomisd|ucomiss|ud2|unpckhpd|unpckhps|unpcklpd|unpcklps|vbroadcast|vcvtph2ps|vcvtp2sph|verr|verw|vextractf128|vinsertf128|vmaskmov|vpermilpd|vpermilps|vperm2f128|vtestpd|vtestps|vzeroall|vzeroupper|wait|fwait|wbinvd|wrfsbase|wrgsbase|wrmsr|xadd|xchg|xgetbv|xlat|xlatb|xor|xorpd|xorps|xrstor|xsave|xsaveopt|xsetbv|lzcnt|extrq|insertq|movntsd|movntss|vfmaddpd|vfmaddps|vfmaddsd|vfmaddss|vfmaddsubbpd|vfmaddsubps|vfmsubaddpd|vfmsubaddps|vfmsubpd|vfmsubps|vfmsubsd|vfnmaddpd|vfnmaddps|vfnmaddsd|vfnmaddss|vfnmsubpd|vfnmusbps|vfnmusbsd|vfnmusbss|cvt|xor|cli|sti|hlt|nop|lock|wait|enter|leave|ret|loop(?:n?e|n?z)?|call|j(?:mp|n?e|ge?|ae?|le?|be?|n?o|n?z))\\\\b',\n           caseInsensitive: true },\n         { token: 'variable.parameter.register.assembly',\n           regex: '\\\\b(?:CS|DS|ES|FS|GS|SS|RAX|EAX|RBX|EBX|RCX|ECX|RDX|EDX|RCX|RIP|EIP|IP|RSP|ESP|SP|RSI|ESI|SI|RDI|EDI|DI|RFLAGS|EFLAGS|FLAGS|R8-15|(?:Y|X)MM(?:[0-9]|10|11|12|13|14|15)|(?:A|B|C|D)(?:X|H|L)|CR(?:[0-4]|DR(?:[0-7]|TR6|TR7|EFER)))\\\\b',\n           caseInsensitive: true },\n         { token: 'constant.character.decimal.assembly',\n           regex: '\\\\b[0-9]+\\\\b' },\n         { token: 'constant.character.hexadecimal.assembly',\n           regex: '\\\\b0x[A-F0-9]+\\\\b',\n           caseInsensitive: true },\n         { token: 'constant.character.hexadecimal.assembly',\n           regex: '\\\\b[A-F0-9]+h\\\\b',\n           caseInsensitive: true },\n         { token: 'string.assembly', regex: /'([^\\\\']|\\\\.)*'/ },\n         { token: 'string.assembly', regex: /\"([^\\\\\"]|\\\\.)*\"/ },\n         { token: 'support.function.directive.assembly',\n           regex: '^\\\\[',\n           push: \n            [ { token: 'support.function.directive.assembly',\n                regex: '\\\\]$',\n                next: 'pop' },\n              { defaultToken: 'support.function.directive.assembly' } ] },\n         { token: \n            [ 'support.function.directive.assembly',\n              'support.function.directive.assembly',\n              'entity.name.function.assembly' ],\n           regex: '(^struc)( )([_a-zA-Z][_a-zA-Z0-9]*)' },\n         { token: 'support.function.directive.assembly',\n           regex: '^endstruc\\\\b' },\n        { token: \n            [ 'support.function.directive.assembly',\n              'entity.name.function.assembly',\n              'support.function.directive.assembly',\n              'constant.character.assembly' ],\n           regex: '^(%macro )([_a-zA-Z][_a-zA-Z0-9]*)( )([0-9]+)' },\n         { token: 'support.function.directive.assembly',\n           regex: '^%endmacro' },\n         { token: \n            [ 'text',\n              'support.function.directive.assembly',\n              'text',\n              'entity.name.function.assembly' ],\n           regex: '(\\\\s*)(%define|%xdefine|%idefine|%undef|%assign|%defstr|%strcat|%strlen|%substr|%00|%0|%rotate|%rep|%endrep|%include|\\\\$\\\\$|\\\\$|%unmacro|%if|%elif|%else|%endif|%(?:el)?ifdef|%(?:el)?ifmacro|%(?:el)?ifctx|%(?:el)?ifidn|%(?:el)?ifidni|%(?:el)?ifid|%(?:el)?ifnum|%(?:el)?ifstr|%(?:el)?iftoken|%(?:el)?ifempty|%(?:el)?ifenv|%pathsearch|%depend|%use|%push|%pop|%repl|%arg|%stacksize|%local|%error|%warning|%fatal|%line|%!|%comment|%endcomment|__NASM_VERSION_ID__|__NASM_VER__|__FILE__|__LINE__|__BITS__|__OUTPUT_FORMAT__|__DATE__|__TIME__|__DATE_NUM__|_TIME__NUM__|__UTC_DATE__|__UTC_TIME__|__UTC_DATE_NUM__|__UTC_TIME_NUM__|__POSIX_TIME__|__PASS__|ISTRUC|AT|IEND|BITS 16|BITS 32|BITS 64|USE16|USE32|__SECT__|ABSOLUTE|EXTERN|GLOBAL|COMMON|CPU|FLOAT)\\\\b( ?)((?:[_a-zA-Z][_a-zA-Z0-9]*)?)',\n           caseInsensitive: true },\n          { token: 'support.function.directive.assembly',\n           regex: '\\\\b(?:d[bwdqtoy]|res[bwdqto]|equ|times|align|alignb|sectalign|section|ptr|byte|word|dword|qword|incbin)\\\\b',\n           caseInsensitive: true },\n         { token: 'entity.name.function.assembly', regex: '^\\\\s*%%[\\\\w.]+?:$' },\n         { token: 'entity.name.function.assembly', regex: '^\\\\s*%\\\\$[\\\\w.]+?:$' },\n         { token: 'entity.name.function.assembly', regex: '^[\\\\w.]+?:' },\n         { token: 'entity.name.function.assembly', regex: '^[\\\\w.]+?\\\\b' },\n         { token: 'comment.assembly', regex: ';.*$' } ] \n    };\n    \n    this.normalizeRules();\n};\n\nAssemblyX86HighlightRules.metaData = { fileTypes: [ 'asm' ],\n      name: 'Assembly x86',\n      scopeName: 'source.assembly' };\n\n\noop.inherits(AssemblyX86HighlightRules, TextHighlightRules);\n\nexports.AssemblyX86HighlightRules = AssemblyX86HighlightRules;\n"
  },
  {
    "path": "src/mode/astro.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar AstroHighlightRules = require(\"./astro_highlight_rules\").AstroHighlightRules;\nvar HtmlBehaviour = require(\"./behaviour/html\").HtmlBehaviour;\n\nvar Mode = function() {\n  HtmlMode.call(this);\n  this.HighlightRules = AstroHighlightRules;\n  this.$behaviour = new HtmlBehaviour();\n};\n\noop.inherits(Mode, HtmlMode);\n\n(function() {\n  this.$id = \"ace/mode/astro\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/astro_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar JavascriptHighlightRules =\n  require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nvar AstroHighlightRules = function () {\n  HtmlHighlightRules.call(this);\n\n  var astro = {\n    token: \"paren.quasi.start\",\n    regex: /{/,\n    next: function (state, stack) {\n      if (state !== \"start\") {\n        if (state.indexOf(\"attribute-equals\") !== -1) {\n          stack.splice(0);\n          stack.unshift(\"tag_stuff\");\n        } else {\n          stack.unshift(state);\n        }\n      }\n      return \"inline-js-start\";\n    }\n  };\n\n  for (var key in this.$rules) {\n    if (\n      key.startsWith(\"js\") ||\n      key.startsWith(\"css\") ||\n      key.startsWith(\"comment\")\n    )\n      continue;\n    this.$rules[key].unshift(astro);\n  }\n\n  this.$rules.start.unshift({\n    token: \"comment\",\n    regex: /^---$/,\n    onMatch: function (value, state, stack) {\n      stack.splice(0);\n      return this.token;\n    },\n    next: \"javascript-start\"\n  });\n\n  this.embedRules(JavascriptHighlightRules, \"javascript-\", [\n    {\n      regex: /^---$/,\n      token: \"comment\",\n      next: \"start\",\n      onMatch: function (value, state, stack) {\n        stack.splice(0);\n        return this.token;\n      }\n    }\n  ]);\n\n  this.embedRules(JavascriptHighlightRules, \"inline-js-\");\n\n  var astroRules = [\n    {\n      regex: /}/,\n      token: \"paren.quasi.end\",\n      onMatch: function (value, state, stack) {\n        if (stack[0] === \"inline-js-start\") {\n          stack.shift();\n          this.next = stack.shift();\n          if (this.next.indexOf(\"string\") !== -1) \n            return \"paren.quasi.end\";\n          return \"paren.rparen\";\n        } else {\n          this.next = stack.shift() || \"start\";\n          return this.token;\n        }\n      }\n    },\n    {\n      regex: /{/,\n      token: \"paren.lparen\",\n      push: \"inline-js-start\"\n    }\n  ];\n\n  this.$rules[\"inline-js-start\"].unshift(astroRules);\n  this.$rules[\"inline-js-no_regex\"].unshift(astroRules);\n\n\n  function overwriteJSXendRule(prefix) {\n    for (var index in this.$rules[prefix + \"jsxAttributes\"]) {\n      if (\n        this.$rules[prefix + \"jsxAttributes\"][index].token ===\n        \"meta.tag.punctuation.tag-close.xml\"\n      ) {\n        this.$rules[prefix + \"jsxAttributes\"][index].onMatch = function (\n          value,\n          currentState,\n          stack\n        ) {\n          if (currentState == stack[0]) stack.shift();\n          if (value.length == 2) {\n            if (stack[0] == this.nextState) stack[1]--;\n            if (!stack[1] || stack[1] < 0) {\n              stack.splice(0, 2);\n            }\n          }\n          this.next = stack[0] || prefix + \"start\";\n          return [{ type: this.token, value: value }];\n        };\n        break;\n      }\n    }\n  }\n\n  overwriteJSXendRule.call(this, \"javascript-\");\n  overwriteJSXendRule.call(this, \"inline-js-\");\n\n  this.normalizeRules();\n};\n\noop.inherits(AstroHighlightRules, HtmlHighlightRules);\nexports.AstroHighlightRules = AstroHighlightRules;"
  },
  {
    "path": "src/mode/autohotkey.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar AutoHotKeyHighlightRules = require(\"./autohotkey_highlight_rules\").AutoHotKeyHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = AutoHotKeyHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \";\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/autohotkey\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/autohotkey_highlight_rules.js",
    "content": "/* This file was autogenerated from C:\\Users\\LED\\Desktop\\AutoHotKey.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar AutoHotKeyHighlightRules = function() {\n    var autoItKeywords = 'And|ByRef|Case|Const|ContinueCase|ContinueLoop|Default|Dim|Do|Else|ElseIf|EndFunc|EndIf|EndSelect|EndSwitch|EndWith|Enum|Exit|ExitLoop|False|For|Func|Global|If|In|Local|Next|Not|Or|ReDim|Return|Select|Step|Switch|Then|To|True|Until|WEnd|While|With|' +       \n        'Abs|ACos|AdlibDisable|AdlibEnable|Asc|AscW|ASin|Assign|ATan|AutoItSetOption|AutoItWinGetTitle|AutoItWinSetTitle|Beep|Binary|BinaryLen|BinaryMid|BinaryToString|BitAND|BitNOT|BitOR|BitRotate|BitShift|BitXOR|BlockInput|Break|Call|CDTray|Ceiling|Chr|ChrW|ClipGet|ClipPut|ConsoleRead|ConsoleWrite|ConsoleWriteError|ControlClick|ControlCommand|ControlDisable|ControlEnable|ControlFocus|ControlGetFocus|ControlGetHandle|ControlGetPos|ControlGetText|ControlHide|ControlListView|ControlMove|ControlSend|ControlSetText|ControlShow|ControlTreeView|Cos|Dec|DirCopy|DirCreate|DirGetSize|DirMove|DirRemove|DllCall|DllCallbackFree|DllCallbackGetPtr|DllCallbackRegister|DllClose|DllOpen|DllStructCreate|DllStructGetData|DllStructGetPtr|DllStructGetSize|DllStructSetData|DriveGetDrive|DriveGetFileSystem|DriveGetLabel|DriveGetSerial|DriveGetType|DriveMapAdd|DriveMapDel|DriveMapGet|DriveSetLabel|DriveSpaceFree|DriveSpaceTotal|DriveStatus|EnvGet|EnvSet|EnvUpdate|Eval|Execute|Exp|FileChangeDir|FileClose|FileCopy|FileCreateNTFSLink|FileCreateShortcut|FileDelete|FileExists|FileFindFirstFile|FileFindNextFile|FileGetAttrib|FileGetLongName|FileGetShortcut|FileGetShortName|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileOpen|FileOpenDialog|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileSaveDialog|FileSelectFolder|FileSetAttrib|FileSetTime|FileWrite|FileWriteLine|Floor|FtpSetProxy|GUICreate|GUICtrlCreateAvi|GUICtrlCreateButton|GUICtrlCreateCheckbox|GUICtrlCreateCombo|GUICtrlCreateContextMenu|GUICtrlCreateDate|GUICtrlCreateDummy|GUICtrlCreateEdit|GUICtrlCreateGraphic|GUICtrlCreateGroup|GUICtrlCreateIcon|GUICtrlCreateInput|GUICtrlCreateLabel|GUICtrlCreateList|GUICtrlCreateListView|GUICtrlCreateListViewItem|GUICtrlCreateMenu|GUICtrlCreateMenuItem|GUICtrlCreateMonthCal|GUICtrlCreateObj|GUICtrlCreatePic|GUICtrlCreateProgress|GUICtrlCreateRadio|GUICtrlCreateSlider|GUICtrlCreateTab|GUICtrlCreateTabItem|GUICtrlCreateTreeView|GUICtrlCreateTreeViewItem|GUICtrlCreateUpdown|GUICtrlDelete|GUICtrlGetHandle|GUICtrlGetState|GUICtrlRead|GUICtrlRecvMsg|GUICtrlRegisterListViewSort|GUICtrlSendMsg|GUICtrlSendToDummy|GUICtrlSetBkColor|GUICtrlSetColor|GUICtrlSetCursor|GUICtrlSetData|GUICtrlSetFont|GUICtrlSetDefColor|GUICtrlSetDefBkColor|GUICtrlSetGraphic|GUICtrlSetImage|GUICtrlSetLimit|GUICtrlSetOnEvent|GUICtrlSetPos|GUICtrlSetResizing|GUICtrlSetState|GUICtrlSetStyle|GUICtrlSetTip|GUIDelete|GUIGetCursorInfo|GUIGetMsg|GUIGetStyle|GUIRegisterMsg|GUISetAccelerators()|GUISetBkColor|GUISetCoord|GUISetCursor|GUISetFont|GUISetHelp|GUISetIcon|GUISetOnEvent|GUISetState|GUISetStyle|GUIStartGroup|GUISwitch|Hex|HotKeySet|HttpSetProxy|HWnd|InetGet|InetGetSize|IniDelete|IniRead|IniReadSection|IniReadSectionNames|IniRenameSection|IniWrite|IniWriteSection|InputBox|Int|IsAdmin|IsArray|IsBinary|IsBool|IsDeclared|IsDllStruct|IsFloat|IsHWnd|IsInt|IsKeyword|IsNumber|IsObj|IsPtr|IsString|Log|MemGetStats|Mod|MouseClick|MouseClickDrag|MouseDown|MouseGetCursor|MouseGetPos|MouseMove|MouseUp|MouseWheel|MsgBox|Number|ObjCreate|ObjEvent|ObjGet|ObjName|Opt|Ping|PixelChecksum|PixelGetColor|PixelSearch|PluginClose|PluginOpen|ProcessClose|ProcessExists|ProcessGetStats|ProcessList|ProcessSetPriority|ProcessWait|ProcessWaitClose|ProgressOff|ProgressOn|ProgressSet|Ptr|Random|RegDelete|RegEnumKey|RegEnumVal|RegRead|RegWrite|Round|Run|RunAs|RunAsWait|RunWait|Send|SendKeepActive|SetError|SetExtended|ShellExecute|ShellExecuteWait|Shutdown|Sin|Sleep|SoundPlay|SoundSetWaveVolume|SplashImageOn|SplashOff|SplashTextOn|Sqrt|SRandom|StatusbarGetText|StderrRead|StdinWrite|StdioClose|StdoutRead|String|StringAddCR|StringCompare|StringFormat|StringInStr|StringIsAlNum|StringIsAlpha|StringIsASCII|StringIsDigit|StringIsFloat|StringIsInt|StringIsLower|StringIsSpace|StringIsUpper|StringIsXDigit|StringLeft|StringLen|StringLower|StringMid|StringRegExp|StringRegExpReplace|StringReplace|StringRight|StringSplit|StringStripCR|StringStripWS|StringToBinary|StringTrimLeft|StringTrimRight|StringUpper|Tan|TCPAccept|TCPCloseSocket|TCPConnect|TCPListen|TCPNameToIP|TCPRecv|TCPSend|TCPShutdown|TCPStartup|TimerDiff|TimerInit|ToolTip|TrayCreateItem|TrayCreateMenu|TrayGetMsg|TrayItemDelete|TrayItemGetHandle|TrayItemGetState|TrayItemGetText|TrayItemSetOnEvent|TrayItemSetState|TrayItemSetText|TraySetClick|TraySetIcon|TraySetOnEvent|TraySetPauseIcon|TraySetState|TraySetToolTip|TrayTip|UBound|UDPBind|UDPCloseSocket|UDPOpen|UDPRecv|UDPSend|UDPShutdown|UDPStartup|VarGetType|WinActivate|WinActive|WinClose|WinExists|WinFlash|WinGetCaretPos|WinGetClassList|WinGetClientSize|WinGetHandle|WinGetPos|WinGetProcess|WinGetState|WinGetText|WinGetTitle|WinKill|WinList|WinMenuSelectItem|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinSetOnTop|WinSetState|WinSetTitle|WinSetTrans|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive|' +\n        'ArrayAdd|ArrayBinarySearch|ArrayConcatenate|ArrayDelete|ArrayDisplay|ArrayFindAll|ArrayInsert|ArrayMax|ArrayMaxIndex|ArrayMin|ArrayMinIndex|ArrayPop|ArrayPush|ArrayReverse|ArraySearch|ArraySort|ArraySwap|ArrayToClip|ArrayToString|ArrayTrim|ChooseColor|ChooseFont|ClipBoard_ChangeChain|ClipBoard_Close|ClipBoard_CountFormats|ClipBoard_Empty|ClipBoard_EnumFormats|ClipBoard_FormatStr|ClipBoard_GetData|ClipBoard_GetDataEx|ClipBoard_GetFormatName|ClipBoard_GetOpenWindow|ClipBoard_GetOwner|ClipBoard_GetPriorityFormat|ClipBoard_GetSequenceNumber|ClipBoard_GetViewer|ClipBoard_IsFormatAvailable|ClipBoard_Open|ClipBoard_RegisterFormat|ClipBoard_SetData|ClipBoard_SetDataEx|ClipBoard_SetViewer|ClipPutFile|ColorConvertHSLtoRGB|ColorConvertRGBtoHSL|ColorGetBlue|ColorGetGreen|ColorGetRed|Date_Time_CompareFileTime|Date_Time_DOSDateTimeToArray|Date_Time_DOSDateTimeToFileTime|Date_Time_DOSDateTimeToStr|Date_Time_DOSDateToArray|Date_Time_DOSDateToStr|Date_Time_DOSTimeToArray|Date_Time_DOSTimeToStr|Date_Time_EncodeFileTime|Date_Time_EncodeSystemTime|Date_Time_FileTimeToArray|Date_Time_FileTimeToDOSDateTime|Date_Time_FileTimeToLocalFileTime|Date_Time_FileTimeToStr|Date_Time_FileTimeToSystemTime|Date_Time_GetFileTime|Date_Time_GetLocalTime|Date_Time_GetSystemTime|Date_Time_GetSystemTimeAdjustment|Date_Time_GetSystemTimeAsFileTime|Date_Time_GetSystemTimes|Date_Time_GetTickCount|Date_Time_GetTimeZoneInformation|Date_Time_LocalFileTimeToFileTime|Date_Time_SetFileTime|Date_Time_SetLocalTime|Date_Time_SetSystemTime|Date_Time_SetSystemTimeAdjustment|Date_Time_SetTimeZoneInformation|Date_Time_SystemTimeToArray|Date_Time_SystemTimeToDateStr|Date_Time_SystemTimeToDateTimeStr|Date_Time_SystemTimeToFileTime|Date_Time_SystemTimeToTimeStr|Date_Time_SystemTimeToTzSpecificLocalTime|Date_Time_TzSpecificLocalTimeToSystemTime|DateAdd|DateDayOfWeek|DateDaysInMonth|DateDiff|DateIsLeapYear|DateIsValid|DateTimeFormat|DateTimeSplit|DateToDayOfWeek|DateToDayOfWeekISO|DateToDayValue|DateToMonth|DayValueToDate|DebugBugReportEnv|DebugOut|DebugSetup|Degree|EventLog__Backup|EventLog__Clear|EventLog__Close|EventLog__Count|EventLog__DeregisterSource|EventLog__Full|EventLog__Notify|EventLog__Oldest|EventLog__Open|EventLog__OpenBackup|EventLog__Read|EventLog__RegisterSource|EventLog__Report|FileCountLines|FileCreate|FileListToArray|FilePrint|FileReadToArray|FileWriteFromArray|FileWriteLog|FileWriteToLine|GDIPlus_ArrowCapCreate|GDIPlus_ArrowCapDispose|GDIPlus_ArrowCapGetFillState|GDIPlus_ArrowCapGetHeight|GDIPlus_ArrowCapGetMiddleInset|GDIPlus_ArrowCapGetWidth|GDIPlus_ArrowCapSetFillState|GDIPlus_ArrowCapSetHeight|GDIPlus_ArrowCapSetMiddleInset|GDIPlus_ArrowCapSetWidth|GDIPlus_BitmapCloneArea|GDIPlus_BitmapCreateFromFile|GDIPlus_BitmapCreateFromGraphics|GDIPlus_BitmapCreateFromHBITMAP|GDIPlus_BitmapCreateHBITMAPFromBitmap|GDIPlus_BitmapDispose|GDIPlus_BitmapLockBits|GDIPlus_BitmapUnlockBits|GDIPlus_BrushClone|GDIPlus_BrushCreateSolid|GDIPlus_BrushDispose|GDIPlus_BrushGetType|GDIPlus_CustomLineCapDispose|GDIPlus_Decoders|GDIPlus_DecodersGetCount|GDIPlus_DecodersGetSize|GDIPlus_Encoders|GDIPlus_EncodersGetCLSID|GDIPlus_EncodersGetCount|GDIPlus_EncodersGetParamList|GDIPlus_EncodersGetParamListSize|GDIPlus_EncodersGetSize|GDIPlus_FontCreate|GDIPlus_FontDispose|GDIPlus_FontFamilyCreate|GDIPlus_FontFamilyDispose|GDIPlus_GraphicsClear|GDIPlus_GraphicsCreateFromHDC|GDIPlus_GraphicsCreateFromHWND|GDIPlus_GraphicsDispose|GDIPlus_GraphicsDrawArc|GDIPlus_GraphicsDrawBezier|GDIPlus_GraphicsDrawClosedCurve|GDIPlus_GraphicsDrawCurve|GDIPlus_GraphicsDrawEllipse|GDIPlus_GraphicsDrawImage|GDIPlus_GraphicsDrawImageRect|GDIPlus_GraphicsDrawImageRectRect|GDIPlus_GraphicsDrawLine|GDIPlus_GraphicsDrawPie|GDIPlus_GraphicsDrawPolygon|GDIPlus_GraphicsDrawRect|GDIPlus_GraphicsDrawString|GDIPlus_GraphicsDrawStringEx|GDIPlus_GraphicsFillClosedCurve|GDIPlus_GraphicsFillEllipse|GDIPlus_GraphicsFillPie|GDIPlus_GraphicsFillRect|GDIPlus_GraphicsGetDC|GDIPlus_GraphicsGetSmoothingMode|GDIPlus_GraphicsMeasureString|GDIPlus_GraphicsReleaseDC|GDIPlus_GraphicsSetSmoothingMode|GDIPlus_GraphicsSetTransform|GDIPlus_ImageDispose|GDIPlus_ImageGetGraphicsContext|GDIPlus_ImageGetHeight|GDIPlus_ImageGetWidth|GDIPlus_ImageLoadFromFile|GDIPlus_ImageSaveToFile|GDIPlus_ImageSaveToFileEx|GDIPlus_MatrixCreate|GDIPlus_MatrixDispose|GDIPlus_MatrixRotate|GDIPlus_ParamAdd|GDIPlus_ParamInit|GDIPlus_PenCreate|GDIPlus_PenDispose|GDIPlus_PenGetAlignment|GDIPlus_PenGetColor|GDIPlus_PenGetCustomEndCap|GDIPlus_PenGetDashCap|GDIPlus_PenGetDashStyle|GDIPlus_PenGetEndCap|GDIPlus_PenGetWidth|GDIPlus_PenSetAlignment|GDIPlus_PenSetColor|GDIPlus_PenSetCustomEndCap|GDIPlus_PenSetDashCap|GDIPlus_PenSetDashStyle|GDIPlus_PenSetEndCap|GDIPlus_PenSetWidth|GDIPlus_RectFCreate|GDIPlus_Shutdown|GDIPlus_Startup|GDIPlus_StringFormatCreate|GDIPlus_StringFormatDispose|GetIP|GUICtrlAVI_Close|GUICtrlAVI_Create|GUICtrlAVI_Destroy|GUICtrlAVI_Open|GUICtrlAVI_OpenEx|GUICtrlAVI_Play|GUICtrlAVI_Seek|GUICtrlAVI_Show|GUICtrlAVI_Stop|GUICtrlButton_Click|GUICtrlButton_Create|GUICtrlButton_Destroy|GUICtrlButton_Enable|GUICtrlButton_GetCheck|GUICtrlButton_GetFocus|GUICtrlButton_GetIdealSize|GUICtrlButton_GetImage|GUICtrlButton_GetImageList|GUICtrlButton_GetState|GUICtrlButton_GetText|GUICtrlButton_GetTextMargin|GUICtrlButton_SetCheck|GUICtrlButton_SetFocus|GUICtrlButton_SetImage|GUICtrlButton_SetImageList|GUICtrlButton_SetSize|GUICtrlButton_SetState|GUICtrlButton_SetStyle|GUICtrlButton_SetText|GUICtrlButton_SetTextMargin|GUICtrlButton_Show|GUICtrlComboBox_AddDir|GUICtrlComboBox_AddString|GUICtrlComboBox_AutoComplete|GUICtrlComboBox_BeginUpdate|GUICtrlComboBox_Create|GUICtrlComboBox_DeleteString|GUICtrlComboBox_Destroy|GUICtrlComboBox_EndUpdate|GUICtrlComboBox_FindString|GUICtrlComboBox_FindStringExact|GUICtrlComboBox_GetComboBoxInfo|GUICtrlComboBox_GetCount|GUICtrlComboBox_GetCurSel|GUICtrlComboBox_GetDroppedControlRect|GUICtrlComboBox_GetDroppedControlRectEx|GUICtrlComboBox_GetDroppedState|GUICtrlComboBox_GetDroppedWidth|GUICtrlComboBox_GetEditSel|GUICtrlComboBox_GetEditText|GUICtrlComboBox_GetExtendedUI|GUICtrlComboBox_GetHorizontalExtent|GUICtrlComboBox_GetItemHeight|GUICtrlComboBox_GetLBText|GUICtrlComboBox_GetLBTextLen|GUICtrlComboBox_GetList|GUICtrlComboBox_GetListArray|GUICtrlComboBox_GetLocale|GUICtrlComboBox_GetLocaleCountry|GUICtrlComboBox_GetLocaleLang|GUICtrlComboBox_GetLocalePrimLang|GUICtrlComboBox_GetLocaleSubLang|GUICtrlComboBox_GetMinVisible|GUICtrlComboBox_GetTopIndex|GUICtrlComboBox_InitStorage|GUICtrlComboBox_InsertString|GUICtrlComboBox_LimitText|GUICtrlComboBox_ReplaceEditSel|GUICtrlComboBox_ResetContent|GUICtrlComboBox_SelectString|GUICtrlComboBox_SetCurSel|GUICtrlComboBox_SetDroppedWidth|GUICtrlComboBox_SetEditSel|GUICtrlComboBox_SetEditText|GUICtrlComboBox_SetExtendedUI|GUICtrlComboBox_SetHorizontalExtent|GUICtrlComboBox_SetItemHeight|GUICtrlComboBox_SetMinVisible|GUICtrlComboBox_SetTopIndex|GUICtrlComboBox_ShowDropDown|GUICtrlComboBoxEx_AddDir|GUICtrlComboBoxEx_AddString|GUICtrlComboBoxEx_BeginUpdate|GUICtrlComboBoxEx_Create|GUICtrlComboBoxEx_CreateSolidBitMap|GUICtrlComboBoxEx_DeleteString|GUICtrlComboBoxEx_Destroy|GUICtrlComboBoxEx_EndUpdate|GUICtrlComboBoxEx_FindStringExact|GUICtrlComboBoxEx_GetComboBoxInfo|GUICtrlComboBoxEx_GetComboControl|GUICtrlComboBoxEx_GetCount|GUICtrlComboBoxEx_GetCurSel|GUICtrlComboBoxEx_GetDroppedControlRect|GUICtrlComboBoxEx_GetDroppedControlRectEx|GUICtrlComboBoxEx_GetDroppedState|GUICtrlComboBoxEx_GetDroppedWidth|GUICtrlComboBoxEx_GetEditControl|GUICtrlComboBoxEx_GetEditSel|GUICtrlComboBoxEx_GetEditText|GUICtrlComboBoxEx_GetExtendedStyle|GUICtrlComboBoxEx_GetExtendedUI|GUICtrlComboBoxEx_GetImageList|GUICtrlComboBoxEx_GetItem|GUICtrlComboBoxEx_GetItemEx|GUICtrlComboBoxEx_GetItemHeight|GUICtrlComboBoxEx_GetItemImage|GUICtrlComboBoxEx_GetItemIndent|GUICtrlComboBoxEx_GetItemOverlayImage|GUICtrlComboBoxEx_GetItemParam|GUICtrlComboBoxEx_GetItemSelectedImage|GUICtrlComboBoxEx_GetItemText|GUICtrlComboBoxEx_GetItemTextLen|GUICtrlComboBoxEx_GetList|GUICtrlComboBoxEx_GetListArray|GUICtrlComboBoxEx_GetLocale|GUICtrlComboBoxEx_GetLocaleCountry|GUICtrlComboBoxEx_GetLocaleLang|GUICtrlComboBoxEx_GetLocalePrimLang|GUICtrlComboBoxEx_GetLocaleSubLang|GUICtrlComboBoxEx_GetMinVisible|GUICtrlComboBoxEx_GetTopIndex|GUICtrlComboBoxEx_InitStorage|GUICtrlComboBoxEx_InsertString|GUICtrlComboBoxEx_LimitText|GUICtrlComboBoxEx_ReplaceEditSel|GUICtrlComboBoxEx_ResetContent|GUICtrlComboBoxEx_SetCurSel|GUICtrlComboBoxEx_SetDroppedWidth|GUICtrlComboBoxEx_SetEditSel|GUICtrlComboBoxEx_SetEditText|GUICtrlComboBoxEx_SetExtendedStyle|GUICtrlComboBoxEx_SetExtendedUI|GUICtrlComboBoxEx_SetImageList|GUICtrlComboBoxEx_SetItem|GUICtrlComboBoxEx_SetItemEx|GUICtrlComboBoxEx_SetItemHeight|GUICtrlComboBoxEx_SetItemImage|GUICtrlComboBoxEx_SetItemIndent|GUICtrlComboBoxEx_SetItemOverlayImage|GUICtrlComboBoxEx_SetItemParam|GUICtrlComboBoxEx_SetItemSelectedImage|GUICtrlComboBoxEx_SetMinVisible|GUICtrlComboBoxEx_SetTopIndex|GUICtrlComboBoxEx_ShowDropDown|GUICtrlDTP_Create|GUICtrlDTP_Destroy|GUICtrlDTP_GetMCColor|GUICtrlDTP_GetMCFont|GUICtrlDTP_GetMonthCal|GUICtrlDTP_GetRange|GUICtrlDTP_GetRangeEx|GUICtrlDTP_GetSystemTime|GUICtrlDTP_GetSystemTimeEx|GUICtrlDTP_SetFormat|GUICtrlDTP_SetMCColor|GUICtrlDTP_SetMCFont|GUICtrlDTP_SetRange|GUICtrlDTP_SetRangeEx|GUICtrlDTP_SetSystemTime|GUICtrlDTP_SetSystemTimeEx|GUICtrlEdit_AppendText|GUICtrlEdit_BeginUpdate|GUICtrlEdit_CanUndo|GUICtrlEdit_CharFromPos|GUICtrlEdit_Create|GUICtrlEdit_Destroy|GUICtrlEdit_EmptyUndoBuffer|GUICtrlEdit_EndUpdate|GUICtrlEdit_Find|GUICtrlEdit_FmtLines|GUICtrlEdit_GetFirstVisibleLine|GUICtrlEdit_GetLimitText|GUICtrlEdit_GetLine|GUICtrlEdit_GetLineCount|GUICtrlEdit_GetMargins|GUICtrlEdit_GetModify|GUICtrlEdit_GetPasswordChar|GUICtrlEdit_GetRECT|GUICtrlEdit_GetRECTEx|GUICtrlEdit_GetSel|GUICtrlEdit_GetText|GUICtrlEdit_GetTextLen|GUICtrlEdit_HideBalloonTip|GUICtrlEdit_InsertText|GUICtrlEdit_LineFromChar|GUICtrlEdit_LineIndex|GUICtrlEdit_LineLength|GUICtrlEdit_LineScroll|GUICtrlEdit_PosFromChar|GUICtrlEdit_ReplaceSel|GUICtrlEdit_Scroll|GUICtrlEdit_SetLimitText|GUICtrlEdit_SetMargins|GUICtrlEdit_SetModify|GUICtrlEdit_SetPasswordChar|GUICtrlEdit_SetReadOnly|GUICtrlEdit_SetRECT|GUICtrlEdit_SetRECTEx|GUICtrlEdit_SetRECTNP|GUICtrlEdit_SetRectNPEx|GUICtrlEdit_SetSel|GUICtrlEdit_SetTabStops|GUICtrlEdit_SetText|GUICtrlEdit_ShowBalloonTip|GUICtrlEdit_Undo|GUICtrlHeader_AddItem|GUICtrlHeader_ClearFilter|GUICtrlHeader_ClearFilterAll|GUICtrlHeader_Create|GUICtrlHeader_CreateDragImage|GUICtrlHeader_DeleteItem|GUICtrlHeader_Destroy|GUICtrlHeader_EditFilter|GUICtrlHeader_GetBitmapMargin|GUICtrlHeader_GetImageList|GUICtrlHeader_GetItem|GUICtrlHeader_GetItemAlign|GUICtrlHeader_GetItemBitmap|GUICtrlHeader_GetItemCount|GUICtrlHeader_GetItemDisplay|GUICtrlHeader_GetItemFlags|GUICtrlHeader_GetItemFormat|GUICtrlHeader_GetItemImage|GUICtrlHeader_GetItemOrder|GUICtrlHeader_GetItemParam|GUICtrlHeader_GetItemRect|GUICtrlHeader_GetItemRectEx|GUICtrlHeader_GetItemText|GUICtrlHeader_GetItemWidth|GUICtrlHeader_GetOrderArray|GUICtrlHeader_GetUnicodeFormat|GUICtrlHeader_HitTest|GUICtrlHeader_InsertItem|GUICtrlHeader_Layout|GUICtrlHeader_OrderToIndex|GUICtrlHeader_SetBitmapMargin|GUICtrlHeader_SetFilterChangeTimeout|GUICtrlHeader_SetHotDivider|GUICtrlHeader_SetImageList|GUICtrlHeader_SetItem|GUICtrlHeader_SetItemAlign|GUICtrlHeader_SetItemBitmap|GUICtrlHeader_SetItemDisplay|GUICtrlHeader_SetItemFlags|GUICtrlHeader_SetItemFormat|GUICtrlHeader_SetItemImage|GUICtrlHeader_SetItemOrder|GUICtrlHeader_SetItemParam|GUICtrlHeader_SetItemText|GUICtrlHeader_SetItemWidth|GUICtrlHeader_SetOrderArray|GUICtrlHeader_SetUnicodeFormat|GUICtrlIpAddress_ClearAddress|GUICtrlIpAddress_Create|GUICtrlIpAddress_Destroy|GUICtrlIpAddress_Get|GUICtrlIpAddress_GetArray|GUICtrlIpAddress_GetEx|GUICtrlIpAddress_IsBlank|GUICtrlIpAddress_Set|GUICtrlIpAddress_SetArray|GUICtrlIpAddress_SetEx|GUICtrlIpAddress_SetFocus|GUICtrlIpAddress_SetFont|GUICtrlIpAddress_SetRange|GUICtrlIpAddress_ShowHide|GUICtrlListBox_AddFile|GUICtrlListBox_AddString|GUICtrlListBox_BeginUpdate|GUICtrlListBox_Create|GUICtrlListBox_DeleteString|GUICtrlListBox_Destroy|GUICtrlListBox_Dir|GUICtrlListBox_EndUpdate|GUICtrlListBox_FindInText|GUICtrlListBox_FindString|GUICtrlListBox_GetAnchorIndex|GUICtrlListBox_GetCaretIndex|GUICtrlListBox_GetCount|GUICtrlListBox_GetCurSel|GUICtrlListBox_GetHorizontalExtent|GUICtrlListBox_GetItemData|GUICtrlListBox_GetItemHeight|GUICtrlListBox_GetItemRect|GUICtrlListBox_GetItemRectEx|GUICtrlListBox_GetListBoxInfo|GUICtrlListBox_GetLocale|GUICtrlListBox_GetLocaleCountry|GUICtrlListBox_GetLocaleLang|GUICtrlListBox_GetLocalePrimLang|GUICtrlListBox_GetLocaleSubLang|GUICtrlListBox_GetSel|GUICtrlListBox_GetSelCount|GUICtrlListBox_GetSelItems|GUICtrlListBox_GetSelItemsText|GUICtrlListBox_GetText|GUICtrlListBox_GetTextLen|GUICtrlListBox_GetTopIndex|GUICtrlListBox_InitStorage|GUICtrlListBox_InsertString|GUICtrlListBox_ItemFromPoint|GUICtrlListBox_ReplaceString|GUICtrlListBox_ResetContent|GUICtrlListBox_SelectString|GUICtrlListBox_SelItemRange|GUICtrlListBox_SelItemRangeEx|GUICtrlListBox_SetAnchorIndex|GUICtrlListBox_SetCaretIndex|GUICtrlListBox_SetColumnWidth|GUICtrlListBox_SetCurSel|GUICtrlListBox_SetHorizontalExtent|GUICtrlListBox_SetItemData|GUICtrlListBox_SetItemHeight|GUICtrlListBox_SetLocale|GUICtrlListBox_SetSel|GUICtrlListBox_SetTabStops|GUICtrlListBox_SetTopIndex|GUICtrlListBox_Sort|GUICtrlListBox_SwapString|GUICtrlListBox_UpdateHScroll|GUICtrlListView_AddArray|GUICtrlListView_AddColumn|GUICtrlListView_AddItem|GUICtrlListView_AddSubItem|GUICtrlListView_ApproximateViewHeight|GUICtrlListView_ApproximateViewRect|GUICtrlListView_ApproximateViewWidth|GUICtrlListView_Arrange|GUICtrlListView_BeginUpdate|GUICtrlListView_CancelEditLabel|GUICtrlListView_ClickItem|GUICtrlListView_CopyItems|GUICtrlListView_Create|GUICtrlListView_CreateDragImage|GUICtrlListView_CreateSolidBitMap|GUICtrlListView_DeleteAllItems|GUICtrlListView_DeleteColumn|GUICtrlListView_DeleteItem|GUICtrlListView_DeleteItemsSelected|GUICtrlListView_Destroy|GUICtrlListView_DrawDragImage|GUICtrlListView_EditLabel|GUICtrlListView_EnableGroupView|GUICtrlListView_EndUpdate|GUICtrlListView_EnsureVisible|GUICtrlListView_FindInText|GUICtrlListView_FindItem|GUICtrlListView_FindNearest|GUICtrlListView_FindParam|GUICtrlListView_FindText|GUICtrlListView_GetBkColor|GUICtrlListView_GetBkImage|GUICtrlListView_GetCallbackMask|GUICtrlListView_GetColumn|GUICtrlListView_GetColumnCount|GUICtrlListView_GetColumnOrder|GUICtrlListView_GetColumnOrderArray|GUICtrlListView_GetColumnWidth|GUICtrlListView_GetCounterPage|GUICtrlListView_GetEditControl|GUICtrlListView_GetExtendedListViewStyle|GUICtrlListView_GetGroupInfo|GUICtrlListView_GetGroupViewEnabled|GUICtrlListView_GetHeader|GUICtrlListView_GetHotCursor|GUICtrlListView_GetHotItem|GUICtrlListView_GetHoverTime|GUICtrlListView_GetImageList|GUICtrlListView_GetISearchString|GUICtrlListView_GetItem|GUICtrlListView_GetItemChecked|GUICtrlListView_GetItemCount|GUICtrlListView_GetItemCut|GUICtrlListView_GetItemDropHilited|GUICtrlListView_GetItemEx|GUICtrlListView_GetItemFocused|GUICtrlListView_GetItemGroupID|GUICtrlListView_GetItemImage|GUICtrlListView_GetItemIndent|GUICtrlListView_GetItemParam|GUICtrlListView_GetItemPosition|GUICtrlListView_GetItemPositionX|GUICtrlListView_GetItemPositionY|GUICtrlListView_GetItemRect|GUICtrlListView_GetItemRectEx|GUICtrlListView_GetItemSelected|GUICtrlListView_GetItemSpacing|GUICtrlListView_GetItemSpacingX|GUICtrlListView_GetItemSpacingY|GUICtrlListView_GetItemState|GUICtrlListView_GetItemStateImage|GUICtrlListView_GetItemText|GUICtrlListView_GetItemTextArray|GUICtrlListView_GetItemTextString|GUICtrlListView_GetNextItem|GUICtrlListView_GetNumberOfWorkAreas|GUICtrlListView_GetOrigin|GUICtrlListView_GetOriginX|GUICtrlListView_GetOriginY|GUICtrlListView_GetOutlineColor|GUICtrlListView_GetSelectedColumn|GUICtrlListView_GetSelectedCount|GUICtrlListView_GetSelectedIndices|GUICtrlListView_GetSelectionMark|GUICtrlListView_GetStringWidth|GUICtrlListView_GetSubItemRect|GUICtrlListView_GetTextBkColor|GUICtrlListView_GetTextColor|GUICtrlListView_GetToolTips|GUICtrlListView_GetTopIndex|GUICtrlListView_GetUnicodeFormat|GUICtrlListView_GetView|GUICtrlListView_GetViewDetails|GUICtrlListView_GetViewLarge|GUICtrlListView_GetViewList|GUICtrlListView_GetViewRect|GUICtrlListView_GetViewSmall|GUICtrlListView_GetViewTile|GUICtrlListView_HideColumn|GUICtrlListView_HitTest|GUICtrlListView_InsertColumn|GUICtrlListView_InsertGroup|GUICtrlListView_InsertItem|GUICtrlListView_JustifyColumn|GUICtrlListView_MapIDToIndex|GUICtrlListView_MapIndexToID|GUICtrlListView_RedrawItems|GUICtrlListView_RegisterSortCallBack|GUICtrlListView_RemoveAllGroups|GUICtrlListView_RemoveGroup|GUICtrlListView_Scroll|GUICtrlListView_SetBkColor|GUICtrlListView_SetBkImage|GUICtrlListView_SetCallBackMask|GUICtrlListView_SetColumn|GUICtrlListView_SetColumnOrder|GUICtrlListView_SetColumnOrderArray|GUICtrlListView_SetColumnWidth|GUICtrlListView_SetExtendedListViewStyle|GUICtrlListView_SetGroupInfo|GUICtrlListView_SetHotItem|GUICtrlListView_SetHoverTime|GUICtrlListView_SetIconSpacing|GUICtrlListView_SetImageList|GUICtrlListView_SetItem|GUICtrlListView_SetItemChecked|GUICtrlListView_SetItemCount|GUICtrlListView_SetItemCut|GUICtrlListView_SetItemDropHilited|GUICtrlListView_SetItemEx|GUICtrlListView_SetItemFocused|GUICtrlListView_SetItemGroupID|GUICtrlListView_SetItemImage|GUICtrlListView_SetItemIndent|GUICtrlListView_SetItemParam|GUICtrlListView_SetItemPosition|GUICtrlListView_SetItemPosition32|GUICtrlListView_SetItemSelected|GUICtrlListView_SetItemState|GUICtrlListView_SetItemStateImage|GUICtrlListView_SetItemText|GUICtrlListView_SetOutlineColor|GUICtrlListView_SetSelectedColumn|GUICtrlListView_SetSelectionMark|GUICtrlListView_SetTextBkColor|GUICtrlListView_SetTextColor|GUICtrlListView_SetToolTips|GUICtrlListView_SetUnicodeFormat|GUICtrlListView_SetView|GUICtrlListView_SetWorkAreas|GUICtrlListView_SimpleSort|GUICtrlListView_SortItems|GUICtrlListView_SubItemHitTest|GUICtrlListView_UnRegisterSortCallBack|GUICtrlMenu_AddMenuItem|GUICtrlMenu_AppendMenu|GUICtrlMenu_CheckMenuItem|GUICtrlMenu_CheckRadioItem|GUICtrlMenu_CreateMenu|GUICtrlMenu_CreatePopup|GUICtrlMenu_DeleteMenu|GUICtrlMenu_DestroyMenu|GUICtrlMenu_DrawMenuBar|GUICtrlMenu_EnableMenuItem|GUICtrlMenu_FindItem|GUICtrlMenu_FindParent|GUICtrlMenu_GetItemBmp|GUICtrlMenu_GetItemBmpChecked|GUICtrlMenu_GetItemBmpUnchecked|GUICtrlMenu_GetItemChecked|GUICtrlMenu_GetItemCount|GUICtrlMenu_GetItemData|GUICtrlMenu_GetItemDefault|GUICtrlMenu_GetItemDisabled|GUICtrlMenu_GetItemEnabled|GUICtrlMenu_GetItemGrayed|GUICtrlMenu_GetItemHighlighted|GUICtrlMenu_GetItemID|GUICtrlMenu_GetItemInfo|GUICtrlMenu_GetItemRect|GUICtrlMenu_GetItemRectEx|GUICtrlMenu_GetItemState|GUICtrlMenu_GetItemStateEx|GUICtrlMenu_GetItemSubMenu|GUICtrlMenu_GetItemText|GUICtrlMenu_GetItemType|GUICtrlMenu_GetMenu|GUICtrlMenu_GetMenuBackground|GUICtrlMenu_GetMenuBarInfo|GUICtrlMenu_GetMenuContextHelpID|GUICtrlMenu_GetMenuData|GUICtrlMenu_GetMenuDefaultItem|GUICtrlMenu_GetMenuHeight|GUICtrlMenu_GetMenuInfo|GUICtrlMenu_GetMenuStyle|GUICtrlMenu_GetSystemMenu|GUICtrlMenu_InsertMenuItem|GUICtrlMenu_InsertMenuItemEx|GUICtrlMenu_IsMenu|GUICtrlMenu_LoadMenu|GUICtrlMenu_MapAccelerator|GUICtrlMenu_MenuItemFromPoint|GUICtrlMenu_RemoveMenu|GUICtrlMenu_SetItemBitmaps|GUICtrlMenu_SetItemBmp|GUICtrlMenu_SetItemBmpChecked|GUICtrlMenu_SetItemBmpUnchecked|GUICtrlMenu_SetItemChecked|GUICtrlMenu_SetItemData|GUICtrlMenu_SetItemDefault|GUICtrlMenu_SetItemDisabled|GUICtrlMenu_SetItemEnabled|GUICtrlMenu_SetItemGrayed|GUICtrlMenu_SetItemHighlighted|GUICtrlMenu_SetItemID|GUICtrlMenu_SetItemInfo|GUICtrlMenu_SetItemState|GUICtrlMenu_SetItemSubMenu|GUICtrlMenu_SetItemText|GUICtrlMenu_SetItemType|GUICtrlMenu_SetMenu|GUICtrlMenu_SetMenuBackground|GUICtrlMenu_SetMenuContextHelpID|GUICtrlMenu_SetMenuData|GUICtrlMenu_SetMenuDefaultItem|GUICtrlMenu_SetMenuHeight|GUICtrlMenu_SetMenuInfo|GUICtrlMenu_SetMenuStyle|GUICtrlMenu_TrackPopupMenu|GUICtrlMonthCal_Create|GUICtrlMonthCal_Destroy|GUICtrlMonthCal_GetColor|GUICtrlMonthCal_GetColorArray|GUICtrlMonthCal_GetCurSel|GUICtrlMonthCal_GetCurSelStr|GUICtrlMonthCal_GetFirstDOW|GUICtrlMonthCal_GetFirstDOWStr|GUICtrlMonthCal_GetMaxSelCount|GUICtrlMonthCal_GetMaxTodayWidth|GUICtrlMonthCal_GetMinReqHeight|GUICtrlMonthCal_GetMinReqRect|GUICtrlMonthCal_GetMinReqRectArray|GUICtrlMonthCal_GetMinReqWidth|GUICtrlMonthCal_GetMonthDelta|GUICtrlMonthCal_GetMonthRange|GUICtrlMonthCal_GetMonthRangeMax|GUICtrlMonthCal_GetMonthRangeMaxStr|GUICtrlMonthCal_GetMonthRangeMin|GUICtrlMonthCal_GetMonthRangeMinStr|GUICtrlMonthCal_GetMonthRangeSpan|GUICtrlMonthCal_GetRange|GUICtrlMonthCal_GetRangeMax|GUICtrlMonthCal_GetRangeMaxStr|GUICtrlMonthCal_GetRangeMin|GUICtrlMonthCal_GetRangeMinStr|GUICtrlMonthCal_GetSelRange|GUICtrlMonthCal_GetSelRangeMax|GUICtrlMonthCal_GetSelRangeMaxStr|GUICtrlMonthCal_GetSelRangeMin|GUICtrlMonthCal_GetSelRangeMinStr|GUICtrlMonthCal_GetToday|GUICtrlMonthCal_GetTodayStr|GUICtrlMonthCal_GetUnicodeFormat|GUICtrlMonthCal_HitTest|GUICtrlMonthCal_SetColor|GUICtrlMonthCal_SetCurSel|GUICtrlMonthCal_SetDayState|GUICtrlMonthCal_SetFirstDOW|GUICtrlMonthCal_SetMaxSelCount|GUICtrlMonthCal_SetMonthDelta|GUICtrlMonthCal_SetRange|GUICtrlMonthCal_SetSelRange|GUICtrlMonthCal_SetToday|GUICtrlMonthCal_SetUnicodeFormat|GUICtrlRebar_AddBand|GUICtrlRebar_AddToolBarBand|GUICtrlRebar_BeginDrag|GUICtrlRebar_Create|GUICtrlRebar_DeleteBand|GUICtrlRebar_Destroy|GUICtrlRebar_DragMove|GUICtrlRebar_EndDrag|GUICtrlRebar_GetBandBackColor|GUICtrlRebar_GetBandBorders|GUICtrlRebar_GetBandBordersEx|GUICtrlRebar_GetBandChildHandle|GUICtrlRebar_GetBandChildSize|GUICtrlRebar_GetBandCount|GUICtrlRebar_GetBandForeColor|GUICtrlRebar_GetBandHeaderSize|GUICtrlRebar_GetBandID|GUICtrlRebar_GetBandIdealSize|GUICtrlRebar_GetBandLength|GUICtrlRebar_GetBandLParam|GUICtrlRebar_GetBandMargins|GUICtrlRebar_GetBandMarginsEx|GUICtrlRebar_GetBandRect|GUICtrlRebar_GetBandRectEx|GUICtrlRebar_GetBandStyle|GUICtrlRebar_GetBandStyleBreak|GUICtrlRebar_GetBandStyleChildEdge|GUICtrlRebar_GetBandStyleFixedBMP|GUICtrlRebar_GetBandStyleFixedSize|GUICtrlRebar_GetBandStyleGripperAlways|GUICtrlRebar_GetBandStyleHidden|GUICtrlRebar_GetBandStyleHideTitle|GUICtrlRebar_GetBandStyleNoGripper|GUICtrlRebar_GetBandStyleTopAlign|GUICtrlRebar_GetBandStyleUseChevron|GUICtrlRebar_GetBandStyleVariableHeight|GUICtrlRebar_GetBandText|GUICtrlRebar_GetBarHeight|GUICtrlRebar_GetBKColor|GUICtrlRebar_GetColorScheme|GUICtrlRebar_GetRowCount|GUICtrlRebar_GetRowHeight|GUICtrlRebar_GetTextColor|GUICtrlRebar_GetToolTips|GUICtrlRebar_GetUnicodeFormat|GUICtrlRebar_HitTest|GUICtrlRebar_IDToIndex|GUICtrlRebar_MaximizeBand|GUICtrlRebar_MinimizeBand|GUICtrlRebar_MoveBand|GUICtrlRebar_SetBandBackColor|GUICtrlRebar_SetBandForeColor|GUICtrlRebar_SetBandHeaderSize|GUICtrlRebar_SetBandID|GUICtrlRebar_SetBandIdealSize|GUICtrlRebar_SetBandLength|GUICtrlRebar_SetBandLParam|GUICtrlRebar_SetBandStyle|GUICtrlRebar_SetBandStyleBreak|GUICtrlRebar_SetBandStyleChildEdge|GUICtrlRebar_SetBandStyleFixedBMP|GUICtrlRebar_SetBandStyleFixedSize|GUICtrlRebar_SetBandStyleGripperAlways|GUICtrlRebar_SetBandStyleHidden|GUICtrlRebar_SetBandStyleHideTitle|GUICtrlRebar_SetBandStyleNoGripper|GUICtrlRebar_SetBandStyleTopAlign|GUICtrlRebar_SetBandStyleUseChevron|GUICtrlRebar_SetBandStyleVariableHeight|GUICtrlRebar_SetBandText|GUICtrlRebar_SetBKColor|GUICtrlRebar_SetColorScheme|GUICtrlRebar_SetTextColor|GUICtrlRebar_SetToolTips|GUICtrlRebar_SetUnicodeFormat|GUICtrlRebar_ShowBand|GUICtrlSlider_ClearSel|GUICtrlSlider_ClearTics|GUICtrlSlider_Create|GUICtrlSlider_Destroy|GUICtrlSlider_GetBuddy|GUICtrlSlider_GetChannelRect|GUICtrlSlider_GetLineSize|GUICtrlSlider_GetNumTics|GUICtrlSlider_GetPageSize|GUICtrlSlider_GetPos|GUICtrlSlider_GetPTics|GUICtrlSlider_GetRange|GUICtrlSlider_GetRangeMax|GUICtrlSlider_GetRangeMin|GUICtrlSlider_GetSel|GUICtrlSlider_GetSelEnd|GUICtrlSlider_GetSelStart|GUICtrlSlider_GetThumbLength|GUICtrlSlider_GetThumbRect|GUICtrlSlider_GetThumbRectEx|GUICtrlSlider_GetTic|GUICtrlSlider_GetTicPos|GUICtrlSlider_GetToolTips|GUICtrlSlider_GetUnicodeFormat|GUICtrlSlider_SetBuddy|GUICtrlSlider_SetLineSize|GUICtrlSlider_SetPageSize|GUICtrlSlider_SetPos|GUICtrlSlider_SetRange|GUICtrlSlider_SetRangeMax|GUICtrlSlider_SetRangeMin|GUICtrlSlider_SetSel|GUICtrlSlider_SetSelEnd|GUICtrlSlider_SetSelStart|GUICtrlSlider_SetThumbLength|GUICtrlSlider_SetTic|GUICtrlSlider_SetTicFreq|GUICtrlSlider_SetTipSide|GUICtrlSlider_SetToolTips|GUICtrlSlider_SetUnicodeFormat|GUICtrlStatusBar_Create|GUICtrlStatusBar_Destroy|GUICtrlStatusBar_EmbedControl|GUICtrlStatusBar_GetBorders|GUICtrlStatusBar_GetBordersHorz|GUICtrlStatusBar_GetBordersRect|GUICtrlStatusBar_GetBordersVert|GUICtrlStatusBar_GetCount|GUICtrlStatusBar_GetHeight|GUICtrlStatusBar_GetIcon|GUICtrlStatusBar_GetParts|GUICtrlStatusBar_GetRect|GUICtrlStatusBar_GetRectEx|GUICtrlStatusBar_GetText|GUICtrlStatusBar_GetTextFlags|GUICtrlStatusBar_GetTextLength|GUICtrlStatusBar_GetTextLengthEx|GUICtrlStatusBar_GetTipText|GUICtrlStatusBar_GetUnicodeFormat|GUICtrlStatusBar_GetWidth|GUICtrlStatusBar_IsSimple|GUICtrlStatusBar_Resize|GUICtrlStatusBar_SetBkColor|GUICtrlStatusBar_SetIcon|GUICtrlStatusBar_SetMinHeight|GUICtrlStatusBar_SetParts|GUICtrlStatusBar_SetSimple|GUICtrlStatusBar_SetText|GUICtrlStatusBar_SetTipText|GUICtrlStatusBar_SetUnicodeFormat|GUICtrlStatusBar_ShowHide|GUICtrlTab_Create|GUICtrlTab_DeleteAllItems|GUICtrlTab_DeleteItem|GUICtrlTab_DeselectAll|GUICtrlTab_Destroy|GUICtrlTab_FindTab|GUICtrlTab_GetCurFocus|GUICtrlTab_GetCurSel|GUICtrlTab_GetDisplayRect|GUICtrlTab_GetDisplayRectEx|GUICtrlTab_GetExtendedStyle|GUICtrlTab_GetImageList|GUICtrlTab_GetItem|GUICtrlTab_GetItemCount|GUICtrlTab_GetItemImage|GUICtrlTab_GetItemParam|GUICtrlTab_GetItemRect|GUICtrlTab_GetItemRectEx|GUICtrlTab_GetItemState|GUICtrlTab_GetItemText|GUICtrlTab_GetRowCount|GUICtrlTab_GetToolTips|GUICtrlTab_GetUnicodeFormat|GUICtrlTab_HighlightItem|GUICtrlTab_HitTest|GUICtrlTab_InsertItem|GUICtrlTab_RemoveImage|GUICtrlTab_SetCurFocus|GUICtrlTab_SetCurSel|GUICtrlTab_SetExtendedStyle|GUICtrlTab_SetImageList|GUICtrlTab_SetItem|GUICtrlTab_SetItemImage|GUICtrlTab_SetItemParam|GUICtrlTab_SetItemSize|GUICtrlTab_SetItemState|GUICtrlTab_SetItemText|GUICtrlTab_SetMinTabWidth|GUICtrlTab_SetPadding|GUICtrlTab_SetToolTips|GUICtrlTab_SetUnicodeFormat|GUICtrlToolbar_AddBitmap|GUICtrlToolbar_AddButton|GUICtrlToolbar_AddButtonSep|GUICtrlToolbar_AddString|GUICtrlToolbar_ButtonCount|GUICtrlToolbar_CheckButton|GUICtrlToolbar_ClickAccel|GUICtrlToolbar_ClickButton|GUICtrlToolbar_ClickIndex|GUICtrlToolbar_CommandToIndex|GUICtrlToolbar_Create|GUICtrlToolbar_Customize|GUICtrlToolbar_DeleteButton|GUICtrlToolbar_Destroy|GUICtrlToolbar_EnableButton|GUICtrlToolbar_FindToolbar|GUICtrlToolbar_GetAnchorHighlight|GUICtrlToolbar_GetBitmapFlags|GUICtrlToolbar_GetButtonBitmap|GUICtrlToolbar_GetButtonInfo|GUICtrlToolbar_GetButtonInfoEx|GUICtrlToolbar_GetButtonParam|GUICtrlToolbar_GetButtonRect|GUICtrlToolbar_GetButtonRectEx|GUICtrlToolbar_GetButtonSize|GUICtrlToolbar_GetButtonState|GUICtrlToolbar_GetButtonStyle|GUICtrlToolbar_GetButtonText|GUICtrlToolbar_GetColorScheme|GUICtrlToolbar_GetDisabledImageList|GUICtrlToolbar_GetExtendedStyle|GUICtrlToolbar_GetHotImageList|GUICtrlToolbar_GetHotItem|GUICtrlToolbar_GetImageList|GUICtrlToolbar_GetInsertMark|GUICtrlToolbar_GetInsertMarkColor|GUICtrlToolbar_GetMaxSize|GUICtrlToolbar_GetMetrics|GUICtrlToolbar_GetPadding|GUICtrlToolbar_GetRows|GUICtrlToolbar_GetString|GUICtrlToolbar_GetStyle|GUICtrlToolbar_GetStyleAltDrag|GUICtrlToolbar_GetStyleCustomErase|GUICtrlToolbar_GetStyleFlat|GUICtrlToolbar_GetStyleList|GUICtrlToolbar_GetStyleRegisterDrop|GUICtrlToolbar_GetStyleToolTips|GUICtrlToolbar_GetStyleTransparent|GUICtrlToolbar_GetStyleWrapable|GUICtrlToolbar_GetTextRows|GUICtrlToolbar_GetToolTips|GUICtrlToolbar_GetUnicodeFormat|GUICtrlToolbar_HideButton|GUICtrlToolbar_HighlightButton|GUICtrlToolbar_HitTest|GUICtrlToolbar_IndexToCommand|GUICtrlToolbar_InsertButton|GUICtrlToolbar_InsertMarkHitTest|GUICtrlToolbar_IsButtonChecked|GUICtrlToolbar_IsButtonEnabled|GUICtrlToolbar_IsButtonHidden|GUICtrlToolbar_IsButtonHighlighted|GUICtrlToolbar_IsButtonIndeterminate|GUICtrlToolbar_IsButtonPressed|GUICtrlToolbar_LoadBitmap|GUICtrlToolbar_LoadImages|GUICtrlToolbar_MapAccelerator|GUICtrlToolbar_MoveButton|GUICtrlToolbar_PressButton|GUICtrlToolbar_SetAnchorHighlight|GUICtrlToolbar_SetBitmapSize|GUICtrlToolbar_SetButtonBitMap|GUICtrlToolbar_SetButtonInfo|GUICtrlToolbar_SetButtonInfoEx|GUICtrlToolbar_SetButtonParam|GUICtrlToolbar_SetButtonSize|GUICtrlToolbar_SetButtonState|GUICtrlToolbar_SetButtonStyle|GUICtrlToolbar_SetButtonText|GUICtrlToolbar_SetButtonWidth|GUICtrlToolbar_SetCmdID|GUICtrlToolbar_SetColorScheme|GUICtrlToolbar_SetDisabledImageList|GUICtrlToolbar_SetDrawTextFlags|GUICtrlToolbar_SetExtendedStyle|GUICtrlToolbar_SetHotImageList|GUICtrlToolbar_SetHotItem|GUICtrlToolbar_SetImageList|GUICtrlToolbar_SetIndent|GUICtrlToolbar_SetIndeterminate|GUICtrlToolbar_SetInsertMark|GUICtrlToolbar_SetInsertMarkColor|GUICtrlToolbar_SetMaxTextRows|GUICtrlToolbar_SetMetrics|GUICtrlToolbar_SetPadding|GUICtrlToolbar_SetParent|GUICtrlToolbar_SetRows|GUICtrlToolbar_SetStyle|GUICtrlToolbar_SetStyleAltDrag|GUICtrlToolbar_SetStyleCustomErase|GUICtrlToolbar_SetStyleFlat|GUICtrlToolbar_SetStyleList|GUICtrlToolbar_SetStyleRegisterDrop|GUICtrlToolbar_SetStyleToolTips|GUICtrlToolbar_SetStyleTransparent|GUICtrlToolbar_SetStyleWrapable|GUICtrlToolbar_SetToolTips|GUICtrlToolbar_SetUnicodeFormat|GUICtrlToolbar_SetWindowTheme|GUICtrlTreeView_Add|GUICtrlTreeView_AddChild|GUICtrlTreeView_AddChildFirst|GUICtrlTreeView_AddFirst|GUICtrlTreeView_BeginUpdate|GUICtrlTreeView_ClickItem|GUICtrlTreeView_Create|GUICtrlTreeView_CreateDragImage|GUICtrlTreeView_CreateSolidBitMap|GUICtrlTreeView_Delete|GUICtrlTreeView_DeleteAll|GUICtrlTreeView_DeleteChildren|GUICtrlTreeView_Destroy|GUICtrlTreeView_DisplayRect|GUICtrlTreeView_DisplayRectEx|GUICtrlTreeView_EditText|GUICtrlTreeView_EndEdit|GUICtrlTreeView_EndUpdate|GUICtrlTreeView_EnsureVisible|GUICtrlTreeView_Expand|GUICtrlTreeView_ExpandedOnce|GUICtrlTreeView_FindItem|GUICtrlTreeView_FindItemEx|GUICtrlTreeView_GetBkColor|GUICtrlTreeView_GetBold|GUICtrlTreeView_GetChecked|GUICtrlTreeView_GetChildCount|GUICtrlTreeView_GetChildren|GUICtrlTreeView_GetCount|GUICtrlTreeView_GetCut|GUICtrlTreeView_GetDropTarget|GUICtrlTreeView_GetEditControl|GUICtrlTreeView_GetExpanded|GUICtrlTreeView_GetFirstChild|GUICtrlTreeView_GetFirstItem|GUICtrlTreeView_GetFirstVisible|GUICtrlTreeView_GetFocused|GUICtrlTreeView_GetHeight|GUICtrlTreeView_GetImageIndex|GUICtrlTreeView_GetImageListIconHandle|GUICtrlTreeView_GetIndent|GUICtrlTreeView_GetInsertMarkColor|GUICtrlTreeView_GetISearchString|GUICtrlTreeView_GetItemByIndex|GUICtrlTreeView_GetItemHandle|GUICtrlTreeView_GetItemParam|GUICtrlTreeView_GetLastChild|GUICtrlTreeView_GetLineColor|GUICtrlTreeView_GetNext|GUICtrlTreeView_GetNextChild|GUICtrlTreeView_GetNextSibling|GUICtrlTreeView_GetNextVisible|GUICtrlTreeView_GetNormalImageList|GUICtrlTreeView_GetParentHandle|GUICtrlTreeView_GetParentParam|GUICtrlTreeView_GetPrev|GUICtrlTreeView_GetPrevChild|GUICtrlTreeView_GetPrevSibling|GUICtrlTreeView_GetPrevVisible|GUICtrlTreeView_GetScrollTime|GUICtrlTreeView_GetSelected|GUICtrlTreeView_GetSelectedImageIndex|GUICtrlTreeView_GetSelection|GUICtrlTreeView_GetSiblingCount|GUICtrlTreeView_GetState|GUICtrlTreeView_GetStateImageIndex|GUICtrlTreeView_GetStateImageList|GUICtrlTreeView_GetText|GUICtrlTreeView_GetTextColor|GUICtrlTreeView_GetToolTips|GUICtrlTreeView_GetTree|GUICtrlTreeView_GetUnicodeFormat|GUICtrlTreeView_GetVisible|GUICtrlTreeView_GetVisibleCount|GUICtrlTreeView_HitTest|GUICtrlTreeView_HitTestEx|GUICtrlTreeView_HitTestItem|GUICtrlTreeView_Index|GUICtrlTreeView_InsertItem|GUICtrlTreeView_IsFirstItem|GUICtrlTreeView_IsParent|GUICtrlTreeView_Level|GUICtrlTreeView_SelectItem|GUICtrlTreeView_SelectItemByIndex|GUICtrlTreeView_SetBkColor|GUICtrlTreeView_SetBold|GUICtrlTreeView_SetChecked|GUICtrlTreeView_SetCheckedByIndex|GUICtrlTreeView_SetChildren|GUICtrlTreeView_SetCut|GUICtrlTreeView_SetDropTarget|GUICtrlTreeView_SetFocused|GUICtrlTreeView_SetHeight|GUICtrlTreeView_SetIcon|GUICtrlTreeView_SetImageIndex|GUICtrlTreeView_SetIndent|GUICtrlTreeView_SetInsertMark|GUICtrlTreeView_SetInsertMarkColor|GUICtrlTreeView_SetItemHeight|GUICtrlTreeView_SetItemParam|GUICtrlTreeView_SetLineColor|GUICtrlTreeView_SetNormalImageList|GUICtrlTreeView_SetScrollTime|GUICtrlTreeView_SetSelected|GUICtrlTreeView_SetSelectedImageIndex|GUICtrlTreeView_SetState|GUICtrlTreeView_SetStateImageIndex|GUICtrlTreeView_SetStateImageList|GUICtrlTreeView_SetText|GUICtrlTreeView_SetTextColor|GUICtrlTreeView_SetToolTips|GUICtrlTreeView_SetUnicodeFormat|GUICtrlTreeView_Sort|GUIImageList_Add|GUIImageList_AddBitmap|GUIImageList_AddIcon|GUIImageList_AddMasked|GUIImageList_BeginDrag|GUIImageList_Copy|GUIImageList_Create|GUIImageList_Destroy|GUIImageList_DestroyIcon|GUIImageList_DragEnter|GUIImageList_DragLeave|GUIImageList_DragMove|GUIImageList_Draw|GUIImageList_DrawEx|GUIImageList_Duplicate|GUIImageList_EndDrag|GUIImageList_GetBkColor|GUIImageList_GetIcon|GUIImageList_GetIconHeight|GUIImageList_GetIconSize|GUIImageList_GetIconSizeEx|GUIImageList_GetIconWidth|GUIImageList_GetImageCount|GUIImageList_GetImageInfoEx|GUIImageList_Remove|GUIImageList_ReplaceIcon|GUIImageList_SetBkColor|GUIImageList_SetIconSize|GUIImageList_SetImageCount|GUIImageList_Swap|GUIScrollBars_EnableScrollBar|GUIScrollBars_GetScrollBarInfoEx|GUIScrollBars_GetScrollBarRect|GUIScrollBars_GetScrollBarRGState|GUIScrollBars_GetScrollBarXYLineButton|GUIScrollBars_GetScrollBarXYThumbBottom|GUIScrollBars_GetScrollBarXYThumbTop|GUIScrollBars_GetScrollInfo|GUIScrollBars_GetScrollInfoEx|GUIScrollBars_GetScrollInfoMax|GUIScrollBars_GetScrollInfoMin|GUIScrollBars_GetScrollInfoPage|GUIScrollBars_GetScrollInfoPos|GUIScrollBars_GetScrollInfoTrackPos|GUIScrollBars_GetScrollPos|GUIScrollBars_GetScrollRange|GUIScrollBars_Init|GUIScrollBars_ScrollWindow|GUIScrollBars_SetScrollInfo|GUIScrollBars_SetScrollInfoMax|GUIScrollBars_SetScrollInfoMin|GUIScrollBars_SetScrollInfoPage|GUIScrollBars_SetScrollInfoPos|GUIScrollBars_SetScrollRange|GUIScrollBars_ShowScrollBar|GUIToolTip_Activate|GUIToolTip_AddTool|GUIToolTip_AdjustRect|GUIToolTip_BitsToTTF|GUIToolTip_Create|GUIToolTip_DelTool|GUIToolTip_Destroy|GUIToolTip_EnumTools|GUIToolTip_GetBubbleHeight|GUIToolTip_GetBubbleSize|GUIToolTip_GetBubbleWidth|GUIToolTip_GetCurrentTool|GUIToolTip_GetDelayTime|GUIToolTip_GetMargin|GUIToolTip_GetMarginEx|GUIToolTip_GetMaxTipWidth|GUIToolTip_GetText|GUIToolTip_GetTipBkColor|GUIToolTip_GetTipTextColor|GUIToolTip_GetTitleBitMap|GUIToolTip_GetTitleText|GUIToolTip_GetToolCount|GUIToolTip_GetToolInfo|GUIToolTip_HitTest|GUIToolTip_NewToolRect|GUIToolTip_Pop|GUIToolTip_PopUp|GUIToolTip_SetDelayTime|GUIToolTip_SetMargin|GUIToolTip_SetMaxTipWidth|GUIToolTip_SetTipBkColor|GUIToolTip_SetTipTextColor|GUIToolTip_SetTitle|GUIToolTip_SetToolInfo|GUIToolTip_SetWindowTheme|GUIToolTip_ToolExists|GUIToolTip_ToolToArray|GUIToolTip_TrackActivate|GUIToolTip_TrackPosition|GUIToolTip_TTFToBits|GUIToolTip_Update|GUIToolTip_UpdateTipText|HexToString|IE_Example|IE_Introduction|IE_VersionInfo|IEAction|IEAttach|IEBodyReadHTML|IEBodyReadText|IEBodyWriteHTML|IECreate|IECreateEmbedded|IEDocGetObj|IEDocInsertHTML|IEDocInsertText|IEDocReadHTML|IEDocWriteHTML|IEErrorHandlerDeRegister|IEErrorHandlerRegister|IEErrorNotify|IEFormElementCheckBoxSelect|IEFormElementGetCollection|IEFormElementGetObjByName|IEFormElementGetValue|IEFormElementOptionSelect|IEFormElementRadioSelect|IEFormElementSetValue|IEFormGetCollection|IEFormGetObjByName|IEFormImageClick|IEFormReset|IEFormSubmit|IEFrameGetCollection|IEFrameGetObjByName|IEGetObjById|IEGetObjByName|IEHeadInsertEventScript|IEImgClick|IEImgGetCollection|IEIsFrameSet|IELinkClickByIndex|IELinkClickByText|IELinkGetCollection|IELoadWait|IELoadWaitTimeout|IENavigate|IEPropertyGet|IEPropertySet|IEQuit|IETableGetCollection|IETableWriteToArray|IETagNameAllGetCollection|IETagNameGetCollection|Iif|INetExplorerCapable|INetGetSource|INetMail|INetSmtpMail|IsPressed|MathCheckDiv|Max|MemGlobalAlloc|MemGlobalFree|MemGlobalLock|MemGlobalSize|MemGlobalUnlock|MemMoveMemory|MemMsgBox|MemShowError|MemVirtualAlloc|MemVirtualAllocEx|MemVirtualFree|MemVirtualFreeEx|Min|MouseTrap|NamedPipes_CallNamedPipe|NamedPipes_ConnectNamedPipe|NamedPipes_CreateNamedPipe|NamedPipes_CreatePipe|NamedPipes_DisconnectNamedPipe|NamedPipes_GetNamedPipeHandleState|NamedPipes_GetNamedPipeInfo|NamedPipes_PeekNamedPipe|NamedPipes_SetNamedPipeHandleState|NamedPipes_TransactNamedPipe|NamedPipes_WaitNamedPipe|Net_Share_ConnectionEnum|Net_Share_FileClose|Net_Share_FileEnum|Net_Share_FileGetInfo|Net_Share_PermStr|Net_Share_ResourceStr|Net_Share_SessionDel|Net_Share_SessionEnum|Net_Share_SessionGetInfo|Net_Share_ShareAdd|Net_Share_ShareCheck|Net_Share_ShareDel|Net_Share_ShareEnum|Net_Share_ShareGetInfo|Net_Share_ShareSetInfo|Net_Share_StatisticsGetSvr|Net_Share_StatisticsGetWrk|Now|NowCalc|NowCalcDate|NowDate|NowTime|PathFull|PathMake|PathSplit|ProcessGetName|ProcessGetPriority|Radian|ReplaceStringInFile|RunDOS|ScreenCapture_Capture|ScreenCapture_CaptureWnd|ScreenCapture_SaveImage|ScreenCapture_SetBMPFormat|ScreenCapture_SetJPGQuality|ScreenCapture_SetTIFColorDepth|ScreenCapture_SetTIFCompression|Security__AdjustTokenPrivileges|Security__GetAccountSid|Security__GetLengthSid|Security__GetTokenInformation|Security__ImpersonateSelf|Security__IsValidSid|Security__LookupAccountName|Security__LookupAccountSid|Security__LookupPrivilegeValue|Security__OpenProcessToken|Security__OpenThreadToken|Security__OpenThreadTokenEx|Security__SetPrivilege|Security__SidToStringSid|Security__SidTypeStr|Security__StringSidToSid|SendMessage|SendMessageA|SetDate|SetTime|Singleton|SoundClose|SoundLength|SoundOpen|SoundPause|SoundPlay|SoundPos|SoundResume|SoundSeek|SoundStatus|SoundStop|SQLite_Changes|SQLite_Close|SQLite_Display2DResult|SQLite_Encode|SQLite_ErrCode|SQLite_ErrMsg|SQLite_Escape|SQLite_Exec|SQLite_FetchData|SQLite_FetchNames|SQLite_GetTable|SQLite_GetTable2d|SQLite_LastInsertRowID|SQLite_LibVersion|SQLite_Open|SQLite_Query|SQLite_QueryFinalize|SQLite_QueryReset|SQLite_QuerySingleRow|SQLite_SaveMode|SQLite_SetTimeout|SQLite_Shutdown|SQLite_SQLiteExe|SQLite_Startup|SQLite_TotalChanges|StringAddComma|StringBetween|StringEncrypt|StringInsert|StringProper|StringRepeat|StringReverse|StringSplit|StringToHex|TCPIpToName|TempFile|TicksToTime|Timer_Diff|Timer_GetTimerID|Timer_Init|Timer_KillAllTimers|Timer_KillTimer|Timer_SetTimer|TimeToTicks|VersionCompare|viClose|viExecCommand|viFindGpib|viGpibBusReset|viGTL|viOpen|viSetAttribute|viSetTimeout|WeekNumberISO|WinAPI_AttachConsole|WinAPI_AttachThreadInput|WinAPI_Beep|WinAPI_BitBlt|WinAPI_CallNextHookEx|WinAPI_Check|WinAPI_ClientToScreen|WinAPI_CloseHandle|WinAPI_CommDlgExtendedError|WinAPI_CopyIcon|WinAPI_CreateBitmap|WinAPI_CreateCompatibleBitmap|WinAPI_CreateCompatibleDC|WinAPI_CreateEvent|WinAPI_CreateFile|WinAPI_CreateFont|WinAPI_CreateFontIndirect|WinAPI_CreateProcess|WinAPI_CreateSolidBitmap|WinAPI_CreateSolidBrush|WinAPI_CreateWindowEx|WinAPI_DefWindowProc|WinAPI_DeleteDC|WinAPI_DeleteObject|WinAPI_DestroyIcon|WinAPI_DestroyWindow|WinAPI_DrawEdge|WinAPI_DrawFrameControl|WinAPI_DrawIcon|WinAPI_DrawIconEx|WinAPI_DrawText|WinAPI_EnableWindow|WinAPI_EnumDisplayDevices|WinAPI_EnumWindows|WinAPI_EnumWindowsPopup|WinAPI_EnumWindowsTop|WinAPI_ExpandEnvironmentStrings|WinAPI_ExtractIconEx|WinAPI_FatalAppExit|WinAPI_FillRect|WinAPI_FindExecutable|WinAPI_FindWindow|WinAPI_FlashWindow|WinAPI_FlashWindowEx|WinAPI_FloatToInt|WinAPI_FlushFileBuffers|WinAPI_FormatMessage|WinAPI_FrameRect|WinAPI_FreeLibrary|WinAPI_GetAncestor|WinAPI_GetAsyncKeyState|WinAPI_GetClassName|WinAPI_GetClientHeight|WinAPI_GetClientRect|WinAPI_GetClientWidth|WinAPI_GetCurrentProcess|WinAPI_GetCurrentProcessID|WinAPI_GetCurrentThread|WinAPI_GetCurrentThreadId|WinAPI_GetCursorInfo|WinAPI_GetDC|WinAPI_GetDesktopWindow|WinAPI_GetDeviceCaps|WinAPI_GetDIBits|WinAPI_GetDlgCtrlID|WinAPI_GetDlgItem|WinAPI_GetFileSizeEx|WinAPI_GetFocus|WinAPI_GetForegroundWindow|WinAPI_GetIconInfo|WinAPI_GetLastError|WinAPI_GetLastErrorMessage|WinAPI_GetModuleHandle|WinAPI_GetMousePos|WinAPI_GetMousePosX|WinAPI_GetMousePosY|WinAPI_GetObject|WinAPI_GetOpenFileName|WinAPI_GetOverlappedResult|WinAPI_GetParent|WinAPI_GetProcessAffinityMask|WinAPI_GetSaveFileName|WinAPI_GetStdHandle|WinAPI_GetStockObject|WinAPI_GetSysColor|WinAPI_GetSysColorBrush|WinAPI_GetSystemMetrics|WinAPI_GetTextExtentPoint32|WinAPI_GetWindow|WinAPI_GetWindowDC|WinAPI_GetWindowHeight|WinAPI_GetWindowLong|WinAPI_GetWindowRect|WinAPI_GetWindowText|WinAPI_GetWindowThreadProcessId|WinAPI_GetWindowWidth|WinAPI_GetXYFromPoint|WinAPI_GlobalMemStatus|WinAPI_GUIDFromString|WinAPI_GUIDFromStringEx|WinAPI_HiWord|WinAPI_InProcess|WinAPI_IntToFloat|WinAPI_InvalidateRect|WinAPI_IsClassName|WinAPI_IsWindow|WinAPI_IsWindowVisible|WinAPI_LoadBitmap|WinAPI_LoadImage|WinAPI_LoadLibrary|WinAPI_LoadLibraryEx|WinAPI_LoadShell32Icon|WinAPI_LoadString|WinAPI_LocalFree|WinAPI_LoWord|WinAPI_MakeDWord|WinAPI_MAKELANGID|WinAPI_MAKELCID|WinAPI_MakeLong|WinAPI_MessageBeep|WinAPI_Mouse_Event|WinAPI_MoveWindow|WinAPI_MsgBox|WinAPI_MulDiv|WinAPI_MultiByteToWideChar|WinAPI_MultiByteToWideCharEx|WinAPI_OpenProcess|WinAPI_PointFromRect|WinAPI_PostMessage|WinAPI_PrimaryLangId|WinAPI_PtInRect|WinAPI_ReadFile|WinAPI_ReadProcessMemory|WinAPI_RectIsEmpty|WinAPI_RedrawWindow|WinAPI_RegisterWindowMessage|WinAPI_ReleaseCapture|WinAPI_ReleaseDC|WinAPI_ScreenToClient|WinAPI_SelectObject|WinAPI_SetBkColor|WinAPI_SetCapture|WinAPI_SetCursor|WinAPI_SetDefaultPrinter|WinAPI_SetDIBits|WinAPI_SetEvent|WinAPI_SetFocus|WinAPI_SetFont|WinAPI_SetHandleInformation|WinAPI_SetLastError|WinAPI_SetParent|WinAPI_SetProcessAffinityMask|WinAPI_SetSysColors|WinAPI_SetTextColor|WinAPI_SetWindowLong|WinAPI_SetWindowPos|WinAPI_SetWindowsHookEx|WinAPI_SetWindowText|WinAPI_ShowCursor|WinAPI_ShowError|WinAPI_ShowMsg|WinAPI_ShowWindow|WinAPI_StringFromGUID|WinAPI_SubLangId|WinAPI_SystemParametersInfo|WinAPI_TwipsPerPixelX|WinAPI_TwipsPerPixelY|WinAPI_UnhookWindowsHookEx|WinAPI_UpdateLayeredWindow|WinAPI_UpdateWindow|WinAPI_ValidateClassName|WinAPI_WaitForInputIdle|WinAPI_WaitForMultipleObjects|WinAPI_WaitForSingleObject|WinAPI_WideCharToMultiByte|WinAPI_WindowFromPoint|WinAPI_WriteConsole|WinAPI_WriteFile|WinAPI_WriteProcessMemory|WinNet_AddConnection|WinNet_AddConnection2|WinNet_AddConnection3|WinNet_CancelConnection|WinNet_CancelConnection2|WinNet_CloseEnum|WinNet_ConnectionDialog|WinNet_ConnectionDialog1|WinNet_DisconnectDialog|WinNet_DisconnectDialog1|WinNet_EnumResource|WinNet_GetConnection|WinNet_GetConnectionPerformance|WinNet_GetLastError|WinNet_GetNetworkInformation|WinNet_GetProviderName|WinNet_GetResourceInformation|WinNet_GetResourceParent|WinNet_GetUniversalName|WinNet_GetUser|WinNet_OpenEnum|WinNet_RestoreConnection|WinNet_UseConnection|Word_VersionInfo|WordAttach|WordCreate|WordDocAdd|WordDocAddLink|WordDocAddPicture|WordDocClose|WordDocFindReplace|WordDocGetCollection|WordDocLinkGetCollection|WordDocOpen|WordDocPrint|WordDocPropertyGet|WordDocPropertySet|WordDocSave|WordDocSaveAs|WordErrorHandlerDeRegister|WordErrorHandlerRegister|WordErrorNotify|WordMacroRun|WordPropertyGet|WordPropertySet|WordQuit|' +\n        'ce|comments-end|comments-start|cs|include|include-once|NoTrayIcon|RequireAdmin|' +\n        'AutoIt3Wrapper_Au3Check_Parameters|AutoIt3Wrapper_Au3Check_Stop_OnWarning|AutoIt3Wrapper_Change2CUI|AutoIt3Wrapper_Compression|AutoIt3Wrapper_cvsWrapper_Parameters|AutoIt3Wrapper_Icon|AutoIt3Wrapper_Outfile|AutoIt3Wrapper_Outfile_Type|AutoIt3Wrapper_Plugin_Funcs|AutoIt3Wrapper_Res_Comment|AutoIt3Wrapper_Res_Description|AutoIt3Wrapper_Res_Field|AutoIt3Wrapper_Res_File_Add|AutoIt3Wrapper_Res_Fileversion|AutoIt3Wrapper_Res_FileVersion_AutoIncrement|AutoIt3Wrapper_Res_Icon_Add|AutoIt3Wrapper_Res_Language|AutoIt3Wrapper_Res_LegalCopyright|AutoIt3Wrapper_res_requestedExecutionLevel|AutoIt3Wrapper_Res_SaveSource|AutoIt3Wrapper_Run_After|AutoIt3Wrapper_Run_Au3check|AutoIt3Wrapper_Run_Before|AutoIt3Wrapper_Run_cvsWrapper|AutoIt3Wrapper_Run_Debug_Mode|AutoIt3Wrapper_Run_Obfuscator|AutoIt3Wrapper_Run_Tidy|AutoIt3Wrapper_Tidy_Stop_OnError|AutoIt3Wrapper_UseAnsi|AutoIt3Wrapper_UseUpx|AutoIt3Wrapper_UseX64|AutoIt3Wrapper_Version|EndRegion|forceref|Obfuscator_Ignore_Funcs|Obfuscator_Ignore_Variables|Obfuscator_Parameters|Region|Tidy_Parameters';\n    var atKeywords = 'AppDataCommonDir|AppDataDir|AutoItExe|AutoItPID|AutoItUnicode|AutoItVersion|AutoItX64|COM_EventObj|CommonFilesDir|Compiled|ComputerName|ComSpec|CR|CRLF|DesktopCommonDir|DesktopDepth|DesktopDir|DesktopHeight|DesktopRefresh|DesktopWidth|DocumentsCommonDir|error|exitCode|exitMethod|extended|FavoritesCommonDir|FavoritesDir|GUI_CtrlHandle|GUI_CtrlId|GUI_DragFile|GUI_DragId|GUI_DropId|GUI_WinHandle|HomeDrive|HomePath|HomeShare|HotKeyPressed|HOUR|InetGetActive|InetGetBytesRead|IPAddress1|IPAddress2|IPAddress3|IPAddress4|KBLayout|LF|LogonDNSDomain|LogonDomain|LogonServer|MDAY|MIN|MON|MyDocumentsDir|NumParams|OSBuild|OSLang|OSServicePack|OSTYPE|OSVersion|ProcessorArch|ProgramFilesDir|ProgramsCommonDir|ProgramsDir|ScriptDir|ScriptFullPath|ScriptLineNumber|ScriptName|SEC|StartMenuCommonDir|StartMenuDir|StartupCommonDir|StartupDir|SW_DISABLE|SW_ENABLE|SW_HIDE|SW_LOCK|SW_MAXIMIZE|SW_MINIMIZE|SW_RESTORE|SW_SHOW|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWMINNOACTIVE|SW_SHOWNA|SW_SHOWNOACTIVATE|SW_SHOWNORMAL|SW_UNLOCK|SystemDir|TAB|TempDir|TRAY_ID|TrayIconFlashing|TrayIconVisible|UserName|UserProfileDir|WDAY|WindowsDir|WorkingDir|YDAY|YEAR';\n    \n    this.$rules = { start: \n       [ { token: 'comment.line.ahk', regex: '(?:^| );.*$' },\n         { token: 'comment.block.ahk',\n           regex: '/\\\\*', push: \n            [ { token: 'comment.block.ahk', regex: '\\\\*/', next: 'pop' },\n              { defaultToken: 'comment.block.ahk' } ] },\n         { token: 'doc.comment.ahk',\n           regex: '#cs', push: \n            [ { token: 'doc.comment.ahk', regex: '#ce', next: 'pop' },\n              { defaultToken: 'doc.comment.ahk' } ] },\n         { token: 'keyword.command.ahk',\n           regex: '(?:\\\\b|^)(?:allowsamelinecomments|clipboardtimeout|commentflag|errorstdout|escapechar|hotkeyinterval|hotkeymodifiertimeout|hotstring|include|includeagain|installkeybdhook|installmousehook|keyhistory|ltrim|maxhotkeysperinterval|maxmem|maxthreads|maxthreadsbuffer|maxthreadsperhotkey|noenv|notrayicon|persistent|singleinstance|usehook|winactivateforce|autotrim|blockinput|click|clipwait|continue|control|controlclick|controlfocus|controlget|controlgetfocus|controlgetpos|controlgettext|controlmove|controlsend|controlsendraw|controlsettext|coordmode|critical|detecthiddentext|detecthiddenwindows|drive|driveget|drivespacefree|edit|endrepeat|envadd|envdiv|envget|envmult|envset|envsub|envupdate|exit|exitapp|fileappend|filecopy|filecopydir|filecreatedir|filecreateshortcut|filedelete|filegetattrib|filegetshortcut|filegetsize|filegettime|filegetversion|fileinstall|filemove|filemovedir|fileread|filereadline|filerecycle|filerecycleempty|fileremovedir|fileselectfile|fileselectfolder|filesetattrib|filesettime|formattime|getkeystate|gosub|goto|groupactivate|groupadd|groupclose|groupdeactivate|gui|guicontrol|guicontrolget|hideautoitwin|hotkey|ifequal|ifexist|ifgreater|ifgreaterorequal|ifinstring|ifless|iflessorequal|ifmsgbox|ifnotequal|ifnotexist|ifnotinstring|ifwinactive|ifwinexist|ifwinnotactive|ifwinnotexist|imagesearch|inidelete|iniread|iniwrite|input|inputbox|keyhistory|keywait|listhotkeys|listlines|listvars|menu|mouseclick|mouseclickdrag|mousegetpos|mousemove|msgbox|onexit|outputdebug|pause|pixelgetcolor|pixelsearch|postmessage|process|progress|random|regdelete|regread|regwrite|reload|repeat|run|runas|runwait|send|sendevent|sendinput|sendmode|sendplay|sendmessage|sendraw|setbatchlines|setcapslockstate|setcontroldelay|setdefaultmousespeed|setenv|setformat|setkeydelay|setmousedelay|setnumlockstate|setscrolllockstate|setstorecapslockmode|settimer|settitlematchmode|setwindelay|setworkingdir|shutdown|sleep|sort|soundbeep|soundget|soundgetwavevolume|soundplay|soundset|soundsetwavevolume|splashimage|splashtextoff|splashtexton|splitpath|statusbargettext|statusbarwait|stringcasesense|stringgetpos|stringleft|stringlen|stringlower|stringmid|stringreplace|stringright|stringsplit|stringtrimleft|stringtrimright|stringupper|suspend|sysget|thread|tooltip|transform|traytip|urldownloadtofile|while|winactivate|winactivatebottom|winclose|winget|wingetactivestats|wingetactivetitle|wingetclass|wingetpos|wingettext|wingettitle|winhide|winkill|winmaximize|winmenuselectitem|winminimize|winminimizeall|winminimizeallundo|winmove|winrestore|winset|winsettitle|winshow|winwait|winwaitactive|winwaitclose|winwaitnotactive)\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.control.ahk',\n           regex: '(?:\\\\b|^)(?:if|else|return|loop|break|for|while|global|local|byref)\\\\b',\n           caseInsensitive: true },\n         { token: 'support.function.ahk',\n           regex: '(?:\\\\b|^)(?:abs|acos|asc|asin|atan|ceil|chr|cos|dllcall|exp|fileexist|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist)\\\\b',\n           caseInsensitive: true },\n         { token: 'variable.predefined.ahk',\n           regex: '(?:\\\\b|^)(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\\\\b',\n           caseInsensitive: true },\n         { token: 'support.constant.ahk',\n           regex: '(?:\\\\b|^)(?:shift|lshift|rshift|alt|lalt|ralt|control|lcontrol|rcontrol|ctrl|lctrl|rctrl|lwin|rwin|appskey|altdown|altup|shiftdown|shiftup|ctrldown|ctrlup|lwindown|lwinup|rwindown|rwinup|lbutton|rbutton|mbutton|wheelup|wheelleft|wheelright|wheeldown|xbutton1|xbutton2|joy1|joy2|joy3|joy4|joy5|joy6|joy7|joy8|joy9|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy30|joy31|joy32|joyx|joyy|joyz|joyr|joyu|joyv|joypov|joyname|joybuttons|joyaxes|joyinfo|space|tab|enter|escape|esc|backspace|bs|delete|del|insert|ins|pgup|pgdn|home|end|up|down|left|right|printscreen|ctrlbreak|pause|scrolllock|capslock|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadmult|numpadadd|numpadsub|numpaddiv|numpaddot|numpaddel|numpadins|numpadclear|numpadup|numpaddown|numpadleft|numpadright|numpadhome|numpadend|numpadpgup|numpadpgdn|numpadenter|f1|f2|f3|f4|f5|f6|f7|f8|f9|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f20|f21|f22|f23|f24|browser_back|browser_forward|browser_refresh|browser_stop|browser_search|browser_favorites|browser_home|volume_mute|volume_down|volume_up|media_next|media_prev|media_stop|media_play_pause|launch_mail|launch_media|launch_app1|launch_app2)\\\\b',\n           caseInsensitive: true },\n         { token: 'variable.parameter',\n           regex: '(?:\\\\b|^)(?:pixel|mouse|screen|relative|rgb|ltrim|rtrim|join|low|belownormal|normal|abovenormal|high|realtime|ahk_id|ahk_pid|ahk_class|ahk_group|between|contains|in|is|integer|float|integerfast|floatfast|number|digit|xdigit|alpha|upper|lower|alnum|time|date|not|or|and|alwaysontop|topmost|top|bottom|transparent|transcolor|redraw|region|id|idlast|processname|minmax|controllist|count|list|capacity|statuscd|eject|lock|unlock|label|filesystem|label|setlabel|serial|type|status|static|seconds|minutes|hours|days|read|parse|logoff|close|error|single|tray|add|rename|check|uncheck|togglecheck|enable|disable|toggleenable|default|nodefault|standard|nostandard|color|delete|deleteall|icon|noicon|tip|click|show|mainwindow|nomainwindow|useerrorlevel|text|picture|pic|groupbox|button|checkbox|radio|dropdownlist|ddl|combobox|listbox|listview|datetime|monthcal|updown|slider|tab|tab2|statusbar|treeview|iconsmall|tile|report|sortdesc|nosort|nosorthdr|grid|hdr|autosize|range|xm|ym|ys|xs|xp|yp|font|resize|owner|submit|nohide|minimize|maximize|restore|noactivate|na|cancel|destroy|center|margin|maxsize|minsize|owndialogs|guiescape|guiclose|guisize|guicontextmenu|guidropfiles|tabstop|section|altsubmit|wrap|hscroll|vscroll|border|top|bottom|buttons|expand|first|imagelist|lines|wantctrla|wantf2|vis|visfirst|number|uppercase|lowercase|limit|password|multi|wantreturn|group|background|bold|italic|strike|underline|norm|backgroundtrans|theme|caption|delimiter|minimizebox|maximizebox|sysmenu|toolwindow|flash|style|exstyle|check3|checked|checkedgray|readonly|password|hidden|left|right|center|notab|section|move|focus|hide|choose|choosestring|text|pos|enabled|disabled|visible|lastfound|lastfoundexist|alttab|shiftalttab|alttabmenu|alttabandmenu|alttabmenudismiss|notimers|interrupt|priority|waitclose|blind|raw|unicode|deref|pow|bitnot|bitand|bitor|bitxor|bitshiftleft|bitshiftright|yes|no|ok|cancel|abort|retry|ignore|tryagain|on|off|all|hkey_local_machine|hkey_users|hkey_current_user|hkey_classes_root|hkey_current_config|hklm|hku|hkcu|hkcr|hkcc|reg_sz|reg_expand_sz|reg_multi_sz|reg_dword|reg_qword|reg_binary|reg_link|reg_resource_list|reg_full_resource_descriptor|reg_resource_requirements_list|reg_dword_big_endian)\\\\b',\n           caseInsensitive: true },\n         { keywordMap: {\"constant.language\": autoItKeywords}, regex: '\\\\w+\\\\b'},\n         { keywordMap: {\"variable.function\": atKeywords}, regex: '@\\\\w+\\\\b'},\n         { token : \"constant.numeric\", regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"},\n         { token: 'keyword.operator.ahk',\n           regex: '=|==|<>|:=|<|>|\\\\*|\\\\/|\\\\+|:|\\\\?|\\\\-' },\n         { token: 'punctuation.ahk',\n           regex: /#|`|::|,|%/ },\n         { token: 'paren',\n           regex: /[{}()]/ },\n         { token: \n            [ 'punctuation.quote.double',\n              'string.quoted.ahk',\n              'punctuation.quote.double' ],\n           regex: '(\")((?:[^\"]|\"\")*)(\")' },\n         { token: [ 'label.ahk', 'punctuation.definition.label.ahk' ],\n           regex: '^([^: ]+)(:)(?!:)' } ] };\n    \n    this.normalizeRules();\n};\n\nAutoHotKeyHighlightRules.metaData = { name: 'AutoHotKey',\n      scopeName: 'source.ahk',\n      fileTypes: [ 'ahk' ],\n      foldingStartMarker: '^\\\\s*/\\\\*|^(?![^{]*?;|[^{]*?/\\\\*(?!.*?\\\\*/.*?\\\\{)).*?\\\\{\\\\s*($|;|/\\\\*(?!.*?\\\\*/.*\\\\S))',\n      foldingStopMarker: '^\\\\s*\\\\*/|^\\\\s*\\\\}' };\n\n\noop.inherits(AutoHotKeyHighlightRules, TextHighlightRules);\n\nexports.AutoHotKeyHighlightRules = AutoHotKeyHighlightRules;\n"
  },
  {
    "path": "src/mode/basic.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar BasicHighlightRules = require(\"./basic_highlight_rules\").BasicHighlightRules;\nvar FoldMode = require(\"./folding/basic\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = BasicHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n    this.indentKeywords = this.foldingRules.indentKeywords;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = [\"REM\"];\n\n    this.getMatching = function(session, row, column, tokenRange) {\n        if (row == undefined) {\n            var pos = session.selection.lead;\n            column = pos.column;\n            row = pos.row;\n        }\n        if (tokenRange == undefined)\n            tokenRange = true;\n\n        var startToken = session.getTokenAt(row, column);\n        if (startToken) {\n            var val = startToken.value.toLowerCase();\n            if (val in this.indentKeywords)\n                return this.foldingRules.basicBlock(session, row, column, tokenRange);\n        }\n    };\n\n    this.$id = \"ace/mode/basic\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/basic_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar BasicHighlightRules = function () {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control\": \"FOR|TO|NEXT|GOSUB|RETURN|IF|THEN|ELSE|GOTO|ON|WHILE|WEND|TRON|TROFF\",\n        \"entity.name\": \"Auto|Call|Chain|Clear|Close|Common|Cont|Data|MERGE|ALL|Delete|DIM|EDIT|END|ERASE|ERROR|FIELD|\"\n            + \"GET|INPUT|KILL|LET|LIST|LLIST|LOAD|LSET|RSET|MERGE|NEW|NULL|OPEN|OUT|POKE|PRINT|PUT|RANDOMIZE|READ|\"\n            + \"RENUM|RESTORE|RESUME|RUN|SAVE|STOP|SWAP|WAIT|WIDTH\",\n        \"keyword.operator\": \"Mod|And|Not|Or|Xor|Eqv|Imp\",\n        \"support.function\": \"ABS|ASC|ATN|CDBL|CINT|COS|CSNG|CVI|CVS|CVD|EOF|EXP|FIX|FRE|INP|INSTR|INT|LEN|LOC|LOG|LPOS|\"\n            + \"PEEK|POS|RND|SGN|SIN|SPC|SQR|TAB|TAN|USR|VAL|VARPTR\"\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"string\",\n                regex: /\"(?:\\\\.|[^\"\\\\])*\"/\n            },\n            {\n                token: \"support.function\",\n                regex: /(HEX|CHR|INPUT|LEFT|MID|MKI|MKS|MKD|OCT|RIGHT|SPACE|STR|STRING)\\$/\n            }, {\n                token: \"entity.name\",\n                regex: /(?:DEF\\s(?:SEG|USR|FN[a-zA-Z]+)|LINE\\sINPUT|L?PRINT#?(?:\\sUSING)?|MID\\$|ON\\sERROR\\sGOTO|OPTION\\sBASE|WRITE#?|DATE\\$|INKEY\\$|TIME\\$)/\n            }, {\n                token: \"variable\",\n                regex: /[a-zA-Z][a-zA-Z0-9_]{0,38}[$%!#]?(?=\\s*=)/\n            }, {\n                token: \"keyword.operator\",\n                regex: /\\\\|=|\\^|\\*|\\/|\\+|\\-|<|>|-/\n            }, {\n                token: \"paren.lparen\",\n                regex: /[([]/\n            }, {\n                token: \"paren.rparen\",\n                regex: /[\\)\\]]/\n            }, {\n                token: \"constant.numeric\",\n                regex: /[+-]?\\d+(\\.\\d+)?([ED][+-]?\\d+)?(?:[!#])?/\n            }, {\n                token: \"constant.numeric\", //hexal, octal\n                regex: /&[HO]?[0-9A-F]+/\n            }, {\n                token: \"comment\",\n                regex: /REM\\s+.*$/\n            }, {\n                regex: \"\\\\w+\",\n                token: keywordMapper\n            },{\n                token: \"punctiation\",\n                regex: /[,;]/\n\n            }\n        ]\n\n    };\n    this.normalizeRules();\n};\n\noop.inherits(BasicHighlightRules, TextHighlightRules);\n\nexports.BasicHighlightRules = BasicHighlightRules;\n"
  },
  {
    "path": "src/mode/batchfile.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar BatchFileHighlightRules = require(\"./batchfile_highlight_rules\").BatchFileHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = BatchFileHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"::\";\n    this.blockComment = \"\";\n    this.$id = \"ace/mode/batchfile\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/batchfile_highlight_rules.js",
    "content": "/* This file was autogenerated from C:\\Users\\LED\\AppData\\Roaming\\Sublime Text 2\\Packages\\Batch File\\Batch File.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar BatchFileHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'keyword.command.dosbatch',\n           regex: '\\\\b(?:append|assoc|at|attrib|break|cacls|cd|chcp|chdir|chkdsk|chkntfs|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskcomp|diskcopy|doskey|echo|endlocal|erase|fc|find|findstr|format|ftype|graftabl|help|keyb|label|md|mkdir|mode|more|move|path|pause|popd|print|prompt|pushd|rd|recover|ren|rename|replace|restore|rmdir|set|setlocal|shift|sort|start|subst|time|title|tree|type|ver|verify|vol|xcopy)\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.control.statement.dosbatch',\n           regex: '\\\\b(?:goto|call|exit)\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.control.conditional.if.dosbatch',\n           regex: '\\\\bif\\\\s+not\\\\s+(?:exist|defined|errorlevel|cmdextversion)\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.control.conditional.dosbatch',\n           regex: '\\\\b(?:if|else)\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.control.repeat.dosbatch',\n           regex: '\\\\bfor\\\\b',\n           caseInsensitive: true },\n         { token: 'keyword.operator.dosbatch',\n           regex: '\\\\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\\\\b' },\n         { token: ['doc.comment', 'comment'],\n           regex: '(?:^|\\\\b)(rem)($|\\\\s.*$)',\n           caseInsensitive: true },\n         { token: 'comment.line.colons.dosbatch',\n           regex: '::.*$' },\n         { include: 'variable' },\n         { token: 'punctuation.definition.string.begin.shell',\n           regex: '\"',\n           push: [ \n              { token: 'punctuation.definition.string.end.shell', regex: '\"', next: 'pop' },\n              { include: 'variable' },\n              { defaultToken: 'string.quoted.double.dosbatch' } ] },\n         { token: 'keyword.operator.pipe.dosbatch', regex: '[|]' },\n         { token: 'keyword.operator.redirect.shell',\n           regex: '&>|\\\\d*>&\\\\d*|\\\\d*(?:>>|>|<)|\\\\d*<&|\\\\d*<>' } ],\n        variable: [\n         { token: 'constant.numeric', regex: '%%\\\\w+|%[*\\\\d]|%\\\\w+%'},\n         { token: 'constant.numeric', regex: '%~\\\\d+'},\n         { token: ['markup.list', 'constant.other', 'markup.list'],\n            regex: '(%)(\\\\w+)(%?)' }]};\n    \n    this.normalizeRules();\n};\n\nBatchFileHighlightRules.metaData = { name: 'Batch File',\n      scopeName: 'source.dosbatch',\n      fileTypes: [ 'bat' ] };\n\n\noop.inherits(BatchFileHighlightRules, TextHighlightRules);\n\nexports.BatchFileHighlightRules = BatchFileHighlightRules;\n"
  },
  {
    "path": "src/mode/behaviour/behaviour_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../../test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"../../multi_select\");\nvar assert = require(\"../../test/assertions\");\nvar Range = require(\"../../range\").Range;\nvar Editor = require(\"../../editor\").Editor;\nvar UndoManager = require(\"../../undomanager\").UndoManager;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar MockRenderer = require(\"../../test/mockrenderer\").MockRenderer;\nvar JavaScriptMode = require(\"../javascript\").Mode;\nvar RustMode = require(\"../rust\").Mode;\nvar XMLMode = require(\"../xml\").Mode;\nvar HTMLMode = require(\"../html\").Mode;\nvar CSSMode = require(\"../css\").Mode;\nvar MarkdownMode = require(\"../markdown\").Mode;\nvar PythonMode = require(\"../python\").Mode;\nvar editor;\nvar exec = function(name, times, args) {\n    do {\n        editor.commands.exec(name, editor, args);\n    } while(times --> 1);\n};\nvar testRanges = function(str) {\n    assert.equal(editor.selection.getAllRanges() + \"\", str + \"\");\n};\n\nmodule.exports = {\n    \"test: cstyle\": function() {\n        function testValue(line) {\n            assert.equal(editor.getValue(), Array(4).join(line + \"\\n\"));\n        }\n        function testSelection(line, col, inc) {\n            editor.selection.rangeList.ranges.forEach(function(r) {\n                assert.range(r, line, col, line, col);\n                line += (inc || 1);\n            });\n        }\n        var doc = new EditSession([\n            \"\",\n            \"\",\n            \"\",\n            \"\"\n        ], new JavaScriptMode());\n        editor = new Editor(new MockRenderer(), doc);\n        editor.setOption(\"behavioursEnabled\", true);\n\n        editor.navigateFileStart();\n        exec(\"addCursorBelow\", 2);\n\n        exec(\"insertstring\", 1, \"if \");\n        \n        // pairing ( \n        exec(\"insertstring\", 1, \"(\");\n        testValue(\"if ()\");\n        testSelection(0, 4);\n        exec(\"insertstring\", 1, \")\");\n        testValue(\"if ()\");\n        testSelection(0, 5);\n        \n        // pairing [ \n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \"[\");\n        testValue(\"if ([])\");\n        testSelection(0, 5);\n        \n        exec(\"insertstring\", 1, \"]\");\n        testValue(\"if ([])\");\n        testSelection(0, 6);\n        \n        // test deletion\n        exec(\"gotoleft\", 1);\n        exec(\"backspace\", 1);\n        testValue(\"if ()\");\n        testSelection(0, 4);\n\n        exec(\"gotolineend\", 1);\n        exec(\"insertstring\", 1, \"{\");\n        testValue(\"if (){}\");\n        testSelection(0, 6);\n        \n        exec(\"insertstring\", 1, \"}\");\n        testValue(\"if (){}\");\n        testSelection(0, 7);\n        \n        exec(\"gotolinestart\", 1);\n        exec(\"insertstring\", 1, \"(\");\n        testValue(\"(if (){}\");\n        exec(\"backspace\", 1);\n        \n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"{\");\n        assert.equal(editor.getValue(), \"{\");\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"{\\n    \\n}\");\n        \n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"(\");\n        exec(\"insertstring\", 1, '\"');\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '(\"\")');\n        exec(\"backspace\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '(\"\")');\n        \n        editor.setValue(\"('foo')\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"selectMoreBefore\", 1);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"('foo')\");\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '(\"foo\")');\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '(\"foo\")');\n        \n        editor.setValue(\"\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '\"\"');\n        exec(\"insertstring\", 1, '\\\\');\n        exec(\"insertstring\", 1, 'n');\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), '\"\\\\n\"');\n        \n        editor.setValue(\"\");        \n        exec(\"insertstring\", 1, '`');\n        assert.equal(editor.getValue(), '``');\n        exec(\"insertstring\", 1, 'n');\n        assert.equal(editor.getValue(), '`n`');\n        exec(\"backspace\", 2);\n        assert.equal(editor.getValue(), '');\n\n        // multiline string interpolation test case\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"var x=\");\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"var x=``\");\n        exec(\"insertstring\", 1, \"$\");\n        exec(\"insertstring\", 1, \"{\");\n        assert.equal(editor.getValue(), \"var x=`${}`\");\n        // Testing for the auto-pairing of curly braces inside a JSX element attribute\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"var x=<a href=\");\n        exec(\"insertstring\", 1, \"{\");\n        assert.equal(editor.getValue(), \"var x=<a href={}\");\n        // Testing of excluded token types auto-pairing\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"var x=<div>\");\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \"{\");\n        assert.equal(editor.getValue(), \"var x=<div{>\");\n        // Testing for the auto-pairing of curly braces inside a JSX element \n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, \"var x=<div>\\\\n    \");\n        exec(\"insertstring\", 1, \"{\");\n        assert.equal(editor.getValue(), \"var x=<div>\\\\n    {}\");\n    },\n    \"test: xml\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.session.setUndoManager(new UndoManager());\n        editor.setValue([\"<OuterTag>\",\n            \"    <SelfClosingTag />\"\n        ].join(\"\\n\"));\n        editor.session.setMode(new XMLMode);\n        exec(\"golinedown\", 1);\n        exec(\"gotolineend\", 1);\n        exec(\"insertstring\", 1, '\\n');\n        assert.equal(editor.session.getLine(2), \"    \");\n        exec(\"gotolineup\", 1);\n        exec(\"gotolineend\", 1);\n        exec(\"insertstring\", 1, '\\n');\n        assert.equal(editor.session.getLine(2), \"    \");\n        editor.session.setValue([\"<OuterTag\",\n            \"    <xyzrt\"\n        ].join(\"\\n\"));        \n        exec(\"golinedown\", 1);\n        exec(\"gotolineend\", 1);\n        exec(\"selectleft\", 3);\n        exec(\"insertstring\", 1, '>');\n        assert.equal(editor.session.getLine(1), \"    <xy></xy>\");\n        \n        editor.setValue([\"<a x='11'\",\n            \"<b a='\",\n            \"   \",\n            \"'     >\"\n        ].join(\"\\n\"));\n        editor.selection.moveTo(0, 100);\n        exec(\"insertstring\", 1, '>');\n        editor.selection.moveTo(1, 100);\n        exec(\"insertstring\", 1, '>');\n        editor.selection.moveTo(2, 1);\n        exec(\"insertstring\", 1, '>');\n        editor.selection.moveTo(3, 1);\n        exec(\"insertstring\", 1, '>');\n        assert.equal(editor.getValue(), [\n            \"<a x='11'></a>\",\n            \"<b a='>\",\n            \" >  \",\n            \"'>     >\"\n        ].join(\"\\n\"));\n        \n        editor.setValue(\"\");\n        \"<div x='1'>\".split(\"\").forEach(function(ch) {\n            exec(\"insertstring\", 1, ch);\n        });\n        assert.equal(editor.getValue(), \"<div x='1'></div>\");\n        exec(\"insertstring\", 1, \">\");\n        assert.equal(editor.getValue(), \"<div x='1'>></div>\");\n        \n        editor.setValue(\"<div '\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), \"<div \\\"\");\n        \n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"<div '\");\n        \n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \"a\");\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"<div 'a'\");\n    },\n    \"test: html\": function() {\n        editor.session.setMode(new HTMLMode);\n        editor.setWrapBehavioursEnabled(false);\n        editor.setValue(\"<div a\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"<div '\");\n        \n        editor.setWrapBehavioursEnabled(true);\n        editor.setValue(\"<div a\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"<div 'a'\");\n        \n        editor.setValue(\"<div a=></div>\", 1);\n        exec(\"gotoleft\", 7);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), \"<div a=\\\"\\\"></div>\");\n        exec(\"insertstring\", 1, '\"');\n        exec(\"gotoright\", 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"<div a=\\\"\\\">\\n    \\n</div>\");\n        \n        exec(\"undo\", 1);\n        assert.equal(editor.getValue(), \"<div a=\\\"\\\"></div>\");\n        exec(\"gotoleft\", 1);\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"<div a=\\\"></div>\");\n        exec(\"undo\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"<div a=></div>\");\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"<div a></div>\");\n        \n        editor.setValue(\"    <div><div>\", 1);\n        editor.selection.moveTo(0, 9);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"    <div>\\n        <div>\");\n        \n        editor.setValue(\"  <div></div>\", 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"  <div></div>\\n  \");\n        \n        editor.setValue(\"    <br><br>\", 1);\n        editor.selection.moveTo(0, 8);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"    <br>\\n    <br>\");\n        \n        editor.setValue(\"<div a='x\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \">\");\n        assert.equal(editor.getValue(), \"<div a='>x\");\n        \n        editor.setValue(\"\");\n        \"<!DOCTYPE html></div><link><a>\".split(\"\").forEach(function(ch) {\n            exec(\"insertstring\", 1, ch);\n        });\n        assert.equal(editor.getValue(), \"<!DOCTYPE html></div><link><a></a>\");\n    },\n    \"test: quotes\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.session.setMode(new RustMode);\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, '\"');\n        exec(\"insertstring\", 1, 'a');\n        assert.equal(editor.getValue(), '\"a\"');\n        exec(\"backspace\", 2);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"'\");\n        \n        editor.session.setMode(new JavaScriptMode);\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, '\"');\n        exec(\"insertstring\", 1, 'a');\n        assert.equal(editor.getValue(), '\"a\"');\n        exec(\"backspace\", 2);\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"''\");\n        exec(\"backspace\", 1);\n        exec(\"insertstring\", 1, '`');\n        exec(\"insertstring\", 1, 'b');\n        assert.equal(editor.getValue(), \"`b`\");\n\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, 'a');\n        exec(\"insertstring\", 1, \"'\");\n        assert.equal(editor.getValue(), \"a'\");\n\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, 'b');\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"b``\");\n    },\n    \"test: css\": function() {\n        editor.session.setMode(new CSSMode());\n        editor.setWrapBehavioursEnabled(true);\n        editor.setValue(\"a {padding\", 1);\n        exec(\"insertstring\", 1, \":\");\n        assert.equal(editor.getValue(), \"a {padding:;\");\n\n        editor.setValue(\"a {padding:\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \":\");\n        assert.equal(editor.getValue(), \"a {padding:\");\n\n        editor.setValue(\"a {padding   \", 1);\n        exec(\"insertstring\", 1, \":\");\n        assert.equal(editor.getValue(), \"a {padding   :;\");\n\n        editor.setValue(\"a\", 1);\n        exec(\"insertstring\", 1, \":\");\n        assert.equal(editor.getValue(), \"a:\");\n\n        editor.setValue(\"a {padding\", 1);\n        exec(\"insertstring\", 1, \":\");\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"a {padding\");\n        exec(\"backspace\", 2);\n        exec(\"insertstring\", 1, \":;\");\n        exec(\"gotoleft\", 1);\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"a {paddi;\");\n\n        editor.setValue(\"a {padding    :\", 1);\n        exec(\"backspace\", 1);\n        assert.equal(editor.getValue(), \"a {padding    \");\n\n\n        editor.setValue(\"a {padding:\", 1);\n        exec(\"insertstring\", 1, \";\");\n        assert.equal(editor.getValue(), \"a {padding:;\");\n\n        editor.setValue(\";\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \"a {padding\");\n        exec(\"insertstring\", 1, \":\");\n        assert.equal(editor.getValue(), \"a {padding:;\");\n\n        editor.setValue(\";\", 1);\n        exec(\"selectleft\", 1);\n        exec(\"insertstring\", 1, \";\");\n        assert.equal(editor.getValue(), \";\");\n\n        editor.setValue(\"a {padding:;\", 1);\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \";\");\n        assert.equal(editor.getValue(), \"a {padding:;\");\n\n        editor.setValue(\"a {padding:10px\", 1);\n        exec(\"insertstring\", 1, \"!\");\n        assert.equal(editor.getValue(), \"a {padding:10px!important\");\n        exec(\"removewordleft\", 2);\n        exec(\"insertstring\", 1, \"}\");\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \"!\");\n        assert.equal(editor.getValue(), \"a {padding:10px!important}\");\n        exec(\"removewordleft\", 2);\n        exec(\"insertstring\", 1, \";\");\n        exec(\"gotoleft\", 1);\n        exec(\"insertstring\", 1, \"!\");\n        assert.equal(editor.getValue(), \"a {padding:10px!important;}\");\n        editor.selection.moveTo(0, 3);\n        exec(\"insertstring\", 1, \"!\");\n        assert.equal(editor.getValue(), \"a {!padding:10px!important;}\");\n    },\n    \"test: markdown\": function() {\n        editor.session.setMode(new MarkdownMode());\n        editor.setValue(\"```html\", 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"```html\\n\");\n        editor.setValue(\"\", 1);\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"``\");\n        exec(\"insertstring\", 1, \"x\");\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"`x`\");\n        editor.setValue(\"\", 1);\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"x\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"```x```\");\n        editor.setValue(\"\", 1);\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"x\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"``x``\");\n        editor.setValue(\"\", 1);\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"-\");\n        exec(\"insertstring\", 1, \"`\");\n        exec(\"insertstring\", 1, \"`\");\n        assert.equal(editor.getValue(), \"``-``\");\n    },\n    \"test: python\": function() {\n        editor.session.setMode(new PythonMode());\n        editor.setValue(\"f\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), 'f\"\"');\n\n        // there is no such prefix for python\n        editor.setValue(\"p\", 1);\n        exec(\"insertstring\", 1, '\"');\n        assert.equal(editor.getValue(), 'p\"');\n    },\n    \"test: doc comment auto-closing\": function() {\n        editor.session.setMode(new JavaScriptMode());\n        editor.setWrapBehavioursEnabled(true);\n\n        // Test case 1: Starting a new doc comment\n        editor.setValue(\"/**\", 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/**\\n * \\n */\");\n\n        // Test case 2: Continuing an existing doc comment with asterisk on a new line\n        editor.setValue(\"/**\\n * Test\", 1);\n        editor.gotoLine(1, 5);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/**\\n * \\n * Test\");\n        \n        // Test case 3: Starting a new doc comment with 4-space indentation\n        editor.setValue(\"    /**\", 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"    /**\\n     * \\n     */\");\n\n        // Test case 4: Cursor between closing */ and opening /** on the same line\n        editor.setValue(\"/**\\n * Some comment\\n *//**\", 1);\n        editor.gotoLine(3, 3);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/**\\n * Some comment\\n */\\n /**\");\n\n        // Test case 5: Cursor at start of the line with doc comment\n        editor.setValue(\"/**\\n * Some comment\\n */\", 1);\n        editor.gotoLine(1, 0);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"\\n/**\\n * Some comment\\n */\");\n\n        // Test case 6: Cursor at the end of the first comment\n        editor.setValue(\"/** comment */identifier/**\", 1);\n        editor.gotoLine(1, 14);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/** comment */\\nidentifier/**\");\n\n        // Test case 7: Cursor at the start of the second comment\n        editor.setValue(\"/** comment */identifier/**\", 1);\n        editor.gotoLine(1, 24);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/** comment */identifier\\n/**\");\n\n        // Test case 8: Cursor between '/' and '*' in a comment\n        editor.setValue(\"/** comment */\", 1);\n        editor.gotoLine(1, 1);\n        exec(\"insertstring\", 1, \"\\n\");\n        assert.equal(editor.getValue(), \"/\\n** comment */\");\n\n    },\n    \"test: fragment auto-closing\": function () {\n        editor.setWrapBehavioursEnabled(true);\n        editor.session.setMode(new JavaScriptMode());\n        editor.setValue(\"\");\n        exec(\"insertstring\", 1, '<');\n        exec(\"insertstring\", 1, '>');\n        assert.equal(editor.getValue(), '<></>');\n    }\n};\n\n\nrequire(\"../../test/run\")(module);"
  },
  {
    "path": "src/mode/behaviour/css.js",
    "content": "\"use strict\";\nvar oop = require(\"../../lib/oop\");\nvar Behaviour = require(\"../behaviour\").Behaviour;\nvar CstyleBehaviour = require(\"./cstyle\").CstyleBehaviour;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n/**@type {(new() => Partial<import(\"../../../ace-internal\").Ace.Behaviour>)}*/\nvar CssBehaviour = function () {\n\n    this.inherit(CstyleBehaviour);\n\n    this.add(\"colon\", \"insertion\", function (state, action, editor, session, text) {\n        if (text === ':' && editor.selection.isEmpty()) {\n            var cursor = editor.getCursorPosition();\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n            if (token && token.value.match(/\\s+/)) {\n                token = iterator.stepBackward();\n            }\n            if (token && token.type === 'support.type') {\n                var line = session.doc.getLine(cursor.row);\n                var rightChar = line.substring(cursor.column, cursor.column + 1);\n                if (rightChar === ':') {\n                    return {\n                       text: '',\n                       selection: [1, 1]\n                    };\n                }\n                if (/^(\\s+[^;]|\\s*$)/.test(line.substring(cursor.column))) {\n                    return {\n                       text: ':;',\n                       selection: [1, 1]\n                    };\n                }\n            }\n        }\n    });\n\n    this.add(\"colon\", \"deletion\", function (state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected === ':') {\n            var cursor = editor.getCursorPosition();\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n            if (token && token.value.match(/\\s+/)) {\n                token = iterator.stepBackward();\n            }\n            if (token && token.type === 'support.type') {\n                var line = session.doc.getLine(range.start.row);\n                var rightChar = line.substring(range.end.column, range.end.column + 1);\n                if (rightChar === ';') {\n                    range.end.column ++;\n                    return range;\n                }\n            }\n        }\n    });\n\n    this.add(\"semicolon\", \"insertion\", function (state, action, editor, session, text) {\n        if (text === ';' && editor.selection.isEmpty()) {\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar === ';') {\n                return {\n                   text: '',\n                   selection: [1, 1]\n                };\n            }\n        }\n    });\n\n    this.add(\"!important\", \"insertion\", function (state, action, editor, session, text) {\n        if (text === '!' && editor.selection.isEmpty()) {\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n\n            if (/^\\s*(;|}|$)/.test(line.substring(cursor.column))) {\n                return {\n                    text: '!important',\n                    selection: [10, 10]\n                };\n            }\n        }\n    });\n\n};\noop.inherits(CssBehaviour, CstyleBehaviour);\n\nexports.CssBehaviour = CssBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/cstyle.js",
    "content": "\"use strict\";\nvar oop = require(\"../../lib/oop\");\nvar Behaviour = require(\"../behaviour\").Behaviour;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\nvar lang = require(\"../../lib/lang\");\n\nvar SAFE_INSERT_IN_TOKENS =\n    [\"text\", \"paren.rparen\", \"rparen\", \"paren\", \"punctuation.operator\"];\nvar SAFE_INSERT_BEFORE_TOKENS =\n    [\"text\", \"paren.rparen\", \"rparen\", \"paren\", \"punctuation.operator\", \"comment\"];\n\nvar context;\nvar contextCache = {};\nvar defaultQuotes = {'\"' : '\"', \"'\" : \"'\"};\n\nvar initContext = function(editor) {\n    var id = -1;\n    if (editor.multiSelect) {\n        id = editor.selection.index;\n        if (contextCache.rangeCount != editor.multiSelect.rangeCount)\n            contextCache = {rangeCount: editor.multiSelect.rangeCount};\n    }\n    if (contextCache[id])\n        return context = contextCache[id];\n    context = contextCache[id] = {\n        autoInsertedBrackets: 0,\n        autoInsertedRow: -1,\n        autoInsertedLineEnd: \"\",\n        maybeInsertedBrackets: 0,\n        maybeInsertedRow: -1,\n        maybeInsertedLineStart: \"\",\n        maybeInsertedLineEnd: \"\"\n    };\n};\n\nvar getWrapped = function(selection, selected, opening, closing) {\n    var rowDiff = selection.end.row - selection.start.row;\n    return {\n        text: opening + selected + closing,\n        selection: [\n                0,\n                selection.start.column + 1,\n                rowDiff,\n                selection.end.column + (rowDiff ? 0 : 1)\n            ]\n    };\n};\n/**\n * Creates a new Cstyle behaviour object with the specified options.\n * @param {Object} [options] - The options for the Cstyle behaviour object.\n * @param {boolean} [options.braces] - Whether to force braces auto-pairing.\n * @param {boolean} [options.closeDocComment] - enables automatic insertion of closing tags for documentation comments.\n */\nvar CstyleBehaviour;\nCstyleBehaviour = function(options) {\n    options = options || {};\n    this.add(\"braces\", \"insertion\", function(state, action, editor, session, text) {\n        var cursor = editor.getCursorPosition();\n        var line = session.doc.getLine(cursor.row);\n        if (text == '{') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            var token = session.getTokenAt(cursor.row, cursor.column);\n            if (selected !== \"\" && selected !== \"{\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '{', '}');\n            }\n            else if (token && /(?:string)\\.quasi|\\.xml/.test(token.type)) {\n                let excludeTokens = [\n                    /tag\\-(?:open|name)/, /attribute\\-name/\n                ];\n                if (excludeTokens.some((el) => el.test(token.type)) || /(string)\\.quasi/.test(token.type)\n                    && token.value[cursor.column - token.start - 1] !== '$') return;\n\n                CstyleBehaviour.recordAutoInsert(editor, session, \"}\");\n                return {\n                    text: '{}',\n                    selection: [1, 1]\n                };\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                if (/[\\]\\}\\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options.braces) {\n                    CstyleBehaviour.recordAutoInsert(editor, session, \"}\");\n                    return {\n                        text: '{}',\n                        selection: [1, 1]\n                    };\n                } else {\n                    CstyleBehaviour.recordMaybeInsert(editor, session, \"{\");\n                    return {\n                        text: '{',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        } else if (text == '}') {\n            initContext(editor);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == '}') {\n                var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        } else if (text == \"\\n\" || text == \"\\r\\n\") {\n            initContext(editor);\n            var closing = \"\";\n            if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {\n                closing = lang.stringRepeat(\"}\", context.maybeInsertedBrackets);\n                CstyleBehaviour.clearMaybeInsertedClosing();\n            }\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar === '}') {\n                var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');\n                if (!openBracePos)\n                     return null;\n                var next_indent = this.$getIndent(session.getLine(openBracePos.row));\n            } else if (closing) {\n                var next_indent = this.$getIndent(line);\n            } else {\n                CstyleBehaviour.clearMaybeInsertedClosing();\n                return;\n            }\n            var indent = next_indent + session.getTabString();\n\n            return {\n                text: '\\n' + indent + '\\n' + next_indent + closing,\n                selection: [1, indent.length, 1, indent.length]\n            };\n        } else {\n            CstyleBehaviour.clearMaybeInsertedClosing();\n        }\n    });\n\n    this.add(\"braces\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '{') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.end.column, range.end.column + 1);\n            if (rightChar == '}') {\n                range.end.column++;\n                return range;\n            } else {\n                context.maybeInsertedBrackets--;\n            }\n        }\n    });\n\n    this.add(\"parens\", \"insertion\", function(state, action, editor, session, text) {\n        if (text == '(') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '(', ')');\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                CstyleBehaviour.recordAutoInsert(editor, session, \")\");\n                return {\n                    text: '()',\n                    selection: [1, 1]\n                };\n            }\n        } else if (text == ')') {\n            initContext(editor);\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == ')') {\n                var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        }\n    });\n\n    this.add(\"parens\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '(') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == ')') {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    this.add(\"brackets\", \"insertion\", function(state, action, editor, session, text) {\n        if (text == '[') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '[', ']');\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                CstyleBehaviour.recordAutoInsert(editor, session, \"]\");\n                return {\n                    text: '[]',\n                    selection: [1, 1]\n                };\n            }\n        } else if (text == ']') {\n            initContext(editor);\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == ']') {\n                var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        }\n    });\n\n    this.add(\"brackets\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '[') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == ']') {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    this.add(\"string_dquotes\", \"insertion\", function(state, action, editor, session, text) {\n        var quotes = session.$mode.$quotes || defaultQuotes;\n        if (text.length == 1 && quotes[text]) {\n            if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1)\n                return;\n            initContext(editor);\n            var quote = text;\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, quote, quote);\n            } else if (!selected) {\n                var cursor = editor.getCursorPosition();\n                var line = session.doc.getLine(cursor.row);\n                var leftChar = line.substring(cursor.column-1, cursor.column);\n                var rightChar = line.substring(cursor.column, cursor.column + 1);\n\n                var token = session.getTokenAt(cursor.row, cursor.column);\n                var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);\n                // We're escaped.\n                if (leftChar == \"\\\\\" && token && /escape/.test(token.type))\n                    return null;\n\n                var stringBefore = token && /string|escape/.test(token.type);\n                var stringAfter = !rightToken || /string|escape/.test(rightToken.type);\n\n                var pair;\n                if (rightChar == quote) {\n                    pair = stringBefore !== stringAfter;\n                    if (pair && /string\\.end/.test(rightToken.type))\n                        pair = false;\n                } else {\n                    if (stringBefore && !stringAfter)\n                        return null; // wrap string with different quote\n                    if (stringBefore && stringAfter)\n                        return null; // do not pair quotes inside strings\n                    var wordRe = session.$mode.tokenRe;\n                    wordRe.lastIndex = 0;\n                    var isWordBefore = wordRe.test(leftChar);\n                    wordRe.lastIndex = 0;\n                    var isWordAfter = wordRe.test(rightChar);\n\n                    var pairQuotesAfter = session.$mode.$pairQuotesAfter;\n                    var shouldPairQuotes = pairQuotesAfter && pairQuotesAfter[quote] && pairQuotesAfter[quote].test(leftChar);\n\n                    if ((!shouldPairQuotes && isWordBefore) || isWordAfter)\n                        return null; // before or after alphanumeric\n                    if (rightChar && !/[\\s;,.})\\]\\\\]/.test(rightChar))\n                        return null; // there is rightChar and it isn't closing\n                    var charBefore = line[cursor.column - 2];\n                    if (leftChar == quote &&  (charBefore == quote || wordRe.test(charBefore)))\n                        return null;\n                    pair = true;\n                }\n                return {\n                    text: pair ? quote + quote : \"\",\n                    selection: [1,1]\n                };\n            }\n        }\n    });\n\n    this.add(\"string_dquotes\", \"deletion\", function(state, action, editor, session, range) {\n        var quotes = session.$mode.$quotes || defaultQuotes;\n\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && quotes.hasOwnProperty(selected)) {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == selected) {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    if (options.closeDocComment !== false) {\n        this.add(\"doc comment end\", \"insertion\", function (state, action, editor, session, text) {\n            if (state === \"doc-start\" && (text === \"\\n\" || text === \"\\r\\n\") && editor.selection.isEmpty()) {\n                var cursor = editor.getCursorPosition();\n                if (cursor.column === 0) {\n                    return;\n                }\n                var line = session.doc.getLine(cursor.row);\n                var nextLine = session.doc.getLine(cursor.row + 1);\n                var tokens = session.getTokens(cursor.row);\n                var index = 0;\n                for (var i = 0; i < tokens.length; i++) {\n                    index += tokens[i].value.length;\n                    var currentToken = tokens[i];\n                    if (index >= cursor.column) {\n                        if (index === cursor.column) {\n                            if (!/\\.doc/.test(currentToken.type)) {\n                                return;\n                            }\n                            if (/\\*\\//.test(currentToken.value)) {\n                                var nextToken = tokens[i + 1];\n                                if (!nextToken || !/\\.doc/.test(nextToken.type)) {\n                                    return;\n                                }\n                            }\n                        }\n                        var cursorPosInToken = cursor.column - (index - currentToken.value.length);\n\n                        // Check for the pattern `*/` followed by `/**` within the token\n                        var closeDocPos = currentToken.value.indexOf(\"*/\");\n                        var openDocPos = currentToken.value.indexOf(\"/**\", closeDocPos > - 1 ? closeDocPos + 2 : 0);\n\n                        if (openDocPos !== -1 && cursorPosInToken > openDocPos && cursorPosInToken < openDocPos + 3) {\n                            return;\n                        }\n                        if (closeDocPos !== -1 && openDocPos !== -1 && cursorPosInToken >= closeDocPos\n                            && cursorPosInToken <= openDocPos || !/\\.doc/.test(currentToken.type)) {\n                            return;\n                        }\n                        break;\n                    }\n                }\n                var indent = this.$getIndent(line);\n                if (/\\s*\\*/.test(nextLine)) {\n                    if (/^\\s*\\*/.test(line)) {\n                        return {\n                            text: text + indent + \"* \",\n                            selection: [1, 2 + indent.length, 1, 2 + indent.length]\n                        };\n                    }\n                    else {\n                        return {\n                            text: text + indent + \" * \",\n                            selection: [1, 3 + indent.length, 1, 3 + indent.length]\n                        };\n                    }\n\n                }\n                if (/\\/\\*\\*/.test(line.substring(0, cursor.column))) {\n                    return {\n                        text: text + indent + \" * \" + text + \" \" + indent + \"*/\",\n                        selection: [1, 4 + indent.length, 1, 4 + indent.length]\n                    };\n                }\n            }\n        });\n    }\n};\n\n/**\n * @this {CstyleBehaviour}\n */\n// @ts-ignore\nCstyleBehaviour.isSaneInsertion = function(editor, session) {\n    var cursor = editor.getCursorPosition();\n    var iterator = new TokenIterator(session, cursor.row, cursor.column);\n\n    // Don't insert in the middle of a keyword/identifier/lexical\n    if (!this.$matchTokenType(iterator.getCurrentToken() || \"text\", SAFE_INSERT_IN_TOKENS)) {\n        if (/[)}\\]]/.test(editor.session.getLine(cursor.row)[cursor.column]))\n            return true;\n        // Look ahead in case we're at the end of a token\n        var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);\n        if (!this.$matchTokenType(iterator2.getCurrentToken() || \"text\", SAFE_INSERT_IN_TOKENS))\n            return false;\n    }\n\n    // Only insert in front of whitespace/comments\n    iterator.stepForward();\n    return iterator.getCurrentTokenRow() !== cursor.row ||\n        this.$matchTokenType(iterator.getCurrentToken() || \"text\", SAFE_INSERT_BEFORE_TOKENS);\n};\nCstyleBehaviour[\"$matchTokenType\"] = function(token, types) {\n    return types.indexOf(token.type || token) > -1;\n};\n\nCstyleBehaviour[\"recordAutoInsert\"] = function(editor, session, bracket) {\n    var cursor = editor.getCursorPosition();\n    var line = session.doc.getLine(cursor.row);\n    // Reset previous state if text or context changed too much\n    if (!this[\"isAutoInsertedClosing\"](cursor, line, context.autoInsertedLineEnd[0]))\n        context.autoInsertedBrackets = 0;\n    context.autoInsertedRow = cursor.row;\n    context.autoInsertedLineEnd = bracket + line.substr(cursor.column);\n    context.autoInsertedBrackets++;\n};\n\nCstyleBehaviour[\"recordMaybeInsert\"] = function(editor, session, bracket) {\n    var cursor = editor.getCursorPosition();\n    var line = session.doc.getLine(cursor.row);\n    if (!this[\"isMaybeInsertedClosing\"](cursor, line))\n        context.maybeInsertedBrackets = 0;\n    context.maybeInsertedRow = cursor.row;\n    context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;\n    context.maybeInsertedLineEnd = line.substr(cursor.column);\n    context.maybeInsertedBrackets++;\n};\n\nCstyleBehaviour[\"isAutoInsertedClosing\"] = function(cursor, line, bracket) {\n    return context.autoInsertedBrackets > 0 &&\n        cursor.row === context.autoInsertedRow &&\n        bracket === context.autoInsertedLineEnd[0] &&\n        line.substr(cursor.column) === context.autoInsertedLineEnd;\n};\n\nCstyleBehaviour[\"isMaybeInsertedClosing\"] = function(cursor, line) {\n    return context.maybeInsertedBrackets > 0 &&\n        cursor.row === context.maybeInsertedRow &&\n        line.substr(cursor.column) === context.maybeInsertedLineEnd &&\n        line.substr(0, cursor.column) == context.maybeInsertedLineStart;\n};\n\nCstyleBehaviour[\"popAutoInsertedClosing\"] = function() {\n    context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);\n    context.autoInsertedBrackets--;\n};\n\nCstyleBehaviour[\"clearMaybeInsertedClosing\"] = function() {\n    if (context) {\n        context.maybeInsertedBrackets = 0;\n        context.maybeInsertedRow = -1;\n    }\n};\n\n\n\noop.inherits(CstyleBehaviour, Behaviour);\n\nexports.CstyleBehaviour = CstyleBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/html.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar XmlBehaviour = require(\"../behaviour/xml\").XmlBehaviour;\n\n/**@type {(new() => Partial<import(\"../../../ace-internal\").Ace.Behaviour>)}*/\nvar HtmlBehaviour = function () {\n\n    XmlBehaviour.call(this);\n\n};\n\noop.inherits(HtmlBehaviour, XmlBehaviour);\n\nexports.HtmlBehaviour = HtmlBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/javascript.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nconst {TokenIterator} = require(\"../../token_iterator\");\nvar CstyleBehaviour = require(\"../behaviour/cstyle\").CstyleBehaviour;\nvar XmlBehaviour = require(\"../behaviour/xml\").XmlBehaviour;\nvar JavaScriptBehaviour = function () {\n    var xmlBehaviours = new XmlBehaviour({closeCurlyBraces: true}).getBehaviours();\n    this.addBehaviours(xmlBehaviours);\n    this.inherit(CstyleBehaviour);\n\n    this.add(\"autoclosing-fragment\", \"insertion\", function (state, action, editor, session, text) {\n        if (text == '>') {\n            var position = editor.getSelectionRange().start;\n            var iterator = new TokenIterator(session, position.row, position.column);\n            var token = iterator.getCurrentToken() || iterator.stepBackward();\n            if (!token) return;\n            if (token.value == '<') {\n                return {\n                    text: \"></>\",\n                    selection: [1, 1]\n                };\n            }\n        }\n    });\n};\n\noop.inherits(JavaScriptBehaviour, CstyleBehaviour);\n\nexports.JavaScriptBehaviour = JavaScriptBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/liquid.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../../lib/oop\");\n    var Behaviour = require(\"../behaviour\").Behaviour;\n    var XmlBehaviour = require(\"./xml\").XmlBehaviour;\n    var TokenIterator = require(\"../../token_iterator\").TokenIterator;\n    var lang = require(\"../../lib/lang\");\n\n    function is(token, type) {\n        return token && token.type.lastIndexOf(type + \".xml\") > -1;\n    }\n\n/**@type {(new() => Partial<import(\"../../../ace-internal\").Ace.Behaviour>)}*/\n    var LiquidBehaviour = function () {\n        XmlBehaviour.call(this);\n        this.add(\"autoBraceTagClosing\",\"insertion\", function (state, action, editor, session, text) {\n            if (text == '}') {\n                var position = editor.getSelectionRange().start;\n                var iterator = new TokenIterator(session, position.row, position.column);\n                var token = iterator.getCurrentToken() || iterator.stepBackward();\n\n                // exit if we're not in a tag\n                if (!token || !( token.value.trim() === '%' || is(token, \"tag-name\") || is(token, \"tag-whitespace\") || is(token, \"attribute-name\") || is(token, \"attribute-equals\") || is(token, \"attribute-value\")))\n                    return;\n\n                // exit if we're inside of a quoted attribute value\n                if (is(token, \"reference.attribute-value\"))\n                    return;\n\n                if (is(token, \"attribute-value\")) {\n                    var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length;\n                    if (position.column < tokenEndColumn)\n                        return;\n                    if (position.column == tokenEndColumn) {\n                        var nextToken = iterator.stepForward();\n                        // TODO also handle non-closed string at the end of the line\n                        if (nextToken && is(nextToken, \"attribute-value\"))\n                            return;\n                        iterator.stepBackward();\n                    }\n                }\n                // exit if the tag is empty\n                if (/{%\\s*%/.test(session.getLine(position.row))) return;\n                if (/^\\s*}/.test(session.getLine(position.row).slice(position.column)))\n                    return;\n\n                // find tag name\n                while (!token.type != 'meta.tag.punctuation.tag-open') {\n                    token = iterator.stepBackward();\n                    if (token.value == '{%') {\n                        while(true) {\n                            token = iterator.stepForward();\n\n                            if (token.type === 'meta.tag.punctuation.tag-open') {\n                                break;\n                            } else if (token.value.trim() == '%') {\n                                token = null;\n                                break;\n                            }\n                        }\n                        break;\n                    }\n                }\n                if (!token ) return ;\n                var tokenRow = iterator.getCurrentTokenRow();\n                var tokenColumn = iterator.getCurrentTokenColumn();\n\n                // exit if the tag is ending\n                if (is(iterator.stepBackward(), \"end-tag-open\"))\n                return;\n\n                var element = token.value;\n                if (tokenRow == position.row)\n                    element = element.substring(0, position.column - tokenColumn);\n\n                if (this.voidElements.hasOwnProperty(element.toLowerCase()))\n                     return;\n                return {\n                   text: \"}\" + \"{% end\" + element + \" %}\",\n                   selection: [1, 1]\n                };\n            }\n        });\n\n    };\n\n    oop.inherits(LiquidBehaviour, Behaviour);\n\n    exports.LiquidBehaviour = LiquidBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/xml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Behaviour = require(\"../behaviour\").Behaviour;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\nfunction is(token, type) {\n    return token && token.type.lastIndexOf(type + \".xml\") > -1;\n}\n\n/**@type {(new() => Partial<import(\"../../../ace-internal\").Ace.Behaviour>)}*/\nvar XmlBehaviour = function () {\n\n    this.add(\"string_dquotes\", \"insertion\", function (state, action, editor, session, text) {\n        if (text == '\"' || text == \"'\") {\n            var quote = text;\n            var selected = session.doc.getTextRange(editor.getSelectionRange());\n            if (selected !== \"\" && selected !== \"'\" && selected != '\"' && editor.getWrapBehavioursEnabled()) {\n                return {\n                    text: quote + selected + quote,\n                    selection: false\n                };\n            }\n\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n\n            if (rightChar == quote && (is(token, \"attribute-value\") || is(token, \"string\"))) {\n                // Ignore input and move right one if we're typing over the closing quote.\n                return {\n                    text: \"\",\n                    selection: [1, 1]\n                };\n            }\n\n            if (!token)\n                token = iterator.stepBackward();\n\n            if (!token)\n                return;\n\n            while (is(token, \"tag-whitespace\") || is(token, \"whitespace\")) {\n                token = iterator.stepBackward();\n            }\n            var rightSpace = !rightChar || rightChar.match(/\\s/);\n            if (is(token, \"attribute-equals\") && (rightSpace || rightChar == '>') || (is(token, \"decl-attribute-equals\") && (rightSpace || rightChar == '?'))) {\n                return {\n                    text: quote + quote,\n                    selection: [1, 1]\n                };\n            }\n        }\n    });\n\n    this.add(\"string_dquotes\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && (selected == '\"' || selected == \"'\")) {\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == selected) {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    this.add(\"autoclosing\", \"insertion\", function (state, action, editor, session, text) {\n        if (text == '>') {\n            var position = editor.getSelectionRange().start;\n            var iterator = new TokenIterator(session, position.row, position.column);\n            var token = iterator.getCurrentToken() || iterator.stepBackward();\n\n            // exit if we're not in a tag\n            if (!token || !(is(token, \"tag-name\") || is(token, \"tag-whitespace\") || is(token, \"attribute-name\") || is(token, \"attribute-equals\") || is(token, \"attribute-value\")))\n                return;\n\n            // exit if we're inside of a quoted attribute value\n            if (is(token, \"reference.attribute-value\"))\n                return;\n            if (is(token, \"attribute-value\")) {\n                var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length;\n                if (position.column < tokenEndColumn)\n                    return;\n                if (position.column == tokenEndColumn) {\n                    var nextToken = iterator.stepForward();\n                    // TODO also handle non-closed string at the end of the line\n                    if (nextToken && is(nextToken, \"attribute-value\"))\n                        return;\n                    iterator.stepBackward();\n                }\n            }\n\n            if (/^\\s*>/.test(session.getLine(position.row).slice(position.column)))\n                return;\n\n            // find tag name\n            while (!is(token, \"tag-name\")) {\n                token = iterator.stepBackward();\n                if (token.value == \"<\") {\n                    token = iterator.stepForward();\n                    break;\n                }\n            }\n\n            var tokenRow = iterator.getCurrentTokenRow();\n            var tokenColumn = iterator.getCurrentTokenColumn();\n\n            // exit if the tag is ending\n            if (is(iterator.stepBackward(), \"end-tag-open\"))\n                return;\n\n            var element = token.value;\n            if (tokenRow == position.row)\n                element = element.substring(0, position.column - tokenColumn);\n\n            if (this.voidElements && this.voidElements.hasOwnProperty(element.toLowerCase()))\n                 return;\n\n            return {\n               text: \">\" + \"</\" + element + \">\",\n               selection: [1, 1]\n            };\n        }\n    });\n\n    this.add(\"autoindent\", \"insertion\", function (state, action, editor, session, text) {\n        if (text == \"\\n\") {\n            var cursor = editor.getCursorPosition();\n            var line = session.getLine(cursor.row);\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n\n            if (is(token, \"\") && token.type.indexOf(\"tag-close\") !== -1) {\n                if (token.value == \"/>\")\n                    return;\n                //get tag name\n                while (token && token.type.indexOf(\"tag-name\") === -1) {\n                    token = iterator.stepBackward();\n                }\n\n                if (!token) {\n                    return;\n                }\n\n                var tag = token.value;\n                var row = iterator.getCurrentTokenRow();\n\n                //don't indent after closing tag\n                token = iterator.stepBackward();\n                if (!token || token.type.indexOf(\"end-tag\") !== -1) {\n                    return;\n                }\n\n                if (this.voidElements && !this.voidElements[tag] || !this.voidElements) {\n                    var nextToken = session.getTokenAt(cursor.row, cursor.column+1);\n                    var line = session.getLine(row);\n                    var nextIndent = this.$getIndent(line);\n                    var indent = nextIndent + session.getTabString();\n\n                    if (nextToken && nextToken.value === \"</\") {\n                        return {\n                            text: \"\\n\" + indent + \"\\n\" + nextIndent,\n                            selection: [1, indent.length, 1, indent.length]\n                        };\n                    } else {\n                        return {\n                            text: \"\\n\" + indent\n                        };\n                    }\n                }\n            }\n        }\n    });\n\n};\n\noop.inherits(XmlBehaviour, Behaviour);\n\nexports.XmlBehaviour = XmlBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour/xquery.js",
    "content": "\"use strict\";\n\n  var oop = require(\"../../lib/oop\");\n  var Behaviour = require('../behaviour').Behaviour;\n  var CstyleBehaviour = require('./cstyle').CstyleBehaviour;\n  var XmlBehaviour = require(\"../behaviour/xml\").XmlBehaviour;\n  var TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\nfunction hasType(token, type) {\n    var hasType = true;\n    var typeList = token.type.split('.');\n    var needleList = type.split('.');\n    needleList.forEach(function(needle){\n        if (typeList.indexOf(needle) == -1) {\n            hasType = false;\n            return false;\n        }\n    });\n    return hasType;\n}\n\n/**@type {(new() => Partial<import(\"../../../ace-internal\").Ace.Behaviour>)}*/\n  var XQueryBehaviour = function () {\n\n      this.inherit(CstyleBehaviour, [\"braces\", \"parens\", \"string_dquotes\"]); // Get string behaviour\n      this.inherit(XmlBehaviour); // Get xml behaviour\n\n      this.add(\"autoclosing\", \"insertion\", function (state, action, editor, session, text) {\n        if (text == '>') {\n            var position = editor.getCursorPosition();\n            var iterator = new TokenIterator(session, position.row, position.column);\n            var token = iterator.getCurrentToken();\n            var atCursor = false;\n            var state = JSON.parse(state).pop();\n            if ((token && token.value === '>') || state !== \"StartTag\") return;\n            if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){\n                do {\n                    token = iterator.stepBackward();\n                } while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text')));\n            } else {\n                atCursor = true;\n            }\n            var previous = iterator.stepBackward();\n            if (!token || !hasType(token, 'meta.tag') || (previous !== null && previous.value.match('/'))) {\n                return;\n            }\n            var tag = token.value.substring(1);\n            if (atCursor){\n                var tag = tag.substring(0, position.column - token.start);\n            }\n\n            return {\n               text: '>' + '</' + tag + '>',\n               selection: [1, 1]\n            };\n        }\n    });\n\n  };\n  oop.inherits(XQueryBehaviour, Behaviour);\n\n  exports.XQueryBehaviour = XQueryBehaviour;\n"
  },
  {
    "path": "src/mode/behaviour.js",
    "content": "\"use strict\";\n\nvar Behaviour;\nBehaviour = function() {\n   this.$behaviours = {};\n};\n\n(function () {\n\n    /**\n     * @this {Behaviour & this}\n     */\n    this.add = function (name, action, callback) {\n        switch (undefined) {\n          case this.$behaviours:\n              this.$behaviours = {};\n          case this.$behaviours[name]:\n              this.$behaviours[name] = {};\n        }\n        this.$behaviours[name][action] = callback;\n    };\n\n    /**\n     * @this {Behaviour & this}\n     */\n    this.addBehaviours = function (behaviours) {\n        for (var key in behaviours) {\n            for (var action in behaviours[key]) {\n                this.add(key, action, behaviours[key][action]);\n            }\n        }\n    };\n\n    /**\n     * @this {Behaviour & this}\n     */\n    this.remove = function (name) {\n        if (this.$behaviours && this.$behaviours[name]) {\n            delete this.$behaviours[name];\n        }\n    };\n\n    /**\n     * @this {Behaviour & this}\n     */\n    this.inherit = function (mode, filter) {\n        if (typeof mode === \"function\") {\n            var behaviours = new mode().getBehaviours(filter);\n        } else {\n            var behaviours = mode.getBehaviours(filter);\n        }\n        this.addBehaviours(behaviours);\n    };\n\n    /**\n     *\n     * @param [filter]\n     * @returns {{}|*}\n     * @this {Behaviour & this}\n     */\n    this.getBehaviours = function (filter) {\n        if (!filter) {\n            return this.$behaviours;\n        } else {\n            var ret = {};\n            for (var i = 0; i < filter.length; i++) {\n                if (this.$behaviours[filter[i]]) {\n                    ret[filter[i]] = this.$behaviours[filter[i]];\n                }\n            }\n            return ret;\n        }\n    };\n\n}).call(Behaviour.prototype);\n\nexports.Behaviour = Behaviour;\n"
  },
  {
    "path": "src/mode/bibtex.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar BibTeXHighlightRules = require(\"./bibtex_highlight_rules\").BibTeXHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = BibTeXHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/bibtex\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/bibtex_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar BibTeXHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [\n            {\n                token: \"comment\",\n                regex: /@Comment\\{/,\n                stateName: \"bibtexComment\",\n                push: [\n                    {\n                        token: \"comment\",\n                        regex: /}/,\n                        next: \"pop\"\n                    }, {\n                        token: \"comment\",\n                        regex: /\\{/,\n                        push: \"bibtexComment\"\n                    }, {\n                        defaultToken: \"comment\"\n                    }\n                ]\n            }, {\n                token: [\n                    \"keyword\", \"text\", \"paren.lparen\", \"text\", \"variable\", \"text\", \"keyword.operator\"\n                ],\n                regex: /(@String)(\\s*)(\\{)(\\s*)([a-zA-Z]*)(\\s*)(=)/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    }, {\n                        include: \"#misc\"\n                    }, {\n                        defaultToken: \"text\"\n                    }\n                ]\n            }, {\n                token: [\n                    \"keyword\", \"text\", \"paren.lparen\", \"text\", \"variable\", \"text\", \"keyword.operator\"\n                ],\n                regex: /(@String)(\\s*)(\\()(\\s*)([a-zA-Z]*)(\\s*)(=)/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    }, {\n                        include: \"#misc\"\n                    }, {\n                        defaultToken: \"text\"\n                    }\n                ]\n            }, {\n                token: [\n                    \"keyword\", \"text\", \"paren.lparen\"\n                ],\n                regex: /(@preamble)(\\s*)(\\()/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    }, {\n                        include: \"#misc\"\n                    }, {\n                        defaultToken: \"text\"\n                    }\n                ]\n            }, {\n                token: [\n                    \"keyword\", \"text\", \"paren.lparen\"\n                ],\n                regex: /(@preamble)(\\s*)(\\{)/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    }, {\n                        include: \"#misc\"\n                    }, {\n                        defaultToken: \"text\"\n                    }\n                ]\n            }, {\n                token: [\n                    \"keyword\", \"text\", \"paren.lparen\", \"text\", \"support.class\"\n                ],\n                regex: /(@[a-zA-Z]+)(\\s*)(\\{)(\\s*)([\\w-]+)/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    }, {\n                        token: [\n                            \"variable\", \"text\", \"keyword.operator\"\n                        ],\n                        regex: /([a-zA-Z0-9\\!\\$\\&\\*\\+\\-\\.\\/\\:\\;\\<\\>\\?\\[\\]\\^\\_\\`\\|]+)(\\s*)(=)/,\n                        push: [\n                            {\n                                token: \"text\",\n                                regex: /(?=[,}])/,\n                                next: \"pop\"\n                            }, {\n                                include: \"#misc\"\n                            }, {\n                                include: \"#integer\"\n                            }, {\n                                defaultToken: \"text\"\n                            }\n                        ]\n                    }, {\n                        token: \"punctuation\",\n                        regex: /,/\n                    }, {\n                        defaultToken: \"text\"\n                    }\n                ]\n            }, {\n                defaultToken: \"comment\"\n            }\n        ],\n        \"#integer\": [\n            {\n                token: \"constant.numeric.bibtex\",\n                regex: /\\d+/\n            }\n        ],\n        \"#misc\": [\n            {\n                token: \"string\",\n                regex: /\"/,\n                push: \"#string_quotes\"\n            }, {\n                token: \"paren.lparen\",\n                regex: /\\{/,\n                push: \"#string_braces\"\n            }, {\n                token: \"keyword.operator\",\n                regex: /#/\n            }\n        ],\n        \"#string_braces\": [\n            {\n                token: \"paren.rparen\",\n                regex: /\\}/,\n                next: \"pop\"\n            }, {\n                token: \"invalid.illegal\",\n                regex: /@/\n            }, {\n                include: \"#misc\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ],\n        \"#string_quotes\": [\n            {\n                token: \"string\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                include: \"#misc\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(BibTeXHighlightRules, TextHighlightRules);\n\nexports.BibTeXHighlightRules = BibTeXHighlightRules;"
  },
  {
    "path": "src/mode/c9search.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar C9SearchHighlightRules = require(\"./c9search_highlight_rules\").C9SearchHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar C9StyleFoldMode = require(\"./folding/c9search\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = C9SearchHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new C9StyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/c9search\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/c9search_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nfunction safeCreateRegexp(source, flag) {\n    try {\n        return new RegExp(source, flag);\n    } catch(e) {}\n}\n\nvar C9SearchHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    this.$rules = {\n        \"start\" : [\n            {\n                tokenNames : [\"c9searchresults.constant.numeric\", \"c9searchresults.text\", \"c9searchresults.text\", \"c9searchresults.keyword\"],\n                regex : /(^\\s+[0-9]+)(:)(\\d*\\s?)([^\\r\\n]+)/,\n                onMatch : function(val, state, stack) {\n                    var values = this.splitRegex.exec(val);\n                    var types = this.tokenNames;\n                    var tokens = [{\n                        type: types[0],\n                        value: values[1]\n                    }, {\n                        type: types[1],\n                        value: values[2]\n                    }];\n                    \n                    if (values[3]) {\n                        if (values[3] == \" \")\n                            tokens[1] = { type: types[1], value: values[2] + \" \" };\n                        else\n                            tokens.push({ type: types[1], value: values[3] });\n                    }\n                    var regex = stack[1];\n                    var str = values[4];\n                    \n                    var m;\n                    var last = 0;\n                    if (regex && regex.exec) {\n                        regex.lastIndex = 0;\n                        while (m = regex.exec(str)) {\n                            var skipped = str.substring(last, m.index);\n                            last = regex.lastIndex;\n                            if (skipped)\n                                tokens.push({type: types[2], value: skipped});\n                            if (m[0])\n                                tokens.push({type: types[3], value: m[0]});\n                            else if (!skipped)\n                                break;\n                        }\n                    }\n                    if (last < str.length)\n                        tokens.push({type: types[2], value: str.substr(last)});\n                    return tokens;\n                }\n            },\n            {\n                regex : \"^Searching for [^\\\\r\\\\n]*$\",\n                onMatch: function(val, state, stack) {\n                    var parts = val.split(\"\\x01\");\n                    if (parts.length < 3)\n                        return \"text\";\n\n                    var options, search;\n                    \n                    var i = 0;\n                    var tokens = [{\n                        value: parts[i++] + \"'\",\n                        type: \"text\"\n                    }, {\n                        value: search = parts[i++],\n                        type: \"text\" // \"c9searchresults.keyword\"\n                    }, {\n                        value: \"'\" + parts[i++],\n                        type: \"text\"\n                    }];\n                    \n                    // replaced\n                    if (parts[2] !== \" in\") {\n                        tokens.push({\n                            value: \"'\" + parts[i++] + \"'\",\n                            type: \"text\"\n                        }, {\n                            value: parts[i++],\n                            type: \"text\"\n                        });\n                    }\n                    // path\n                    tokens.push({\n                        value: \" \" + parts[i++] + \" \",\n                        type: \"text\"\n                    });\n                    // options\n                    if (parts[i+1]) {\n                        options = parts[i+1];\n                        tokens.push({\n                            value: \"(\" + parts[i+1] + \")\",\n                            type: \"text\"\n                        });\n                        i += 1;\n                    } else {\n                        i -= 1;\n                    }\n                    while (i++ < parts.length) {\n                        parts[i] && tokens.push({\n                            value: parts[i],\n                            type: \"text\"\n                        });\n                    }\n                    \n                    if (search) {\n                        if (!/regex/.test(options))\n                            search = lang.escapeRegExp(search);\n                        if (/whole/.test(options))\n                            search = \"\\\\b\" + search + \"\\\\b\";\n                    }\n                    \n                    var regex = search && safeCreateRegexp(\n                        \"(\" + search + \")\",\n                        / sensitive/.test(options) ? \"g\" : \"ig\"\n                    );\n                    if (regex) {\n                        stack[0] = state;\n                        stack[1] = regex;\n                    }\n                    \n                    return tokens;\n                }\n            },\n            {\n                regex : \"^(?=Found \\\\d+ matches)\",\n                token : \"text\",\n                next : \"numbers\"\n            },\n            {\n                token : \"string\", // single line\n                regex : \"^\\\\S:?[^:]+\",\n                next : \"numbers\"\n            }\n        ],\n        numbers:[{\n            regex : \"\\\\d+\",\n            token : \"constant.numeric\"\n        }, {\n            regex : \"$\",\n            token : \"text\",\n            next : \"start\"\n        }]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(C9SearchHighlightRules, TextHighlightRules);\n\nexports.C9SearchHighlightRules = C9SearchHighlightRules;\n"
  },
  {
    "path": "src/mode/c_cpp.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar c_cppHighlightRules = require(\"./c_cpp_highlight_rules\").c_cppHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = c_cppHighlightRules;\n\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState == \"start\") {\n                return \"\";\n            }\n            var match = line.match(/^\\s*(\\/?)\\*/);\n            if (match) {\n                if (match[1]) {\n                    indent += \" \";\n                }\n                indent += \"* \";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/c_cpp\";\n    this.snippetFileId = \"ace/snippets/c_cpp\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/c_cpp_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n// used by objective-c\nvar cFunctions = exports.cFunctions = \"hypot|hypotf|hypotl|sscanf|system|snprintf|scanf|scalbn|scalbnf|scalbnl|scalbln|scalblnf|scalblnl|sin|sinh|sinhf|sinhl|sinf|sinl|signal|signbit|strstr|strspn|strncpy|strncat|strncmp|strcspn|strchr|strcoll|strcpy|strcat|strcmp|strtoimax|strtod|strtoul|strtoull|strtoumax|strtok|strtof|strtol|strtold|strtoll|strerror|strpbrk|strftime|strlen|strrchr|strxfrm|sprintf|setjmp|setvbuf|setlocale|setbuf|sqrt|sqrtf|sqrtl|swscanf|swprintf|srand|nearbyint|nearbyintf|nearbyintl|nexttoward|nexttowardf|nexttowardl|nextafter|nextafterf|nextafterl|nan|nanf|nanl|csin|csinh|csinhf|csinhl|csinf|csinl|csqrt|csqrtf|csqrtl|ccos|ccosh|ccoshf|ccosf|ccosl|cimag|cimagf|cimagl|ctime|ctan|ctanh|ctanhf|ctanhl|ctanf|ctanl|cos|cosh|coshf|coshl|cosf|cosl|conj|conjf|conjl|copysign|copysignf|copysignl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|ceil|ceilf|ceill|cexp|cexpf|cexpl|clock|clog|clogf|clogl|clearerr|casin|casinh|casinhf|casinhl|casinf|casinl|cacos|cacosh|cacoshf|cacoshl|cacosf|cacosl|catan|catanh|catanhf|catanhl|catanf|catanl|calloc|carg|cargf|cargl|cabs|cabsf|cabsl|creal|crealf|creall|cbrt|cbrtf|cbrtl|time|toupper|tolower|tan|tanh|tanhf|tanhl|tanf|tanl|trunc|truncf|truncl|tgamma|tgammaf|tgammal|tmpnam|tmpfile|isspace|isnormal|isnan|iscntrl|isinf|isdigit|isunordered|isupper|ispunct|isprint|isfinite|iswspace|iswcntrl|iswctype|iswdigit|iswupper|iswpunct|iswprint|iswlower|iswalnum|iswalpha|iswgraph|iswxdigit|iswblank|islower|isless|islessequal|islessgreater|isalnum|isalpha|isgreater|isgreaterequal|isgraph|isxdigit|isblank|ilogb|ilogbf|ilogbl|imaxdiv|imaxabs|div|difftime|_Exit|ungetc|ungetwc|pow|powf|powl|puts|putc|putchar|putwc|putwchar|perror|printf|erf|erfc|erfcf|erfcl|erff|erfl|exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|vsscanf|vsnprintf|vscanf|vsprintf|vswscanf|vswprintf|vprintf|vfscanf|vfprintf|vfwscanf|vfwprintf|vwscanf|vwprintf|va_start|va_copy|va_end|va_arg|qsort|fscanf|fsetpos|fseek|fclose|ftell|fopen|fdim|fdimf|fdiml|fpclassify|fputs|fputc|fputws|fputwc|fprintf|feholdexcept|fesetenv|fesetexceptflag|fesetround|feclearexcept|fetestexcept|feof|feupdateenv|feraiseexcept|ferror|fegetenv|fegetexceptflag|fegetround|fflush|fwscanf|fwide|fwprintf|fwrite|floor|floorf|floorl|fabs|fabsf|fabsl|fgets|fgetc|fgetpos|fgetws|fgetwc|freopen|free|fread|frexp|frexpf|frexpl|fmin|fminf|fminl|fmod|fmodf|fmodl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|ldiv|ldexp|ldexpf|ldexpl|longjmp|localtime|localeconv|log|log1p|log1pf|log1pl|log10|log10f|log10l|log2|log2f|log2l|logf|logl|logb|logbf|logbl|labs|lldiv|llabs|llrint|llrintf|llrintl|llround|llroundf|llroundl|lrint|lrintf|lrintl|lround|lroundf|lroundl|lgamma|lgammaf|lgammal|wscanf|wcsstr|wcsspn|wcsncpy|wcsncat|wcsncmp|wcscspn|wcschr|wcscoll|wcscpy|wcscat|wcscmp|wcstoimax|wcstod|wcstoul|wcstoull|wcstoumax|wcstok|wcstof|wcstol|wcstold|wcstoll|wcstombs|wcspbrk|wcsftime|wcslen|wcsrchr|wcsrtombs|wcsxfrm|wctob|wctomb|wcrtomb|wprintf|wmemset|wmemchr|wmemcpy|wmemcmp|wmemmove|assert|asctime|asin|asinh|asinhf|asinhl|asinf|asinl|acos|acosh|acoshf|acoshl|acosf|acosl|atoi|atof|atol|atoll|atexit|atan|atanh|atanhf|atanhl|atan2|atan2f|atan2l|atanf|atanl|abs|abort|gets|getc|getchar|getenv|getwc|getwchar|gmtime|rint|rintf|rintl|round|roundf|roundl|rename|realloc|rewind|remove|remquo|remquof|remquol|remainder|remainderf|remainderl|rand|raise|bsearch|btowc|modf|modff|modfl|memset|memchr|memcpy|memcmp|memmove|mktime|malloc|mbsinit|mbstowcs|mbsrtowcs|mbtowc|mblen|mbrtowc|mbrlen\";\n\nvar c_cppHighlightRules = function(extraKeywords) {\n\n    var keywordControls = (\n        \"break|case|continue|default|do|else|for|goto|if|_Pragma|\" +\n        \"return|switch|while|catch|operator|try|throw|using\"\n    );\n    \n    var storageType = (\n        \"asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|\" +\n        \"_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|\" +\n        \"class|wchar_t|template|char16_t|char32_t\"\n    );\n\n    var storageModifiers = (\n        \"const|extern|register|restrict|static|volatile|inline|private|\" +\n        \"protected|public|friend|explicit|virtual|export|mutable|typename|\" +\n        \"constexpr|new|delete|alignas|alignof|decltype|noexcept|thread_local\"\n    );\n\n    var keywordOperators = (\n        \"and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|\" +\n        \"const_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace\"\n    );\n\n    var builtinConstants = (\n        \"NULL|true|false|TRUE|FALSE|nullptr\"\n    );\n\n    var keywordMapper = this.$keywords = this.createKeywordMapper(Object.assign({\n        \"keyword.control\" : keywordControls,\n        \"storage.type\" : storageType,\n        \"storage.modifier\" : storageModifiers,\n        \"keyword.operator\" : keywordOperators,\n        \"variable.language\": \"this\",\n        \"constant.language\": builtinConstants,\n        \"support.function.C99.c\": cFunctions\n    }, extraKeywords), \"identifier\");\n\n    var identifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\\\\b\";\n    var escapeRe = /\\\\(?:['\"?\\\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\\d]{2}|u[a-fA-F\\d]{4}U[a-fA-F\\d]{8}|.)/.source;\n    var formatRe = \"%\"\n          + /(\\d+\\$)?/.source // field (argument #)\n          + /[#0\\- +']*/.source // flags\n          + /[,;:_]?/.source // separator character (AltiVec)\n          + /((-?\\d+)|\\*(-?\\d+\\$)?)?/.source // minimum field width\n          + /(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?/.source // precision\n          + /(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?/.source // length modifier\n          + /(\\[[^\"\\]]+\\]|[diouxXDOUeEfFgGaACcSspn%])/.source; // conversion type\n          \n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { \n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"//$\",\n                next : \"start\"\n            }, {\n                token : \"comment\",\n                regex : \"//\",\n                next : \"singleLineComment\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // character\n                regex : \"'(?:\" + escapeRe + \"|.)?'\"\n            }, {\n                token : \"string.start\",\n                regex : '\"', \n                stateName: \"qqstring\",\n                next: [\n                    { token: \"string\", regex: /\\\\\\s*$/, next: \"qqstring\" },\n                    { token: \"constant.language.escape\", regex: escapeRe },\n                    { token: \"constant.language.escape\", regex: formatRe },\n                    { token: \"string.end\", regex: '\"|$', next: \"start\" },\n                    { defaultToken: \"string\"}\n                ]\n            }, {\n                token : \"string.start\",\n                regex : 'R\"\\\\(', \n                stateName: \"rawString\",\n                next: [\n                    { token: \"string.end\", regex: '\\\\)\"', next: \"start\" },\n                    { defaultToken: \"string\"}\n                ]\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n            }, {\n                token : \"keyword\", // pre-compiler directives\n                regex : \"#\\\\s*(?:include|import|pragma|line|define|undef)\\\\b\",\n                next  : \"directive\"\n            }, {\n                token : \"keyword\", // special case pre-compiler directive\n                regex : \"#\\\\s*(?:endif|if|ifdef|else|elif|ifndef)\\\\b\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\"\n            }, {\n                token : \"keyword.operator\",\n                regex : /--|\\+\\+|<<=|>>=|>>>=|<>|&&|\\|\\||\\?:|[*%\\/+\\-&\\^|~!<>=]=?/\n            }, {\n              token : \"punctuation.operator\",\n              regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"singleLineComment\" : [\n            {\n                token : \"comment\",\n                regex : /\\\\$/,\n                next : \"singleLineComment\"\n            }, {\n                token : \"comment\",\n                regex : /$/,\n                next : \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }\n        ],\n        \"directive\" : [\n            {\n                token : \"constant.other.multiline\",\n                regex : /\\\\/\n            },\n            {\n                token : \"constant.other.multiline\",\n                regex : /.*\\\\/\n            },\n            {\n                token : \"constant.other\",\n                regex : \"\\\\s*<.+?>\",\n                next : \"start\"\n            },\n            {\n                token : \"constant.other\", // single line\n                regex : '\\\\s*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]',\n                next : \"start\"\n            }, \n            {\n                token : \"constant.other\", // single line\n                regex : \"\\\\s*['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\",\n                next : \"start\"\n            },\n            // \"\\\" implies multiline, while \"/\" implies comment\n            {\n                token : \"constant.other\",\n                regex : /[^\\\\\\/]+/,\n                next : \"start\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.normalizeRules();\n};\n\noop.inherits(c_cppHighlightRules, TextHighlightRules);\n\nexports.c_cppHighlightRules = c_cppHighlightRules;\n"
  },
  {
    "path": "src/mode/cirru.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CirruHighlightRules = require(\"./cirru_highlight_rules\").CirruHighlightRules;\nvar CoffeeFoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = CirruHighlightRules;\n    this.foldingRules = new CoffeeFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.$id = \"ace/mode/cirru\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/cirru_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n// see http://cirru.org for more about this language\nvar CirruHighlightRules = function() {\n    this.$rules = {\n        start: [{\n            token: 'constant.numeric',\n            regex: /[\\d\\.]+/\n        }, {\n            token: 'comment.line.double-dash',\n            regex: /--/,\n            next: 'comment'\n        }, {\n            token: 'storage.modifier',\n            regex: /\\(/\n        }, {\n            token: 'storage.modifier',\n            regex: /,/,\n            next: 'line'\n        }, {\n            token: 'support.function',\n            regex: /[^\\(\\)\"\\s{}\\[\\]]+/,\n            next: 'line'\n        }, {\n            token: 'string.quoted.double',\n            regex: /\"/,\n            next: 'string'\n        }, {\n            token: 'storage.modifier',\n            regex: /\\)/\n        }],\n        comment: [{\n            token: 'comment.line.double-dash',\n            regex: / +[^\\n]+/,\n            next: 'start'\n        }],\n        string: [{\n            token: 'string.quoted.double',\n            regex: /\"/,\n            next: 'line'\n        }, {\n            token: 'constant.character.escape',\n            regex: /\\\\/,\n            next: 'escape'\n        }, {\n            token: 'string.quoted.double',\n            regex: /[^\\\\\"]+/\n        }],\n        escape: [{\n            token: 'constant.character.escape',\n            regex: /./,\n            next: 'string'\n        }],\n        line: [{\n            token: 'constant.numeric',\n            regex: /[\\d\\.]+/\n        }, {\n            token: 'markup.raw',\n            regex: /^\\s*/,\n            next: 'start'\n        }, {\n            token: 'storage.modifier',\n            regex: /\\$/,\n            next: 'start'\n        }, {\n            token: 'variable.parameter',\n            regex: /[^\\(\\)\"\\s{}\\[\\]]+/\n        }, {\n            token: 'storage.modifier',\n            regex: /\\(/,\n            next: 'start'\n        }, {\n            token: 'storage.modifier',\n            regex: /\\)/\n        }, {\n            token: 'markup.raw',\n            regex: /^ */,\n            next: 'start'\n        }, {\n            token: 'string.quoted.double',\n            regex: /\"/,\n            next: 'string'\n        }]\n    };\n\n};\n\noop.inherits(CirruHighlightRules, TextHighlightRules);\n\nexports.CirruHighlightRules = CirruHighlightRules;\n"
  },
  {
    "path": "src/mode/clojure.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ClojureHighlightRules = require(\"./clojure_highlight_rules\").ClojureHighlightRules;\nvar MatchingParensOutdent = require(\"./matching_parens_outdent\").MatchingParensOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = ClojureHighlightRules;\n    this.$outdent = new MatchingParensOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \";\";\n    this.minorIndentFunctions = [\"defn\", \"defn-\", \"defmacro\", \"def\", \"deftest\", \"testing\"];\n\n    this.$toIndent = function(str) {\n        return str.split('').map(function(ch) {\n            if (/\\s/.exec(ch)) {\n                return ch;\n            } else {\n                return ' ';\n            }\n        }).join('');\n    };\n\n    this.$calculateIndent = function(line, tab) {\n        var baseIndent = this.$getIndent(line);\n        var delta = 0;\n        var isParen, ch;\n        // Walk back from end of line, find matching braces\n        for (var i = line.length - 1; i >= 0; i--) {\n            ch = line[i];\n            if (ch === '(') {\n                delta--;\n                isParen = true;\n            } else if (ch === '(' || ch === '[' || ch === '{') {\n                delta--;\n                isParen = false;\n            } else if (ch === ')' || ch === ']' || ch === '}') {\n                delta++;\n            }\n            if (delta < 0) {\n                break;\n            }\n        }\n        if (delta < 0 && isParen) {\n            // Were more brackets opened than closed and was a ( left open?\n            i += 1;\n            var iBefore = i;\n            var fn = '';\n            while (true) {\n                ch = line[i];\n                if (ch === ' ' || ch === '\\t') {\n                    if(this.minorIndentFunctions.indexOf(fn) !== -1) {\n                        return this.$toIndent(line.substring(0, iBefore - 1) + tab);\n                    } else {\n                        return this.$toIndent(line.substring(0, i + 1));\n                    }\n                } else if (ch === undefined) {\n                    return this.$toIndent(line.substring(0, iBefore - 1) + tab);\n                }\n                fn += line[i];\n                i++;\n            }\n        } else if(delta < 0 && !isParen) {\n            // Were more brackets openend than closed and was it not a (?\n            return this.$toIndent(line.substring(0, i+1));\n        } else if(delta > 0) {\n            // Mere more brackets closed than opened? Outdent.\n            baseIndent = baseIndent.substring(0, baseIndent.length - tab.length);\n            return baseIndent;\n        } else {\n            // Were they nicely matched? Just indent like line before.\n            return baseIndent;\n        }\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$calculateIndent(line, tab);\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/clojure\";\n    this.snippetFileId = \"ace/snippets/clojure\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/clojure_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\n\nvar ClojureHighlightRules = function() {\n\n    var builtinFunctions = (\n        '* *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* ' +\n        '*command-line-args* *compile-files* *compile-path* *e *err* *file* ' +\n        '*flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* ' +\n        '*print-dup* *print-length* *print-level* *print-meta* *print-readably* ' +\n        '*read-eval* *source-path* *use-context-classloader* ' +\n        '*warn-on-reflection* + - -> ->> .. / < <= = ' +\n        '== > &gt; >= &gt;= accessor aclone ' +\n        'add-classpath add-watch agent agent-errors aget alength alias all-ns ' +\n        'alter alter-meta! alter-var-root amap ancestors and apply areduce ' +\n        'array-map aset aset-boolean aset-byte aset-char aset-double aset-float ' +\n        'aset-int aset-long aset-short assert assoc assoc! assoc-in associative? ' +\n        'atom await await-for await1 bases bean bigdec bigint binding bit-and ' +\n        'bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left ' +\n        'bit-shift-right bit-test bit-xor boolean boolean-array booleans ' +\n        'bound-fn bound-fn* butlast byte byte-array bytes cast char char-array ' +\n        'char-escape-string char-name-string char? chars chunk chunk-append ' +\n        'chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? ' +\n        'class class? clear-agent-errors clojure-version coll? comment commute ' +\n        'comp comparator compare compare-and-set! compile complement concat cond ' +\n        'condp conj conj! cons constantly construct-proxy contains? count ' +\n        'counted? create-ns create-struct cycle dec decimal? declare definline ' +\n        'defmacro defmethod defmulti defn defn- defonce defstruct delay delay? ' +\n        'deliver deref derive descendants destructure disj disj! dissoc dissoc! ' +\n        'distinct distinct? doall doc dorun doseq dosync dotimes doto double ' +\n        'double-array doubles drop drop-last drop-while empty empty? ensure ' +\n        'enumeration-seq eval even? every? false? ffirst file-seq filter find ' +\n        'find-doc find-ns find-var first float float-array float? floats flush ' +\n        'fn fn? fnext for force format future future-call future-cancel ' +\n        'future-cancelled? future-done? future? gen-class gen-interface gensym ' +\n        'get get-in get-method get-proxy-class get-thread-bindings get-validator ' +\n        'hash hash-map hash-set identical? identity if-let if-not ifn? import ' +\n        'in-ns inc init-proxy instance? int int-array integer? interleave intern ' +\n        'interpose into into-array ints io! isa? iterate iterator-seq juxt key ' +\n        'keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list ' +\n        'list* list? load load-file load-reader load-string loaded-libs locking ' +\n        'long long-array longs loop macroexpand macroexpand-1 make-array ' +\n        'make-hierarchy map map? mapcat max max-key memfn memoize merge ' +\n        'merge-with meta method-sig methods min min-key mod name namespace neg? ' +\n        'newline next nfirst nil? nnext not not-any? not-empty not-every? not= ' +\n        'ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ' +\n        'ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? ' +\n        'or parents partial partition pcalls peek persistent! pmap pop pop! ' +\n        'pop-thread-bindings pos? pr pr-str prefer-method prefers ' +\n        'primitives-classnames print print-ctor print-doc print-dup print-method ' +\n        'print-namespace-doc print-simple print-special-doc print-str printf ' +\n        'println println-str prn prn-str promise proxy proxy-call-with-super ' +\n        'proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot ' +\n        'rand rand-int range ratio? rational? rationalize re-find re-groups ' +\n        're-matcher re-matches re-pattern re-seq read read-line read-string ' +\n        'reduce ref ref-history-count ref-max-history ref-min-history ref-set ' +\n        'refer refer-clojure release-pending-sends rem remove remove-method ' +\n        'remove-ns remove-watch repeat repeatedly replace replicate require ' +\n        'reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq ' +\n        'rsubseq second select-keys send send-off seq seq? seque sequence ' +\n        'sequential? set set-validator! set? short short-array shorts ' +\n        'shutdown-agents slurp some sort sort-by sorted-map sorted-map-by ' +\n        'sorted-set sorted-set-by sorted? special-form-anchor special-symbol? ' +\n        'split-at split-with str stream? string? struct struct-map subs subseq ' +\n        'subvec supers swap! symbol symbol? sync syntax-symbol-anchor take ' +\n        'take-last take-nth take-while test the-ns time to-array to-array-2d ' +\n        'trampoline transient tree-seq true? type unchecked-add unchecked-dec ' +\n        'unchecked-divide unchecked-inc unchecked-multiply unchecked-negate ' +\n        'unchecked-remainder unchecked-subtract underive unquote ' +\n        'unquote-splicing update-in update-proxy use val vals var-get var-set ' +\n        'var? vary-meta vec vector vector? when when-first when-let when-not ' +\n        'while with-bindings with-bindings* with-in-str with-loading-context ' +\n        'with-local-vars with-meta with-open with-out-str with-precision xml-seq ' +\n        'zero? zipmap'\n    );\n\n    var keywords = ('throw try var ' +\n        'def do fn if let loop monitor-enter monitor-exit new quote recur set!'\n    );\n\n    var buildinConstants = (\"true false nil\");\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants,\n        \"support.function\": builtinFunctions\n    }, \"identifier\", false, \" \");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \";.*$\"\n            }, {\n                token : \"keyword\", //parens\n                regex : \"[\\\\(|\\\\)]\"\n            }, {\n                token : \"keyword\", //lists\n                regex : \"[\\\\'\\\\(]\"\n            }, {\n                token : \"keyword\", //vectors\n                regex : \"[\\\\[|\\\\]]\"\n            }, {\n                token : \"string.regexp\", //Regular Expressions\n                regex : '#\"',\n                next: \"regex\"\n            }, {\n                token : \"keyword\", //sets and maps\n                regex : \"[\\\\{|\\\\}|\\\\#\\\\{|\\\\#\\\\}]\"\n            }, {\n                    token : \"keyword\", // ampersands\n                    regex : '[\\\\&]'\n            }, {\n                    token : \"keyword\", // metadata\n                    regex : '[\\\\#\\\\^\\\\{]'\n            }, {\n                    token : \"keyword\", // anonymous fn syntactic sugar\n                    regex : '[\\\\%]'\n            }, {\n                    token : \"keyword\", // deref reader macro\n                    regex : '[@]'\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language\",\n                regex : '[!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+||=|!=|<=|>=|<>|<|>|!|&&]'\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$\\\\-]*\\\\b\"\n            }, {\n                token : \"string\", // single line\n                regex : '\"',\n                next: \"string\"\n            }, {\n                token : \"constant\", // symbol\n                regex : /:[^()\\[\\]{}'\"\\^%`,;\\s]+/\n            }\n\n        ],\n        \"string\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : \"\\\\\\\\.|\\\\\\\\$\"\n            }, {\n                token : \"string\",\n                regex : '\"',\n                next : \"start\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ],\n         \"regex\": [\n            {\n                // escapes\n                token: \"regexp.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                // flag\n                token: \"string.regexp\",\n                regex: '\"',\n                next: \"start\"\n            }, {\n                // operators\n                token : \"constant.language.escape\",\n                regex: /\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/\n            }, {\n                token : \"constant.language.delimiter\",\n                regex: /\\|/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\[\\^?/,\n                next: \"regex_character_class\"\n            }, {\n                defaultToken: \"string.regexp\"\n            }\n        ],\n        \"regex_character_class\": [\n            {\n                token: \"regexp.charclass.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"]\",\n                next: \"regex\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"-\"\n            }, {\n                defaultToken: \"string.regexp.charachterclass\"\n            }\n        ]\n    };\n};\n\noop.inherits(ClojureHighlightRules, TextHighlightRules);\n\nexports.ClojureHighlightRules = ClojureHighlightRules;\n"
  },
  {
    "path": "src/mode/clue.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ClueHighlightRules = require(\"./clue_highlight_rules\").ClueHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = ClueHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n    this.lineCommentStart = \"//\";\n    this.blockComment = { start: \"/*\", end: \"*/\" };\n    this.$quotes = { '\"': '\"', \"'\": \"'\", \"`\": \"`\" };\n    this.$pairQuotesAfter = {\n        \"`\": /\\w/\n    };\n\n    this.$id = \"ace/mode/clue\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/clue_highlight_rules.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/* This file was autogenerated from clue.json (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ClueHighlightRules = function () {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: [\n                \"keyword.control.directive.clue\",\n                \"text\",\n                \"text\"\n            ],\n            regex: /(@version)( )(.+?(?=\\n))/\n        }, {\n            token: [\"keyword.control.macro.clue\", \"text\", \"text\"],\n            regex: /(@macro)( )([A-Za-z_][0-9A-Za-z_]*)/\n        }, {\n            token: [\n                \"keyword.control.import.clue\",\n                \"text\",\n                \"string\"\n            ],\n            regex: /(@import)( )(\".*\")/\n        }, {\n            token: \"meta.preprocessor.macro.invocation.clue\",\n            regex: /\\$[A-Za-z_][0-9A-Za-z_]*!/\n        }, {\n            token: \"keyword.control.directive.clue\",\n            regex: /@(?:(?:else_)?(?:ifos|iflua|ifdef|ifndef|ifcmp|ifos|iflua|ifdef|ifcmp|if)|else|define|macro|error|print)/\n        }, {\n            token: \"constant.numeric.integer.hexadecimal.clue\",\n            regex: /\\b0[xX][0-9A-Fa-f]+(?![pPeE.0-9])\\b/\n\n        }, {\n            token: \"constant.numeric.float.hexadecimal.clue\",\n            regex: /\\b0[xX][0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]+)?(?:[eE]-?\\d*)?(?:[pP][-+]\\d+)?\\b/\n        }, {\n            token: \"constant.numeric.integer.clue\",\n            regex: /\\b\\d+(?![pPeE.0-9])/\n        }, {\n            token: \"constant.numeric.float.clue\",\n            regex: /\\b\\d+(?:\\.\\d+)?(?:[eE]-?\\d*)?/\n        }, {\n            token: \"punctuation.definition.string.multilined.begin.clue\",\n            regex: /'/,\n            push: [{\n                token: \"punctuation.definition.string.multilined.end.clue\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                include: \"#escaped_char\"\n            }, {\n                defaultToken: \"string.quoted.single.clue\"\n            }]\n        }, {\n            token: \"punctuation.definition.string.multilined.begin.clue\",\n            regex: /\"/,\n            push: [{\n                token: \"punctuation.definition.string.multilined.end.clue\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                include: \"#escaped_char\"\n            }, {\n                defaultToken: \"string.quoted.double.clue\"\n            }]\n        }, {\n            token: \"punctuation.definition.string.multilined.begin.clue\",\n            regex: /`/,\n            push: [{\n                token: \"punctuation.definition.string.multilined.end.clue\",\n                regex: /`/,\n                next: \"pop\"\n            }, {\n                include: \"#escaped_char\"\n            }, {\n                defaultToken: \"string.multiline.clue\"\n            }]\n        }, {\n            token: \"comment.line.double-dash.clue\",\n            regex: /\\/\\/.*/\n        }, {\n            token: \"punctuation.definition.comment.begin.clue\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"punctuation.definition.comment.end.clue\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                include: \"#escaped_char\"\n            }, {\n                defaultToken: \"comment.block.clue\"\n            }]\n        }, {\n            token: \"keyword.control.clue\",\n            regex: /\\b(?:if|elseif|else|for|of|in|with|while|meta|until|fn|method|return|loop|enum|goto|continue|break|try|catch|match|default|macro)\\b/\n        }, {\n            token: \"keyword.scope.clue\",\n            regex: /\\b(?:local|global|static)\\b/\n        }, {\n            token: \"constant.language.clue\",\n            regex: /\\b(?:false|nil|true|_G|_VERSION|math\\.(?:pi|huge))\\b/\n        }, {\n            token: \"constant.language.ellipsis.clue\",\n            regex: /\\.{3}(?!\\.)/\n        }, {\n            token: \"keyword.operator.property.clue\",\n            regex: /\\.|::/,\n            next: \"property_identifier\"\n        }, {\n            token: \"keyword.operator.clue\",\n            regex: /\\/_|\\&|\\||\\!|\\~|\\?|\\$|@|\\+|-|%|#|\\*|\\/|\\^|==?|<=?|>=?|\\.{2}|\\?\\?=?|(?:&&|\\|\\|)=?/\n        }, {\n            token: \"variable.language.self.clue\",\n            regex: /\\bself\\b/\n        }, {\n            token: \"support.function.any-method.clue\",\n            regex: /\\b[a-zA-Z_][a-zA-Z0-9_]*\\b(?=\\(\\s*)/\n        }, {\n            token: \"variable.other.clue\",\n            regex: /[A-Za-z_][0-9A-Za-z_]*/\n        }],\n        \"#escaped_char\": [{\n            token: \"constant.character.escape.clue\",\n            regex: /\\\\[abfnrtvz\\\\\"'$]/\n        }, {\n            token: \"constant.character.escape.byte.clue\",\n            regex: /\\\\\\d{1,3}/\n        }, {\n            token: \"constant.character.escape.byte.clue\",\n            regex: /\\\\x[0-9A-Fa-f][0-9A-Fa-f]/\n        }, {\n            token: \"constant.character.escape.unicode.clue\",\n            regex: /\\\\u\\{[0-9A-Fa-f]+\\}/\n        }, {\n            token: \"invalid.illegal.character.escape.clue\",\n            regex: /\\\\./\n        }],\n        property_identifier: [{\n            token: \"variable.other.property.clue\",\n            regex: /[A-Za-z_][0-9A-Za-z_]*/,\n            next: \"start\"\n        }, {\n            token: \"\",\n            regex: \"\",\n            next: \"start\"\n        }],\n    };\n\n    this.normalizeRules();\n};\n\nClueHighlightRules.metaData = {\n    name: \"Clue\",\n    scopeName: \"source.clue\"\n};\n\n\noop.inherits(ClueHighlightRules, TextHighlightRules);\n\nexports.ClueHighlightRules = ClueHighlightRules;\n"
  },
  {
    "path": "src/mode/cobol.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CobolHighlightRules = require(\"./cobol_highlight_rules\").CobolHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = CobolHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"*\";\n\n    this.$id = \"ace/mode/cobol\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/cobol_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar CobolHighlightRules = function() {\nvar keywords = \"ACCEPT|MERGE|SUM|ADD||MESSAGE|TABLE|ADVANCING|MODE|TAPE|\" +\n\"AFTER|MULTIPLY|TEST|ALL|NEGATIVE|TEXT|ALPHABET|NEXT|THAN|\" +\n\"ALSO|NO|THEN|ALTERNATE|NOT|THROUGH|AND|NUMBER|THRU|ANY|OCCURS|\" +\n\"TIME|ARE|OF|TO|AREA|OFF|TOP||ASCENDING|OMITTED|TRUE|ASSIGN|ON|TYPE|AT|OPEN|\" +\n\"UNIT|AUTHOR|OR|UNTIL|BEFORE|OTHER|UP|BLANK|OUTPUT|USE|BLOCK|PAGE|USING|BOTTOM|\" +\n\"PERFORM|VALUE|BY|PIC|VALUES|CALL|PICTURE|WHEN|CANCEL|PLUS|WITH|CD|POINTER|WRITE|\" +\n\"CHARACTER|POSITION||ZERO|CLOSE|POSITIVE|ZEROS|COLUMN|PROCEDURE|ZEROES|COMMA|PROGRAM|\" +\n\"COMMON|PROGRAM-ID|COMMUNICATION|QUOTE|COMP|RANDOM|COMPUTE|READ|CONTAINS|RECEIVE|CONFIGURATION|\" +\n\"RECORD|CONTINUE|REDEFINES|CONTROL|REFERENCE|COPY|REMAINDER|COUNT|REPLACE|DATA|REPORT|DATE|RESERVE|\" +\n\"DAY|RESET|DELETE|RETURN|DESTINATION|REWIND|DISABLE|REWRITE|DISPLAY|RIGHT|DIVIDE|RUN|DOWN|SAME|\" +\n\"ELSE|SEARCH|ENABLE|SECTION|END|SELECT|ENVIRONMENT|SENTENCE|EQUAL|SET|ERROR|SIGN|EXIT|SEQUENTIAL|\" +\n\"EXTERNAL|SIZE|FLASE|SORT|FILE|SOURCE|LENGTH|SPACE|LESS|STANDARD|LIMIT|START|LINE|STOP|LOCK|STRING|LOW-VALUE|SUBTRACT\";\n\n    var builtinConstants = (\n        \"true|false|null\"\n    );\n\n    var builtinFunctions = (\n        \"count|min|max|avg|sum|rank|now|coalesce|main\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"\\\\*.*$\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\".*?\"'\n        }, {\n            token : \"string\",           // ' string\n            regex : \"'.*?'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n};\n\noop.inherits(CobolHighlightRules, TextHighlightRules);\n\nexports.CobolHighlightRules = CobolHighlightRules;\n"
  },
  {
    "path": "src/mode/coffee.js",
    "content": "\"use strict\";\n\nvar Rules = require(\"./coffee_highlight_rules\").CoffeeHighlightRules;\nvar Outdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\nvar Range = require(\"../range\").Range;\nvar TextMode = require(\"./text\").Mode;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\nvar oop = require(\"../lib/oop\");\n\nfunction Mode() {\n    this.HighlightRules = Rules;\n    this.$outdent = new Outdent();\n    this.foldingRules = new FoldMode();\n}\n\noop.inherits(Mode, TextMode);\n\n(function() {\n    \n    /*:\n      [({[=:]        # Opening parentheses or brackets\n     |[-=]>          # OR single or double arrow\n     |\\b(?:          # OR one of these words:\n       else          #    else\n      |try           # OR try\n      |(?:swi|ca)tch # OR catch, optionally followed by:\n        (?:\\s*[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*)?  # a variable\n      |finally       # OR finally\n     ))\\s*$          # all as the last thing on a line (allowing trailing space)\n    |                # ---- OR ---- :\n    ^\\s*             # a line starting with optional space\n    (else\\b\\s*)?     # followed by an optional \"else\"\n    (?:              # followed by one of the following:\n       if            #    if\n      |for           # OR for\n      |while         # OR while\n      |loop          # OR loop\n    )\\b              #    (as a word)\n    (?!.*\\bthen\\b)   # ... but NOT followed by \"then\" on the line\n    */\n    var indenter = /(?:[({[=:]|[-=]>|\\b(?:else|try|(?:swi|ca)tch(?:\\s+[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*)?|finally))\\s*$|^\\s*(else\\b\\s*)?(?:if|for|while|loop)\\b(?!.*\\bthen\\b)/;\n    \n    this.lineCommentStart = \"#\";\n    this.blockComment = {start: \"###\", end: \"###\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n    \n        if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&\n            state === 'start' && indenter.test(line))\n            indent += tab;\n        return indent;\n    };\n    \n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n    \n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/coffee_worker\", \"Worker\");\n        worker.attachToDocument(session.getDocument());\n        \n        worker.on(\"annotate\", function(e) {\n            session.setAnnotations(e.data);\n        });\n        \n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n        \n        return worker;\n    };\n\n    this.$id = \"ace/mode/coffee\";\n    this.snippetFileId = \"ace/snippets/coffee\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/coffee_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    oop.inherits(CoffeeHighlightRules, TextHighlightRules);\n\n    function CoffeeHighlightRules() {\n        var identifier = \"[$A-Za-z_\\\\x7f-\\\\uffff][$\\\\w\\\\x7f-\\\\uffff]*\";\n\n        var keywords = (\n            \"this|throw|then|try|typeof|super|switch|return|break|by|continue|\" +\n            \"catch|class|in|instanceof|is|isnt|if|else|extends|for|own|\" +\n            \"finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|\" +\n            \"or|on|unless|until|and|yes|yield|export|import|default\"\n        );\n\n        var langConstant = (\n            \"true|false|null|undefined|NaN|Infinity\"\n        );\n\n        var illegal = (\n            \"case|const|function|var|void|with|enum|implements|\" +\n            \"interface|let|package|private|protected|public|static\"\n        );\n\n        var supportClass = (\n            \"Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|\" +\n            \"Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|\" +\n            \"SyntaxError|TypeError|URIError|\"  +\n            \"ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|\" +\n            \"Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray\"\n        );\n\n        var supportFunction = (\n            \"Math|JSON|isNaN|isFinite|parseInt|parseFloat|encodeURI|\" +\n            \"encodeURIComponent|decodeURI|decodeURIComponent|String|\"\n        );\n\n        var variableLanguage = (\n            \"window|arguments|prototype|document\"\n        );\n\n        var keywordMapper = this.createKeywordMapper({\n            \"keyword\": keywords,\n            \"constant.language\": langConstant,\n            \"invalid.illegal\": illegal,\n            \"language.support.class\": supportClass,\n            \"language.support.function\": supportFunction,\n            \"variable.language\": variableLanguage\n        }, \"identifier\");\n\n        var functionRule = {\n            token: [\"paren.lparen\", \"variable.parameter\", \"paren.rparen\", \"text\", \"storage.type\"],\n            regex: /(?:(\\()((?:\"[^\")]*?\"|'[^')]*?'|\\/[^\\/)]*?\\/|[^()\"'\\/])*?)(\\))(\\s*))?([\\-=]>)/.source\n        };\n\n        var stringEscape = /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)/;\n\n        this.$rules = {\n            start : [\n                {\n                    token : \"constant.numeric\",\n                    regex : \"(?:0x[\\\\da-fA-F]+|(?:\\\\d+(?:\\\\.\\\\d+)?|\\\\.\\\\d+)(?:[eE][+-]?\\\\d+)?)\"\n                }, {\n                    stateName: \"qdoc\",\n                    token : \"string\", regex : \"'''\", next : [\n                        {token : \"string\", regex : \"'''\", next : \"start\"},\n                        {token : \"constant.language.escape\", regex : stringEscape},\n                        {defaultToken: \"string\"}\n                    ]\n                }, {\n                    stateName: \"qqdoc\",\n                    token : \"string\",\n                    regex : '\"\"\"',\n                    next : [\n                        {token : \"string\", regex : '\"\"\"', next : \"start\"},\n                        {token : \"paren.string\", regex : '#{', push : \"start\"},\n                        {token : \"constant.language.escape\", regex : stringEscape},\n                        {defaultToken: \"string\"}\n                    ]\n                }, {\n                    stateName: \"qstring\",\n                    token : \"string\", regex : \"'\", next : [\n                        {token : \"string\", regex : \"'\", next : \"start\"},\n                        {token : \"constant.language.escape\", regex : stringEscape},\n                        {defaultToken: \"string\"}\n                    ]\n                }, {\n                    stateName: \"qqstring\",\n                    token : \"string.start\", regex : '\"', next : [\n                        {token : \"string.end\", regex : '\"', next : \"start\"},\n                        {token : \"paren.string\", regex : '#{', push : \"start\"},\n                        {token : \"constant.language.escape\", regex : stringEscape},\n                        {defaultToken: \"string\"}\n                    ]\n                }, {\n                    stateName: \"js\",\n                    token : \"string\", regex : \"`\", next : [\n                        {token : \"string\", regex : \"`\", next : \"start\"},\n                        {token : \"constant.language.escape\", regex : stringEscape},\n                        {defaultToken: \"string\"}\n                    ]\n                }, {\n                    regex: \"[{}]\", onMatch: function(val, state, stack) {\n                        this.next = \"\";\n                        if (val == \"{\" && stack.length) {\n                            stack.unshift(\"start\", state);\n                            return \"paren\";\n                        }\n                        if (val == \"}\" && stack.length) {\n                            stack.shift();\n                            this.next = stack.shift() || \"\";\n                            if (this.next.indexOf(\"string\") != -1)\n                                return \"paren.string\";\n                        }\n                        return \"paren\";\n                    }\n                }, {\n                    token : \"string.regex\",\n                    regex : \"///\",\n                    next : \"heregex\"\n                }, {\n                    token : \"string.regex\",\n                    regex : /(?:\\/(?![\\s=])[^[\\/\\n\\\\]*(?:(?:\\\\[\\s\\S]|\\[[^\\]\\n\\\\]*(?:\\\\[\\s\\S][^\\]\\n\\\\]*)*])[^[\\/\\n\\\\]*)*\\/)(?:[imgy]{0,4})(?!\\w)/\n                }, {\n                    token : \"comment\",\n                    regex : \"###(?!#)\",\n                    next : \"comment\"\n                }, {\n                    token : \"comment\",\n                    regex : \"#.*\"\n                }, {\n                    token : [\"punctuation.operator\", \"text\", \"identifier\"],\n                    regex : \"(\\\\.)(\\\\s*)(\" + illegal + \")\"\n                }, {\n                    token : \"punctuation.operator\",\n                    regex : \"\\\\.{1,3}\"\n                }, {\n                    //class A extends B\n                    token : [\"keyword\", \"text\", \"language.support.class\",\n                     \"text\", \"keyword\", \"text\", \"language.support.class\"],\n                    regex : \"(class)(\\\\s+)(\" + identifier + \")(?:(\\\\s+)(extends)(\\\\s+)(\" + identifier + \"))?\"\n                }, {\n                    //play = (...) ->\n                    token : [\"entity.name.function\", \"text\", \"keyword.operator\", \"text\"].concat(functionRule.token),\n                    regex : \"(\" + identifier + \")(\\\\s*)([=:])(\\\\s*)\" + functionRule.regex\n                }, \n                functionRule, \n                {\n                    token : \"variable\",\n                    regex : \"@(?:\" + identifier + \")?\"\n                }, {\n                    token: keywordMapper,\n                    regex : identifier\n                }, {\n                    token : \"punctuation.operator\",\n                    regex : \"\\\\,|\\\\.\"\n                }, {\n                    token : \"storage.type\",\n                    regex : \"[\\\\-=]>\"\n                }, {\n                    token : \"keyword.operator\",\n                    regex : \"(?:[-+*/%<>&|^!?=]=|>>>=?|\\\\-\\\\-|\\\\+\\\\+|::|&&=|\\\\|\\\\|=|<<=|>>=|\\\\?\\\\.|\\\\.{2,3}|[!*+-=><])\"\n                }, {\n                    token : \"paren.lparen\",\n                    regex : \"[({[]\"\n                }, {\n                    token : \"paren.rparen\",\n                    regex : \"[\\\\]})]\"\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }],\n\n\n            heregex : [{\n                token : \"string.regex\",\n                regex : '.*?///[imgy]{0,4}',\n                next : \"start\"\n            }, {\n                token : \"comment.regex\",\n                regex : \"\\\\s+(?:#.*)?\"\n            }, {\n                token : \"string.regex\",\n                regex : \"\\\\S+\"\n            }],\n\n            comment : [{\n                token : \"comment\",\n                regex : '###',\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }]\n        };\n        this.normalizeRules();\n    }\n\n    exports.CoffeeHighlightRules = CoffeeHighlightRules;\n"
  },
  {
    "path": "src/mode/coldfusion.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar HtmlMode = require(\"./html\").Mode;\nvar ColdfusionHighlightRules = require(\"./coldfusion_highlight_rules\").ColdfusionHighlightRules;\n\nvar voidElements = \"cfabort|cfapplication|cfargument|cfassociate|cfbreak|cfcache|cfcollection|cfcookie|cfdbinfo|cfdirectory|cfdump|cfelse|cfelseif|cferror|cfexchangecalendar|cfexchangeconnection|cfexchangecontact|cfexchangefilter|cfexchangetask|cfexit|cffeed|cffile|cfflush|cfftp|cfheader|cfhtmlhead|cfhttpparam|cfimage|cfimport|cfinclude|cfindex|cfinsert|cfinvokeargument|cflocation|cflog|cfmailparam|cfNTauthenticate|cfobject|cfobjectcache|cfparam|cfpdfformparam|cfprint|cfprocparam|cfprocresult|cfproperty|cfqueryparam|cfregistry|cfreportparam|cfrethrow|cfreturn|cfschedule|cfsearch|cfset|cfsetting|cfthrow|cfzipparam)\".split(\"|\");\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    \n    this.HighlightRules = ColdfusionHighlightRules;\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n\n    // mix with html void elements\n    this.voidElements = oop.mixin(lang.arrayToMap(voidElements), this.voidElements);\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n\n    this.$id = \"ace/mode/coldfusion\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/coldfusion_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar ColdfusionHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    this.$rules.tag[2].token = function (start, tag) {\n        var group = tag.slice(0,2) == \"cf\" ? \"keyword\" : \"meta.tag\";\n        return [\"meta.tag.punctuation.\" + (start == \"<\" ? \"\" : \"end-\") + \"tag-open.xml\",\n            group + \".tag-name.xml\"];\n    };\n\n    var jsAndCss = Object.keys(this.$rules).filter(function(x) {\n        return /^(js|css)-/.test(x);\n    });\n    this.embedRules({\n        cfmlComment: [\n            { regex: \"<!---\", token: \"comment.start\", push: \"cfmlComment\"}, \n            { regex: \"--->\", token: \"comment.end\", next: \"pop\"},\n            { defaultToken: \"comment\"}\n        ]\n    }, \"\", [\n        { regex: \"<!---\", token: \"comment.start\", push: \"cfmlComment\"}\n    ], [\n        \"comment\", \"start\", \"tag_whitespace\", \"cdata\"\n    ].concat(jsAndCss));\n    \n    \n    this.$rules.cfTag = [\n        {include : \"attributes\"},\n        {token : \"meta.tag.punctuation.tag-close.xml\", regex : \"/?>\", next : \"pop\"}\n    ];\n    var cfTag = {\n        token : function(start, tag) {\n            return [\"meta.tag.punctuation.\" + (start == \"<\" ? \"\" : \"end-\") + \"tag-open.xml\",\n                \"keyword.tag-name.xml\"];\n        },\n        regex : \"(</?)(cf[-_a-zA-Z0-9:.]+)\",\n        push: \"cfTag\"\n    };\n    jsAndCss.forEach(function(s) {\n        this.$rules[s].unshift(cfTag);\n    }, this);\n    \n    this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), \"cfjs-\", \"cfscript\");\n\n    this.normalizeRules();\n};\n\noop.inherits(ColdfusionHighlightRules, HtmlHighlightRules);\n\nexports.ColdfusionHighlightRules = ColdfusionHighlightRules;\n"
  },
  {
    "path": "src/mode/coldfusion_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Range = require(\"../range\").Range;\nvar ColdfusionMode = require(\"./coldfusion\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {    \n        this.mode = new ColdfusionMode();\n    },\n\n    \"test: toggle comment lines\" : function() {\n        var session = new EditSession([\"  abc\", \"  cde\", \"fg\"]);\n\n        var range = new Range(0, 3, 1, 1);\n        var comment = this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"  <!--abc-->\", \"  <!--cde-->\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: next line indent should be the same as the current line indent\" : function() {\n        assert.equal(\"     \", this.mode.getNextLineIndent(\"start\", \"     abc\"));\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"abc\"));\n        assert.equal(\"\\t\", this.mode.getNextLineIndent(\"start\", \"\\tabc\"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/crystal.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CrystalHighlightRules = require(\"./crystal_highlight_rules\").CrystalHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar Range = require(\"../range\").Range;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = CrystalHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n\n    this.lineCommentStart = \"#\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            var startingClassOrMethod = line.match(/^\\s*(class|def|module)\\s.*$/);\n            var startingDoBlock = line.match(/.*do(\\s*|\\s+\\|.*\\|\\s*)$/);\n            var startingConditional = line.match(/^\\s*(if|else|when)\\s*/);\n            if (match || startingClassOrMethod || startingDoBlock || startingConditional) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return /^\\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, session, row) {\n        var line = session.getLine(row);\n        if (/}/.test(line))\n            return this.$outdent.autoOutdent(session, row);\n        var indent = this.$getIndent(line);\n        var prevLine = session.getLine(row - 1);\n        var prevIndent = this.$getIndent(prevLine);\n        var tab = session.getTabString();\n        if (prevIndent.length <= indent.length) {\n            if (indent.slice(-tab.length) == tab)\n                session.remove(new Range(row, indent.length-tab.length, row, indent.length));\n        }\n    };\n\n    this.$id = \"ace/mode/crystal\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/crystal_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var CrystalHighlightRules = function () {\n\n        var builtinFunctions = (\n            \"puts|initialize|previous_def|typeof|as|pointerof|sizeof|instance_sizeof\"\n        );\n\n        var keywords = (\n            \"if|end|else|elsif|unless|case|when|break|while|next|until|def|return|class|new|getter|setter|property|lib\"\n            + \"|fun|do|struct|private|protected|public|module|super|abstract|include|extend|begin|enum|raise|yield|with\"\n            + \"|alias|rescue|ensure|macro|uninitialized|union|type|require\"\n        );\n\n        var buildinConstants = (\n            \"true|TRUE|false|FALSE|nil|NIL|__LINE__|__END_LINE__|__FILE__|__DIR__\"\n        );\n\n        var builtinVariables = (\n            \"$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|\" +\n            \"root_url|flash|session|cookies|params|request|response|logger|self\"\n        );\n\n        var keywordMapper = this.$keywords = this.createKeywordMapper({\n            \"keyword\": keywords,\n            \"constant.language\": buildinConstants,\n            \"variable.language\": builtinVariables,\n            \"support.function\": builtinFunctions\n        }, \"identifier\");\n\n        var hexNumber = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n        var decNumber = \"(?:[0-9][\\\\d_]*)\";\n        var octNumber = \"(?:0o[0-7][0-7]*)\";\n        var binNumber = \"(?:0[bB][01]+)\";\n        var intNumber = \"(?:[+-]?)(?:\" + hexNumber + \"|\" + decNumber + \"|\" + octNumber + \"|\" + binNumber + \")(?:_?[iIuU](?:8|16|32|64))?\\\\b\";\n        var escapeExpression = /\\\\(?:[nsrtvfbae'\"\\\\]|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}})/;\n        var extEscapeExspresssion = /\\\\(?:[nsrtvfbae'\"\\\\]|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}}|u{(:?[\\da-fA-F]{2}\\s)*[\\da-fA-F]{2}})/;\n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n\n        this.$rules = {\n            \"start\": [\n                {\n                    token: \"comment\",\n                    regex: \"#.*$\"\n                }, {\n                    token: \"string.regexp\",\n                    regex: \"[/]\",\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.regexp\",\n                        regex: \"[/][imx]*(?=[).,;\\\\s]|$)\",\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string.regexp\"\n                    }]\n                },\n                [{\n                    regex: \"[{}]\", onMatch: function (val, state, stack) {\n                        this.next = val == \"{\" ? this.nextState : \"\";\n                        if (val == \"{\" && stack.length) {\n                            stack.unshift(\"start\", state);\n                            return \"paren.lparen\";\n                        }\n                        if (val == \"}\" && stack.length) {\n                            stack.shift();\n                            this.next = stack.shift();\n                            if (this.next.indexOf(\"string\") != -1)\n                                return \"paren.end\";\n                        }\n                        return val == \"{\" ? \"paren.lparen\" : \"paren.rparen\";\n                    },\n                    nextState: \"start\"\n                }, {\n                    token: \"string.start\",\n                    regex: /\"/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string\",\n                        regex: /\\\\#{/\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /\"/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    token: \"string.start\",\n                    regex: /`/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string\",\n                        regex: /\\\\#{/\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /`/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"rpstring\",\n                    token: \"string.start\",\n                    regex: /%[Qx]?\\(/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.start\",\n                        regex: /\\(/,\n                        push: \"rpstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"spstring\",\n                    token: \"string.start\",\n                    regex: /%[Qx]?\\[/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.start\",\n                        regex: /\\[/,\n                        push: \"spstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /]/,\n                        next: \"pop\"\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"fpstring\",\n                    token: \"string.start\",\n                    regex: /%[Qx]?{/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.start\",\n                        regex: /{/,\n                        push: \"fpstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /}/,\n                        next: \"pop\"\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"tpstring\",\n                    token: \"string.start\",\n                    regex: /%[Qx]?</,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.start\",\n                        regex: /</,\n                        push: \"tpstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: />/,\n                        next: \"pop\"\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"ppstring\",\n                    token: \"string.start\",\n                    regex: /%[Qx]?\\|/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"string.end\",\n                        regex: /\\|/,\n                        next: \"pop\"\n                    }, {\n                        token: \"paren.start\",\n                        regex: /#{/,\n                        push: \"start\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"rpqstring\",\n                    token: \"string.start\",\n                    regex: /%[qwir]\\(/,\n                    push: [{\n                        token: \"string.start\",\n                        regex: /\\(/,\n                        push: \"rpqstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"spqstring\",\n                    token: \"string.start\",\n                    regex: /%[qwir]\\[/,\n                    push: [{\n                        token: \"string.start\",\n                        regex: /\\[/,\n                        push: \"spqstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /]/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"fpqstring\",\n                    token: \"string.start\",\n                    regex: /%[qwir]{/,\n                    push: [{\n                        token: \"string.start\",\n                        regex: /{/,\n                        push: \"fpqstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: /}/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"tpqstring\",\n                    token: \"string.start\",\n                    regex: /%[qwir]</,\n                    push: [{\n                        token: \"string.start\",\n                        regex: /</,\n                        push: \"tpqstring\"\n                    }, {\n                        token: \"string.end\",\n                        regex: />/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    stateName: \"ppqstring\",\n                    token: \"string.start\",\n                    regex: /%[qwir]\\|/,\n                    push: [{\n                        token: \"string.end\",\n                        regex: /\\|/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }, {\n                    token: \"string.start\",\n                    regex: /'/,\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: escapeExpression\n                    }, {\n                        token: \"string.end\",\n                        regex: /'|$/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }]\n                }], {\n                    token: \"text\", // namespaces aren't symbols\n                    regex: \"::\"\n                }, {\n                    token: \"variable.instance\", // instance variable\n                    regex: \"@{1,2}[a-zA-Z_\\\\d]+\"\n                }, {\n                    token: \"variable.fresh\", // fresh variable\n                    regex: \"%[a-zA-Z_\\\\d]+\"\n                }, {\n                    token: \"support.class\", // class name\n                    regex: \"[A-Z][a-zA-Z_\\\\d]+\"\n                }, {\n                    token: \"constant.other.symbol\", // symbol\n                    regex: \"[:](?:(?:===|<=>|\\\\[]\\\\?|\\\\[]=|\\\\[]|>>|\\\\*\\\\*|<<|==|!=|>=|<=|!~|=~|<|\\\\+|-|\\\\*|\\\\/|%|&|\\\\||\\\\^|>|!|~)|(?:(?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?))\"\n                }, {\n                    token: \"constant.numeric\", // float\n                    regex: \"[+-]?\\\\d(?:\\\\d|_(?=\\\\d))*(?:(?:\\\\.\\\\d(?:\\\\d|_(?=\\\\d))*)?(?:[eE][+-]?\\\\d+)?)?(?:_?[fF](?:32|64))?\\\\b\"\n                }, {\n                    token: \"constant.numeric\",\n                    regex: intNumber\n                }, {\n                    token: \"constant.other.symbol\",\n                    regex: ':\"',\n                    push: [{\n                        token: \"constant.language.escape\",\n                        regex: extEscapeExspresssion\n                    }, {\n                        token: \"constant.other.symbol\",\n                        regex: '\"',\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"constant.other.symbol\"\n                    }]\n                }, {\n                    token: \"constant.language.boolean\",\n                    regex: \"(?:true|false)\\\\b\"\n                }, {\n                    token: \"support.function\",\n                    regex: \"(?:is_a\\\\?|nil\\\\?|responds_to\\\\?|as\\\\?)\"\n                }, {\n                    token: keywordMapper,\n                    regex: \"[a-zA-Z_$][a-zA-Z0-9_$!?]*\\\\b\"\n                }, {\n                    token: \"variable.system\",\n                    regex: \"\\\\$\\\\!|\\\\$\\\\?\"\n                }, {\n                    token: \"punctuation.separator.key-value\",\n                    regex: \"=>\"\n                }, {\n                    stateName: \"heredoc\",\n                    onMatch: function (value, currentState, stack) {\n                        var next = \"heredoc\";\n                        var tokens = value.split(this.splitRegex);\n                        stack.push(next, tokens[3]);\n                        return [\n                            {type: \"constant\", value: tokens[1]},\n                            {type: \"string\", value: tokens[2]},\n                            {type: \"support.class\", value: tokens[3]},\n                            {type: \"string\", value: tokens[4]}\n                        ];\n                    },\n                    regex: \"(<<-)([']?)([\\\\w]+)([']?)\",\n                    rules: {\n                        heredoc: [{\n                            token: \"string\",\n                            regex: \"^ +\"\n                        }, {\n                            onMatch: function (value, currentState, stack) {\n                                if (value === stack[1]) {\n                                    stack.shift();\n                                    stack.shift();\n                                    this.next = stack[0] || \"start\";\n                                    return \"support.class\";\n                                }\n                                this.next = \"\";\n                                return \"string\";\n                            },\n                            regex: \".*$\",\n                            next: \"start\"\n                        }]\n                    }\n                }, {\n                    regex: \"$\",\n                    token: \"empty\",\n                    next: function (currentState, stack) {\n                        if (stack[0] === \"heredoc\")\n                            return stack[0];\n                        return currentState;\n                    }\n                }, {\n                    token: \"punctuation.operator\",\n                    regex: /[.]\\s*(?![.])/,\n                    push: [{\n                        token : \"punctuation.operator\",\n                        regex : /[.]\\s*(?![.])/\n                    }, {\n                        token : \"support.function\",\n                        regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                    }, {\n                        regex: \"\",\n                        token: \"empty\",\n                        next: \"pop\"\n                    }]\n                }, {\n                    token: \"keyword.operator\",\n                    regex: \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|\\\\?|\\\\:|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\^|\\\\|\"\n                }, {\n                    token: \"punctuation.operator\",\n                    regex: /[?:,;.]/\n                }, {\n                    token: \"paren.lparen\",\n                    regex: \"[[({]\"\n                }, {\n                    token: \"paren.rparen\",\n                    regex: \"[\\\\])}]\"\n                }, {\n                    token: \"text\",\n                    regex: \"\\\\s+\"\n                }\n            ]\n        };\n\n        this.normalizeRules();\n    };\n\n    oop.inherits(CrystalHighlightRules, TextHighlightRules);\n\n    exports.CrystalHighlightRules = CrystalHighlightRules;\n"
  },
  {
    "path": "src/mode/csharp.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CSharpHighlightRules = require(\"./csharp_highlight_rules\").CSharpHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/csharp\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = CSharpHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    \n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n  \n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n  \n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n    \n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n  \n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n  \n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/csharp\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/csharp_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar CSharpHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": \"abstract|async|await|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|partial|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic\",\n        \"constant.language\": \"null|true|false\"\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // character\n                regex : /'(?:.|\\\\(:?u[\\da-fA-F]+|x[\\da-fA-F]+|[tbrf'\"n]))?'/\n            }, {\n                token : \"string\", start : '\"', end : '\"|$', next: [\n                    {token: \"constant.language.escape\", regex: /\\\\(:?u[\\da-fA-F]+|x[\\da-fA-F]+|[tbrf'\"n])/},\n                    {token: \"invalid\", regex: /\\\\./}\n                ]\n            }, {\n                token : \"string\", start : '@\"', end : '\"', next:[\n                    {token: \"constant.language.escape\", regex: '\"\"'}\n                ]\n            }, {\n                token : \"string\", start : /\\$\"/, end : '\"|$', next: [\n                    {token: \"constant.language.escape\", regex: /\\\\(:?$)|{{/},\n                    {token: \"constant.language.escape\", regex: /\\\\(:?u[\\da-fA-F]+|x[\\da-fA-F]+|[tbrf'\"n])/},\n                    {token: \"invalid\", regex: /\\\\./}\n                ]\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token : \"keyword\",\n                regex : \"^\\\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.normalizeRules();\n};\n\noop.inherits(CSharpHighlightRules, TextHighlightRules);\n\nexports.CSharpHighlightRules = CSharpHighlightRules;\n"
  },
  {
    "path": "src/mode/csound_document.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CsoundDocumentHighlightRules = require(\"./csound_document_highlight_rules\").CsoundDocumentHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = CsoundDocumentHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/csound_document\";\n    this.snippetFileId = \"ace/snippets/csound_document\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/csound_document_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n\nvar CsoundOrchestraHighlightRules = require(\"./csound_orchestra_highlight_rules\").CsoundOrchestraHighlightRules;\nvar CsoundScoreHighlightRules = require(\"./csound_score_highlight_rules\").CsoundScoreHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar CsoundDocumentHighlightRules = function() {\n\n    var orchestraHighlightRules = new CsoundOrchestraHighlightRules(\"csound-\");\n    var scoreHighlightRules = new CsoundScoreHighlightRules(\"csound-score-\");\n\n    this.$rules = {\n        \"start\": [\n            {\n                token : [\"meta.tag.punctuation.tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n                regex : /(<)(CsoundSynthesi[sz]er)(>)/,\n                next  : \"synthesizer\"\n            },\n            {defaultToken : \"text.csound-document\"}\n        ],\n\n        \"synthesizer\": [\n            {\n                token : [\"meta.tag.punctuation.end-tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n                regex : \"(</)(CsoundSynthesi[sz]er)(>)\",\n                next  : \"start\"\n            }, {\n                token : [\"meta.tag.punctuation.tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n                regex : \"(<)(CsInstruments)(>)\",\n                next  : orchestraHighlightRules.embeddedRulePrefix + \"start\"\n            }, {\n                token : [\"meta.tag.punctuation.tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n                regex : \"(<)(CsScore)(>)\",\n                next  : scoreHighlightRules.embeddedRulePrefix + \"start\"\n            }, {\n                token : [\"meta.tag.punctuation.tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n                regex : \"(<)([Hh][Tt][Mm][Ll])(>)\",\n                next  : \"html-start\"\n            }\n        ]\n    };\n\n    this.embedRules(orchestraHighlightRules.getRules(), orchestraHighlightRules.embeddedRulePrefix, [{\n        token : [\"meta.tag.punctuation.end-tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n        regex : \"(</)(CsInstruments)(>)\",\n        next  : \"synthesizer\"\n    }]);\n    this.embedRules(scoreHighlightRules.getRules(), scoreHighlightRules.embeddedRulePrefix, [{\n        token : [\"meta.tag.punctuation.end-tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n        regex : \"(</)(CsScore)(>)\",\n        next  : \"synthesizer\"\n    }]);\n    this.embedRules(HtmlHighlightRules, \"html-\", [{\n        token : [\"meta.tag.punctuation.end-tag-open.csound-document\", \"entity.name.tag.begin.csound-document\", \"meta.tag.punctuation.tag-close.csound-document\"],\n        regex : \"(</)([Hh][Tt][Mm][Ll])(>)\",\n        next  : \"synthesizer\"\n    }]);\n\n    this.normalizeRules();\n};\n\noop.inherits(CsoundDocumentHighlightRules, TextHighlightRules);\n\nexports.CsoundDocumentHighlightRules = CsoundDocumentHighlightRules;\n"
  },
  {
    "path": "src/mode/csound_orchestra.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CsoundOrchestraHighlightRules = require(\"./csound_orchestra_highlight_rules\").CsoundOrchestraHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = CsoundOrchestraHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \";\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/csound_orchestra\";\n    this.snippetFileId = \"ace/snippets/csound_orchestra\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/csound_orchestra_highlight_rules.js",
    "content": "\"use strict\";\n\nvar lang = require(\"../lib/lang\");\nvar oop = require(\"../lib/oop\");\n\nvar CsoundPreprocessorHighlightRules = require(\"./csound_preprocessor_highlight_rules\").CsoundPreprocessorHighlightRules;\nvar CsoundScoreHighlightRules = require(\"./csound_score_highlight_rules\").CsoundScoreHighlightRules;\nvar LuaHighlightRules = require(\"./lua_highlight_rules\").LuaHighlightRules;\nvar PythonHighlightRules = require(\"./python_highlight_rules\").PythonHighlightRules;\n\nvar CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {\n\n    CsoundPreprocessorHighlightRules.call(this, embeddedRulePrefix);\n\n    // To update the opcodes and deprecatedOpcodes arrays, run\n    /*\n      curl --remote-name --show-error --silent https://raw.githubusercontent.com/pygments/pygments/master/pygments/lexers/_csound_builtins.py\n      python -c \"import json; from _csound_builtins import OPCODES, DEPRECATED_OPCODES, REMOVED_OPCODES; print('var opcodes = {};'.format(json.dumps(sorted(list(OPCODES)), indent=4))); print('var deprecatedOpcodes = {};'.format(json.dumps(sorted(list(DEPRECATED_OPCODES.union(REMOVED_OPCODES))), indent=4)))\"\n    */\n    // and then paste the output.\n    var opcodes = [\n        \"ATSadd\",\n        \"ATSaddnz\",\n        \"ATSbufread\",\n        \"ATScross\",\n        \"ATSinfo\",\n        \"ATSinterpread\",\n        \"ATSpartialtap\",\n        \"ATSread\",\n        \"ATSreadnz\",\n        \"ATSsinnoi\",\n        \"FLbox\",\n        \"FLbutBank\",\n        \"FLbutton\",\n        \"FLcloseButton\",\n        \"FLcolor\",\n        \"FLcolor2\",\n        \"FLcount\",\n        \"FLexecButton\",\n        \"FLgetsnap\",\n        \"FLgroup\",\n        \"FLgroupEnd\",\n        \"FLgroup_end\",\n        \"FLhide\",\n        \"FLhvsBox\",\n        \"FLhvsBoxSetValue\",\n        \"FLjoy\",\n        \"FLkeyIn\",\n        \"FLknob\",\n        \"FLlabel\",\n        \"FLloadsnap\",\n        \"FLmouse\",\n        \"FLpack\",\n        \"FLpackEnd\",\n        \"FLpack_end\",\n        \"FLpanel\",\n        \"FLpanelEnd\",\n        \"FLpanel_end\",\n        \"FLprintk\",\n        \"FLprintk2\",\n        \"FLroller\",\n        \"FLrun\",\n        \"FLsavesnap\",\n        \"FLscroll\",\n        \"FLscrollEnd\",\n        \"FLscroll_end\",\n        \"FLsetAlign\",\n        \"FLsetBox\",\n        \"FLsetColor\",\n        \"FLsetColor2\",\n        \"FLsetFont\",\n        \"FLsetPosition\",\n        \"FLsetSize\",\n        \"FLsetSnapGroup\",\n        \"FLsetText\",\n        \"FLsetTextColor\",\n        \"FLsetTextSize\",\n        \"FLsetTextType\",\n        \"FLsetVal\",\n        \"FLsetVal_i\",\n        \"FLsetVali\",\n        \"FLsetsnap\",\n        \"FLshow\",\n        \"FLslidBnk\",\n        \"FLslidBnk2\",\n        \"FLslidBnk2Set\",\n        \"FLslidBnk2Setk\",\n        \"FLslidBnkGetHandle\",\n        \"FLslidBnkSet\",\n        \"FLslidBnkSetk\",\n        \"FLslider\",\n        \"FLtabs\",\n        \"FLtabsEnd\",\n        \"FLtabs_end\",\n        \"FLtext\",\n        \"FLupdate\",\n        \"FLvalue\",\n        \"FLvkeybd\",\n        \"FLvslidBnk\",\n        \"FLvslidBnk2\",\n        \"FLxyin\",\n        \"JackoAudioIn\",\n        \"JackoAudioInConnect\",\n        \"JackoAudioOut\",\n        \"JackoAudioOutConnect\",\n        \"JackoFreewheel\",\n        \"JackoInfo\",\n        \"JackoInit\",\n        \"JackoMidiInConnect\",\n        \"JackoMidiOut\",\n        \"JackoMidiOutConnect\",\n        \"JackoNoteOut\",\n        \"JackoOn\",\n        \"JackoTransport\",\n        \"K35_hpf\",\n        \"K35_lpf\",\n        \"MixerClear\",\n        \"MixerGetLevel\",\n        \"MixerReceive\",\n        \"MixerSend\",\n        \"MixerSetLevel\",\n        \"MixerSetLevel_i\",\n        \"OSCbundle\",\n        \"OSCcount\",\n        \"OSCinit\",\n        \"OSCinitM\",\n        \"OSClisten\",\n        \"OSCraw\",\n        \"OSCsend\",\n        \"OSCsend_lo\",\n        \"S\",\n        \"STKBandedWG\",\n        \"STKBeeThree\",\n        \"STKBlowBotl\",\n        \"STKBlowHole\",\n        \"STKBowed\",\n        \"STKBrass\",\n        \"STKClarinet\",\n        \"STKDrummer\",\n        \"STKFMVoices\",\n        \"STKFlute\",\n        \"STKHevyMetl\",\n        \"STKMandolin\",\n        \"STKModalBar\",\n        \"STKMoog\",\n        \"STKPercFlut\",\n        \"STKPlucked\",\n        \"STKResonate\",\n        \"STKRhodey\",\n        \"STKSaxofony\",\n        \"STKShakers\",\n        \"STKSimple\",\n        \"STKSitar\",\n        \"STKStifKarp\",\n        \"STKTubeBell\",\n        \"STKVoicForm\",\n        \"STKWhistle\",\n        \"STKWurley\",\n        \"a\",\n        \"abs\",\n        \"active\",\n        \"adsr\",\n        \"adsyn\",\n        \"adsynt\",\n        \"adsynt2\",\n        \"aftouch\",\n        \"allpole\",\n        \"alpass\",\n        \"alwayson\",\n        \"ampdb\",\n        \"ampdbfs\",\n        \"ampmidi\",\n        \"ampmidicurve\",\n        \"ampmidid\",\n        \"apoleparams\",\n        \"arduinoRead\",\n        \"arduinoReadF\",\n        \"arduinoStart\",\n        \"arduinoStop\",\n        \"areson\",\n        \"aresonk\",\n        \"atone\",\n        \"atonek\",\n        \"atonex\",\n        \"autocorr\",\n        \"babo\",\n        \"balance\",\n        \"balance2\",\n        \"bamboo\",\n        \"barmodel\",\n        \"bbcutm\",\n        \"bbcuts\",\n        \"betarand\",\n        \"bexprnd\",\n        \"bformdec1\",\n        \"bformdec2\",\n        \"bformenc1\",\n        \"binit\",\n        \"biquad\",\n        \"biquada\",\n        \"birnd\",\n        \"bob\",\n        \"bpf\",\n        \"bpfcos\",\n        \"bqrez\",\n        \"butbp\",\n        \"butbr\",\n        \"buthp\",\n        \"butlp\",\n        \"butterbp\",\n        \"butterbr\",\n        \"butterhp\",\n        \"butterlp\",\n        \"button\",\n        \"buzz\",\n        \"c2r\",\n        \"cabasa\",\n        \"cauchy\",\n        \"cauchyi\",\n        \"cbrt\",\n        \"ceil\",\n        \"cell\",\n        \"cent\",\n        \"centroid\",\n        \"ceps\",\n        \"cepsinv\",\n        \"chanctrl\",\n        \"changed\",\n        \"changed2\",\n        \"chani\",\n        \"chano\",\n        \"chebyshevpoly\",\n        \"checkbox\",\n        \"chn_S\",\n        \"chn_a\",\n        \"chn_k\",\n        \"chnclear\",\n        \"chnexport\",\n        \"chnget\",\n        \"chngeta\",\n        \"chngeti\",\n        \"chngetk\",\n        \"chngetks\",\n        \"chngets\",\n        \"chnmix\",\n        \"chnparams\",\n        \"chnset\",\n        \"chnseta\",\n        \"chnseti\",\n        \"chnsetk\",\n        \"chnsetks\",\n        \"chnsets\",\n        \"chuap\",\n        \"clear\",\n        \"clfilt\",\n        \"clip\",\n        \"clockoff\",\n        \"clockon\",\n        \"cmp\",\n        \"cmplxprod\",\n        \"cntCreate\",\n        \"cntCycles\",\n        \"cntDelete\",\n        \"cntDelete_i\",\n        \"cntRead\",\n        \"cntReset\",\n        \"cntState\",\n        \"comb\",\n        \"combinv\",\n        \"compilecsd\",\n        \"compileorc\",\n        \"compilestr\",\n        \"compress\",\n        \"compress2\",\n        \"connect\",\n        \"control\",\n        \"convle\",\n        \"convolve\",\n        \"copya2ftab\",\n        \"copyf2array\",\n        \"cos\",\n        \"cosh\",\n        \"cosinv\",\n        \"cosseg\",\n        \"cossegb\",\n        \"cossegr\",\n        \"count\",\n        \"count_i\",\n        \"cps2pch\",\n        \"cpsmidi\",\n        \"cpsmidib\",\n        \"cpsmidinn\",\n        \"cpsoct\",\n        \"cpspch\",\n        \"cpstmid\",\n        \"cpstun\",\n        \"cpstuni\",\n        \"cpsxpch\",\n        \"cpumeter\",\n        \"cpuprc\",\n        \"cross2\",\n        \"crossfm\",\n        \"crossfmi\",\n        \"crossfmpm\",\n        \"crossfmpmi\",\n        \"crosspm\",\n        \"crosspmi\",\n        \"crunch\",\n        \"ctlchn\",\n        \"ctrl14\",\n        \"ctrl21\",\n        \"ctrl7\",\n        \"ctrlinit\",\n        \"ctrlpreset\",\n        \"ctrlprint\",\n        \"ctrlprintpresets\",\n        \"ctrlsave\",\n        \"ctrlselect\",\n        \"cuserrnd\",\n        \"dam\",\n        \"date\",\n        \"dates\",\n        \"db\",\n        \"dbamp\",\n        \"dbfsamp\",\n        \"dcblock\",\n        \"dcblock2\",\n        \"dconv\",\n        \"dct\",\n        \"dctinv\",\n        \"deinterleave\",\n        \"delay\",\n        \"delay1\",\n        \"delayk\",\n        \"delayr\",\n        \"delayw\",\n        \"deltap\",\n        \"deltap3\",\n        \"deltapi\",\n        \"deltapn\",\n        \"deltapx\",\n        \"deltapxw\",\n        \"denorm\",\n        \"diff\",\n        \"diode_ladder\",\n        \"directory\",\n        \"diskgrain\",\n        \"diskin\",\n        \"diskin2\",\n        \"dispfft\",\n        \"display\",\n        \"distort\",\n        \"distort1\",\n        \"divz\",\n        \"doppler\",\n        \"dot\",\n        \"downsamp\",\n        \"dripwater\",\n        \"dssiactivate\",\n        \"dssiaudio\",\n        \"dssictls\",\n        \"dssiinit\",\n        \"dssilist\",\n        \"dumpk\",\n        \"dumpk2\",\n        \"dumpk3\",\n        \"dumpk4\",\n        \"duserrnd\",\n        \"dust\",\n        \"dust2\",\n        \"elapsedcycles\",\n        \"elapsedtime\",\n        \"envlpx\",\n        \"envlpxr\",\n        \"ephasor\",\n        \"eqfil\",\n        \"evalstr\",\n        \"event\",\n        \"event_i\",\n        \"eventcycles\",\n        \"eventtime\",\n        \"exciter\",\n        \"exitnow\",\n        \"exp\",\n        \"expcurve\",\n        \"expon\",\n        \"exprand\",\n        \"exprandi\",\n        \"expseg\",\n        \"expsega\",\n        \"expsegb\",\n        \"expsegba\",\n        \"expsegr\",\n        \"fareylen\",\n        \"fareyleni\",\n        \"faustaudio\",\n        \"faustcompile\",\n        \"faustctl\",\n        \"faustdsp\",\n        \"faustgen\",\n        \"faustplay\",\n        \"fft\",\n        \"fftinv\",\n        \"ficlose\",\n        \"filebit\",\n        \"filelen\",\n        \"filenchnls\",\n        \"filepeak\",\n        \"filescal\",\n        \"filesr\",\n        \"filevalid\",\n        \"fillarray\",\n        \"filter2\",\n        \"fin\",\n        \"fini\",\n        \"fink\",\n        \"fiopen\",\n        \"flanger\",\n        \"flashtxt\",\n        \"flooper\",\n        \"flooper2\",\n        \"floor\",\n        \"fluidAllOut\",\n        \"fluidCCi\",\n        \"fluidCCk\",\n        \"fluidControl\",\n        \"fluidEngine\",\n        \"fluidInfo\",\n        \"fluidLoad\",\n        \"fluidNote\",\n        \"fluidOut\",\n        \"fluidProgramSelect\",\n        \"fluidSetInterpMethod\",\n        \"fmanal\",\n        \"fmax\",\n        \"fmb3\",\n        \"fmbell\",\n        \"fmin\",\n        \"fmmetal\",\n        \"fmod\",\n        \"fmpercfl\",\n        \"fmrhode\",\n        \"fmvoice\",\n        \"fmwurlie\",\n        \"fof\",\n        \"fof2\",\n        \"fofilter\",\n        \"fog\",\n        \"fold\",\n        \"follow\",\n        \"follow2\",\n        \"foscil\",\n        \"foscili\",\n        \"fout\",\n        \"fouti\",\n        \"foutir\",\n        \"foutk\",\n        \"fprintks\",\n        \"fprints\",\n        \"frac\",\n        \"fractalnoise\",\n        \"framebuffer\",\n        \"freeverb\",\n        \"ftaudio\",\n        \"ftchnls\",\n        \"ftconv\",\n        \"ftcps\",\n        \"ftexists\",\n        \"ftfree\",\n        \"ftgen\",\n        \"ftgenonce\",\n        \"ftgentmp\",\n        \"ftlen\",\n        \"ftload\",\n        \"ftloadk\",\n        \"ftlptim\",\n        \"ftmorf\",\n        \"ftom\",\n        \"ftprint\",\n        \"ftresize\",\n        \"ftresizei\",\n        \"ftsamplebank\",\n        \"ftsave\",\n        \"ftsavek\",\n        \"ftset\",\n        \"ftslice\",\n        \"ftslicei\",\n        \"ftsr\",\n        \"gain\",\n        \"gainslider\",\n        \"gauss\",\n        \"gaussi\",\n        \"gausstrig\",\n        \"gbuzz\",\n        \"genarray\",\n        \"genarray_i\",\n        \"gendy\",\n        \"gendyc\",\n        \"gendyx\",\n        \"getcfg\",\n        \"getcol\",\n        \"getftargs\",\n        \"getrow\",\n        \"getseed\",\n        \"gogobel\",\n        \"grain\",\n        \"grain2\",\n        \"grain3\",\n        \"granule\",\n        \"gtadsr\",\n        \"gtf\",\n        \"guiro\",\n        \"harmon\",\n        \"harmon2\",\n        \"harmon3\",\n        \"harmon4\",\n        \"hdf5read\",\n        \"hdf5write\",\n        \"hilbert\",\n        \"hilbert2\",\n        \"hrtfearly\",\n        \"hrtfmove\",\n        \"hrtfmove2\",\n        \"hrtfreverb\",\n        \"hrtfstat\",\n        \"hsboscil\",\n        \"hvs1\",\n        \"hvs2\",\n        \"hvs3\",\n        \"hypot\",\n        \"i\",\n        \"ihold\",\n        \"imagecreate\",\n        \"imagefree\",\n        \"imagegetpixel\",\n        \"imageload\",\n        \"imagesave\",\n        \"imagesetpixel\",\n        \"imagesize\",\n        \"in\",\n        \"in32\",\n        \"inch\",\n        \"inh\",\n        \"init\",\n        \"initc14\",\n        \"initc21\",\n        \"initc7\",\n        \"inleta\",\n        \"inletf\",\n        \"inletk\",\n        \"inletkid\",\n        \"inletv\",\n        \"ino\",\n        \"inq\",\n        \"inrg\",\n        \"ins\",\n        \"insglobal\",\n        \"insremot\",\n        \"int\",\n        \"integ\",\n        \"interleave\",\n        \"interp\",\n        \"invalue\",\n        \"inx\",\n        \"inz\",\n        \"jacktransport\",\n        \"jitter\",\n        \"jitter2\",\n        \"joystick\",\n        \"jspline\",\n        \"k\",\n        \"la_i_add_mc\",\n        \"la_i_add_mr\",\n        \"la_i_add_vc\",\n        \"la_i_add_vr\",\n        \"la_i_assign_mc\",\n        \"la_i_assign_mr\",\n        \"la_i_assign_t\",\n        \"la_i_assign_vc\",\n        \"la_i_assign_vr\",\n        \"la_i_conjugate_mc\",\n        \"la_i_conjugate_mr\",\n        \"la_i_conjugate_vc\",\n        \"la_i_conjugate_vr\",\n        \"la_i_distance_vc\",\n        \"la_i_distance_vr\",\n        \"la_i_divide_mc\",\n        \"la_i_divide_mr\",\n        \"la_i_divide_vc\",\n        \"la_i_divide_vr\",\n        \"la_i_dot_mc\",\n        \"la_i_dot_mc_vc\",\n        \"la_i_dot_mr\",\n        \"la_i_dot_mr_vr\",\n        \"la_i_dot_vc\",\n        \"la_i_dot_vr\",\n        \"la_i_get_mc\",\n        \"la_i_get_mr\",\n        \"la_i_get_vc\",\n        \"la_i_get_vr\",\n        \"la_i_invert_mc\",\n        \"la_i_invert_mr\",\n        \"la_i_lower_solve_mc\",\n        \"la_i_lower_solve_mr\",\n        \"la_i_lu_det_mc\",\n        \"la_i_lu_det_mr\",\n        \"la_i_lu_factor_mc\",\n        \"la_i_lu_factor_mr\",\n        \"la_i_lu_solve_mc\",\n        \"la_i_lu_solve_mr\",\n        \"la_i_mc_create\",\n        \"la_i_mc_set\",\n        \"la_i_mr_create\",\n        \"la_i_mr_set\",\n        \"la_i_multiply_mc\",\n        \"la_i_multiply_mr\",\n        \"la_i_multiply_vc\",\n        \"la_i_multiply_vr\",\n        \"la_i_norm1_mc\",\n        \"la_i_norm1_mr\",\n        \"la_i_norm1_vc\",\n        \"la_i_norm1_vr\",\n        \"la_i_norm_euclid_mc\",\n        \"la_i_norm_euclid_mr\",\n        \"la_i_norm_euclid_vc\",\n        \"la_i_norm_euclid_vr\",\n        \"la_i_norm_inf_mc\",\n        \"la_i_norm_inf_mr\",\n        \"la_i_norm_inf_vc\",\n        \"la_i_norm_inf_vr\",\n        \"la_i_norm_max_mc\",\n        \"la_i_norm_max_mr\",\n        \"la_i_print_mc\",\n        \"la_i_print_mr\",\n        \"la_i_print_vc\",\n        \"la_i_print_vr\",\n        \"la_i_qr_eigen_mc\",\n        \"la_i_qr_eigen_mr\",\n        \"la_i_qr_factor_mc\",\n        \"la_i_qr_factor_mr\",\n        \"la_i_qr_sym_eigen_mc\",\n        \"la_i_qr_sym_eigen_mr\",\n        \"la_i_random_mc\",\n        \"la_i_random_mr\",\n        \"la_i_random_vc\",\n        \"la_i_random_vr\",\n        \"la_i_size_mc\",\n        \"la_i_size_mr\",\n        \"la_i_size_vc\",\n        \"la_i_size_vr\",\n        \"la_i_subtract_mc\",\n        \"la_i_subtract_mr\",\n        \"la_i_subtract_vc\",\n        \"la_i_subtract_vr\",\n        \"la_i_t_assign\",\n        \"la_i_trace_mc\",\n        \"la_i_trace_mr\",\n        \"la_i_transpose_mc\",\n        \"la_i_transpose_mr\",\n        \"la_i_upper_solve_mc\",\n        \"la_i_upper_solve_mr\",\n        \"la_i_vc_create\",\n        \"la_i_vc_set\",\n        \"la_i_vr_create\",\n        \"la_i_vr_set\",\n        \"la_k_a_assign\",\n        \"la_k_add_mc\",\n        \"la_k_add_mr\",\n        \"la_k_add_vc\",\n        \"la_k_add_vr\",\n        \"la_k_assign_a\",\n        \"la_k_assign_f\",\n        \"la_k_assign_mc\",\n        \"la_k_assign_mr\",\n        \"la_k_assign_t\",\n        \"la_k_assign_vc\",\n        \"la_k_assign_vr\",\n        \"la_k_conjugate_mc\",\n        \"la_k_conjugate_mr\",\n        \"la_k_conjugate_vc\",\n        \"la_k_conjugate_vr\",\n        \"la_k_current_f\",\n        \"la_k_current_vr\",\n        \"la_k_distance_vc\",\n        \"la_k_distance_vr\",\n        \"la_k_divide_mc\",\n        \"la_k_divide_mr\",\n        \"la_k_divide_vc\",\n        \"la_k_divide_vr\",\n        \"la_k_dot_mc\",\n        \"la_k_dot_mc_vc\",\n        \"la_k_dot_mr\",\n        \"la_k_dot_mr_vr\",\n        \"la_k_dot_vc\",\n        \"la_k_dot_vr\",\n        \"la_k_f_assign\",\n        \"la_k_get_mc\",\n        \"la_k_get_mr\",\n        \"la_k_get_vc\",\n        \"la_k_get_vr\",\n        \"la_k_invert_mc\",\n        \"la_k_invert_mr\",\n        \"la_k_lower_solve_mc\",\n        \"la_k_lower_solve_mr\",\n        \"la_k_lu_det_mc\",\n        \"la_k_lu_det_mr\",\n        \"la_k_lu_factor_mc\",\n        \"la_k_lu_factor_mr\",\n        \"la_k_lu_solve_mc\",\n        \"la_k_lu_solve_mr\",\n        \"la_k_mc_set\",\n        \"la_k_mr_set\",\n        \"la_k_multiply_mc\",\n        \"la_k_multiply_mr\",\n        \"la_k_multiply_vc\",\n        \"la_k_multiply_vr\",\n        \"la_k_norm1_mc\",\n        \"la_k_norm1_mr\",\n        \"la_k_norm1_vc\",\n        \"la_k_norm1_vr\",\n        \"la_k_norm_euclid_mc\",\n        \"la_k_norm_euclid_mr\",\n        \"la_k_norm_euclid_vc\",\n        \"la_k_norm_euclid_vr\",\n        \"la_k_norm_inf_mc\",\n        \"la_k_norm_inf_mr\",\n        \"la_k_norm_inf_vc\",\n        \"la_k_norm_inf_vr\",\n        \"la_k_norm_max_mc\",\n        \"la_k_norm_max_mr\",\n        \"la_k_qr_eigen_mc\",\n        \"la_k_qr_eigen_mr\",\n        \"la_k_qr_factor_mc\",\n        \"la_k_qr_factor_mr\",\n        \"la_k_qr_sym_eigen_mc\",\n        \"la_k_qr_sym_eigen_mr\",\n        \"la_k_random_mc\",\n        \"la_k_random_mr\",\n        \"la_k_random_vc\",\n        \"la_k_random_vr\",\n        \"la_k_subtract_mc\",\n        \"la_k_subtract_mr\",\n        \"la_k_subtract_vc\",\n        \"la_k_subtract_vr\",\n        \"la_k_t_assign\",\n        \"la_k_trace_mc\",\n        \"la_k_trace_mr\",\n        \"la_k_upper_solve_mc\",\n        \"la_k_upper_solve_mr\",\n        \"la_k_vc_set\",\n        \"la_k_vr_set\",\n        \"lag\",\n        \"lagud\",\n        \"lastcycle\",\n        \"lenarray\",\n        \"lfo\",\n        \"lfsr\",\n        \"limit\",\n        \"limit1\",\n        \"lincos\",\n        \"line\",\n        \"linen\",\n        \"linenr\",\n        \"lineto\",\n        \"link_beat_force\",\n        \"link_beat_get\",\n        \"link_beat_request\",\n        \"link_create\",\n        \"link_enable\",\n        \"link_is_enabled\",\n        \"link_metro\",\n        \"link_peers\",\n        \"link_tempo_get\",\n        \"link_tempo_set\",\n        \"linlin\",\n        \"linrand\",\n        \"linseg\",\n        \"linsegb\",\n        \"linsegr\",\n        \"liveconv\",\n        \"locsend\",\n        \"locsig\",\n        \"log\",\n        \"log10\",\n        \"log2\",\n        \"logbtwo\",\n        \"logcurve\",\n        \"loopseg\",\n        \"loopsegp\",\n        \"looptseg\",\n        \"loopxseg\",\n        \"lorenz\",\n        \"loscil\",\n        \"loscil3\",\n        \"loscil3phs\",\n        \"loscilphs\",\n        \"loscilx\",\n        \"lowpass2\",\n        \"lowres\",\n        \"lowresx\",\n        \"lpcanal\",\n        \"lpcfilter\",\n        \"lpf18\",\n        \"lpform\",\n        \"lpfreson\",\n        \"lphasor\",\n        \"lpinterp\",\n        \"lposcil\",\n        \"lposcil3\",\n        \"lposcila\",\n        \"lposcilsa\",\n        \"lposcilsa2\",\n        \"lpread\",\n        \"lpreson\",\n        \"lpshold\",\n        \"lpsholdp\",\n        \"lpslot\",\n        \"lufs\",\n        \"mac\",\n        \"maca\",\n        \"madsr\",\n        \"mags\",\n        \"mandel\",\n        \"mandol\",\n        \"maparray\",\n        \"maparray_i\",\n        \"marimba\",\n        \"massign\",\n        \"max\",\n        \"max_k\",\n        \"maxabs\",\n        \"maxabsaccum\",\n        \"maxaccum\",\n        \"maxalloc\",\n        \"maxarray\",\n        \"mclock\",\n        \"mdelay\",\n        \"median\",\n        \"mediank\",\n        \"metro\",\n        \"metro2\",\n        \"metrobpm\",\n        \"mfb\",\n        \"midglobal\",\n        \"midiarp\",\n        \"midic14\",\n        \"midic21\",\n        \"midic7\",\n        \"midichannelaftertouch\",\n        \"midichn\",\n        \"midicontrolchange\",\n        \"midictrl\",\n        \"mididefault\",\n        \"midifilestatus\",\n        \"midiin\",\n        \"midinoteoff\",\n        \"midinoteoncps\",\n        \"midinoteonkey\",\n        \"midinoteonoct\",\n        \"midinoteonpch\",\n        \"midion\",\n        \"midion2\",\n        \"midiout\",\n        \"midiout_i\",\n        \"midipgm\",\n        \"midipitchbend\",\n        \"midipolyaftertouch\",\n        \"midiprogramchange\",\n        \"miditempo\",\n        \"midremot\",\n        \"min\",\n        \"minabs\",\n        \"minabsaccum\",\n        \"minaccum\",\n        \"minarray\",\n        \"mincer\",\n        \"mirror\",\n        \"mode\",\n        \"modmatrix\",\n        \"monitor\",\n        \"moog\",\n        \"moogladder\",\n        \"moogladder2\",\n        \"moogvcf\",\n        \"moogvcf2\",\n        \"moscil\",\n        \"mp3bitrate\",\n        \"mp3in\",\n        \"mp3len\",\n        \"mp3nchnls\",\n        \"mp3out\",\n        \"mp3scal\",\n        \"mp3sr\",\n        \"mpulse\",\n        \"mrtmsg\",\n        \"ms2st\",\n        \"mtof\",\n        \"mton\",\n        \"multitap\",\n        \"mute\",\n        \"mvchpf\",\n        \"mvclpf1\",\n        \"mvclpf2\",\n        \"mvclpf3\",\n        \"mvclpf4\",\n        \"mvmfilter\",\n        \"mxadsr\",\n        \"nchnls_hw\",\n        \"nestedap\",\n        \"nlalp\",\n        \"nlfilt\",\n        \"nlfilt2\",\n        \"noise\",\n        \"noteoff\",\n        \"noteon\",\n        \"noteondur\",\n        \"noteondur2\",\n        \"notnum\",\n        \"nreverb\",\n        \"nrpn\",\n        \"nsamp\",\n        \"nstance\",\n        \"nstrnum\",\n        \"nstrstr\",\n        \"ntof\",\n        \"ntom\",\n        \"ntrpol\",\n        \"nxtpow2\",\n        \"octave\",\n        \"octcps\",\n        \"octmidi\",\n        \"octmidib\",\n        \"octmidinn\",\n        \"octpch\",\n        \"olabuffer\",\n        \"oscbnk\",\n        \"oscil\",\n        \"oscil1\",\n        \"oscil1i\",\n        \"oscil3\",\n        \"oscili\",\n        \"oscilikt\",\n        \"osciliktp\",\n        \"oscilikts\",\n        \"osciln\",\n        \"oscils\",\n        \"oscilx\",\n        \"out\",\n        \"out32\",\n        \"outall\",\n        \"outc\",\n        \"outch\",\n        \"outh\",\n        \"outiat\",\n        \"outic\",\n        \"outic14\",\n        \"outipat\",\n        \"outipb\",\n        \"outipc\",\n        \"outkat\",\n        \"outkc\",\n        \"outkc14\",\n        \"outkpat\",\n        \"outkpb\",\n        \"outkpc\",\n        \"outleta\",\n        \"outletf\",\n        \"outletk\",\n        \"outletkid\",\n        \"outletv\",\n        \"outo\",\n        \"outq\",\n        \"outq1\",\n        \"outq2\",\n        \"outq3\",\n        \"outq4\",\n        \"outrg\",\n        \"outs\",\n        \"outs1\",\n        \"outs2\",\n        \"outvalue\",\n        \"outx\",\n        \"outz\",\n        \"p\",\n        \"p5gconnect\",\n        \"p5gdata\",\n        \"pan\",\n        \"pan2\",\n        \"pareq\",\n        \"part2txt\",\n        \"partials\",\n        \"partikkel\",\n        \"partikkelget\",\n        \"partikkelset\",\n        \"partikkelsync\",\n        \"passign\",\n        \"paulstretch\",\n        \"pcauchy\",\n        \"pchbend\",\n        \"pchmidi\",\n        \"pchmidib\",\n        \"pchmidinn\",\n        \"pchoct\",\n        \"pchtom\",\n        \"pconvolve\",\n        \"pcount\",\n        \"pdclip\",\n        \"pdhalf\",\n        \"pdhalfy\",\n        \"peak\",\n        \"pgmassign\",\n        \"pgmchn\",\n        \"phaser1\",\n        \"phaser2\",\n        \"phasor\",\n        \"phasorbnk\",\n        \"phs\",\n        \"pindex\",\n        \"pinker\",\n        \"pinkish\",\n        \"pitch\",\n        \"pitchac\",\n        \"pitchamdf\",\n        \"planet\",\n        \"platerev\",\n        \"plltrack\",\n        \"pluck\",\n        \"poisson\",\n        \"pol2rect\",\n        \"polyaft\",\n        \"polynomial\",\n        \"port\",\n        \"portk\",\n        \"poscil\",\n        \"poscil3\",\n        \"pow\",\n        \"powershape\",\n        \"powoftwo\",\n        \"pows\",\n        \"prealloc\",\n        \"prepiano\",\n        \"print\",\n        \"print_type\",\n        \"printarray\",\n        \"printf\",\n        \"printf_i\",\n        \"printk\",\n        \"printk2\",\n        \"printks\",\n        \"printks2\",\n        \"println\",\n        \"prints\",\n        \"printsk\",\n        \"product\",\n        \"pset\",\n        \"ptablew\",\n        \"ptrack\",\n        \"puts\",\n        \"pvadd\",\n        \"pvbufread\",\n        \"pvcross\",\n        \"pvinterp\",\n        \"pvoc\",\n        \"pvread\",\n        \"pvs2array\",\n        \"pvs2tab\",\n        \"pvsadsyn\",\n        \"pvsanal\",\n        \"pvsarp\",\n        \"pvsbandp\",\n        \"pvsbandr\",\n        \"pvsbandwidth\",\n        \"pvsbin\",\n        \"pvsblur\",\n        \"pvsbuffer\",\n        \"pvsbufread\",\n        \"pvsbufread2\",\n        \"pvscale\",\n        \"pvscent\",\n        \"pvsceps\",\n        \"pvscfs\",\n        \"pvscross\",\n        \"pvsdemix\",\n        \"pvsdiskin\",\n        \"pvsdisp\",\n        \"pvsenvftw\",\n        \"pvsfilter\",\n        \"pvsfread\",\n        \"pvsfreeze\",\n        \"pvsfromarray\",\n        \"pvsftr\",\n        \"pvsftw\",\n        \"pvsfwrite\",\n        \"pvsgain\",\n        \"pvsgendy\",\n        \"pvshift\",\n        \"pvsifd\",\n        \"pvsin\",\n        \"pvsinfo\",\n        \"pvsinit\",\n        \"pvslock\",\n        \"pvslpc\",\n        \"pvsmaska\",\n        \"pvsmix\",\n        \"pvsmooth\",\n        \"pvsmorph\",\n        \"pvsosc\",\n        \"pvsout\",\n        \"pvspitch\",\n        \"pvstanal\",\n        \"pvstencil\",\n        \"pvstrace\",\n        \"pvsvoc\",\n        \"pvswarp\",\n        \"pvsynth\",\n        \"pwd\",\n        \"pyassign\",\n        \"pyassigni\",\n        \"pyassignt\",\n        \"pycall\",\n        \"pycall1\",\n        \"pycall1i\",\n        \"pycall1t\",\n        \"pycall2\",\n        \"pycall2i\",\n        \"pycall2t\",\n        \"pycall3\",\n        \"pycall3i\",\n        \"pycall3t\",\n        \"pycall4\",\n        \"pycall4i\",\n        \"pycall4t\",\n        \"pycall5\",\n        \"pycall5i\",\n        \"pycall5t\",\n        \"pycall6\",\n        \"pycall6i\",\n        \"pycall6t\",\n        \"pycall7\",\n        \"pycall7i\",\n        \"pycall7t\",\n        \"pycall8\",\n        \"pycall8i\",\n        \"pycall8t\",\n        \"pycalli\",\n        \"pycalln\",\n        \"pycallni\",\n        \"pycallt\",\n        \"pyeval\",\n        \"pyevali\",\n        \"pyevalt\",\n        \"pyexec\",\n        \"pyexeci\",\n        \"pyexect\",\n        \"pyinit\",\n        \"pylassign\",\n        \"pylassigni\",\n        \"pylassignt\",\n        \"pylcall\",\n        \"pylcall1\",\n        \"pylcall1i\",\n        \"pylcall1t\",\n        \"pylcall2\",\n        \"pylcall2i\",\n        \"pylcall2t\",\n        \"pylcall3\",\n        \"pylcall3i\",\n        \"pylcall3t\",\n        \"pylcall4\",\n        \"pylcall4i\",\n        \"pylcall4t\",\n        \"pylcall5\",\n        \"pylcall5i\",\n        \"pylcall5t\",\n        \"pylcall6\",\n        \"pylcall6i\",\n        \"pylcall6t\",\n        \"pylcall7\",\n        \"pylcall7i\",\n        \"pylcall7t\",\n        \"pylcall8\",\n        \"pylcall8i\",\n        \"pylcall8t\",\n        \"pylcalli\",\n        \"pylcalln\",\n        \"pylcallni\",\n        \"pylcallt\",\n        \"pyleval\",\n        \"pylevali\",\n        \"pylevalt\",\n        \"pylexec\",\n        \"pylexeci\",\n        \"pylexect\",\n        \"pylrun\",\n        \"pylruni\",\n        \"pylrunt\",\n        \"pyrun\",\n        \"pyruni\",\n        \"pyrunt\",\n        \"qinf\",\n        \"qnan\",\n        \"r2c\",\n        \"rand\",\n        \"randc\",\n        \"randh\",\n        \"randi\",\n        \"random\",\n        \"randomh\",\n        \"randomi\",\n        \"rbjeq\",\n        \"readclock\",\n        \"readf\",\n        \"readfi\",\n        \"readk\",\n        \"readk2\",\n        \"readk3\",\n        \"readk4\",\n        \"readks\",\n        \"readscore\",\n        \"readscratch\",\n        \"rect2pol\",\n        \"release\",\n        \"remoteport\",\n        \"remove\",\n        \"repluck\",\n        \"reshapearray\",\n        \"reson\",\n        \"resonbnk\",\n        \"resonk\",\n        \"resonr\",\n        \"resonx\",\n        \"resonxk\",\n        \"resony\",\n        \"resonz\",\n        \"resyn\",\n        \"reverb\",\n        \"reverb2\",\n        \"reverbsc\",\n        \"rewindscore\",\n        \"rezzy\",\n        \"rfft\",\n        \"rifft\",\n        \"rms\",\n        \"rnd\",\n        \"rnd31\",\n        \"rndseed\",\n        \"round\",\n        \"rspline\",\n        \"rtclock\",\n        \"s16b14\",\n        \"s32b14\",\n        \"samphold\",\n        \"sandpaper\",\n        \"sc_lag\",\n        \"sc_lagud\",\n        \"sc_phasor\",\n        \"sc_trig\",\n        \"scale\",\n        \"scale2\",\n        \"scalearray\",\n        \"scanhammer\",\n        \"scanmap\",\n        \"scans\",\n        \"scansmap\",\n        \"scantable\",\n        \"scanu\",\n        \"scanu2\",\n        \"schedkwhen\",\n        \"schedkwhennamed\",\n        \"schedule\",\n        \"schedulek\",\n        \"schedwhen\",\n        \"scoreline\",\n        \"scoreline_i\",\n        \"seed\",\n        \"sekere\",\n        \"select\",\n        \"semitone\",\n        \"sense\",\n        \"sensekey\",\n        \"seqtime\",\n        \"seqtime2\",\n        \"sequ\",\n        \"sequstate\",\n        \"serialBegin\",\n        \"serialEnd\",\n        \"serialFlush\",\n        \"serialPrint\",\n        \"serialRead\",\n        \"serialWrite\",\n        \"serialWrite_i\",\n        \"setcol\",\n        \"setctrl\",\n        \"setksmps\",\n        \"setrow\",\n        \"setscorepos\",\n        \"sfilist\",\n        \"sfinstr\",\n        \"sfinstr3\",\n        \"sfinstr3m\",\n        \"sfinstrm\",\n        \"sfload\",\n        \"sflooper\",\n        \"sfpassign\",\n        \"sfplay\",\n        \"sfplay3\",\n        \"sfplay3m\",\n        \"sfplaym\",\n        \"sfplist\",\n        \"sfpreset\",\n        \"shaker\",\n        \"shiftin\",\n        \"shiftout\",\n        \"signum\",\n        \"sin\",\n        \"sinh\",\n        \"sininv\",\n        \"sinsyn\",\n        \"skf\",\n        \"sleighbells\",\n        \"slicearray\",\n        \"slicearray_i\",\n        \"slider16\",\n        \"slider16f\",\n        \"slider16table\",\n        \"slider16tablef\",\n        \"slider32\",\n        \"slider32f\",\n        \"slider32table\",\n        \"slider32tablef\",\n        \"slider64\",\n        \"slider64f\",\n        \"slider64table\",\n        \"slider64tablef\",\n        \"slider8\",\n        \"slider8f\",\n        \"slider8table\",\n        \"slider8tablef\",\n        \"sliderKawai\",\n        \"sndloop\",\n        \"sndwarp\",\n        \"sndwarpst\",\n        \"sockrecv\",\n        \"sockrecvs\",\n        \"socksend\",\n        \"socksends\",\n        \"sorta\",\n        \"sortd\",\n        \"soundin\",\n        \"space\",\n        \"spat3d\",\n        \"spat3di\",\n        \"spat3dt\",\n        \"spdist\",\n        \"spf\",\n        \"splitrig\",\n        \"sprintf\",\n        \"sprintfk\",\n        \"spsend\",\n        \"sqrt\",\n        \"squinewave\",\n        \"st2ms\",\n        \"statevar\",\n        \"sterrain\",\n        \"stix\",\n        \"strcat\",\n        \"strcatk\",\n        \"strchar\",\n        \"strchark\",\n        \"strcmp\",\n        \"strcmpk\",\n        \"strcpy\",\n        \"strcpyk\",\n        \"strecv\",\n        \"streson\",\n        \"strfromurl\",\n        \"strget\",\n        \"strindex\",\n        \"strindexk\",\n        \"string2array\",\n        \"strlen\",\n        \"strlenk\",\n        \"strlower\",\n        \"strlowerk\",\n        \"strrindex\",\n        \"strrindexk\",\n        \"strset\",\n        \"strstrip\",\n        \"strsub\",\n        \"strsubk\",\n        \"strtod\",\n        \"strtodk\",\n        \"strtol\",\n        \"strtolk\",\n        \"strupper\",\n        \"strupperk\",\n        \"stsend\",\n        \"subinstr\",\n        \"subinstrinit\",\n        \"sum\",\n        \"sumarray\",\n        \"svfilter\",\n        \"svn\",\n        \"syncgrain\",\n        \"syncloop\",\n        \"syncphasor\",\n        \"system\",\n        \"system_i\",\n        \"tab\",\n        \"tab2array\",\n        \"tab2pvs\",\n        \"tab_i\",\n        \"tabifd\",\n        \"table\",\n        \"table3\",\n        \"table3kt\",\n        \"tablecopy\",\n        \"tablefilter\",\n        \"tablefilteri\",\n        \"tablegpw\",\n        \"tablei\",\n        \"tableicopy\",\n        \"tableigpw\",\n        \"tableikt\",\n        \"tableimix\",\n        \"tablekt\",\n        \"tablemix\",\n        \"tableng\",\n        \"tablera\",\n        \"tableseg\",\n        \"tableshuffle\",\n        \"tableshufflei\",\n        \"tablew\",\n        \"tablewa\",\n        \"tablewkt\",\n        \"tablexkt\",\n        \"tablexseg\",\n        \"tabmorph\",\n        \"tabmorpha\",\n        \"tabmorphak\",\n        \"tabmorphi\",\n        \"tabplay\",\n        \"tabrec\",\n        \"tabsum\",\n        \"tabw\",\n        \"tabw_i\",\n        \"tambourine\",\n        \"tan\",\n        \"tanh\",\n        \"taninv\",\n        \"taninv2\",\n        \"tbvcf\",\n        \"tempest\",\n        \"tempo\",\n        \"temposcal\",\n        \"tempoval\",\n        \"timedseq\",\n        \"timeinstk\",\n        \"timeinsts\",\n        \"timek\",\n        \"times\",\n        \"tival\",\n        \"tlineto\",\n        \"tone\",\n        \"tonek\",\n        \"tonex\",\n        \"tradsyn\",\n        \"trandom\",\n        \"transeg\",\n        \"transegb\",\n        \"transegr\",\n        \"trcross\",\n        \"trfilter\",\n        \"trhighest\",\n        \"trigExpseg\",\n        \"trigLinseg\",\n        \"trigexpseg\",\n        \"trigger\",\n        \"trighold\",\n        \"triglinseg\",\n        \"trigphasor\",\n        \"trigseq\",\n        \"trim\",\n        \"trim_i\",\n        \"trirand\",\n        \"trlowest\",\n        \"trmix\",\n        \"trscale\",\n        \"trshift\",\n        \"trsplit\",\n        \"turnoff\",\n        \"turnoff2\",\n        \"turnoff2_i\",\n        \"turnoff3\",\n        \"turnon\",\n        \"tvconv\",\n        \"unirand\",\n        \"unwrap\",\n        \"upsamp\",\n        \"urandom\",\n        \"urd\",\n        \"vactrol\",\n        \"vadd\",\n        \"vadd_i\",\n        \"vaddv\",\n        \"vaddv_i\",\n        \"vaget\",\n        \"valpass\",\n        \"vaset\",\n        \"vbap\",\n        \"vbapg\",\n        \"vbapgmove\",\n        \"vbaplsinit\",\n        \"vbapmove\",\n        \"vbapz\",\n        \"vbapzmove\",\n        \"vcella\",\n        \"vclpf\",\n        \"vco\",\n        \"vco2\",\n        \"vco2ft\",\n        \"vco2ift\",\n        \"vco2init\",\n        \"vcomb\",\n        \"vcopy\",\n        \"vcopy_i\",\n        \"vdel_k\",\n        \"vdelay\",\n        \"vdelay3\",\n        \"vdelayk\",\n        \"vdelayx\",\n        \"vdelayxq\",\n        \"vdelayxs\",\n        \"vdelayxw\",\n        \"vdelayxwq\",\n        \"vdelayxws\",\n        \"vdivv\",\n        \"vdivv_i\",\n        \"vecdelay\",\n        \"veloc\",\n        \"vexp\",\n        \"vexp_i\",\n        \"vexpseg\",\n        \"vexpv\",\n        \"vexpv_i\",\n        \"vibes\",\n        \"vibr\",\n        \"vibrato\",\n        \"vincr\",\n        \"vlimit\",\n        \"vlinseg\",\n        \"vlowres\",\n        \"vmap\",\n        \"vmirror\",\n        \"vmult\",\n        \"vmult_i\",\n        \"vmultv\",\n        \"vmultv_i\",\n        \"voice\",\n        \"vosim\",\n        \"vphaseseg\",\n        \"vport\",\n        \"vpow\",\n        \"vpow_i\",\n        \"vpowv\",\n        \"vpowv_i\",\n        \"vps\",\n        \"vpvoc\",\n        \"vrandh\",\n        \"vrandi\",\n        \"vsubv\",\n        \"vsubv_i\",\n        \"vtaba\",\n        \"vtabi\",\n        \"vtabk\",\n        \"vtable1k\",\n        \"vtablea\",\n        \"vtablei\",\n        \"vtablek\",\n        \"vtablewa\",\n        \"vtablewi\",\n        \"vtablewk\",\n        \"vtabwa\",\n        \"vtabwi\",\n        \"vtabwk\",\n        \"vwrap\",\n        \"waveset\",\n        \"websocket\",\n        \"weibull\",\n        \"wgbow\",\n        \"wgbowedbar\",\n        \"wgbrass\",\n        \"wgclar\",\n        \"wgflute\",\n        \"wgpluck\",\n        \"wgpluck2\",\n        \"wguide1\",\n        \"wguide2\",\n        \"wiiconnect\",\n        \"wiidata\",\n        \"wiirange\",\n        \"wiisend\",\n        \"window\",\n        \"wrap\",\n        \"writescratch\",\n        \"wterrain\",\n        \"wterrain2\",\n        \"xadsr\",\n        \"xin\",\n        \"xout\",\n        \"xtratim\",\n        \"xyscale\",\n        \"zacl\",\n        \"zakinit\",\n        \"zamod\",\n        \"zar\",\n        \"zarg\",\n        \"zaw\",\n        \"zawm\",\n        \"zdf_1pole\",\n        \"zdf_1pole_mode\",\n        \"zdf_2pole\",\n        \"zdf_2pole_mode\",\n        \"zdf_ladder\",\n        \"zfilter2\",\n        \"zir\",\n        \"ziw\",\n        \"ziwm\",\n        \"zkcl\",\n        \"zkmod\",\n        \"zkr\",\n        \"zkw\",\n        \"zkwm\"\n    ];\n    var deprecatedOpcodes = [\n        \"OSCsendA\",\n        \"array\",\n        \"beadsynt\",\n        \"beosc\",\n        \"bformdec\",\n        \"bformenc\",\n        \"buchla\",\n        \"copy2ftab\",\n        \"copy2ttab\",\n        \"getrowlin\",\n        \"hrtfer\",\n        \"ktableseg\",\n        \"lentab\",\n        \"lua_exec\",\n        \"lua_iaopcall\",\n        \"lua_iaopcall_off\",\n        \"lua_ikopcall\",\n        \"lua_ikopcall_off\",\n        \"lua_iopcall\",\n        \"lua_iopcall_off\",\n        \"lua_opdef\",\n        \"maxtab\",\n        \"mintab\",\n        \"mp3scal_check\",\n        \"mp3scal_load\",\n        \"mp3scal_load2\",\n        \"mp3scal_play\",\n        \"mp3scal_play2\",\n        \"pop\",\n        \"pop_f\",\n        \"ptable\",\n        \"ptable3\",\n        \"ptablei\",\n        \"ptableiw\",\n        \"push\",\n        \"push_f\",\n        \"pvsgendy\",\n        \"scalet\",\n        \"signalflowgraph\",\n        \"sndload\",\n        \"socksend_k\",\n        \"soundout\",\n        \"soundouts\",\n        \"specaddm\",\n        \"specdiff\",\n        \"specdisp\",\n        \"specfilt\",\n        \"spechist\",\n        \"specptrk\",\n        \"specscal\",\n        \"specsum\",\n        \"spectrum\",\n        \"stack\",\n        \"sumTableFilter\",\n        \"sumtab\",\n        \"systime\",\n        \"tabgen\",\n        \"tableiw\",\n        \"tabmap\",\n        \"tabmap_i\",\n        \"tabrowlin\",\n        \"tabslice\",\n        \"tb0\",\n        \"tb0_init\",\n        \"tb1\",\n        \"tb10\",\n        \"tb10_init\",\n        \"tb11\",\n        \"tb11_init\",\n        \"tb12\",\n        \"tb12_init\",\n        \"tb13\",\n        \"tb13_init\",\n        \"tb14\",\n        \"tb14_init\",\n        \"tb15\",\n        \"tb15_init\",\n        \"tb1_init\",\n        \"tb2\",\n        \"tb2_init\",\n        \"tb3\",\n        \"tb3_init\",\n        \"tb4\",\n        \"tb4_init\",\n        \"tb5\",\n        \"tb5_init\",\n        \"tb6\",\n        \"tb6_init\",\n        \"tb7\",\n        \"tb7_init\",\n        \"tb8\",\n        \"tb8_init\",\n        \"tb9\",\n        \"tb9_init\",\n        \"vbap16\",\n        \"vbap1move\",\n        \"vbap4\",\n        \"vbap4move\",\n        \"vbap8\",\n        \"vbap8move\",\n        \"xscanmap\",\n        \"xscans\",\n        \"xscansmap\",\n        \"xscanu\",\n        \"xyin\"\n    ];\n\n    opcodes = lang.arrayToMap(opcodes);\n    deprecatedOpcodes = lang.arrayToMap(deprecatedOpcodes);\n\n    this.lineContinuations = [\n        {\n            token : \"constant.character.escape.line-continuation.csound\",\n            regex : /\\\\$/\n        }, this.pushRule({\n            token : \"constant.character.escape.line-continuation.csound\",\n            regex : /\\\\/,\n            next  : \"line continuation\"\n        })\n    ];\n\n    this.comments.push(this.lineContinuations);\n\n    this.quotedStringContents.push(\n        this.lineContinuations,\n        {\n            token : \"invalid.illegal\",\n            regex : /[^\"\\\\]*$/\n        }\n    );\n\n    var start = this.$rules.start;\n    start.splice(1, 0, {\n        token : [\"text.csound\", \"entity.name.label.csound\", \"entity.punctuation.label.csound\", \"text.csound\"],\n        regex : /^([ \\t]*)(\\w+)(:)([ \\t]+|$)/\n    });\n    start.push(\n        this.pushRule({\n            token : \"keyword.function.csound\",\n            regex : /\\binstr\\b/,\n            next  : \"instrument numbers and identifiers\"\n        }), this.pushRule({\n            token : \"keyword.function.csound\",\n            regex : /\\bopcode\\b/,\n            next  : \"after opcode keyword\"\n        }), {\n            token : \"keyword.other.csound\",\n            regex : /\\bend(?:in|op)\\b/\n        },\n\n        {\n            token : \"variable.language.csound\",\n            regex : /\\b(?:0dbfs|A4|k(?:r|smps)|nchnls(?:_i)?|sr)\\b/\n        },\n\n        this.numbers,\n\n        {\n            token : \"keyword.operator.csound\",\n            regex : \"\\\\+=|-=|\\\\*=|/=|<<|>>|<=|>=|==|!=|&&|\\\\|\\\\||[~¬]|[=!+\\\\-*/^%&|<>#?:]\"\n        },\n\n        this.pushRule({\n            token : \"punctuation.definition.string.begin.csound\",\n            regex : /\"/,\n            next  : \"quoted string\"\n        }), this.pushRule({\n            token : \"punctuation.definition.string.begin.csound\",\n            regex : /{{/,\n            next  : \"braced string\"\n        }),\n\n        {\n            token : \"keyword.control.csound\",\n            regex : /\\b(?:do|else(?:if)?|end(?:if|until)|fi|i(?:f|then)|kthen|od|r(?:ir)?eturn|then|until|while)\\b/\n        },\n\n        this.pushRule({\n            token : \"keyword.control.csound\",\n            regex : /\\b[ik]?goto\\b/,\n            next  : \"goto before label\"\n        }), this.pushRule({\n            token : \"keyword.control.csound\",\n            regex : /\\b(?:r(?:einit|igoto)|tigoto)\\b/,\n            next  : \"goto before label\"\n        }), this.pushRule({\n            token : \"keyword.control.csound\",\n            regex : /\\bc(?:g|in?|k|nk?)goto\\b/,\n            next  : [\"goto before label\", \"goto before argument\"]\n        }), this.pushRule({\n            token : \"keyword.control.csound\",\n            regex : /\\btimout\\b/,\n            next  : [\"goto before label\", \"goto before argument\", \"goto before argument\"]\n        }), this.pushRule({\n            token : \"keyword.control.csound\",\n            regex : /\\bloop_[gl][et]\\b/,\n            next  : [\"goto before label\", \"goto before argument\", \"goto before argument\", \"goto before argument\"]\n        }),\n\n        this.pushRule({\n            token : \"support.function.csound\",\n            regex : /\\b(?:readscore|scoreline(?:_i)?)\\b/,\n            next  : \"Csound score opcode\"\n        }), this.pushRule({\n            token : \"support.function.csound\",\n            regex : /\\bpyl?run[it]?\\b(?!$)/,\n            next  : \"Python opcode\"\n        }), this.pushRule({\n            token : \"support.function.csound\",\n            regex : /\\blua_(?:exec|opdef)\\b(?!$)/,\n            next  : \"Lua opcode\"\n        }),\n\n        {\n            token : \"support.variable.csound\",\n            regex : /\\bp\\d+\\b/\n        }, {\n            regex : /\\b([A-Z_a-z]\\w*)(?:(:)([A-Za-z]))?\\b/, onMatch: function(value, currentState, stack, line) {\n                var tokens = value.split(this.splitRegex);\n                var name = tokens[1];\n                var type;\n                if (opcodes.hasOwnProperty(name))\n                    type = \"support.function.csound\";\n                else if (deprecatedOpcodes.hasOwnProperty(name))\n                    type = \"invalid.deprecated.csound\";\n                if (type) {\n                    if (tokens[2]) {\n                        return [\n                            {type: type, value: name},\n                            {type: \"punctuation.type-annotation.csound\", value: tokens[2]},\n                            {type: \"type-annotation.storage.type.csound\", value: tokens[3]}\n                        ];\n                    }\n                    return type;\n                }\n                return \"text.csound\";\n            }\n        }\n    );\n\n    this.$rules[\"macro parameter value list\"].splice(2, 0, {\n        token : \"punctuation.definition.string.begin.csound\",\n        regex : /{{/,\n        next  : \"macro parameter value braced string\"\n    });\n\n    var scoreHighlightRules = new CsoundScoreHighlightRules(\"csound-score-\");\n\n    this.addRules({\n        \"macro parameter value braced string\": [\n            {\n                token : \"constant.character.escape.csound\",\n                regex : /\\\\[#'()]/\n            }, {\n                token : \"invalid.illegal.csound.csound\",\n                regex : /[#'()]/\n            }, {\n                token : \"punctuation.definition.string.end.csound\",\n                regex : /}}/,\n                next  : \"macro parameter value list\"\n            }, {\n                defaultToken: \"string.braced.csound\"\n            }\n        ],\n\n        \"instrument numbers and identifiers\": [\n            this.comments,\n            {\n                token : \"entity.name.function.csound\",\n                regex : /\\d+|[A-Z_a-z]\\w*/\n            }, this.popRule({\n                token : \"empty\",\n                regex : /$/\n            })\n        ],\n\n        \"after opcode keyword\": [\n            this.comments,\n            this.popRule({\n                token : \"empty\",\n                regex : /$/\n            }), this.popRule({\n                token : \"entity.name.function.opcode.csound\",\n                regex : /[A-Z_a-z]\\w*/,\n                next  : \"opcode type signatures\"\n            })\n        ],\n        \"opcode type signatures\": [\n            this.comments,\n            this.popRule({\n                token : \"empty\",\n                regex : /$/\n            }), {\n                token : \"storage.type.csound\",\n                // https://github.com/csound/csound/search?q=XIDENT+path%3AEngine+filename%3Acsound_orc.lex\n                regex : /\\b(?:0|[afijkKoOpPStV\\[\\]]+)/\n            }\n        ],\n\n        \"quoted string\": [\n            this.popRule({\n                token : \"punctuation.definition.string.end.csound\",\n                regex : /\"/\n            }),\n            this.quotedStringContents,\n            {\n                defaultToken: \"string.quoted.csound\"\n            }\n        ],\n        \"braced string\": [\n            this.popRule({\n                token : \"punctuation.definition.string.end.csound\",\n                regex : /}}/\n            }),\n            this.bracedStringContents,\n            {\n                defaultToken: \"string.braced.csound\"\n            }\n        ],\n\n        \"goto before argument\": [\n            this.popRule({\n                token : \"text.csound\",\n                regex : /,/\n            }),\n            start\n        ],\n        \"goto before label\": [\n            {\n                token : \"text.csound\",\n                regex : /\\s+/\n            },\n            this.comments,\n            this.popRule({\n                token : \"entity.name.label.csound\",\n                regex : /\\w+/\n            }), this.popRule({\n                token : \"empty\",\n                regex : /(?!\\w)/\n            })\n        ],\n\n        \"Csound score opcode\": [\n            this.comments,\n            {\n                token : \"punctuation.definition.string.begin.csound\",\n                regex : /{{/,\n                next  : scoreHighlightRules.embeddedRulePrefix + \"start\"\n            }, this.popRule({\n                token : \"empty\",\n                regex : /$/\n            })\n        ],\n\n        \"Python opcode\": [\n            this.comments,\n            {\n                token : \"punctuation.definition.string.begin.csound\",\n                regex : /{{/,\n                next  : \"python-start\"\n            }, this.popRule({\n                token : \"empty\",\n                regex : /$/\n            })\n        ],\n\n        \"Lua opcode\": [\n            this.comments,\n            {\n                token : \"punctuation.definition.string.begin.csound\",\n                regex : /{{/,\n                next  : \"lua-start\"\n            }, this.popRule({\n                token : \"empty\",\n                regex : /$/\n            })\n        ],\n\n        \"line continuation\": [\n            this.popRule({\n                token : \"empty\",\n                regex : /$/\n            }),\n            this.semicolonComments,\n            {\n                token : \"invalid.illegal.csound\",\n                regex : /\\S.*/\n            }\n        ]\n    });\n\n    var rules = [\n        this.popRule({\n            token : \"punctuation.definition.string.end.csound\",\n            regex : /}}/\n        })\n    ];\n    this.embedRules(scoreHighlightRules.getRules(), scoreHighlightRules.embeddedRulePrefix, rules);\n    this.embedRules(PythonHighlightRules, \"python-\", rules);\n    this.embedRules(LuaHighlightRules, \"lua-\", rules);\n\n    this.normalizeRules();\n};\n\noop.inherits(CsoundOrchestraHighlightRules, CsoundPreprocessorHighlightRules);\n\nexports.CsoundOrchestraHighlightRules = CsoundOrchestraHighlightRules;\n"
  },
  {
    "path": "src/mode/csound_preprocessor_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar CsoundPreprocessorHighlightRules = function(embeddedRulePrefix) {\n\n    this.embeddedRulePrefix = embeddedRulePrefix === undefined ? \"\" : embeddedRulePrefix;\n\n    this.semicolonComments = {\n        token : \"comment.line.semicolon.csound\",\n        regex : \";.*$\"\n    };\n\n    this.comments = [\n        {\n            token : \"punctuation.definition.comment.begin.csound\",\n            regex : \"/\\\\*\",\n            push  : [\n                {\n                    token : \"punctuation.definition.comment.end.csound\",\n                    regex : \"\\\\*/\",\n                    next  : \"pop\"\n                }, {\n                    defaultToken: \"comment.block.csound\"\n                }\n            ]\n        }, {\n            token : \"comment.line.double-slash.csound\",\n            regex : \"//.*$\"\n        },\n        this.semicolonComments\n    ];\n\n    this.macroUses = [\n        {\n            token : [\"entity.name.function.preprocessor.csound\", \"punctuation.definition.macro-parameter-value-list.begin.csound\"],\n            regex : /(\\$[A-Z_a-z]\\w*\\.?)(\\()/,\n            next  : \"macro parameter value list\"\n        }, {\n            token : \"entity.name.function.preprocessor.csound\",\n            regex : /\\$[A-Z_a-z]\\w*(?:\\.|\\b)/\n        }\n    ];\n\n    this.numbers = [\n        {\n            token : \"constant.numeric.float.csound\",\n            regex : /(?:\\d+[Ee][+-]?\\d+)|(?:\\d+\\.\\d*|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?/\n        }, {\n            token : [\"storage.type.number.csound\", \"constant.numeric.integer.hexadecimal.csound\"],\n            regex : /(0[Xx])([0-9A-Fa-f]+)/\n        }, {\n            token : \"constant.numeric.integer.decimal.csound\",\n            regex : /\\d+/\n        }\n    ];\n\n    this.bracedStringContents = [\n        {\n            token : \"constant.character.escape.csound\",\n            // https://github.com/csound/csound/search?q=unquote_string+path%3AEngine+filename%3Acsound_orc_compile.c\n            regex : /\\\\(?:[\\\\abnrt\"]|[0-7]{1,3})/\n        },\n        // Format specifiers are included in quoted and braced strings. This\n        // means that format specifiers are highlighted in all strings, even\n        // though only\n        //   fprintks        https://csound.com/docs/manual/fprintks.html\n        //   fprints         https://csound.com/docs/manual/fprints.html\n        //   printf/printf_i https://csound.com/docs/manual/printf.html\n        //   printks         https://csound.com/docs/manual/printks.html\n        //   prints          https://csound.com/docs/manual/prints.html\n        //   sprintf         https://csound.com/docs/manual/sprintf.html\n        //   sprintfk        https://csound.com/docs/manual/sprintfk.html\n        // work with strings that contain format specifiers. In addition, these\n        // opcodes’ handling of format specifiers is inconsistent:\n        //   - fprintks, fprints, printks, and prints do accept %a and %A\n        //     specifiers, but can’t accept %s specifiers.\n        //   - printf, printf_i, sprintf, and sprintfk don’t accept %a and %A\n        //     specifiers, but do accept %s specifiers.\n        // See https://github.com/csound/csound/issues/747 for more information.\n        {\n            token : \"constant.character.placeholder.csound\",\n            regex : /%[#0\\- +]*\\d*(?:\\.\\d+)?[diuoxXfFeEgGaAcs]/\n        }, {\n            token : \"constant.character.escape.csound\",\n            regex : /%%/\n        }\n    ];\n\n    this.quotedStringContents = [\n        this.macroUses,\n        this.bracedStringContents\n    ];\n\n    var start = [\n        this.comments,\n\n        {\n            token : \"keyword.preprocessor.csound\",\n            regex : /#(?:e(?:nd(?:if)?|lse)\\b|##)|@@?[ \\t]*\\d+/\n        }, {\n            token : \"keyword.preprocessor.csound\",\n            regex : /#include/,\n            push  : [\n                this.comments,\n                {\n                    token : \"string.csound\",\n                    regex : /([^ \\t])(?:.*?\\1)/,\n                    next  : \"pop\"\n                }\n            ]\n        }, {\n            token : \"keyword.preprocessor.csound\",\n            regex : /#includestr/,\n            push  : [\n                this.comments,\n                {\n                    token : \"string.csound\",\n                    regex : /([^ \\t])(?:.*?\\1)/,\n                    next  : \"pop\"\n                }\n            ]\n        }, {\n            token : \"keyword.preprocessor.csound\",\n            regex : /#[ \\t]*define/,\n            next  : \"define directive\"\n        }, {\n            token : \"keyword.preprocessor.csound\",\n            regex : /#(?:ifn?def|undef)\\b/,\n            next  : \"macro directive\"\n        },\n\n        this.macroUses\n    ];\n\n    this.$rules = {\n        \"start\": start,\n\n        \"define directive\": [\n            this.comments,\n            {\n                token : \"entity.name.function.preprocessor.csound\",\n                regex : /[A-Z_a-z]\\w*/\n            }, {\n                token : \"punctuation.definition.macro-parameter-name-list.begin.csound\",\n                regex : /\\(/,\n                next  : \"macro parameter name list\"\n            }, {\n                token : \"punctuation.definition.macro.begin.csound\",\n                regex : /#/,\n                next  : \"macro body\"\n            }\n        ],\n        \"macro parameter name list\": [\n            {\n                token : \"variable.parameter.preprocessor.csound\",\n                regex : /[A-Z_a-z]\\w*/\n            }, {\n                token : \"punctuation.definition.macro-parameter-name-list.end.csound\",\n                regex : /\\)/,\n                next  : \"define directive\"\n            }\n        ],\n        \"macro body\": [\n            {\n                token : \"constant.character.escape.csound\",\n                regex : /\\\\#/\n            }, {\n                token : \"punctuation.definition.macro.end.csound\",\n                regex : /#/,\n                next  : \"start\"\n            },\n            start\n        ],\n\n        \"macro directive\": [\n            this.comments,\n            {\n                token : \"entity.name.function.preprocessor.csound\",\n                regex : /[A-Z_a-z]\\w*/,\n                next  : \"start\"\n            }\n        ],\n\n        \"macro parameter value list\": [\n            {\n                token : \"punctuation.definition.macro-parameter-value-list.end.csound\",\n                regex : /\\)/,\n                next  : \"start\"\n            }, {\n                token : \"punctuation.definition.string.begin.csound\",\n                regex : /\"/,\n                next  : \"macro parameter value quoted string\"\n            }, this.pushRule({\n                token : \"punctuation.macro-parameter-value-parenthetical.begin.csound\",\n                regex : /\\(/,\n                next  : \"macro parameter value parenthetical\"\n            }), {\n                token : \"punctuation.macro-parameter-value-separator.csound\",\n                regex : \"[#']\"\n            }\n        ],\n        \"macro parameter value quoted string\": [\n            {\n                token : \"constant.character.escape.csound\",\n                regex : /\\\\[#'()]/\n            }, {\n                token : \"invalid.illegal.csound\",\n                regex : /[#'()]/\n            }, {\n                token : \"punctuation.definition.string.end.csound\",\n                regex : /\"/,\n                next  : \"macro parameter value list\"\n            },\n            this.quotedStringContents,\n            {\n                defaultToken: \"string.quoted.csound\"\n            }\n        ],\n        \"macro parameter value parenthetical\": [\n            {\n                token : \"constant.character.escape.csound\",\n                regex : /\\\\\\)/\n            }, this.popRule({\n                token : \"punctuation.macro-parameter-value-parenthetical.end.csound\",\n                regex : /\\)/\n            }), this.pushRule({\n                token : \"punctuation.macro-parameter-value-parenthetical.begin.csound\",\n                regex : /\\(/,\n                next  : \"macro parameter value parenthetical\"\n            }),\n            start\n        ]\n    };\n};\n\noop.inherits(CsoundPreprocessorHighlightRules, TextHighlightRules);\n\n(function() {\n\n    this.pushRule = function(params) {\n        if (Array.isArray(params.next)) {\n            for (var i = 0; i < params.next.length; i++) {\n                params.next[i] = this.embeddedRulePrefix + params.next[i];\n            }\n        }\n\n        return {\n            regex : params.regex, onMatch: function(value, currentState, stack, line) {\n                if (stack.length === 0)\n                    stack.push(currentState);\n                if (Array.isArray(params.next)) {\n                    for (var i = 0; i < params.next.length; i++) {\n                        stack.push(params.next[i]);\n                    }\n                } else {\n                    stack.push(params.next);\n                }\n                this.next = stack[stack.length - 1];\n                return params.token;\n            },\n\n            get next() { return Array.isArray(params.next) ? params.next[params.next.length - 1] : params.next; },\n            set next(next) {\n                if (!Array.isArray(params.next)) {\n                    params.next = next;\n                }\n            },\n\n            get token() { return params.token; }\n        };\n    };\n\n    this.popRule = function(params) {\n        if (params.next) {\n            params.next = this.embeddedRulePrefix + params.next;\n        }\n\n        return {\n            regex : params.regex, onMatch: function(value, currentState, stack, line) {\n                stack.pop();\n                if (params.next) {\n                    stack.push(params.next);\n                    this.next = stack[stack.length - 1];\n                } else {\n                    this.next = stack.length > 1 ? stack[stack.length - 1] : stack.pop();\n                }\n                return params.token;\n            }\n        };\n    };\n\n}).call(CsoundPreprocessorHighlightRules.prototype);\n\nexports.CsoundPreprocessorHighlightRules = CsoundPreprocessorHighlightRules;\n"
  },
  {
    "path": "src/mode/csound_score.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CsoundScoreHighlightRules = require(\"./csound_score_highlight_rules\").CsoundScoreHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = CsoundScoreHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \";\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/csound_score\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/csound_score_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n\nvar CsoundPreprocessorHighlightRules = require(\"./csound_preprocessor_highlight_rules\").CsoundPreprocessorHighlightRules;\n\nvar CsoundScoreHighlightRules = function(embeddedRulePrefix) {\n\n    CsoundPreprocessorHighlightRules.call(this, embeddedRulePrefix);\n\n    this.quotedStringContents.push({\n        token : \"invalid.illegal.csound-score\",\n        regex : /[^\"]*$/\n    });\n\n    var start = this.$rules.start;\n    start.push(\n        {\n            token : \"keyword.control.csound-score\",\n            regex : /[aBbCdefiqstvxy]/\n        }, {\n            // w statements are generated internally and should not be used; see\n            // https://github.com/csound/csound/issues/750.\n            token : \"invalid.illegal.csound-score\",\n            regex : /w/\n        }, {\n            // z is not a statement, but rather a constant equal to\n            // 800,000,000,000. 800 billion seconds is about 25,367.8 years. See\n            // also https://csound.github.io/docs/manual/ScoreTop.html and\n            // https://github.com/csound/csound/search?q=stof+path%3AEngine+filename%3Asread.c.\n            token : \"constant.numeric.language.csound-score\",\n            regex : /z/\n        }, {\n            token : [\"keyword.control.csound-score\", \"constant.numeric.integer.decimal.csound-score\"],\n            regex : /([nNpP][pP])(\\d+)/\n        }, {\n            token : \"keyword.other.csound-score\",\n            regex : /[mn]/,\n            push  : [\n                {\n                    token : \"empty\",\n                    regex : /$/,\n                    next  : \"pop\"\n                },\n                this.comments,\n                {\n                    token : \"entity.name.label.csound-score\",\n                    regex : /[A-Z_a-z]\\w*/\n                }\n            ]\n        }, {\n            token : \"keyword.preprocessor.csound-score\",\n            regex : /r\\b/,\n            next  : \"repeat section\"\n        },\n\n        this.numbers,\n\n        {\n            token : \"keyword.operator.csound-score\",\n            regex : \"[!+\\\\-*/^%&|<>#~.]\"\n        },\n\n        this.pushRule({\n            token : \"punctuation.definition.string.begin.csound-score\",\n            regex : /\"/,\n            next  : \"quoted string\"\n        }),\n\n        this.pushRule({\n            token : \"punctuation.braced-loop.begin.csound-score\",\n            regex : /{/,\n            next  : \"loop after left brace\"\n        })\n    );\n\n    this.addRules({\n        \"repeat section\": [\n            {\n                token : \"empty\",\n                regex : /$/,\n                next  : \"start\"\n            },\n            this.comments,\n            {\n                token : \"constant.numeric.integer.decimal.csound-score\",\n                regex : /\\d+/,\n                next  : \"repeat section before label\"\n            }\n        ],\n        \"repeat section before label\": [\n            {\n                token : \"empty\",\n                regex : /$/,\n                next  : \"start\"\n            },\n            this.comments,\n            {\n                token : \"entity.name.label.csound-score\",\n                regex : /[A-Z_a-z]\\w*/,\n                next  : \"start\"\n            }\n        ],\n\n        \"quoted string\": [\n            this.popRule({\n                token : \"punctuation.definition.string.end.csound-score\",\n                regex : /\"/\n            }),\n            this.quotedStringContents,\n            {\n                defaultToken: \"string.quoted.csound-score\"\n            }\n        ],\n\n        \"loop after left brace\": [\n            this.popRule({\n                token : \"constant.numeric.integer.decimal.csound-score\",\n                regex : /\\d+/,\n                next  : \"loop after repeat count\"\n            }),\n            this.comments,\n            {\n                token : \"invalid.illegal.csound\",\n                regex : /\\S.*/\n            }\n        ],\n        \"loop after repeat count\": [\n            this.popRule({\n                token : \"entity.name.function.preprocessor.csound-score\",\n                regex : /[A-Z_a-z]\\w*\\b/,\n                next  : \"loop after macro name\"\n            }),\n            this.comments,\n            {\n                token : \"invalid.illegal.csound\",\n                regex : /\\S.*/\n            }\n        ],\n        \"loop after macro name\": [\n            start,\n            this.popRule({\n                token : \"punctuation.braced-loop.end.csound-score\",\n                regex : /}/\n            })\n        ]\n    });\n\n    this.normalizeRules();\n};\n\noop.inherits(CsoundScoreHighlightRules, CsoundPreprocessorHighlightRules);\n\nexports.CsoundScoreHighlightRules = CsoundScoreHighlightRules;\n"
  },
  {
    "path": "src/mode/csp.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n    \"use strict\";\n\n    var TextMode = require(\"./text\").Mode;\n    var CspHighlightRules = require(\"./csp_highlight_rules\").CspHighlightRules;\n    var oop = require(\"../lib/oop\");\n\n    var Mode = function() {\n        this.HighlightRules = CspHighlightRules;\n    };\n\n    oop.inherits(Mode, TextMode);\n\n    (function() {\n        this.$id = \"ace/mode/csp\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/csp_highlight_rules.js",
    "content": "/*\n    EXPLANATION\n\n    This highlight rules were created to help developer spot typos when working\n    with Content-Security-Policy (CSP). See:\n    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/\n */\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var CspHighlightRules = function() {\n        var keywordMapper = this.createKeywordMapper({\n            \"constant.language\": \"child-src|connect-src|default-src|font-src|frame-src|img-src|manifest-src|media-src|object-src\"\n                  + \"|script-src|style-src|worker-src|base-uri|plugin-types|sandbox|disown-opener|form-action|frame-ancestors|report-uri\"\n                  + \"|report-to|upgrade-insecure-requests|block-all-mixed-content|require-sri-for|reflected-xss|referrer|policy-uri\",\n            \"variable\": \"'none'|'self'|'unsafe-inline'|'unsafe-eval'|'strict-dynamic'|'unsafe-hashed-attributes'\"\n        }, \"identifier\", true);\n\n        this.$rules = {\n            start: [{\n                token: \"string.link\",\n                regex: /https?:[^;\\s]*/\n            }, {\n                token: \"operator.punctuation\",\n                regex: /;/\n            }, {\n                token: keywordMapper,\n                regex: /[^\\s;]+/\n            }]\n        };\n    };\n\n    oop.inherits(CspHighlightRules, TextHighlightRules);\n\n    exports.CspHighlightRules = CspHighlightRules;\n"
  },
  {
    "path": "src/mode/css.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CssHighlightRules = require(\"./css_highlight_rules\").CssHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\nvar CssCompletions = require(\"./css_completions\").CssCompletions;\nvar CssBehaviour = require(\"./behaviour/css\").CssBehaviour;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = CssHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = new CssBehaviour();\n    this.$completer = new CssCompletions();\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.foldingRules = \"cStyle\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        // ignore braces in comments\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        var match = line.match(/^.*\\{\\s*$/);\n        if (match) {\n            indent += tab;\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        return this.$completer.getCompletions(state, session, pos, prefix);\n    };\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/css_worker\", \"Worker\");\n        worker.attachToDocument(session.getDocument());\n\n        worker.on(\"annotate\", function(e) {\n            session.setAnnotations(e.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n    this.$id = \"ace/mode/css\";\n    this.snippetFileId = \"ace/snippets/css\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/css_completions.js",
    "content": "\"use strict\";\n\nvar propertyMap = {\n    \"background\": {\"#$0\": 1},\n    \"background-color\": {\"#$0\": 1, \"transparent\": 1, \"fixed\": 1},\n    \"background-image\": {\"url('/$0')\": 1},\n    \"background-repeat\": {\"repeat\": 1, \"repeat-x\": 1, \"repeat-y\": 1, \"no-repeat\": 1, \"inherit\": 1},\n    \"background-position\": {\"bottom\":2, \"center\":2, \"left\":2, \"right\":2, \"top\":2, \"inherit\":2},\n    \"background-attachment\": {\"scroll\": 1, \"fixed\": 1},\n    \"background-size\": {\"cover\": 1, \"contain\": 1},\n    \"background-clip\": {\"border-box\": 1, \"padding-box\": 1, \"content-box\": 1},\n    \"background-origin\": {\"border-box\": 1, \"padding-box\": 1, \"content-box\": 1},\n    \"border\": {\"solid $0\": 1, \"dashed $0\": 1, \"dotted $0\": 1, \"#$0\": 1},\n    \"border-color\": {\"#$0\": 1},\n    \"border-style\": {\"solid\":2, \"dashed\":2, \"dotted\":2, \"double\":2, \"groove\":2, \"hidden\":2, \"inherit\":2, \"inset\":2, \"none\":2, \"outset\":2, \"ridged\":2},\n    \"border-collapse\": {\"collapse\": 1, \"separate\": 1},\n    \"bottom\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"clear\": {\"left\": 1, \"right\": 1, \"both\": 1, \"none\": 1},\n    \"color\": {\"#$0\": 1, \"rgb(#$00,0,0)\": 1},\n    \"cursor\": {\"default\": 1, \"pointer\": 1, \"move\": 1, \"text\": 1, \"wait\": 1, \"help\": 1, \"progress\": 1, \"n-resize\": 1, \"ne-resize\": 1, \"e-resize\": 1, \"se-resize\": 1, \"s-resize\": 1, \"sw-resize\": 1, \"w-resize\": 1, \"nw-resize\": 1},\n    \"display\": {\"none\": 1, \"block\": 1, \"inline\": 1, \"inline-block\": 1, \"table-cell\": 1},\n    \"empty-cells\": {\"show\": 1, \"hide\": 1},\n    \"float\": {\"left\": 1, \"right\": 1, \"none\": 1},\n    \"font-family\": {\"Arial\":2,\"Comic Sans MS\":2,\"Consolas\":2,\"Courier New\":2,\"Courier\":2,\"Georgia\":2,\"Monospace\":2,\"Sans-Serif\":2, \"Segoe UI\":2,\"Tahoma\":2,\"Times New Roman\":2,\"Trebuchet MS\":2,\"Verdana\": 1},\n    \"font-size\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"font-weight\": {\"bold\": 1, \"normal\": 1},\n    \"font-style\": {\"italic\": 1, \"normal\": 1},\n    \"font-variant\": {\"normal\": 1, \"small-caps\": 1},\n    \"height\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"left\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"letter-spacing\": {\"normal\": 1},\n    \"line-height\": {\"normal\": 1},\n    \"list-style-type\": {\"none\": 1, \"disc\": 1, \"circle\": 1, \"square\": 1, \"decimal\": 1, \"decimal-leading-zero\": 1, \"lower-roman\": 1, \"upper-roman\": 1, \"lower-greek\": 1, \"lower-latin\": 1, \"upper-latin\": 1, \"georgian\": 1, \"lower-alpha\": 1, \"upper-alpha\": 1},\n    \"margin\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"margin-right\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"margin-left\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"margin-top\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"margin-bottom\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"max-height\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"max-width\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"min-height\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"min-width\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"overflow\": {\"hidden\": 1, \"visible\": 1, \"auto\": 1, \"scroll\": 1},\n    \"overflow-x\": {\"hidden\": 1, \"visible\": 1, \"auto\": 1, \"scroll\": 1},\n    \"overflow-y\": {\"hidden\": 1, \"visible\": 1, \"auto\": 1, \"scroll\": 1},\n    \"padding\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"padding-top\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"padding-right\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"padding-bottom\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"padding-left\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"page-break-after\": {\"auto\": 1, \"always\": 1, \"avoid\": 1, \"left\": 1, \"right\": 1},\n    \"page-break-before\": {\"auto\": 1, \"always\": 1, \"avoid\": 1, \"left\": 1, \"right\": 1},\n    \"position\": {\"absolute\": 1, \"relative\": 1, \"fixed\": 1, \"static\": 1},\n    \"right\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"table-layout\": {\"fixed\": 1, \"auto\": 1},\n    \"text-decoration\": {\"none\": 1, \"underline\": 1, \"line-through\": 1, \"blink\": 1},\n    \"text-align\": {\"left\": 1, \"right\": 1, \"center\": 1, \"justify\": 1},\n    \"text-transform\": {\"capitalize\": 1, \"uppercase\": 1, \"lowercase\": 1, \"none\": 1},\n    \"top\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"vertical-align\": {\"top\": 1, \"bottom\": 1},\n    \"visibility\": {\"hidden\": 1, \"visible\": 1},\n    \"white-space\": {\"nowrap\": 1, \"normal\": 1, \"pre\": 1, \"pre-line\": 1, \"pre-wrap\": 1},\n    \"width\": {\"px\": 1, \"em\": 1, \"%\": 1},\n    \"word-spacing\": {\"normal\": 1},\n\n    // opacity\n    \"filter\": {\"alpha(opacity=$0100)\": 1},\n\n    \"text-shadow\": {\"$02px 2px 2px #777\": 1},\n    \"text-overflow\": {\"ellipsis-word\": 1, \"clip\": 1, \"ellipsis\": 1},\n\n    // border radius\n    \"-moz-border-radius\": 1,\n    \"-moz-border-radius-topright\": 1,\n    \"-moz-border-radius-bottomright\": 1,\n    \"-moz-border-radius-topleft\": 1,\n    \"-moz-border-radius-bottomleft\": 1,\n    \"-webkit-border-radius\": 1,\n    \"-webkit-border-top-right-radius\": 1,\n    \"-webkit-border-top-left-radius\": 1,\n    \"-webkit-border-bottom-right-radius\": 1,\n    \"-webkit-border-bottom-left-radius\": 1,\n\n    // dropshadows\n    \"-moz-box-shadow\": 1,\n    \"-webkit-box-shadow\": 1,\n\n    // transformations\n    \"transform\": {\"rotate($00deg)\": 1, \"skew($00deg)\": 1},\n    \"-moz-transform\": {\"rotate($00deg)\": 1, \"skew($00deg)\": 1},\n    \"-webkit-transform\": {\"rotate($00deg)\": 1, \"skew($00deg)\": 1 }\n};\n\nvar CssCompletions = function() {\n\n};\n\n(function() {\n\n    this.completionsDefined = false;\n\n    this.defineCompletions = function() {\n        //fill in missing properties\n        if (document) {\n            var style = document.createElement('c').style;\n\n            for (var i in style) {\n                if (typeof style[i] !== 'string')\n                    continue;\n\n                var name = i.replace(/[A-Z]/g, function(x) {\n                    return '-' + x.toLowerCase();\n                });\n\n                if (!propertyMap.hasOwnProperty(name))\n                    propertyMap[name] = 1;\n            }\n        }\n\n        this.completionsDefined = true;\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        if (!this.completionsDefined) {\n            this.defineCompletions();\n        }\n\n        if (state==='ruleset' || session.$mode.$id == \"ace/mode/scss\") {\n            //css attribute value\n            var line = session.getLine(pos.row).substr(0, pos.column);\n            var inParens = /\\([^)]*$/.test(line);\n            if (inParens) {\n                line = line.substr(line.lastIndexOf('(') + 1);\n            }\n            if (/:[^;]+$/.test(line)) {\n                /([\\w\\-]+):[^:]*$/.test(line);\n\n                return this.getPropertyValueCompletions(state, session, pos, prefix);\n            } else {\n                return this.getPropertyCompletions(state, session, pos, prefix, inParens);\n            }\n        }\n\n        return [];\n    };\n\n    this.getPropertyCompletions = function(state, session, pos, prefix, skipSemicolon) {\n        skipSemicolon = skipSemicolon || false;\n        var properties = Object.keys(propertyMap);\n        return properties.map(function(property){\n            return {\n                caption: property,\n                snippet: property + ': $0' + (skipSemicolon ? '' : ';'),\n                meta: \"property\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getPropertyValueCompletions = function(state, session, pos, prefix) {\n        var line = session.getLine(pos.row).substr(0, pos.column);\n        var property = (/([\\w\\-]+):[^:]*$/.exec(line) || {})[1];\n\n        if (!property)\n            return [];\n        var values = [];\n        if (property in propertyMap && typeof propertyMap[property] === \"object\") {\n            values = Object.keys(propertyMap[property]);\n        }\n        return values.map(function(value){\n            return {\n                caption: value,\n                snippet: value,\n                meta: \"property value\",\n                score: 1000000\n            };\n        });\n    };\n\n}).call(CssCompletions.prototype);\n\nexports.CssCompletions = CssCompletions;\n"
  },
  {
    "path": "src/mode/css_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\n/* Exports are for Stylus and Less highlighters */\nvar supportType = exports.supportType = \"align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index\";\nvar supportFunction = exports.supportFunction = \"rgb|rgba|url|attr|counter|counters\";\nvar supportConstant = exports.supportConstant = \"absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom\";\nvar supportConstantColor = exports.supportConstantColor = \"aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen\";\nvar supportConstantFonts = exports.supportConstantFonts = \"arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace\";\n\nvar numRe = exports.numRe = \"\\\\-?(?:(?:[0-9]+(?:\\\\.[0-9]+)?)|(?:\\\\.[0-9]+))\";\nvar pseudoElements = exports.pseudoElements = \"(\\\\:+)\\\\b(after|before|first-letter|first-line|moz-selection|selection)\\\\b\";\nvar pseudoClasses  = exports.pseudoClasses =  \"(:)\\\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\\\b\";\n\nvar CssHighlightRules = function() {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": supportFunction,\n        \"support.constant\": supportConstant,\n        \"support.type\": supportType,\n        \"support.constant.color\": supportConstantColor,\n        \"support.constant.fonts\": supportConstantFonts\n    }, \"text\", true);\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [{\n            include : [\"strings\", \"url\", \"comments\"]\n        }, {\n            token: \"paren.lparen\",\n            regex: \"\\\\{\",\n            next:  \"ruleset\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"\\\\}\"\n        }, {\n            token: \"string\",\n            regex: \"@(?!viewport)\",\n            next:  \"media\"\n        }, {\n            token: \"keyword\",\n            regex: \"#[a-z0-9-_]+\"\n        }, {\n            token: \"keyword\",\n            regex: \"%\"\n        }, {\n            token: \"variable\",\n            regex: \"\\\\.[a-z0-9-_]+\"\n        }, {\n            token: \"string\",\n            regex: \":[a-z0-9-_]+\"\n        }, {\n            token : \"constant.numeric\",\n            regex : numRe\n        }, {\n            token: \"constant\",\n            regex: \"[a-z0-9-_]+\"\n        }, {\n            caseInsensitive: true\n        }],\n\n        \"media\": [{\n            include : [\"strings\", \"url\", \"comments\"]\n        }, {\n            token: \"paren.lparen\",\n            regex: \"\\\\{\",\n            next:  \"start\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"\\\\}\",\n            next:  \"start\"\n        }, {\n            token: \"string\",\n            regex: \";\",\n            next:  \"start\"\n        }, {\n            token: \"keyword\",\n            regex: \"(?:media|supports|document|charset|import|namespace|media|supports|document\"\n                + \"|page|font|keyframes|viewport|counter-style|font-feature-values\"\n                + \"|swash|ornaments|annotation|stylistic|styleset|character-variant)\"\n        }],\n\n        \"comments\" : [{\n            token: \"comment\", // multi line comment\n            regex: \"\\\\/\\\\*\",\n            push: [{\n                token : \"comment\",\n                regex : \"\\\\*\\\\/\",\n                next : \"pop\"\n            }, {\n                defaultToken : \"comment\"\n            }]\n        }],\n\n        \"ruleset\" : [{\n            regex : \"-(webkit|ms|moz|o)-\",\n            token : \"text\"\n        }, {\n            token : \"punctuation.operator\",\n            regex : \"[:;]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"\\\\}\",\n            next : \"start\"\n        }, {\n            include : [\"strings\", \"url\", \"comments\"]\n        }, {\n            token : [\"constant.numeric\", \"keyword\"],\n            regex : \"(\" + numRe + \")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)\"\n        }, {\n            token : \"constant.numeric\",\n            regex : numRe\n        }, {\n            token : \"constant.numeric\",  // hex6 color\n            regex : \"#[a-f0-9]{6}\"\n        }, {\n            token : \"constant.numeric\", // hex3 color\n            regex : \"#[a-f0-9]{3}\"\n        }, {\n            token : [\"punctuation\", \"entity.other.attribute-name.pseudo-element.css\"],\n            regex : pseudoElements\n        }, {\n            token : [\"punctuation\", \"entity.other.attribute-name.pseudo-class.css\"],\n            regex : pseudoClasses\n        }, {\n            include: \"url\"\n        }, {\n            token : keywordMapper,\n            regex : \"\\\\-?[a-zA-Z_][a-zA-Z0-9_\\\\-]*\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"\\\\{\"\n        }, {\n            caseInsensitive: true\n        }],\n\n        url: [{\n            token : \"support.function\",\n            regex : \"(?:url(:?-prefix)?|domain|regexp)\\\\(\",\n            push: [{\n                token : \"support.function\",\n                regex : \"\\\\)\",\n                next : \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }],\n\n        strings: [{\n            token : \"string.start\",\n            regex : \"'\",\n            push : [{\n                token : \"string.end\",\n                regex : \"'|$\",\n                next: \"pop\"\n            }, {\n                include : \"escapes\"\n            }, {\n                token : \"constant.language.escape\",\n                regex : /\\\\$/,\n                consumeLineEnd: true\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token : \"string.start\",\n            regex : '\"',\n            push : [{\n                token : \"string.end\",\n                regex : '\"|$',\n                next: \"pop\"\n            }, {\n                include : \"escapes\"\n            }, {\n                token : \"constant.language.escape\",\n                regex : /\\\\$/,\n                consumeLineEnd: true\n            }, {\n                defaultToken: \"string\"\n            }]\n        }],\n        escapes: [{\n            token : \"constant.language.escape\",\n            regex : /\\\\([a-fA-F\\d]{1,6}|[^a-fA-F\\d])/\n        }]\n\n    };\n\n    this.normalizeRules();\n};\n\noop.inherits(CssHighlightRules, TextHighlightRules);\n\nexports.CssHighlightRules = CssHighlightRules;\n"
  },
  {
    "path": "src/mode/css_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar CssMode = require(\"./css\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    \n    name: \"CSS\",\n    \n    setUp : function() {\n        this.mode = new CssMode();\n    },\n\n    \"test: toggle comment lines\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\", \"fg\"].join(\"\\n\"));\n\n        var comment = this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"/*  abc*/\", \"/*cde*/\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n\n    \"test: lines should keep indentation\" : function() {\n        assert.equal(\"   \", this.mode.getNextLineIndent(\"start\", \"   abc\", \"  \"));\n        assert.equal(\"\\t\", this.mode.getNextLineIndent(\"start\", \"\\tabc\", \"  \"));\n    },\n\n    \"test: new line after { should increase indent\" : function() {\n        assert.equal(\"     \", this.mode.getNextLineIndent(\"start\", \"   abc{\", \"  \"));\n        assert.equal(\"\\t  \", this.mode.getNextLineIndent(\"start\", \"\\tabc  { \", \"  \"));\n    },\n\n    \"test: no indent increase after { in a comment\" : function() {\n        assert.equal(\"   \", this.mode.getNextLineIndent(\"start\", \"   /*{\", \"  \"));\n        assert.equal(\"   \", this.mode.getNextLineIndent(\"start\", \"   /*{  \", \"  \"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/csv.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar escapeRegExp = require(\"../lib/lang\").escapeRegExp;\nvar CsvHighlightRules = require(\"./csv_highlight_rules\").CsvHighlightRules;\n\nvar Mode = function(options) {\n    this.HighlightRules = CsvHighlightRules;\n    if (!options) options = {};\n    var separatorRegex = [options.splitter || \",\", options.quote || '\"']\n        .map(escapeRegExp).join(\"|\");\n    this.$tokenizer = {\n        getLineTokens: function(line, state, row) {\n            return tokenizeCsv(line, state, this.options);\n        },\n        options: {\n            quotes: options.quote || '\"',\n            separatorRegex: new RegExp(\"(\" + separatorRegex + \")\"),\n            spliter: options.splitter || \",\"\n        },\n        states: {},\n    };\n    this.$highlightRules = new this.HighlightRules();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.getTokenizer = function() {\n        return this.$tokenizer;\n    };\n\n    this.$id = \"ace/mode/csv\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n\n\nvar classNames = [\"keyword\", \"text\", \"string\", \"string.regex\", \"variable\", \"constant.numeric\"];\n\nfunction tokenizeCsv(line, state, options) {\n    var result = [];\n    var parts = line.split(options.separatorRegex);\n    var spliter = options.spliter;\n    var quote = options.quote || '\"';\n    var stateParts = (state||\"start\").split(\"-\");\n    var column = parseInt(stateParts[1]) || 0;\n    var inString = stateParts[0] == 'string';\n    var atColumnStart = !inString;\n    for (var i = 0; i < parts.length; i++) {\n        var value = parts[i];\n        if (value) {\n            var isSeparator = false;\n            if (value == spliter && !inString) {\n                column++;\n                atColumnStart = true;\n                isSeparator = true;\n            } \n            else if (value == quote) {\n                if (atColumnStart) {\n                    inString = true;\n                    atColumnStart = false;\n                } else if (inString) {\n                    if (parts[i + 1] == '' && parts[i + 2] == quote) {\n                        value = quote + quote;\n                        i += 2;\n                    } else {\n                        inString = false;\n                    }\n                }\n            }\n            else {\n                atColumnStart = false;\n            }\n\n            result.push(\n                {\n                    value: value,\n                    type: classNames[column % classNames.length] + \".csv_\" + column + (isSeparator ? \".csv_separator\" : \"\")\n                }\n            );\n        }\n    }\n    return { tokens: result, state: inString ? \"string-\" + column : \"start\" };\n\n}"
  },
  {
    "path": "src/mode/csv_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\nvar CsvHighlightRules = function() {\n    TextHighlightRules.call(this);\n};\n\noop.inherits(CsvHighlightRules, TextHighlightRules);\n\nexports.CsvHighlightRules = CsvHighlightRules;\n"
  },
  {
    "path": "src/mode/curly.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n// defines the parent mode\nvar HtmlMode = require(\"./html\").Mode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar HtmlFoldMode = require(\"./folding/html\").FoldMode;\n\n// defines the language specific highlighters and folding rules\nvar CurlyHighlightRules = require(\"./curly_highlight_rules\").CurlyHighlightRules;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = CurlyHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new HtmlFoldMode();\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.$id = \"ace/mode/curly\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/curly_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\n\nvar CurlyHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    this.$rules[\"start\"].unshift({\n        token: \"variable\",\n        regex: \"{{\",\n        push: \"curly-start\"\n    });\n\n    this.$rules[\"curly-start\"] = [{\n        token: \"variable\",\n        regex: \"}}\",\n        next: \"pop\"\n    }];\n\n    this.normalizeRules();\n};\n\noop.inherits(CurlyHighlightRules, HtmlHighlightRules);\n\nexports.CurlyHighlightRules = CurlyHighlightRules;\n"
  },
  {
    "path": "src/mode/cuttlefish.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CuttlefishHighlightRules = require(\"./cuttlefish_highlight_rules\").CuttlefishHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = CuttlefishHighlightRules;\n    this.foldingRules = null;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/cuttlefish\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/cuttlefish_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\nvar CuttlefishHighlightRules = function () {\n    this.$rules = {\n        start: [{\n            token: ['text', 'comment'],\n            regex: /^([ \\t]*)(#.*)$/\n        }, {\n            token: ['text', 'keyword', 'text', 'string', 'text', 'comment'],\n            regex: /^([ \\t]*)(include)([ \\t]*)([A-Za-z0-9-\\_\\.\\*\\/]+)([ \\t]*)(#.*)?$/\n        }, {\n            token: ['text', 'keyword', 'text', 'operator', 'text', 'string', 'text', 'comment'],\n            regex: /^([ \\t]*)([A-Za-z0-9-_]+(?:\\.[A-Za-z0-9-_]+)*)([ \\t]*)(=)([ \\t]*)([^ \\t#][^#]*?)([ \\t]*)(#.*)?$/\n        }, {\n            defaultToken: 'invalid'\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nCuttlefishHighlightRules.metaData = {\n    fileTypes: ['conf'],\n    keyEquivalent: '^~C',\n    name: 'Cuttlefish',\n    scopeName: 'source.conf'\n};\n\n\noop.inherits(CuttlefishHighlightRules, TextHighlightRules);\n\nexports.CuttlefishHighlightRules = CuttlefishHighlightRules;\n"
  },
  {
    "path": "src/mode/d.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar DHighlightRules = require(\"./d_highlight_rules\").DHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = DHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/d\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/d_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar DHighlightRules = function() {\n\n    var keywords = (\n        \"this|super|import|module|body|mixin|__traits|invariant|alias|asm|delete|\"+\n        \"typeof|typeid|sizeof|cast|new|in|is|typedef|__vector|__parameters\"\n    );\n\n    var keywordControls = (\n        \"break|case|continue|default|do|else|for|foreach|foreach_reverse|goto|if|\" +\n        \"return|switch|while|catch|try|throw|finally|version|assert|unittest|with\"\n    );\n    \n    var types = (\n        \"auto|bool|char|dchar|wchar|byte|ubyte|float|double|real|\" +\n        \"cfloat|creal|cdouble|cent|ifloat|ireal|idouble|\" +\n        \"int|long|short|void|uint|ulong|ushort|ucent|\" +\n        \"function|delegate|string|wstring|dstring|size_t|ptrdiff_t|hash_t|Object\"\n    );\n\n    var modifiers = (\n        \"abstract|align|debug|deprecated|export|extern|const|final|in|inout|out|\" +\n        \"ref|immutable|lazy|nothrow|override|package|pragma|private|protected|\" +\n        \"public|pure|scope|shared|__gshared|synchronized|static|volatile\"\n    );\n    \n    var storages = (\n        \"class|struct|union|template|interface|enum|macro\"\n    );\n    \n    var stringEscapesSeq =  {\n        token: \"constant.language.escape\",\n        regex: \"\\\\\\\\(?:(?:x[0-9A-F]{2})|(?:[0-7]{1,3})|(?:['\\\"\\\\?0abfnrtv\\\\\\\\])|\" +\n            \"(?:u[0-9a-fA-F]{4})|(?:U[0-9a-fA-F]{8}))\"\n    };\n\n    var builtinConstants = (\n        \"null|true|false|\"+\n        \"__DATE__|__EOF__|__TIME__|__TIMESTAMP__|__VENDOR__|__VERSION__|\"+\n        \"__FILE__|__MODULE__|__LINE__|__FUNCTION__|__PRETTY_FUNCTION__\"\n    );\n    \n    var operators = (\n        \"/|/\\\\=|&|&\\\\=|&&|\\\\|\\\\|\\\\=|\\\\|\\\\||\\\\-|\\\\-\\\\=|\\\\-\\\\-|\\\\+|\" +\n        \"\\\\+\\\\=|\\\\+\\\\+|\\\\<|\\\\<\\\\=|\\\\<\\\\<|\\\\<\\\\<\\\\=|\\\\<\\\\>|\\\\<\\\\>\\\\=|\\\\>|\\\\>\\\\=|\\\\>\\\\>\\\\=|\" +\n        \"\\\\>\\\\>\\\\>\\\\=|\\\\>\\\\>|\\\\>\\\\>\\\\>|\\\\!|\\\\!\\\\=|\\\\!\\\\<\\\\>|\\\\!\\\\<\\\\>\\\\=|\\\\!\\\\<|\\\\!\\\\<\\\\=|\" +\n        \"\\\\!\\\\>|\\\\!\\\\>\\\\=|\\\\?|\\\\$|\\\\=|\\\\=\\\\=|\\\\*|\\\\*\\\\=|%|%\\\\=|\" +\n        \"\\\\^|\\\\^\\\\=|\\\\^\\\\^|\\\\^\\\\^\\\\=|~|~\\\\=|\\\\=\\\\>|#\"\n    );\n\n    var keywordMapper = this.$keywords = this.createKeywordMapper({\n        \"keyword.modifier\" : modifiers,\n        \"keyword.control\" :  keywordControls,\n        \"keyword.type\" :     types,\n        \"keyword\":           keywords,\n        \"keyword.storage\":   storages,\n        \"punctation\": \"\\\\.|\\\\,|;|\\\\.\\\\.|\\\\.\\\\.\\\\.\",\n        \"keyword.operator\" : operators,\n        \"constant.language\": builtinConstants\n    }, \"identifier\");\n    \n    var identifierRe = \"[a-zA-Z_\\u00a1-\\uffff][a-zA-Z\\\\d_\\u00a1-\\uffff]*\\\\b\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {     //-------------------------------------------------------- COMMENTS\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"star-comment\"\n            }, {\n                token: \"comment.shebang\",\n                regex: \"^\\\\s*#!.*\"\n            }, {\n                token : \"comment\",\n                regex : \"\\\\/\\\\+\",\n                next: \"plus-comment\"\n            }, {  //-------------------------------------------------------- STRINGS\n                onMatch: function(value, currentState, state) {\n                    state.unshift(this.next, value.substr(2));\n                    return \"string\";\n                },\n                regex: 'q\"(?:[\\\\[\\\\(\\\\{\\\\<]+)',\n                next: 'operator-heredoc-string'\n            }, {\n                onMatch: function(value, currentState, state) {\n                    state.unshift(this.next, value.substr(2));\n                    return \"string\";\n                },\n                regex: 'q\"(?:[a-zA-Z_]+)$',\n                next: 'identifier-heredoc-string'\n            }, {\n                token : \"string\", // multi line string start\n                regex : '[xr]?\"',\n                next : \"quote-string\"\n            }, {\n                token : \"string\", // multi line string start\n                regex : '[xr]?`',\n                next : \"backtick-string\"\n            }, {\n                token : \"string\", // single line\n                regex : \"[xr]?['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?['][cdw]?\"\n            }, {  //-------------------------------------------------------- RULES\n                token: [\"keyword\", \"text\", \"paren.lparen\"],\n                regex: /(asm)(\\s*)({)/,\n                next: \"d-asm\"\n            }, {\n                token: [\"keyword\", \"text\", \"paren.lparen\", \"constant.language\"],\n                regex: \"(__traits)(\\\\s*)(\\\\()(\"+identifierRe+\")\"\n            }, { // import|module abc\n                token: [\"keyword\", \"text\", \"variable.module\"],\n                regex: \"(import|module)(\\\\s+)((?:\"+identifierRe+\"\\\\.?)*)\"\n            }, { // storage Name\n                token: [\"keyword.storage\", \"text\", \"entity.name.type\"],\n                regex: \"(\"+storages+\")(\\\\s*)(\"+identifierRe+\")\"\n            }, { // alias|typedef foo bar;\n                token: [\"keyword\", \"text\", \"variable.storage\", \"text\"],\n                regex: \"(alias|typedef)(\\\\s*)(\"+identifierRe+\")(\\\\s*)\"\n            }, {  //-------------------------------------------------------- OTHERS\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F_]+(l|ul|u|f|F|L|U|UL)?\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d[\\\\d_]*(?:(?:\\\\.[\\\\d_]*)?(?:[eE][+-]?[\\\\d_]+)?)?(l|ul|u|f|F|L|U|UL)?\\\\b\"\n            }, {\n                token: \"entity.other.attribute-name\",\n                regex: \"@\"+identifierRe\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_][a-zA-Z0-9_]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : operators\n            }, {\n                token : \"punctuation.operator\",\n                regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.|\\\\:\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"star-comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken: 'comment'\n            }\n        ],\n        \"plus-comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\+\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken: 'comment'\n            }\n        ],\n        \n        \"quote-string\" : [\n           stringEscapesSeq,\n           {\n                token : \"string\",\n                regex : '\"[cdw]?',\n                next : \"start\"\n            }, {\n                defaultToken: 'string'\n            }\n        ],\n        \n        \"backtick-string\" : [\n           stringEscapesSeq,\n           {\n                token : \"string\",\n                regex : '`[cdw]?',\n                next : \"start\"\n            }, {\n                defaultToken: 'string'\n            }\n        ],\n        \n        \"operator-heredoc-string\": [\n            {\n                onMatch: function(value, currentState, state) {\n                    value = value.substring(value.length-2, value.length-1);\n                    var map = {'>':'<',']':'[',')':'(','}':'{'};\n                    if(Object.keys(map).indexOf(value) != -1)\n                        value = map[value];\n                    if(value != state[1]) return \"string\";\n                    state.shift();\n                    state.shift();\n                    \n                    return \"string\";\n                },\n                regex: '(?:[\\\\]\\\\)}>]+)\"',\n                next: 'start'\n            }, {\n                token: 'string',\n                regex: '[^\\\\]\\\\)}>]+'\n            }\n        ],\n        \n        \"identifier-heredoc-string\": [\n            {\n                onMatch: function(value, currentState, state) {\n                    value = value.substring(0, value.length-1);\n                    if(value != state[1]) return \"string\";\n                    state.shift();\n                    state.shift();\n                    \n                    return \"string\";\n                },\n                regex: '^(?:[A-Za-z_][a-zA-Z0-9]+)\"',\n                next: 'start'\n            }, {\n                token: 'string',\n                regex: '[^\\\\]\\\\)}>]+'\n            }\n        ],\n        \n        \"d-asm\": [\n            {\n                token: \"paren.rparen\",\n                regex: \"\\\\}\",\n                next: \"start\"\n            }, {\n                token: 'keyword.instruction',\n                regex: '[a-zA-Z]+',\n                next: 'd-asm-instruction' \n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }\n        ],\n        \n        // minimal asm support\n        'd-asm-instruction': [\n            {\n                token: 'constant.language',\n                regex: /AL|AH|AX|EAX|BL|BH|BX|EBX|CL|CH|CX|ECX|DL|DH|DX|EDX|BP|EBP|SP|ESP|DI|EDI|SI|ESI/i\n            }, {\n                token: 'identifier',\n                regex: '[a-zA-Z]+'\n            }, {\n                token: 'string',\n                regex: '\"[^\"]*\"'\n            }, {\n                token: 'comment',\n                regex: '//.*$'\n            }, {\n                token: 'constant.numeric',\n                regex: '[0-9.xA-F]+'\n            }, {\n                token: 'punctuation.operator',\n                regex: '\\\\,'\n            }, {\n                token: 'punctuation.operator',\n                regex: ';',\n                next: 'd-asm'\n            }, {\n                token: 'text',\n                regex: '\\\\s+'\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\nDHighlightRules.metaData = {\n      comment: 'D language',\n      fileTypes: [ 'd', 'di' ],\n      firstLineMatch: '^#!.*\\\\b[glr]?dmd\\\\b.',\n      foldingStartMarker: '(?x)/\\\\*\\\\*(?!\\\\*)|^(?![^{]*?//|[^{]*?/\\\\*(?!.*?\\\\*/.*?\\\\{)).*?\\\\{\\\\s*($|//|/\\\\*(?!.*?\\\\*/.*\\\\S))',\n      foldingStopMarker: '(?<!\\\\*)\\\\*\\\\*/|^\\\\s*\\\\}',\n      keyEquivalent: '^~D',\n      name: 'D',\n      scopeName: 'source.d'\n};\noop.inherits(DHighlightRules, TextHighlightRules);\n\nexports.DHighlightRules = DHighlightRules;\n"
  },
  {
    "path": "src/mode/dart.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar CMode = require(\"./c_cpp\").Mode;\nvar DartHighlightRules = require(\"./dart_highlight_rules\").DartHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    CMode.call(this);\n    this.HighlightRules = DartHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, CMode);\n\n(function() { \n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/dart\";\n    this.snippetFileId = \"ace/snippets/dart\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/dart_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: 958518BC-799F-477A-99F9-5B28EBF230F6) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar DartHighlightRules = function() {\n\n    var constantLanguage = \"true|false|null\";\n    var variableLanguage = \"this|super\";\n    var keywordControl = \"try|catch|finally|throw|rethrow|assert|break|case|continue|default|do|else|for|if|in|return|switch|while|new|deferred|async|await\";\n    var keywordDeclaration = \"abstract|class|extends|external|factory|implements|get|native|operator|set|typedef|with|enum\";\n    var storageModifier = \"static|final|const\";\n    var storageType = \"void|bool|num|int|double|dynamic|var|String\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"constant.language.dart\": constantLanguage,\n        \"variable.language.dart\": variableLanguage,\n        \"keyword.control.dart\": keywordControl,\n        \"keyword.declaration.dart\": keywordDeclaration,\n        \"storage.modifier.dart\": storageModifier,\n        \"storage.type.primitive.dart\": storageType\n    }, \"identifier\");\n\n    var stringfill = [{\n        token : \"constant.language.escape\",\n        regex : /\\\\./\n    }, {\n        token : \"text\",\n        regex : /\\$(?:\\w+|{[^\"'}]+})?/\n    }, {\n        defaultToken : \"string\"\n    }];\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n    \"start\": [\n        {\n            token : \"comment\",\n            regex : /\\/\\/.*$/\n        },\n        DocCommentHighlightRules.getStartRule(\"doc-start\"),\n        {\n            token : \"comment\", // multi line comment\n            regex : /\\/\\*/,\n            next : \"comment\"\n        },\n        {\n            token: [\"meta.preprocessor.script.dart\"],\n            regex: \"^(#!.*)$\"\n        },\n        {\n            token: \"keyword.other.import.dart\",\n            regex: \"(?:\\\\b)(?:library|import|export|part|of|show|hide)(?:\\\\b)\"\n        },\n        {\n            token : [\"keyword.other.import.dart\", \"text\"],\n            regex : \"(?:\\\\b)(prefix)(\\\\s*:)\"\n        },\n        {\n            regex: \"\\\\bas\\\\b\",\n            token: \"keyword.cast.dart\"\n        },\n        {\n            regex: \"\\\\?|:\",\n            token: \"keyword.control.ternary.dart\"\n        },\n        {\n            regex: \"(?:\\\\b)(is\\\\!?)(?:\\\\b)\",\n            token: [\"keyword.operator.dart\"]\n        },\n        {\n            regex: \"(<<|>>>?|~|\\\\^|\\\\||&)\",\n            token: [\"keyword.operator.bitwise.dart\"]\n        },\n        {\n            regex: \"((?:&|\\\\^|\\\\||<<|>>>?)=)\",\n            token: [\"keyword.operator.assignment.bitwise.dart\"]\n        },\n        {\n            regex: \"(===?|!==?|<=?|>=?)\",\n            token: [\"keyword.operator.comparison.dart\"]\n        },\n        {\n            regex: \"((?:[+*/%-]|\\\\~)=)\",\n            token: [\"keyword.operator.assignment.arithmetic.dart\"]\n        },\n        {\n            regex: \"=\",\n            token: \"keyword.operator.assignment.dart\"\n        },\n        {\n            token : \"string\",\n            regex : \"'''\",\n            next : \"qdoc\"\n        }, \n        {\n            token : \"string\",\n            regex : '\"\"\"',\n            next : \"qqdoc\"\n        }, \n        {\n            token : \"string\",\n            regex : \"'\",\n            next : \"qstring\"\n        }, \n        {\n            token : \"string\",\n            regex : '\"',\n            next : \"qqstring\"\n        }, \n        {\n            regex: \"(\\\\-\\\\-|\\\\+\\\\+)\",\n            token: [\"keyword.operator.increment-decrement.dart\"]\n        },\n        {\n            regex: \"(\\\\-|\\\\+|\\\\*|\\\\/|\\\\~\\\\/|%)\",\n            token: [\"keyword.operator.arithmetic.dart\"]\n        },\n        {\n            regex: \"(!|&&|\\\\|\\\\|)\",\n            token: [\"keyword.operator.logical.dart\"]\n        },\n        {\n            token : \"constant.numeric\", // hex\n            regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n        }, \n        {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, \n        {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }\n    ],\n    \"comment\" : [\n        {\n            token : \"comment\", // closing comment\n            regex : \"\\\\*\\\\/\",\n            next : \"start\"\n        }, {\n            defaultToken : \"comment\"\n        }\n    ],\n    \"qdoc\" : [\n        {\n            token : \"string\",\n            regex : \"'''\",\n            next : \"start\"\n        }\n    ].concat(stringfill),\n\n    \"qqdoc\" : [\n        {\n            token : \"string\",\n            regex : '\"\"\"',\n            next : \"start\"\n        }\n    ].concat(stringfill),\n\n    \"qstring\" : [\n        {\n            token : \"string\",\n            regex : \"'|$\",\n            next : \"start\"\n        }\n    ].concat(stringfill),\n\n    \"qqstring\" : [\n        {\n            token : \"string\",\n            regex : '\"|$',\n            next : \"start\"\n        }\n    ].concat(stringfill)\n    // TODO add support for interpolation and raw strings\n};\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(DartHighlightRules, TextHighlightRules);\n\nexports.DartHighlightRules = DartHighlightRules;\n"
  },
  {
    "path": "src/mode/diff.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./diff_highlight_rules\").DiffHighlightRules;\nvar FoldMode = require(\"./folding/diff\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.foldingRules = new FoldMode([\"diff\", \"@@|\\\\*{5}\"], \"i\");\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.$id = \"ace/mode/diff\";\n    this.snippetFileId = \"ace/snippets/diff\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/diff_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar DiffHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [{\n                regex: \"^(?:\\\\*{15}|={67}|-{3}|\\\\+{3})$\",\n                token: \"punctuation.definition.separator.diff\",\n                \"name\": \"keyword\"\n            }, { //diff.range.unified\n                regex: \"^(@@)(\\\\s*.+?\\\\s*)(@@)(.*)$\",\n                token: [\n                    \"constant\",\n                    \"constant.numeric\",\n                    \"constant\",\n                    \"comment.doc.tag\"\n                ]\n            }, { //diff.range.normal\n                regex: \"^(\\\\d+)([,\\\\d]+)(a|d|c)(\\\\d+)([,\\\\d]+)(.*)$\",\n                token: [\n                    \"constant.numeric\",\n                    \"punctuation.definition.range.diff\",\n                    \"constant.function\",\n                    \"constant.numeric\",\n                    \"punctuation.definition.range.diff\",\n                    \"invalid\"\n                ],\n                \"name\": \"meta.\"\n            }, {\n                regex: \"^(\\\\-{3}|\\\\+{3}|\\\\*{3})( .+)$\",\n                token: [\n                    \"constant.numeric\",\n                    \"meta.tag\"\n                ]\n            }, { // added\n                regex: \"^([!+>])(.*?)(\\\\s*)$\",\n                token: [\n                    \"support.constant\",\n                    \"text\",\n                    \"invalid\"\n                ]\n            }, { // removed\n                regex: \"^([<\\\\-])(.*?)(\\\\s*)$\",\n                token: [\n                    \"support.function\",\n                    \"string\",\n                    \"invalid\"\n                ]\n            }, {\n                regex: \"^(diff)(\\\\s+--\\\\w+)?(.+?)( .+)?$\",\n                token: [\"variable\", \"variable\", \"keyword\", \"variable\"]\n            }, {\n                regex: \"^Index.+$\",\n                token: \"variable\"\n            }, {\n                regex: \"^\\\\s+$\",\n                token: \"text\"\n            }, {\n                regex: \"\\\\s*$\",\n                token: \"invalid\"\n            }, {\n                defaultToken: \"invisible\",\n                caseInsensitive: true\n            }\n        ]\n    };\n};\n\noop.inherits(DiffHighlightRules, TextHighlightRules);\n\nexports.DiffHighlightRules = DiffHighlightRules;\n"
  },
  {
    "path": "src/mode/django.js",
    "content": "var oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar DjangoHighlightRules = function(){\n    this.$rules = {\n        'start': [{\n            token: \"string\",\n            regex: '\".*?\"'\n        }, {\n            token: \"string\",\n            regex: \"'.*?'\"\n        }, {\n            token: \"constant\",\n            regex: '[0-9]+'\n        }, {\n            token: \"variable\",\n            regex: \"[-_a-zA-Z0-9:]+\"\n        }],\n        'tag': [{\n            token: \"entity.name.function\",\n            regex: \"[a-zA-Z][_a-zA-Z0-9]*\",\n            next: \"start\"\n        }]\n    };\n};\n\noop.inherits(DjangoHighlightRules, TextHighlightRules);\n\nvar DjangoHtmlHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    var startRules = [\n        {\n            token: \"comment.line\",\n            regex: \"\\\\{#.*?#\\\\}\"\n        }, {\n            token: \"comment.block\",\n            regex: \"\\\\{\\\\%\\\\s*comment\\\\s*\\\\%\\\\}\",\n            push: [{\n                token: \"comment.block\",\n                regex: \"\\\\{\\\\%\\\\s*endcomment\\\\s*\\\\%\\\\}\",\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block\"\n            }]\n        }, {\n            token: \"constant.language\",\n            regex: \"\\\\{\\\\{\",\n            push: \"django-start\"\n        }, {\n            token: \"constant.language\",\n            regex: \"\\\\{\\\\%\",\n            push: \"django-tag\"\n        }\n    ];\n    var endRules = [\n        {\n            token: \"constant.language\",\n            regex: \"\\\\%\\\\}\",\n            next: \"pop\"\n        }, {\n            token: \"constant.language\",\n            regex: \"\\\\}\\\\}\",\n            next: \"pop\"\n        }\n    ];\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n    this.embedRules(DjangoHighlightRules, \"django-\", endRules, [\"start\"]);\n    this.normalizeRules();\n};\n\noop.inherits(DjangoHtmlHighlightRules, HtmlHighlightRules);\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = DjangoHtmlHighlightRules;\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.$id = \"ace/mode/django\";\n    this.snippetFileId = \"ace/snippets/django\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/doc_comment_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar DocCommentHighlightRules = function () {\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"comment.doc.tag\",\n                regex: \"@\\\\w+(?=\\\\s|$)\"\n            }, DocCommentHighlightRules.getTagRule(), {\n                defaultToken: \"comment.doc.body\",\n                caseInsensitive: true\n            }\n        ]\n    };\n};\n\noop.inherits(DocCommentHighlightRules, TextHighlightRules);\n\nDocCommentHighlightRules.getTagRule = function(start) {\n    return {\n        token : \"comment.doc.tag.storage.type\",\n        regex : \"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"\n    };\n};\n\nDocCommentHighlightRules.getStartRule = function(start) {\n    return {\n        token : \"comment.doc\", // doc comment\n        regex: /\\/\\*\\*(?!\\/)/,\n        next  : start\n    };\n};\n\nDocCommentHighlightRules.getEndRule = function (start) {\n    return {\n        token : \"comment.doc\", // closing comment\n        regex : \"\\\\*\\\\/\",\n        next  : start\n    };\n};\n\n\nexports.DocCommentHighlightRules = DocCommentHighlightRules;\n"
  },
  {
    "path": "src/mode/dockerfile.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar ShMode = require(\"./sh\").Mode;\nvar DockerfileHighlightRules = require(\"./dockerfile_highlight_rules\").DockerfileHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    ShMode.call(this);\n    \n    this.HighlightRules = DockerfileHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, ShMode);\n\n(function() {\n    this.$id = \"ace/mode/dockerfile\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/dockerfile_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar ShHighlightRules = require(\"./sh_highlight_rules\").ShHighlightRules;\n\nvar DockerfileHighlightRules = function() {\n    ShHighlightRules.call(this);\n\n    var startRules = this.$rules.start;\n    for (var i = 0; i < startRules.length; i++) {\n        if (startRules[i].token == \"variable.language\") {\n            startRules.splice(i, 0, {\n                token: \"constant.language\",\n                regex: \"(?:^(?:FROM|MAINTAINER|RUN|CMD|EXPOSE|ENV|ADD|ENTRYPOINT|VOLUME|USER|WORKDIR|ONBUILD|COPY|LABEL)\\\\b)\",\n                caseInsensitive: true\n            });\n            break;\n        }\n    }\n    \n};\n\noop.inherits(DockerfileHighlightRules, ShHighlightRules);\n\nexports.DockerfileHighlightRules = DockerfileHighlightRules;\n"
  },
  {
    "path": "src/mode/dot.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar DotHighlightRules = require(\"./dot_highlight_rules\").DotHighlightRules;\nvar DotFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = DotHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new DotFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = [\"//\", \"#\"];\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*(?:\\bcase\\b.*:|[\\{\\(\\[])\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/dot\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/dot_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n\nvar DotHighlightRules = function() {\n\n   var keywords = lang.arrayToMap(\n        (\"strict|node|edge|graph|digraph|subgraph\").split(\"|\")\n   );\n\n   var attributes = lang.arrayToMap(\n        (\"damping|k|url|area|arrowhead|arrowsize|arrowtail|aspect|bb|bgcolor|center|charset|clusterrank|color|colorscheme|comment|compound|concentrate|constraint|decorate|defaultdist|dim|dimen|dir|diredgeconstraints|distortion|dpi|edgeurl|edgehref|edgetarget|edgetooltip|epsilon|esep|fillcolor|fixedsize|fontcolor|fontname|fontnames|fontpath|fontsize|forcelabels|gradientangle|group|headurl|head_lp|headclip|headhref|headlabel|headport|headtarget|headtooltip|height|href|id|image|imagepath|imagescale|label|labelurl|label_scheme|labelangle|labeldistance|labelfloat|labelfontcolor|labelfontname|labelfontsize|labelhref|labeljust|labelloc|labeltarget|labeltooltip|landscape|layer|layerlistsep|layers|layerselect|layersep|layout|len|levels|levelsgap|lhead|lheight|lp|ltail|lwidth|margin|maxiter|mclimit|mindist|minlen|mode|model|mosek|nodesep|nojustify|normalize|nslimit|nslimit1|ordering|orientation|outputorder|overlap|overlap_scaling|pack|packmode|pad|page|pagedir|pencolor|penwidth|peripheries|pin|pos|quadtree|quantum|rank|rankdir|ranksep|ratio|rects|regular|remincross|repulsiveforce|resolution|root|rotate|rotation|samehead|sametail|samplepoints|scale|searchsize|sep|shape|shapefile|showboxes|sides|size|skew|smoothing|sortv|splines|start|style|stylesheet|tailurl|tail_lp|tailclip|tailhref|taillabel|tailport|tailtarget|tailtooltip|target|tooltip|truecolor|vertices|viewport|voro_margin|weight|width|xlabel|xlp|z\").split(\"|\")\n   );\n\n   this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : /\\/\\/.*$/\n            }, {\n                token : \"comment\",\n                regex : /#.*$/\n            }, {\n                token : \"comment\", // multi line comment\n                merge : true,\n                regex : /\\/\\*/,\n                next : \"comment\"\n            }, {\n                token : \"string\",\n                regex : \"'(?=.)\",\n                next  : \"qstring\"\n            }, {\n                token : \"string\",\n                regex : '\"(?=.)',\n                next  : \"qqstring\"\n            }, {\n                token : \"constant.numeric\",\n                regex : /[+\\-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)?\\b/\n            }, {\n                token : \"keyword.operator\",\n                regex : /\\+|=|\\->/\n            }, {\n                token : \"punctuation.operator\",\n                regex : /,|;/\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[{]/\n            }, {\n                token : \"paren.rparen\",\n                regex : /[\\]}]/\n            }, {\n                token: \"comment\",\n                regex: /^#!.*$/\n            }, {\n                token: function(value) {\n                    if (keywords.hasOwnProperty(value.toLowerCase())) {\n                        return \"keyword\";\n                    }\n                    else if (attributes.hasOwnProperty(value.toLowerCase())) {\n                        return \"variable\";\n                    }\n                    else {\n                        return \"text\";\n                    }\n                },\n                regex: \"\\\\-?[a-zA-Z_][a-zA-Z0-9_\\\\-]*\"\n           }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"string\",\n                regex : '[^\"\\\\\\\\]+',\n                merge : true\n            }, {\n                token : \"string\",\n                regex : \"\\\\\\\\$\",\n                next  : \"qqstring\",\n                merge : true\n            }, {\n                token : \"string\",\n                regex : '\"|$',\n                next  : \"start\",\n                merge : true\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"string\",\n                regex : \"[^'\\\\\\\\]+\",\n                merge : true\n            }, {\n                token : \"string\",\n                regex : \"\\\\\\\\$\",\n                next  : \"qstring\",\n                merge : true\n            }, {\n                token : \"string\",\n                regex : \"'|$\",\n                next  : \"start\",\n                merge : true\n            }\n        ]\n   };\n};\n\noop.inherits(DotHighlightRules, TextHighlightRules);\n\nexports.DotHighlightRules = DotHighlightRules;\n"
  },
  {
    "path": "src/mode/drools.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar DroolsHighlightRules = require(\"./drools_highlight_rules\").DroolsHighlightRules;\nvar DroolsFoldMode = require(\"./folding/drools\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = DroolsHighlightRules;\n    this.foldingRules = new DroolsFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.$id = \"ace/mode/drools\";\n    this.snippetFileId = \"ace/snippets/drools\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/drools_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar JavaHighlightRules = require(\"./java_highlight_rules\").JavaHighlightRules;\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n\nvar identifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\";\nvar packageIdentifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][\\\\.a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\";\n\nvar DroolsHighlightRules = function() {\n\n    var keywords = (\"date|effective|expires|lock|on|active|no|loop|auto|focus\" +\n        \"|activation|group|agenda|ruleflow|duration|timer|calendars|refract|direct\" +\n        \"|dialect|salience|enabled|attributes|extends|template\" +\n        \"|function|contains|matches|eval|excludes|soundslike\" +\n        \"|memberof|not|in|or|and|exists|forall|over|from|entry|point|accumulate|acc|collect\" +\n        \"|action|reverse|result|end|init|instanceof|extends|super|boolean|char|byte|short\" +\n        \"|int|long|float|double|this|void|class|new|case|final|if|else|for|while|do\" +\n        \"|default|try|catch|finally|switch|synchronized|return|throw|break|continue|assert\" +\n        \"|modify|static|public|protected|private|abstract|native|transient|volatile\" +\n        \"|strictfp|throws|interface|enum|implements|type|window|trait|no-loop|str\"\n      );\n\n      var langClasses = (\n          \"AbstractMethodError|AssertionError|ClassCircularityError|\"+\n          \"ClassFormatError|Deprecated|EnumConstantNotPresentException|\"+\n          \"ExceptionInInitializerError|IllegalAccessError|\"+\n          \"IllegalThreadStateException|InstantiationError|InternalError|\"+\n          \"NegativeArraySizeException|NoSuchFieldError|Override|Process|\"+\n          \"ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|\"+\n          \"SuppressWarnings|TypeNotPresentException|UnknownError|\"+\n          \"UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|\"+\n          \"InstantiationException|IndexOutOfBoundsException|\"+\n          \"ArrayIndexOutOfBoundsException|CloneNotSupportedException|\"+\n          \"NoSuchFieldException|IllegalArgumentException|NumberFormatException|\"+\n          \"SecurityException|Void|InheritableThreadLocal|IllegalStateException|\"+\n          \"InterruptedException|NoSuchMethodException|IllegalAccessException|\"+\n          \"UnsupportedOperationException|Enum|StrictMath|Package|Compiler|\"+\n          \"Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|\"+\n          \"NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|\"+\n          \"NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|\"+\n          \"Character|Boolean|StackTraceElement|Appendable|StringBuffer|\"+\n          \"Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|\"+\n          \"StackOverflowError|OutOfMemoryError|VirtualMachineError|\"+\n          \"ArrayStoreException|ClassCastException|LinkageError|\"+\n          \"NoClassDefFoundError|ClassNotFoundException|RuntimeException|\"+\n          \"Exception|ThreadDeath|Error|Throwable|System|ClassLoader|\"+\n          \"Cloneable|Class|CharSequence|Comparable|String|Object\"\n      );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"constant.language\": \"null\",\n        \"support.class\" : langClasses,\n        \"support.function\" : \"retract|update|modify|insert\"\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var stringRules = function() {\n      return [{\n        token : \"string\", // single line\n        regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n      }, {\n        token : \"string\", // single line\n        regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n      }];\n    };\n\n\n      var basicPreRules = function(blockCommentRules) {\n        return [{\n            token : \"comment\",\n            regex : \"\\\\/\\\\/.*$\"\n        },\n        DocCommentHighlightRules.getStartRule(\"doc-start\"),\n        {\n            token : \"comment\", // multi line comment\n            regex : \"\\\\/\\\\*\",\n            next : blockCommentRules\n        }, {\n            token : \"constant.numeric\", // hex\n            regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : \"constant.language.boolean\",\n            regex : \"(?:true|false)\\\\b\"\n          }];\n      };\n\n      var blockCommentRules = function(returnRule) {\n        return [\n            {\n                token : \"comment.block\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : returnRule\n            }, {\n                defaultToken : \"comment.block\"\n            }\n        ];\n      };\n\n      var basicPostRules = function() {\n        return [{\n            token : keywordMapper,\n            // TODO: Unicode escape sequences\n            // TODO: Unicode identifiers\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n        }, {\n            token : \"lparen\",\n            regex : \"[[({]\"\n        }, {\n            token : \"rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }];\n      };\n\n\n    this.$rules = {\n        \"start\" : [].concat(basicPreRules(\"block.comment\"), [\n              {\n                token : \"entity.name.type\",\n                regex : \"@[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n              }, {\n                // package com.example\n                token : [\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(package)(\\\\s+)(\" + packageIdentifierRe +\")\"\n              }, {\n                // import function com.Util.staticMethod\n                token : [\"keyword\",\"text\",\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(import)(\\\\s+)(function)(\\\\s+)(\" + packageIdentifierRe +\")\"\n              }, {\n                // import function com.Util.staticMethod\n                token : [\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(import)(\\\\s+)(\" + packageIdentifierRe +\")\"\n              }, {\n                // global com.example.Type identifier\n                token : [\"keyword\",\"text\",\"entity.name.type\",\"text\",\"variable\"],\n                regex : \"(global)(\\\\s+)(\" + packageIdentifierRe +\")(\\\\s+)(\" + identifierRe +\")\"\n              }, {\n                // declare trait DeclaredType\n                token : [\"keyword\",\"text\",\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(declare)(\\\\s+)(trait)(\\\\s+)(\" + identifierRe +\")\"\n              }, {\n                // declare trait DeclaredType\n                token : [\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(declare)(\\\\s+)(\" + identifierRe +\")\"\n              }, {\n                // declare trait DeclaredType\n                token : [\"keyword\",\"text\",\"entity.name.type\"],\n                regex : \"(extends)(\\\\s+)(\" + packageIdentifierRe +\")\"\n              }, {\n                // rule ...\n                token : [\"keyword\",\"text\"],\n                regex : \"(rule)(\\\\s+)\",\n                next :  \"asset.name\"\n              }],\n              stringRules(),\n              [{\n                // variable :\n                token : [\"variable.other\",\"text\",\"text\"],\n                regex : \"(\" + identifierRe + \")(\\\\s*)(:)\"\n              }, {\n                // query ...\n                token : [\"keyword\",\"text\"],\n                regex : \"(query)(\\\\s+)\",\n                next :  \"asset.name\"\n              }, {\n                // when ...\n                token : [\"keyword\",\"text\"],\n                regex : \"(when)(\\\\s*)\"\n              }, {\n                // then <java/mvel code> end\n                token : [\"keyword\",\"text\"],\n                regex : \"(then)(\\\\s*)\",\n                next :  \"java-start\"\n              }, {\n                  token : \"paren.lparen\",\n                  regex : /[\\[({]/\n              }, {\n                  token : \"paren.rparen\",\n                  regex : /[\\])}]/\n              }], basicPostRules()),\n        \"block.comment\" : blockCommentRules(\"start\"),\n        \"asset.name\" : [\n            {\n                token : \"entity.name\",\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"entity.name\",\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"entity.name\",\n                regex : identifierRe\n            }, {\n                regex: \"\",\n                token: \"empty\",\n                next: \"start\"\n            }]\n    };\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n\n    this.embedRules(JavaHighlightRules, \"java-\", [\n      {\n       token : \"support.function\",\n       regex: \"\\\\b(insert|modify|retract|update)\\\\b\"\n     }, {\n       token : \"keyword\",\n       regex: \"\\\\bend\\\\b\",\n       next  : \"start\"\n    }]);\n\n};\n\noop.inherits(DroolsHighlightRules, TextHighlightRules);\n\nexports.DroolsHighlightRules = DroolsHighlightRules;\n"
  },
  {
    "path": "src/mode/edifact.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar EdifactHighlightRules = require(\"./edifact_highlight_rules\").EdifactHighlightRules;\n\nvar Mode = function() {\n   \n    this.HighlightRules = EdifactHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/edifact\";\n    this.snippetFileId = \"ace/snippets/edifact\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/edifact_highlight_rules.js",
    "content": "\"use strict\";\n    \n    var oop = require(\"../lib/oop\");\n    var DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n    \n    var EdifactHighlightRules = function() {\n    \n        var header = (\n            \"UNH\"\n        );\n        var segment = (\n            \"ADR|AGR|AJT|ALC|ALI|APP|APR|ARD|ARR|ASI|ATT|AUT|\"+\n            \"BAS|BGM|BII|BUS|\"+\n            \"CAV|CCD|CCI|CDI|CDS|CDV|CED|CIN|CLA|CLI|CMP|CNI|CNT|COD|COM|COT|CPI|CPS|CPT|CST|CTA|CUX|\"+\n            \"DAM|DFN|DGS|DII|DIM|DLI|DLM|DMS|DOC|DRD|DSG|DSI|DTM|\"+\n            \"EDT|EFI|ELM|ELU|ELV|EMP|EQA|EQD|EQN|ERC|ERP|EVE|FCA|FII|FNS|FNT|FOR|FSQ|FTX|\"+\n            \"GDS|GEI|GID|GIN|GIR|GOR|GPO|GRU|HAN|HYN|ICD|IDE|IFD|IHC|IMD|IND|INP|INV|IRQ|\"+\n            \"LAN|LIN|LOC|MEA|MEM|MKS|MOA|MSG|MTD|NAD|NAT|\"+\n            \"PAC|PAI|PAS|PCC|PCD|PCI|PDI|PER|PGI|PIA|PNA|POC|PRC|PRI|PRV|PSD|PTY|PYT|\"+\n            \"QRS|QTY|QUA|QVR|\"+\n            \"RCS|REL|RFF|RJL|RNG|ROD|RSL|RTE|\"+\n            \"SAL|SCC|SCD|SEG|SEL|SEQ|SFI|SGP|SGU|SPR|SPS|STA|STC|STG|STS|\"+\n            \"TAX|TCC|TDT|TEM|TMD|TMP|TOD|TPL|TRU|TSR|\"+\n            \"UNB|UNZ|UNT|UGH|UGT|UNS|\"+\n            \"VLI\"\n        );\n    \n        var header = (\n            \"UNH\"\n        );\n    \n        var buildinConstants = (\"null|Infinity|NaN|undefined\");\n        var langClasses = (\n            \"\"\n        );\n    \n        var keywords = (\n            \"BY|SE|ON|INV|JP|UNOA\"\n        );\n    \n        var keywordMapper = this.createKeywordMapper({\n            \"variable.language\": \"this\",\n            \"keyword\": keywords,\n            \"entity.name.segment\":segment,\n            \"entity.name.header\":header,\n            \"constant.language\": buildinConstants,\n            \"support.function\": langClasses\n        }, \"identifier\");\n    \n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n    \n        this.$rules = {\n            \"start\" : [\n                {\n                    token : \"punctuation.operator\",\n                    regex : \"\\\\+.\\\\+\"\n                }, {\n                    token : \"constant.language.boolean\",\n                    regex : \"(?:true|false)\\\\b\"\n                }, {\n                    token : keywordMapper,\n                    regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                }, {\n                    token : \"keyword.operator\",\n                    regex : \"\\\\+\"\n                }, {\n                    token : \"punctuation.operator\",\n                    regex : \"\\\\:|'\"\n                },{\n                    token : \"identifier\",\n                    regex : \"\\\\:D\\\\:\"\n                }\n            ]\n        };\n    \n        this.embedRules(DocCommentHighlightRules, \"doc-\",\n            [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    };\n    \n    EdifactHighlightRules.metaData = { fileTypes: [ 'edi' ],\n          keyEquivalent: '^~E',\n          name: 'Edifact',\n          scopeName: 'source.edifact' };\n    \n    oop.inherits(EdifactHighlightRules, TextHighlightRules);\n    \n    exports.EdifactHighlightRules = EdifactHighlightRules;\n"
  },
  {
    "path": "src/mode/eiffel.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar EiffelHighlightRules = require(\"./eiffel_highlight_rules\").EiffelHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = EiffelHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.$id = \"ace/mode/eiffel\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/eiffel_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar EiffelHighlightRules = function() {\n    var keywords = \"across|agent|alias|all|attached|as|assign|attribute|check|\" +\n        \"class|convert|create|debug|deferred|detachable|do|else|elseif|end|\" +\n        \"ensure|expanded|export|external|feature|from|frozen|if|inherit|\" +\n        \"inspect|invariant|like|local|loop|not|note|obsolete|old|once|\" +\n        \"Precursor|redefine|rename|require|rescue|retry|select|separate|\" +\n        \"some|then|undefine|until|variant|when\";\n\n    var operatorKeywords = \"and|implies|or|xor\";\n\n    var languageConstants = \"Void\";\n\n    var booleanConstants = \"True|False\";\n\n    var languageVariables = \"Current|Result\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"constant.language\": languageConstants,\n        \"constant.language.boolean\": booleanConstants,\n        \"variable.language\": languageVariables,\n        \"keyword.operator\": operatorKeywords,\n        \"keyword\": keywords\n    }, \"identifier\", true);\n\n    var simpleString = /(?:[^\"%\\b\\f\\v]|%[A-DFHLNQR-V%'\"()<>]|%\\/(?:0[xX][\\da-fA-F](?:_*[\\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\\d(?:_*\\d)*)\\/)+?/;\n\n    this.$rules = {\n        \"start\": [{\n                token : \"string.quoted.other\", // Aligned-verbatim-strings (verbatim option not supported)\n                regex : /\"\\[/,\n                next: \"aligned_verbatim_string\"\n            }, {\n                token : \"string.quoted.other\", // Non-aligned-verbatim-strings (verbatim option not supported)\n                regex : /\"\\{/,\n                next: \"non-aligned_verbatim_string\"\n            }, {\n                token : \"string.quoted.double\",\n                regex : /\"(?:[^%\\b\\f\\n\\r\\v]|%[A-DFHLNQR-V%'\"()<>]|%\\/(?:0[xX][\\da-fA-F](?:_*[\\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\\d(?:_*\\d)*)\\/)*?\"/\n            }, {\n                token : \"comment.line.double-dash\",\n                regex : /--.*/\n            }, {\n                token : \"constant.character\",\n                regex : /'(?:[^%\\b\\f\\n\\r\\t\\v]|%[A-DFHLNQR-V%'\"()<>]|%\\/(?:0[xX][\\da-fA-F](?:_*[\\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\\d(?:_*\\d)*)\\/)'/\n            }, {\n                token : \"constant.numeric\", // hexa | octal | bin\n                regex : /\\b0(?:[xX][\\da-fA-F](?:_*[\\da-fA-F])*|[cC][0-7](?:_*[0-7])*|[bB][01](?:_*[01])*)\\b/\n            }, {\n                token : \"constant.numeric\",\n                regex : /(?:\\d(?:_*\\d)*)?\\.(?:(?:\\d(?:_*\\d)*)?[eE][+-]?)?\\d(?:_*\\d)*|\\d(?:_*\\d)*\\.?/\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[({]|<<|\\|\\(/\n            }, {\n                token : \"paren.rparen\",\n                regex : /[\\])}]|>>|\\|\\)/\n            }, {\n                token : \"keyword.operator\", // punctuation\n                regex : /:=|->|\\.(?=\\w)|[;,:?]/\n            }, {\n                token : \"keyword.operator\",\n                regex : /\\\\\\\\|\\|\\.\\.\\||\\.\\.|\\/[~\\/]?|[><\\/]=?|[-+*^=~]/\n            }, {\n                token : function (v) {\n                    var result = keywordMapper(v);\n                    if (result === \"identifier\" && v === v.toUpperCase()) {\n                        result =  \"entity.name.type\";\n                    }\n                    return result;\n                },\n                regex : /[a-zA-Z][a-zA-Z\\d_]*\\b/\n            }, {\n                token : \"text\",\n                regex : /\\s+/\n            }\n        ],\n        \"aligned_verbatim_string\" : [{\n                token : \"string\",\n                regex : /]\"/,\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : simpleString\n            }\n        ],\n        \"non-aligned_verbatim_string\" : [{\n                token : \"string.quoted.other\",\n                regex : /}\"/,\n                next : \"start\"\n            }, {\n                token : \"string.quoted.other\",\n                regex : simpleString\n            }\n        ]};\n};\n\noop.inherits(EiffelHighlightRules, TextHighlightRules);\n\nexports.EiffelHighlightRules = EiffelHighlightRules;\n"
  },
  {
    "path": "src/mode/ejs.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nvar EjsHighlightRules = function(start, end) {\n    HtmlHighlightRules.call(this);\n    \n    if (!start)\n        start = \"(?:<%|<\\\\?|{{)\";\n    if (!end)\n        end = \"(?:%>|\\\\?>|}})\";\n\n    for (var i in this.$rules) {\n        this.$rules[i].unshift({\n            token : \"markup.list.meta.tag\",\n            regex : start + \"(?![>}])[-=]?\",\n            push  : \"ejs-start\"\n        });\n    }\n    \n    this.embedRules(new JavaScriptHighlightRules({jsx: false}).getRules(), \"ejs-\", [{\n        token : \"markup.list.meta.tag\",\n        regex : \"-?\" + end,\n        next  : \"pop\"\n    }, {\n        token: \"comment\",\n        regex: \"//.*?\" + end,\n        next: \"pop\"\n    }]);\n    \n    this.normalizeRules();\n};\n\n\noop.inherits(EjsHighlightRules, HtmlHighlightRules);\n\nexports.EjsHighlightRules = EjsHighlightRules;\n\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar CssMode = require(\"./css\").Mode;\nvar RubyMode = require(\"./ruby\").Mode;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = EjsHighlightRules;    \n    this.createModeDelegates({\n        \"js-\": JavaScriptMode,\n        \"css-\": CssMode,\n        \"ejs-\": JavaScriptMode\n    });\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n\n    this.$id = \"ace/mode/ejs\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/elixir.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ElixirHighlightRules = require(\"./elixir_highlight_rules\").ElixirHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ElixirHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    // this.blockComment = {start: \"\"/*\"\", end: \"\"*/\"\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/elixir\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/elixir_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.githubusercontent.com/elixir-lang/elixir-tmbundle/master/Syntaxes/Elixir.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ElixirHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: \n            [ 'meta.module.elixir',\n              'keyword.control.module.elixir',\n              'meta.module.elixir',\n              'entity.name.type.module.elixir' ],\n           regex: '^(\\\\s*)(defmodule)(\\\\s+)((?:[A-Z]\\\\w*\\\\s*\\\\.\\\\s*)*[A-Z]\\\\w*)' },\n         { token: 'comment.documentation.heredoc',\n           regex: '@(?:module|type)?doc (?:~[a-z])?\"\"\"',\n           push: \n            [ { token: 'comment.documentation.heredoc',\n                regex: '\\\\s*\"\"\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'comment.documentation.heredoc' } ],\n           comment: '@doc with heredocs is treated as documentation' },\n         { token: 'comment.documentation.heredoc',\n           regex: '@(?:module|type)?doc ~[A-Z]\"\"\"',\n           push: \n            [ { token: 'comment.documentation.heredoc',\n                regex: '\\\\s*\"\"\"',\n                next: 'pop' },\n              { defaultToken: 'comment.documentation.heredoc' } ],\n           comment: '@doc with heredocs is treated as documentation' },\n         { token: 'comment.documentation.heredoc',\n           regex: '@(?:module|type)?doc (?:~[a-z])?\\'\\'\\'',\n           push: \n            [ { token: 'comment.documentation.heredoc',\n                regex: '\\\\s*\\'\\'\\'',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'comment.documentation.heredoc' } ],\n           comment: '@doc with heredocs is treated as documentation' },\n         { token: 'comment.documentation.heredoc',\n           regex: '@(?:module|type)?doc ~[A-Z]\\'\\'\\'',\n           push: \n            [ { token: 'comment.documentation.heredoc',\n                regex: '\\\\s*\\'\\'\\'',\n                next: 'pop' },\n              { defaultToken: 'comment.documentation.heredoc' } ],\n           comment: '@doc with heredocs is treated as documentation' },\n         { token: 'comment.documentation.false',\n           regex: '@(?:module|type)?doc false',\n           comment: '@doc false is treated as documentation' },\n         { token: 'comment.documentation.string',\n           regex: '@(?:module|type)?doc \"',\n           push: \n            [ { token: 'comment.documentation.string',\n                regex: '\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'comment.documentation.string' } ],\n           comment: '@doc with string is treated as documentation' },\n         { token: 'keyword.control.elixir',\n           regex: '\\\\b(?:do|end|case|bc|lc|for|if|cond|unless|try|receive|fn|defmodule|defp?|defprotocol|defimpl|defrecord|defstruct|defmacrop?|defdelegate|defcallback|defmacrocallback|defexception|defoverridable|exit|after|rescue|catch|else|raise|throw|import|require|alias|use|quote|unquote|super)\\\\b(?![?!])',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?<!\\\\.)\\\\b(do|end|case|bc|lc|for|if|cond|unless|try|receive|fn|defmodule|defp?|defprotocol|defimpl|defrecord|defstruct|defmacrop?|defdelegate|defcallback|defmacrocallback|defexception|defoverridable|exit|after|rescue|catch|else|raise|throw|import|require|alias|use|quote|unquote|super)\\\\b(?![?!])' },\n         { token: 'keyword.operator.elixir',\n           regex: '\\\\b(?:and|not|or|when|xor|in|inlist|inbits)\\\\b',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?<!\\\\.)\\\\b(and|not|or|when|xor|in|inlist|inbits)\\\\b',\n           comment: ' as above, just doesn\\'t need a \\'end\\' and does a logic operation' },\n         { token: 'constant.language.elixir',\n           regex: '\\\\b(?:nil|true|false)\\\\b(?![?!])' },\n         { token: 'variable.language.elixir',\n           regex: '\\\\b__(?:CALLER|ENV|MODULE|DIR)__\\\\b(?![?!])' },\n         { token: \n            [ 'punctuation.definition.variable.elixir',\n              'variable.other.readwrite.module.elixir' ],\n           regex: '(@)([a-zA-Z_]\\\\w*)' },\n         { token: \n            [ 'punctuation.definition.variable.elixir',\n              'variable.other.anonymous.elixir' ],\n           regex: '(&)(\\\\d*)' },\n         { token: 'variable.other.constant.elixir',\n           regex: '\\\\b[A-Z]\\\\w*\\\\b' },\n         { token: 'constant.numeric.elixir',\n           regex: '\\\\b(?:0x[\\\\da-fA-F](?:_?[\\\\da-fA-F])*|\\\\d(?:_?\\\\d)*(?:\\\\.(?![^[:space:][:digit:]])(?:_?\\\\d)*)?(?:[eE][-+]?\\\\d(?:_?\\\\d)*)?|0b[01]+|0o[0-7]+)\\\\b',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '\\\\b(0x\\\\h(?>_?\\\\h)*|\\\\d(?>_?\\\\d)*(\\\\.(?![^[:space:][:digit:]])(?>_?\\\\d)*)?([eE][-+]?\\\\d(?>_?\\\\d)*)?|0b[01]+|0o[0-7]+)\\\\b' },\n         { token: 'punctuation.definition.constant.elixir',\n           regex: ':\\'',\n           push: \n            [ { token: 'punctuation.definition.constant.elixir',\n                regex: '\\'',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'constant.other.symbol.single-quoted.elixir' } ] },\n         { token: 'punctuation.definition.constant.elixir',\n           regex: ':\"',\n           push: \n            [ { token: 'punctuation.definition.constant.elixir',\n                regex: '\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'constant.other.symbol.double-quoted.elixir' } ] },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '(?:\\'\\'\\')',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?>\\'\\'\\')',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '^\\\\s*\\'\\'\\'',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'support.function.variable.quoted.single.heredoc.elixir' } ],\n           comment: 'Single-quoted heredocs' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\'',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'support.function.variable.quoted.single.elixir' } ],\n           comment: 'single quoted string (allows for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '(?:\"\"\")',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?>\"\"\")',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '^\\\\s*\"\"\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.quoted.double.heredoc.elixir' } ],\n           comment: 'Double-quoted heredocs' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.quoted.double.elixir' } ],\n           comment: 'double quoted string (allows for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z](?:\"\"\")',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '~[a-z](?>\"\"\")',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '^\\\\s*\"\"\"',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.quoted.double.heredoc.elixir' } ],\n           comment: 'Double-quoted heredocs sigils' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z]\\\\{',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\}[a-z]*',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.interpolated.elixir' } ],\n           comment: 'sigil (allow for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z]\\\\[',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\][a-z]*',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.interpolated.elixir' } ],\n           comment: 'sigil (allow for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z]\\\\<',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\>[a-z]*',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.interpolated.elixir' } ],\n           comment: 'sigil (allow for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z]\\\\(',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\)[a-z]*',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.interpolated.elixir' } ],\n           comment: 'sigil (allow for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[a-z][^\\\\w]',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '[^\\\\w][a-z]*',\n                next: 'pop' },\n              { include: '#interpolated_elixir' },\n              { include: '#escaped_char' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.interpolated.elixir' } ],\n           comment: 'sigil (allow for interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z](?:\"\"\")',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '~[A-Z](?>\"\"\")',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '^\\\\s*\"\"\"',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'Double-quoted heredocs sigils' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z]\\\\{',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\}[a-z]*',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'sigil (without interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z]\\\\[',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\][a-z]*',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'sigil (without interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z]\\\\<',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\>[a-z]*',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'sigil (without interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z]\\\\(',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '\\\\)[a-z]*',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'sigil (without interpolation)' },\n         { token: 'punctuation.definition.string.begin.elixir',\n           regex: '~[A-Z][^\\\\w]',\n           push: \n            [ { token: 'punctuation.definition.string.end.elixir',\n                regex: '[^\\\\w][a-z]*',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],\n           comment: 'sigil (without interpolation)' },\n         { token: ['punctuation.definition.constant.elixir', 'constant.other.symbol.elixir'],\n           regex: '(:)([a-zA-Z_][\\\\w@]*(?:[?!]|=(?![>=]))?|\\\\<\\\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\\\-|\\\\|>|=>|~|~=|=|/|\\\\\\\\\\\\\\\\|\\\\*\\\\*?|\\\\.\\\\.?\\\\.?|>=?|<=?|&&?&?|\\\\+\\\\+?|\\\\-\\\\-?|\\\\|\\\\|?\\\\|?|\\\\!|@|\\\\%?\\\\{\\\\}|%|\\\\[\\\\]|\\\\^(?:\\\\^\\\\^)?)',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?<!:)(:)(?>[a-zA-Z_][\\\\w@]*(?>[?!]|=(?![>=]))?|\\\\<\\\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\\\-|\\\\|>|=>|~|~=|=|/|\\\\\\\\\\\\\\\\|\\\\*\\\\*?|\\\\.\\\\.?\\\\.?|>=?|<=?|&&?&?|\\\\+\\\\+?|\\\\-\\\\-?|\\\\|\\\\|?\\\\|?|\\\\!|@|\\\\%?\\\\{\\\\}|%|\\\\[\\\\]|\\\\^(\\\\^\\\\^)?)',\n           comment: 'symbols' },\n         { token: 'punctuation.definition.constant.elixir',\n           regex: '(?:[a-zA-Z_][\\\\w@]*(?:[?!])?):(?!:)',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?>[a-zA-Z_][\\\\w@]*(?>[?!])?)(:)(?!:)',\n           comment: 'symbols' },\n         { token: \n            [ 'punctuation.definition.comment.elixir',\n              'comment.line.number-sign.elixir' ],\n           regex: '(#)(.*)' },\n         { token: 'constant.numeric.elixir',\n           regex: '\\\\?(?:\\\\\\\\(?:x[\\\\da-fA-F]{1,2}(?![\\\\da-fA-F])\\\\b|[^xMC])|[^\\\\s\\\\\\\\])',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?<!\\\\w)\\\\?(\\\\\\\\(x\\\\h{1,2}(?!\\\\h)\\\\b|[^xMC])|[^\\\\s\\\\\\\\])',\n           comment: '\\n\\t\\t\\tmatches questionmark-letters.\\n\\n\\t\\t\\texamples (1st alternation = hex):\\n\\t\\t\\t?\\\\x1     ?\\\\x61\\n\\n\\t\\t\\texamples (2rd alternation = escaped):\\n\\t\\t\\t?\\\\n      ?\\\\b\\n\\n\\t\\t\\texamples (3rd alternation = normal):\\n\\t\\t\\t?a       ?A       ?0 \\n\\t\\t\\t?*       ?\"       ?( \\n\\t\\t\\t?.       ?#\\n\\t\\t\\t\\n\\t\\t\\tthe negative lookbehind prevents against matching\\n\\t\\t\\tp(42.tainted?)\\n\\t\\t\\t' },\n        /* { token: 'punctuation.separator.variable.elixir',\n           regex: '(?<=\\\\{|do|\\\\{\\\\s|do\\\\s)\\\\|',\n           TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n           originalRegex: '(?<=\\\\{|do|\\\\{\\\\s|do\\\\s)(\\\\|)',\n           push: \n            [ { token: 'punctuation.separator.variable.elixir',\n                regex: '\\\\|',\n                next: 'pop' },\n              { token: 'variable.other.block.elixir',\n                regex: '[_a-zA-Z][_a-zA-Z0-9]*' },\n              { token: 'punctuation.separator.variable.elixir', regex: ',' } ] },*/\n         { token: 'keyword.operator.assignment.augmented.elixir',\n           regex: '\\\\+=|\\\\-=|\\\\|\\\\|=|~=|&&=' },\n         { token: 'keyword.operator.comparison.elixir',\n           regex: '===?|!==?|<=?|>=?' },\n         { token: 'keyword.operator.bitwise.elixir',\n           regex: '\\\\|{3}|&{3}|\\\\^{3}|<{3}|>{3}|~{3}' },\n         { token: 'keyword.operator.logical.elixir',\n           regex: '!+|\\\\bnot\\\\b|&&|\\\\band\\\\b|\\\\|\\\\||\\\\bor\\\\b|\\\\bxor\\\\b',\n           originalRegex: '(?<=[ \\\\t])!+|\\\\bnot\\\\b|&&|\\\\band\\\\b|\\\\|\\\\||\\\\bor\\\\b|\\\\bxor\\\\b' },\n         { token: 'keyword.operator.arithmetic.elixir',\n           regex: '\\\\*|\\\\+|\\\\-|/' },\n         { token: 'keyword.operator.other.elixir',\n           regex: '\\\\||\\\\+\\\\+|\\\\-\\\\-|\\\\*\\\\*|\\\\\\\\\\\\\\\\|\\\\<\\\\-|\\\\<\\\\>|\\\\<\\\\<|\\\\>\\\\>|\\\\:\\\\:|\\\\.\\\\.|\\\\|>|~|=>' },\n         { token: 'keyword.operator.assignment.elixir', regex: '=' },\n         { token: 'punctuation.separator.other.elixir', regex: ':' },\n         { token: 'punctuation.separator.statement.elixir',\n           regex: '\\\\;' },\n         { token: 'punctuation.separator.object.elixir', regex: ',' },\n         { token: 'punctuation.separator.method.elixir', regex: '\\\\.' },\n         { token: 'punctuation.section.scope.elixir', regex: '\\\\{|\\\\}' },\n         { token: 'punctuation.section.array.elixir', regex: '\\\\[|\\\\]' },\n         { token: 'punctuation.section.function.elixir',\n           regex: '\\\\(|\\\\)' } ],\n      '#escaped_char': \n       [ { token: 'constant.character.escape.elixir',\n           regex: '\\\\\\\\(?:x[\\\\da-fA-F]{1,2}|.)' } ],\n      '#interpolated_elixir': \n       [ { token: \n            [ 'source.elixir.embedded.source',\n              'source.elixir.embedded.source.empty' ],\n           regex: '(#\\\\{)(\\\\})' },\n         { todo: \n            { token: 'punctuation.section.embedded.elixir',\n              regex: '#\\\\{',\n              push: \n               [ { token: 'punctuation.section.embedded.elixir',\n                   regex: '\\\\}',\n                   next: 'pop' },\n                 { include: '#nest_curly_and_self' },\n                 { include: '$self' },\n                 { defaultToken: 'source.elixir.embedded.source' } ] } } ],\n      '#nest_curly_and_self': \n       [ { token: 'punctuation.section.scope.elixir',\n           regex: '\\\\{',\n           push: \n            [ { token: 'punctuation.section.scope.elixir',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#nest_curly_and_self' } ] },\n         { include: '$self' } ],\n      '#regex_sub': \n       [ { include: '#interpolated_elixir' },\n         { include: '#escaped_char' },\n         { token: \n            [ 'punctuation.definition.arbitrary-repitition.elixir',\n              'string.regexp.arbitrary-repitition.elixir',\n              'string.regexp.arbitrary-repitition.elixir',\n              'punctuation.definition.arbitrary-repitition.elixir' ],\n           regex: '(\\\\{)(\\\\d+)((?:,\\\\d+)?)(\\\\})' },\n         { token: 'punctuation.definition.character-class.elixir',\n           regex: '\\\\[(?:\\\\^?\\\\])?',\n           push: \n            [ { token: 'punctuation.definition.character-class.elixir',\n                regex: '\\\\]',\n                next: 'pop' },\n              { include: '#escaped_char' },\n              { defaultToken: 'string.regexp.character-class.elixir' } ] },\n         { token: 'punctuation.definition.group.elixir',\n           regex: '\\\\(',\n           push: \n            [ { token: 'punctuation.definition.group.elixir',\n                regex: '\\\\)',\n                next: 'pop' },\n              { include: '#regex_sub' },\n              { defaultToken: 'string.regexp.group.elixir' } ] },\n         { token: \n            [ 'punctuation.definition.comment.elixir',\n              'comment.line.number-sign.elixir' ],\n           regex: '(?:^|\\\\s)(#)(\\\\s[[a-zA-Z0-9,. \\\\t?!-][^\\\\x00-\\\\x7F]]*$)',\n           originalRegex: '(?<=^|\\\\s)(#)\\\\s[[a-zA-Z0-9,. \\\\t?!-][^\\\\x{00}-\\\\x{7F}]]*$',\n           comment: 'We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.' } ] };\n    \n    this.normalizeRules();\n};\n\nElixirHighlightRules.metaData = { comment: 'Textmate bundle for Elixir Programming Language.',\n      fileTypes: [ 'ex', 'exs' ],\n      firstLineMatch: '^#!/.*\\\\belixir',\n      foldingStartMarker: '(after|else|catch|rescue|\\\\-\\\\>|\\\\{|\\\\[|do)\\\\s*$',\n      foldingStopMarker: '^\\\\s*((\\\\}|\\\\]|after|else|catch|rescue)\\\\s*$|end\\\\b)',\n      keyEquivalent: '^~E',\n      name: 'Elixir',\n      scopeName: 'source.elixir' };\n\n\noop.inherits(ElixirHighlightRules, TextHighlightRules);\n\nexports.ElixirHighlightRules = ElixirHighlightRules;\n"
  },
  {
    "path": "src/mode/elm.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./elm_highlight_rules\").ElmHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"{-\", end: \"-}\", nestable: true};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/elm\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/elm_highlight_rules.js",
    "content": "// TODO check with https://github.com/deadfoxygrandpa/Elm.tmLanguage\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ElmHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n       \"keyword\": \"as|case|class|data|default|deriving|do|else|export|foreign|\" +\n            \"hiding|jsevent|if|import|in|infix|infixl|infixr|instance|let|\" +\n            \"module|newtype|of|open|then|type|where|_|port|\\u03BB\"\n    }, \"identifier\");\n    \n    var escapeRe = /\\\\(\\d+|['\"\\\\&trnbvf])/;\n    \n    var smallRe = /[a-z_]/.source;\n    var largeRe = /[A-Z]/.source;\n    var idRe = /[a-z_A-Z0-9']/.source;\n\n    this.$rules = {\n        start: [{\n            token: \"string.start\",\n            regex: '\"',\n            next: \"string\"\n        }, {\n            token: \"string.character\",\n            regex: \"'(?:\" + escapeRe.source + \"|.)'?\"\n        }, {\n            regex: /0(?:[xX][0-9A-Fa-f]+|[oO][0-7]+)|\\d+(\\.\\d+)?([eE][-+]?\\d*)?/,\n            token: \"constant.numeric\"\n        }, {\n            token: \"comment\",\n            regex: \"--.*\"\n        }, {\n            token : \"keyword\",\n            regex : /\\.\\.|\\||:|=|\\\\|\"|->|<-|\\u2192/\n        }, {\n            token : \"keyword.operator\",\n            regex : /[-!#$%&*+.\\/<=>?@\\\\^|~:\\u03BB\\u2192]+/\n        }, {\n            token : \"operator.punctuation\",\n            regex : /[,;`]/\n        }, {\n            regex : largeRe + idRe + \"+\\\\.?\",\n            token : function(value) {\n                if (value[value.length - 1] == \".\")\n                    return \"entity.name.function\"; \n                return \"constant.language\"; \n            }\n        }, {\n            regex : \"^\" + smallRe  + idRe + \"+\",\n            token : function(value) {\n                return \"constant.language\"; \n            }\n        }, {\n            token : keywordMapper,\n            regex : \"[\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]+\\\\b\"\n        }, {\n            regex: \"{-#?\",\n            token: \"comment.start\",\n            onMatch: function(value, currentState, stack) {\n                this.next = value.length == 2 ? \"blockComment\" : \"docComment\";\n                return this.token;\n            }\n        }, {\n            token: \"variable.language\",\n            regex: /\\[markdown\\|/,\n            next: \"markdown\"\n        }, {\n            token: \"paren.lparen\",\n            regex: /[\\[({]/ \n        }, {\n            token: \"paren.rparen\",\n            regex: /[\\])}]/\n        } ],\n        markdown: [{\n            regex: /\\|\\]/,\n            next: \"start\"\n        }, {\n            defaultToken : \"string\"\n        }],\n        blockComment: [{\n            regex: \"{-\",\n            token: \"comment.start\",\n            push: \"blockComment\"\n        }, {\n            regex: \"-}\",\n            token: \"comment.end\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }],\n        docComment: [{\n            regex: \"{-\",\n            token: \"comment.start\",\n            push: \"docComment\"\n        }, {\n            regex: \"-}\",\n            token: \"comment.end\",\n            next: \"pop\" \n        }, {\n            defaultToken: \"doc.comment\"\n        }],\n        string: [{\n            token: \"constant.language.escape\",\n            regex: escapeRe\n        }, {\n            token: \"text\",\n            regex: /\\\\(\\s|$)/,\n            next: \"stringGap\"\n        }, {\n            token: \"string.end\",\n            regex: '\"',\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        stringGap: [{\n            token: \"text\",\n            regex: /\\\\/,\n            next: \"string\"\n        }, {\n            token: \"error\",\n            regex: \"\",\n            next: \"start\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(ElmHighlightRules, TextHighlightRules);\n\nexports.ElmHighlightRules = ElmHighlightRules;\n"
  },
  {
    "path": "src/mode/erlang.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ErlangHighlightRules = require(\"./erlang_highlight_rules\").ErlangHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ErlangHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"%\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/erlang\";\n    this.snippetFileId = \"ace/snippets/erlang\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/erlang_highlight_rules.js",
    "content": "/* This file was autogenerated from tm bundles\\erlang.tmbundle\\Syntaxes\\Erlang.plist (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ErlangHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { include: '#module-directive' },\n         { include: '#import-export-directive' },\n         { include: '#behaviour-directive' },\n         { include: '#record-directive' },\n         { include: '#define-directive' },\n         { include: '#macro-directive' },\n         { include: '#directive' },\n         { include: '#function' },\n         { include: '#everything-else' } ],\n      '#atom': \n       [ { token: 'punctuation.definition.symbol.begin.erlang',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.symbol.end.erlang',\n                regex: '\\'',\n                next: 'pop' },\n              { token: \n                 [ 'punctuation.definition.escape.erlang',\n                   'constant.other.symbol.escape.erlang',\n                   'punctuation.definition.escape.erlang',\n                   'constant.other.symbol.escape.erlang',\n                   'constant.other.symbol.escape.erlang' ],\n                regex: '(\\\\\\\\)(?:([bdefnrstv\\\\\\\\\\'\"])|(\\\\^)([@-_])|([0-7]{1,3}))' },\n              { token: 'invalid.illegal.atom.erlang', regex: '\\\\\\\\\\\\^?.?' },\n              { defaultToken: 'constant.other.symbol.quoted.single.erlang' } ] },\n         { token: 'constant.other.symbol.unquoted.erlang',\n           regex: '[a-z][a-zA-Z\\\\d@_]*' } ],\n      '#behaviour-directive': \n       [ { token: \n            [ 'meta.directive.behaviour.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.behaviour.erlang',\n              'keyword.control.directive.behaviour.erlang',\n              'meta.directive.behaviour.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.behaviour.erlang',\n              'entity.name.type.class.behaviour.definition.erlang',\n              'meta.directive.behaviour.erlang',\n              'punctuation.definition.parameters.end.erlang',\n              'meta.directive.behaviour.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(behaviour)(\\\\s*)(\\\\()(\\\\s*)([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(\\\\))(\\\\s*)(\\\\.)' } ],\n      '#binary': \n       [ { token: 'punctuation.definition.binary.begin.erlang',\n           regex: '<<',\n           push: \n            [ { token: 'punctuation.definition.binary.end.erlang',\n                regex: '>>',\n                next: 'pop' },\n              { token: \n                 [ 'punctuation.separator.binary.erlang',\n                   'punctuation.separator.value-size.erlang' ],\n                regex: '(,)|(:)' },\n              { include: '#internal-type-specifiers' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.structure.binary.erlang' } ] } ],\n      '#character': \n       [ { token: \n            [ 'punctuation.definition.character.erlang',\n              'punctuation.definition.escape.erlang',\n              'constant.character.escape.erlang',\n              'punctuation.definition.escape.erlang',\n              'constant.character.escape.erlang',\n              'constant.character.escape.erlang' ],\n           regex: '(\\\\$)(\\\\\\\\)(?:([bdefnrstv\\\\\\\\\\'\"])|(\\\\^)([@-_])|([0-7]{1,3}))' },\n         { token: 'invalid.illegal.character.erlang',\n           regex: '\\\\$\\\\\\\\\\\\^?.?' },\n         { token: \n            [ 'punctuation.definition.character.erlang',\n              'constant.character.erlang' ],\n           regex: '(\\\\$)(\\\\S)' },\n         { token: 'invalid.illegal.character.erlang', regex: '\\\\$.?' } ],\n      '#comment': \n       [ { token: 'punctuation.definition.comment.erlang',\n           regex: '%.*$',\n           push_: \n            [ { token: 'comment.line.percentage.erlang',\n                regex: '$',\n                next: 'pop' },\n              { defaultToken: 'comment.line.percentage.erlang' } ] } ],\n      '#define-directive': \n       [ { token: \n            [ 'meta.directive.define.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.define.erlang',\n              'keyword.control.directive.define.erlang',\n              'meta.directive.define.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.define.erlang',\n              'entity.name.function.macro.definition.erlang',\n              'meta.directive.define.erlang',\n              'punctuation.separator.parameters.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(define)(\\\\s*)(\\\\()(\\\\s*)([a-zA-Z\\\\d@_]+)(\\\\s*)(,)',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.define.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\))(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.directive.define.erlang' } ] },\n         { token: 'meta.directive.define.erlang',\n           regex: '(?=^\\\\s*-\\\\s*define\\\\s*\\\\(\\\\s*[a-zA-Z\\\\d@_]+\\\\s*\\\\()',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.define.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\))(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { token: \n                 [ 'text',\n                   'punctuation.section.directive.begin.erlang',\n                   'text',\n                   'keyword.control.directive.define.erlang',\n                   'text',\n                   'punctuation.definition.parameters.begin.erlang',\n                   'text',\n                   'entity.name.function.macro.definition.erlang',\n                   'text',\n                   'punctuation.definition.parameters.begin.erlang' ],\n                regex: '^(\\\\s*)(-)(\\\\s*)(define)(\\\\s*)(\\\\()(\\\\s*)([a-zA-Z\\\\d@_]+)(\\\\s*)(\\\\()',\n                push: \n                 [ { token: \n                      [ 'punctuation.definition.parameters.end.erlang',\n                        'text',\n                        'punctuation.separator.parameters.erlang' ],\n                     regex: '(\\\\))(\\\\s*)(,)',\n                     next: 'pop' },\n                   { token: 'punctuation.separator.parameters.erlang', regex: ',' },\n                   { include: '#everything-else' } ] },\n              { token: 'punctuation.separator.define.erlang',\n                regex: '\\\\|\\\\||\\\\||:|;|,|\\\\.|->' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.directive.define.erlang' } ] } ],\n      '#directive': \n       [ { token: \n            [ 'meta.directive.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.erlang',\n              'keyword.control.directive.erlang',\n              'meta.directive.erlang',\n              'punctuation.definition.parameters.begin.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(\\\\(?)',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\)?)(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.directive.erlang' } ] },\n         { token: \n            [ 'meta.directive.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.erlang',\n              'keyword.control.directive.erlang',\n              'meta.directive.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(\\\\.)' } ],\n      '#everything-else': \n       [ { include: '#comment' },\n         { include: '#record-usage' },\n         { include: '#macro-usage' },\n         { include: '#expression' },\n         { include: '#keyword' },\n         { include: '#textual-operator' },\n         { include: '#function-call' },\n         { include: '#tuple' },\n         { include: '#list' },\n         { include: '#binary' },\n         { include: '#parenthesized-expression' },\n         { include: '#character' },\n         { include: '#number' },\n         { include: '#atom' },\n         { include: '#string' },\n         { include: '#symbolic-operator' },\n         { include: '#variable' } ],\n      '#expression': \n       [ { token: 'keyword.control.if.erlang',\n           regex: '\\\\bif\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#internal-expression-punctuation' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.if.erlang' } ] },\n         { token: 'keyword.control.case.erlang',\n           regex: '\\\\bcase\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#internal-expression-punctuation' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.case.erlang' } ] },\n         { token: 'keyword.control.receive.erlang',\n           regex: '\\\\breceive\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#internal-expression-punctuation' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.receive.erlang' } ] },\n         { token: \n            [ 'keyword.control.fun.erlang',\n              'text',\n              'entity.name.type.class.module.erlang',\n              'text',\n              'punctuation.separator.module-function.erlang',\n              'text',\n              'entity.name.function.erlang',\n              'text',\n              'punctuation.separator.function-arity.erlang' ],\n           regex: '\\\\b(fun)(\\\\s*)(?:([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(:)(\\\\s*))?([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(/)' },\n         { token: 'keyword.control.fun.erlang',\n           regex: '\\\\bfun\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { token: 'text',\n                regex: '(?=\\\\()',\n                push: \n                 [ { token: 'punctuation.separator.clauses.erlang',\n                     regex: ';|(?=\\\\bend\\\\b)',\n                     next: 'pop' },\n                   { include: '#internal-function-parts' } ] },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.fun.erlang' } ] },\n         { token: 'keyword.control.try.erlang',\n           regex: '\\\\btry\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#internal-expression-punctuation' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.try.erlang' } ] },\n         { token: 'keyword.control.begin.erlang',\n           regex: '\\\\bbegin\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#internal-expression-punctuation' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.begin.erlang' } ] },\n         { token: 'keyword.control.query.erlang',\n           regex: '\\\\bquery\\\\b',\n           push: \n            [ { token: 'keyword.control.end.erlang',\n                regex: '\\\\bend\\\\b',\n                next: 'pop' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.query.erlang' } ] } ],\n      '#function': \n       [ { token: \n            [ 'meta.function.erlang',\n              'entity.name.function.definition.erlang',\n              'meta.function.erlang' ],\n           regex: '^(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(?=\\\\()',\n           push: \n            [ { token: 'punctuation.terminator.function.erlang',\n                regex: '\\\\.',\n                next: 'pop' },\n              { token: [ 'text', 'entity.name.function.erlang', 'text' ],\n                regex: '^(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(?=\\\\()' },\n              { token: 'text',\n                regex: '(?=\\\\()',\n                push: \n                 [ { token: 'punctuation.separator.clauses.erlang',\n                     regex: ';|(?=\\\\.)',\n                     next: 'pop' },\n                   { include: '#parenthesized-expression' },\n                   { include: '#internal-function-parts' } ] },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.function.erlang' } ] } ],\n      '#function-call': \n       [ { token: 'meta.function-call.erlang',\n           regex: '(?=(?:[a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')\\\\s*(?:\\\\(|:\\\\s*(?:[a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')\\\\s*\\\\())',\n           push: \n            [ { token: 'punctuation.definition.parameters.end.erlang',\n                regex: '\\\\)',\n                next: 'pop' },\n              { token: \n                 [ 'entity.name.type.class.module.erlang',\n                   'text',\n                   'punctuation.separator.module-function.erlang',\n                   'text',\n                   'entity.name.function.guard.erlang',\n                   'text',\n                   'punctuation.definition.parameters.begin.erlang' ],\n                regex: '(?:(erlang)(\\\\s*)(:)(\\\\s*))?(is_atom|is_binary|is_constant|is_float|is_function|is_integer|is_list|is_number|is_pid|is_port|is_reference|is_tuple|is_record|abs|element|hd|length|node|round|self|size|tl|trunc)(\\\\s*)(\\\\()',\n                push: \n                 [ { token: 'text', regex: '(?=\\\\))', next: 'pop' },\n                   { token: 'punctuation.separator.parameters.erlang', regex: ',' },\n                   { include: '#everything-else' } ] },\n              { token: \n                 [ 'entity.name.type.class.module.erlang',\n                   'text',\n                   'punctuation.separator.module-function.erlang',\n                   'text',\n                   'entity.name.function.erlang',\n                   'text',\n                   'punctuation.definition.parameters.begin.erlang' ],\n                regex: '(?:([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(:)(\\\\s*))?([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(\\\\()',\n                push: \n                 [ { token: 'text', regex: '(?=\\\\))', next: 'pop' },\n                   { token: 'punctuation.separator.parameters.erlang', regex: ',' },\n                   { include: '#everything-else' } ] },\n              { defaultToken: 'meta.function-call.erlang' } ] } ],\n      '#import-export-directive': \n       [ { token: \n            [ 'meta.directive.import.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.import.erlang',\n              'keyword.control.directive.import.erlang',\n              'meta.directive.import.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.import.erlang',\n              'entity.name.type.class.module.erlang',\n              'meta.directive.import.erlang',\n              'punctuation.separator.parameters.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(import)(\\\\s*)(\\\\()(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(,)',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.import.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\))(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { include: '#internal-function-list' },\n              { defaultToken: 'meta.directive.import.erlang' } ] },\n         { token: \n            [ 'meta.directive.export.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.export.erlang',\n              'keyword.control.directive.export.erlang',\n              'meta.directive.export.erlang',\n              'punctuation.definition.parameters.begin.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(export)(\\\\s*)(\\\\()',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.export.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\))(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { include: '#internal-function-list' },\n              { defaultToken: 'meta.directive.export.erlang' } ] } ],\n      '#internal-expression-punctuation': \n       [ { token: \n            [ 'punctuation.separator.clause-head-body.erlang',\n              'punctuation.separator.clauses.erlang',\n              'punctuation.separator.expressions.erlang' ],\n           regex: '(->)|(;)|(,)' } ],\n      '#internal-function-list': \n       [ { token: 'punctuation.definition.list.begin.erlang',\n           regex: '\\\\[',\n           push: \n            [ { token: 'punctuation.definition.list.end.erlang',\n                regex: '\\\\]',\n                next: 'pop' },\n              { token: \n                 [ 'entity.name.function.erlang',\n                   'text',\n                   'punctuation.separator.function-arity.erlang' ],\n                regex: '([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(/)',\n                push: \n                 [ { token: 'punctuation.separator.list.erlang',\n                     regex: ',|(?=\\\\])',\n                     next: 'pop' },\n                   { include: '#everything-else' } ] },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.structure.list.function.erlang' } ] } ],\n      '#internal-function-parts': \n       [ { token: 'text',\n           regex: '(?=\\\\()',\n           push: \n            [ { token: 'punctuation.separator.clause-head-body.erlang',\n                regex: '->',\n                next: 'pop' },\n              { token: 'punctuation.definition.parameters.begin.erlang',\n                regex: '\\\\(',\n                push: \n                 [ { token: 'punctuation.definition.parameters.end.erlang',\n                     regex: '\\\\)',\n                     next: 'pop' },\n                   { token: 'punctuation.separator.parameters.erlang', regex: ',' },\n                   { include: '#everything-else' } ] },\n              { token: 'punctuation.separator.guards.erlang', regex: ',|;' },\n              { include: '#everything-else' } ] },\n         { token: 'punctuation.separator.expressions.erlang',\n           regex: ',' },\n         { include: '#everything-else' } ],\n      '#internal-record-body': \n       [ { token: 'punctuation.definition.class.record.begin.erlang',\n           regex: '\\\\{',\n           push: \n            [ { token: 'meta.structure.record.erlang',\n                regex: '(?=\\\\})',\n                next: 'pop' },\n              { token: \n                 [ 'variable.other.field.erlang',\n                   'variable.language.omitted.field.erlang',\n                   'text',\n                   'keyword.operator.assignment.erlang' ],\n                regex: '(?:([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')|(_))(\\\\s*)(=|::)',\n                push: \n                 [ { token: 'punctuation.separator.class.record.erlang',\n                     regex: ',|(?=\\\\})',\n                     next: 'pop' },\n                   { include: '#everything-else' } ] },\n              { token: \n                 [ 'variable.other.field.erlang',\n                   'text',\n                   'punctuation.separator.class.record.erlang' ],\n                regex: '([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)((?:,)?)' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.structure.record.erlang' } ] } ],\n      '#internal-type-specifiers': \n       [ { token: 'punctuation.separator.value-type.erlang',\n           regex: '/',\n           push: \n            [ { token: 'text', regex: '(?=,|:|>>)', next: 'pop' },\n              { token: \n                 [ 'storage.type.erlang',\n                   'storage.modifier.signedness.erlang',\n                   'storage.modifier.endianness.erlang',\n                   'storage.modifier.unit.erlang',\n                   'punctuation.separator.type-specifiers.erlang' ],\n                regex: '(integer|float|binary|bytes|bitstring|bits)|(signed|unsigned)|(big|little|native)|(unit)|(-)' } ] } ],\n      '#keyword': \n       [ { token: 'keyword.control.erlang',\n           regex: '\\\\b(?:after|begin|case|catch|cond|end|fun|if|let|of|query|try|receive|when)\\\\b' } ],\n      '#list': \n       [ { token: 'punctuation.definition.list.begin.erlang',\n           regex: '\\\\[',\n           push: \n            [ { token: 'punctuation.definition.list.end.erlang',\n                regex: '\\\\]',\n                next: 'pop' },\n              { token: 'punctuation.separator.list.erlang',\n                regex: '\\\\||\\\\|\\\\||,' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.structure.list.erlang' } ] } ],\n      '#macro-directive': \n       [ { token: \n            [ 'meta.directive.ifdef.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.ifdef.erlang',\n              'keyword.control.directive.ifdef.erlang',\n              'meta.directive.ifdef.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.ifdef.erlang',\n              'entity.name.function.macro.erlang',\n              'meta.directive.ifdef.erlang',\n              'punctuation.definition.parameters.end.erlang',\n              'meta.directive.ifdef.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(ifdef)(\\\\s*)(\\\\()(\\\\s*)([a-zA-Z\\\\d@_]+)(\\\\s*)(\\\\))(\\\\s*)(\\\\.)' },\n         { token: \n            [ 'meta.directive.ifndef.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.ifndef.erlang',\n              'keyword.control.directive.ifndef.erlang',\n              'meta.directive.ifndef.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.ifndef.erlang',\n              'entity.name.function.macro.erlang',\n              'meta.directive.ifndef.erlang',\n              'punctuation.definition.parameters.end.erlang',\n              'meta.directive.ifndef.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(ifndef)(\\\\s*)(\\\\()(\\\\s*)([a-zA-Z\\\\d@_]+)(\\\\s*)(\\\\))(\\\\s*)(\\\\.)' },\n         { token: \n            [ 'meta.directive.undef.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.undef.erlang',\n              'keyword.control.directive.undef.erlang',\n              'meta.directive.undef.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.undef.erlang',\n              'entity.name.function.macro.erlang',\n              'meta.directive.undef.erlang',\n              'punctuation.definition.parameters.end.erlang',\n              'meta.directive.undef.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(undef)(\\\\s*)(\\\\()(\\\\s*)([a-zA-Z\\\\d@_]+)(\\\\s*)(\\\\))(\\\\s*)(\\\\.)' } ],\n      '#macro-usage': \n       [ { token: \n            [ 'keyword.operator.macro.erlang',\n              'meta.macro-usage.erlang',\n              'entity.name.function.macro.erlang' ],\n           regex: '(\\\\?\\\\??)(\\\\s*)([a-zA-Z\\\\d@_]+)' } ],\n      '#module-directive': \n       [ { token: \n            [ 'meta.directive.module.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.module.erlang',\n              'keyword.control.directive.module.erlang',\n              'meta.directive.module.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.module.erlang',\n              'entity.name.type.class.module.definition.erlang',\n              'meta.directive.module.erlang',\n              'punctuation.definition.parameters.end.erlang',\n              'meta.directive.module.erlang',\n              'punctuation.section.directive.end.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(module)(\\\\s*)(\\\\()(\\\\s*)([a-z][a-zA-Z\\\\d@_]*)(\\\\s*)(\\\\))(\\\\s*)(\\\\.)' } ],\n      '#number': \n       [ { token: 'text',\n           regex: '(?=\\\\d)',\n           push: \n            [ { token: 'text', regex: '(?!\\\\d)', next: 'pop' },\n              { token: \n                 [ 'constant.numeric.float.erlang',\n                   'punctuation.separator.integer-float.erlang',\n                   'constant.numeric.float.erlang',\n                   'punctuation.separator.float-exponent.erlang' ],\n                regex: '(\\\\d+)(\\\\.)(\\\\d+)((?:[eE][\\\\+\\\\-]?\\\\d+)?)' },\n              { token: \n                 [ 'constant.numeric.integer.binary.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.binary.erlang' ],\n                regex: '(2)(#)([0-1]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-3.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-3.erlang' ],\n                regex: '(3)(#)([0-2]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-4.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-4.erlang' ],\n                regex: '(4)(#)([0-3]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-5.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-5.erlang' ],\n                regex: '(5)(#)([0-4]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-6.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-6.erlang' ],\n                regex: '(6)(#)([0-5]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-7.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-7.erlang' ],\n                regex: '(7)(#)([0-6]+)' },\n              { token: \n                 [ 'constant.numeric.integer.octal.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.octal.erlang' ],\n                regex: '(8)(#)([0-7]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-9.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-9.erlang' ],\n                regex: '(9)(#)([0-8]+)' },\n              { token: \n                 [ 'constant.numeric.integer.decimal.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.decimal.erlang' ],\n                regex: '(10)(#)(\\\\d+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-11.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-11.erlang' ],\n                regex: '(11)(#)([\\\\daA]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-12.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-12.erlang' ],\n                regex: '(12)(#)([\\\\da-bA-B]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-13.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-13.erlang' ],\n                regex: '(13)(#)([\\\\da-cA-C]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-14.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-14.erlang' ],\n                regex: '(14)(#)([\\\\da-dA-D]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-15.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-15.erlang' ],\n                regex: '(15)(#)([\\\\da-eA-E]+)' },\n              { token: \n                 [ 'constant.numeric.integer.hexadecimal.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.hexadecimal.erlang' ],\n                regex: '(16)(#)([\\\\da-fA-F]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-17.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-17.erlang' ],\n                regex: '(17)(#)([\\\\da-gA-G]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-18.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-18.erlang' ],\n                regex: '(18)(#)([\\\\da-hA-H]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-19.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-19.erlang' ],\n                regex: '(19)(#)([\\\\da-iA-I]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-20.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-20.erlang' ],\n                regex: '(20)(#)([\\\\da-jA-J]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-21.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-21.erlang' ],\n                regex: '(21)(#)([\\\\da-kA-K]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-22.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-22.erlang' ],\n                regex: '(22)(#)([\\\\da-lA-L]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-23.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-23.erlang' ],\n                regex: '(23)(#)([\\\\da-mA-M]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-24.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-24.erlang' ],\n                regex: '(24)(#)([\\\\da-nA-N]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-25.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-25.erlang' ],\n                regex: '(25)(#)([\\\\da-oA-O]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-26.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-26.erlang' ],\n                regex: '(26)(#)([\\\\da-pA-P]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-27.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-27.erlang' ],\n                regex: '(27)(#)([\\\\da-qA-Q]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-28.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-28.erlang' ],\n                regex: '(28)(#)([\\\\da-rA-R]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-29.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-29.erlang' ],\n                regex: '(29)(#)([\\\\da-sA-S]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-30.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-30.erlang' ],\n                regex: '(30)(#)([\\\\da-tA-T]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-31.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-31.erlang' ],\n                regex: '(31)(#)([\\\\da-uA-U]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-32.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-32.erlang' ],\n                regex: '(32)(#)([\\\\da-vA-V]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-33.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-33.erlang' ],\n                regex: '(33)(#)([\\\\da-wA-W]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-34.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-34.erlang' ],\n                regex: '(34)(#)([\\\\da-xA-X]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-35.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-35.erlang' ],\n                regex: '(35)(#)([\\\\da-yA-Y]+)' },\n              { token: \n                 [ 'constant.numeric.integer.base-36.erlang',\n                   'punctuation.separator.base-integer.erlang',\n                   'constant.numeric.integer.base-36.erlang' ],\n                regex: '(36)(#)([\\\\da-zA-Z]+)' },\n              { token: 'invalid.illegal.integer.erlang',\n                regex: '\\\\d+#[\\\\da-zA-Z]+' },\n              { token: 'constant.numeric.integer.decimal.erlang',\n                regex: '\\\\d+' } ] } ],\n      '#parenthesized-expression': \n       [ { token: 'punctuation.section.expression.begin.erlang',\n           regex: '\\\\(',\n           push: \n            [ { token: 'punctuation.section.expression.end.erlang',\n                regex: '\\\\)',\n                next: 'pop' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.expression.parenthesized' } ] } ],\n      '#record-directive': \n       [ { token: \n            [ 'meta.directive.record.erlang',\n              'punctuation.section.directive.begin.erlang',\n              'meta.directive.record.erlang',\n              'keyword.control.directive.import.erlang',\n              'meta.directive.record.erlang',\n              'punctuation.definition.parameters.begin.erlang',\n              'meta.directive.record.erlang',\n              'entity.name.type.class.record.definition.erlang',\n              'meta.directive.record.erlang',\n              'punctuation.separator.parameters.erlang' ],\n           regex: '^(\\\\s*)(-)(\\\\s*)(record)(\\\\s*)(\\\\()(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(,)',\n           push: \n            [ { token: \n                 [ 'punctuation.definition.class.record.end.erlang',\n                   'meta.directive.record.erlang',\n                   'punctuation.definition.parameters.end.erlang',\n                   'meta.directive.record.erlang',\n                   'punctuation.section.directive.end.erlang' ],\n                regex: '(\\\\})(\\\\s*)(\\\\))(\\\\s*)(\\\\.)',\n                next: 'pop' },\n              { include: '#internal-record-body' },\n              { defaultToken: 'meta.directive.record.erlang' } ] } ],\n      '#record-usage': \n       [ { token: \n            [ 'keyword.operator.record.erlang',\n              'meta.record-usage.erlang',\n              'entity.name.type.class.record.erlang',\n              'meta.record-usage.erlang',\n              'punctuation.separator.record-field.erlang',\n              'meta.record-usage.erlang',\n              'variable.other.field.erlang' ],\n           regex: '(#)(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')(\\\\s*)(\\\\.)(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')' },\n         { token: \n            [ 'keyword.operator.record.erlang',\n              'meta.record-usage.erlang',\n              'entity.name.type.class.record.erlang' ],\n           regex: '(#)(\\\\s*)([a-z][a-zA-Z\\\\d@_]*|\\'[^\\']*\\')',\n           push: \n            [ { token: 'punctuation.definition.class.record.end.erlang',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#internal-record-body' },\n              { defaultToken: 'meta.record-usage.erlang' } ] } ],\n      '#string': \n       [ { token: 'punctuation.definition.string.begin.erlang',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.erlang',\n                regex: '\"',\n                next: 'pop' },\n              { token: \n                 [ 'punctuation.definition.escape.erlang',\n                   'constant.character.escape.erlang',\n                   'punctuation.definition.escape.erlang',\n                   'constant.character.escape.erlang',\n                   'constant.character.escape.erlang' ],\n                regex: '(\\\\\\\\)(?:([bdefnrstv\\\\\\\\\\'\"])|(\\\\^)([@-_])|([0-7]{1,3}))' },\n              { token: 'invalid.illegal.string.erlang', regex: '\\\\\\\\\\\\^?.?' },\n              { token: \n                 [ 'punctuation.definition.erlang',\n                   'punctuation.separator.erlang',\n                   'constant.other.erlang',\n                   'punctuation.separator.erlang',\n                   'punctuation.separator.erlang',\n                   'constant.other.erlang',\n                   'punctuation.separator.erlang',\n                   'punctuation.separator.erlang',\n                   'punctuation.separator.erlang',\n                   'constant.other.erlang',\n                   'constant.other.erlang' ],\n                regex: '(~)(?:((?:\\\\-)?)(\\\\d+)|(\\\\*))?(?:(\\\\.)(?:(\\\\d+)|(\\\\*)))?(?:(\\\\.)(?:(\\\\*)|(.)))?([~cfegswpWPBX#bx\\\\+ni])' },\n              { token: \n                 [ 'punctuation.definition.erlang',\n                   'punctuation.separator.erlang',\n                   'constant.other.erlang',\n                   'constant.other.erlang' ],\n                regex: '(~)((?:\\\\*)?)((?:\\\\d+)?)([~du\\\\-#fsacl])' },\n              { token: 'invalid.illegal.string.erlang', regex: '~.?' },\n              { defaultToken: 'string.quoted.double.erlang' } ] } ],\n      '#symbolic-operator': \n       [ { token: 'keyword.operator.symbolic.erlang',\n           regex: '\\\\+\\\\+|\\\\+|--|-|\\\\*|/=|/|=/=|=:=|==|=<|=|<-|<|>=|>|!|::' } ],\n      '#textual-operator': \n       [ { token: 'keyword.operator.textual.erlang',\n           regex: '\\\\b(?:andalso|band|and|bxor|xor|bor|orelse|or|bnot|not|bsl|bsr|div|rem)\\\\b' } ],\n      '#tuple': \n       [ { token: 'punctuation.definition.tuple.begin.erlang',\n           regex: '\\\\{',\n           push: \n            [ { token: 'punctuation.definition.tuple.end.erlang',\n                regex: '\\\\}',\n                next: 'pop' },\n              { token: 'punctuation.separator.tuple.erlang', regex: ',' },\n              { include: '#everything-else' },\n              { defaultToken: 'meta.structure.tuple.erlang' } ] } ],\n      '#variable': \n       [ { token: [ 'variable.other.erlang', 'variable.language.omitted.erlang' ],\n           regex: '(_[a-zA-Z\\\\d@_]+|[A-Z][a-zA-Z\\\\d@_]*)|(_)' } ] };\n    \n    this.normalizeRules();\n};\n\nErlangHighlightRules.metaData = { comment: 'The recognition of function definitions and compiler directives (such as module, record and macro definitions) requires that each of the aforementioned constructs must be the first string inside a line (except for whitespace).  Also, the function/module/record/macro names must be given unquoted.  -- desp',\n      fileTypes: [ 'erl', 'hrl' ],\n      keyEquivalent: '^~E',\n      name: 'Erlang',\n      scopeName: 'source.erlang' };\n\n\noop.inherits(ErlangHighlightRules, TextHighlightRules);\n\nexports.ErlangHighlightRules = ErlangHighlightRules;\n"
  },
  {
    "path": "src/mode/flix.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar FlixHighlightRules = require(\"./flix_highlight_rules\").FlixHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = FlixHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/flix\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/flix_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar FlixHighlightRules = function() {\n    \n    var keywords = (\n        \"use|checked_cast|checked_ecast|unchecked_cast|as|discard|from|into|inject|\" +\n        \"project|solve|query|where|select|force|import|region|handler|instanceof|new|pquery|psolve|run|super\"\n    );\n    var controlKeywords = (\n        \"choose|forA|forM|foreach|yield|if|else|case|match|ematch|try|catch|throw|spawn|par\"\n    );\n    var operators = \"not|and|or|fix\";\n    var declarations = \"eff|def|redef|law|enum|case|type|alias|trait|instance|mod|struct|let\";\n    var modifiers = \"with|lazy|lawful|pub|override|sealed|static|mut|unsafe\";\n    var primitives = \"Unit|Bool|Char|Float32|Float64|Int8|Int16|Int32|Int64|BigInt|String\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"keyword.control\": controlKeywords,\n        \"keyword.operator\": operators,\n        \"storage.type\": declarations,\n        \"storage.modifier\": modifiers,\n        \"support.type\": primitives\n    }, \"identifier\");\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment.line\",\n                regex : \"\\\\/\\\\/.*$\"\n            }, {\n                token : \"comment.block\",\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\",\n                regex : '\"',\n                next : \"string\"\n            }, {\n                token : \"string.regexp\",\n                regex : 'regex\"',\n                next : \"regex\"\n            }, {\n                token : \"constant.character\",\n                regex : \"'\",\n                next : \"char\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0x[a-fA-F0-9](_*[a-fA-F0-9])*(i8|i16|i32|i64|ii)?\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[0-9](_*[0-9])*\\\\.[0-9](_*[0-9])*(f32|f64)?\\\\b\"\n            }, {\n                token : \"constant.numeric\", // integer\n                regex : \"[0-9](_*[0-9])*(i8|i16|i32|i64|ii)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(true|false)\\\\b\"\n            }, {\n                token : \"constant.language\",\n                regex : \"null\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"\\\\->|~>|<\\\\-|=>\"\n            }, {\n                token : \"storage.modifier\",\n                regex : \"@(Deprecated|Experimental|Internal|ParallelWhenPure|Parallel|LazyWhenPure|Lazy|Skip|Test)\\\\b\"\n            }, {\n                token : \"keyword\", // hole\n                regex : \"(\\\\?\\\\?\\\\?|\\\\?[a-zA-Z0-9]+)\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment.block\",\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment.block\"\n            }\n        ],\n        \"string\" : [\n            {\n                token : \"constant.character.escape\", // unicode\n                regex : \"\\\\\\\\(u[0-9a-fA-F]{4})\"\n            }, {\n                token : \"constant.character.escape\",\n                regex : '\\\\\\\\.'\n            }, {\n                token : \"string\",\n                regex : '\"',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '[^\"\\\\\\\\]+'\n            }\n        ],\n        \"regex\" : [\n            {\n                token : \"constant.character.escape\", // unicode\n                regex : \"\\\\\\\\(u[0-9a-fA-F]{4})\"\n            }, {\n                token : \"constant.character.escape\",\n                regex : '\\\\\\\\.'\n            }, {\n                token : \"string.regexp\",\n                regex : '\"',\n                next : \"start\"\n            }, {\n                token : \"string.regexp\",\n                regex : '[^\"\\\\\\\\]+'\n            }\n        ],\n        \"char\" : [\n            {\n                token : \"constant.character.escape\", // unicode\n                regex : \"\\\\\\\\(u[0-9a-fA-F]{4})\"\n            }, {\n                token : \"constant.character.escape\",\n                regex : '\\\\\\\\.'\n            }, {\n                token : \"constant.character\",\n                regex : \"'\",\n                next : \"start\"\n            }, {\n                token : \"constant.character\",\n                regex : \"[^'\\\\\\\\]+\"\n            }\n        ]\n    };\n\n};\n\noop.inherits(FlixHighlightRules, TextHighlightRules);\n\nexports.FlixHighlightRules = FlixHighlightRules;"
  },
  {
    "path": "src/mode/folding/asciidoc.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.foldingStartMarker = /^(?:\\|={10,}|[\\.\\/=\\-~^+]{4,}\\s*$|={1,5} )/;\n    this.singleLineHeadingRe = /^={1,5}(?=\\s+\\S)/;\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        if (!this.foldingStartMarker.test(line))\n            return \"\";\n\n        if (line[0] == \"=\") {\n            if (this.singleLineHeadingRe.test(line))\n                return \"start\";\n            if (session.getLine(row - 1).length != session.getLine(row).length)\n                return \"\";\n            return \"start\";\n        }\n        if (session.bgTokenizer.getState(row) == \"dissallowDelimitedBlock\")\n            return \"end\";\n        return \"start\";\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n        if (!line.match(this.foldingStartMarker))\n            return;\n\n        var token;\n        function getTokenType(row) {\n            token = session.getTokens(row)[0];\n            return token && token.type;\n        }\n\n        var levels = [\"=\",\"-\",\"~\",\"^\",\"+\"];\n        var heading = \"markup.heading\";\n        var singleLineHeadingRe = this.singleLineHeadingRe;\n        function getLevel() {\n            var match = token.value.match(singleLineHeadingRe);\n            if (match)\n                return match[0].length;\n            var level = levels.indexOf(token.value[0]) + 1;\n            if (level == 1) {\n                if (session.getLine(row - 1).length != session.getLine(row).length)\n                    return Infinity;\n            }\n            return level;\n        }\n\n        if (getTokenType(row) == heading) {\n            var startHeadingLevel = getLevel();\n            while (++row < maxRow) {\n                if (getTokenType(row) != heading)\n                    continue;\n                var level = getLevel();\n                if (level <= startHeadingLevel)\n                    break;\n            }\n\n            var isSingleLineHeading = token && token.value.match(this.singleLineHeadingRe);\n            endRow = isSingleLineHeading ? row - 1 : row - 2;\n\n            if (endRow > startRow) {\n                while (endRow > startRow && (!getTokenType(endRow) || token.value[0] == \"[\"))\n                    endRow--;\n            }\n\n            if (endRow > startRow) {\n                var endColumn = session.getLine(endRow).length;\n                return new Range(startRow, startColumn, endRow, endColumn);\n            }\n        } else {\n            var state = session.bgTokenizer.getState(row);\n            if (state == \"dissallowDelimitedBlock\") {\n                while (row -- > 0) {\n                    if (session.bgTokenizer.getState(row).lastIndexOf(\"Block\") == -1)\n                        break;\n                }\n                endRow = row + 1;\n                if (endRow < startRow) {\n                    var endColumn = session.getLine(row).length;\n                    return new Range(endRow, 5, startRow, startColumn - 5);\n                }\n            } else {\n                while (++row < maxRow) {\n                    if (session.bgTokenizer.getState(row) == \"dissallowDelimitedBlock\")\n                        break;\n                }\n                endRow = row;\n                if (endRow > startRow) {\n                    var endColumn = session.getLine(row).length;\n                    return new Range(startRow, 5, endRow, endColumn - 5);\n                }\n            }\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/basic.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.indentKeywords = {\n        \"tron\": 1,\n        \"while\": 1,\n        \"for\": 1,\n        \"troff\": -1,\n        \"wend\": -1,\n        \"next\": -1\n    };\n\n    this.foldingStartMarker = /(?:\\s|^)(tron|while|for)\\b/i;\n    this.foldingStopMarker = /(?:\\b)(troff|next|wend)\\b/i;\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n        if (isStart || isEnd) {\n            var match = (isEnd) ? this.foldingStopMarker.exec(line) : this.foldingStartMarker.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type === \"keyword.control\")\n                    return this.basicBlock(session, row, match.index + 2);\n            }\n        }\n    };\n\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n        if (isStart && !isEnd) {\n            var match = this.foldingStartMarker.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type == \"keyword.control\") {\n                    return \"start\";\n                }\n            }\n        }\n        if (foldStyle != \"markbeginend\" || !isEnd || isStart && isEnd)\n            return \"\";\n\n        var match = line.match(this.foldingStopMarker);\n        var keyword = match && match[1].toLowerCase();\n        if (this.indentKeywords[keyword]) {\n            if (session.getTokenAt(row, match.index + 2).type === \"keyword.control\")\n                return \"end\";\n        }\n\n        return \"\";\n    };\n\n    this.basicBlock = function(session, row, column, tokenRange) {\n        var stream = new TokenIterator(session, row, column);\n\n        var token = stream.getCurrentToken();\n        if (!token || token.type != \"keyword.control\")\n            return;\n\n        var val = token.value.toLowerCase();\n        var stack = [val];\n        var dir = this.indentKeywords[val];\n\n        if (!dir)\n            return;\n\n        var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length;\n        var startRow = row;\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while(token = stream.step()) {\n            val = token.value.toLowerCase();\n            if (token.type !== \"keyword.control\" || !this.indentKeywords[val])\n                continue;\n            var level = dir * this.indentKeywords[val];\n\n            if (level > 0) {\n                stack.unshift(val);\n            } else if (level <= 0) {\n                stack.shift();\n            }\n            if (stack.length === 0) {\n                break;\n            }\n        }\n\n        if (!token)\n            return null;\n\n        if (tokenRange)\n            return stream.getCurrentTokenRange();\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1)\n            return new Range(row, session.getLine(row).length, startRow, startColumn);\n        else\n            return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/basic_test.js",
    "content": "\"use strict\";\n\nvar BasicMode = require(\"../basic\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    setUp: function() {\n        this.mode = new BasicMode();\n    },\n\n    \"test: ms-basic mode folding with markbeginend\": function() {\n        var session = new EditSession([\n            '10 INPUT\"HOW MANY DIGITS\";N',\n            '20 T=TIME',\n            '30 L=INT(10*N/3)+1:DIM A(L)',\n            '40 Z$=\"000000\":T$=\"999999\"',\n            '50 FOR I=1TOL:A(I)=2:NEXT',\n            '60 M=0:P=0',\n            '70 FOR J=1TON:Q=0:K=2*L+1',\n            '80 FOR I=L TO 1 STEP -1',\n            'WHILE FLIPS',\n            'FLIPS=0',\n            'FOR I=1 TO J-1',\n            'IF A$(I)>A$(I+1) THEN',\n            'SWAP A$(I),',\n            'A$(I+1):FLIPS=1',\n            'NEXT I',\n            'WEND',\n            '90 K=K-2:X=10*A(I)+Q*I',\n            '100 Q=INT(X/K):A(I)=X-Q*K',\n            '110 NEXT',\n            '120 Y=INT(Q/10):A(1)=Q-10*Y:Q=Y',\n            '130 IF Q=9 THEN M=M+1:GOTO170',\n            '140 IF Q>9 THEN PRINT CHR$(49+P);LEFT$(Z$,M);:GOTO170',\n            '150 PRINT CHR$(48+P);LEFT$(T$,M);',\n            '160 P=Q:M=0',\n            '170 NEXT',\n            '180 PRINT CHR$(48+P):PRINT (TIME-T)/59.98'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        // Assert fold widgets at the start of foldable regions\n        assert.equal(session.getFoldWidget(6), \"start\");  // Line 6: FOR J=1TON\n        assert.equal(session.getFoldWidget(7), \"start\");  // Line 7: FOR I=L TO 1 STEP -1\n        assert.equal(session.getFoldWidget(8), \"start\");  // Line 8: WHILE FLIPS\n        assert.equal(session.getFoldWidget(10), \"start\"); // Line10: FOR I=1 TO J-1\n\n        // Assert fold widgets at the end of foldable regions\n        assert.equal(session.getFoldWidget(14), \"end\");   // Line14: NEXT I\n        assert.equal(session.getFoldWidget(15), \"end\");   // Line15: WEND\n        assert.equal(session.getFoldWidget(18), \"end\");   // Line18: 110 NEXT\n        assert.equal(session.getFoldWidget(24), \"end\");   // Line24: 170 NEXT\n\n        // Lines without fold widgets\n        for (var i = 0; i < session.getLength(); i++) {\n            if ([0, 1, 2, 3, 4, 6, 7, 8, 10, 14, 15, 18, 24].indexOf(i) === -1) {\n                assert.equal(session.getFoldWidget(i), \"\");\n            }\n        }\n\n        // Check folding ranges from start lines\n        var range;\n        range = session.getFoldWidgetRange(6);\n        assert.range(range, 6, 25, 24, 4);\n\n        range = session.getFoldWidgetRange(7);\n        assert.range(range, 7, 23, 18, 4);\n\n        range = session.getFoldWidgetRange(8);\n        assert.range(range, 8, 11, 15, 0);\n\n        range = session.getFoldWidgetRange(10);\n        assert.range(range, 10, 14, 14, 0);\n\n        // Check folding ranges from end lines\n        range = session.getFoldWidgetRange(14);\n        assert.range(range, 10, 14, 14, 0);\n\n        range = session.getFoldWidgetRange(15);\n        assert.range(range, 8, 11, 15, 0);\n\n        range = session.getFoldWidgetRange(18);\n        assert.range(range, 7, 23, 18, 4);\n\n        range = session.getFoldWidgetRange(24);\n        assert.range(range, 6, 25, 24, 4);\n    }\n};\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/c9search.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.foldingStartMarker = /^(\\S.*:|Searching for.*)$/;\n    this.foldingStopMarker = /^(\\s+|Found.*)$/;\n    \n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var lines = session.doc.getAllLines(row);\n        var line = lines[row];\n        var level1 = /^(Found.*|Searching for.*)$/;\n        var level2 = /^(\\S.*:|\\s*)$/;\n        var re = level1.test(line) ? level1 : level2;\n        \n        var startRow = row;\n        var endRow = row;\n\n        if (this.foldingStartMarker.test(line)) {\n            for (var i = row + 1, l = session.getLength(); i < l; i++) {\n                if (re.test(lines[i]))\n                    break;\n            }\n            endRow = i;\n        }\n        else if (this.foldingStopMarker.test(line)) {\n            for (var i = row - 1; i >= 0; i--) {\n                line = lines[i];\n                if (re.test(line))\n                    break;\n            }\n            startRow = i;\n        }\n        if (startRow != endRow) {\n            var col = line.length;\n            if (re === level1)\n                col = line.search(/\\(Found[^)]+\\)$|$/);\n            return new Range(startRow, col, endRow, 0);\n        }\n    };\n    \n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/coffee.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.commentBlock = function(session, row) {\n        var re = /\\S/;\n        var line = session.getLine(row);\n        var startLevel = line.search(re);\n        if (startLevel == -1 || line[startLevel] != \"#\")\n            return;\n\n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var level = line.search(re);\n\n            if (level == -1)\n                continue;\n\n            if (line[level] != \"#\")\n                break;\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var range = this.indentationBlock(session, row);\n        if (range)\n            return range;\n\n        range = this.commentBlock(session, row);\n        if (range)\n            return range;\n    };\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var indent = line.search(/\\S/);\n        var next = session.getLine(row + 1);\n        var prev = session.getLine(row - 1);\n        var prevIndent = prev.search(/\\S/);\n        var nextIndent = next.search(/\\S/);\n\n        if (indent == -1) {\n            session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? \"start\" : \"\";\n            return \"\";\n        }\n\n        // documentation comments\n        if (prevIndent == -1) {\n            if (indent == nextIndent && line[indent] == \"#\" && next[indent] == \"#\") {\n                session.foldWidgets[row - 1] = \"\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"start\";\n            }\n        } else if (prevIndent == indent && line[indent] == \"#\" && prev[indent] == \"#\") {\n            if (session.getLine(row - 2).search(/\\S/) == -1) {\n                session.foldWidgets[row - 1] = \"start\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"\";\n            }\n        }\n\n        if (prevIndent!= -1 && prevIndent < indent)\n            session.foldWidgets[row - 1] = \"start\";\n        else\n            session.foldWidgets[row - 1] = \"\";\n\n        if (indent < nextIndent)\n            return \"start\";\n        else\n            return \"\";\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/coffee_test.js",
    "content": "\"use strict\";\n\nvar CoffeeMode = require(\"../coffee\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\nfunction testFoldWidgets(array) {\n    var session = array.filter(function(_, i){return i % 2 == 1;});\n    session = new EditSession(session);\n    var mode = new CoffeeMode();\n    session.setFoldStyle(\"markbeginend\");\n    session.setMode(mode);\n\n    var widgets = array.filter(function(_, i){return i % 2 == 0;});\n    widgets.forEach(function(w, i){\n        session.foldWidgets[i] = session.getFoldWidget(i);\n    });\n    widgets.forEach(function(w, i){\n        w = w.split(\",\");\n        var type = w[0] == \">\" ? \"start\" : w[0] == \"<\" ? \"end\" : \"\";\n        assert.equal(session.foldWidgets[i], type);\n        if (!type)\n            return;\n        var range = session.getFoldWidgetRange(i);\n        if (!w[1]) {\n            assert.equal(range, null);\n            return;\n        }\n        assert.equal(range.start.row, i);\n        assert.equal(range.end.row - range.start.row, parseInt(w[1]));\n        testColumn(w[2], range.start);\n        testColumn(w[3], range.end);\n    });\n\n    function testColumn(w, pos) {\n        if (!w)\n            return;\n        if (w == \"l\")\n            w = session.getLine(pos.row).length;\n        else\n            w = parseInt(w);\n        assert.equal(pos.column, w);\n    }\n}\nmodule.exports = {\n    \"test: coffee script indentation based folding\": function() {\n       testFoldWidgets([\n            '>,1,l,l',         ' ## indented comment',\n            '',                '  # ',\n            '',                '',\n            '>,1,l,l',         ' # plain comment',\n            '',                ' # ',\n            '>,2',             ' function (x)=>',\n            '',                '  ',\n            '',                '  x++',\n            '',                '  ',\n            '',                '  ',\n            '>,2',             ' bar = ',\n            '',                '   foo: 1',\n            '',                '   baz: lighter'\n        ]);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/csharp.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar CFoldMode = require(\"./cstyle\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(commentRegex) {\n    if (commentRegex) {\n        this.foldingStartMarker = new RegExp(\n            this.foldingStartMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.start)\n        );\n        this.foldingStopMarker = new RegExp(\n            this.foldingStopMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.end)\n        );\n    }\n};\noop.inherits(FoldMode, CFoldMode);\n\n(function() {\n    this.usingRe = /^\\s*using \\S/;\n\n    this.getFoldWidgetRangeBase = this.getFoldWidgetRange;\n    this.getFoldWidgetBase = this.getFoldWidget;\n    \n    this.getFoldWidget = function(session, foldStyle, row) {\n        var fw = this.getFoldWidgetBase(session, foldStyle, row);\n        if (!fw) {\n            var line = session.getLine(row);\n            if (/^\\s*#region\\b/.test(line)) \n                return \"start\";\n            var usingRe = this.usingRe;\n            if (usingRe.test(line)) {\n                var prev = session.getLine(row - 1);\n                var next = session.getLine(row + 1);\n                if (!usingRe.test(prev) && usingRe.test(next))\n                    return \"start\";\n            }\n        }\n        return fw;\n    };\n    \n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var range = this.getFoldWidgetRangeBase(session, foldStyle, row);\n        if (range)\n            return range;\n\n        var line = session.getLine(row);\n        if (this.usingRe.test(line))\n            return this.getUsingStatementBlock(session, line, row);\n            \n        if (/^\\s*#region\\b/.test(line))\n            return this.getRegionBlock(session, line, row);\n    };\n    \n    this.getUsingStatementBlock = function(session, line, row) {\n        var startColumn = line.match(this.usingRe)[0].length - 1;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            if (/^\\s*$/.test(line))\n                continue;\n            if (!this.usingRe.test(line))\n                break;\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n    \n    this.getRegionBlock = function(session, line, row) {\n        var startColumn = line.search(/\\s*$/);\n        var maxRow = session.getLength();\n        var startRow = row;\n        \n        var re = /^\\s*#(end)?region\\b/;\n        var depth = 1;\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var m = re.exec(line);\n            if (!m)\n                continue;\n            if (m[1])\n                depth--;\n            else\n                depth++;\n\n            if (!depth)\n                break;\n        }\n\n        var endRow = row;\n        if (endRow > startRow) {\n            return new Range(startRow, startColumn, endRow, line.length);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/cstyle.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(commentRegex) {\n    if (commentRegex) {\n        this.foldingStartMarker = new RegExp(\n            this.foldingStartMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.start)\n        );\n        this.foldingStopMarker = new RegExp(\n            this.foldingStopMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.end)\n        );\n    }\n};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    \n    this.foldingStartMarker = /([\\{\\[\\(])[^\\}\\]\\)]*$|^\\s*(\\/\\*)/;\n    this.foldingStopMarker = /^[^\\[\\{\\(]*([\\}\\]\\)])|^[\\s\\*]*(\\*\\/)/;\n    this.singleLineBlockCommentRe= /^\\s*(\\/\\*).*\\*\\/\\s*$/;\n    this.tripleStarBlockCommentRe = /^\\s*(\\/\\*\\*\\*).*\\*\\/\\s*$/;\n    this.startRegionRe = /^\\s*(\\/\\*|\\/\\/)#?region\\b/;\n    \n    //prevent naming conflict with any modes that inherit from cstyle and override this (like csharp)\n    this._getFoldWidgetBase = this.getFoldWidget;\n    \n    /**\n     * Gets fold widget with some non-standard extras:\n     *\n     * @example lineCommentRegionStart\n     *      //#region [optional description]\n     *\n     * @example blockCommentRegionStart\n     *      /*#region [optional description] *[/]\n     *\n     * @example tripleStarFoldingSection\n     *      /*** this folds even though 1 line because it has 3 stars ***[/]\n     * \n     * @note the pound symbol for region tags is optional\n     */\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n    \n        if (this.singleLineBlockCommentRe.test(line)) {\n            // No widget for single line block comment unless region or triple star\n            if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line))\n                return \"\";\n        }\n    \n        var fw = this._getFoldWidgetBase(session, foldStyle, row);\n    \n        if (!fw && this.startRegionRe.test(line))\n            return \"start\"; // lineCommentRegionStart\n    \n        return fw;\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {\n        var line = session.getLine(row);\n        \n        if (this.startRegionRe.test(line))\n            return this.getCommentRegionBlock(session, line, row);\n        \n        var match = line.match(this.foldingStartMarker);\n        if (match) {\n            var i = match.index;\n\n            if (match[1])\n                return this.openingBracketBlock(session, match[1], row, i);\n                \n            var range = session.getCommentFoldRange(row, i + match[0].length, 1);\n            \n            if (range && !range.isMultiLine()) {\n                if (forceMultiline) {\n                    range = this.getSectionRange(session, row);\n                } else if (foldStyle != \"all\")\n                    range = null;\n            }\n            \n            return range;\n        }\n\n        if (foldStyle === \"markbegin\")\n            return;\n\n        var match = line.match(this.foldingStopMarker);\n        if (match) {\n            var i = match.index + match[0].length;\n\n            if (match[1])\n                return this.closingBracketBlock(session, match[1], row, i);\n\n            return session.getCommentFoldRange(row, i, -1);\n        }\n    };\n    \n    this.getSectionRange = function(session, row) {\n        var line = session.getLine(row);\n        var startIndent = line.search(/\\S/);\n        var startRow = row;\n        var startColumn = line.length;\n        row = row + 1;\n        var endRow = row;\n        var maxRow = session.getLength();\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var indent = line.search(/\\S/);\n            if (indent === -1)\n                continue;\n            if  (startIndent > indent)\n                break;\n            var subRange = this.getFoldWidgetRange(session, \"all\", row);\n            \n            if (subRange) {\n                if (subRange.start.row <= startRow) {\n                    break;\n                } else if (subRange.isMultiLine()) {\n                    row = subRange.end.row;\n                } else if (startIndent == indent) {\n                    break;\n                }\n            }\n            endRow = row;\n        }\n        \n        return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);\n    };\n    \n    /**\n     * gets comment region block with end region assumed to be start of comment in any cstyle mode or SQL mode (--) which inherits from this.\n     * There may optionally be a pound symbol before the region/endregion statement\n     */\n    this.getCommentRegionBlock = function(session, line, row) {\n        var startColumn = line.search(/\\s*$/);\n        var maxRow = session.getLength();\n        var startRow = row;\n        \n        var re = /^\\s*(?:\\/\\*|\\/\\/|--)#?(end)?region\\b/;\n        var depth = 1;\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var m = re.exec(line);\n            if (!m) continue;\n            if (m[1]) depth--;\n            else depth++;\n\n            if (!depth) break;\n        }\n\n        var endRow = row;\n        if (endRow > startRow) {\n            return new Range(startRow, startColumn, endRow, line.length);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/cstyle_test.js",
    "content": "\"use strict\";\n\nvar JavaScriptMode = require(\"../javascript\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n    \"test: fold comments\": function() {\n        var session = new EditSession([\n            '/*',\n            'stuff',\n            '*/'\n        ]);\n        \n        var mode = new JavaScriptMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 2, 2, 0);\n        assert.range(session.getFoldWidgetRange(2), 0, 2, 2, 0);\n    },\n    \n    \"test: fold doc style comments\": function() {\n        var session = new EditSession([\n            '/**',\n            ' * stuff',\n            ' * *** */'\n        ]);\n        \n        var mode = new JavaScriptMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 3, 2, 7);\n        assert.range(session.getFoldWidgetRange(2), 0, 3, 2, 7);\n    },\n    \n    \"test: fold sections\": function() {\n        var session = new EditSession([\n            '/*** section0 ***/',\n            '{',\n            '    /*** section1 ***/',\n            '    stuff',\n            '       ',\n            '    /*** section2 ***/',\n            '       ',\n            '    stuff',\n            '       ',\n            '     }',\n            'foo'\n        ]);\n        \n        var mode = new JavaScriptMode();\n        session.setFoldStyle(\"markbegin\");\n        session.setMode(mode);\n        \n        assert.range(session.getFoldWidgetRange(0, true), 0, 18, 10, 3);\n        assert.range(session.getFoldWidgetRange(2, true), 2, 22, 3, 9);\n        assert.range(session.getFoldWidgetRange(5, true), 5, 22, 7, 9);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/diff.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function(levels, flag) {\n\tthis.regExpList = levels;\n\tthis.flag = flag;\n\tthis.foldingStartMarker = RegExp(\"^(\" + levels.join(\"|\") + \")\", this.flag);\n};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var start = {row: row, column: line.length};\n\n        var regList = this.regExpList;\n        for (var i = 1; i <= regList.length; i++) {\n            var re = RegExp(\"^(\" + regList.slice(0, i).join(\"|\") + \")\", this.flag);\n            if (re.test(line))\n                break;\n        }\n\n        for (var l = session.getLength(); ++row < l; ) {\n            line = session.getLine(row);\n            if (re.test(line))\n                break;\n        }\n        if (row == start.row + 1)\n            return;\n        return new Range(start.row, start.column, row - 1, line.length);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/drools.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function () {\n\n    // regular expressions that identify starting and stopping points\n    this.foldingStartMarker = /\\b(rule|declare|query|when|then)\\b/;\n    this.foldingStopMarker = /\\bend\\b/;\n    this.importRegex = /^import /;\n    this.globalRegex = /^global /;\n    this.getBaseFoldWidget = this.getFoldWidget;\n\n    this.getFoldWidget = function (session, foldStyle, row) {\n        if (foldStyle === \"markbegin\") {\n            var line = session.getLine(row);\n            if (this.importRegex.test(line)) {\n                if (row === 0 || !this.importRegex.test(session.getLine(row - 1)))\n                    return \"start\";\n            }\n            if (this.globalRegex.test(line)) {\n                if (row === 0 || !this.globalRegex.test(session.getLine(row - 1)))\n                    return \"start\";\n            }\n        }\n\n        return this.getBaseFoldWidget(session, foldStyle, row);\n    };\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var match = line.match(this.foldingStartMarker);\n\n        if (match) {\n            if (match[1]) {\n                var position = {row: row, column: line.length};\n                var iterator = new TokenIterator(session, position.row, position.column);\n                var seek = \"end\";\n                var token = iterator.getCurrentToken();\n                if (token.value == \"when\") {\n                    seek = \"then\";\n                }\n                while (token) {\n                    if (token.value == seek) {\n                        return Range.fromPoints(position ,{\n                            row: iterator.getCurrentTokenRow(),\n                            column: iterator.getCurrentTokenColumn()\n                        });\n                    }\n                    token = iterator.stepForward();\n                }\n            }\n\n        }\n        match = line.match(this.importRegex);\n        if (match) {\n            return getMatchedFoldRange(session, this.importRegex, match, row);\n        }\n        match = line.match(this.globalRegex);\n        if (match) {\n            return getMatchedFoldRange(session, this.globalRegex, match, row);\n        }\n        // test each line, and return a range of segments to collapse\n    };\n\n}).call(FoldMode.prototype);\n\nfunction getMatchedFoldRange(session, regex, match, row) {\n    let startColumn = match[0].length;\n    let maxRow = session.getLength();\n    let startRow = row;\n    let endRow = row;\n\n    while (++row < maxRow) {\n        let line = session.getLine(row);\n        if (line.match(/^\\s*$/))\n            continue;\n\n        if (!line.match(regex))\n            break;\n\n        endRow = row;\n    }\n\n    if (endRow > startRow) {\n        let endColumn = session.getLine(endRow).length;\n        return new Range(startRow, startColumn, endRow, endColumn);\n    }\n}\n"
  },
  {
    "path": "src/mode/folding/drools_test.js",
    "content": "\"use strict\";\n\nconst DroolsMode = require(\"../drools\").Mode;\nconst EditSession = require(\"../../edit_session\").EditSession;\nconst assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n  \"test: drools folds\": function () {\n    const session = new EditSession([\n      'package com.example.ace',\n      'import java.math.BigDecimal',\n      'import function my.package.Foo.hello',\n      '',\n      'global org.slf4j.Logger logger',\n      'global java.lang.Boolean checkFlag',\n      '',\n      'declare trait GoldenCustomer',\n      '    balance : long @Alias( \"org.acme.foo.accountBalance\" )',\n      'end',\n      'query isContainedIn( String x, String y )',\n      '    Location( z, y; ) and isContainedIn( x, z;)',\n      'end',\n      'rule \"go1\"',\n      '    String( this == \"go1\" )',\n      '    isContainedIn(\"Office\", \"House\"; )',\n      'then',\n      '    System.out.println( \"office is in the house\" );',\n      'end'\n    ]);\n\n    const mode = new DroolsMode();\n    session.setMode(mode);\n    session.setFoldStyle(\"markbegin\");\n\n    assert.equal(session.getFoldWidget(0), \"\");\n    assert.equal(session.getFoldWidget(1), \"start\"); // import\n    assert.equal(session.getFoldWidget(2), \"\");\n    assert.equal(session.getFoldWidget(3), \"\");\n    assert.equal(session.getFoldWidget(4), \"start\"); // global\n    assert.equal(session.getFoldWidget(5), \"\");\n    assert.equal(session.getFoldWidget(6), \"\");\n    assert.equal(session.getFoldWidget(7), \"start\"); // declare\n    assert.equal(session.getFoldWidget(8), \"\");\n    assert.equal(session.getFoldWidget(9), \"\");\n    assert.equal(session.getFoldWidget(10), \"start\");  // query\n    assert.equal(session.getFoldWidget(11), \"\");\n    assert.equal(session.getFoldWidget(12), \"\");\n    assert.equal(session.getFoldWidget(13), \"start\"); // rule\n    assert.equal(session.getFoldWidget(14), \"\");\n    assert.equal(session.getFoldWidget(15), \"\");\n    assert.equal(session.getFoldWidget(16), \"start\"); // then\n    assert.equal(session.getFoldWidget(17), \"\");\n    assert.equal(session.getFoldWidget(18), \"\");\n\n    assert.range(session.getFoldWidgetRange(1), 1, 7, 2, 36); // import\n    assert.range(session.getFoldWidgetRange(4), 4, 7, 5, 34); // global\n    assert.range(session.getFoldWidgetRange(7), 7, 28, 9, 0); // declare\n    assert.range(session.getFoldWidgetRange(10), 10, 41, 12, 0); // query\n    assert.range(session.getFoldWidgetRange(13), 13, 10, 18, 0); // rule\n    assert.range(session.getFoldWidgetRange(16), 16, 4, 18, 0); // then\n  }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/fold_mode.js",
    "content": "\"use strict\";\n\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\n\n(function() {\n\n    this.foldingStartMarker = null;\n    this.foldingStopMarker = null;\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        if (this.foldingStartMarker.test(line))\n            return \"start\";\n        if (foldStyle == \"markbeginend\"\n                && this.foldingStopMarker\n                && this.foldingStopMarker.test(line))\n            return \"end\";\n        return \"\";\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        return null;\n    };\n\n    this.indentationBlock = function(session, row, column) {\n        var re = /\\S/;\n        var line = session.getLine(row);\n        var startLevel = line.search(re);\n        if (startLevel == -1)\n            return;\n\n        var startColumn = column || line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            var level = session.getLine(row).search(re);\n\n            if (level == -1)\n                continue;\n\n            if (level <= startLevel) {\n                var token = session.getTokenAt(row, 0);\n                if (!token || token.type !== \"string\")\n                    break;\n            }\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n    this.openingBracketBlock = function(session, bracket, row, column, typeRe) {\n        var start = {row: row, column: column + 1};\n        var end = session.$findClosingBracket(bracket, start, typeRe);\n        if (!end)\n            return;\n\n        var fw = session.foldWidgets[end.row];\n        if (fw == null)\n            fw = session.getFoldWidget(end.row);\n\n        if (fw == \"start\" && end.row > start.row) {\n            end.row --;\n            end.column = session.getLine(end.row).length;\n        }\n        return Range.fromPoints(start, end);\n    };\n\n    this.closingBracketBlock = function(session, bracket, row, column, typeRe) {\n        var end = {row: row, column: column};\n        var start = session.$findOpeningBracket(bracket, end);\n\n        if (!start)\n            return;\n\n        start.column++;\n        end.column--;\n\n        return  Range.fromPoints(start, end);\n    };\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/fold_mode_test.js",
    "content": "\"use strict\";\n\nvar MarkdownMode = require(\"../markdown\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n    \"test: markdown folding\": function() {\n        var session = new EditSession([\n            \"# heading 1\",\n            \"## heading 2\",\n            \"something\",\n            \"### heading 3\",\n            \"#### heading4\",\n            \"other\",\n            \"\",\n            \"article 1\",\n            \"======\",\n            \"A Paragraph.\",\n            \"level 2\",\n            \"--------\",\n            \"A Paragraph.\"\n        ]);\n        var expected = \"[0/11][5/5],[1/12][5/5],,[3/13][5/5],[4/13][5/5],,,,[8/6][12/12],,,[11/8][12/12],\";\n\n        var mode = new MarkdownMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        var ranges = session.doc.getAllLines().map(function(_, i) {\n            return session.getFoldWidgetRange(i); \n        });\n\n        assert.equal(ranges.toString().replace(/Range:|[\\s]|->/g, \"\"), expected);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/haskell_cabal.js",
    "content": "/*\n* Folding mode for Cabal files (Haskell): allow folding each seaction, including\n* the initial general section.\n*/\n\n\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n  /**\n  is the row a heading?\n  */\n  this.isHeading = function (session,row) {\n      var heading = \"markup.heading\";\n      var token = session.getTokens(row)[0];\n      return row==0 || (token && token.type.lastIndexOf(heading, 0) === 0);\n  };\n\n  this.getFoldWidget = function(session, foldStyle, row) {\n      if (this.isHeading(session,row)){\n        return \"start\";\n      } else if (foldStyle === \"markbeginend\" && !(/^\\s*$/.test(session.getLine(row)))){\n        var maxRow = session.getLength();\n        while (++row < maxRow) {\n          if (!(/^\\s*$/.test(session.getLine(row)))){\n              break;\n          }\n        }\n        if (row==maxRow || this.isHeading(session,row)){\n          return \"end\";\n        }\n      }\n      return \"\";\n  };\n\n\n  this.getFoldWidgetRange = function(session, foldStyle, row) {\n      var line = session.getLine(row);\n      var startColumn = line.length;\n      var maxRow = session.getLength();\n      var startRow = row;\n      var endRow = row;\n      // go until next heading\n      if (this.isHeading(session,row)) {\n          while (++row < maxRow) {\n              if (this.isHeading(session,row)){\n                row--;\n                break;\n              }\n          }\n\n          endRow = row;\n          // remove empty lines at end\n          if (endRow > startRow) {\n              while (endRow > startRow && /^\\s*$/.test(session.getLine(endRow)))\n                  endRow--;\n          }\n\n          if (endRow > startRow) {\n              var endColumn = session.getLine(endRow).length;\n              return new Range(startRow, startColumn, endRow, endColumn);\n          }\n      // go back to heading\n      } else if (this.getFoldWidget(session, foldStyle, row)===\"end\"){\n        var endRow = row;\n        var endColumn = session.getLine(endRow).length;\n        while (--row>=0){\n          if (this.isHeading(session,row)){\n            break;\n          }\n        }\n        var line = session.getLine(row);\n        var startColumn = line.length;\n        return new Range(row, startColumn, endRow, endColumn);\n      }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/html.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar MixedFoldMode = require(\"./mixed\").FoldMode;\nvar XmlFoldMode = require(\"./xml\").FoldMode;\nvar CStyleFoldMode = require(\"./cstyle\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(voidElements, optionalTags) {\n    MixedFoldMode.call(this, new XmlFoldMode(voidElements, optionalTags), {\n        \"js-\": new CStyleFoldMode(),\n        \"css-\": new CStyleFoldMode()\n    });\n};\n\noop.inherits(FoldMode, MixedFoldMode);\n"
  },
  {
    "path": "src/mode/folding/html_test.js",
    "content": "\"use strict\";\n\nvar HtmlMode = require(\"../html\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n    \"test: fold mixed html and javascript\": function() {\n        var session = new EditSession([\n            '<script type=\"text/javascript\"> ',\n            'function() foo {',\n            '    var bar = 1;',\n            '}',\n            '</script>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"end\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 31, 4, 0);\n        assert.range(session.getFoldWidgetRange(4), 0, 31, 4, 0);\n        \n        assert.range(session.getFoldWidgetRange(1), 1, 16, 3, 0);\n        assert.range(session.getFoldWidgetRange(3), 1, 16, 3, 0);\n    },\n    \n    \"test: fold mixed html and css\": function() {\n        var session = new EditSession([\n            '<style type=\"text/css\">',\n            '    .text-layer {',\n            '        font-family: Monaco, \"Courier New\", monospace;',\n            '    }',\n            '</style>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"end\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 23, 4, 0);\n        assert.range(session.getFoldWidgetRange(4), 0, 23, 4, 0);\n        \n        assert.range(session.getFoldWidgetRange(1), 1, 17, 3, 4);\n        assert.range(session.getFoldWidgetRange(3), 1, 17, 3, 4);\n    },\n    \n    \"test: fold should skip self closing elements\": function() {\n        var session = new EditSession([\n            '<body>',\n            '<br />',\n            '</body>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 6, 2, 0);\n        assert.range(session.getFoldWidgetRange(2), 0, 6, 2, 0);\n    },\n    \n    \"test: fold should skip void elements\": function() {\n        var session = new EditSession([\n            '<body>',\n            '<br>',\n            '</body>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 6, 2, 0);\n        assert.range(session.getFoldWidgetRange(2), 0, 6, 2, 0);\n    },\n    \n    \"test: fold multiple unclosed elements\": function() {\n        var session = new EditSession([\n            '<div>',\n            '<p>',\n            'juhu',\n            '<p>',\n            'kinners',\n            '</div>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 5, 5, 0);\n        assert.range(session.getFoldWidgetRange(5), 0, 5, 5, 0);\n    },\n    \n    \"test: fold multiple nested optional elements\": function() {\n        var session = new EditSession([\n            '<p>',\n            '<li>',\n            '<p>juhu',\n            '<p>',\n            'kinners',\n            '</li>'\n        ]);\n        \n        var mode = new HtmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"start\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(1), 1, 4, 5, 0);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/ini.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function() {\n};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.foldingStartMarker = /^\\s*\\[([^\\])]*)]\\s*(?:$|[;#])/;\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var re = this.foldingStartMarker;\n        var line = session.getLine(row);\n        \n        var m = line.match(re);\n        \n        if (!m) return;\n        \n        var startName = m[1] + \".\";\n        \n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            if (/^\\s*$/.test(line))\n                continue;\n            m = line.match(re);\n            if (m && m[1].lastIndexOf(startName, 0) !== 0)\n                break;\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/java.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar CStyleFoldMode = require(\"./cstyle\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, CStyleFoldMode);\n\n(function() {\n    this.importRegex = /^import /;\n    this.getCStyleFoldWidget = this.getFoldWidget;\n    this.getFoldWidget = function(session, foldStyle, row) {\n        if (foldStyle === \"markbegin\") {\n            var line = session.getLine(row);\n            if (this.importRegex.test(line)) {\n                if (row == 0 || !this.importRegex.test(session.getLine(row - 1)))\n                    return \"start\";\n            }\n        }\n\n        return this.getCStyleFoldWidget(session, foldStyle, row);\n    };\n    \n    this.getCstyleFoldWidgetRange = this.getFoldWidgetRange;\n    this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {\n        var line = session.getLine(row);\n        var match = line.match(this.importRegex);\n        if (!match || foldStyle !== \"markbegin\")\n            return this.getCstyleFoldWidgetRange(session, foldStyle, row, forceMultiline);\n\n        var startColumn = match[0].length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            var line = session.getLine(row);\n            if (line.match(/^\\s*$/))\n                continue;\n\n            if (!line.match(this.importRegex))\n                break;\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/javascript.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar XmlFoldMode = require(\"./xml\").FoldMode;\nvar CFoldMode = require(\"./cstyle\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function (commentRegex) {\n    if (commentRegex) {\n        this.foldingStartMarker = new RegExp(\n            this.foldingStartMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.start));\n        this.foldingStopMarker = new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/, \"|\" + commentRegex.end));\n    }\n\n    this.xmlFoldMode = new XmlFoldMode();\n};\noop.inherits(FoldMode, CFoldMode);\n\n(function () {\n\n    this.getFoldWidgetRangeBase = this.getFoldWidgetRange;\n    this.getFoldWidgetBase = this.getFoldWidget;\n\n    this.getFoldWidget = function (session, foldStyle, row) {\n        var fw = this.getFoldWidgetBase(session, foldStyle, row);\n        if (!fw) {\n            return this.xmlFoldMode.getFoldWidget(session, foldStyle, row);\n        }\n        return fw;\n    };\n\n    this.getFoldWidgetRange = function (session, foldStyle, row, forceMultiline) {\n        var range = this.getFoldWidgetRangeBase(session, foldStyle, row, forceMultiline);\n        if (range) return range;\n\n        return this.xmlFoldMode.getFoldWidgetRange(session, foldStyle, row);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/javascript_test.js",
    "content": "\"use strict\";\n\nvar JavaScriptMode = require(\"../javascript\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    \"test: fold jsdoc style comments\": function() {\n        var session = new EditSession([\n            '/**',\n             ' *',\n             ' * @param {string[]} items',\n             ' * @param nada',\n             '*/ '\n        ]);\n\n        var mode = new JavaScriptMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 3, 4, 0);\n        assert.range(session.getFoldWidgetRange(4), 0, 3, 4, 0);\n    },\n    \"test: fold mixed js and jsx\": function () {\n        var session = new EditSession([\n            'function Greeting(props) {', '    return (', '        <div>', '            {/* Comment inside JSX */}',\n            '            <h1>Hello, {props.name}</h1>', '            <p>You are {props.age} years old.</p>',\n            '        </div>', '    );', '}', ''\n        ]);\n\n        var mode = new JavaScriptMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"start\");\n        assert.equal(session.getFoldWidget(3), \"\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"\");\n        assert.equal(session.getFoldWidget(6), \"end\");\n        assert.equal(session.getFoldWidget(7), \"end\");\n        assert.equal(session.getFoldWidget(8), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 26, 8, 0);\n        assert.range(session.getFoldWidgetRange(1), 1, 12, 7, 4);\n        assert.range(session.getFoldWidgetRange(2), 2, 13, 6, 8);\n    }\n\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/latex.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\nvar keywordLevels = {\n    \"\\\\subparagraph\": 1,\n    \"\\\\paragraph\": 2,\n    \"\\\\subsubsubsection\": 3,\n    \"\\\\subsubsection\": 4,\n    \"\\\\subsection\": 5,\n    \"\\\\section\": 6,\n    \"\\\\chapter\": 7,\n    \"\\\\part\": 8,\n    \"\\\\begin\": 9,\n    \"\\\\end\": 10\n};\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.foldingStartMarker = /^\\s*\\\\(begin)|\\s*\\\\(part|chapter|(?:sub)*(?:section|paragraph))\\b|{\\s*$/;\n    this.foldingStopMarker = /^\\s*\\\\(end)\\b|^\\s*}/;\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.doc.getLine(row);\n        var match = this.foldingStartMarker.exec(line);\n        if (match) {\n            if (match[1])\n                return this.latexBlock(session, row, match[0].length - 1);\n            if (match[2])\n                return this.latexSection(session, row, match[0].length - 1);\n\n            return this.openingBracketBlock(session, \"{\", row, match.index);\n        }\n\n        var match = this.foldingStopMarker.exec(line);\n        if (match) {\n            if (match[1])\n                return this.latexBlock(session, row, match[0].length - 1);\n\n            return this.closingBracketBlock(session, \"}\", row, match.index + match[0].length);\n        }\n    };\n\n    this.latexBlock = function(session, row, column, returnRange) {\n        var keywords = {\n            \"\\\\begin\": 1,\n            \"\\\\end\": -1\n        };\n\n        var stream = new TokenIterator(session, row, column);\n        var token = stream.getCurrentToken();\n        if (!token || !(token.type == \"storage.type\" || token.type == \"constant.character.escape\"))\n            return;\n\n        var val = token.value;\n        var dir = keywords[val];\n\n        var getType = function() {\n            var token = stream.stepForward();\n            var type = token && token.type == \"lparen\" ? stream.stepForward().value : \"\";\n            if (dir === -1) {\n                stream.stepBackward();\n                if (type)\n                    stream.stepBackward();\n            }\n            return type;\n        };\n        var stack = [getType()];\n        var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length;\n        var startRow = row;\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while(token = stream.step()) {\n            if (!token || !(token.type == \"storage.type\" || token.type == \"constant.character.escape\"))\n                continue;\n            var level = keywords[token.value];\n            if (!level)\n                continue;\n            var type = getType();\n            if (level === dir)\n                stack.unshift(type);\n            else if (stack.shift() !== type || !stack.length)\n                break;\n        }\n\n        if (stack.length)\n            return;\n        \n        if (dir == 1) {\n            stream.stepBackward();\n            stream.stepBackward();\n        }\n        \n        if (returnRange)\n            return stream.getCurrentTokenRange();\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1)\n            return new Range(row, session.getLine(row).length, startRow, startColumn);\n        else\n            return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());\n    };\n\n    this.latexSection = function(session, row, column) {\n        var stream = new TokenIterator(session, row, column);\n        var token = stream.getCurrentToken();\n        if (!token || token.type != \"storage.type\")\n            return;\n\n        var startLevel = keywordLevels[token.value] || 0;\n        var stackDepth = 0;\n        var endRow = row;\n\n        while(token = stream.stepForward()) {\n            if (token.type !== \"storage.type\")\n                continue;\n            var level = keywordLevels[token.value] || 0;\n\n            if (level >= 9) {\n                if (!stackDepth)\n                    endRow = stream.getCurrentTokenRow() - 1;\n                stackDepth += level == 9 ? 1 : - 1;\n                if (stackDepth < 0)\n                    break;\n            } else if (level >= startLevel)\n                break;\n        }\n\n        if (!stackDepth)\n            endRow = stream.getCurrentTokenRow() - 1;\n\n        while (endRow > row && !/\\S/.test(session.getLine(endRow)))\n            endRow--;\n\n        return new Range(\n            row, session.getLine(row).length,\n            endRow, session.getLine(endRow).length\n        );\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/latex_test.js",
    "content": "\"use strict\";\n\nvar LatexMode = require(\"../latex\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    \"test: latex block folding\": function () {\n        var session = new EditSession([\n            '\\\\usepackage{amsmath}', '\\\\title{\\\\LaTeX}', '\\\\date{}', '\\\\begin'\n        ]);\n\n        var mode = new LatexMode();\n        session.setFoldStyle(\"markbegin\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidgetRange(3), null);\n\n        session.setValue(session.getValue() + '{test}\\nsome text here \\n\\\\end{test}');\n\n        assert.range(session.getFoldWidgetRange(3), 3, 12, 5, 0);\n    }\n};\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/lua.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.foldingStartMarker = /\\b(function|then|do|repeat)\\b|{\\s*$|(\\[=*\\[)/;\n    this.foldingStopMarker = /\\bend\\b|^\\s*}|\\]=*\\]/;\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n\n        if (isStart && !isEnd) {\n            var match = line.match(this.foldingStartMarker);\n            if (match[1] == \"then\" && /\\belseif\\b/.test(line))\n                return;\n            if (match[1]) {\n                if (session.getTokenAt(row, match.index + 1).type === \"keyword\")\n                    return \"start\";\n            } else if (match[2]) {\n                var type = session.bgTokenizer.getState(row) || \"\";\n                if (type[0] == \"bracketedComment\" || type[0] == \"bracketedString\")\n                    return \"start\";\n            } else {\n                return \"start\";\n            }\n        }\n        if (foldStyle != \"markbeginend\" || !isEnd || isStart && isEnd)\n            return \"\";\n\n        var match = line.match(this.foldingStopMarker);\n        if (match[0] === \"end\") {\n            if (session.getTokenAt(row, match.index + 1).type === \"keyword\")\n                return \"end\";\n        } else if (match[0][0] === \"]\") {\n            var type = session.bgTokenizer.getState(row - 1) || \"\";\n            if (type[0] == \"bracketedComment\" || type[0] == \"bracketedString\")\n                return \"end\";\n        } else\n            return \"end\";\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.doc.getLine(row);\n        var match = this.foldingStartMarker.exec(line);\n        if (match) {\n            if (match[1])\n                return this.luaBlock(session, row, match.index + 1);\n\n            if (match[2])\n                return session.getCommentFoldRange(row, match.index + 1);\n\n            return this.openingBracketBlock(session, \"{\", row, match.index);\n        }\n\n        var match = this.foldingStopMarker.exec(line);\n        if (match) {\n            if (match[0] === \"end\") {\n                if (session.getTokenAt(row, match.index + 1).type === \"keyword\")\n                    return this.luaBlock(session, row, match.index + 1);\n            }\n\n            if (match[0][0] === \"]\")\n                return session.getCommentFoldRange(row, match.index + 1);\n\n            return this.closingBracketBlock(session, \"}\", row, match.index + match[0].length);\n        }\n    };\n\n    this.luaBlock = function(session, row, column, tokenRange) {\n        var stream = new TokenIterator(session, row, column);\n        var indentKeywords = {\n            \"function\": 1,\n            \"do\": 1,\n            \"then\": 1,\n            \"elseif\": -1,\n            \"end\": -1,\n            \"repeat\": 1,\n            \"until\": -1\n        };\n\n        var token = stream.getCurrentToken();\n        if (!token || token.type != \"keyword\")\n            return;\n\n        var val = token.value;\n        var stack = [val];\n        var dir = indentKeywords[val];\n\n        if (!dir)\n            return;\n\n        var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length;\n        var startRow = row;\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while(token = stream.step()) {\n            if (token.type !== \"keyword\")\n                continue;\n            var level = dir * indentKeywords[token.value];\n\n            if (level > 0) {\n                stack.unshift(token.value);\n            } else if (level <= 0) {\n                stack.shift();\n                if (!stack.length && token.value != \"elseif\")\n                    break;\n                if (level === 0)\n                    stack.unshift(token.value);\n            }\n        }\n\n        if (!token)\n            return null;\n\n        if (tokenRange)\n            return stream.getCurrentTokenRange();\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1)\n            return new Range(row, session.getLine(row).length, startRow, startColumn);\n        else\n            return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/lua_test.js",
    "content": "\"use strict\";\n\nvar LuaMode = require(\"../lua\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    \"test: lua multi-line comment and string folding\": function () {\n        var session = new EditSession([\n            '--[[This is a multi-line comment in Lua', 'It can span multiple lines until it encounters', ']]--', '',\n            'local title = [[This is a multi-line string in Lua',\n            'It can also span multiple lines until it encounters ]]'\n        ]);\n\n        var luaMode = new LuaMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(luaMode);\n        session.bgTokenizer.$worker();\n\n        assert.equal(session.getFoldWidget(0), \"start\"); // Comment starts\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        assert.equal(session.getFoldWidget(3), \"\");\n        assert.equal(session.getFoldWidget(4), \"start\"); // String starts\n        assert.equal(session.getFoldWidget(5), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 4, 2, 0);\n        assert.range(session.getFoldWidgetRange(2), 0, 4, 2, 0);\n        assert.range(session.getFoldWidgetRange(4), 4, 16, 5, 52);\n        assert.range(session.getFoldWidgetRange(5), 4, 16, 5, 52);\n    }\n\n};\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/markdown.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.foldingStartMarker = /^(?:[=-]+\\s*$|#{1,6} |`{3})/;\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        if (!this.foldingStartMarker.test(line))\n            return \"\";\n\n        if (line[0] == \"`\") {\n            if (session.bgTokenizer.getState(row) == \"start\")\n                return \"end\";\n            return \"start\";\n        }\n\n        return \"start\";\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n        if (!line.match(this.foldingStartMarker))\n            return;\n\n        if (line[0] == \"`\") {\n            if (session.bgTokenizer.getState(row) !== \"start\") {\n                while (++row < maxRow) {\n                    line = session.getLine(row);\n                    if (line[0] == \"`\" & line.substring(0, 3) == \"```\")\n                        break;\n                }\n                return new Range(startRow, startColumn, row, 0);\n            } else {\n                while (row -- > 0) {\n                    line = session.getLine(row);\n                    if (line[0] == \"`\" & line.substring(0, 3) == \"```\")\n                        break;\n                }\n                return new Range(row, line.length, startRow, 0);\n            }\n        }\n\n        var token;\n        function isHeading(row) {\n            token = session.getTokens(row)[0];\n            return token && token.type.lastIndexOf(heading, 0) === 0;\n        }\n\n        var heading = \"markup.heading\";\n        function getLevel() {\n            var ch = token.value[0];\n            if (ch == \"=\") return 6;\n            if (ch == \"-\") return 5;\n            return 7 - token.value.search(/[^#]|$/);\n        }\n\n        if (isHeading(row)) {\n            var startHeadingLevel = getLevel();\n            while (++row < maxRow) {\n                if (!isHeading(row))\n                    continue;\n                var level = getLevel();\n                if (level >= startHeadingLevel)\n                    break;\n            }\n\n            endRow = row - (!token || [\"=\", \"-\"].indexOf(token.value[0]) == -1 ? 1 : 2);\n\n            if (endRow > startRow) {\n                while (endRow > startRow && /^\\s*$/.test(session.getLine(endRow)))\n                    endRow--;\n            }\n\n            if (endRow > startRow) {\n                var endColumn = session.getLine(endRow).length;\n                return new Range(startRow, startColumn, endRow, endColumn);\n            }\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/mixed.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(defaultMode, subModes) {\n    this.defaultMode = defaultMode;\n    this.subModes = subModes;\n};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n\n    this.$getMode = function(state) {\n        if (typeof state != \"string\") \n            state = state[0];\n        for (var key in this.subModes) {\n            if (state.indexOf(key) === 0)\n                return this.subModes[key];\n        }\n        return null;\n    };\n    \n    this.$tryMode = function(state, session, foldStyle, row) {\n        var mode = this.$getMode(state);\n        return (mode ? mode.getFoldWidget(session, foldStyle, row) : \"\");\n    };\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        return (\n            this.$tryMode(session.getState(row-1), session, foldStyle, row) ||\n            this.$tryMode(session.getState(row), session, foldStyle, row) ||\n            this.defaultMode.getFoldWidget(session, foldStyle, row)\n        );\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var mode = this.$getMode(session.getState(row-1));\n        \n        if (!mode || !mode.getFoldWidget(session, foldStyle, row))\n            mode = this.$getMode(session.getState(row));\n        \n        if (!mode || !mode.getFoldWidget(session, foldStyle, row))\n            mode = this.defaultMode;\n        \n        return mode.getFoldWidgetRange(session, foldStyle, row);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/nunjucks.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nconst {FoldMode: MixedFoldMode} = require(\"./mixed\");\nvar HtmlFoldMode = require(\"./html\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function (voidElements, optionalTags) {\n    HtmlFoldMode.call(this, voidElements, optionalTags);\n};\n\noop.inherits(FoldMode, HtmlFoldMode);\n\n(function () {//TODO: set|endset\n    this.getFoldWidgetRangeBase = this.getFoldWidgetRange;\n    this.getFoldWidgetBase = this.getFoldWidget;\n\n    this.indentKeywords = {\n        \"block\": 1,\n        \"if\": 1,\n        \"for\": 1,\n        \"asyncEach\": 1,\n        \"asyncAll\": 1,\n        \"macro\": 1,\n        \"filter\": 1,\n        \"call\": 1,\n        \"else\": 0,\n        \"elif\": 0,\n        \"set\": 1,\n        \"endblock\": -1,\n        \"endif\": -1,\n        \"endfor\": -1,\n        \"endeach\": -1,\n        \"endall\": -1,\n        \"endmacro\": -1,\n        \"endfilter\": -1,\n        \"endcall\": -1,\n        \"endset\": -1\n    };\n\n    this.foldingStartMarkerNunjucks = /(?:\\{%-?\\s*)(?:(block|if|else|elif|for|asyncEach|asyncAll|macro|filter|call)\\b.*)|(?:\\bset(?:[^=]*))(?=%})/i;\n    this.foldingStopMarkerNunjucks = /(?:\\{%-?\\s*)(endblock|endif|endfor|endeach|endall|endmacro|endfilter|endcall|endset)\\b.*(?=%})/i;\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.doc.getLine(row);\n        let offset = calculateOffset(this.foldingStartMarkerNunjucks, line);\n        if (offset) {\n            return this.nunjucksBlock(session, row, offset);\n        }\n\n        offset = calculateOffset(this.foldingStopMarkerNunjucks, line);\n        if (offset) {\n            return this.nunjucksBlock(session, row, offset);\n        }\n        return this.getFoldWidgetRangeBase(session, foldStyle, row);\n    };\n\n    /**\n     *\n     * @param {RegExp} regExp\n     * @param line\n     * @return {*}\n     */\n    function calculateOffset(regExp, line) {\n        var match = regExp.exec(line);\n        if (match) {\n            var keyword = match[0].includes(\"set\") ? \"set\" : match[1].toLowerCase();\n            if (keyword) {\n                var offsetInMatch = match[0].toLowerCase().indexOf(keyword);\n                return match.index + offsetInMatch + 1;\n            }\n        }\n    }\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarkerNunjucks.test(line);\n        var isEnd = this.foldingStopMarkerNunjucks.test(line);\n        if (isStart && !isEnd) {\n            var offset = calculateOffset(this.foldingStartMarkerNunjucks, line);\n            if (offset) {\n                var type = session.getTokenAt(row, offset).type;\n                if (type === \"keyword.control\") {\n                    return \"start\";\n                }\n            }\n        }\n        if (isEnd && !isStart && foldStyle === \"markbeginend\") {\n            var offset = calculateOffset(this.foldingStopMarkerNunjucks, line);\n            if (offset) {\n                var type = session.getTokenAt(row, offset).type;\n                if (type === \"keyword.control\") {\n                    return \"end\";\n                }\n            }\n        }\n        return this.getFoldWidgetBase(session, foldStyle, row);\n    };\n\n    /**\n     *\n     * @param {TokenIterator} stream\n     */\n    function getTokenPosition(stream, findStart) {\n        let token;\n        const currentIndex = stream.$tokenIndex;\n        const type = findStart ? \"punctuation.begin\" : \"punctuation.end\";\n        stream.step = findStart ? stream.stepBackward : stream.stepForward;\n        while (token = stream.step()) {\n            if (token.type !== type) continue;\n            break;\n        }\n        if (!token) return;\n        let pos = stream.getCurrentTokenPosition();\n        if (!findStart) {\n            pos.column = pos.column + token.value.length;\n        }\n        stream.$tokenIndex = currentIndex;\n        return pos;\n    }\n\n    this.nunjucksBlock = function (session, row, column) {\n        var stream = new TokenIterator(session, row, column);\n\n        var token = stream.getCurrentToken();\n        if (!token || token.type != \"keyword.control\") return;\n\n        var val = token.value;\n        var stack = [val];\n        var dir = this.indentKeywords[val];\n\n        if (val === \"else\" || val === \"elif\") {\n            dir = 1;\n        }\n\n        if (!dir) return;\n\n        var start = getTokenPosition(stream, dir === -1);\n\n        if (!token) return;\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while (token = stream.step()) {\n            if (token.type !== \"keyword.control\") continue;\n            var level = dir * this.indentKeywords[token.value];\n\n            if (token.value === \"set\") {\n                var tokenPos = stream.getCurrentTokenPosition();\n                var line = session.getLine(tokenPos.row).substring(tokenPos.column);\n                if (!/^[^=]*%}/.test(line)) {\n                    continue;\n                }\n            }\n            if (level > 0) {\n                stack.unshift(token.value);\n            }\n            else if (level <= 0) {\n                stack.shift();\n                if (!stack.length) break;\n                if (level === 0) stack.unshift(token.value);\n            }\n        }\n\n        if (!token) return null;\n\n        var end = getTokenPosition(stream, dir === 1);\n        return dir === 1 ? Range.fromPoints(start, end) : Range.fromPoints(end, start);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/nunjucks_test.js",
    "content": "\"use strict\";\n\nvar NunjucksMode = require(\"../nunjucks\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new NunjucksMode();\n    },\n\n    \"test: nunjucks folding\": function() {\n        var session = new EditSession([\n            '{% block header %}',\n            '  <section class=\"left\">',\n            '    {% block left %}{% endblock %}',\n            '    {% set standardModal %}',\n            '      {% include \"standardModalData.html\" %}',\n            '      {% set cls = cycler(\"odd\", \"even\") %}',\n            '    {% endset %}',\n            '    {% if hungry %}',\n            '      I am hungry',\n            '    {% elif tired %}',\n            '      I am tired',\n            '    {% else %}',\n            '      I am good!',\n            '    {% endif %}',\n            '  </section>',\n            '{% endblock %}'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"\");  // set with =\n        assert.equal(session.getFoldWidget(6), \"end\");\n        assert.equal(session.getFoldWidget(7), \"start\");\n        assert.equal(session.getFoldWidget(8), \"\");\n        assert.equal(session.getFoldWidget(9), \"start\");\n        assert.equal(session.getFoldWidget(10), \"\");\n        assert.equal(session.getFoldWidget(11), \"start\");\n        assert.equal(session.getFoldWidget(12), \"\");\n        assert.equal(session.getFoldWidget(13), \"end\");\n        assert.equal(session.getFoldWidget(14), \"end\");\n        assert.equal(session.getFoldWidget(15), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 18, 15, 0);\n        assert.range(session.getFoldWidgetRange(1), 1, 24, 14, 2);\n        assert.range(session.getFoldWidgetRange(3), 3, 27, 6, 4);\n        assert.range(session.getFoldWidgetRange(6), 3, 27, 6, 4);\n        assert.range(session.getFoldWidgetRange(7), 7, 19, 9, 4);\n        assert.range(session.getFoldWidgetRange(11), 11, 14, 13, 4);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);"
  },
  {
    "path": "src/mode/folding/php.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar CstyleFoldMode = require(\"./cstyle\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function () {\n};\n\noop.inherits(FoldMode, CstyleFoldMode);\n\n(function () {\n    this.getFoldWidgetRangeBase = this.getFoldWidgetRange;\n    this.getFoldWidgetBase = this.getFoldWidget;\n    \n    this.indentKeywords = {\n        \"if\": 1,\n        \"while\": 1,\n        \"for\": 1,\n        \"foreach\": 1,\n        \"switch\": 1,\n        \"else\": 0,\n        \"elseif\": 0,\n        \"endif\": -1,\n        \"endwhile\": -1,\n        \"endfor\": -1,\n        \"endforeach\": -1,\n        \"endswitch\": -1\n    };\n\n    this.foldingStartMarkerPhp = /(?:\\s|^)(if|else|elseif|while|for|foreach|switch).*\\:/i;\n    this.foldingStopMarkerPhp = /(?:\\s|^)(endif|endwhile|endfor|endforeach|endswitch)\\;/i;\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.doc.getLine(row);\n        var match = this.foldingStartMarkerPhp.exec(line);\n        if (match) {\n            return this.phpBlock(session, row, match.index + 2);\n        }\n\n        var match = this.foldingStopMarkerPhp.exec(line);\n        if (match) {\n            return this.phpBlock(session, row, match.index + 2);\n        }\n        return this.getFoldWidgetRangeBase(session, foldStyle, row);\n    };\n\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarkerPhp.test(line);\n        var isEnd = this.foldingStopMarkerPhp.test(line);\n        if (isStart && !isEnd) {\n            var match = this.foldingStartMarkerPhp.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type == \"keyword\") {\n                    return \"start\";\n                }\n            }\n        }\n        if (isEnd && foldStyle === \"markbeginend\") {\n            var match = this.foldingStopMarkerPhp.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type == \"keyword\") {\n                    return \"end\";\n                }\n            }\n        }\n        return this.getFoldWidgetBase(session, foldStyle, row);\n    };\n\n    this.phpBlock = function (session, row, column, tokenRange) {\n        var stream = new TokenIterator(session, row, column);\n\n        var token = stream.getCurrentToken();\n        if (!token || token.type != \"keyword\") return;\n\n        var val = token.value;\n        var stack = [val];\n        var dir = this.indentKeywords[val];\n\n        if (val === \"else\" || val === \"elseif\") {\n            dir = 1;\n        }\n\n        if (!dir) return;\n\n        var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length;\n        var startRow = row;\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while (token = stream.step()) {\n            if (token.type !== \"keyword\") continue;\n            var level = dir * this.indentKeywords[token.value];\n\n            if (level > 0) {\n                stack.unshift(token.value);\n            }\n            else if (level <= 0) {\n                stack.shift();\n                if (!stack.length) break;\n                if (level === 0) stack.unshift(token.value);\n            }\n        }\n\n        if (!token) return null;\n\n        if (tokenRange) return stream.getCurrentTokenRange();\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1) return new Range(\n            row, session.getLine(row).length, startRow, startColumn); else return new Range(\n            startRow, startColumn, row, stream.getCurrentTokenColumn());\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/php_test.js",
    "content": "\"use strict\";\n\nvar PHPMode = require(\"../php\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    setUp: function () {\n        this.mode = new PHPMode();\n    },\n\n    \"test: php folding with alternative syntax\": function () {\n        var session = new EditSession([\n            '<?php', \n            'function checkNumber($number)', \n            '{', \n            '   switch ($number) {', \n            '       case 0:',\n            '       echo \"Number is zero again\";', \n            '           if ($number == 0):',\n            '               echo \"Number is zero\";', \n            '           elseif ($number > 0):',\n            '               echo \"Number is positive\";', \n            '           else:',\n            '               echo \"Number is negative\";', \n            'endif;', \n            '       break;', \n            '       default:',\n            '           echo \"Number is not zero\";', \n            '       }', 'foreach (array(1, 2, 3) as $num):',\n            '       echo \"Num: $num\";', \n            '   endforeach;', \n            '}', \n            '?>', \n            '', \n            '<script>', \n            '    function test() {', \n            '        ', \n            '    }', \n            '</script>', \n            '<style>', \n            '    div {', \n            '        color: red;', \n            '    }', \n            '</style>'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n        session.bgTokenizer.$worker();\n\n        assert.equal(session.getFoldWidget(0), \"\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"start\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"\");\n        assert.equal(session.getFoldWidget(6), \"start\");\n        assert.equal(session.getFoldWidget(7), \"\");\n        assert.equal(session.getFoldWidget(8), \"start\");\n        assert.equal(session.getFoldWidget(10), \"start\");\n        assert.equal(session.getFoldWidget(12), \"end\");\n        assert.equal(session.getFoldWidget(16), \"end\");\n        assert.equal(session.getFoldWidget(17), \"start\");\n        assert.equal(session.getFoldWidget(19), \"end\");\n        assert.equal(session.getFoldWidget(20), \"end\");\n        assert.equal(session.getFoldWidget(21), \"\");\n        assert.equal(session.getFoldWidget(22), \"\");\n        assert.equal(session.getFoldWidget(23), \"start\");\n        assert.equal(session.getFoldWidget(24), \"start\");\n        assert.equal(session.getFoldWidget(25), \"\");\n        assert.equal(session.getFoldWidget(26), \"end\");\n        assert.equal(session.getFoldWidget(27), \"end\");\n        assert.equal(session.getFoldWidget(28), \"start\");\n        assert.equal(session.getFoldWidget(29), \"start\");\n        assert.equal(session.getFoldWidget(30), \"\");\n        assert.equal(session.getFoldWidget(31), \"end\");\n        assert.equal(session.getFoldWidget(32), \"end\");\n\n        assert.range(session.getFoldWidgetRange(2), 2, 1, 20, 0); // Range for the function's foldable section\n        assert.range(session.getFoldWidgetRange(3), 3, 21, 16, 7); // Range for the 'switch' statement\n        assert.range(session.getFoldWidgetRange(6), 6, 29, 8, 11); // Range for the 'if' block\n        assert.range(session.getFoldWidgetRange(8), 8, 32, 10, 11); // Range for the 'elseif' block\n        assert.range(session.getFoldWidgetRange(10), 10, 16, 12, 0); // Range for the 'else' block\n        assert.range(session.getFoldWidgetRange(12), 10, 16, 12, 0); // Range for the 'endif' line\n        assert.range(session.getFoldWidgetRange(17), 17, 33, 19, 3);\n        assert.range(session.getFoldWidgetRange(19), 17, 33, 19, 3);\n        assert.range(session.getFoldWidgetRange(23), 23, 8, 27, 0); // Range for script tag\n        assert.range(session.getFoldWidgetRange(24), 24, 21, 26, 4); // Range for cstyle { } block\n        assert.range(session.getFoldWidgetRange(26), 24, 21, 26, 4); // Range for closing cstyle { } block\n        assert.range(session.getFoldWidgetRange(27), 23, 8, 27, 0); // Range for closing script tag\n        assert.range(session.getFoldWidgetRange(28), 28, 7, 32, 0); // Range for openning style tag\n        assert.range(session.getFoldWidgetRange(29), 29, 9, 31, 4); // Range for cstyle { } block\n        assert.range(session.getFoldWidgetRange(31), 29, 9, 31, 4); // Range for closing cstyle { } block\n        assert.range(session.getFoldWidgetRange(32), 28, 7, 32, 0); // Range for closing style tag\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/pythonic.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(markers) {\n    this.foldingStartMarker = new RegExp(\"([\\\\[{])(?:\\\\s*)$|(\" + markers + \")(?:\\\\s*)(?:#.*)?$\");\n};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var match = line.match(this.foldingStartMarker);\n        if (match) {\n            if (match[1])\n                return this.openingBracketBlock(session, match[1], row, match.index);\n            if (match[2])\n                return this.indentationBlock(session, row, match.index + match[2].length);\n            return this.indentationBlock(session, row);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/pythonic_test.js",
    "content": "\"use strict\";\n\nvar PythonMode = require(\"../python\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n    \"test: bracket folding\": function() {\n        var session = new EditSession([\n            '[ ',\n            'stuff',\n            ']',\n            '[ ',\n            '{ ',\n            '[  #-'\n        ]);\n\n        var mode = new PythonMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"start\");\n        assert.equal(session.getFoldWidget(5), \"\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 1, 2, 0);\n        assert.equal(session.getFoldWidgetRange(3), null);\n        assert.equal(session.getFoldWidgetRange(5), null);\n    },\n\n    \"test: indentation folding\": function() {\n        var session = new EditSession([\n            'def a: #',\n            '',\n            ' b:',\n            '  c',\n            ' ',\n            '  c',\n            '',\n            ' ',\n            ''\n        ]);\n\n        var mode = new PythonMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"start\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 6, 5, 3);\n        assert.range(session.getFoldWidgetRange(2), 2, 3, 5, 3);\n    },\n    \n    \"test: indentation folding with strings\": function() {\n        var session = new EditSession([\n            'def a: #',\n            '  print \"\"\"',\n            'xx',\n            '\"\"\"',\n            '',\n            '  c',\n            '',\n            ''\n        ]);\n\n        var mode = new PythonMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        session.bgTokenizer.$worker();\n        assert.range(session.getFoldWidgetRange(0), 0, 6, 5, 3);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/ruby.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function () {\n};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function () {\n    this.indentKeywords = {\n        \"class\": 1,\n        \"def\": 1,\n        \"module\": 1,\n        \"do\": 1,\n        \"unless\": 1,\n        \"if\": 1,\n        \"while\": 1,\n        \"for\": 1,\n        \"until\": 1,\n        \"begin\": 1,\n        \"else\": 0,\n        \"elsif\": 0,\n        \"rescue\": 0,\n        \"ensure\": 0,\n        \"when\": 0,\n        \"end\": -1,\n        \"case\": 1,\n        \"=begin\": 1,\n        \"=end\": -1\n    };\n\n    this.foldingStartMarker = /(?:\\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\\b|({\\s*$)|(=begin)/;\n    this.foldingStopMarker = /(=end(?=$|\\s.*$))|(^\\s*})|\\b(end)\\b/;\n\n    this.getFoldWidget = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n\n        if (isStart && !isEnd) {\n            var match = line.match(this.foldingStartMarker);\n            if (match[1]) {\n                if (match[1] == \"if\" || match[1] == \"else\" || match[1] == \"while\" || match[1] == \"until\" || match[1] == \"unless\") {\n                    if (match[1] == \"else\" && /^\\s*else\\s*$/.test(line) === false) {\n                        return;\n                    }\n                    if (/^\\s*(?:if|else|while|until|unless)\\s*/.test(line) === false) {\n                        return;\n                    }\n                }\n\n                if (match[1] == \"when\") {\n                    if (/\\sthen\\s/.test(line) === true) {\n                        return;\n                    }\n                }\n                if (session.getTokenAt(row, match.index + 2).type === \"keyword\")\n                    return \"start\";\n            } else if (match[3]) {\n                if (session.getTokenAt(row, match.index + 1).type === \"comment.multiline\")\n                    return \"start\";\n            } else {\n                return \"start\";\n            }\n        }\n        if (foldStyle != \"markbeginend\" || !isEnd || isStart && isEnd)\n            return \"\";\n\n        var match = line.match(this.foldingStopMarker);\n        if (match[3] === \"end\") {\n            if (session.getTokenAt(row, match.index + 1).type === \"keyword\")\n                return \"end\";\n        } else if (match[1]) {\n            if (session.getTokenAt(row, match.index + 1).type === \"comment.multiline\")\n                return \"end\";\n        } else\n            return \"end\";\n    };\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.doc.getLine(row);\n        var match = this.foldingStartMarker.exec(line);\n        if (match) {\n            if (match[1] || match[3])\n                return this.rubyBlock(session, row, match.index + 2);\n\n            return this.openingBracketBlock(session, \"{\", row, match.index);\n        }\n\n        var match = this.foldingStopMarker.exec(line);\n        if (match) {\n            if (match[3] === \"end\") {\n                if (session.getTokenAt(row, match.index + 1).type === \"keyword\")\n                    return this.rubyBlock(session, row, match.index + 1);\n            }\n\n            if (match[1] === \"=end\") {\n                if (session.getTokenAt(row, match.index + 1).type === \"comment.multiline\")\n                    return this.rubyBlock(session, row, match.index + 1);\n            }\n\n            return this.closingBracketBlock(session, \"}\", row, match.index + match[0].length);\n        }\n    };\n\n    this.rubyBlock = function (session, row, column, tokenRange) {\n        var stream = new TokenIterator(session, row, column);\n\n        var token = stream.getCurrentToken();\n        if (!token || (token.type != \"keyword\" && token.type != \"comment.multiline\"))\n            return;\n\n        var val = token.value;\n        var line = session.getLine(row);\n        switch (token.value) {\n            case \"if\":\n            case \"unless\":\n            case \"while\":\n            case \"until\":\n                var checkToken = new RegExp(\"^\\\\s*\" + token.value);\n                if (!checkToken.test(line)) {\n                    return;\n                }\n                var dir = this.indentKeywords[val];\n                break;\n            case \"when\":\n                if (/\\sthen\\s/.test(line)) {\n                    return;\n                }\n            case \"elsif\":\n            case \"rescue\":\n            case \"ensure\":\n                var dir = 1;\n                break;\n            case \"else\":\n                var checkToken = new RegExp(\"^\\\\s*\" + token.value + \"\\\\s*$\");\n                if (!checkToken.test(line)) {\n                    return;\n                }\n                var dir = 1;\n                break;\n            default:\n                var dir = this.indentKeywords[val];\n                break;\n        }\n\n        var stack = [val];\n        if (!dir)\n            return;\n\n        var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length;\n        var startRow = row;\n        var ranges = [];\n        ranges.push(stream.getCurrentTokenRange());\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        if (token.type == \"comment.multiline\") {\n            while (token = stream.step()) {\n                if (token.type !== \"comment.multiline\")\n                    continue;\n                if (dir == 1) {\n                    startColumn = 6;\n                    if (token.value == \"=end\") {\n                        break;\n                    }\n                } else {\n                    if (token.value == \"=begin\") {\n                        break;\n                    }\n                }\n            }\n        } else {\n            while (token = stream.step()) {\n                var ignore = false;\n                if (token.type !== \"keyword\")\n                    continue;\n                var level = dir * this.indentKeywords[token.value];\n                line = session.getLine(stream.getCurrentTokenRow());\n                switch (token.value) {\n                    case \"do\":\n                        for (var i = stream.$tokenIndex - 1; i >= 0; i--) {\n                            var prevToken = stream.$rowTokens[i];\n                            if (prevToken && (prevToken.value == \"while\" || prevToken.value == \"until\" || prevToken.value == \"for\")) {\n                                level = 0;\n                                break;\n                            }\n                        }\n                        break;\n                    case \"else\":\n                        var checkToken = new RegExp(\"^\\\\s*\" + token.value + \"\\\\s*$\");\n                        if (!checkToken.test(line) || val == \"case\") {\n                            level = 0;\n                            ignore = true;\n                        }\n                        break;\n                    case \"if\":\n                    case \"unless\":\n                    case \"while\":\n                    case \"until\":\n                        var checkToken = new RegExp(\"^\\\\s*\" + token.value);\n                        if (!checkToken.test(line)) {\n                            level = 0;\n                            ignore = true;\n                        }\n                        break;\n                    case \"when\":\n                        if (/\\sthen\\s/.test(line) || val == \"case\") {\n                            level = 0;\n                            ignore = true;\n                        }\n                        break;\n                }\n\n                if (level > 0) {\n                    stack.unshift(token.value);\n                } else if (level <= 0 && ignore === false) {\n                    stack.shift();\n                    if (!stack.length) {\n                        if ((val == \"while\" || val == \"until\" || val == \"for\") && token.value != \"do\") {\n                            break;\n                        }\n                        if (token.value == \"do\" && dir == -1 && level != 0)\n                            break;\n                        if (token.value != \"do\")\n                            break;\n                    }\n\n                    if (level === 0) {\n                        stack.unshift(token.value);\n                    }\n                }\n            }\n        }\n\n        if (!token)\n            return null;\n\n        if (tokenRange) {\n            ranges.push(stream.getCurrentTokenRange());\n            return ranges;\n        }\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1) {\n            if (token.type === \"comment.multiline\") {\n                var endColumn = 6;\n            } else {\n                var endColumn = session.getLine(row).length;\n            }\n            return new Range(row, endColumn, startRow - 1, startColumn);\n        } else\n            return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/ruby_test.js",
    "content": "\"use strict\";\n\nvar RubyMode = require(\"../ruby\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new RubyMode();\n    },\n\n    \"test: opening/ending tags matching/folding\": function() {\n        var session = new EditSession([\n            'def Name(n)',\n            '   if i == 0',\n            '      ...',\n            '   else',\n            '      ...',\n            '   end',\n            'end'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        var ranges = this.mode.getMatching(session, 0, 0);\n        assert.range(ranges[0], 0, 0, 0, 3);\n        assert.range(ranges[1], 6, 0, 6, 3);\n\n        ranges = this.mode.getMatching(session, 6, 1);\n        assert.range(ranges[1], 0, 0, 0, 3);\n        assert.range(ranges[0], 6, 0, 6, 3);\n\n        ranges = this.mode.getMatching(session, 1, 4);\n        assert.range(ranges[0], 1, 3, 1, 5);\n        assert.range(ranges[1], 3, 3, 3, 7);\n\n        ranges = this.mode.getMatching(session, 5, 4);\n        assert.range(ranges[1], 3, 3, 3, 7);\n        assert.range(ranges[0], 5, 3, 5, 6);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(5), \"end\");\n        assert.equal(session.getFoldWidget(6), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 11, 5, 6);\n        assert.equal(session.getFoldWidgetRange(2), null);\n        assert.equal(session.getFoldWidgetRange(4), null);\n        assert.range(session.getFoldWidgetRange(5), 3, 7, 4, 9);\n    },\n\n    \"test: if/unless/while/until used as modifier shouldn't have matching tag and start/end fold\": function() {\n        var session = new EditSession([\n            'if i == 0',\n            '   a += 1 if a.zero?',\n            'else',\n            '   a += 1 unless a.zero?',\n            'end'\n        ]);\n\n        session.setMode(this.mode);\n    },\n\n    \"test: brackets folding\": function() {\n        var session = new EditSession([\n            'def to_json(*a)',\n            '{',\n            '\"json_class\"   => self.class.name, # = \"Range\"',\n            '\"data\"         => [ first, last, exclude_end? ]',\n            '}.to_json(*a)',\n            'end'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n        assert.equal(session.getFoldWidget(5), \"end\");\n\n        assert.range(session.getFoldWidgetRange(1), 1, 1, 4, 0);\n        assert.range(session.getFoldWidgetRange(4), 1, 1, 4, 0);\n    },\n\n    \"test: multiline comments matching and folding\": function() {\n        var session = new EditSession([\n            '=begin',\n            'text line 1',\n            'text line 2',\n            'text line 3',\n            '=end'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        var ranges = this.mode.getMatching(session, 0, 2);\n        assert.range(ranges[0], 0, 0, 0, 6);\n        assert.range(ranges[1], 4, 0, 4, 4);\n\n        ranges = this.mode.getMatching(session, 4, 2);\n        assert.range(ranges[1], 0, 0, 0, 6);\n        assert.range(ranges[0], 4, 0, 4, 4);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n\n        assert.range(session.getFoldWidgetRange(0), 0,6,3,11);\n        assert.range(session.getFoldWidgetRange(4), 0,6,3,11);\n    },\n\n    \"test: `case` with multiline `when` expressions matchings and foldings\": function() {\n        var session = new EditSession([\n            'case',\n            'when a == 1',\n            ' puts \"a is one\"',\n            'when a == 2',\n            ' puts \"a is two\"',\n            'else',\n            ' puts \"a is not one or two\"',\n            'end'\n        ]);\n\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(this.mode);\n\n        var ranges = this.mode.getMatching(session, 0, 2);\n\n        //`case` should always be closed with `end`\n        assert.range(ranges[0], 0, 0, 0, 4);\n        assert.range(ranges[1], 7, 0, 7, 3);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.range(session.getFoldWidgetRange(0), 0,4,6,27);\n\n        //`end` should close last block\n        ranges = this.mode.getMatching(session, 7, 2);\n        assert.range(ranges[0], 7, 0, 7, 3);\n        assert.range(ranges[1], 5, 0, 5, 4);\n\n        assert.equal(session.getFoldWidget(7), \"end\");\n        assert.range(session.getFoldWidgetRange(7), 5,4,6,27);\n\n        //`else` should be closed with `end`\n        ranges = this.mode.getMatching(session, 5, 2);\n        assert.range(ranges[1], 7, 0, 7, 3);\n        assert.range(ranges[0], 5, 0, 5, 4);\n\n        assert.equal(session.getFoldWidget(5), \"start\");\n        assert.range(session.getFoldWidgetRange(5), 5,4,6,27);\n\n        //first `when` should close by next `when`\n        ranges = this.mode.getMatching(session, 1, 2);\n        assert.range(ranges[0], 1, 0, 1, 4);\n        assert.range(ranges[1], 3, 0, 3, 4);\n\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.range(session.getFoldWidgetRange(1), 1,11,2,16);\n    },\n\n    \"test: `case` with single line `when` expressions matchings and foldings\": function() {\n        var session = new EditSession([\n            'kind = case year',\n            '       when 1850..1889 then \"Blues\"',\n            '       when 1890..1909 then \"Ragtime\"',\n            '       when 1910..1929 then \"New Orleans Jazz\"',\n            '       when 1930..1939 then \"Swing\"',\n            '       when 1940..1950 then \"Bebop\"',\n            '       else \"Jazz\"',\n            '       end'\n        ]);\n\n        session.setMode(this.mode);\n\n        var ranges = this.mode.getMatching(session, 0, 9);\n\n        //`case` should always be closed with `end`\n        assert.range(ranges[0], 0, 7, 0, 11);\n        assert.range(ranges[1], 7, 7, 7, 10);\n\n        //`end` should close `case`\n        ranges = this.mode.getMatching(session, 7, 9);\n        assert.range(ranges[1], 0, 7, 0, 11);\n        assert.range(ranges[0], 7, 7, 7, 10);\n\n        //`when` shouldn't have any matchings in single line form\n        ranges = this.mode.getMatching(session, 1, 8);\n        assert.equal(ranges, undefined);\n\n        assert.equal(session.getFoldWidget(1), undefined);\n        assert.equal(session.getFoldWidgetRange(1), null);\n\n        //`else` shouldn't have any matchings in single line form\n        ranges = this.mode.getMatching(session, 6, 8);\n        assert.equal(ranges, undefined);\n\n        assert.equal(session.getFoldWidget(6), undefined);\n        assert.equal(session.getFoldWidgetRange(6), null);\n    },\n\n    \"test: loops `while` and `until` including `do` keyword and `do` loops should properly highlight\": function() {\n        var session = new EditSession([\n            'while a < 10 do',\n            '   p a',\n            '   a += 1',\n            '   0.upto 5 do |value|',\n            '       selected << value if value==2...value==2',\n            '   end',\n            'end'\n        ]);\n\n        session.setMode(this.mode);\n\n        var ranges = this.mode.getMatching(session, 0, 3);\n        assert.range(ranges[0], 0, 0, 0, 5);\n        assert.range(ranges[1], 6, 0, 6, 3);\n\n        ranges = this.mode.getMatching(session, 6, 1);\n        assert.range(ranges[1], 0, 0, 0, 5);\n        assert.range(ranges[0], 6, 0, 6, 3);\n\n        //for `do` keyword we also returns proper `end` from `while` loop\n        ranges = this.mode.getMatching(session, 0, 14);\n        assert.range(ranges[0], 0, 13, 0, 15);\n        assert.range(ranges[1], 6, 0, 6, 3);\n\n        ranges = this.mode.getMatching(session, 3, 13);\n        assert.range(ranges[0], 3, 12, 3, 14);\n        assert.range(ranges[1], 5, 3, 5, 6);\n\n        ranges = this.mode.getMatching(session, 5, 4);\n        assert.range(ranges[1], 3, 12, 3, 14);\n        assert.range(ranges[0], 5, 3, 5, 6);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/sql.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./cstyle\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    /** \n     * Inheriting cstyle folding because it handles the region comment folding \n     * and special block comment folding appropriately.\n     * \n     * Cstyle's getCommentRegionBlock() contains the sql comment characters '--' for end region block.\n     */\n    \n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/sqlserver.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./cstyle\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    /** \n     * Inheriting cstyle folding because it handles the region comment folding \n     * and special block comment folding appropriately.\n     * \n     * Cstyle's getCommentRegionBlock() contains the sql comment characters '--' for end region block.\n     */\n    \n    this.foldingStartMarker = /(\\bCASE\\b|\\bBEGIN\\b)|^\\s*(\\/\\*)/i;\n    // this.foldingStopMarker = /(\\bEND\\b)|^[\\s\\*]*(\\*\\/)/i;\n    this.startRegionRe = /^\\s*(\\/\\*|--)#?region\\b/;\n    \n    this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {\n        var line = session.getLine(row);\n    \n        if (this.startRegionRe.test(line)) return this.getCommentRegionBlock(session, line, row);\n    \n        var match = line.match(this.foldingStartMarker);\n        if (match) {\n            var i = match.index;\n            if (match[1]) return this.getBeginEndBlock(session, row, i, match[1]);\n    \n            var range = session.getCommentFoldRange(row, i + match[0].length, 1);\n            if (range && !range.isMultiLine()) {\n                if (forceMultiline) {\n                    range = this.getSectionRange(session, row);\n                }\n                else if (foldStyle != \"all\") range = null;\n            }\n    \n            return range;\n        }\n    \n        if (foldStyle === \"markbegin\") return;\n        //TODO: add support for end folding markers\n        return;\n    };\n    \n    /**\n     * @returns {Range} folding block for sequence that starts with 'CASE' or 'BEGIN' and ends with 'END'\n     * @param {string} matchSequence - the sequence of charaters that started the fold widget, which should remain visible when the fold widget is folded\n     */\n    this.getBeginEndBlock = function(session, row, column, matchSequence) {\n        var start = {\n            row: row,\n            column: column + matchSequence.length\n        };\n        var maxRow = session.getLength();\n        var line;\n    \n        var depth = 1;\n        var re = /(\\bCASE\\b|\\bBEGIN\\b)|(\\bEND\\b)/i;\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var m = re.exec(line);\n            if (!m) continue;\n            if (m[1]) depth++;\n            else depth--;\n    \n            if (!depth) break;\n        }\n        var endRow = row;\n        if (endRow > start.row) {\n            return new Range(start.row, start.column, endRow, line.length);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/vbscript.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\n\n\nvar FoldMode = exports.FoldMode = function() {};\n\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n    this.indentKeywords = {\n        \"class\": 1,\n        \"function\": 1,\n        \"sub\": 1,\n        \"if\": 1,\n        \"select\": 1,\n        \"do\": 1,\n        \"for\": 1,\n        \"while\": 1,\n        \"with\": 1,\n        \"property\": 1,\n        \"else\": 1,\n        \"elseif\": 1,\n        \"end\": -1,\n        \"loop\": -1,\n        \"next\": -1,\n        \"wend\": -1,\n        \"exit\": 0,\n        \"until\": 0\n    };\n\n    this.foldingStartMarker = /(?:\\s|^)(class|function|sub|if|select|do|for|while|with|property|else|elseif)\\b/i;\n    this.foldingStopMarker = /\\b(end|loop|next|wend)\\b/i;\n\n    this.getFoldWidgetRange = function (session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n        if (isStart || isEnd) {\n            var match = (isEnd) ? this.foldingStopMarker.exec(line) : this.foldingStartMarker.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type === \"keyword.control.asp\" || type === \"storage.type.function.asp\")\n                    return this.vbsBlock(session, row, match.index + 2);\n            }\n        }\n    };\n\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var isStart = this.foldingStartMarker.test(line);\n        var isEnd = this.foldingStopMarker.test(line);\n        if (/(?:\\s*|^)Exit\\s+(Do|For|Sub|Function|Property)\\b/i.test(line)) return \"\";\n        if (isStart && !isEnd) {\n            var match = this.foldingStartMarker.exec(line);\n            var keyword = match && match[1].toLowerCase();\n            if (keyword) {\n                var type = session.getTokenAt(row, match.index + 2).type;\n                if (type == \"keyword.control.asp\" || type == \"storage.type.function.asp\") {\n                    if (keyword == \"if\" && !/then\\s*('|$)/i.test(line))\n                        return \"\";\n                    return \"start\";\n                }\n            }\n        }\n        return \"\";\n    };\n\n    this.vbsBlock = function(session, row, column, tokenRange) {\n        var stream = new TokenIterator(session, row, column);\n\n        var endOpenings = {\n            \"class\": 1,\n            \"function\": 1,\n            \"sub\": 1,\n            \"if\": 1,\n            \"select\": 1,\n            \"with\": 1,\n            \"property\": 1,\n            \"else\": 1,\n            \"elseif\": 1\n        };\n\n        var token = stream.getCurrentToken();\n        if (!token || (token.type != \"keyword.control.asp\" && token.type != \"storage.type.function.asp\"))\n            return;\n\n        var startTokenValue = token.value.toLowerCase();\n        var val = token.value.toLowerCase();\n\n        var firstRange = stream.getCurrentTokenRange();\n\n        var doubleKeywordResult = this.$isDoubleKeyword(token, stream);\n        if (doubleKeywordResult === \"ignore\") {\n            return;\n        }\n        var doubleKeywordPosition = null;\n        if (doubleKeywordResult) {\n            firstRange = doubleKeywordResult.range;\n            doubleKeywordPosition = doubleKeywordResult.position;\n            if (doubleKeywordResult.position === \"second\") {\n                val = doubleKeywordResult.keyword;\n                startTokenValue = val;\n            }\n        }\n\n        var stack = [val];\n        var dir = this.indentKeywords[val];\n\n        if (!dir)\n            return;\n\n        if (doubleKeywordPosition === \"first\" && dir === 1) {\n            stream.stepForward();\n            stream.stepForward();\n        } else if (doubleKeywordPosition === \"second\" && dir === -1) {\n            stream.stepBackward();\n            stream.stepBackward();\n        }\n\n        switch (val) {\n            case \"property\":\n            case \"sub\":\n            case \"function\":\n            case \"if\":\n            case \"select\":\n            case \"do\":\n            case \"for\":\n            case \"class\":\n            case \"while\":\n            case \"with\":\n                var line = session.getLine(row);\n                var singleLineCondition = /^\\s*If\\s+.*\\s+Then(?!')\\s+(?!')\\S/i.test(line);\n                if (singleLineCondition)\n                    return;\n                var checkToken = new RegExp(\"(?:^|\\\\s)\" + val, \"i\");\n                var endTest = /^\\s*End\\s(If|Sub|Select|Function|Class|With|Property)\\s*/i.test(line);\n                if (!checkToken.test(line) && !endTest) {\n                    return;\n                }\n                if (endTest) {\n                    var tokenRange = stream.getCurrentTokenRange();\n                    stream.step = stream.stepBackward;\n                    stream.step();\n                    stream.step();\n                    token = stream.getCurrentToken();\n                    if (token) {\n                        val = token.value.toLowerCase();\n                        if (val == \"end\") {\n                            firstRange = stream.getCurrentTokenRange();\n                            firstRange = new Range(firstRange.start.row, firstRange.start.column, tokenRange.start.row, tokenRange.end.column);\n                        }\n                    }\n                    dir = -1;\n                }\n                break;\n            case \"end\":\n                var tokenPos = stream.getCurrentTokenPosition();\n                firstRange = stream.getCurrentTokenRange();\n                stream.step = stream.stepForward;\n                stream.step();\n                stream.step();\n                token = stream.getCurrentToken();\n                if (token) {\n                    val = token.value.toLowerCase();\n                    if (val in endOpenings) {\n                        startTokenValue = val;\n                        var nextTokenPos = stream.getCurrentTokenPosition();\n                        var endColumn = nextTokenPos.column + val.length;\n                        firstRange = new Range(tokenPos.row, tokenPos.column, nextTokenPos.row, endColumn);\n                    }\n                }\n                stream.step = stream.stepBackward;\n                stream.step();\n                stream.step();\n                break;\n        }\n        var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length;\n        var startRow = row;\n        var ranges = [];\n        ranges.push(firstRange);\n\n        stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;\n        while(token = stream.step()) {\n            var outputRange = null;\n            var ignore = false;\n            if (token.type != \"keyword.control.asp\" && token.type != \"storage.type.function.asp\")\n                continue;\n            val = token.value.toLowerCase();\n            var level = dir * this.indentKeywords[val];\n\n            switch (val) {\n                case \"property\":\n                case \"sub\":\n                case \"function\":\n                case \"if\":\n                case \"select\":\n                case \"do\":\n                case \"for\":\n                case \"class\":\n                case \"while\":\n                case \"with\":\n                case \"until\":\n                case \"exit\":\n                    var line = session.getLine(stream.getCurrentTokenRow());\n                    var singleLineCondition = /^\\s*If\\s+.*\\s+Then(?!')\\s+(?!')\\S/i.test(line);\n                    if (singleLineCondition) {\n                        level = 0;\n                        ignore = true;\n                    }\n                    var checkToken = new RegExp(\"^\\\\s* end\\\\s+\" + val, \"i\");\n                    if (checkToken.test(line)) {\n                        level = 0;\n                        ignore = true;\n                    }\n                    var doubleKeyword = this.$isDoubleKeyword(token, stream);\n                    if (doubleKeyword === \"ignore\" || (doubleKeyword && doubleKeyword.position === \"second\")) {\n                        level = 0;\n                        ignore = true;\n                    }\n                    break;\n                case \"elseif\":\n                case \"else\":\n                    level = 0;\n                    if (startTokenValue != \"elseif\") {\n                        ignore = true;\n                    }\n                    break;\n            }\n\n            if (level > 0) {\n                stack.unshift(val);\n            } else if (level <= 0 && ignore === false) {\n                stack.shift();\n                if (!stack.length) {\n                    switch (val) {\n                        case \"end\":\n                            var tokenPos = stream.getCurrentTokenPosition();\n                            outputRange = stream.getCurrentTokenRange();\n                            stream.step();\n                            stream.step();\n                            token = stream.getCurrentToken();\n                            if (token) {\n                                val = token.value.toLowerCase();\n                                if (val in endOpenings) {\n                                    if ((startTokenValue == \"else\" || startTokenValue == \"elseif\")) {\n                                        if (val !== \"if\") {\n                                            ranges.shift();\n                                        }\n                                        } else {\n                                            if (val != startTokenValue)\n                                                ranges.shift();\n                                    }\n                                    var nextTokenPos = stream.getCurrentTokenPosition();\n                                    var endColumn = nextTokenPos.column + val.length;\n                                    outputRange.setEnd(nextTokenPos.row, endColumn);\n                                } else {\n                                    ranges.shift();\n                                }\n                                } else {\n                                ranges.shift();\n                            }\n                            stream.step = stream.stepBackward;\n                            stream.step();\n                            stream.step();\n                            token = stream.getCurrentToken();\n                            val = token.value.toLowerCase();\n                            break;\n                        case \"select\":\n                        case \"sub\":\n                        case \"if\":\n                        case \"function\":\n                        case \"class\":\n                        case \"with\":\n                        case \"property\":\n                                if (val != startTokenValue)\n                                    ranges.shift();\n                            break;\n                        case \"do\":\n                            if (startTokenValue != \"loop\")\n                                ranges.shift();\n                            var doDouble = this.$isDoubleKeyword(token, stream);\n                            outputRange = (doDouble && doDouble.position === \"first\")\n                                ? doDouble.range\n                                : stream.getCurrentTokenRange();\n                            break;\n                        case \"loop\":\n                            if (startTokenValue != \"do\")\n                                ranges.shift();\n                            var loopDouble = this.$isDoubleKeyword(token, stream);\n                            outputRange = (loopDouble && loopDouble.position === \"first\")\n                                ? loopDouble.range\n                                : stream.getCurrentTokenRange();\n                            break;\n                        case \"for\":\n                                if (startTokenValue != \"next\")\n                                    ranges.shift();\n                            break;\n                        case \"next\":\n                                if (startTokenValue != \"for\")\n                                    ranges.shift();\n                            break;\n                        case \"while\":\n                                if (startTokenValue != \"wend\")\n                                    ranges.shift();\n                            break;\n                        case \"wend\":\n                                if (startTokenValue != \"while\")\n                                    ranges.shift();\n                            break;\n                    }\n                    break;\n                }\n\n                if (level === 0){\n                    stack.unshift(val);\n                }\n            }\n        }\n\n        if (!token)\n            return null;\n\n        if (tokenRange) {\n            if (!outputRange) {\n                ranges.push(stream.getCurrentTokenRange());\n            } else {\n                ranges.push(outputRange);\n            }\n            return ranges;\n        }\n\n        var row = stream.getCurrentTokenRow();\n        if (dir === -1) {\n            var endColumn = session.getLine(row).length;\n            return new Range(row, endColumn, startRow - 1, startColumn);\n        } else\n            return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length);\n    };\n\n    /**\n     * @param {Token} currentToken\n     * @param {TokenIterator} stream\n     * @return {false | \"ignore\" | { range: Range, position: \"first\" | \"second\", keyword: string }}\n     */\n    this.$isDoubleKeyword = function (currentToken, stream) {\n        var val = currentToken.value.toLowerCase();\n        var tokenIndex = stream.$tokenIndex;\n        var rowTokens = stream.$rowTokens;\n\n        var prevKeywordIndex = tokenIndex - 2;\n        var prevKeyword = prevKeywordIndex >= 0 ? rowTokens[prevKeywordIndex] : null;\n        if (prevKeyword) {\n            var prevVal = prevKeyword.value.toLowerCase();\n\n            // Do While / Do Until\n            if ((val === \"while\" || val === \"until\") && prevVal === \"do\") {\n                return {\n                    range: this.$getDoubleKeywordRange(prevKeywordIndex, tokenIndex, stream),\n                    position: \"second\",\n                    keyword: \"do\"\n                };\n            }\n\n            // Loop While / Loop Until\n            if ((val === \"while\" || val === \"until\") && prevVal === \"loop\") {\n                return {\n                    range: this.$getDoubleKeywordRange(prevKeywordIndex, tokenIndex, stream),\n                    position: \"second\",\n                    keyword: \"loop\"\n                };\n            }\n\n            if (prevVal === \"exit\" && (val === \"for\" || val === \"do\" || val === \"sub\" || val === \"function\" || val === \"property\")) {\n                return \"ignore\";\n            }\n        }\n\n        var nextKeywordIndex = tokenIndex + 2;\n        var nextKeyword = nextKeywordIndex < rowTokens.length ? rowTokens[nextKeywordIndex] : null;\n        if (nextKeyword) {\n            var nextVal = nextKeyword.value.toLowerCase();\n\n            // Do While / Do Until\n            if (val === \"do\" && (nextVal === \"while\" || nextVal === \"until\")) {\n                return {\n                    range: this.$getDoubleKeywordRange(tokenIndex, nextKeywordIndex, stream),\n                    position: \"first\",\n                    keyword: \"do\"\n                };\n            }\n\n            // Loop While / Loop Until\n            if (val === \"loop\" && (nextVal === \"while\" || nextVal === \"until\")) {\n                return {\n                    range: this.$getDoubleKeywordRange(tokenIndex, nextKeywordIndex, stream),\n                    position: \"first\",\n                    keyword: \"loop\"\n                };\n            }\n\n            if (val === \"exit\" && (nextVal === \"for\" || nextVal === \"do\" || nextVal === \"sub\" || nextVal === \"function\" || nextVal === \"property\")) {\n                return \"ignore\";\n            }\n        }\n\n        return false;\n    };\n\n    /**\n     * Calculate range spanning both tokens of a double keyword\n     * @param {number} firstTokenIndex\n     * @param {number} secondTokenIndex\n     * @param {TokenIterator} stream\n     * @return {Range}\n     */\n    this.$getDoubleKeywordRange = function (firstTokenIndex, secondTokenIndex, stream) {\n        var row = stream.$row;\n        var rowTokens = stream.$rowTokens;\n\n        var firstStart = 0;\n        for (var i = 0; i < firstTokenIndex; i++) {\n            firstStart += rowTokens[i].value.length;\n        }\n\n        var secondEnd = 0;\n        for (var i = 0; i <= secondTokenIndex; i++) {\n            secondEnd += rowTokens[i].value.length;\n        }\n\n        return new Range(row, firstStart, row, secondEnd);\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/vbscript_test.js",
    "content": "\"use strict\";\n\nvar VBScriptMode = require(\"../vbscript\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new VBScriptMode();\n    },\n\n    \"test: visual basic script indentation based folding\": function() {\n        var session = new EditSession([\n            'Sub MakeHelloWorldFile (FileName)',\n            '   \\'Create a new file in C: drive or overwrite existing file',\n            '   Set FSO = CreateObject(\"Scripting.FileSystemObject\")',\n            '   If FSO.FileExists(FileName) Then \\'comment ',\n            '      Answer = MsgBox (\"File \" & FileName & \" exists ... OK to overwrite?\", vbOKCancel)',\n            '      \\'If button selected is not OK, then quit now',\n            '      \\'vbOK is a language constant',\n            '      If Answer <> vbOK Then Exit Sub',\n            '   Else',\n            '      \\'Confirm OK to create',\n            '      Answer = MsgBox (\"File \" & FileName & \" ... OK to create?\", vbOKCancel)',\n            '      If Answer <> vbOK Then Exit Sub',\n            '   End If',\n            '   \\'Create new file (or replace an existing file)',\n            '   Set FileObject = FSO.CreateTextFile (FileName)',\n            '   FileObject.WriteLine \"Time ... \" & Now()',\n            '   FileObject.WriteLine \"Hello World\"',\n            '   FileObject.Close()',\n            '   MsgBox \"File \" & FileName & \" ... updated.\"',\n            'End Sub'\n        ]);\n\n        session.setFoldStyle(\"markbegin\");\n        session.setMode(this.mode);\n\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"start\");\n        assert.equal(session.getFoldWidget(4), \"\");\n        assert.equal(session.getFoldWidget(8), \"start\");\n        assert.equal(session.getFoldWidget(9), \"\");\n\n        assert.range(session.getFoldWidgetRange(0), 0, 33, 18, 46);\n        assert.range(session.getFoldWidgetRange(3), 3, 45, 11, 37);\n        assert.range(session.getFoldWidgetRange(12), 3, 45, 11, 37);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/velocity.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, BaseFoldMode);\n\n(function() {\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var range = this.indentationBlock(session, row);\n        if (range)\n            return range;\n\n        var re = /\\S/;\n        var line = session.getLine(row);\n        var startLevel = line.search(re);\n        if (startLevel == -1 || line[startLevel] != \"##\")\n            return;\n\n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            line = session.getLine(row);\n            var level = line.search(re);\n\n            if (level == -1)\n                continue;\n\n            if (line[level] != \"##\")\n                break;\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var indent = line.search(/\\S/);\n        var next = session.getLine(row + 1);\n        var prev = session.getLine(row - 1);\n        var prevIndent = prev.search(/\\S/);\n        var nextIndent = next.search(/\\S/);\n\n        if (indent == -1) {\n            session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? \"start\" : \"\";\n            return \"\";\n        }\n\n        // documentation comments\n        if (prevIndent == -1) {\n            if (indent == nextIndent && line[indent] == \"##\" && next[indent] == \"##\") {\n                session.foldWidgets[row - 1] = \"\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"start\";\n            }\n        } else if (prevIndent == indent && line[indent] == \"##\" && prev[indent] == \"##\") {\n            if (session.getLine(row - 2).search(/\\S/) == -1) {\n                session.foldWidgets[row - 1] = \"start\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"\";\n            }\n        }\n\n        if (prevIndent!= -1 && prevIndent < indent)\n            session.foldWidgets[row - 1] = \"start\";\n        else\n            session.foldWidgets[row - 1] = \"\";\n\n        if (indent < nextIndent)\n            return \"start\";\n        else\n            return \"\";\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/xml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Range = require(\"../../range\").Range;\nvar BaseFoldMode = require(\"./fold_mode\").FoldMode;\n\nvar FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) {\n    BaseFoldMode.call(this);\n    this.voidElements = voidElements || {};\n    this.optionalEndTags = oop.mixin({}, this.voidElements);\n    if (optionalEndTags)\n        oop.mixin(this.optionalEndTags, optionalEndTags);\n    \n};\noop.inherits(FoldMode, BaseFoldMode);\n\nvar Tag = function() {\n    this.tagName = \"\";\n    this.closing = false;\n    this.selfClosing = false;\n    this.start = {row: 0, column: 0};\n    this.end = {row: 0, column: 0};\n};\n\nfunction is(token, type) {\n    return token && token.type && token.type.lastIndexOf(type + \".xml\") > -1;\n}\n\n(function() {\n\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var tag = this._getFirstTagInLine(session, row);\n\n        if (!tag)\n            return this.getCommentFoldWidget(session, row);\n\n        if (tag.closing || (!tag.tagName && tag.selfClosing))\n            return foldStyle === \"markbeginend\" ? \"end\" : \"\";\n\n        if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase()))\n            return \"\";\n\n        if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column))\n            return \"\";\n\n        return \"start\";\n    };\n    \n    this.getCommentFoldWidget = function(session, row) {\n        if (/comment/.test(session.getState(row)) && /<!-/.test(session.getLine(row)))\n            return \"start\";\n        return \"\";\n    };\n\n    /*\n     * returns a first tag (or a fragment) in a line\n     */\n    this._getFirstTagInLine = function(session, row) {\n        var tokens = session.getTokens(row);\n        var tag = new Tag();\n\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            if (is(token, \"tag-open\")) {\n                tag.end.column = tag.start.column + token.value.length;\n                tag.closing = is(token, \"end-tag-open\");\n                token = tokens[++i];\n                if (!token)\n                    return null;\n                tag.tagName = token.value;\n                if (token.value === \"\") { //skip empty tag name token for fragment\n                    token = tokens[++i];\n                    if (!token) return null;\n                    tag.tagName = token.value;\n                }\n                tag.end.column += token.value.length;\n                for (i++; i < tokens.length; i++) {\n                    token = tokens[i];\n                    tag.end.column += token.value.length;\n                    if (is(token, \"tag-close\")) {\n                        tag.selfClosing = token.value == '/>';\n                        break;\n                    }\n                }\n                return tag;\n            } else if (is(token, \"tag-close\")) {\n                tag.selfClosing = token.value == '/>';\n                return tag;\n            }\n            tag.start.column += token.value.length;\n        }\n\n        return null;\n    };\n\n    this._findEndTagInLine = function(session, row, tagName, startColumn) {\n        var tokens = session.getTokens(row);\n        var column = 0;\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            column += token.value.length;\n            if (column < startColumn - 1)\n                continue;\n            if (is(token, \"end-tag-open\")) {\n                token = tokens[i + 1];\n                if (is(token, \"tag-name\") && token.value === \"\") {\n                    token = tokens[i + 2];\n                }\n                if (token && token.value == tagName)\n                    return true;\n            }\n        }\n        return false;\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var firstTag = this._getFirstTagInLine(session, row);\n        if (!firstTag) {\n            return this.getCommentFoldWidget(session, row) && session.getCommentFoldRange(\n                row, session.getLine(row).length);\n        }\n        var tags = session.getMatchingTags({row: row, column: 0});\n        if (tags) {\n            return new Range(\n                tags.openTag.end.row, tags.openTag.end.column, tags.closeTag.start.row, tags.closeTag.start.column);\n        }\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/xml_test.js",
    "content": "\"use strict\";\n\nvar XmlMode = require(\"../xml\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\n\nmodule.exports = {\n\n    \"test: fold multi line self closing element\": function() {\n        var session = new EditSession([\n            '<person',\n            '  firstname=\"fabian\"',\n            '  lastname=\"jakobs\"/>'\n        ]);\n        \n        var mode = new XmlMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 8, 2, 19);\n        assert.range(session.getFoldWidgetRange(2), 0, 8, 2, 19);\n    },\n    \n    \"test: fold should skip self closing elements\": function() {\n        var session = new EditSession([\n            '<person>',\n            '  <attrib value=\"fabian\"/>',\n            '</person>'\n        ]);\n        \n        var mode = new XmlMode();\n        session.setFoldStyle(\"markbeginend\");\n        session.setMode(mode);\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"\");\n        assert.equal(session.getFoldWidget(2), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 8, 2, 0);\n        assert.range(session.getFoldWidgetRange(2), 0, 8, 2, 0);\n    },\n    \n    \"test: fold should skip multi line self closing elements\": function() {\n        var session = new EditSession([\n            '<person>',\n            '  <attib',\n            '     key=\"name\"',\n            '     value=\"fabian\"/>',\n            '</person>'\n        ]);\n        \n        var mode = new XmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n        \n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(1), \"start\");\n        assert.equal(session.getFoldWidget(2), \"\");\n        assert.equal(session.getFoldWidget(3), \"end\");\n        assert.equal(session.getFoldWidget(4), \"end\");\n        \n        assert.range(session.getFoldWidgetRange(0), 0, 8, 4, 0);\n        assert.range(session.getFoldWidgetRange(1), 1, 9, 3, 19);\n        assert.range(session.getFoldWidgetRange(3), 1, 9, 3, 19);\n        assert.range(session.getFoldWidgetRange(4), 0, 8, 4, 0);\n    },\n    \"test: fold should handle multi-line comments inside nested elements correctly\": function () {\n        var session = new EditSession([\n            '<parentElement>', '  <childElement>', '    text <!--', '      This is a multi-line comment',\n            '      that spans multiple lines', '    -->', '  </childElement>', '  <anotherChildElement>',\n            '    <!-- Another comment -->', '  </anotherChildElement>', '</parentElement>'\n        ]);\n\n        var mode = new XmlMode();\n        session.setMode(mode);\n        session.setFoldStyle(\"markbeginend\");\n\n        // Checks for the parentElement\n        assert.equal(session.getFoldWidget(0), \"start\");\n        assert.equal(session.getFoldWidget(10), \"end\");\n\n        // Checks for multi-line comment folding\n        assert.equal(session.getFoldWidget(2), \"start\");\n\n        // Checks for anotherChildElement folding (with single-line comment)\n        assert.equal(session.getFoldWidget(7), \"start\");\n        assert.equal(session.getFoldWidget(8), \"\");\n        assert.equal(session.getFoldWidget(9), \"end\");\n\n        // Verifying fold ranges\n        assert.range(session.getFoldWidgetRange(0), 0, 15, 10, 0);\n        assert.range(session.getFoldWidgetRange(2), 2, 13, 5, 4);\n        assert.equal(session.getFoldWidgetRange(8), \"\");\n    }\n\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/folding/yaml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar CoffeeFoldMode = require(\"./coffee\").FoldMode;\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\noop.inherits(FoldMode, CoffeeFoldMode);\n\n(function() {\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        var re = /\\S/;\n        var line = session.getLine(row);\n        var startLevel = line.search(re);\n        var isCommentFold = line[startLevel] === \"#\";\n        var isDashFold = line[startLevel] === \"-\";\n        \n        if (startLevel == -1)\n            return;\n\n        var startColumn = line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        // Comment folding\n        if (isCommentFold) {\n            var range = this.commentBlock(session, row);\n            if (range)\n                return range;\n        // Indentation folding (used for indentations that start with a '-').\n        } else if (isDashFold) {\n            var range = this.indentationBlock(session, row);\n            if (range)\n                return range;\n        // List folding (used for indentations that don't start with a '-')..\n        } else {\n            while (++row < maxRow) {\n                var line = session.getLine(row);\n                var level = line.search(re);\n\n                if (level == -1)\n                    continue;\n\n                if (level <= startLevel && line[startLevel] !== '-') {\n                    var token = session.getTokenAt(row, 0);\n                    if (!token || token.type !== \"string\")\n                        break;\n                }\n\n                endRow = row;\n            }\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n    // must return \"\" if there's no fold, to enable caching\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        var indent = line.search(/\\S/);\n        var next = session.getLine(row + 1);\n        var prev = session.getLine(row - 1);\n        var prevIndent = prev.search(/\\S/);\n        var nextIndent = next.search(/\\S/);\n\n        var lineStartsWithDash = line[indent] === '-';\n\n        if (indent == -1) {\n            session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? \"start\" : \"\";\n            return \"\";\n        }\n\n        // documentation comments\n        if (prevIndent == -1) {\n            if (indent == nextIndent && line[indent] == \"#\" && next[indent] == \"#\") {\n                session.foldWidgets[row - 1] = \"\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"start\";\n            }\n        } else if (prevIndent == indent && line[indent] == \"#\" && prev[indent] == \"#\") {\n            if (session.getLine(row - 2).search(/\\S/) == -1) {\n                session.foldWidgets[row - 1] = \"start\";\n                session.foldWidgets[row + 1] = \"\";\n                return \"\";\n            }\n        }\n\n        // Indentation fold\n        if (prevIndent!= -1 && prevIndent < indent) {\n            session.foldWidgets[row - 1] = \"start\";\n        // Fold non-indented list\n        } else if (prevIndent!= -1 &&  (prevIndent == indent && lineStartsWithDash)) {\n            session.foldWidgets[row - 1] = \"start\";\n        } else {\n            session.foldWidgets[row - 1] = \"\";\n        }\n\n        if (indent < nextIndent)\n            return \"start\";\n        else\n            return \"\";\n    };\n\n}).call(FoldMode.prototype);\n"
  },
  {
    "path": "src/mode/folding/yaml_test.js",
    "content": "\"use strict\";\n\nvar YamlMode = require(\"../yaml\").Mode;\nvar EditSession = require(\"../../edit_session\").EditSession;\nvar assert = require(\"../../test/assertions\");\nfunction testFoldWidgets(array) {\n    var session = array.filter(function(_, i){return i % 2 == 1;});\n    session = new EditSession(session);\n    var mode = new YamlMode();\n    session.setFoldStyle(\"markbeginend\");\n    session.setMode(mode);\n\n    var widgets = array.filter(function(_, i){return i % 2 == 0;});\n    widgets.forEach(function(w, i){\n        session.foldWidgets[i] = session.getFoldWidget(i);\n    });\n    widgets.forEach(function(w, i){\n        w = w.split(\",\");\n        var type = w[0] == \">\" ? \"start\" : w[0] == \"<\" ? \"end\" : \"\";\n        assert.equal(session.foldWidgets[i], type);\n        if (!type)\n            return;\n        var range = session.getFoldWidgetRange(i);\n        if (!w[1]) {\n            assert.equal(range, null);\n            return;\n        }\n        assert.equal(range.start.row, i);\n        assert.equal(range.end.row - range.start.row, parseInt(w[1]));\n        testColumn(w[2], range.start);\n        testColumn(w[3], range.end);\n    });\n\n    function testColumn(w, pos) {\n        if (!w)\n            return;\n        if (w == \"l\")\n            w = session.getLine(pos.row).length;\n        else\n            w = parseInt(w);\n        assert.equal(pos.column, w);\n    }\n}\nmodule.exports = {\n    \"test: yaml indentation based folding\": function() {\n       testFoldWidgets([\n            '>,1,l,l',         ' ## indented comment',\n            '',                '  # ',\n            '',                '',\n            '',                '  ',\n            '>,1',             'list: ',\n            '',                '  -item',\n            '',                '  ',\n            '>,2',             'list: ',\n            '>,1',             '  -item1',\n            '',                '   item2',\n            '',                '  ',\n            '>,4',             'list: ',\n            '>,1',             '  -item1',\n            '',                '   item2',\n            '>,1',             '  -item3',\n            '',                '   item4',\n            '',                '  ',\n            '>,1',             'list: ',\n            '',                '-item',\n            '',                '  ',\n            '>,2',             'list: ',\n            '>,1',             '-item1',\n            '',                ' item2',\n            '',                '  ',\n            '>,4',             'list: ',\n            '>,1',             '-item1',\n            '',                ' item2',\n            '>,1',             '-item3',\n            '',                ' item4'\n        ]);\n    }\n};\n\n\nrequire(\"../../test/run\")(module);\n"
  },
  {
    "path": "src/mode/forth.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ForthHighlightRules = require(\"./forth_highlight_rules\").ForthHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ForthHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/forth\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/forth_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/vze26m98/Forth.tmbundle/master/Syntaxes/Forth.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ForthHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: [ { include: '#forth' } ],\n      '#comment':\n       [ { token: 'comment.line.double-dash.forth',\n           regex: '(?:^|\\\\s)--\\\\s.*$',\n           comment: 'line comments for iForth' },\n         { token: 'comment.line.backslash.forth',\n           regex: '(?:^|\\\\s)\\\\\\\\[\\\\s\\\\S]*$',\n           comment: 'ANSI line comment' },\n         { token: 'comment.line.backslash-g.forth',\n           regex: '(?:^|\\\\s)\\\\\\\\[Gg] .*$',\n           comment: 'gForth line comment' },\n         { token: 'comment.block.forth',\n           regex: '(?:^|\\\\s)\\\\(\\\\*(?=\\\\s|$)',\n           push:\n            [ { token: 'comment.block.forth',\n                regex: '(?:^|\\\\s)\\\\*\\\\)(?=\\\\s|$)',\n                next: 'pop' },\n              { defaultToken: 'comment.block.forth' } ],\n           comment: 'multiline comments for iForth' },\n         { token: 'comment.block.documentation.forth',\n           regex: '\\\\bDOC\\\\b',\n           caseInsensitive: true,\n           push:\n            [ { token: 'comment.block.documentation.forth',\n                regex: '\\\\bENDDOC\\\\b',\n                caseInsensitive: true,\n                next: 'pop' },\n              { defaultToken: 'comment.block.documentation.forth' } ],\n           comment: 'documentation comments for iForth' },\n         { token: 'comment.line.parentheses.forth',\n           regex: '(?:^|\\\\s)\\\\.?\\\\( [^)]*\\\\)',\n           comment: 'ANSI line comment' } ],\n      '#constant':\n       [ { token: 'constant.language.forth',\n           regex: '(?:^|\\\\s)(?:TRUE|FALSE|BL|PI|CELL|C/L|R/O|W/O|R/W)(?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'constant.numeric.forth',\n           regex: '(?:^|\\\\s)[$#%]?[-+]?[0-9]+(?:\\\\.[0-9]*e-?[0-9]+|\\\\.?[0-9a-fA-F]*)(?=\\\\s|$)'},\n         { token: 'constant.character.forth',\n           regex: '(?:^|\\\\s)(?:[&^]\\\\S|(?:\"|\\')\\\\S(?:\"|\\'))(?=\\\\s|$)'}],\n      '#forth':\n       [ { include: '#constant' },\n         { include: '#comment' },\n         { include: '#string' },\n         { include: '#word' },\n         { include: '#variable' },\n         { include: '#storage' },\n         { include: '#word-def' } ],\n      '#storage':\n       [ { token: 'storage.type.forth',\n           regex: '(?:^|\\\\s)(?:2CONSTANT|2VARIABLE|ALIAS|CONSTANT|CREATE-INTERPRET/COMPILE[:]?|CREATE|DEFER|FCONSTANT|FIELD|FVARIABLE|USER|VALUE|VARIABLE|VOCABULARY)(?=\\\\s|$)',\n           caseInsensitive: true}],\n      '#string':\n       [ { token: 'string.quoted.double.forth',\n           regex: '(ABORT\" |BREAK\" |\\\\.\" |C\" |0\"|S\\\\\\\\?\" )([^\"]+\")',\n           caseInsensitive: true},\n         { token: 'string.unquoted.forth',\n           regex: '(?:INCLUDE|NEEDS|REQUIRE|USE)[ ]\\\\S+(?=\\\\s|$)',\n           caseInsensitive: true}],\n      '#variable':\n       [ { token: 'variable.language.forth',\n           regex: '\\\\b(?:I|J)\\\\b',\n           caseInsensitive: true } ],\n      '#word':\n       [ { token: 'keyword.control.immediate.forth',\n           regex: '(?:^|\\\\s)\\\\[(?:\\\\?DO|\\\\+LOOP|AGAIN|BEGIN|DEFINED|DO|ELSE|ENDIF|FOR|IF|IFDEF|IFUNDEF|LOOP|NEXT|REPEAT|THEN|UNTIL|WHILE)\\\\](?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'keyword.other.immediate.forth',\n           regex: '(?:^|\\\\s)(?:COMPILE-ONLY|IMMEDIATE|IS|RESTRICT|TO|WHAT\\'S|])(?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'keyword.control.compile-only.forth',\n           regex: '(?:^|\\\\s)(?:-DO|\\\\-LOOP|\\\\?DO|\\\\?LEAVE|\\\\+DO|\\\\+LOOP|ABORT\\\\\"|AGAIN|AHEAD|BEGIN|CASE|DO|ELSE|ENDCASE|ENDIF|ENDOF|ENDTRY\\\\-IFERROR|ENDTRY|FOR|IF|IFERROR|LEAVE|LOOP|NEXT|RECOVER|REPEAT|RESTORE|THEN|TRY|U\\\\-DO|U\\\\+DO|UNTIL|WHILE)(?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'keyword.other.compile-only.forth',\n           regex: '(?:^|\\\\s)(?:\\\\?DUP-0=-IF|\\\\?DUP-IF|\\\\)|\\\\[|\\\\[\\'\\\\]|\\\\[CHAR\\\\]|\\\\[COMPILE\\\\]|\\\\[IS\\\\]|\\\\[TO\\\\]|<COMPILATION|<INTERPRETATION|ASSERT\\\\(|ASSERT0\\\\(|ASSERT1\\\\(|ASSERT2\\\\(|ASSERT3\\\\(|COMPILATION>|DEFERS|DOES>|INTERPRETATION>|OF|POSTPONE)(?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'keyword.other.non-immediate.forth',\n           regex: '(?:^|\\\\s)(?:\\'|<IS>|<TO>|CHAR|END-STRUCT|INCLUDE[D]?|LOAD|NEEDS|REQUIRE[D]?|REVISION|SEE|STRUCT|THRU|USE)(?=\\\\s|$)',\n           caseInsensitive: true},\n         { token: 'keyword.other.warning.forth',\n           regex: '(?:^|\\\\s)(?:~~|BREAK:|BREAK\"|DBG)(?=\\\\s|$)',\n           caseInsensitive: true}],\n      '#word-def':\n       [ { token:\n            [ 'keyword.other.compile-only.forth',\n              'keyword.other.compile-only.forth',\n              'meta.block.forth',\n              'entity.name.function.forth' ],\n           regex: '(:NONAME)|(^:|\\\\s:)(\\\\s)(\\\\S+)(?=\\\\s|$)',\n           caseInsensitive: true,\n           push:\n            [ { token: 'keyword.other.compile-only.forth',\n                regex: ';(?:CODE)?',\n                caseInsensitive: true,\n                next: 'pop' },\n              { include: '#constant' },\n              { include: '#comment' },\n              { include: '#string' },\n              { include: '#word' },\n              { include: '#variable' },\n              { include: '#storage' },\n              { defaultToken: 'meta.block.forth' } ] } ] };\n    \n    this.normalizeRules();\n};\n\nForthHighlightRules.metaData = { fileTypes: [ 'frt', 'fs', 'ldr', 'fth', '4th' ],\n      foldingStartMarker: '/\\\\*\\\\*|\\\\{\\\\s*$',\n      foldingStopMarker: '\\\\*\\\\*/|^\\\\s*\\\\}',\n      keyEquivalent: '^~F',\n      name: 'Forth',\n      scopeName: 'source.forth' };\n\n\noop.inherits(ForthHighlightRules, TextHighlightRules);\n\nexports.ForthHighlightRules = ForthHighlightRules;\n"
  },
  {
    "path": "src/mode/fortran.js",
    "content": "/* Derived from Python rules */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar FortranHighlightRules = require(\"./fortran_highlight_rules\").FortranHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = FortranHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"!\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    var outdents = {\n        \"return\": 1,\n        \"break\": 1,\n        \"continue\": 1,\n        \"RETURN\": 1,\n        \"BREAK\": 1,\n        \"CONTINUE\": 1\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (input !== \"\\r\\n\" && input !== \"\\r\" && input !== \"\\n\")\n            return false;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n\n        if (!tokens)\n            return false;\n        do {\n            var last = tokens.pop();\n        } while (last && (last.type == \"comment\" || (last.type == \"text\" && last.value.match(/^\\s+$/))));\n\n        if (!last)\n            return false;\n\n        return (last.type == \"keyword\" && outdents[last.value]);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n\n        row += 1;\n        var indent = this.$getIndent(doc.getLine(row));\n        var tab = doc.getTabString();\n        if (indent.slice(-tab.length) == tab)\n            doc.remove(new Range(row, indent.length-tab.length, row, indent.length));\n    };\n\n    this.$id = \"ace/mode/fortran\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/fortran_highlight_rules.js",
    "content": "/* Derived from Python highlighing rules */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar FortranHighlightRules = function() {\n\n    var keywords = (\n        \"call|case|contains|continue|cycle|do|else|elseif|end|enddo|endif|function|\"+ \n        \"if|implicit|in|include|inout|intent|module|none|only|out|print|program|return|\"+ \n        \"select|status|stop|subroutine|\" +\n        \"return|then|use|while|write|\"+\n        \"CALL|CASE|CONTAINS|CONTINUE|CYCLE|DO|ELSE|ELSEIF|END|ENDDO|ENDIF|FUNCTION|\"+\n        \"IF|IMPLICIT|IN|INCLUDE|INOUT|INTENT|MODULE|NONE|ONLY|OUT|PRINT|PROGRAM|RETURN|\"+\n        \"SELECT|STATUS|STOP|SUBROUTINE|\" +\n        \"RETURN|THEN|USE|WHILE|WRITE\"\n    );\n\n    var keywordOperators = (\n        \"and|or|not|eq|ne|gt|ge|lt|le|\" +\n        \"AND|OR|NOT|EQ|NE|GT|GE|LT|LE\" \n    );\n\n    var builtinConstants = (\n        \"true|false|TRUE|FALSE\"\n    );\n\n    var builtinFunctions = (\n        \"abs|achar|acos|acosh|adjustl|adjustr|aimag|aint|all|allocate|\"+\n        \"anint|any|asin|asinh|associated|atan|atan2|atanh|\"+\n        \"bessel_j0|bessel_j1|bessel_jn|bessel_y0|bessel_y1|bessel_yn|\"+\n        \"bge|bgt|bit_size|ble|blt|btest|ceiling|char|cmplx|conjg|cos|cosh|\"+\n        \"count|cpu_time|cshift|date_and_time|dble|deallocate|digits|dim|dot_product|dprod|\"+\n        \"dshiftl|dshiftr|dsqrt|eoshift|epsilon|erf|erfc|erfc_scaled|exp|float|floor|\"+\n        \"format|fraction|gamma|input|len|lge|lgt|lle|llt|log|log10|maskl|maskr|matmul|max|maxloc|maxval|\"+\n        \"merge|min|minloc|minval|mod|modulo|nint|not|norm2|null|nullify|pack|parity|popcnt|poppar|\"+\n        \"precision|present|product|radix|random_number|random_seed|range|repeat|reshape|round|\"+\n        \"rrspacing|same_type_as|scale|scan|selected_char_kind|selected_int_kind|selected_real_kind|\"+\n        \"set_exponent|shape|shifta|shiftl|shiftr|sign|sin|sinh|size|sngl|spacing|spread|\"+\n        \"sqrt|sum|system_clock|tan|tanh|tiny|trailz|transfer|transpose|trim|ubound|unpack|verify|\" +\n        \"ABS|ACHAR|ACOS|ACOSH|ADJUSTL|ADJUSTR|AIMAG|AINT|ALL|ALLOCATE|\"+\n        \"ANINT|ANY|ASIN|ASINH|ASSOCIATED|ATAN|ATAN2|ATANH|\"+\n        \"BESSEL_J0|BESSEL_J1|BESSEL_JN|BESSEL_Y0|BESSEL_Y1|BESSEL_YN|\"+\n        \"BGE|BGT|BIT_SIZE|BLE|BLT|BTEST|CEILING|CHAR|CMPLX|CONJG|COS|COSH|\"+\n        \"COUNT|CPU_TIME|CSHIFT|DATE_AND_TIME|DBLE|DEALLOCATE|DIGITS|DIM|DOT_PRODUCT|DPROD|\"+\n        \"DSHIFTL|DSHIFTR|DSQRT|EOSHIFT|EPSILON|ERF|ERFC|ERFC_SCALED|EXP|FLOAT|FLOOR|\"+\n        \"FORMAT|FRACTION|GAMMA|INPUT|LEN|LGE|LGT|LLE|LLT|LOG|LOG10|MASKL|MASKR|MATMUL|MAX|MAXLOC|MAXVAL|\"+\n        \"MERGE|MIN|MINLOC|MINVAL|MOD|MODULO|NINT|NOT|NORM2|NULL|NULLIFY|PACK|PARITY|POPCNT|POPPAR|\"+\n        \"PRECISION|PRESENT|PRODUCT|RADIX|RANDOM_NUMBER|RANDOM_SEED|RANGE|REPEAT|RESHAPE|ROUND|\"+\n        \"RRSPACING|SAME_TYPE_AS|SCALE|SCAN|SELECTED_CHAR_KIND|SELECTED_INT_KIND|SELECTED_REAL_KIND|\"+\n        \"SET_EXPONENT|SHAPE|SHIFTA|SHIFTL|SHIFTR|SIGN|SIN|SINH|SIZE|SNGL|SPACING|SPREAD|\"+\n        \"SQRT|SUM|SYSTEM_CLOCK|TAN|TANH|TINY|TRAILZ|TRANSFER|TRANSPOSE|TRIM|UBOUND|UNPACK|VERIFY\"\n    );\n\n    var storageType = (\n        \"logical|character|integer|real|type|\" +\n        \"LOGICAL|CHARACTER|INTEGER|REAL|TYPE\"    \n    );\n\n    var storageModifiers = ( \n        \"allocatable|dimension|intent|parameter|pointer|target|private|public|\" +\n        \"ALLOCATABLE|DIMENSION|INTENT|PARAMETER|POINTER|TARGET|PRIVATE|PUBLIC\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"invalid.deprecated\": \"debugger\",\n        \"support.function\": builtinFunctions,\n        \"constant.language\": builtinConstants,\n        \"keyword\": keywords,\n        \"keyword.operator\": keywordOperators,\n        \"storage.type\": storageType,\n        \"storage.modifier\" : storageModifiers\n    }, \"identifier\");\n\n    var strPre = \"(?:r|u|ur|R|U|UR|Ur|uR)?\";\n\n    var decimalInteger = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    var octInteger = \"(?:0[oO]?[0-7]+)\";\n    var hexInteger = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n    var binInteger = \"(?:0[bB][01]+)\";\n    var integer = \"(?:\" + decimalInteger + \"|\" + octInteger + \"|\" + hexInteger + \"|\" + binInteger + \")\";\n\n    var exponent = \"(?:[eE][+-]?\\\\d+)\";\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var exponentFloat = \"(?:(?:\" + pointFloat + \"|\" +  intPart + \")\" + exponent + \")\";\n    var floatNumber = \"(?:\" + exponentFloat + \"|\" + pointFloat + \")\";\n\n    var stringEscape =  \"\\\\\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\\\\\abfnrtv'\\\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"!.*$\"\n        }, {\n            token : \"string\",           // multi line \"\"\" string start\n            regex : strPre + '\"{3}',\n            next : \"qqstring3\"\n        }, {\n            token : \"string\",           // \" string\n            regex : strPre + '\"(?=.)',\n            next : \"qqstring\"\n        }, {\n            token : \"string\",           // multi line ''' string start\n            regex : strPre + \"'{3}\",\n            next : \"qstring3\"\n        }, {\n            token : \"string\",           // ' string\n            regex : strPre + \"'(?=.)\",\n            next : \"qstring\"\n        }, {\n            token : \"constant.numeric\", // imaginary\n            regex : \"(?:\" + floatNumber + \"|\\\\d+)[jJ]\\\\b\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : floatNumber\n        }, {\n            token : \"constant.numeric\", // long integer\n            regex : integer + \"[lL]\\\\b\"\n        }, {\n            token : \"constant.numeric\", // integer\n            regex : integer + \"\\\\b\"\n        }, {\n            token : \"keyword\", // pre-compiler directives\n            regex : \"#\\\\s*(?:include|import|define|undef|INCLUDE|IMPORT|DEFINE|UNDEF)\\\\b\"\n        }, {\n            token : \"keyword\", // special case pre-compiler directive\n            regex : \"#\\\\s*(?:endif|ifdef|else|elseif|ifndef|ENDIF|IFDEF|ELSE|ELSEIF|IFNDEF)\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|%|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\[\\\\(\\\\{]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\]\\\\)\\\\}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ],\n        \"qqstring3\" : [ {\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\", // multi line \"\"\" string end\n            regex : '\"{3}',\n            next : \"start\"\n        }, {\n            defaultToken : \"string\"\n        } ],\n        \"qstring3\" : [ {\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\", // multi line \"\"\" string end\n            regex : '\"{3}',\n            next : \"start\"\n        }, {\n            defaultToken : \"string\"\n        } ],\n        \"qqstring\" : [{\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        }, {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"qstring\" : [{\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qstring\"\n        }, {\n            token : \"string\",\n            regex : \"'|$\",\n            next  : \"start\"\n        }, {\n            defaultToken: \"string\"\n        }]\n    };\n};\n\noop.inherits(FortranHighlightRules, TextHighlightRules);\n\nexports.FortranHighlightRules = FortranHighlightRules;\n"
  },
  {
    "path": "src/mode/fsharp.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextMode = require(\"./text\").Mode;\n    var FSharpHighlightRules = require(\"./fsharp_highlight_rules\").FSharpHighlightRules;\n    var CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\n    var Mode = function () {\n        TextMode.call(this);\n        this.HighlightRules = FSharpHighlightRules;\n        this.foldingRules = new CStyleFoldMode();\n    };\n\n    oop.inherits(Mode, TextMode);\n\n\n    (function () {\n        this.lineCommentStart = \"//\";\n        this.blockComment = {start: \"(*\", end: \"*)\", nestable: true};\n\n\n        this.$id = \"ace/mode/fsharp\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/fsharp_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar FSharpHighlightRules = function () {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable\": \"this\",\n        \"keyword\": 'abstract|assert|base|begin|class|default|delegate|done|downcast|downto|elif\\\n|else|exception|extern|false|finally|function|global|inherit|inline|interface|internal|lazy|match\\\n|member|module|mutable|namespace|open|or|override|private|public|rec|return|return!|select|static\\\n|struct|then|to|true|try|typeof|upcast|use|use!|val|void|when|while|with|yield|yield!|__SOURCE_DIRECTORY__\\\n|as|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue\\\n|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall\\\n|trait|virtual|volatile|and|do|end|for|fun|if|in|let|let!|new|not|null|of|endif',\n        \"constant\": \"true|false\"\n    }, \"identifier\");\n\n    var floatNumber = \"(?:(?:(?:(?:(?:(?:\\\\d+)?(?:\\\\.\\\\d+))|(?:(?:\\\\d+)\\\\.))|(?:\\\\d+))(?:[eE][+-]?\\\\d+))|(?:(?:(?:\\\\d+)?(?:\\\\.\\\\d+))|(?:(?:\\\\d+)\\\\.)))\";\n\n    this.$rules = {\n        \"start\": [\n            {\n              token: \"variable.classes\",\n              regex: '\\\\[\\\\<[.]*\\\\>\\\\]'\n            },\n            {\n                token: \"comment\",\n                regex: '//.*$'\n            },\n            {\n                token: \"comment.start\",\n                regex: /\\(\\*(?!\\))/,\n                push: \"blockComment\"\n            },\n            {\n                token: \"string\",\n                regex: \"'.'\"\n            },\n            {\n                token: \"string\",\n                regex: '\"\"\"',\n                next  : [{\n                    token : \"constant.language.escape\",\n                    regex : /\\\\./,\n                    next  : \"qqstring\"\n                }, {\n                    token : \"string\",\n                    regex : '\"\"\"',\n                    next  : \"start\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            },\n            {\n                token: \"string\",\n                regex: '\"',\n                next  : [{\n                    token : \"constant.language.escape\",\n                    regex : /\\\\./,\n                    next  : \"qqstring\"\n                }, {\n                    token : \"string\",\n                    regex : '\"',\n                    next  : \"start\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            },\n            {\n                token: [\"verbatim.string\", \"string\"],\n                regex: '(@?)(\")',\n                stateName : \"qqstring\",\n                next  : [{\n                    token : \"constant.language.escape\",\n                    regex : '\"\"'\n                }, {\n                    token : \"string\",\n                    regex : '\"',\n                    next  : \"start\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            },\n            {\n                token: \"constant.float\",\n                regex: \"(?:\" + floatNumber + \"|\\\\d+)[jJ]\\\\b\"\n            },\n            {\n                token: \"constant.float\",\n                regex: floatNumber\n            },\n            {\n                token: \"constant.integer\",\n                regex: \"(?:(?:(?:[1-9]\\\\d*)|(?:0))|(?:0[oO]?[0-7]+)|(?:0[xX][\\\\dA-Fa-f]+)|(?:0[bB][01]+))\\\\b\"\n            },\n            {\n                token: [\"keyword.type\", \"variable\"],\n                regex: \"(type\\\\s)([a-zA-Z0-9_$\\-]*\\\\b)\"\n            },\n            {\n                token: keywordMapper,\n                regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            },\n            {\n                token: \"keyword.operator\",\n                regex: \"\\\\+\\\\.|\\\\-\\\\.|\\\\*\\\\.|\\\\/\\\\.|#|;;|\\\\+|\\\\-|\\\\*|\\\\*\\\\*\\\\/|\\\\/\\\\/|%|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|<-|=|\\\\(\\\\*\\\\)\"\n            },\n            {\n                token: \"paren.lparen\",\n                regex: \"[[({]\"\n            },\n            {\n                token: \"paren.rparen\",\n                regex: \"[\\\\])}]\"\n            }\n        ],\n        blockComment: [{\n            regex: /\\(\\*\\)/,\n            token: \"comment\"\n        }, {\n            regex: /\\(\\*(?!\\))/,\n            token: \"comment.start\",\n            push: \"blockComment\"\n        }, {\n            regex: /\\*\\)/,\n            token: \"comment.end\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }]\n    };\n    this.normalizeRules();\n};\n\n\noop.inherits(FSharpHighlightRules, TextHighlightRules);\n\nexports.FSharpHighlightRules = FSharpHighlightRules;\n"
  },
  {
    "path": "src/mode/fsl.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar FSLHighlightRules = require(\"./fsl_highlight_rules\").FSLHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = FSLHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/fsl\";\n    this.snippetFileId = \"ace/snippets/fsl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/fsl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar FSLHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"punctuation.definition.comment.mn\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"punctuation.definition.comment.mn\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.fsl\"\n            }]\n        }, {\n            token: \"comment.line.fsl\",\n            regex: /\\/\\//,\n            push: [{\n                token: \"comment.line.fsl\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.line.fsl\"\n            }]\n        }, {\n            token: \"entity.name.function\",\n            regex: /\\${/,\n            push: [{\n                token: \"entity.name.function\",\n                regex: /}/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"keyword.other\"\n            }],\n            comment: \"js outcalls\"\n        }, {\n            token: \"constant.numeric\",\n            regex: /[0-9]*\\.[0-9]*\\.[0-9]*/,\n            comment: \"semver\"\n        }, {\n            token: \"constant.language.fslLanguage\",\n            regex: \"(?:\"\n                + \"graph_layout|machine_name|machine_author|machine_license|machine_comment|machine_language\"\n                + \"|machine_version|machine_reference|npm_name|graph_layout|on_init|on_halt|on_end|on_terminate|on_finalize|on_transition\"\n                + \"|on_action|on_stochastic_action|on_legal|on_main|on_forced|on_validation|on_validation_failure|on_transition_refused|on_forced_transition_refused\"\n                + \"|on_action_refused|on_enter|on_exit|start_states|end_states|terminal_states|final_states|fsl_version\"\n                + \")\\\\s*:\"\n        }, {\n            token: \"keyword.control.transition.fslArrow\",\n            regex: /<->|<-|->|<=>|=>|<=|<~>|~>|<~|<-=>|<=->|<-~>|<~->|<=~>|<~=>/\n        }, {\n            token: \"constant.numeric.fslProbability\",\n            regex: /[0-9]+%/,\n            comment: \"edge probability annotation\"\n        }, {\n            token: \"constant.character.fslAction\",\n            regex: /\\'[^']*\\'/,\n            comment: \"action annotation\"\n        }, {\n            token: \"string.quoted.double.fslLabel.doublequoted\",\n            regex: /\\\"[^\"]*\\\"/,\n            comment: \"fsl label annotation\"\n        }, {\n            token: \"entity.name.tag.fslLabel.atom\",\n            regex: /[a-zA-Z0-9_.+&()#@!?,]/,\n            comment: \"fsl label annotation\"\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nFSLHighlightRules.metaData = {\n    fileTypes: [\"fsl\", \"fsl_state\"],\n    name: \"FSL\",\n    scopeName: \"source.fsl\"\n};\n\n\noop.inherits(FSLHighlightRules, TextHighlightRules);\n\nexports.FSLHighlightRules = FSLHighlightRules;\n"
  },
  {
    "path": "src/mode/ftl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar FtlHighlightRules = require(\"./ftl_highlight_rules\").FtlHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = FtlHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.$id = \"ace/mode/ftl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ftl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar FtlLangHighlightRules = function () {\n\n    var stringBuiltIns = \"\\\\?|substring|cap_first|uncap_first|capitalize|chop_linebreak|date|time|datetime|\"\n        + \"ends_with|html|groups|index_of|j_string|js_string|json_string|last_index_of|length|lower_case|\"\n        + \"left_pad|right_pad|contains|matches|number|replace|rtf|url|split|starts_with|string|trim|\"\n        + \"upper_case|word_list|xhtml|xml\";\n    var numberBuiltIns = \"c|round|floor|ceiling\";\n    var dateBuiltIns = \"iso_[a-z_]+\";\n    var seqBuiltIns = \"first|last|seq_contains|seq_index_of|seq_last_index_of|reverse|size|sort|sort_by|chunk\";\n    var hashBuiltIns = \"keys|values\";\n    var xmlBuiltIns = \"children|parent|root|ancestors|node_name|node_type|node_namespace\";\n    var expertBuiltIns = \"byte|double|float|int|long|short|number_to_date|number_to_time|number_to_datetime|\"\n        + \"eval|has_content|interpret|is_[a-z_]+|namespacenew\";\n    var allBuiltIns = stringBuiltIns + numberBuiltIns + dateBuiltIns + seqBuiltIns + hashBuiltIns\n        + xmlBuiltIns + expertBuiltIns;\n\n    var deprecatedBuiltIns = \"default|exists|if_exists|web_safe\";\n\n    var variables = \"data_model|error|globals|lang|locale|locals|main|namespace|node|current_node|\"\n        + \"now|output_encoding|template_name|url_escaping_charset|vars|version\";\n\n    var operators = \"gt|gte|lt|lte|as|in|using\";\n\n    var reserved = \"true|false\";\n\n    var attributes = \"encoding|parse|locale|number_format|date_format|time_format|datetime_format|time_zone|\"\n        + \"url_escaping_charset|classic_compatible|strip_whitespace|strip_text|strict_syntax|ns_prefixes|\"\n        + \"attributes\";\n\n    this.$rules = {\n        \"start\" : [{\n            token : \"constant.character.entity\",\n            regex : /&[^;]+;/\n        }, {\n            token : \"support.function\",\n            regex : \"\\\\?(\"+allBuiltIns+\")\"\n        },  {\n            token : \"support.function.deprecated\",\n            regex : \"\\\\?(\"+deprecatedBuiltIns+\")\"\n        }, {\n            token : \"language.variable\",\n            regex : \"\\\\.(?:\"+variables+\")\"\n        }, {\n            token : \"constant.language\",\n            regex : \"\\\\b(\"+reserved+\")\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\b(?:\"+operators+\")\\\\b\"\n        }, {\n            token : \"entity.other.attribute-name\",\n            regex : attributes\n        }, {\n            token : \"string\", //\n            regex : /['\"]/,\n            next : \"qstring\"\n        }, {\n            // Deal with variable names that contains number\n            // e.g. <#if var42 == 42 >\n            token : function(value) {\n                if (value.match(\"^[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?$\")) {\n                    return \"constant.numeric\";\n                } else {\n                    return \"variable\";\n                }\n            },\n            regex : /[\\w.+\\-]+/\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|\\\\.|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[[({]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }],\n\n        \"qstring\" : [{\n            token : \"constant.character.escape\",\n            regex : '\\\\\\\\[nrtvef\\\\\\\\\"$]'\n        }, {\n            token : \"string\",\n            regex : /['\"]/,\n            next : \"start\"\n        }, {\n            defaultToken : \"string\"\n        }]\n    };\n};\n\noop.inherits(FtlLangHighlightRules, TextHighlightRules);\n\nvar FtlHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    var directives = \"assign|attempt|break|case|compress|default|elseif|else|escape|fallback|function|flush|\"\n        + \"ftl|global|if|import|include|list|local|lt|macro|nested|noescape|noparse|nt|recover|recurse|return|rt|\"\n        + \"setting|stop|switch|t|visit\";\n\n    var startRules = [\n        {\n            token : \"comment\",\n            regex : \"<#--\",\n            next : \"ftl-dcomment\"\n        }, {\n            token : \"string.interpolated\",\n            regex : \"\\\\${\",\n            push  : \"ftl-start\"\n        }, {\n            token : \"keyword.function\",\n            regex :  \"</?#(\"+directives+\")\",\n            push : \"ftl-start\"\n        }, {\n            token : \"keyword.other\",\n            regex : \"</?@[a-zA-Z\\\\.]+\",\n            push : \"ftl-start\"\n        }\n    ];\n\n    var endRules = [\n        {\n           token : \"keyword\",\n            regex : \"/?>\",\n            next  : \"pop\"\n        }, {\n            token : \"string.interpolated\",\n            regex : \"}\",\n            next  : \"pop\"\n        }\n    ];\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n    this.embedRules(FtlLangHighlightRules, \"ftl-\", endRules, [\"start\"]);\n\n    this.addRules({\n        \"ftl-dcomment\" : [{\n            token : \"comment\",\n            regex : \"-->\",\n            next : \"pop\"\n        }, {\n            defaultToken : \"comment\"\n        }]\n    });\n\n    this.normalizeRules();\n};\n\noop.inherits(FtlHighlightRules, HtmlHighlightRules);\n\nexports.FtlHighlightRules = FtlHighlightRules;\n"
  },
  {
    "path": "src/mode/gcode.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextMode = require(\"./text\").Mode;\n    var GcodeHighlightRules = require(\"./gcode_highlight_rules\").GcodeHighlightRules;\n    var Range = require(\"../range\").Range;\n\n    var Mode = function() {\n        this.HighlightRules = GcodeHighlightRules;\n        this.$behaviour = this.$defaultBehaviour;\n    };\n    oop.inherits(Mode, TextMode);\n\n    (function() {\n        this.$id = \"ace/mode/gcode\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/gcode_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var GcodeHighlightRules = function() {\n\n        var keywords = (\n            \"IF|DO|WHILE|ENDWHILE|CALL|ENDIF|SUB|ENDSUB|GOTO|REPEAT|ENDREPEAT|CALL\"\n            );\n\n        var builtinConstants = (\n            \"PI\"\n            );\n\n        var builtinFunctions = (\n            \"ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN\"\n            );\n        var keywordMapper = this.createKeywordMapper({\n            \"support.function\": builtinFunctions,\n            \"keyword\": keywords,\n            \"constant.language\": builtinConstants\n        }, \"identifier\", true);\n\n        this.$rules = {\n            \"start\" : [ {\n                token : \"comment\",\n                regex : \"\\\\(.*\\\\)\"\n            }, {\n                token : \"comment\",           // block number\n                regex : \"([N])([0-9]+)\"\n            }, {\n                token : \"string\",           // \" string\n                regex : \"([G])([0-9]+\\\\.?[0-9]?)\"\n            }, {\n                token : \"string\",           // ' string\n                regex : \"([M])([0-9]+\\\\.?[0-9]?)\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"([-+]?([0-9]*\\\\.?[0-9]+\\\\.?))|(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\"\n            }, {\n                token : keywordMapper,\n                regex : \"[A-Z]\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"EQ|LT|GT|NE|GE|LE|OR|XOR\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[\\\\[]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\]]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            } ]\n        };\n    };\n\n    oop.inherits(GcodeHighlightRules, TextHighlightRules);\n\n    exports.GcodeHighlightRules = GcodeHighlightRules;\n"
  },
  {
    "path": "src/mode/gherkin.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar GherkinHighlightRules = require(\"./gherkin_highlight_rules\").GherkinHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = GherkinHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/gherkin\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        var space2 = \"  \";\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        \n        if(line.match(\"[ ]*\\\\|\")) {\n            indent += \"| \";\n        }\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n        \n\n        if (state == \"start\") {\n            if (line.match(\"Scenario:|Feature:|Scenario Outline:|Background:\")) {\n                indent += space2;\n            } else if(line.match(\"(Given|Then).+(:)$|Examples:\")) {\n                indent += space2;\n            } else if(line.match(\"\\\\*.+\")) {\n                indent += \"* \";\n            } \n        }\n        \n\n        return indent;\n    };\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/gherkin_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar stringEscape =  \"\\\\\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\\\\\abfnrtv'\\\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";\n\nvar GherkinHighlightRules = function() {\n    var languages = [{\n        name: \"en\",\n        labels: \"Feature|Background|Scenario(?: Outline)?|Examples\",\n        keywords: \"Given|When|Then|And|But\"\n    }\n    /* TODO find a way to enable this when first line in the file is # language: pl\n    , {\n        name: \"pl\",\n        labels: \"Właściwość|Funkcja|Aspekt|Potrzeba biznesowa|Założenia|Scenariusz|Szablon scenariusza|Przykłady\",\n        keywords: \"Mając|Zakładając(?:, że)?|Jeżeli|Jeśli|Gdy|Kiedy|Wtedy|Oraz|I|Ale\"\n    }\n    */];\n    \n    var labels = languages.map(function(l) {\n        return l.labels;\n    }).join(\"|\");\n    var keywords = languages.map(function(l) {\n        return l.keywords;\n    }).join(\"|\");\n    \n    // need to include constant ints\n    this.$rules = {\n        start : [{\n            token: \"constant.numeric\",\n            regex: \"(?:(?:[1-9]\\\\d*)|(?:0))\"\n        }, {\n            token : \"comment\",\n            regex : \"#.*$\"\n        }, {\n            token : \"keyword\",\n            regex : \"(?:\" + labels + \"):|(?:\" + keywords + \")\\\\b\"\n        }, {\n            token : \"keyword\",\n            regex : \"\\\\*\"\n        }, {\n            token : \"string\",           // multi line \"\"\" string start\n            regex : '\"{3}',\n            next : \"qqstring3\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\"',\n            next : \"qqstring\"\n        }, {\n            token : \"text\",\n            regex : \"^\\\\s*(?=@[\\\\w])\",\n            next : [{\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }, {\n                token : \"variable.parameter\",\n                regex : \"@[\\\\w]+\"\n            }, {\n                token : \"empty\",\n                regex : \"\",\n                next : \"start\"\n            }]\n        }, {\n            token : \"comment\",\n            regex : \"<[^>]+>\"\n        }, {\n            token : \"comment\",\n            regex : \"\\\\|(?=.)\",\n            next : \"table-item\"\n        }, {\n            token : \"comment\",\n            regex : \"\\\\|$\",\n            next : \"start\"\n        }],\n        \"qqstring3\" : [ {\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\", // multi line \"\"\" string end\n            regex : '\"{3}',\n            next : \"start\"\n        }, {\n            defaultToken : \"string\"\n        }],\n        \"qqstring\" : [{\n            token : \"constant.language.escape\",\n            regex : stringEscape\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        }, {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"table-item\" : [{\n            token : \"comment\",\n            regex : /$/,\n            next : \"start\"\n        }, {\n            token : \"comment\",\n            regex : /\\|/\n        }, {\n            token : \"string\",\n            regex : /\\\\./\n        }, {\n            defaultToken : \"string\"\n        }]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(GherkinHighlightRules, TextHighlightRules);\n\nexports.GherkinHighlightRules = GherkinHighlightRules;\n"
  },
  {
    "path": "src/mode/gitignore.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar GitignoreHighlightRules = require(\"./gitignore_highlight_rules\").GitignoreHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = GitignoreHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/gitignore\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/gitignore_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar GitignoreHighlightRules = function() {\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : /^\\s*#.*$/\n            }, {\n                token : \"keyword\", // negated patterns\n                regex : /^\\s*!.*$/\n            }\n        ]\n    };\n    \n    this.normalizeRules();\n};\n\nGitignoreHighlightRules.metaData = {\n    fileTypes: ['gitignore'],\n    name: 'Gitignore'\n};\n\noop.inherits(GitignoreHighlightRules, TextHighlightRules);\n\nexports.GitignoreHighlightRules = GitignoreHighlightRules;\n"
  },
  {
    "path": "src/mode/glsl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar CMode = require(\"./c_cpp\").Mode;\nvar glslHighlightRules = require(\"./glsl_highlight_rules\").glslHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = glslHighlightRules;\n    \n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, CMode);\n\n(function() {\n    this.$id = \"ace/mode/glsl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/glsl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar c_cppHighlightRules = require(\"./c_cpp_highlight_rules\").c_cppHighlightRules;\n\nvar glslHighlightRules = function() {\n\n    var keywords = (\n        \"attribute|const|uniform|varying|break|continue|do|for|while|\" +\n        \"if|else|in|out|inout|float|int|void|bool|true|false|\" +\n        \"lowp|mediump|highp|precision|invariant|discard|return|mat2|mat3|\" +\n        \"mat4|vec2|vec3|vec4|ivec2|ivec3|ivec4|bvec2|bvec3|bvec4|sampler2D|\" +\n        \"samplerCube|struct\"\n    );\n\n    var buildinConstants = (\n        \"radians|degrees|sin|cos|tan|asin|acos|atan|pow|\" +\n        \"exp|log|exp2|log2|sqrt|inversesqrt|abs|sign|floor|ceil|fract|mod|\" +\n        \"min|max|clamp|mix|step|smoothstep|length|distance|dot|cross|\" +\n        \"normalize|faceforward|reflect|refract|matrixCompMult|lessThan|\" +\n        \"lessThanEqual|greaterThan|greaterThanEqual|equal|notEqual|any|all|\" +\n        \"not|dFdx|dFdy|fwidth|texture2D|texture2DProj|texture2DLod|\" +\n        \"texture2DProjLod|textureCube|textureCubeLod|\" +\n        \"gl_MaxVertexAttribs|gl_MaxVertexUniformVectors|gl_MaxVaryingVectors|\" +\n        \"gl_MaxVertexTextureImageUnits|gl_MaxCombinedTextureImageUnits|\" +\n        \"gl_MaxTextureImageUnits|gl_MaxFragmentUniformVectors|gl_MaxDrawBuffers|\" +\n        \"gl_DepthRangeParameters|gl_DepthRange|\" +\n        // The following two are only for MIME x-shader/x-vertex.\n        \"gl_Position|gl_PointSize|\" +\n        // The following five are only for MIME x-shader/x-fragment.\n        \"gl_FragCoord|gl_FrontFacing|gl_PointCoord|gl_FragColor|gl_FragData\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants\n    }, \"identifier\");\n\n    this.$rules = new c_cppHighlightRules().$rules;\n    this.$rules.start.forEach(function(rule) {\n        if (typeof rule.token == \"function\")\n            rule.token = keywordMapper;\n    });\n};\n\noop.inherits(glslHighlightRules, c_cppHighlightRules);\n\nexports.glslHighlightRules = glslHighlightRules;\n"
  },
  {
    "path": "src/mode/gobstones.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar GobstonesHighlightRules = require(\"./gobstones_highlight_rules\").GobstonesHighlightRules;\n\nvar Mode = function() {\n    JavaScriptMode.call(this);\n    this.HighlightRules = GobstonesHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, JavaScriptMode);\n\n(function() {\n\n    this.createWorker = function() {\n        return null;\n    };\n\n    this.$id = \"ace/mode/gobstones\";\n    this.snippetFileId = \"ace/snippets/gobstones\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/gobstones_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar GobstonesHighlightRules = function() {\n\n  var definitions = {\n    standard: \"program|procedure|function|interactive|return|let\",\n    type: \"type|is|variant|record|field|case\"\n  };\n\n  var control = {\n    commands: {\n      repetitions: \"repeat|while|foreach|in\",\n      alternatives: \"if|elseif|else|switch\"\n    },\n    expressions: {\n      alternatives: \"choose|when|otherwise|matching|select|on\"\n    }\n  };\n\n  var values = {\n    colors: \"Verde|Rojo|Azul|Negro\",\n    cardinals: \"Norte|Sur|Este|Oeste\",\n    booleans: \"True|False\",\n    numbers: /([-]?)([0-9]+)\\b/,\n    strings: '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n  };\n\n  var primitives = {\n    commands: \"Poner|Sacar|Mover|IrAlBorde|VaciarTablero|BOOM\",\n    expressions: \"nroBolitas|hayBolitas|puedeMover|\"+\n                  \"siguiente|previo|opuesto|\"+\n                  \"minBool|maxBool|minDir|maxDir|minColor|maxColor|\"+\n                  \"primero|sinElPrimero|esVacía|\"+\n                  \"boom\",\n    keys: \"K_A|K_B|K_C|K_D|K_E|K_F|K_G|K_G|K_H|K_I|K_J|K_K|K_L|K_M|K_N|K_Ñ|\"+\n      \"K_O|K_P|K_Q|K_R|K_S|K_T|K_U|K_V|K_W|K_X|K_Y|K_Z|\"+\n      \"K_0|K_1|K_2|K_3|K_4|K_5|K_6|K_7|K_8|K_9|\"+\n      \"K_F1|K_F2|K_F3|K_F4|K_F5|K_F6|K_F7|K_F8|K_F9|K_F10|K_F11|K_12|\"+\n      \"K_UP|K_DOWN|K_LEFT|K_RIGHT|K_RETURN|K_BACKSPACE|K_TAB|K_SPACE|K_ESCAPE\"+\n\n      \"K_CTRL_A|K_CTRL_B|K_CTRL_C|K_CTRL_D|K_CTRL_E|K_CTRL_F|K_CTRL_G|K_CTRL_G|\"+\n      \"K_CTRL_H|K_CTRL_I|K_CTRL_J|K_CTRL_K|K_CTRL_L|K_CTRL_M|K_CTRL_N|K_CTRL_Ñ|\"+\n      \"K_CTRL_O|K_CTRL_P|K_CTRL_Q|K_CTRL_R|K_CTRL_S|K_CTRL_T|K_CTRL_U|K_CTRL_V|\"+\n      \"K_CTRL_W|K_CTRL_X|K_CTRL_Y|K_CTRL_Z|\"+\n      \"K_CTRL_0|K_CTRL_1|K_CTRL_2|K_CTRL_3|K_CTRL_4|K_CTRL_5|K_CTRL_6|K_CTRL_7|K_CTRL_8|K_CTRL_9|\"+\n      \"K_CTRL_F1|K_CTRL_F2|K_CTRL_F3|K_CTRL_F4|K_CTRL_F5|K_CTRL_F6|K_CTRL_F7|\"+\n      \"K_CTRL_F8|K_CTRL_F9|K_CTRL_F10|K_CTRL_F11|K_CTRL_F12|\"+\n      \"K_CTRL_UP|K_CTRL_DOWN|K_CTRL_LEFT|K_CTRL_RIGHT|K_CTRL_RETURN|\"+\n      \"K_CTRL_BACKSPACE|K_CTRL_TAB|K_CTRL_SPACE|K_CTRL_ESCAPE\"+\n\n      \"K_ALT_A|K_ALT_B|K_ALT_C|K_ALT_D|K_ALT_E|K_ALT_F|K_ALT_G|K_ALT_G|K_ALT_H|\"+\n      \"K_ALT_I|K_ALT_J|K_ALT_K|K_ALT_L|K_ALT_M|K_ALT_N|K_ALT_Ñ|K_ALT_O|K_ALT_P|\"+\n      \"K_ALT_Q|K_ALT_R|K_ALT_S|K_ALT_T|K_ALT_U|K_ALT_V|K_ALT_W|K_ALT_X|K_ALT_Y|K_ALT_Z|\"+\n      \"K_ALT_0|K_ALT_1|K_ALT_2|K_ALT_3|K_ALT_4|K_ALT_5|K_ALT_6|K_ALT_7|K_ALT_8|K_ALT_9|\"+\n      \"K_ALT_F1|K_ALT_F2|K_ALT_F3|K_ALT_F4|K_ALT_F5|K_ALT_F6|K_ALT_F7|K_ALT_F8|\"+\n      \"K_ALT_F9|K_ALT_F10|K_ALT_F11|K_ALT_F12|\"+\n      \"K_ALT_UP|K_ALT_DOWN|K_ALT_LEFT|K_ALT_RIGHT|K_ALT_RETURN|K_ALT_BACKSPACE|\"+\n      \"K_ALT_TAB|K_ALT_SPACE|K_ALT_ESCAPE\"+\n\n      \"K_SHIFT_A|K_SHIFT_B|K_SHIFT_C|K_SHIFT_D|K_SHIFT_E|K_SHIFT_F|K_SHIFT_G|\"+\n      \"K_SHIFT_G|K_SHIFT_H|K_SHIFT_I|K_SHIFT_J|K_SHIFT_K|K_SHIFT_L|K_SHIFT_M|\"+\n      \"K_SHIFT_N|K_SHIFT_Ñ|K_SHIFT_O|K_SHIFT_P|K_SHIFT_Q|K_SHIFT_R|K_SHIFT_S|\"+\n      \"K_SHIFT_T|K_SHIFT_U|K_SHIFT_V|K_SHIFT_W|K_SHIFT_X|K_SHIFT_Y|K_SHIFT_Z|\"+\n      \"K_SHIFT_0|K_SHIFT_1|K_SHIFT_2|K_SHIFT_3|K_SHIFT_4|K_SHIFT_5|K_SHIFT_6|\"+\n      \"K_SHIFT_7|K_SHIFT_8|K_SHIFT_9|\"+\n      \"K_SHIFT_F1|K_SHIFT_F2|K_SHIFT_F3|K_SHIFT_F4|K_SHIFT_F5|K_SHIFT_F6|\"+\n      \"K_SHIFT_F7|K_SHIFT_F8|K_SHIFT_F9|K_SHIFT_F10|K_SHIFT_F11|K_SHIFT_F12|\"+\n      \"K_SHIFT_UP|K_SHIFT_DOWN|K_SHIFT_LEFT|K_SHIFT_RIGHT|K_SHIFT_RETURN|\"+\n      \"K_SHIFT_BACKSPACE|K_SHIFT_TAB|K_SHIFT_SPACE|K_SHIFT_ESCAPE\"+\n\n      \"K_CTRL_ALT_A|K_CTRL_ALT_B|K_CTRL_ALT_C|K_CTRL_ALT_D|K_CTRL_ALT_E|\"+\n      \"K_CTRL_ALT_F|K_CTRL_ALT_G|K_CTRL_ALT_G|K_CTRL_ALT_H|K_CTRL_ALT_I|\"+\n      \"K_CTRL_ALT_J|K_CTRL_ALT_K|K_CTRL_ALT_L|K_CTRL_ALT_M|K_CTRL_ALT_N|\"+\n      \"K_CTRL_ALT_Ñ|K_CTRL_ALT_O|K_CTRL_ALT_P|K_CTRL_ALT_Q|K_CTRL_ALT_R|\"+\n      \"K_CTRL_ALT_S|K_CTRL_ALT_T|K_CTRL_ALT_U|K_CTRL_ALT_V|K_CTRL_ALT_W|\"+\n      \"K_CTRL_ALT_X|K_CTRL_ALT_Y|K_CTRL_ALT_Z|\"+\n      \"K_CTRL_ALT_0|K_CTRL_ALT_1|K_CTRL_ALT_2|K_CTRL_ALT_3|K_CTRL_ALT_4|\"+\n      \"K_CTRL_ALT_5|K_CTRL_ALT_6|K_CTRL_ALT_7|K_CTRL_ALT_8|K_CTRL_ALT_9|\"+\n      \"K_CTRL_ALT_F1|K_CTRL_ALT_F2|K_CTRL_ALT_F3|K_CTRL_ALT_F4|K_CTRL_ALT_F5|\"+\n      \"K_CTRL_ALT_F6|K_CTRL_ALT_F7|K_CTRL_ALT_F8|K_CTRL_ALT_F9|K_CTRL_ALT_F10|\"+\n      \"K_CTRL_ALT_F11|K_CTRL_ALT_F12|\"+\n      \"K_CTRL_ALT_UP|K_CTRL_ALT_DOWN|K_CTRL_ALT_LEFT|K_CTRL_ALT_RIGHT|\"+\n      \"K_CTRL_ALT_RETURN|K_CTRL_ALT_BACKSPACE|K_CTRL_ALT_TAB|K_CTRL_ALT_SPACE|K_CTRL_ALT_ESCAPE\"+\n\n      \"K_CTRL_SHIFT_A|K_CTRL_SHIFT_B|K_CTRL_SHIFT_C|K_CTRL_SHIFT_D|K_CTRL_SHIFT_E|\"+\n      \"K_CTRL_SHIFT_F|K_CTRL_SHIFT_G|K_CTRL_SHIFT_G|K_CTRL_SHIFT_H|K_CTRL_SHIFT_I|\"+\n      \"K_CTRL_SHIFT_J|K_CTRL_SHIFT_K|K_CTRL_SHIFT_L|K_CTRL_SHIFT_M|K_CTRL_SHIFT_N|\"+\n      \"K_CTRL_SHIFT_Ñ|K_CTRL_SHIFT_O|K_CTRL_SHIFT_P|K_CTRL_SHIFT_Q|K_CTRL_SHIFT_R|\"+\n      \"K_CTRL_SHIFT_S|K_CTRL_SHIFT_T|K_CTRL_SHIFT_U|K_CTRL_SHIFT_V|K_CTRL_SHIFT_W|\"+\n      \"K_CTRL_SHIFT_X|K_CTRL_SHIFT_Y|K_CTRL_SHIFT_Z|\"+\n      \"K_CTRL_SHIFT_0|K_CTRL_SHIFT_1|K_CTRL_SHIFT_2|K_CTRL_SHIFT_3|K_CTRL_SHIFT_4|\"+\n      \"K_CTRL_SHIFT_5|K_CTRL_SHIFT_6|K_CTRL_SHIFT_7|K_CTRL_SHIFT_8|K_CTRL_SHIFT_9|\"+\n      \"K_CTRL_SHIFT_F1|K_CTRL_SHIFT_F2|K_CTRL_SHIFT_F3|K_CTRL_SHIFT_F4|\"+\n      \"K_CTRL_SHIFT_F5|K_CTRL_SHIFT_F6|K_CTRL_SHIFT_F7|K_CTRL_SHIFT_F8|\"+\n      \"K_CTRL_SHIFT_9|K_CTRL_SHIFT_10|K_CTRL_SHIFT_11|K_CTRL_SHIFT_12|\"+\n      \"K_CTRL_SHIFT_UP|K_CTRL_SHIFT_DOWN|K_CTRL_SHIFT_LEFT|K_CTRL_SHIFT_RIGHT|\"+\n      \"K_CTRL_SHIFT_RETURN|K_CTRL_SHIFT_BACKSPACE|K_CTRL_SHIFT_TAB|\"+\n      \"K_CTRL_SHIFT_SPACE|K_CTRL_SHIFT_ESCAPE\"+\n\n      \"K_ALT_SHIFT_A|K_ALT_SHIFT_B|K_ALT_SHIFT_C|K_ALT_SHIFT_D|K_ALT_SHIFT_E|\"+\n      \"K_ALT_SHIFT_F|K_ALT_SHIFT_G|K_ALT_SHIFT_G|K_ALT_SHIFT_H|K_ALT_SHIFT_I|\"+\n      \"K_ALT_SHIFT_J|K_ALT_SHIFT_K|K_ALT_SHIFT_L|K_ALT_SHIFT_M|K_ALT_SHIFT_N|\"+\n      \"K_ALT_SHIFT_Ñ|K_ALT_SHIFT_O|K_ALT_SHIFT_P|K_ALT_SHIFT_Q|K_ALT_SHIFT_R|\"+\n      \"K_ALT_SHIFT_S|K_ALT_SHIFT_T|K_ALT_SHIFT_U|K_ALT_SHIFT_V|K_ALT_SHIFT_W|\"+\n      \"K_ALT_SHIFT_X|K_ALT_SHIFT_Y|K_ALT_SHIFT_Z|\"+\n      \"K_ALT_SHIFT_0|K_ALT_SHIFT_1|K_ALT_SHIFT_2|K_ALT_SHIFT_3|K_ALT_SHIFT_4|\"+\n      \"K_ALT_SHIFT_5|K_ALT_SHIFT_6|K_ALT_SHIFT_7|K_ALT_SHIFT_8|K_ALT_SHIFT_9|\"+\n      \"K_ALT_SHIFT_F1|K_ALT_SHIFT_F2|K_ALT_SHIFT_F3|K_ALT_SHIFT_F4|\"+\n      \"K_ALT_SHIFT_F5|K_ALT_SHIFT_F6|K_ALT_SHIFT_F7|K_ALT_SHIFT_F8|\"+\n      \"K_ALT_SHIFT_9|K_ALT_SHIFT_10|K_ALT_SHIFT_11|K_ALT_SHIFT_12|\"+\n      \"K_ALT_SHIFT_UP|K_ALT_SHIFT_DOWN|K_ALT_SHIFT_LEFT|K_ALT_SHIFT_RIGHT|\"+\n      \"K_ALT_SHIFT_RETURN|K_ALT_SHIFT_BACKSPACE|K_ALT_SHIFT_TAB|K_ALT_SHIFT_SPACE|\"+\n      \"K_ALT_SHIFT_ESCAPE\"+\n\n      \"K_CTRL_ALT_SHIFT_A|K_CTRL_ALT_SHIFT_B|K_CTRL_ALT_SHIFT_C|K_CTRL_ALT_SHIFT_D|\"+\n      \"K_CTRL_ALT_SHIFT_E|K_CTRL_ALT_SHIFT_F|K_CTRL_ALT_SHIFT_G|K_CTRL_ALT_SHIFT_G|\"+\n      \"K_CTRL_ALT_SHIFT_H|K_CTRL_ALT_SHIFT_I|K_CTRL_ALT_SHIFT_J|K_CTRL_ALT_SHIFT_K|\"+\n      \"K_CTRL_ALT_SHIFT_L|K_CTRL_ALT_SHIFT_M|K_CTRL_ALT_SHIFT_N|K_CTRL_ALT_SHIFT_Ñ|\"+\n      \"K_CTRL_ALT_SHIFT_O|K_CTRL_ALT_SHIFT_P|K_CTRL_ALT_SHIFT_Q|K_CTRL_ALT_SHIFT_R|\"+\n      \"K_CTRL_ALT_SHIFT_S|K_CTRL_ALT_SHIFT_T|K_CTRL_ALT_SHIFT_U|K_CTRL_ALT_SHIFT_V|\"+\n      \"K_CTRL_ALT_SHIFT_W|K_CTRL_ALT_SHIFT_X|K_CTRL_ALT_SHIFT_Y|K_CTRL_ALT_SHIFT_Z|\"+\n      \"K_CTRL_ALT_SHIFT_0|K_CTRL_ALT_SHIFT_1|K_CTRL_ALT_SHIFT_2|K_CTRL_ALT_SHIFT_3|\"+\n      \"K_CTRL_ALT_SHIFT_4|K_CTRL_ALT_SHIFT_5|K_CTRL_ALT_SHIFT_6|K_CTRL_ALT_SHIFT_7|\"+\n      \"K_CTRL_ALT_SHIFT_8|K_CTRL_ALT_SHIFT_9|\"+\n      \"K_CTRL_ALT_SHIFT_F1|K_CTRL_ALT_SHIFT_F2|K_CTRL_ALT_SHIFT_F3|K_CTRL_ALT_SHIFT_F4|\"+\n      \"K_CTRL_ALT_SHIFT_F5|K_CTRL_ALT_SHIFT_F6|K_CTRL_ALT_SHIFT_F7|K_CTRL_ALT_SHIFT_F8|\"+\n      \"K_CTRL_ALT_SHIFT_F9|K_CTRL_ALT_SHIFT_F10|K_CTRL_ALT_SHIFT_F11|K_CTRL_ALT_SHIFT_F12|\"+\n      \"K_CTRL_ALT_SHIFT_UP|K_CTRL_ALT_SHIFT_DOWN|K_CTRL_ALT_SHIFT_LEFT|K_CTRL_ALT_SHIFT_RIGHT|\"+\n      \"K_CTRL_ALT_SHIFT_RETURN|K_CTRL_ALT_SHIFT_BACKSPACE|K_CTRL_ALT_SHIFT_TAB|\"+\n      \"K_CTRL_ALT_SHIFT_SPACE|K_CTRL_ALT_SHIFT_ESCAPE\"\n  };\n\n  var operations = {\n    commands: \":=\",\n    expressions: {\n      numeric: \"\\\\+|\\\\-|\\\\*|\\\\^|div|mod\",\n      comparison: \">=|<=|==|\\\\/=|>|<\",\n      boolean: \"\\\\|\\\\||&&|not\",\n      other: \"\\\\+\\\\+|<\\\\-|\\\\[|\\\\]|\\\\_|\\\\->\"\n    }\n  };\n\n  var comments = {\n    line: {\n      double_slash: \"\\\\/\\\\/.*$\",\n      double_dash: \"\\\\-\\\\-.*$\",\n      number_sign: \"#.*$\"\n    },\n    block: { start: \"\\\\/\\\\*\", end: \"\\\\*\\\\/\" },\n    block_alt: { start: \"\\\\{\\\\-\", end: \"\\\\-\\\\}\" }\n  };\n\n  this.$rules = {\n    \"start\" : [\n      // comments\n      {\n        token : \"comment.line.double-slash.gobstones\",\n        regex : comments.line.double_slash\n      },\n      {\n        token : \"comment.line.double-dash.gobstones\",\n        regex : comments.line.double_dash\n      },\n      {\n        token : \"comment.line.number-sign.gobstones\",\n        regex : comments.line.number_sign\n      },\n      {\n        token : \"comment.block.dash-asterisc.gobstones\",\n        regex : comments.block.start,\n        next : \"block_comment_end\"\n      },\n      {\n        token : \"comment.block.brace-dash.gobstones\",\n        regex : comments.block_alt.start,\n        next : \"block_comment_alt_end\"\n      },\n      // numbers\n      {\n        token : \"constant.numeric.gobstones\",\n        regex : values.numbers\n      },\n      // strings\n      {\n        token : \"string.quoted.double.gobstones\",\n        regex : values.strings\n      },\n      //  operations\n      {\n        token : \"keyword.operator.other.gobstones\",\n        regex : operations.expressions.other\n      },\n      {\n        token : \"keyword.operator.numeric.gobstones\",\n        regex : operations.expressions.numeric\n      },\n      {\n        token : \"keyword.operator.compare.gobstones\",\n        regex : operations.expressions.comparison\n      },\n      {\n        token : \"keyword.operator.boolean.gobstones\",\n        regex : operations.expressions.boolean\n      },\n      // keywords\n      {\n        token : this.createKeywordMapper({\n          // basic constructs\n          \"storage.type.definitions.gobstones\": definitions.standard,\n          \"storage.type.types.gobstones\": definitions.type,\n          \"keyword.control.commands.repetitions.gobstones\": control.commands.repetitions,\n          \"keyword.control.commands.alternatives.gobstones\": control.commands.alternatives,\n          \"keyword.control.expressions.alternatives.gobstones\": control.expressions.alternatives,\n          // types\n          \"constant.language.colors.gobstones\":values.colors,\n          \"constant.language.cardinals.gobstones\": values.cardinals,\n          \"constant.language.boolean.gobstones\": values.booleans,\n          // primitives\n          \"support.function.gobstones\": primitives.commands,\n          \"support.variable.gobstones\": primitives.expressions,\n          \"variable.language.gobstones\": primitives.keys\n      }, \"identifier.gobstones\"),\n        regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n      },\n      {\n        token : \"comma.gobstones\",\n        regex : \",\"\n      },\n      {\n        token : \"semicolon.gobstones\",\n        regex : \";\"\n      },\n      {\n        token : \"lparen\",\n        regex : \"[[({]\"\n      },\n      {\n        token : \"rparen\",\n        regex : \"[\\\\])}]\"\n      },\n      {\n        token : \"text\",\n        regex : \"\\\\s+\"\n      }\n    ],\n    \"block_comment_end\": [{\n        token : \"comment.block.dash-asterisc.gobstones\",\n        regex : comments.block.end,\n        next : \"start\"\n      }, {\n        defaultToken : \"comment.block.dash-asterisc.gobstones\"\n      }\n    ],\n    \"block_comment_alt_end\": [{\n        token : \"comment.block.brace-dash.gobstones\",\n        regex : comments.block_alt.end,\n        next : \"start\"\n      }, {\n        defaultToken : \"comment.block.brace-dash.gobstones\"\n      }\n    ]\n  };\n};\n\noop.inherits(GobstonesHighlightRules, TextHighlightRules);\n\nexports.GobstonesHighlightRules = GobstonesHighlightRules;\n"
  },
  {
    "path": "src/mode/golang.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar GolangHighlightRules = require(\"./golang_highlight_rules\").GolangHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = GolangHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    \n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n        \n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };//end getNextLineIndent\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/golang\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/golang_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\n    var DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var GolangHighlightRules = function() {\n        var keywords = (\n            \"else|break|case|return|goto|if|const|select|\" +\n            \"continue|struct|default|switch|for|range|\" +\n            \"func|import|package|chan|defer|fallthrough|go|interface|map|range|\" +\n            \"select|type|var\"\n        );\n        var builtinTypes = (\n            \"string|uint8|uint16|uint32|uint64|int8|int16|int32|int64|float32|\" +\n            \"float64|complex64|complex128|byte|rune|uint|int|uintptr|bool|error\"\n        );\n        var builtinFunctions = (\n            \"new|close|cap|copy|panic|panicln|print|println|len|make|delete|real|recover|imag|append\"\n        );\n        var builtinConstants = (\"nil|true|false|iota\");\n\n        var keywordMapper = this.createKeywordMapper({\n            \"keyword\": keywords,\n            \"constant.language\": builtinConstants,\n            \"support.function\": builtinFunctions,\n            \"support.type\": builtinTypes\n        }, \"\");\n        \n        var stringEscapeRe = \"\\\\\\\\(?:[0-7]{3}|x\\\\h{2}|u{4}|U\\\\h{6}|[abfnrtv'\\\"\\\\\\\\])\".replace(/\\\\h/g, \"[a-fA-F\\\\d]\");\n\n        this.$rules = {\n            \"start\" : [\n                {\n                    token : \"comment\",\n                    regex : \"\\\\/\\\\/.*$\"\n                },\n                DocCommentHighlightRules.getStartRule(\"doc-start\"),\n                {\n                    token : \"comment.start\", // multi line comment\n                    regex : \"\\\\/\\\\*\",\n                    next : \"comment\"\n                }, {\n                    token : \"string\", // single line\n                    regex : /\"(?:[^\"\\\\]|\\\\.)*?\"/\n                }, {\n                    token : \"string\", // raw\n                    regex : '`',\n                    next : \"bqstring\"\n                }, {\n                    token : \"constant.numeric\", // rune\n                    regex : \"'(?:[^\\\\'\\uD800-\\uDBFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|\" + stringEscapeRe.replace('\"', '')  + \")'\"\n                }, {\n                    token : \"constant.numeric\", // hex\n                    regex : \"0[xX][0-9a-fA-F]+\\\\b\" \n                }, {\n                    token : \"constant.numeric\", // float\n                    regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n                }, {\n                    token : [\"keyword\", \"text\", \"entity.name.function\"],\n                    regex : \"(func)(\\\\s+)([a-zA-Z_$][a-zA-Z0-9_$]*)\\\\b\"\n                }, {\n                    token : function(val) {\n                        if (val[val.length - 1] == \"(\") {\n                            return [{\n                                type: keywordMapper(val.slice(0, -1)) || \"support.function\",\n                                value: val.slice(0, -1)\n                            }, {\n                                type: \"paren.lparen\",\n                                value: val.slice(-1)\n                            }];\n                        }\n                        \n                        return keywordMapper(val) || \"identifier\";\n                    },\n                    regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\\\\(?\"\n                }, {\n                    token : \"keyword.operator\",\n                    regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=\"\n                }, {\n                    token : \"punctuation.operator\",\n                    regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"\n                }, {\n                    token : \"paren.lparen\",\n                    regex : \"[[({]\"\n                }, {\n                    token : \"paren.rparen\",\n                    regex : \"[\\\\])}]\"\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }\n            ],\n            \"comment\" : [\n                {\n                    token : \"comment.end\",\n                    regex : \"\\\\*\\\\/\",\n                    next : \"start\"\n                }, {\n                    defaultToken : \"comment\"\n                }\n            ],\n            \"bqstring\" : [\n                {\n                    token : \"string\",\n                    regex : '`',\n                    next : \"start\"\n                }, {\n                    defaultToken : \"string\"\n                }\n            ]\n        };\n\n        this.embedRules(DocCommentHighlightRules, \"doc-\",\n            [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    };\n    oop.inherits(GolangHighlightRules, TextHighlightRules);\n\n    exports.GolangHighlightRules = GolangHighlightRules;\n"
  },
  {
    "path": "src/mode/graphqlschema.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar GraphQLSchemaHighlightRules = require(\"./graphqlschema_highlight_rules\").GraphQLSchemaHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = GraphQLSchemaHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/graphqlschema\";\n    this.snippetFileId = \"ace/snippets/graphqlschema\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/graphqlschema_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar GraphQLSchemaHighlightRules = function() {\n\n    var keywords = (\n      \"type|interface|union|enum|schema|input|implements|extends|scalar\"\n    );\n\n    var dataTypes = (\n      \"Int|Float|String|ID|Boolean\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"storage.type\": dataTypes\n    }, \"identifier\");\n\n    this.$rules = {\n      \"start\" : [ {\n        token : \"comment\",\n        regex : \"#.*$\"\n      }, {\n        token : \"paren.lparen\",\n        regex : /[\\[({]/,\n        next  : \"start\"\n      }, {\n        token : \"paren.rparen\",\n        regex : /[\\])}]/\n      }, {\n        token : keywordMapper,\n        regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n      } ]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(GraphQLSchemaHighlightRules, TextHighlightRules);\n\nexports.GraphQLSchemaHighlightRules = GraphQLSchemaHighlightRules;\n"
  },
  {
    "path": "src/mode/groovy.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar GroovyHighlightRules = require(\"./groovy_highlight_rules\").GroovyHighlightRules;\n\nvar Mode = function() {\n    JavaScriptMode.call(this);\n    this.HighlightRules = GroovyHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, JavaScriptMode);\n\n(function() {\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/groovy\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/groovy_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar GroovyHighlightRules = function() {\n\n    var keywords = (\n        \"assert|with|abstract|continue|for|new|switch|\" +\n        \"assert|default|goto|package|synchronized|\" +\n        \"boolean|do|if|private|this|\" +\n        \"break|double|implements|protected|throw|\" +\n        \"byte|else|import|public|throws|\" +\n        \"case|enum|instanceof|return|transient|\" +\n        \"catch|extends|int|short|try|\" +\n        \"char|final|interface|static|void|\" +\n        \"class|finally|long|strictfp|volatile|\" +\n        \"def|float|native|super|while\"\n    );\n\n    var buildinConstants = (\n        \"null|Infinity|NaN|undefined\"\n    );\n\n    var langClasses = (\n        \"AbstractMethodError|AssertionError|ClassCircularityError|\"+\n        \"ClassFormatError|Deprecated|EnumConstantNotPresentException|\"+\n        \"ExceptionInInitializerError|IllegalAccessError|\"+\n        \"IllegalThreadStateException|InstantiationError|InternalError|\"+\n        \"NegativeArraySizeException|NoSuchFieldError|Override|Process|\"+\n        \"ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|\"+\n        \"SuppressWarnings|TypeNotPresentException|UnknownError|\"+\n        \"UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|\"+\n        \"InstantiationException|IndexOutOfBoundsException|\"+\n        \"ArrayIndexOutOfBoundsException|CloneNotSupportedException|\"+\n        \"NoSuchFieldException|IllegalArgumentException|NumberFormatException|\"+\n        \"SecurityException|Void|InheritableThreadLocal|IllegalStateException|\"+\n        \"InterruptedException|NoSuchMethodException|IllegalAccessException|\"+\n        \"UnsupportedOperationException|Enum|StrictMath|Package|Compiler|\"+\n        \"Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|\"+\n        \"NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|\"+\n        \"NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|\"+\n        \"Character|Boolean|StackTraceElement|Appendable|StringBuffer|\"+\n        \"Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|\"+\n        \"StackOverflowError|OutOfMemoryError|VirtualMachineError|\"+\n        \"ArrayStoreException|ClassCastException|LinkageError|\"+\n        \"NoClassDefFoundError|ClassNotFoundException|RuntimeException|\"+\n        \"Exception|ThreadDeath|Error|Throwable|System|ClassLoader|\"+\n        \"Cloneable|Class|CharSequence|Comparable|String|Object\"\n    );\n\n    // TODO var importClasses = \"\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"support.function\": langClasses,\n        \"constant.language\": buildinConstants\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string.regexp\",\n                regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n            }, {\n                token : \"string\",\n                regex : '\"\"\"',\n                next  : \"qqstring\"\n            }, {\n                token : \"string\",\n                regex : \"'''\",\n                next  : \"qstring\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : keywordMapper,\n                // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"\\\\?:|\\\\?\\\\.|\\\\*\\\\.|<=>|=~|==~|\\\\.@|\\\\*\\\\.@|\\\\.&|as|in|is|!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token : \"lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:u[0-9A-Fa-f]{4}|.|$)/\n            }, {\n                token : \"constant.language.escape\",\n                regex : /\\$[\\w\\d]+/\n            }, {\n                token : \"constant.language.escape\",\n                regex : /\\$\\{[^\"\\}]+\\}?/\n            }, {\n                token : \"string\",\n                regex : '\"{3,5}',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+?'\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:u[0-9A-Fa-f]{4}|.|$)/\n            }, {\n                token : \"string\",\n                regex : \"'{3,5}\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : \".+?\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(GroovyHighlightRules, TextHighlightRules);\n\nexports.GroovyHighlightRules = GroovyHighlightRules;\n"
  },
  {
    "path": "src/mode/haml.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HamlHighlightRules = require(\"./haml_highlight_rules\").HamlHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HamlHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    \n    this.$id = \"ace/mode/haml\";\n    this.snippetFileId = \"ace/snippets/haml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/haml_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar RubyExports = require(\"./ruby_highlight_rules\");\nvar RubyHighlightRules = RubyExports.RubyHighlightRules;\n\nvar HamlHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    HtmlHighlightRules.call(this);\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"comment.block\", // multiline HTML comment\n                regex: /^\\/$/,\n                next: \"comment\"\n            },\n            {\n                token: \"comment.block\", // multiline HAML comment\n                regex: /^\\-#$/,\n                next: \"comment\"\n            },\n            {\n                token: \"comment.line\", // HTML comment\n                regex: /\\/\\s*.*/\n            },\n            {\n                token: \"comment.line\", // HAML comment\n                regex: /-#\\s*.*/\n            },\n            {\n                token: \"keyword.other.doctype\",\n                regex: \"^!!!\\\\s*(?:[a-zA-Z0-9-_]+)?\"\n            },\n            RubyExports.qString,\n            RubyExports.qqString,\n            RubyExports.tString,\n            {\n                token: \"meta.tag.haml\",\n                regex: /(%[\\w:\\-]+)/\n            },\n            {\n                token: \"keyword.attribute-name.class.haml\",\n                regex: /\\.[\\w-]+/\n            },\n            {\n                token: \"keyword.attribute-name.id.haml\",\n                regex: /#[\\w-]+/,\n                next: \"element_class\"\n            },\n            RubyExports.constantNumericHex,\n            RubyExports.constantNumericFloat,\n            RubyExports.constantOtherSymbol,\n            {\n                token: \"text\",\n                regex: /=|-|~/,\n                next: \"embedded_ruby\"\n            }\n        ],\n        \"element_class\": [\n            {\n                token: \"keyword.attribute-name.class.haml\",\n                regex: /\\.[\\w-]+/\n            },\n            {\n                token: \"punctuation.section\",\n                regex: /\\{/,\n                next: \"element_attributes\"\n            },\n            RubyExports.constantOtherSymbol,\n            {\n                token: \"empty\",\n                regex: \"$|(?!\\\\.|#|\\\\{|\\\\[|=|-|~|\\\\/])\",\n                next: \"start\"\n            }\n        ],\n        \"element_attributes\": [\n            RubyExports.constantOtherSymbol,\n            RubyExports.qString,\n            RubyExports.qqString,\n            RubyExports.tString,\n            RubyExports.constantNumericHex,\n            RubyExports.constantNumericFloat,\n            {\n                token: \"punctuation.section\",\n                regex: /$|\\}/,\n                next: \"start\"\n            }\n        ],\n        \"embedded_ruby\": [\n            RubyExports.constantNumericHex,\n            RubyExports.constantNumericFloat,\n            RubyExports.instanceVariable,\n            RubyExports.qString,\n            RubyExports.qqString,\n            RubyExports.tString,\n            {\n                token : \"support.class\", // class name\n                regex : \"[A-Z][a-zA-Z_\\\\d]+\"\n            },\n            {\n                token : new RubyHighlightRules().getKeywords(),\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            },\n            {\n                token : [\"keyword\", \"text\", \"text\"],\n                regex : \"(?:do|\\\\{)(?: \\\\|[^|]+\\\\|)?$\",\n                next  : \"start\"\n            },\n            {\n                token : [\"text\"],\n                regex : \"^$\",\n                next  : \"start\"\n            },\n            {\n                token : [\"text\"],\n                regex : \"^(?!.*\\\\|\\\\s*$)\",\n                next  : \"start\"\n            }\n        ],\n        \"comment\": [\n            {\n                token: \"comment.block\",\n                regex: /^$/,\n                next: \"start\"\n            },\n            {\n                token: \"comment.block\", // comment spanning the whole line\n                regex: /\\s+.*/\n            }\n        ]\n\n    };\n\n    this.normalizeRules();\n};\n\noop.inherits(HamlHighlightRules, HtmlHighlightRules);\n\nexports.HamlHighlightRules = HamlHighlightRules;\n"
  },
  {
    "path": "src/mode/handlebars.js",
    "content": "/* global define */\n\n  \"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar HandlebarsHighlightRules = require(\"./handlebars_highlight_rules\").HandlebarsHighlightRules;\nvar HtmlBehaviour = require(\"./behaviour/html\").HtmlBehaviour;\nvar HtmlFoldMode = require(\"./folding/html\").FoldMode;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = HandlebarsHighlightRules;\n    this.$behaviour = new HtmlBehaviour();\n};\n\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.blockComment = {start: \"{{!--\", end: \"--}}\"};\n    this.$id = \"ace/mode/handlebars\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/handlebars_highlight_rules.js",
    "content": "/* global define */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nfunction pop2(currentState, stack) {\n    stack.splice(0, 3);\n    return stack.shift() || \"start\";\n}\nvar HandlebarsHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    var hbs = {\n        regex : \"(?={{)\",\n        push : \"handlebars\"\n    };\n    for (var key in this.$rules) {\n        this.$rules[key].unshift(hbs);\n    }\n    this.$rules.handlebars = [{\n        token : \"comment.start\",\n        regex : \"{{!--\",\n        push : [{\n            token : \"comment.end\",\n            regex : \"--}}\",\n            next : pop2\n        }, {\n            defaultToken : \"comment\"\n        }]\n    }, {\n        token : \"comment.start\",\n        regex : \"{{!\",\n        push : [{\n            token : \"comment.end\",\n            regex : \"}}\",\n            next : pop2\n        }, {\n            defaultToken : \"comment\"\n        }]\n    }, {\n        token : \"support.function\", // unescaped variable\n        regex : \"{{{\",\n        push : [{\n            token : \"support.function\",\n            regex : \"}}}\",\n            next : pop2\n        }, {\n            token : \"variable.parameter\",\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\"\n        }]\n    }, {\n        token : \"storage.type.start\", // begin section\n        regex : \"{{[#\\\\^/&]?\",\n        push : [{\n            token : \"storage.type.end\",\n            regex : \"}}\",\n            next : pop2\n        }, {\n            token : \"variable.parameter\",\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\"\n        }]\n    }];\n\n    this.normalizeRules();\n};\n\noop.inherits(HandlebarsHighlightRules, HtmlHighlightRules);\n\nexports.HandlebarsHighlightRules = HandlebarsHighlightRules;\n"
  },
  {
    "path": "src/mode/haskell.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HaskellHighlightRules = require(\"./haskell_highlight_rules\").HaskellHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HaskellHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/haskell\";\n    this.snippetFileId = \"ace/snippets/haskell\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/haskell_cabal.js",
    "content": "/**\n* Haskell Cabal files mode (https://www.haskell.org/cabal/users-guide/developing-packages.html)\n**/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CabalHighlightRules = require(\"./haskell_cabal_highlight_rules\").CabalHighlightRules;\nvar FoldMode = require(\"./folding/haskell_cabal\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = CabalHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/haskell_cabal\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/haskell_cabal_highlight_rules.js",
    "content": "/**\n * Haskell Cabal files highlighter (https://www.haskell.org/cabal/users-guide/developing-packages.html)\n **/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar CabalHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"^\\\\s*--.*$\"\n            }, {\n                token: [\"keyword\"],\n                regex: /^(\\s*\\w.*?)(:(?:\\s+|$))/\n            }, {\n                token : \"constant.numeric\", // float\n                regex : /[\\d_]+(?:(?:[\\.\\d_]*)?)/\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false|TRUE|FALSE|True|False|yes|no)\\\\b\"\n            }, {\n                token : \"markup.heading\",\n                regex : /^(\\w.*)$/\n            }\n        ]};\n\n};\n\noop.inherits(CabalHighlightRules, TextHighlightRules);\n\nexports.CabalHighlightRules = CabalHighlightRules;\n"
  },
  {
    "path": "src/mode/haskell_highlight_rules.js",
    "content": "/* This file was autogenerated from tm bundles\\haskell.tmbundle\\Syntaxes\\Haskell.plist (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar HaskellHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start:\n       [ { token:\n            [ 'punctuation.definition.entity.haskell',\n              'keyword.operator.function.infix.haskell',\n              'punctuation.definition.entity.haskell' ],\n           regex: '(`)([a-zA-Z_\\']*?)(`)',\n           comment: 'In case this regex seems unusual for an infix operator, note that Haskell allows any ordinary function application (elem 4 [1..10]) to be rewritten as an infix expression (4 `elem` [1..10]).' },\n         { token: 'constant.language.unit.haskell', regex: '\\\\(\\\\)' },\n         { token: 'constant.language.empty-list.haskell',\n           regex: '\\\\[\\\\]' },\n         { token: 'keyword.other.haskell',\n           regex: '\\\\b(module|signature)\\\\b',\n           push:\n            [ { token: 'keyword.other.haskell', regex: '\\\\bwhere\\\\b', next: 'pop' },\n              { include: '#module_name' },\n              { include: '#module_exports' },\n              { token: 'invalid', regex: '[a-z]+' },\n              { defaultToken: 'meta.declaration.module.haskell' } ] },\n         { token: 'keyword.other.haskell',\n           regex: '\\\\bclass\\\\b',\n           push:\n            [ { token: 'keyword.other.haskell',\n                regex: '\\\\bwhere\\\\b',\n                next: 'pop' },\n              { token: 'support.class.prelude.haskell',\n                regex: '\\\\b(?:Monad|Functor|Eq|Ord|Read|Show|Num|(?:Frac|Ra)tional|Enum|Bounded|Real(?:Frac|Float)?|Integral|Floating)\\\\b' },\n              { token: 'entity.other.inherited-class.haskell',\n                regex: '[A-Z][A-Za-z_\\']*' },\n              { token: 'variable.other.generic-type.haskell',\n                regex: '\\\\b[a-z][a-zA-Z0-9_\\']*\\\\b' },\n              { defaultToken: 'meta.declaration.class.haskell' } ] },\n         { token: 'keyword.other.haskell',\n           regex: '\\\\binstance\\\\b',\n           push:\n            [ { token: 'keyword.other.haskell',\n                regex: '\\\\bwhere\\\\b|$',\n                next: 'pop' },\n              { include: '#type_signature' },\n              { defaultToken: 'meta.declaration.instance.haskell' } ] },\n         { token: 'keyword.other.haskell',\n           regex: 'import',\n           push:\n            [ { token: 'meta.import.haskell', regex: '$|;|^', next: 'pop' },\n              { token: 'keyword.other.haskell', regex: 'qualified|as|hiding' },\n              { include: '#module_name' },\n              { include: '#module_exports' },\n              { defaultToken: 'meta.import.haskell' } ] },\n         { token: [ 'keyword.other.haskell', 'meta.deriving.haskell' ],\n           regex: '(deriving)(\\\\s*\\\\()',\n           push:\n            [ { token: 'meta.deriving.haskell', regex: '\\\\)', next: 'pop' },\n              { token: 'entity.other.inherited-class.haskell',\n                regex: '\\\\b[A-Z][a-zA-Z_\\']*' },\n              { defaultToken: 'meta.deriving.haskell' } ] },\n         { token: 'keyword.other.haskell',\n           regex: '\\\\b(?:deriving|where|data|type|case|of|let|in|newtype|default)\\\\b' },\n         { token: 'keyword.operator.haskell', regex: '\\\\binfix[lr]?\\\\b' },\n         { token: 'keyword.control.haskell',\n           regex: '\\\\b(?:do|if|then|else)\\\\b' },\n         { token: 'constant.numeric.float.haskell',\n           regex: '\\\\b(?:[0-9]+\\\\.[0-9]+(?:[eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\\\\b',\n           comment: 'Floats are always decimal' },\n         { token: 'constant.numeric.haskell',\n           regex: '\\\\b(?:[0-9]+|0(?:[xX][0-9a-fA-F]+|[oO][0-7]+))\\\\b' },\n         { token:\n            [ 'meta.preprocessor.c',\n              'punctuation.definition.preprocessor.c',\n              'meta.preprocessor.c' ],\n           regex: '^(\\\\s*)(#)(\\\\s*\\\\w+)',\n           comment: 'In addition to Haskell\\'s \"native\" syntax, GHC permits the C preprocessor to be run on a source file.' },\n         { include: '#pragma' },\n         { token: 'punctuation.definition.string.begin.haskell',\n           regex: '\"',\n           push:\n            [ { token: 'punctuation.definition.string.end.haskell',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.haskell',\n                regex: '\\\\\\\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\\\\\\\\\\\"\\'\\\\&])' },\n              { token: 'constant.character.escape.octal.haskell',\n                regex: '\\\\\\\\o[0-7]+|\\\\\\\\x[0-9A-Fa-f]+|\\\\\\\\[0-9]+' },\n              { token: 'constant.character.escape.control.haskell',\n                regex: '\\\\^[A-Z@\\\\[\\\\]\\\\\\\\\\\\^_]' },\n              { defaultToken: 'string.quoted.double.haskell' } ] },\n         { token:\n            [ 'punctuation.definition.string.begin.haskell',\n              'string.quoted.single.haskell',\n              'constant.character.escape.haskell',\n              'constant.character.escape.octal.haskell',\n              'constant.character.escape.hexadecimal.haskell',\n              'constant.character.escape.control.haskell',\n              'punctuation.definition.string.end.haskell' ],\n           regex: '(\\')(?:([\\\\ -\\\\[\\\\]-~])|(\\\\\\\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\\\\\\\\\\\"\\'\\\\&]))|(\\\\\\\\o[0-7]+)|(\\\\\\\\x[0-9A-Fa-f]+)|(\\\\^[A-Z@\\\\[\\\\]\\\\\\\\\\\\^_]))(\\')' },\n         { token:\n            [ 'meta.function.type-declaration.haskell',\n              'entity.name.function.haskell',\n              'meta.function.type-declaration.haskell',\n              'keyword.other.double-colon.haskell' ],\n           regex: '^(\\\\s*)([a-z_][a-zA-Z0-9_\\']*|\\\\([|!%$+\\\\-.,=</>]+\\\\))(\\\\s*)(::)',\n           push:\n            [ { token: 'meta.function.type-declaration.haskell',\n                regex: '$',\n                next: 'pop' },\n              { include: '#type_signature' },\n              { defaultToken: 'meta.function.type-declaration.haskell' } ] },\n         { token: 'support.constant.haskell',\n           regex: '\\\\b(?:Just|Nothing|Left|Right|True|False|LT|EQ|GT|\\\\(\\\\)|\\\\[\\\\])\\\\b' },\n         { token: 'constant.other.haskell', regex: '\\\\b[A-Z]\\\\w*\\\\b' },\n         { include: '#comments' },\n         { token: 'support.function.prelude.haskell',\n           regex: '\\\\b(?:abs|acos|acosh|all|and|any|appendFile|applyM|asTypeOf|asin|asinh|atan|atan2|atanh|break|catch|ceiling|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|div|divMod|drop|dropWhile|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromEnum|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|head|id|init|interact|ioError|isDenormalized|isIEEE|isInfinite|isNaN|isNegativeZero|iterate|last|lcm|length|lex|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|odd|or|otherwise|pi|pred|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|read|readFile|readIO|readList|readLn|readParen|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showList|showParen|showString|shows|showsPrec|significand|signum|sin|sinh|snd|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|toEnum|toInteger|toRational|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\\\\b' },\n         { include: '#infix_op' },\n         { token: 'keyword.operator.haskell',\n           regex: '[|!%$?~+:\\\\-.=</>\\\\\\\\]+',\n           comment: 'In case this regex seems overly general, note that Haskell permits the definition of new operators which can be nearly any string of punctuation characters, such as $%^&*.' },\n         { token: 'punctuation.separator.comma.haskell', regex: ',' } ],\n      '#block_comment':\n       [ { token: 'punctuation.definition.comment.haskell',\n           regex: '\\\\{-(?!#)',\n           push:\n            [ { include: '#block_comment' },\n              { token: 'punctuation.definition.comment.haskell',\n                regex: '-\\\\}',\n                next: 'pop' },\n              { defaultToken: 'comment.block.haskell' } ] } ],\n      '#comments':\n       [ { token: 'punctuation.definition.comment.haskell',\n           regex: '--.*',\n           push_:\n            [ { token: 'comment.line.double-dash.haskell',\n                regex: '$',\n                next: 'pop' },\n              { defaultToken: 'comment.line.double-dash.haskell' } ] },\n         { include: '#block_comment' } ],\n      '#infix_op':\n       [ { token: 'entity.name.function.infix.haskell',\n           regex: '\\\\([|!%$+:\\\\-.=</>]+\\\\)|\\\\(,+\\\\)' } ],\n      '#module_exports':\n       [ { token: 'meta.declaration.exports.haskell',\n           regex: '\\\\(',\n           push:\n            [ { token: 'meta.declaration.exports.haskell.end',\n                regex: '\\\\)',\n                next: 'pop' },\n              { token: 'entity.name.function.haskell',\n                regex: '\\\\b[a-z][a-zA-Z_\\']*' },\n              { token: 'storage.type.haskell', regex: '\\\\b[A-Z][A-Za-z_\\']*' },\n              { token: 'punctuation.separator.comma.haskell', regex: ',' },\n              { include: '#infix_op' },\n              { token: 'meta.other.unknown.haskell',\n                regex: '\\\\(.*?\\\\)',\n                comment: 'So named because I don\\'t know what to call this.' },\n              { defaultToken: 'meta.declaration.exports.haskell.end' } ] } ],\n      '#module_name':\n       [ { token: 'support.other.module.haskell',\n           regex: '[A-Z][A-Za-z._\\']*' } ],\n      '#pragma':\n       [ { token: 'meta.preprocessor.haskell',\n           regex: '\\\\{-#',\n           push:\n            [ { token: 'meta.preprocessor.haskell',\n                regex: '#-\\\\}',\n                next: 'pop' },\n              { token: 'keyword.other.preprocessor.haskell',\n                regex: '\\\\b(?:LANGUAGE|UNPACK|INLINE)\\\\b' },\n              { defaultToken: 'meta.preprocessor.haskell' } ] } ],\n      '#type_signature':\n       [ { token:\n            [ 'meta.class-constraint.haskell',\n              'entity.other.inherited-class.haskell',\n              'meta.class-constraint.haskell',\n              'variable.other.generic-type.haskell',\n              'meta.class-constraint.haskell',\n              'keyword.other.big-arrow.haskell' ],\n           regex: '(\\\\(\\\\s*)([A-Z][A-Za-z]*)(\\\\s+)([a-z][A-Za-z_\\']*)(\\\\)\\\\s*)(=>)' },\n         { include: '#pragma' },\n         { token: 'keyword.other.arrow.haskell', regex: '->' },\n         { token: 'keyword.other.big-arrow.haskell', regex: '=>' },\n         { token: 'support.type.prelude.haskell',\n           regex: '\\\\b(?:Int(?:eger)?|Maybe|Either|Bool|Float|Double|Char|String|Ordering|ShowS|ReadS|FilePath|IO(?:Error)?)\\\\b' },\n         { token: 'variable.other.generic-type.haskell',\n           regex: '\\\\b[a-z][a-zA-Z0-9_\\']*\\\\b' },\n         { token: 'storage.type.haskell',\n           regex: '\\\\b[A-Z][a-zA-Z0-9_\\']*\\\\b' },\n         { token: 'support.constant.unit.haskell', regex: '\\\\(\\\\)' },\n         { include: '#comments' } ] };\n\n    this.normalizeRules();\n};\n\nHaskellHighlightRules.metaData = { fileTypes: [ 'hs' ],\n      keyEquivalent: '^~H',\n      name: 'Haskell',\n      scopeName: 'source.haskell' };\n\n\noop.inherits(HaskellHighlightRules, TextHighlightRules);\n\nexports.HaskellHighlightRules = HaskellHighlightRules;\n"
  },
  {
    "path": "src/mode/haxe.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HaxeHighlightRules = require(\"./haxe_highlight_rules\").HaxeHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HaxeHighlightRules;\n    \n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/haxe\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/haxe_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar HaxeHighlightRules = function() {\n\n    var keywords = (\n        \"break|case|cast|catch|class|continue|default|else|enum|extends|for|function|if|implements|import|in|inline|interface|new|override|package|private|public|return|static|super|switch|this|throw|trace|try|typedef|untyped|var|while|Array|Void|Bool|Int|UInt|Float|Dynamic|String|List|Hash|IntHash|Error|Unknown|Type|Std\"\n    );\n\n    var buildinConstants = (\n        \"null|true|false\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string.regexp\",\n                regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : keywordMapper,\n                // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({<]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}>]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(HaxeHighlightRules, TextHighlightRules);\n\nexports.HaxeHighlightRules = HaxeHighlightRules;\n"
  },
  {
    "path": "src/mode/hjson.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HjsonHighlightRules = require(\"./hjson_highlight_rules\").HjsonHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HjsonHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = { start: \"/*\", end: \"*/\" };\n    this.$id = \"ace/mode/hjson\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/hjson_highlight_rules.js",
    "content": "/* This file was autogenerated from Hjson.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar HjsonHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            include: \"#comments\"\n        }, {\n            include: \"#rootObject\"\n        }, {\n            include: \"#value\"\n        }],\n        \"#array\": [{\n            token: \"paren.lparen\",\n            regex: /\\[/,\n            push: [{\n                token: \"paren.rparen\",\n                regex: /\\]/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                include: \"#comments\"\n            }, {\n                token: \"text\",\n                regex: /,|$/\n            }, {\n                token: \"invalid.illegal\",\n                regex: /[^\\s\\]]/\n            }, {\n                defaultToken: \"array\"\n            }]\n        }],\n        \"#comments\": [{\n            token: [\n                \"comment.punctuation\",\n                \"comment.line\"\n            ],\n            regex: /(#)(.*$)/\n        }, {\n            token: \"comment.punctuation\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"comment.punctuation\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block\"\n            }]\n        }, {\n            token: [\n                \"comment.punctuation\",\n                \"comment.line\"\n            ],\n            regex: /(\\/\\/)(.*$)/\n        }],\n        \"#constant\": [{\n            token: \"constant\",\n            regex: /\\b(?:true|false|null)\\b/\n        }],\n        \"#keyname\": [{\n            token: \"keyword\",\n            regex: /(?:[^,\\{\\[\\}\\]\\s]+|\"(?:[^\"\\\\]|\\\\.)*\")\\s*(?=:)/\n        }],\n        \"#mstring\": [{\n            token: \"string\",\n            regex: /'''/,\n            push: [{\n                token: \"string\",\n                regex: /'''/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }],\n        \"#number\": [{\n            token: \"constant.numeric\",\n            regex: /-?(?:0|[1-9]\\d*)(?:(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)?/,\n            comment: \"handles integer and decimal numbers\"\n        }],\n        \"#object\": [{\n            token: \"paren.lparen\",\n            regex: /\\{/,\n            push: [{\n                token: \"paren.rparen\",\n                regex: /\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#keyname\"\n            }, {\n                include: \"#value\"\n            }, {\n                token: \"text\",\n                regex: /:/\n            }, {\n                token: \"text\",\n                regex: /,/\n            }, {\n                defaultToken: \"paren\"\n            }]\n        }],\n        \"#rootObject\": [{\n            token: \"paren\",\n            regex: /(?=\\s*(?:[^,\\{\\[\\}\\]\\s]+|\"(?:[^\"\\\\]|\\\\.)*\")\\s*:)/,\n            push: [{\n                token: \"paren.rparen\",\n                regex: /---none---/,\n                next: \"pop\"\n            }, {\n                include: \"#keyname\"\n            }, {\n                include: \"#value\"\n            }, {\n                token: \"text\",\n                regex: /:/\n            }, {\n                token: \"text\",\n                regex: /,/\n            }, {\n                defaultToken: \"paren\"\n            }]\n        }],\n        \"#string\": [{\n            token: \"string\",\n            regex: /\"/,\n            push: [{\n                token: \"string\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/\n            }, {\n                token: \"invalid.illegal\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string\"\n            }]\n        }],\n        \"#ustring\": [{\n            token: \"string\",\n            regex: /\\b[^:,0-9\\-\\{\\[\\}\\]\\s].*$/\n        }],\n        \"#value\": [{\n            include: \"#constant\"\n        }, {\n            include: \"#number\"\n        }, {\n            include: \"#string\"\n        }, {\n            include: \"#array\"\n        }, {\n            include: \"#object\"\n        }, {\n            include: \"#comments\"\n        }, {\n            include: \"#mstring\"\n        }, {\n            include: \"#ustring\"\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nHjsonHighlightRules.metaData = {\n    fileTypes: [\"hjson\"],\n    foldingStartMarker: \"(?x:     # turn on extended mode\\n              ^    # a line beginning with\\n              \\\\s*    # some optional space\\n              [{\\\\[]  # the start of an object or array\\n              (?!    # but not followed by\\n              .*   # whatever\\n              [}\\\\]]  # and the close of an object or array\\n              ,?   # an optional comma\\n              \\\\s*  # some optional space\\n              $    # at the end of the line\\n              )\\n              |    # ...or...\\n              [{\\\\[]  # the start of an object or array\\n              \\\\s*    # some optional space\\n              $    # at the end of the line\\n            )\",\n    foldingStopMarker: \"(?x:   # turn on extended mode\\n             ^    # a line beginning with\\n             \\\\s*  # some optional space\\n             [}\\\\]]  # and the close of an object or array\\n             )\",\n    keyEquivalent: \"^~J\",\n    name: \"Hjson\",\n    scopeName: \"source.hjson\"\n};\n\n\noop.inherits(HjsonHighlightRules, TextHighlightRules);\n\nexports.HjsonHighlightRules = HjsonHighlightRules;\n"
  },
  {
    "path": "src/mode/html.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextMode = require(\"./text\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar CssMode = require(\"./css\").Mode;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar XmlBehaviour = require(\"./behaviour/xml\").XmlBehaviour;\nvar HtmlFoldMode = require(\"./folding/html\").FoldMode;\nvar HtmlCompletions = require(\"./html_completions\").HtmlCompletions;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\n\n// http://www.w3.org/TR/html5/syntax.html#void-elements\nvar voidElements = [\"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"menuitem\", \"param\", \"source\", \"track\", \"wbr\"];\nvar optionalEndTags = [\"li\", \"dt\", \"dd\", \"p\", \"rt\", \"rp\", \"optgroup\", \"option\", \"colgroup\", \"td\", \"th\"];\n\nvar Mode = function(options) {\n    this.fragmentContext = options && options.fragmentContext;\n    this.HighlightRules = HtmlHighlightRules;\n    this.$behaviour = new XmlBehaviour();\n    this.$completer = new HtmlCompletions();\n    \n    this.createModeDelegates({\n        \"js-\": JavaScriptMode,\n        \"css-\": CssMode\n    });\n    \n    this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags));\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.blockComment = {start: \"<!--\", end: \"-->\"};\n\n    this.voidElements = lang.arrayToMap(voidElements);\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return false;\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        return this.$completer.getCompletions(state, session, pos, prefix);\n    };\n\n    this.createWorker = function(session) {\n        if (this.constructor != Mode)\n            return;\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/html_worker\", \"Worker\");\n        worker.attachToDocument(session.getDocument());\n\n        if (this.fragmentContext)\n            worker.call(\"setOptions\", [{context: this.fragmentContext}]);\n\n        worker.on(\"error\", function(e) {\n            session.setAnnotations(e.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n    this.$id = \"ace/mode/html\";\n    this.snippetFileId = \"ace/snippets/html\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/html_completions.js",
    "content": "\"use strict\";\n\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\n\nvar commonAttributes = [\n    \"accesskey\",\n    \"class\",\n    \"contenteditable\",\n    \"contextmenu\",\n    \"dir\",\n    \"draggable\",\n    \"dropzone\",\n    \"hidden\",\n    \"id\",\n    \"inert\",\n    \"itemid\",\n    \"itemprop\",\n    \"itemref\",\n    \"itemscope\",\n    \"itemtype\",\n    \"lang\",\n    \"spellcheck\",\n    \"style\",\n    \"tabindex\",\n    \"title\",\n    \"translate\"\n];\n\nvar eventAttributes = [\n    \"onabort\",\n    \"onblur\",\n    \"oncancel\",\n    \"oncanplay\",\n    \"oncanplaythrough\",\n    \"onchange\",\n    \"onclick\",\n    \"onclose\",\n    \"oncontextmenu\",\n    \"oncuechange\",\n    \"ondblclick\",\n    \"ondrag\",\n    \"ondragend\",\n    \"ondragenter\",\n    \"ondragleave\",\n    \"ondragover\",\n    \"ondragstart\",\n    \"ondrop\",\n    \"ondurationchange\",\n    \"onemptied\",\n    \"onended\",\n    \"onerror\",\n    \"onfocus\",\n    \"oninput\",\n    \"oninvalid\",\n    \"onkeydown\",\n    \"onkeypress\",\n    \"onkeyup\",\n    \"onload\",\n    \"onloadeddata\",\n    \"onloadedmetadata\",\n    \"onloadstart\",\n    \"onmousedown\",\n    \"onmousemove\",\n    \"onmouseout\",\n    \"onmouseover\",\n    \"onmouseup\",\n    \"onmousewheel\",\n    \"onpause\",\n    \"onplay\",\n    \"onplaying\",\n    \"onprogress\",\n    \"onratechange\",\n    \"onreset\",\n    \"onscroll\",\n    \"onseeked\",\n    \"onseeking\",\n    \"onselect\",\n    \"onshow\",\n    \"onstalled\",\n    \"onsubmit\",\n    \"onsuspend\",\n    \"ontimeupdate\",\n    \"onvolumechange\",\n    \"onwaiting\"\n];\n\nvar globalAttributes = commonAttributes.concat(eventAttributes);\n\nvar attributeMap = {\n    \"a\": {\"href\": 1, \"target\": {\"_blank\": 1, \"top\": 1}, \"ping\": 1, \"rel\": {\"nofollow\": 1, \"alternate\": 1, \"author\": 1, \"bookmark\": 1, \"help\": 1, \"license\": 1, \"next\": 1, \"noreferrer\": 1, \"prefetch\": 1, \"prev\": 1, \"search\": 1, \"tag\": 1}, \"media\": 1, \"hreflang\": 1, \"type\": 1},\n    \"abbr\": {},\n    \"address\": {},\n    \"area\": {\"shape\": 1, \"coords\": 1, \"href\": 1, \"hreflang\": 1, \"alt\": 1, \"target\": 1, \"media\": 1, \"rel\": 1, \"ping\": 1, \"type\": 1},\n    \"article\": {\"pubdate\": 1},\n    \"aside\": {},\n    \"audio\": {\"src\": 1, \"autobuffer\": 1, \"autoplay\": {\"autoplay\": 1}, \"loop\": {\"loop\": 1}, \"controls\": {\"controls\": 1}, \"muted\": {\"muted\": 1}, \"preload\": {\"auto\": 1, \"metadata\": 1, \"none\": 1 }},\n    \"b\": {},\n    \"base\": {\"href\": 1, \"target\": 1},\n    \"bdi\": {},\n    \"bdo\": {},\n    \"blockquote\": {\"cite\": 1},\n    \"body\": {\"onafterprint\": 1, \"onbeforeprint\": 1, \"onbeforeunload\": 1, \"onhashchange\": 1, \"onmessage\": 1, \"onoffline\": 1, \"onpopstate\": 1, \"onredo\": 1, \"onresize\": 1, \"onstorage\": 1, \"onundo\": 1, \"onunload\": 1},\n    \"br\": {},\n    \"button\": {\"autofocus\": 1, \"disabled\": {\"disabled\": 1}, \"form\": 1, \"formaction\": 1, \"formenctype\": 1, \"formmethod\": 1, \"formnovalidate\": 1, \"formtarget\": 1, \"name\": 1, \"value\": 1, \"type\": {\"button\": 1, \"submit\": 1}},\n    \"canvas\": {\"width\": 1, \"height\": 1},\n    \"caption\": {},\n    \"cite\": {},\n    \"code\": {},\n    \"col\": {\"span\": 1},\n    \"colgroup\": {\"span\": 1},\n    \"command\": {\"type\": 1, \"label\": 1, \"icon\": 1, \"disabled\": 1, \"checked\": 1, \"radiogroup\": 1, \"command\": 1},\n    \"data\": {},\n    \"datalist\": {},\n    \"dd\": {},\n    \"del\": {\"cite\": 1, \"datetime\": 1},\n    \"details\": {\"open\": 1},\n    \"dfn\": {},\n    \"dialog\": {\"open\": 1},\n    \"div\": {},\n    \"dl\": {},\n    \"dt\": {},\n    \"em\": {},\n    \"embed\": {\"src\": 1, \"height\": 1, \"width\": 1, \"type\": 1},\n    \"fieldset\": {\"disabled\": 1, \"form\": 1, \"name\": 1},\n    \"figcaption\": {},\n    \"figure\": {},\n    \"footer\": {},\n    \"form\": {\"accept-charset\": 1, \"action\": 1, \"autocomplete\": 1, \"enctype\": {\"multipart/form-data\": 1, \"application/x-www-form-urlencoded\": 1}, \"method\": {\"get\": 1, \"post\": 1}, \"name\": 1, \"novalidate\": 1, \"target\": {\"_blank\": 1, \"top\": 1}},\n    \"h1\": {},\n    \"h2\": {},\n    \"h3\": {},\n    \"h4\": {},\n    \"h5\": {},\n    \"h6\": {},\n    \"head\": {},\n    \"header\": {},\n    \"hr\": {},\n    \"html\": {\"manifest\": 1},\n    \"i\": {},\n    \"iframe\": {\"name\": 1, \"src\": 1, \"height\": 1, \"width\": 1, \"sandbox\": {\"allow-same-origin\": 1, \"allow-top-navigation\": 1, \"allow-forms\": 1, \"allow-scripts\": 1}, \"seamless\": {\"seamless\": 1}},\n    \"img\": {\"alt\": 1, \"src\": 1, \"height\": 1, \"width\": 1, \"usemap\": 1, \"ismap\": 1},\n    \"input\": {\n        \"type\": {\"text\": 1, \"password\": 1, \"hidden\": 1, \"checkbox\": 1, \"submit\": 1, \"radio\": 1, \"file\": 1, \"button\": 1, \"reset\": 1, \"image\": 31, \"color\": 1, \"date\": 1, \"datetime\": 1, \"datetime-local\": 1, \"email\": 1, \"month\": 1, \"number\": 1, \"range\": 1, \"search\": 1, \"tel\": 1, \"time\": 1, \"url\": 1, \"week\": 1},\n        \"accept\": 1, \"alt\": 1, \"autocomplete\": {\"on\": 1, \"off\": 1}, \"autofocus\": {\"autofocus\": 1}, \"checked\": {\"checked\": 1}, \"disabled\": {\"disabled\": 1}, \"form\": 1, \"formaction\": 1, \"formenctype\": {\"application/x-www-form-urlencoded\": 1, \"multipart/form-data\": 1, \"text/plain\": 1}, \"formmethod\": {\"get\": 1, \"post\": 1}, \"formnovalidate\": {\"formnovalidate\": 1}, \"formtarget\": {\"_blank\": 1, \"_self\": 1, \"_parent\": 1, \"_top\": 1}, \"height\": 1, \"list\": 1, \"max\": 1, \"maxlength\": 1, \"min\": 1, \"multiple\": {\"multiple\": 1}, \"name\": 1, \"pattern\": 1, \"placeholder\": 1, \"readonly\": {\"readonly\": 1}, \"required\": {\"required\": 1}, \"size\": 1, \"src\": 1, \"step\": 1, \"width\": 1, \"files\": 1, \"value\": 1},\n    \"ins\": {\"cite\": 1, \"datetime\": 1},\n    \"kbd\": {},\n    \"keygen\": {\"autofocus\": 1, \"challenge\": {\"challenge\": 1}, \"disabled\": {\"disabled\": 1}, \"form\": 1, \"keytype\": {\"rsa\": 1, \"dsa\": 1, \"ec\": 1}, \"name\": 1},\n    \"label\": {\"form\": 1, \"for\": 1},\n    \"legend\": {},\n    \"li\": {\"value\": 1},\n    \"link\": {\"href\": 1, \"hreflang\": 1, \"rel\": {\"stylesheet\": 1, \"icon\": 1}, \"media\": {\"all\": 1, \"screen\": 1, \"print\": 1}, \"type\": {\"text/css\": 1, \"image/png\": 1, \"image/jpeg\": 1, \"image/gif\": 1}, \"sizes\": 1},\n    \"main\": {},\n    \"map\": {\"name\": 1},\n    \"mark\": {},\n    \"math\": {},\n    \"menu\": {\"type\": 1, \"label\": 1},\n    \"meta\": {\"http-equiv\": {\"content-type\": 1}, \"name\": {\"description\": 1, \"keywords\": 1}, \"content\": {\"text/html; charset=UTF-8\": 1}, \"charset\": 1},\n    \"meter\": {\"value\": 1, \"min\": 1, \"max\": 1, \"low\": 1, \"high\": 1, \"optimum\": 1},\n    \"nav\": {},\n    \"noscript\": {\"href\": 1},\n    \"object\": {\"param\": 1, \"data\": 1, \"type\": 1, \"height\" : 1, \"width\": 1, \"usemap\": 1, \"name\": 1, \"form\": 1, \"classid\": 1},\n    \"ol\": {\"start\": 1, \"reversed\": 1},\n    \"optgroup\": {\"disabled\": 1, \"label\": 1},\n    \"option\": {\"disabled\": 1, \"selected\": 1, \"label\": 1, \"value\": 1},\n    \"output\": {\"for\": 1, \"form\": 1, \"name\": 1},\n    \"p\": {},\n    \"param\": {\"name\": 1, \"value\": 1},\n    \"pre\": {},\n    \"progress\": {\"value\": 1, \"max\": 1},\n    \"q\": {\"cite\": 1},\n    \"rp\": {},\n    \"rt\": {},\n    \"ruby\": {},\n    \"s\": {},\n    \"samp\": {},\n    \"script\": {\"charset\": 1, \"type\": {\"text/javascript\": 1}, \"src\": 1, \"defer\": 1, \"async\": 1},\n    \"select\": {\"autofocus\": 1, \"disabled\": 1, \"form\": 1, \"multiple\": {\"multiple\": 1}, \"name\": 1, \"size\": 1, \"readonly\":{\"readonly\": 1}},\n    \"small\": {},\n    \"source\": {\"src\": 1, \"type\": 1, \"media\": 1},\n    \"span\": {},\n    \"strong\": {},\n    \"style\": {\"type\": 1, \"media\": {\"all\": 1, \"screen\": 1, \"print\": 1}, \"scoped\": 1},\n    \"sub\": {},\n    \"sup\": {},\n    \"svg\": {},\n    \"table\": {\"summary\": 1},\n    \"tbody\": {},\n    \"td\": {\"headers\": 1, \"rowspan\": 1, \"colspan\": 1},\n    \"textarea\": {\"autofocus\": {\"autofocus\": 1}, \"disabled\": {\"disabled\": 1}, \"form\": 1, \"maxlength\": 1, \"name\": 1, \"placeholder\": 1, \"readonly\": {\"readonly\": 1}, \"required\": {\"required\": 1}, \"rows\": 1, \"cols\": 1, \"wrap\": {\"on\": 1, \"off\": 1, \"hard\": 1, \"soft\": 1}},\n    \"tfoot\": {},\n    \"th\": {\"headers\": 1, \"rowspan\": 1, \"colspan\": 1, \"scope\": 1},\n    \"thead\": {},\n    \"time\": {\"datetime\": 1},\n    \"title\": {},\n    \"tr\": {},\n    \"track\": {\"kind\": 1, \"src\": 1, \"srclang\": 1, \"label\": 1, \"default\": 1},\n    \"section\": {},\n    \"summary\": {},\n    \"u\": {},\n    \"ul\": {},\n    \"var\": {},\n    \"video\": {\"src\": 1, \"autobuffer\": 1, \"autoplay\": {\"autoplay\": 1}, \"loop\": {\"loop\": 1}, \"controls\": {\"controls\": 1}, \"width\": 1, \"height\": 1, \"poster\": 1, \"muted\": {\"muted\": 1}, \"preload\": {\"auto\": 1, \"metadata\": 1, \"none\": 1}},\n    \"wbr\": {}\n};\n\nvar elements = Object.keys(attributeMap);\n\nfunction is(token, type) {\n    return token.type.lastIndexOf(type + \".xml\") > -1;\n}\n\nfunction findTagName(session, pos) {\n    var iterator = new TokenIterator(session, pos.row, pos.column);\n    var token = iterator.getCurrentToken();\n    while (token && !is(token, \"tag-name\")){\n        token = iterator.stepBackward();\n    }\n    if (token)\n        return token.value;\n}\n\nfunction findAttributeName(session, pos) {\n    var iterator = new TokenIterator(session, pos.row, pos.column);\n    var token = iterator.getCurrentToken();\n    while (token && !is(token, \"attribute-name\")){\n        token = iterator.stepBackward();\n    }\n    if (token)\n        return token.value;\n}\n\nvar HtmlCompletions = function() {\n\n};\n\n(function() {\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        var token = session.getTokenAt(pos.row, pos.column);\n\n        if (!token)\n            return [];\n\n        // tag name\n        if (is(token, \"tag-name\") || is(token, \"tag-open\") || is(token, \"end-tag-open\"))\n            return this.getTagCompletions(state, session, pos, prefix);\n\n        // tag attribute\n        if (is(token, \"tag-whitespace\") || is(token, \"attribute-name\"))\n            return this.getAttributeCompletions(state, session, pos, prefix);\n            \n        // tag attribute values\n        if (is(token, \"attribute-value\"))\n            return this.getAttributeValueCompletions(state, session, pos, prefix);\n            \n        // HTML entities\n        var line = session.getLine(pos.row).substr(0, pos.column);\n        if (/&[a-z]*$/i.test(line))\n            return this.getHTMLEntityCompletions(state, session, pos, prefix);\n\n        return [];\n    };\n\n    this.getTagCompletions = function(state, session, pos, prefix) {\n        return elements.map(function(element){\n            return {\n                value: element,\n                meta: \"tag\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getAttributeCompletions = function(state, session, pos, prefix) {\n        var tagName = findTagName(session, pos);\n        if (!tagName)\n            return [];\n        var attributes = globalAttributes;\n        if (tagName in attributeMap) {\n            attributes = attributes.concat(Object.keys(attributeMap[tagName]));\n        }\n        return attributes.map(function(attribute){\n            return {\n                caption: attribute,\n                snippet: attribute + '=\"$0\"',\n                meta: \"attribute\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getAttributeValueCompletions = function(state, session, pos, prefix) {\n        var tagName = findTagName(session, pos);\n        var attributeName = findAttributeName(session, pos);\n        \n        if (!tagName)\n            return [];\n        var values = [];\n        if (tagName in attributeMap && attributeName in attributeMap[tagName] && typeof attributeMap[tagName][attributeName] === \"object\") {\n            values = Object.keys(attributeMap[tagName][attributeName]);\n        }\n        return values.map(function(value){\n            return {\n                caption: value,\n                snippet: value,\n                meta: \"attribute value\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getHTMLEntityCompletions = function(state, session, pos, prefix) {\n        var values = ['Aacute;', 'aacute;', 'Acirc;', 'acirc;', 'acute;', 'AElig;', 'aelig;', 'Agrave;', 'agrave;', 'alefsym;', 'Alpha;', 'alpha;', 'amp;', 'and;', 'ang;', 'Aring;', 'aring;', 'asymp;', 'Atilde;', 'atilde;', 'Auml;', 'auml;', 'bdquo;', 'Beta;', 'beta;', 'brvbar;', 'bull;', 'cap;', 'Ccedil;', 'ccedil;', 'cedil;', 'cent;', 'Chi;', 'chi;', 'circ;', 'clubs;', 'cong;', 'copy;', 'crarr;', 'cup;', 'curren;', 'Dagger;', 'dagger;', 'dArr;', 'darr;', 'deg;', 'Delta;', 'delta;', 'diams;', 'divide;', 'Eacute;', 'eacute;', 'Ecirc;', 'ecirc;', 'Egrave;', 'egrave;', 'empty;', 'emsp;', 'ensp;', 'Epsilon;', 'epsilon;', 'equiv;', 'Eta;', 'eta;', 'ETH;', 'eth;', 'Euml;', 'euml;', 'euro;', 'exist;', 'fnof;', 'forall;', 'frac12;', 'frac14;', 'frac34;', 'frasl;', 'Gamma;', 'gamma;', 'ge;', 'gt;', 'hArr;', 'harr;', 'hearts;', 'hellip;', 'Iacute;', 'iacute;', 'Icirc;', 'icirc;', 'iexcl;', 'Igrave;', 'igrave;', 'image;', 'infin;', 'int;', 'Iota;', 'iota;', 'iquest;', 'isin;', 'Iuml;', 'iuml;', 'Kappa;', 'kappa;', 'Lambda;', 'lambda;', 'lang;', 'laquo;', 'lArr;', 'larr;', 'lceil;', 'ldquo;', 'le;', 'lfloor;', 'lowast;', 'loz;', 'lrm;', 'lsaquo;', 'lsquo;', 'lt;', 'macr;', 'mdash;', 'micro;', 'middot;', 'minus;', 'Mu;', 'mu;', 'nabla;', 'nbsp;', 'ndash;', 'ne;', 'ni;', 'not;', 'notin;', 'nsub;', 'Ntilde;', 'ntilde;', 'Nu;', 'nu;', 'Oacute;', 'oacute;', 'Ocirc;', 'ocirc;', 'OElig;', 'oelig;', 'Ograve;', 'ograve;', 'oline;', 'Omega;', 'omega;', 'Omicron;', 'omicron;', 'oplus;', 'or;', 'ordf;', 'ordm;', 'Oslash;', 'oslash;', 'Otilde;', 'otilde;', 'otimes;', 'Ouml;', 'ouml;', 'para;', 'part;', 'permil;', 'perp;', 'Phi;', 'phi;', 'Pi;', 'pi;', 'piv;', 'plusmn;', 'pound;', 'Prime;', 'prime;', 'prod;', 'prop;', 'Psi;', 'psi;', 'quot;', 'radic;', 'rang;', 'raquo;', 'rArr;', 'rarr;', 'rceil;', 'rdquo;', 'real;', 'reg;', 'rfloor;', 'Rho;', 'rho;', 'rlm;', 'rsaquo;', 'rsquo;', 'sbquo;', 'Scaron;', 'scaron;', 'sdot;', 'sect;', 'shy;', 'Sigma;', 'sigma;', 'sigmaf;', 'sim;', 'spades;', 'sub;', 'sube;', 'sum;', 'sup;', 'sup1;', 'sup2;', 'sup3;', 'supe;', 'szlig;', 'Tau;', 'tau;', 'there4;', 'Theta;', 'theta;', 'thetasym;', 'thinsp;', 'THORN;', 'thorn;', 'tilde;', 'times;', 'trade;', 'Uacute;', 'uacute;', 'uArr;', 'uarr;', 'Ucirc;', 'ucirc;', 'Ugrave;', 'ugrave;', 'uml;', 'upsih;', 'Upsilon;', 'upsilon;', 'Uuml;', 'uuml;', 'weierp;', 'Xi;', 'xi;', 'Yacute;', 'yacute;', 'yen;', 'Yuml;', 'yuml;', 'Zeta;', 'zeta;', 'zwj;', 'zwnj;'];\n\n        return values.map(function(value){\n            return {\n                caption: value,\n                snippet: value,\n                meta: \"html entity\",\n                score: 1000000\n            };\n        });\n    };\n\n}).call(HtmlCompletions.prototype);\n\nexports.HtmlCompletions = HtmlCompletions;\n"
  },
  {
    "path": "src/mode/html_elixir.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlElixirHighlightRules = require(\"./html_elixir_highlight_rules\").HtmlElixirHighlightRules;\nvar HtmlMode = require(\"./html\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar CssMode = require(\"./css\").Mode;\nvar ElixirMode = require(\"./elixir\").Mode;\n\nvar Mode = function() {\n    HtmlMode.call(this);   \n    this.HighlightRules = HtmlElixirHighlightRules;\n    this.createModeDelegates({\n        \"js-\": JavaScriptMode,\n        \"css-\": CssMode,\n        \"elixir-\": ElixirMode\n    });\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n\n    this.$id = \"ace/mode/html_elixir\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/html_elixir_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n    var ElixirHighlightRules = require(\"./elixir_highlight_rules\").ElixirHighlightRules;\n\n    var HtmlElixirHighlightRules = function() {\n        HtmlHighlightRules.call(this);\n\n        var startRules = [\n            {\n                regex: \"<%%|%%>\",\n                token: \"constant.language.escape\"\n            }, {\n                token : \"comment.start.eex\",\n                regex : \"<%#\",\n                push  : [{\n                    token : \"comment.end.eex\",\n                    regex: \"%>\",\n                    next: \"pop\",\n                    defaultToken:\"comment\"\n                }]\n            }, {\n                token : \"support.elixir_tag\",\n                regex : \"<%+(?!>)[-=]?\",\n                push  : \"elixir-start\"\n            }\n        ];\n\n        var endRules = [\n            {\n                token : \"support.elixir_tag\",\n                regex : \"%>\",\n                next  : \"pop\"\n            }, {\n                token: \"comment\",\n                regex: \"#(?:[^%]|%[^>])*\"\n            }\n        ];\n\n        for (var key in this.$rules)\n            this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n        this.embedRules(ElixirHighlightRules, \"elixir-\", endRules, [\"start\"]);\n\n        this.normalizeRules();\n    };\n\n\n    oop.inherits(HtmlElixirHighlightRules, HtmlHighlightRules);\n\n    exports.HtmlElixirHighlightRules = HtmlElixirHighlightRules;\n"
  },
  {
    "path": "src/mode/html_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar CssHighlightRules = require(\"./css_highlight_rules\").CssHighlightRules;\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar XmlHighlightRules = require(\"./xml_highlight_rules\").XmlHighlightRules;\n\nvar tagMap = lang.createMap({\n    a           : 'anchor',\n    button \t    : 'form',\n    form        : 'form',\n    img         : 'image',\n    input       : 'form',\n    label       : 'form',\n    option      : 'form',\n    script      : 'script',\n    select      : 'form',\n    textarea    : 'form',\n    style       : 'style',\n    table       : 'table',\n    tbody       : 'table',\n    td          : 'table',\n    tfoot       : 'table',\n    th          : 'table',\n    tr          : 'table'\n});\n\nvar HtmlHighlightRules = function() {\n    XmlHighlightRules.call(this);\n\n    this.addRules({\n        attributes: [{\n            include : \"tag_whitespace\"\n        }, {\n            token : \"entity.other.attribute-name.xml\",\n            regex : \"[-_a-zA-Z0-9:.]+\"\n        }, {\n            token : \"keyword.operator.attribute-equals.xml\",\n            regex : \"=\",\n            push : [{\n                include: \"tag_whitespace\"\n            }, {\n                token : \"string.unquoted.attribute-value.html\",\n                regex : \"[^<>='\\\"`\\\\s]+\",\n                next : \"pop\"\n            }, {\n                token : \"empty\",\n                regex : \"\",\n                next : \"pop\"\n            }]\n        }, {\n            include : \"attribute_value\"\n        }],\n        tag: [{\n            token : function(start, tag) {\n                var group = tagMap[tag];\n                return [\"meta.tag.punctuation.\" + (start == \"<\" ? \"\" : \"end-\") + \"tag-open.xml\",\n                    \"meta.tag\" + (group ? \".\" + group : \"\") + \".tag-name.xml\"];\n            },\n            regex : \"(</?)([-_a-zA-Z0-9:.]+)\",\n            next: \"tag_stuff\"\n        }],\n        tag_stuff: [\n            {include : \"attributes\"},\n            {token : \"meta.tag.punctuation.tag-close.xml\", regex : \"/?>\", next : \"start\"}\n        ]\n    });\n\n    this.embedTagRules(CssHighlightRules, \"css-\", \"style\");\n    this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), \"js-\", \"script\");\n\n    if (this.constructor === HtmlHighlightRules)\n        this.normalizeRules();\n};\n\noop.inherits(HtmlHighlightRules, XmlHighlightRules);\n\nexports.HtmlHighlightRules = HtmlHighlightRules;\n"
  },
  {
    "path": "src/mode/html_ruby.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlRubyHighlightRules = require(\"./html_ruby_highlight_rules\").HtmlRubyHighlightRules;\nvar HtmlMode = require(\"./html\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar CssMode = require(\"./css\").Mode;\nvar RubyMode = require(\"./ruby\").Mode;\n\nvar Mode = function() {\n    HtmlMode.call(this);   \n    this.HighlightRules = HtmlRubyHighlightRules;    \n    this.createModeDelegates({\n        \"js-\": JavaScriptMode,\n        \"css-\": CssMode,\n        \"ruby-\": RubyMode\n    });\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n\n    this.$id = \"ace/mode/html_ruby\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/html_ruby_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n    var RubyHighlightRules = require(\"./ruby_highlight_rules\").RubyHighlightRules;\n\n    var HtmlRubyHighlightRules = function() {\n        HtmlHighlightRules.call(this);\n\n        var startRules = [\n            {\n                regex: \"<%%|%%>\",\n                token: \"constant.language.escape\"\n            }, {\n                token : \"comment.start.erb\",\n                regex : \"<%#\",\n                push  : [{\n                    token : \"comment.end.erb\",\n                    regex: \"%>\",\n                    next: \"pop\",\n                    defaultToken:\"comment\"\n                }]\n            }, {\n                token : \"support.ruby_tag\",\n                regex : \"<%+(?!>)[-=]?\",\n                push  : \"ruby-start\"\n            }\n        ];\n\n        var endRules = [\n            {\n                token : \"support.ruby_tag\",\n                regex : \"%>\",\n                next  : \"pop\"\n            }, {\n                token: \"comment\",\n                regex: \"#(?:[^%]|%[^>])*\"\n            }\n        ];\n\n        for (var key in this.$rules)\n            this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n        this.embedRules(RubyHighlightRules, \"ruby-\", endRules, [\"start\"]);\n\n        this.normalizeRules();\n    };\n\n\n    oop.inherits(HtmlRubyHighlightRules, HtmlHighlightRules);\n\n    exports.HtmlRubyHighlightRules = HtmlRubyHighlightRules;\n"
  },
  {
    "path": "src/mode/html_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Range = require(\"../range\").Range;\nvar HtmlMode = require(\"./html\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {    \n        this.mode = new HtmlMode();\n    },\n\n    \"test: toggle comment lines\" : function() {\n        var session = new EditSession([\"  abc\", \"\", \"fg\"]);\n\n        var range = new Range(0, 3, 1, 1);\n        var comment = this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"  <!--abc-->\", \"\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: next line indent should be the same as the current line indent\" : function() {\n        assert.equal(\"     \", this.mode.getNextLineIndent(\"start\", \"     abc\"));\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"abc\"));\n        assert.equal(\"\\t\", this.mode.getNextLineIndent(\"start\", \"\\tabc\"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/ini.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar IniHighlightRules = require(\"./ini_highlight_rules\").IniHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/ini\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = IniHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \";\";\n    this.blockComment = null;\n    this.$id = \"ace/mode/ini\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ini_highlight_rules.js",
    "content": "/* This file was autogenerated from tool\\tm bundles\\ini.tmbundle\\Syntaxes\\Ini.plist (uuid: ) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar escapeRe = \"\\\\\\\\(?:[\\\\\\\\0abtrn;#=:]|x[a-fA-F\\\\d]{4})\";\n\nvar IniHighlightRules = function() {\n    this.$rules = {\n        start: [{\n            token: 'punctuation.definition.comment.ini',\n            regex: '#.*',\n            push_: [{\n                token: 'comment.line.number-sign.ini',\n                regex: '$|^',\n                next: 'pop'\n            }, {\n                defaultToken: 'comment.line.number-sign.ini'\n            }]\n        }, {\n            token: 'punctuation.definition.comment.ini',\n            regex: ';.*',\n            push_: [{\n                token: 'comment.line.semicolon.ini',\n                regex: '$|^',\n                next: 'pop'\n            }, {\n                defaultToken: 'comment.line.semicolon.ini'\n            }]\n        }, {\n            token: ['keyword.other.definition.ini', 'text', 'punctuation.separator.key-value.ini'],\n            regex: '\\\\b([a-zA-Z0-9_.-]+)\\\\b(\\\\s*)(=)'\n        }, {\n            token: ['punctuation.definition.entity.ini', 'constant.section.group-title.ini', 'punctuation.definition.entity.ini'],\n            regex: '^(\\\\[)(.*?)(\\\\])'\n        }, {\n            token: 'punctuation.definition.string.begin.ini',\n            regex: \"'\",\n            push: [{\n                token: 'punctuation.definition.string.end.ini',\n                regex: \"'\",\n                next: 'pop'\n            }, {\n                token: \"constant.language.escape\",\n                regex: escapeRe\n            }, {\n                defaultToken: 'string.quoted.single.ini'\n            }]\n        }, {\n            token: 'punctuation.definition.string.begin.ini',\n            regex: '\"',\n            push: [{\n                token: \"constant.language.escape\",\n                regex: escapeRe\n            }, {\n                token: 'punctuation.definition.string.end.ini',\n                regex: '\"',\n                next: 'pop'\n            }, {\n                defaultToken: 'string.quoted.double.ini'\n            }]\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nIniHighlightRules.metaData = {\n    fileTypes: ['ini', 'conf'],\n    keyEquivalent: '^~I',\n    name: 'Ini',\n    scopeName: 'source.ini'\n};\n\n\noop.inherits(IniHighlightRules, TextHighlightRules);\n\nexports.IniHighlightRules = IniHighlightRules;\n"
  },
  {
    "path": "src/mode/io.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar IoHighlightRules = require(\"./io_highlight_rules\").IoHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = IoHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/io\";\n    this.snippetFileId = \"ace/snippets/io\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/io_highlight_rules.js",
    "content": "/* This file was autogenerated from tm bundles\\io.tmbundle/Syntaxes/io.plist (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar IoHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'keyword.control.io',\n           regex: '\\\\b(?:if|ifTrue|ifFalse|ifTrueIfFalse|for|loop|reverseForeach|foreach|map|continue|break|while|do|return)\\\\b' },\n         { token: 'punctuation.definition.comment.io',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.io',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.io' } ] },\n         { token: 'punctuation.definition.comment.io',\n           regex: '//',\n           push: \n            [ { token: 'comment.line.double-slash.io',\n                regex: '$',\n                next: 'pop' },\n              { defaultToken: 'comment.line.double-slash.io' } ] },\n         { token: 'punctuation.definition.comment.io',\n           regex: '#',\n           push: \n            [ { token: 'comment.line.number-sign.io', regex: '$', next: 'pop' },\n              { defaultToken: 'comment.line.number-sign.io' } ] },\n         { token: 'variable.language.io',\n           regex: '\\\\b(?:self|sender|target|proto|protos|parent)\\\\b',\n           comment: 'I wonder if some of this isn\\'t variable.other.language? --Allan; scoping this as variable.language to match Objective-C\\'s handling of \\'self\\', which is inconsistent with C++\\'s handling of \\'this\\' but perhaps intentionally so -- Rob' },\n         { token: 'keyword.operator.io',\n           regex: '<=|>=|=|:=|\\\\*|\\\\||\\\\|\\\\||\\\\+|-|/|&|&&|>|<|\\\\?|@|@@|\\\\b(?:and|or)\\\\b' },\n         { token: 'constant.other.io', regex: '\\\\bGL[\\\\w_]+\\\\b' },\n         { token: 'support.class.io', regex: '\\\\b[A-Z](?:\\\\w+)?\\\\b' },\n         { token: 'support.function.io',\n           regex: '\\\\b(?:clone|call|init|method|list|vector|block|\\\\w+(?=\\\\s*\\\\())\\\\b' },\n         { token: 'support.function.open-gl.io',\n           regex: '\\\\bgl(?:u|ut)?[A-Z]\\\\w+\\\\b' },\n         { token: 'punctuation.definition.string.begin.io',\n           regex: '\"\"\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.io',\n                regex: '\"\"\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.io', regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.triple.io' } ] },\n         { token: 'punctuation.definition.string.begin.io',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.io',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.io', regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.double.io' } ] },\n         { token: 'constant.numeric.io',\n           regex: '\\\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\\\.?[0-9]*|\\\\.[0-9]+)(?:(?:e|E)(?:\\\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\\\b' },\n         { token: 'variable.other.global.io', regex: 'Lobby\\\\b' },\n         { token: 'constant.language.io',\n           regex: '\\\\b(?:TRUE|true|FALSE|false|NULL|null|Null|Nil|nil|YES|NO)\\\\b' } ] };\n    \n    this.normalizeRules();\n};\n\nIoHighlightRules.metaData = { fileTypes: [ 'io' ],\n      keyEquivalent: '^~I',\n      name: 'Io',\n      scopeName: 'source.io' };\n\n\noop.inherits(IoHighlightRules, TextHighlightRules);\n\nexports.IoHighlightRules = IoHighlightRules;\n"
  },
  {
    "path": "src/mode/ion.js",
    "content": "/*\n  THIS FILE WAS GENERATED BY 'ligand' USING 'mode.js'\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./ion_highlight_rules\").IonHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = HighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {\n        start: \"/*\",\n        end: \"*/\"\n    };\n\n    this.getNextLineIndent = function (state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function (state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function (state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/ion\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ion_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS GENERATED BY 'ligand' USING 'mode_highlight_rules.js'\n*/\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\n    var IonHighlightRules = function() {\n        // constant.language.bool.ion\n        var k_keywords_bool =\n            \"TRUE|FALSE\";\n        var k_bool = k_keywords_bool;\n\n        // constant.language.null.ion\n        var k_keywords_null =\n            \"NULL.NULL|NULL.BOOL|NULL.INT|NULL.FLOAT|NULL.DECIMAL|NULL.TIMESTAMP|NULL.STRING|NULL.SYMBOL|NULL.BLOB|NULL.CLOB|\"\n            +\"NULL.STRUCT|NULL.LIST|NULL.SEXP|NULL\";\n        var k_null = k_keywords_null;\n\n\n        var keywordMapper = this.createKeywordMapper({\n            \"constant.language.bool.ion\": k_bool,\n            \"constant.language.null.ion\": k_null\n        }, \"constant.other.symbol.identifier.ion\", true);\n\n        var keywordMapperRule = {\n            token : keywordMapper,\n            regex : \"\\\\b\\\\w+(?:\\\\.\\\\w+)?\\\\b\"\n        };\n\n        this.$rules = {\n          \"start\": [\n            {\n              \"include\": \"value\"\n            }\n          ],\n          \"value\": [\n            {\n              \"include\": \"whitespace\"\n            },\n            {\n              \"include\": \"comment\"\n            },\n            {\n              \"include\": \"annotation\"\n            },\n            {\n              \"include\": \"string\"\n            },\n            {\n              \"include\": \"number\"\n            },\n            {\n              \"include\": \"keywords\"\n            },\n            {\n              \"include\": \"symbol\"\n            },\n            {\n              \"include\": \"clob\"\n            },\n            {\n              \"include\": \"blob\"\n            },\n            {\n              \"include\": \"struct\"\n            },\n            {\n              \"include\": \"list\"\n            },\n            {\n              \"include\": \"sexp\"\n            }\n          ],\n          \"sexp\": [\n            {\n              \"token\": \"punctuation.definition.sexp.begin.ion\",\n              \"regex\": \"\\\\(\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.sexp.end.ion\",\n                  \"regex\": \"\\\\)\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"include\": \"value\"\n                },\n                {\n                  \"token\": \"storage.type.symbol.operator.ion\",\n                  \"regex\": \"[\\\\!\\\\#\\\\%\\\\&\\\\*\\\\+\\\\-\\\\./\\\\;\\\\<\\\\=\\\\>\\\\?\\\\@\\\\^\\\\`\\\\|\\\\~]+\"\n                }\n              ]\n            }\n          ],\n          \"comment\": [\n            {\n              \"token\": \"comment.line.ion\",\n              \"regex\": \"//[^\\\\n]*\"\n            },\n            {\n              \"token\": \"comment.block.ion\",\n              \"regex\": \"/\\\\*\",\n              \"push\": [\n                {\n                  \"token\": \"comment.block.ion\",\n                  \"regex\": \"[*]/\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"token\": \"comment.block.ion\",\n                  \"regex\": \"[^*/]+\"\n                },\n                {\n                  \"token\": \"comment.block.ion\",\n                  \"regex\": \"[*/]+\"\n                }\n              ]\n            }\n          ],\n          \"list\": [\n            {\n              \"token\": \"punctuation.definition.list.begin.ion\",\n              \"regex\": \"\\\\[\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.list.end.ion\",\n                  \"regex\": \"\\\\]\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"include\": \"value\"\n                },\n                {\n                  \"token\": \"punctuation.definition.list.separator.ion\",\n                  \"regex\": \",\"\n                }\n              ]\n            }\n          ],\n          \"struct\": [\n            {\n              \"token\": \"punctuation.definition.struct.begin.ion\",\n              \"regex\": \"\\\\{\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.struct.end.ion\",\n                  \"regex\": \"\\\\}\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"include\": \"value\"\n                },\n                {\n                  \"token\": \"punctuation.definition.struct.separator.ion\",\n                  \"regex\": \",|:\"\n                }\n              ]\n            }\n          ],\n          \"blob\": [\n            {\n              \"token\": [\n                \"punctuation.definition.blob.begin.ion\",\n                \"string.other.blob.ion\",\n                \"punctuation.definition.blob.end.ion\"\n              ],\n              \"regex\": \"(\\\\{\\\\{)([^\\\"]*)(\\\\}\\\\})\"\n            }\n          ],\n          \"clob\": [\n            {\n              \"token\": [\n                \"punctuation.definition.clob.begin.ion\",\n                \"string.other.clob.ion\",\n                \"punctuation.definition.clob.end.ion\"\n              ],\n              \"regex\": \"(\\\\{\\\\{)(\\\"[^\\\"]*\\\")(\\\\}\\\\})\"\n            }\n          ],\n          \"symbol\": [\n            {\n              \"token\": \"storage.type.symbol.quoted.ion\",\n              \"regex\": \"(['])((?:(?:\\\\\\\\')|(?:[^']))*?)(['])\"\n            },\n            {\n              \"token\": \"storage.type.symbol.identifier.ion\",\n              \"regex\": \"[\\\\$_a-zA-Z][\\\\$_a-zA-Z0-9]*\"\n            }\n          ],\n          \"number\": [\n            {\n              \"token\": \"constant.numeric.timestamp.ion\",\n              \"regex\": \"\\\\d{4}(?:-\\\\d{2})?(?:-\\\\d{2})?T(?:\\\\d{2}:\\\\d{2})(?::\\\\d{2})?(?:\\\\.\\\\d+)?(?:Z|[-+]\\\\d{2}:\\\\d{2})?\"\n            },\n            {\n              \"token\": \"constant.numeric.timestamp.ion\",\n              \"regex\": \"\\\\d{4}-\\\\d{2}-\\\\d{2}T?\"\n            },\n            {\n              \"token\": \"constant.numeric.integer.binary.ion\",\n              \"regex\": \"-?0[bB][01](?:_?[01])*\"\n            },\n            {\n              \"token\": \"constant.numeric.integer.hex.ion\",\n              \"regex\": \"-?0[xX][0-9a-fA-F](?:_?[0-9a-fA-F])*\"\n            },\n            {\n              \"token\": \"constant.numeric.float.ion\",\n              \"regex\": \"-?(?:0|[1-9](?:_?\\\\d)*)(?:\\\\.(?:\\\\d(?:_?\\\\d)*)?)?(?:[eE][+-]?\\\\d+)\"\n            },\n            {\n              \"token\": \"constant.numeric.float.ion\",\n              \"regex\": \"(?:[-+]inf)|(?:nan)\"\n            },\n            {\n              \"token\": \"constant.numeric.decimal.ion\",\n              \"regex\": \"-?(?:0|[1-9](?:_?\\\\d)*)(?:(?:(?:\\\\.(?:\\\\d(?:_?\\\\d)*)?)(?:[dD][+-]?\\\\d+)|\\\\.(?:\\\\d(?:_?\\\\d)*)?)|(?:[dD][+-]?\\\\d+))\"\n            },\n            {\n              \"token\": \"constant.numeric.integer.ion\",\n              \"regex\": \"-?(?:0|[1-9](?:_?\\\\d)*)\"\n            }\n          ],\n          \"string\": [\n            {\n              \"token\": [\n                \"punctuation.definition.string.begin.ion\",\n                \"string.quoted.double.ion\",\n                \"punctuation.definition.string.end.ion\"\n              ],\n              \"regex\": \"([\\\"])((?:(?:\\\\\\\\\\\")|(?:[^\\\"]))*?)([\\\"])\"\n            },\n            {\n              \"token\": \"punctuation.definition.string.begin.ion\",\n              \"regex\": \"'{3}\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.string.end.ion\",\n                  \"regex\": \"'{3}\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"token\": \"string.quoted.triple.ion\",\n                  \"regex\": \"(?:\\\\\\\\'|[^'])+\"\n                },\n                {\n                  \"token\": \"string.quoted.triple.ion\",\n                  \"regex\": \"'\"\n                }\n              ]\n            }\n          ],\n          \"annotation\": [\n            {\n              \"token\": [\n                \"variable.language.annotation.ion\",\n                \"punctuation.definition.annotation.ion\"\n              ],\n              \"regex\": /('(?:[^'\\\\]|\\\\.)*')\\s*(::)/\n            },\n            {\n              \"token\": [\n                \"variable.language.annotation.ion\",\n                \"punctuation.definition.annotation.ion\"\n              ],\n              \"regex\": \"([\\\\$_a-zA-Z][\\\\$_a-zA-Z0-9]*)\\\\s*(::)\"\n            }\n          ],\n          \"whitespace\": [\n            {\n              \"token\": \"text.ion\",\n              \"regex\": \"\\\\s+\"\n            }\n          ]\n        } ;\n        this.$rules[\"keywords\"] = [keywordMapperRule];\n\n\n        this.normalizeRules();\n    };\n\n    oop.inherits(IonHighlightRules, TextHighlightRules);\n\n    exports.IonHighlightRules = IonHighlightRules;\n"
  },
  {
    "path": "src/mode/jack.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./jack_highlight_rules\").JackHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"--\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n\n    this.$id = \"ace/mode/jack\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jack_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JackHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"string\",\n                regex : '\"',\n                next  : \"string2\"\n            }, {\n                token : \"string\",\n                regex : \"'\",\n                next  : \"string1\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex: \"-?0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"(?:0|[-+]?[1-9][0-9]*)\\\\b\"\n            }, {\n                token : \"constant.binary\",\n                regex : \"<[0-9A-Fa-f][0-9A-Fa-f](\\\\s+[0-9A-Fa-f][0-9A-Fa-f])*>\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : \"constant.language.null\",\n                regex : \"null\\\\b\"\n            }, {\n                token : \"storage.type\",\n                regex: \"(?:Integer|Boolean|Null|String|Buffer|Tuple|List|Object|Function|Coroutine|Form)\\\\b\"\n            }, {\n                token : \"keyword\",\n                regex : \"(?:return|abort|vars|for|delete|in|is|escape|exec|split|and|if|elif|else|while)\\\\b\"\n            }, {\n                token : \"language.builtin\",\n                regex : \"(?:lines|source|parse|read-stream|interval|substr|parseint|write|print|range|rand|inspect|bind|i-values|i-pairs|i-map|i-filter|i-chunk|i-all\\\\?|i-any\\\\?|i-collect|i-zip|i-merge|i-each)\\\\b\"\n            }, {\n                token : \"comment\",\n                regex : \"--.*$\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"storage.form\",\n                regex : \"@[a-z]+\"\n            }, {\n                token : \"constant.other.symbol\",\n                regex : ':+[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?'\n            }, {\n                token : \"variable\",\n                regex : '[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?'\n            }, {\n                token : \"keyword.operator\",\n                regex : \"\\\\|\\\\||\\\\^\\\\^|&&|!=|==|<=|<|>=|>|\\\\+|-|\\\\*|\\\\/|\\\\^|\\\\%|\\\\#|\\\\!\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"string1\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['\"\\\\\\/bfnrt])/\n            }, {\n                token : \"string\",\n                regex : \"[^'\\\\\\\\]+\"\n            }, {\n                token : \"string\",\n                regex : \"'\",\n                next  : \"start\"\n            }, {\n                token : \"string\",\n                regex : \"\",\n                next  : \"start\"\n            }\n        ],\n        \"string2\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['\"\\\\\\/bfnrt])/\n            }, {\n                token : \"string\",\n                regex : '[^\"\\\\\\\\]+'\n            }, {\n                token : \"string\",\n                regex : '\"',\n                next  : \"start\"\n            }, {\n                token : \"string\",\n                regex : \"\",\n                next  : \"start\"\n            }\n        ]\n    };\n    \n};\n\noop.inherits(JackHighlightRules, TextHighlightRules);\n\nexports.JackHighlightRules = JackHighlightRules;\n"
  },
  {
    "path": "src/mode/jade.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar JadeHighlightRules = require(\"./jade_highlight_rules\").JadeHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = JadeHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() { \n\tthis.lineCommentStart = \"//\";\n    this.$id = \"ace/mode/jade\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jade_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: C5B73B98-5F2A-42E3-9F0E-028A74A9FE4B)\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar MarkdownHighlightRules = require(\"./markdown_highlight_rules\").MarkdownHighlightRules;\nvar SassHighlightRules = require(\"./scss_highlight_rules\").ScssHighlightRules;\nvar LessHighlightRules = require(\"./less_highlight_rules\").LessHighlightRules;\nvar CoffeeHighlightRules = require(\"./coffee_highlight_rules\").CoffeeHighlightRules;\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nfunction mixin_embed(tag, prefix) {\n    return { \n        token : \"entity.name.function.jade\",\n        regex : \"^\\\\s*\\\\:\" + tag,\n        next  : prefix + \"start\"\n    };\n}\n\nvar JadeHighlightRules = function() {\n\n    var escapedRe = \"\\\\\\\\(?:x[0-9a-fA-F]{2}|\" + // hex\n        \"u[0-9a-fA-F]{4}|\" + // unicode\n        \"[0-2][0-7]{0,2}|\" + // oct\n        \"3[0-6][0-7]?|\" + // oct\n        \"37[0-7]?|\" + // oct\n        \"[4-7][0-7]?|\" + //oct\n        \".)\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = \n        {\n    \"start\": [\n        {\n            token: \"keyword.control.import.include.jade\",\n            regex: \"\\\\s*\\\\binclude\\\\b\"\n        },\n        {\n            token: \"keyword.other.doctype.jade\",\n            regex: \"^!!!\\\\s*(?:[a-zA-Z0-9-_]+)?\"\n        },\n        {\n            onMatch: function(value, currentState, stack) {\n                stack.unshift(this.next, value.length - 2, currentState);\n                return \"comment\";\n            },\n            regex: /^\\s*\\/\\//,\n            next: \"comment_block\"\n        },\n        mixin_embed(\"markdown\", \"markdown-\"),\n        mixin_embed(\"sass\", \"sass-\"),\n        mixin_embed(\"less\", \"less-\"),\n        mixin_embed(\"coffee\", \"coffee-\"),\n        /*\n        {\n            token: {\n                \"2\": {\n                    \"name\": \"entity.name.function.jade\"\n                }\n            },\n            regex: \"^(\\\\s*)(\\\\:cdata)\",\n            next: \"state_9\"\n        },*/\n        // match stuff like: mixin dialog-title-desc(title, desc)\n        {\n            token: [ \"storage.type.function.jade\",\n                       \"entity.name.function.jade\",\n                       \"punctuation.definition.parameters.begin.jade\",\n                       \"variable.parameter.function.jade\",\n                       \"punctuation.definition.parameters.end.jade\"\n                    ],\n            regex: \"^(\\\\s*mixin)( [\\\\w\\\\-]+)(\\\\s*\\\\()(.*?)(\\\\))\"\n        },\n        // match stuff like: mixin dialog-title-desc\n        {\n            token: [ \"storage.type.function.jade\", \"entity.name.function.jade\"],\n            regex: \"^(\\\\s*mixin)( [\\\\w\\\\-]+)\"\n        },\n        {\n            token: \"source.js.embedded.jade\",\n            regex: \"^\\\\s*(?:-|=|!=)\",\n            next: \"js-start\"\n        },\n        /*{\n            token: \"entity.name.tag.script.jade\",\n            regex: \"^\\\\s*script\",\n            next: \"js_code_tag\"\n        },*/\n        {\n            token: \"string.interpolated.jade\",\n            regex: \"[#!]\\\\{[^\\\\}]+\\\\}\"\n        },\n        // Match any tag, id or class. skip AST filters\n        {\n            token: \"meta.tag.any.jade\",\n            regex: /^\\s*(?!\\w+:)(?:[\\w-]+|(?=\\.|#)])/,\n            next: \"tag_single\"\n        },\n        {\n            token: \"suport.type.attribute.id.jade\",\n            regex: \"#\\\\w+\"\n        },\n        {\n            token: \"suport.type.attribute.class.jade\",\n            regex: \"\\\\.\\\\w+\"\n        },\n        {\n            token: \"punctuation\",\n            regex: \"\\\\s*(?:\\\\()\",\n            next: \"tag_attributes\"\n        }\n    ],\n    \"comment_block\": [\n        {regex: /^\\s*(?:\\/\\/)?/, onMatch: function(value, currentState, stack) {\n            if (value.length <= stack[1]) {\n                if (value.slice(-1) == \"/\") {\n                    stack[1] = value.length - 2;\n                    this.next = \"\";\n                    return \"comment\";\n                }\n                stack.shift();\n                stack.shift();\n                this.next = stack.shift();\n                return \"text\";\n            } else {\n                this.next = \"\";\n                return \"comment\";\n            }\n        }, next: \"start\"},\n        {defaultToken: \"comment\"}\n    ],\n    /*\n    \n    \"state_9\": [\n        {\n            token: \"TODO\",\n            regex: \"^(?!\\\\1\\\\s+)\",\n            next: \"start\"\n        },\n        {\n            token: \"TODO\",\n            regex: \".+\",\n            next: \"state_9\"\n        }\n    ],*/\n    /*\"js_code\": [\n        {\n            token: \"keyword.control.js\",\n            regex: \"\\\\beach\\\\b\"\n        },\n        {\n            token: \"text\",\n            regex: \"$\",\n            next: \"start\"\n        }\n    ],*/\n    /*\"js_code_tag\": [\n        {\n            \"include\": \"source.js\"\n        },\n        {\n            token: \"TODO\",\n            regex: \"^((?=(\\\\1)([\\\\w#\\\\.]|$\\\\n?))|^$\\\\n?)\",\n            next: \"start\"\n        }\n    ],*/\n    \"tag_single\": [\n        {\n            token: \"entity.other.attribute-name.class.jade\",\n            regex: \"\\\\.[\\\\w-]+\"\n        },\n        {\n            token: \"entity.other.attribute-name.id.jade\",\n            regex: \"#[\\\\w-]+\"\n        },\n        {\n            token: [\"text\", \"punctuation\"],\n            regex: \"($)|((?!\\\\.|#|=|-))\",\n            next: \"start\"\n        }\n    ],\n    \"tag_attributes\": [ \n        {\n            token : \"string\",\n            regex : \"'(?=.)\",\n            next  : \"qstring\"\n        }, \n        {\n            token : \"string\",\n            regex : '\"(?=.)',\n            next  : \"qqstring\"\n        },\n        {\n            token: [\"entity.other.attribute-name.jade\", \"punctuation\"],\n            regex: \"([a-zA-Z:\\\\.-]+)(=)?\",\n            next: \"attribute_strings\"\n        },\n        {\n            token: \"punctuation\",\n            regex: \"\\\\)\",\n            next: \"start\"\n        }\n    ],\n    \"attribute_strings\": [\n        {\n            token : \"string\",\n            regex : \"'(?=.)\",\n            next  : \"qstring\"\n        }, \n        {\n            token : \"string\",\n            regex : '\"(?=.)',\n            next  : \"qqstring\"\n        },\n        {\n            token : \"string\",\n            regex : '(?=\\\\S)',\n            next  : \"tag_attributes\"\n        }\n    ],\n    \"qqstring\" : [\n        {\n            token : \"constant.language.escape\",\n            regex : escapedRe\n        }, {\n            token : \"string\",\n            regex : '[^\"\\\\\\\\]+'\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        }, {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"tag_attributes\"\n        }\n    ],\n    \"qstring\" : [\n        {\n            token : \"constant.language.escape\",\n            regex : escapedRe\n        }, {\n            token : \"string\",\n            regex : \"[^'\\\\\\\\]+\"\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qstring\"\n        }, {\n            token : \"string\",\n            regex : \"'|$\",\n            next  : \"tag_attributes\"\n        }\n    ]\n};\n\n    this.embedRules(JavaScriptHighlightRules, \"js-\", [{\n        token: \"text\",\n        regex: \".$\",\n        next: \"start\"\n    }]);\n/*\n    this.embedRules(MarkdownHighlightRules, \"markdown-\", [{\n       token : \"support.function\",\n       regex : \"^\\\\1\\\\s+\",\n       captures: \"1\",\n       next  : \"start\"\n    }]);\n\n    this.embedRules(SassHighlightRules, \"sass-\", [{\n       token : \"support.function\",\n       regex : \"^(?!\\\\1\\\\s+)\",\n       captures: \"1\",\n       next  : \"start\"\n    }]);\n\n    this.embedRules(LessHighlightRules, \"less-\", [{\n       token : \"support.function\",\n       regex : \"^(?!\\\\1\\\\s+)\",\n       captures: \"1\",\n       next  : \"start\"\n    }]);\n\n    this.embedRules(CoffeeHighlightRules, \"coffee-\", [{\n       token : \"support.function\",\n       regex : \"^(?!\\\\1\\\\s+)\",\n       captures: \"1\",\n       next  : \"start\"\n    }]);\n\n    this.embedRules(JavaScriptHighlightRules, \"js-\", [{\n       token : \"support.function\",\n       regex : \"$\",\n       captures: \"1\",\n       next  : \"start\"\n    }]); */\n};\n\noop.inherits(JadeHighlightRules, TextHighlightRules);\n\nexports.JadeHighlightRules = JadeHighlightRules;\n"
  },
  {
    "path": "src/mode/java.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar JavaHighlightRules = require(\"./java_highlight_rules\").JavaHighlightRules;\nvar JavaFoldMode = require(\"./folding/java\").FoldMode;\n\nvar Mode = function() {\n    JavaScriptMode.call(this);\n    this.HighlightRules = JavaHighlightRules;\n    this.foldingRules = new JavaFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, JavaScriptMode);\n\n(function() {\n    \n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/java\";\n    this.snippetFileId = \"ace/snippets/java\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/java_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JavaHighlightRules = function() {\n    var identifierRe = \"[a-zA-Z_$][a-zA-Z0-9_$]*\";\n\n    // taken from http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html\n    var keywords = (\n    \"abstract|continue|for|new|switch|\" +\n    \"assert|default|goto|package|synchronized|\" +\n    \"boolean|do|if|private|this|\" +\n    \"break|double|implements|protected|throw|\" +\n    \"byte|else|import|public|throws|\" +\n    \"case|enum|instanceof|return|transient|\" +\n    \"catch|extends|int|short|try|\" +\n    \"char|final|interface|static|void|\" +\n    \"class|finally|long|strictfp|volatile|\" +\n    \"const|float|native|super|while|\" +\n    \"yield|when|record|var|\" +\n    \"permits|(?:non\\\\-)?sealed\"\n    );\n\n    var buildinConstants = (\"null|Infinity|NaN|undefined\");\n\n\n    var langClasses = (\n        \"AbstractMethodError|AssertionError|ClassCircularityError|\"+\n        \"ClassFormatError|Deprecated|EnumConstantNotPresentException|\"+\n        \"ExceptionInInitializerError|IllegalAccessError|\"+\n        \"IllegalThreadStateException|InstantiationError|InternalError|\"+\n        \"NegativeArraySizeException|NoSuchFieldError|Override|Process|\"+\n        \"ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|\"+\n        \"SuppressWarnings|TypeNotPresentException|UnknownError|\"+\n        \"UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|\"+\n        \"InstantiationException|IndexOutOfBoundsException|\"+\n        \"ArrayIndexOutOfBoundsException|CloneNotSupportedException|\"+\n        \"NoSuchFieldException|IllegalArgumentException|NumberFormatException|\"+\n        \"SecurityException|Void|InheritableThreadLocal|IllegalStateException|\"+\n        \"InterruptedException|NoSuchMethodException|IllegalAccessException|\"+\n        \"UnsupportedOperationException|Enum|StrictMath|Package|Compiler|\"+\n        \"Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|\"+\n        \"NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|\"+\n        \"NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|\"+\n        \"Character|Boolean|StackTraceElement|Appendable|StringBuffer|\"+\n        \"Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|\"+\n        \"StackOverflowError|OutOfMemoryError|VirtualMachineError|\"+\n        \"ArrayStoreException|ClassCastException|LinkageError|\"+\n        \"NoClassDefFoundError|ClassNotFoundException|RuntimeException|\"+\n        \"Exception|ThreadDeath|Error|Throwable|System|ClassLoader|\"+\n        \"Cloneable|Class|CharSequence|Comparable|String|Object\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"constant.language\": buildinConstants,\n        \"support.function\": langClasses\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {include: \"comments\"},\n            {include: \"multiline-strings\"},\n            {include: \"strings\"},\n            {include: \"constants\"},\n            {\n                regex: \"(open(?:\\\\s+))?module(?=\\\\s*\\\\w)\",\n                token: \"keyword\",\n                next: [{\n                    regex: \"{\",\n                    token: \"paren.lparen\",\n                    push: [\n                        {\n                            regex: \"}\",\n                            token: \"paren.rparen\",\n                            next: \"pop\"\n                        },\n                        {include: \"comments\"},\n                        {\n                            // From Section 3.9 of http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jls-diffs.pdf\n                            regex: \"\\\\b(requires|transitive|exports|opens|to|uses|provides|with)\\\\b\",\n                            token: \"keyword\"\n                        }\n                    ]\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }, {\n                    token : \"identifier\",\n                    regex : \"\\\\w+\"\n                }, {\n                    token : \"punctuation.operator\",\n                    regex : \".\"\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }, {\n                    regex: \"\", // exit if there is anything else\n                    next: \"start\"\n                }]\n            },\n            {include: \"statements\"}\n        ],\n        \"comments\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            {\n                token : \"comment.doc\", // doc comment\n                regex: /\\/\\*\\*(?!\\/)/,\n                push  : \"doc-start\"\n            },\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                push : [\n                    {\n                        token : \"comment\", // closing comment\n                        regex : \"\\\\*\\\\/\",\n                        next : \"pop\"\n                    }, {\n                        defaultToken : \"comment\"\n                    }\n                ]\n            },\n        ],\n        \"strings\": [\n            {\n                token: [\"punctuation\", \"string\"],\n                regex: /(\\.)(\")/,\n                push: [\n                    {\n                        token: \"lparen\",\n                        regex: /\\\\\\{/,\n                        push: [\n                            {\n                                token: \"text\",\n                                regex: /$/,\n                                next: \"start\"\n                            }, {\n                                token: \"rparen\",\n                                regex: /}/,\n                                next: \"pop\"\n                            }, {\n                                include: \"strings\"\n                            }, {\n                                include: \"constants\"\n                            }, {\n                                include: \"statements\"\n                            }\n                        ]\n                    }, {\n                        token: \"string\",\n                        regex: /\"/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string\"\n                    }\n                ]\n            },  {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }\n        ],\n        \"multiline-strings\": [\n            {\n                token: [\"punctuation\", \"string\"],\n                regex: /(\\.)(\"\"\")/,\n                push: [\n                    {\n                        token: \"string\",\n                        regex: '\"\"\"',\n                        next: \"pop\"\n                    }, {\n                        token: \"lparen\",\n                        regex: /\\\\\\{/,\n                        push: [\n                            {\n                                token: \"text\",\n                                regex: /$/,\n                                next: \"start\"\n                            }, {\n                                token: \"rparen\",\n                                regex: /}/,\n                                next: \"pop\"\n                            }, {\n                                include: \"multiline-strings\"\n                            }, {\n                                include: \"strings\"\n                            }, {\n                                include: \"constants\"\n                            }, {\n                                include: \"statements\"\n                            }\n                        ]\n                    }, {\n                        token: \"constant.language.escape\",\n                        regex: /\\\\./\n                    }, {\n                        defaultToken: \"string\"\n                    }\n                ]\n            },\n            {\n                token: \"string\",\n                regex: '\"\"\"',\n                push: [\n                    {\n                        token: \"string\",\n                        regex: '\"\"\"',\n                        next: \"pop\"\n                    }, {\n                        token : \"constant.language.escape\",\n                        regex : /\\\\./\n                    }, {\n                        defaultToken: \"string\"\n                    }\n                ]\n            }\n        ],\n        \"constants\": [\n            {\n                token: \"constant.numeric\", // hex\n                regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\\b/\n            }, {\n                token: \"constant.numeric\", // float\n                regex: /[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?[LlSsDdFfYy]?\\b/\n            }, {\n                token: \"constant.language.boolean\",\n                regex: \"(?:true|false)\\\\b\"\n            }\n        ],\n        \"statements\": [\n            {\n                token: [\"keyword\", \"text\", \"identifier\"],\n                regex: \"(record)(\\\\s+)(\"+identifierRe+\")\\\\b\"\n            },\n            {\n                token: \"keyword\",\n                regex: \"(?:\" + keywords + \")\\\\b\"\n            }, {//annotations\n                token: \"storage.type.annotation\",\n                regex: \"@\" + identifierRe + \"\\\\b\"\n            }, {\n                token: \"entity.name.function\",\n                regex: identifierRe + \"(?=\\\\()\"\n            }, {\n                token: keywordMapper, // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex: identifierRe + \"\\\\b\"\n            }, {\n                token: \"keyword.operator\",\n                regex: \"!|\\\\$|%|&|\\\\||\\\\^|\\\\*|\\\\/|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?|\\\\:|\\\\*=|\\\\/=|%=|\\\\+=|\\\\-=|&=|\\\\|=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token: \"lparen\",\n                regex: \"[[({]\"\n            }, {\n                token: \"rparen\",\n                regex: \"[\\\\])}]\"\n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }\n        ]\n    };\n\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"pop\") ]);\n    this.normalizeRules();\n};\n\noop.inherits(JavaHighlightRules, TextHighlightRules);\n\nexports.JavaHighlightRules = JavaHighlightRules;\n"
  },
  {
    "path": "src/mode/javascript.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\nvar JavaScriptBehaviour = require(\"./behaviour/javascript\").JavaScriptBehaviour;\nvar JavaScriptFoldMode = require(\"./folding/javascript\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = JavaScriptHighlightRules;\n\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = new JavaScriptBehaviour();\n    this.foldingRules = new JavaScriptFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$quotes = {'\"': '\"', \"'\": \"'\", \"`\": \"`\"};\n    this.$pairQuotesAfter = {\n        \"`\": /\\w/\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\" || state == \"no_regex\") {\n            var match = line.match(/^.*(?:\\bcase\\b.*:|[\\{\\(\\[])\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState == \"start\" || endState == \"no_regex\") {\n                return \"\";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/javascript_worker\", \"JavaScriptWorker\");\n        worker.attachToDocument(session.getDocument());\n\n        worker.on(\"annotate\", function(results) {\n            session.setAnnotations(results.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n    this.$id = \"ace/mode/javascript\";\n    this.snippetFileId = \"ace/snippets/javascript\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/javascript_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./jsdoc_comment_highlight_rules\").JsDocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n// TODO: Unicode escape sequences\nvar identifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\";\n\nvar JavaScriptHighlightRules = function(options) {\n    // see: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects\n    \n    var keywords = {\n        \"variable.language\":\n            \"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|\"  + // Constructors\n            \"Namespace|QName|XML|XMLList|\"                                             + // E4X\n            \"ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|\"   +\n            \"Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|\"                    +\n            \"Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|\"   + // Errors\n            \"SyntaxError|TypeError|URIError|\"                                          +\n            \"decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|\" + // Non-constructor functions\n            \"isNaN|parseFloat|parseInt|\"                                               +\n            \"JSON|Math|\"                                                               + // Other\n            \"this|arguments|prototype|window|document\"                                 , // Pseudo\n        \"keyword\":\n            \"const|yield|import|get|set|async|await|\" +\n            \"break|case|catch|continue|default|delete|do|else|finally|for|\" +\n            \"if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|\" +\n            // invalid or reserved\n            \"__parent__|__count__|escape|unescape|with|__proto__|\" +\n            \"class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor\",\n        \"storage.type\":\n            \"const|let|var|function\",\n        \"constant.language\":\n            \"null|Infinity|NaN|undefined\",\n        \"support.function\":\n            \"alert\",\n        \"constant.language.boolean\": \"true|false\"\n    };\n    \n    var keywordMapper = this.createKeywordMapper(keywords, \"identifier\");\n\n    // keywords which can be followed by regular expressions\n    var kwBeforeRe = \"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\";\n\n    var escapedRe = \"\\\\\\\\(?:x[0-9a-fA-F]{2}|\" + // hex\n        \"u[0-9a-fA-F]{4}|\" + // unicode\n        \"u{[0-9a-fA-F]{1,6}}|\" + // es6 unicode\n        \"[0-2][0-7]{0,2}|\" + // oct\n        \"3[0-7][0-7]?|\" + // oct\n        \"[4-7][0-7]?|\" + //oct\n        \".)\";\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    \n    var anonymousFunctionRe = \"(function)(\\\\s*)(\\\\*?)\";\n\n    var functionCallStartRule = { //just simple function call\n        token: [\"identifier\", \"text\", \"paren.lparen\"],\n        regex: \"(\\\\b(?!\" + Object.values(keywords).join(\"|\") + \"\\\\b)\" + identifierRe + \")(\\\\s*)(\\\\()\"\n    };\n\n    this.$rules = {\n        \"no_regex\" : [\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            comments(\"no_regex\"),\n            functionCallStartRule,\n            {\n                token : \"string\",\n                regex : \"'(?=.)\",\n                next  : \"qstring\"\n            }, {\n                token : \"string\",\n                regex : '\"(?=.)',\n                next  : \"qqstring\"\n            }, {\n                include: \"numeric_constants\"\n            }, {\n                // play = function() {  }\n                token : [\n                    \"entity.name.function\", \"text\", \"keyword.operator\", \"text\", \"storage.type\",\n                    \"text\", \"storage.type\", \"text\", \"paren.lparen\"\n                ],\n                regex : \"(\" + identifierRe +\")(\\\\s*)(=)(\\\\s*)\" + anonymousFunctionRe + \"(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                // function myFunc(arg) { }\n                token : [\n                    \"storage.type\", \"text\", \"storage.type\", \"text\", \"text\", \"entity.name.function\", \"text\", \"paren.lparen\"\n                ],\n                regex : \"(function)(?:(?:(\\\\s*)(\\\\*)(\\\\s*))|(\\\\s+))(\" + identifierRe + \")(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                // foobar: function() { }\n                token : [\n                    \"entity.name.function\", \"text\", \"punctuation.operator\",\n                    \"text\", \"storage.type\", \"text\", \"storage.type\", \"text\", \"paren.lparen\"\n                ],\n                regex : \"(\" + identifierRe + \")(\\\\s*)(:)(\\\\s*)\" + anonymousFunctionRe + \"(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                // : function() { } (this is for issues with 'foo': function() { })\n                token : [\n                    \"text\", \"text\", \"storage.type\", \"text\", \"storage.type\", \"text\",  \"paren.lparen\"\n                ],\n                regex : \"(:)(\\\\s*)\" + anonymousFunctionRe + \"(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                // from \"module-path\" (this is the only case where 'from' should be a keyword)\n                token : \"keyword\",\n                regex : \"from(?=\\\\s*('|\\\"))\"\n            }, {\n                token : \"keyword\",\n                regex : \"(?:\" + kwBeforeRe + \")\\\\b\",\n                next : \"start\"\n            }, {\n                token : \"support.constant\",\n                regex : /that\\b/\n            }, {\n                token : [\"storage.type\", \"punctuation.operator\", \"support.function.firebug\"],\n                regex : /(console)(\\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\\b/\n            }, {\n                token : keywordMapper,\n                regex : identifierRe\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[.](?![.])/,\n                next  : \"property\"\n            }, {\n                token : \"storage.type\",\n                regex : /=>/,\n                next  : \"start\"\n            }, {\n                token : \"keyword.operator\",\n                regex : /--|\\+\\+|\\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\\|\\||\\?:|[!$%&*+\\-~\\/^]=?/,\n                next  : \"start\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[?:,;.]/,\n                next  : \"start\"\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[({]/,\n                next  : \"start\"\n            }, {\n                token : \"paren.rparen\",\n                regex : /[\\])}]/\n            }, {\n                token: \"comment\",\n                regex: /^#!.*$/\n            }\n        ],\n        property: [{\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }, {\n            token: \"keyword.operator\",\n            regex: /=/\n            }, {\n                // Sound.play = function() {  }\n                token : [\n                    \"storage.type\", \"text\", \"storage.type\", \"text\", \"paren.lparen\"\n                ],\n                regex : anonymousFunctionRe + \"(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                // Sound.play = function play() {  }\n                token: [\n                    \"storage.type\", \"text\", \"storage.type\", \"text\", \"text\", \"entity.name.function\", \"text\", \"paren.lparen\"\n                ],\n                regex: \"(function)(?:(?:(\\\\s*)(\\\\*)(\\\\s*))|(\\\\s+))(\\\\w+)(\\\\s*)(\\\\()\",\n                next: \"function_arguments\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[.](?![.])/\n            }, {\n                token : \"support.function\",\n                regex: \"prototype\"\n            }, {\n                token : \"support.function\",\n                regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/\n            }, {\n                token : \"support.function.dom\",\n                regex : /(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/\n            }, {\n                token :  \"support.constant\",\n                regex : /(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/\n            }, {\n                token : \"identifier\",\n                regex : identifierRe\n            }, {\n                regex: \"\",\n                token: \"empty\",\n                next: \"no_regex\"\n            }\n        ],\n        // regular expressions are only allowed after certain tokens. This\n        // makes sure we don't mix up regexps with the divison operator\n        \"start\": [\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            comments(\"start\"),\n            {\n                token: \"string.regexp\",\n                regex: \"\\\\/\",\n                next: \"regex\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+|^$\",\n                next : \"start\"\n            }, {\n                // immediately return to the start mode without matching\n                // anything\n                token: \"empty\",\n                regex: \"\",\n                next: \"no_regex\"\n            }\n        ],\n        \"regex\": [\n            {\n                // escapes\n                token: \"regexp.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                // flag\n                token: \"string.regexp\",\n                regex: \"/[sxngimy]*\",\n                next: \"no_regex\"\n            }, {\n                // invalid operators\n                token : \"invalid\",\n                regex: /\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/\n            }, {\n                // operators\n                token : \"constant.language.escape\",\n                regex: /\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/\n            }, {\n                token : \"constant.language.delimiter\",\n                regex: /\\|/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\[\\^?/,\n                next: \"regex_character_class\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"no_regex\"\n            }, {\n                defaultToken: \"string.regexp\"\n            }\n        ],\n        \"regex_character_class\": [\n            {\n                token: \"regexp.charclass.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"]\",\n                next: \"regex\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"-\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"no_regex\"\n            }, {\n                defaultToken: \"string.regexp.charachterclass\"\n            }\n        ],\n        \"default_parameter\": [\n            {\n                token : \"string\",\n                regex : \"'(?=.)\",\n                push: [\n                    {\n                        token: \"string\",\n                        regex: \"'|$\",\n                        next: \"pop\"\n                    }, {\n                        include: \"qstring\"\n                    }\n                ]\n            }, {\n                token : \"string\",\n                regex : '\"(?=.)',\n                push: [\n                    {\n                        token: \"string\",\n                        regex: '\"|$',\n                        next: \"pop\"\n                    }, {\n                        include: \"qqstring\"\n                    }\n                ]\n            }, {\n                token : \"constant.language\",\n                regex : \"null|Infinity|NaN|undefined\"\n            }, {\n                include: \"numeric_constants\"\n            }, {\n                token: \"punctuation.operator\",\n                regex: \",\",\n                next: \"function_arguments\"\n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }, {\n                token: \"punctuation.operator\",\n                regex: \"$\"\n            }, {\n                token: \"empty\",\n                regex: \"\",\n                next: \"no_regex\"\n            }\n        ],\n        \"function_arguments\": [\n            comments(\"function_arguments\"),\n            {\n                token: \"variable.parameter\",\n                regex: identifierRe\n            }, {\n                token: \"punctuation.operator\",\n                regex: \",\"\n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }, {\n                token: \"punctuation.operator\",\n                regex: \"$\"\n            }, {\n                token: \"empty\",\n                regex: \"\",\n                next: \"no_regex\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : escapedRe\n            }, {\n                token : \"string\",\n                regex : \"\\\\\\\\$\",\n                consumeLineEnd  : true\n            }, {\n                token : \"string\",\n                regex : '\"|$',\n                next  : \"no_regex\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : escapedRe\n            }, {\n                token : \"string\",\n                regex : \"\\\\\\\\$\",\n                consumeLineEnd  : true\n            }, {\n                token : \"string\",\n                regex : \"'|$\",\n                next  : \"no_regex\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ],\n        \"numeric_constants\": [\n            {\n                token : \"constant.numeric\", // hexadecimal, octal and binary\n                regex : /0(?:[xX][0-9a-fA-F_]+|[oO][0-7_]+|[bB][01_]+)\\b/\n            }, {\n                token : \"constant.numeric\", // decimal integers and floats\n                regex : /(?:\\d[\\d_]*(?:\\.[\\d_]*)?|\\.\\d[\\d_]*)(?:[eE][+-]?\\d+\\b)?/\n            },\n        ]\n    };\n\n\n    if (!options || !options.noES6) {\n        this.$rules.no_regex.unshift({\n            regex: \"[{}]\", onMatch: function(val, state, stack) {\n                this.next = val == \"{\" ? this.nextState : \"\";\n                if (val == \"{\" && stack.length) {\n                    stack.unshift(\"start\", state);\n                }\n                else if (val == \"}\" && stack.length) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    if (this.next.indexOf(\"string\") != -1 || this.next.indexOf(\"jsx\") != -1)\n                        return \"paren.quasi.end\";\n                }\n                return val == \"{\" ? \"paren.lparen\" : \"paren.rparen\";\n            },\n            nextState: \"start\"\n        }, {\n            token : \"string.quasi.start\",\n            regex : /`/,\n            push  : [{\n                token : \"constant.language.escape\",\n                regex : escapedRe\n            }, {\n                token : \"paren.quasi.start\",\n                regex : /\\${/,\n                push  : \"start\"\n            }, {\n                token : \"string.quasi.end\",\n                regex : /`/,\n                next  : \"pop\"\n            }, {\n                defaultToken: \"string.quasi\"\n            }]\n        }, {\n            token: [\"variable.parameter\", \"text\"],\n            regex: \"(\" + identifierRe + \")(\\\\s*)(?=\\\\=>)\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"(\\\\()(?=[^\\\\(]+\\\\s*=>)\",\n            next: \"function_arguments\"\n        }, {\n            token: \"variable.language\",\n            regex: \"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\\\b\"\n        });\n\n        this.$rules[\"function_arguments\"].unshift({\n            token: \"keyword.operator\",\n            regex: \"=\",\n            next: \"default_parameter\"\n        }, {\n            token: \"keyword.operator\",\n            regex: \"\\\\.{3}\"\n        });\n\n        this.$rules[\"property\"].unshift({\n            token: \"support.function\",\n            regex: \"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|\"\n                + \"finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\\\b(?=\\\\()\"\n        }, {\n            token : \"constant.language\",\n            regex : \"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\\\b\"\n        });\n\n        if (!options || options.jsx != false)\n            JSX.call(this);\n    }\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"no_regex\") ]);\n\n    this.normalizeRules();\n};\n\noop.inherits(JavaScriptHighlightRules, TextHighlightRules);\n\nfunction JSX() {\n    var tagRegex = identifierRe.replace(\"\\\\d\", \"\\\\d\\\\-\");\n    var jsxTag = {\n        onMatch : function(val, state, stack) {\n            var offset = val.charAt(1) == \"/\" ? 2 : 1;\n            if (offset == 1) {\n                if (state != this.nextState)\n                    stack.unshift(this.next, this.nextState, 0);\n                else\n                    stack.unshift(this.next);\n                stack[2]++;\n            } else if (offset == 2) {\n                if (state == this.nextState) {\n                    stack[1]--;\n                    if (!stack[1] || stack[1] < 0) {\n                        stack.shift();\n                        stack.shift();\n                    }\n                }\n            }\n            return [{\n                type: \"meta.tag.punctuation.\" + (offset == 1 ? \"\" : \"end-\") + \"tag-open.xml\",\n                value: val.slice(0, offset)\n            }, {\n                type: \"meta.tag.tag-name.xml\",\n                value: val.substr(offset)\n            }];\n        },\n        regex : \"</?(?:\" + tagRegex + \"|(?=>))\",\n        next: \"jsxAttributes\",\n        nextState: \"jsx\"\n    };\n    this.$rules.start.unshift(jsxTag);\n    var jsxJsRule = {\n        regex: \"{\",\n        token: \"paren.quasi.start\",\n        push: \"start\"\n    };\n    this.$rules.jsx = [\n        jsxJsRule,\n        jsxTag,\n        {include : \"reference\"}, {defaultToken: \"string.xml\"}\n    ];\n    this.$rules.jsxAttributes = [{\n        token : \"meta.tag.punctuation.tag-close.xml\",\n        regex : \"/?>\",\n        onMatch : function(value, currentState, stack) {\n            if (currentState == stack[0])\n                stack.shift();\n            if (value.length == 2) {\n                if (stack[0] == this.nextState)\n                    stack[1]--;\n                if (!stack[1] || stack[1] < 0) {\n                    stack.splice(0, 2);\n                }\n            }\n            this.next = stack[0] || \"start\";\n            return [{type: this.token, value: value}];\n        },\n        nextState: \"jsx\"\n    },\n    jsxJsRule,\n    comments(\"jsxAttributes\"),\n    {\n        token : \"entity.other.attribute-name.xml\",\n        regex : tagRegex\n    }, {\n        token : \"keyword.operator.attribute-equals.xml\",\n        regex : \"=\"\n    }, {\n        token : \"text.tag-whitespace.xml\",\n        regex : \"\\\\s+\"\n    }, {\n        token : \"string.attribute-value.xml\",\n        regex : \"'\",\n        stateName : \"jsx_attr_q\",\n        push : [\n            {token : \"string.attribute-value.xml\", regex: \"'\", next: \"pop\"},\n            {include : \"reference\"},\n            {defaultToken : \"string.attribute-value.xml\"}\n        ]\n    }, {\n        token : \"string.attribute-value.xml\",\n        regex : '\"',\n        stateName : \"jsx_attr_qq\",\n        push : [\n            {token : \"string.attribute-value.xml\", regex: '\"', next: \"pop\"},\n            {include : \"reference\"},\n            {defaultToken : \"string.attribute-value.xml\"}\n        ]\n    },\n    jsxTag\n    ];\n    this.$rules.reference = [{\n        token : \"constant.language.escape.reference.xml\",\n        regex : \"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"\n    }];\n}\n\nfunction comments(next) {\n    return [\n        {\n            token : \"comment\", // multi line comment\n            regex : /\\/\\*/,\n            next: [\n                DocCommentHighlightRules.getTagRule(),\n                {token : \"comment\", regex : \"\\\\*\\\\/\", next : next || \"pop\"},\n                {defaultToken : \"comment\", caseInsensitive: true}\n            ]\n        }, {\n            token : \"comment\",\n            regex : \"\\\\/\\\\/\",\n            next: [\n                DocCommentHighlightRules.getTagRule(),\n                {token : \"comment\", regex : \"$|^\", next : next || \"pop\"},\n                {defaultToken : \"comment\", caseInsensitive: true}\n            ]\n        }\n    ];\n}\nexports.JavaScriptHighlightRules = JavaScriptHighlightRules;\n"
  },
  {
    "path": "src/mode/javascript_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {    \n        this.mode = new JavaScriptMode();\n    },\n\n    \"test: getTokenizer() (smoke test)\" : function() {\n        var tokenizer = this.mode.getTokenizer();\n\n        assert.ok(tokenizer instanceof Tokenizer);\n\n        var tokens = tokenizer.getLineTokens(\"'juhu'\", \"start\").tokens;\n        assert.equal(\"string\", tokens[0].type);\n    },\n\n    \"test: toggle comment lines should prepend '//' to each line\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\", \"fg\"]);\n        session.setTabSize(1);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"//   abc\", \"// cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: toggle comment on commented lines should remove leading '//' chars\" : function() {\n        var session = new EditSession([\"//  abc\", \"//cde\", \"fg\"]);\n        session.setTabSize(1);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\" abc\", \"cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n    \n    \"test: toggle comment on all empty lines\" : function() {\n        var session = new EditSession([\"  \", \" \", \"  \"]);\n        session.setTabSize(1);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\" //  \", \" // \", \"  \"].join(\"\\n\"), session.toString());\n    },\n    \n    \"test: toggle comment with empty lines\" : function() {\n        var session = new EditSession([\n            \"        abc\",\n            \"\",\n            \"    cde\", \n            \"    fg\"]);\n        \n        var initial = session.toString();\n        this.mode.toggleCommentLines(\"start\", session, 0, 3);\n        assert.equal([\n            \"    //     abc\",\n            \"\",\n            \"    // cde\", \n            \"    // fg\"].join(\"\\n\"),\n            session.toString()\n        );\n        this.mode.toggleCommentLines(\"start\", session, 0, 3);\n        assert.equal(initial, session.toString());\n    },\n\n    \"test: toggle comment lines twice should return the original text\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\", \"fg\"]);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"  abc\", \"cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: toggle comment on multiple lines with one commented line prepend '//' to each line\" : function() {\n        var session = new EditSession([\"  //  abc\", \"  //cde\", \"    fg\"]);\n        session.setTabSize(1);\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"  // //  abc\", \"  // //cde\", \"  //   fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: toggle comment on a comment line with leading white space\": function() {\n        var session = new EditSession([\"//cde\", \"  //fg\"]);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"cde\", \"  fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: toggle comment lines should take tabsize into account\" : function() {\n        var session = new EditSession([\"  //  abc\", \"  // cde\", \"//    fg\"]);\n        session.setTabSize(2);\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"    abc\", \"  cde\", \"    fg\"].join(\"\\n\"), session.toString());\n        session.setTabSize(4);\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"//     abc\", \"//   cde\", \"//     fg\"].join(\"\\n\"), session.toString());\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"    abc\", \"  cde\", \"    fg\"].join(\"\\n\"), session.toString());\n        \n        session.insert({row: 0, column: 0}, \" \");\n        this.mode.toggleCommentLines(\"start\", session, 0, 2);\n        assert.equal([\"//      abc\", \"//   cde\", \"//     fg\"].join(\"\\n\"), session.toString());        \n    },\n    //there doesn't seem to be any way to make this work\n    \"!test: togglecomment on line with one space\" : function() {\n        var session = new EditSession([\" abc\", \"  // cde\", \"//    fg\"]);\n        var initialValue = session + \"\";\n        session.setTabSize(4);\n        this.mode.toggleCommentLines(\"start\", session, 0, 0);\n        this.mode.toggleCommentLines(\"start\", session, 0, 0);\n        assert.equal(initialValue, session.toString());\n    },\n\n    \"test: auto indent after opening brace\" : function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"if () {\", \"  \"));\n    },\n    \n    \"test: auto indent after case\" : function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"case 'juhu':\", \"  \"));\n    },\n\n    \"test: no auto indent in object literal\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"{ 'juhu':\", \"  \"));\n    },\n\n    \"test: no auto indent after opening brace in multi line comment\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"/*if () {\", \"  \"));\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"comment\", \"  abcd\", \"  \"));\n    },\n\n    \"test: no auto indent after opening brace in single line comment\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"//if () {\", \"  \"));\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"  //if () {\", \"  \"));\n    },\n\n    \"test: no auto indent should add to existing indent\" : function() {\n        assert.equal(\"      \", this.mode.getNextLineIndent(\"start\", \"    if () {\", \"  \"));\n        assert.equal(\"    \", this.mode.getNextLineIndent(\"start\", \"    cde\", \"  \"));\n        assert.equal(\"    \", this.mode.getNextLineIndent(\"start\", \"function foo(items) {\", \"    \"));\n    },\n    \n    \"test: no indent after doc comments\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"doc-start\", \"   */\", \"  \"));\n    },\n\n    \"test: trigger outdent if line is space and new text starts with closing brace\" : function() {\n        assert.ok(this.mode.checkOutdent(\"start\", \"   \", \" }\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \" a  \", \" }\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"\", \"}\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"   \", \"a }\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"   }\", \"}\"));\n    },\n\n    \"test: auto outdent should indent the line with the same indent as the line with the matching opening brace\" : function() {\n        var session = new EditSession([\"  function foo() {\", \"    bla\", \"    }\"], new JavaScriptMode());\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"  }\", session.getLine(2));\n    },\n\n    \"test: no auto outdent if no matching brace is found\" : function() {\n        var session = new EditSession([\"  function foo()\", \"    bla\", \"    }\"]);\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"    }\", session.getLine(2));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/jexl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JexlHighlightRules = require(\"./jexl_highlight_rules\").JexlHighlightRules;\nvar TextMode = require(\"./text\").Mode;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = JexlHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n    this.lineCommentStart = [\"//\", \"##\"];\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/jexl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jexl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JexlHighlightRules = function () {\n\n    var keywords = \"return|var|function|and|or|not|if|for|while|do|continue|break\";\n    var buildinConstants = \"null\";\n    var supportFunc = \"empty|size|new\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants,\n        \"support.function\": supportFunc\n    }, \"identifier\");\n\n    var escapedRe = \"\\\\\\\\(?:x[0-9a-fA-F]{2}|\" + // hex\n        \"u[0-9a-fA-F]{4}|\" + // unicode\n        \"u{[0-9a-fA-F]{1,6}}|\" + // es6 unicode\n        \"|.)\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"comment\",\n                regex: \"\\\\/\\\\/.*$\"\n            }, {\n                token: \"comment\",\n                regex: \"##.*$\"\n            }, {\n                token: \"comment\", // multi line comment\n                regex: \"\\\\/\\\\*\",\n                next: \"comment\"\n            }, {\n                token: [\"comment\", \"text\"],\n                regex: \"(#pragma)(\\\\s.*$)\"\n            }, {\n                token: \"string\", // single line\n                regex: '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token: \"string\", // single line\n                regex: \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token: \"string\", // multi line string\n                regex: \"`\",\n                push: [\n                    {\n                        token: \"constant.language.escape\",\n                        regex: escapedRe\n                    }, {\n                        token: \"string\",\n                        regex: \"`\",\n                        next: \"pop\"\n                    }, {\n                        token: \"lparen\", //interpolation\n                        regex: \"\\\\${\",\n                        push: [\n                            {\n                                token: \"rparen\",\n                                regex: \"}\",\n                                next: \"pop\"\n                            }, {\n                                include: \"start\"\n                            }\n                        ]\n                    }, {\n                        defaultToken: \"string\"\n                    }\n                ]\n            }, {\n                token: \"constant.numeric\", // hex\n                regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\\b/\n            }, {\n                token: \"constant.numeric\", // float\n                regex: /[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?[LlSsDdFfYy]?\\b/\n            }, {\n                token: \"constant.language.boolean\",\n                regex: \"(?:true|false)\\\\b\"\n            }, {\n                token: \"string.regexp\",\n                regex: \"~/\",\n                push: [\n                    {\n                        token: \"constant.language.escape\",\n                        regex: \"\\\\\\\\/\"\n                    }, {\n                        token: \"string.regexp\",\n                        regex: \"$|/\",\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"string.regexp\"\n                    }\n                ]\n            }, {\n                token: keywordMapper,\n                regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token: \"keyword.operator\",\n                regex: \"&&|\\\\|\\\\||!|&|\\\\||\\\\^|~|\\\\?|:|\\\\?\\\\?|==|!=|<|<=|>|>=|=~|!~|=\\\\^|=\\\\$|!\\\\$|\\\\+|\\\\-|\\\\*|%|\\\\/|=\"\n            }, {\n                token: \"lparen\",\n                regex: \"[[({]\"\n            }, {\n                token: \"rparen\",\n                regex: \"[\\\\])}]\"\n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }, {\n                token: \"punctuation\",\n                regex: \"[,.]\"\n            }, {\n                token: \"storage.type.annotation\",\n                regex: \"@[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }\n        ],\n        \"comment\": [\n            {\n                token: \"comment\",\n                regex: \"\\\\*\\\\/\",\n                next: \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }\n        ]\n    };\n\n\n    this.normalizeRules();\n};\n\noop.inherits(JexlHighlightRules, TextHighlightRules);\n\nexports.JexlHighlightRules = JexlHighlightRules;\n"
  },
  {
    "path": "src/mode/js_regex_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar escape = \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\";\nvar quantifier = \"({\\\\d+\\\\b,?\\\\d*}|[+*?])(\\\\??)\";\n\nvar JsRegexHighlightRules = function() {\n    this.$rules = {\n        \"start\": [{\n                // operators\n                token : \"keyword\",\n                regex: \"\\\\\\\\[bB]\",\n                next: \"no_quantifier\"\n            }, {\n                token: \"regexp.keyword.operator\",\n                regex: escape\n            }, {\n                // flag\n                token: \"string.regexp\",\n                regex: \"/\\\\w*\",\n                next: \"start\"\n            }, {               \n                token : [\"string\", \"string.regex\"],\n                regex: quantifier,\n                next: \"no_quantifier\"\n            }, {\n                // operators\n                token : \"keyword\",\n                regex: \"[$^]|\\\\\\\\[bB]\",\n                next: \"no_quantifier\"\n            }, {\n                // operators\n                token : \"constant.language.escape\",\n                regex: /\\(\\?[:=!]|\\)|[()$^+*?]/,\n                next: \"no_quantifier\"\n            }, {\n                token : \"constant.language.delimiter\",\n                regex: /\\|/,\n                next: \"no_quantifier\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\[\\^?/,\n                next: \"character_class\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"start\"\n            }\n        ],\n        \n\n        \"character_class\": [{\n                regex: /\\\\[dDwWsS]/\n            },{\n                token: \"markup.list\",\n                regex: \"(?:\" + escape + \"|.)-(?:[^\\\\]\\\\\\\\]|\" + escape + \")\"\n            }, {\n                token: \"keyword\",\n                regex: escape\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"]\",\n                next: \"start\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"-\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"start\"\n            }, {\n                defaultToken: \"string.regexp.charachterclass\"\n            }\n        ],\n        \"no_quantifier\":[{\n                token: \"invalid\",\n                regex: quantifier\n            }, {\n                token: \"invalid\",\n                regex: \"\",\n                next: \"start\"\n            }\n        ]\n        \n    };\n};\n\noop.inherits(JsRegexHighlightRules, TextHighlightRules);\n\nexports.JsRegexHighlightRules = JsRegexHighlightRules;\n"
  },
  {
    "path": "src/mode/jsdoc_comment_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JsDocCommentHighlightRules = function() {\n    this.$rules = {\n        \"start\": [\n            {\n                token: [\"comment.doc.tag\", \"comment.doc.text\", \"lparen.doc\"],\n                regex: \"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\\\s*)({)\",\n                push: [\n                    {\n                        token: \"lparen.doc\",\n                        regex: \"{\",\n                        push: [\n                            {\n                                include: \"doc-syntax\"\n                            }, {\n                                token: \"rparen.doc\",\n                                regex: \"}|(?=$)\",\n                                next: \"pop\"\n                            }\n                        ]\n                    }, {\n                        token: [\"rparen.doc\", \"text.doc\", \"variable.parameter.doc\", \"lparen.doc\", \"variable.parameter.doc\", \"rparen.doc\"],\n                        regex: /(})(\\s*)(?:([\\w=:\\/\\.]+)|(?:(\\[)([\\w=:\\/\\.\\-\\'\\\" ]+)(\\])))/,\n                        next: \"pop\"\n                    }, {\n                        token: \"rparen.doc\",\n                        regex: \"}|(?=$)\",\n                        next: \"pop\"\n                    }, {\n                        include: \"doc-syntax\"\n                    }, {\n                        defaultToken: \"text.doc\"\n                    }\n                ]\n            }, {\n                token: [\"comment.doc.tag\", \"text.doc\", \"lparen.doc\"],\n                regex: \"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|\" \n                    + \"implements|external|exception|throws|enum|define|extends))(\\\\s*)({)\",\n                push: [\n                    {\n                        token: \"lparen.doc\",\n                        regex: \"{\",\n                        push: [\n                            {\n                                include: \"doc-syntax\"\n                            }, {\n                                token: \"rparen.doc\",\n                                regex: \"}|(?=$)\",\n                                next: \"pop\"\n                            }\n                        ]\n                    }, {\n                        token: \"rparen.doc\",\n                        regex: \"}|(?=$)\",\n                        next: \"pop\"\n                    }, {\n                        include: \"doc-syntax\"\n                    }, {\n                        defaultToken: \"text.doc\"\n                    }\n                    ]\n            }, {\n                token: [\"comment.doc.tag\", \"text.doc\", \"variable.parameter.doc\"],\n                regex: \"(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|\" \n                    + \"requires|param|implements|function|extends|typedef|mixes|constructor|var|\" \n                    + \"memberof\\\\!|event|listens|exports|class|constructs|interface|emits|fires|\" \n                    + \"throws|const|callback|borrows|augments))(\\\\s+)(\\\\w[\\\\w#\\.:\\/~\\\"\\\\-]*)?\"\n            }, {\n                token: [\"comment.doc.tag\", \"text.doc\", \"variable.parameter.doc\"],\n                regex: \"(@method)(\\\\s+)(\\\\w[\\\\w\\.\\\\(\\\\)]*)\"\n            }, {\n                token: \"comment.doc.tag\",\n                regex: \"@access\\\\s+(?:private|public|protected)\"\n            }, {\n                token: \"comment.doc.tag\",\n                regex: \"@kind\\\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)\"\n            }, {\n                token: \"comment.doc.tag\",\n                regex: \"@\\\\w+(?=\\\\s|$)\"\n            },\n            JsDocCommentHighlightRules.getTagRule(),\n        {\n            defaultToken: \"comment.doc.body\",\n            caseInsensitive: true\n        }],\n        \"doc-syntax\": [{\n            token: \"operator.doc\",\n            regex: /[|:]/\n        }, {\n            token: \"paren.doc\",\n            regex: /[\\[\\]]/\n        }]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(JsDocCommentHighlightRules, TextHighlightRules);\n\nJsDocCommentHighlightRules.getTagRule = function(start) {\n    return {\n        token : \"comment.doc.tag.storage.type\",\n        regex : \"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"\n    };\n};\n\nJsDocCommentHighlightRules.getStartRule = function(start) {\n    return {\n        token : \"comment.doc\", // doc comment\n        regex: /\\/\\*\\*(?!\\/)/,\n        next  : start\n    };\n};\n\nJsDocCommentHighlightRules.getEndRule = function (start) {\n    return {\n        token : \"comment.doc\", // closing comment\n        regex : \"\\\\*\\\\/\",\n        next  : start\n    };\n};\n\n\nexports.JsDocCommentHighlightRules = JsDocCommentHighlightRules;\n"
  },
  {
    "path": "src/mode/json.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./json_highlight_rules\").JsonHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/json_worker\", \"JsonWorker\");\n        worker.attachToDocument(session.getDocument());\n\n        worker.on(\"annotate\", function(e) {\n            session.setAnnotations(e.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n\n    this.$id = \"ace/mode/json\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/json5.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./json5_highlight_rules\").Json5HighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/json5\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/json5_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JsonHighlightRules = require(\"./json_highlight_rules\").JsonHighlightRules;\n\nvar Json5HighlightRules = function() {\n    JsonHighlightRules.call(this);\n\n    var startRules = [{\n        token : \"variable\",\n        regex : /[a-zA-Z$_\\u00a1-\\uffff][\\w$\\u00a1-\\uffff]*\\s*(?=:)/\n    }, {\n        token : \"variable\",\n        regex : /['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']\\s*(?=:)/\n    }, {\n        token : \"constant.language.boolean\",\n        regex : /(?:null)\\b/\n    }, {\n        token : \"string\",\n        regex : /'/,\n        next  : [{\n            token : \"constant.language.escape\",\n            regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[\"\\/bfnrt]|$)/,\n            consumeLineEnd  : true\n        }, {\n            token : \"string\",\n            regex : /'|$/,\n            next  : \"start\"\n        }, {\n            defaultToken : \"string\"\n        }]\n    }, {\n        token : \"string\",\n        regex : /\"(?![^\"]*\":)/,\n        next  : [{\n            token : \"constant.language.escape\",\n            regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[\"\\/bfnrt]|$)/,\n            consumeLineEnd  : true\n        }, {\n            token : \"string\",\n            regex : /\"|$/,\n            next  : \"start\"\n        }, {\n            defaultToken : \"string\"\n        }]\n    }, {\n        token : \"constant.numeric\",\n        regex : /[+-]?(?:Infinity|NaN)\\b/\n    }];\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n    this.normalizeRules();\n};\n\noop.inherits(Json5HighlightRules, JsonHighlightRules);\n\nexports.Json5HighlightRules = Json5HighlightRules;\n"
  },
  {
    "path": "src/mode/json_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JsonHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"variable\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]\\\\s*(?=:)'\n            }, {\n                token : \"string\", // single line\n                regex : '\"',\n                next  : \"string\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : \"text\", // single quoted strings are not allowed\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"comment\", // comments are not allowed, but who cares?\n                regex : \"\\\\/\\\\/.*$\"\n            }, {\n                token : \"comment.start\", // comments are not allowed, but who cares?\n                regex : \"\\\\/\\\\*\",\n                next  : \"comment\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[,]/\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"string\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[\"\\\\\\/bfnrt])/\n            }, {\n                token : \"string\",\n                regex : '\"|$',\n                next  : \"start\"\n            }, {\n                defaultToken : \"string\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment.end\", // comments are not allowed, but who cares?\n                regex : \"\\\\*\\\\/\",\n                next  : \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }\n        ]\n    };\n    \n};\n\noop.inherits(JsonHighlightRules, TextHighlightRules);\n\nexports.JsonHighlightRules = JsonHighlightRules;\n"
  },
  {
    "path": "src/mode/jsp.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar JspHighlightRules = require(\"./jsp_highlight_rules\").JspHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = JspHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.$id = \"ace/mode/jsp\";\n    this.snippetFileId = \"ace/snippets/jsp\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jsp_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar JavaHighlightRules = require(\"./java_highlight_rules\").JavaHighlightRules;\n\nvar JspHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    var builtinVariables = 'request|response|out|session|' +\n            'application|config|pageContext|page|Exception';\n\n    var keywords = 'page|include|taglib';\n\n    var startRules = [\n        {\n            token : \"comment\",\n            regex : \"<%--\",\n            push : \"jsp-dcomment\"\n        }, {\n            token : \"meta.tag\", // jsp open tag\n            regex : \"<%@?|<%=?|<%!?|<jsp:[^>]+>\",\n            push  : \"jsp-start\"\n        }\n    ];\n\n    var endRules = [\n        {\n            token : \"meta.tag\", // jsp close tag\n            regex : \"%>|<\\\\/jsp:[^>]+>\",\n            next  : \"pop\"\n        }, {\n            token: \"variable.language\",\n            regex : builtinVariables\n        }, {\n            token: \"keyword\",\n            regex : keywords\n        }\n    ];\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n    this.embedRules(JavaHighlightRules, \"jsp-\", endRules, [\"start\"]);\n\n    this.addRules({\n        \"jsp-dcomment\" : [{\n            token : \"comment\",\n            regex : \".*?--%>\",\n            next : \"pop\"\n        }]\n    });\n\n    this.normalizeRules();\n};\n\noop.inherits(JspHighlightRules, HtmlHighlightRules);\n\nexports.JspHighlightRules = JspHighlightRules;\n"
  },
  {
    "path": "src/mode/jssm.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar JSSMHighlightRules = require(\"./jssm_highlight_rules\").JSSMHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = JSSMHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/jssm\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jssm_highlight_rules.js",
    "content": "/* This file was autogenerated from ./jssm.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JSSMHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"punctuation.definition.comment.mn\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"punctuation.definition.comment.mn\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.jssm\"\n            }],\n            comment: \"block comment\"\n        }, {\n            token: \"comment.line.jssm\",\n            regex: /\\/\\//,\n            push: [{\n                token: \"comment.line.jssm\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.line.jssm\"\n            }],\n            comment: \"block comment\"\n        }, {\n            token: \"entity.name.function\",\n            regex: /\\${/,\n            push: [{\n                token: \"entity.name.function\",\n                regex: /}/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"keyword.other\"\n            }],\n            comment: \"js outcalls\"\n        }, {\n            token: \"constant.numeric\",\n            regex: /[0-9]*\\.[0-9]*\\.[0-9]*/,\n            comment: \"semver\"\n        }, {\n            token: \"constant.language.jssmLanguage\",\n            regex: /graph_layout\\s*:/,\n            comment: \"jssm language tokens\"\n        }, {\n            token: \"constant.language.jssmLanguage\",\n            regex: /machine_name\\s*:/,\n            comment: \"jssm language tokens\"\n        }, {\n            token: \"constant.language.jssmLanguage\",\n            regex: /machine_version\\s*:/,\n            comment: \"jssm language tokens\"\n        }, {\n            token: \"constant.language.jssmLanguage\",\n            regex: /jssm_version\\s*:/,\n            comment: \"jssm language tokens\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.legal_legal\",\n            regex: /<->/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.legal_none\",\n            regex: /<-/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.none_legal\",\n            regex: /->/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.main_main\",\n            regex: /<=>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.none_main\",\n            regex: /=>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.main_none\",\n            regex: /<=/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.forced_forced\",\n            regex: /<~>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.none_forced\",\n            regex: /~>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.forced_none\",\n            regex: /<~/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.legal_main\",\n            regex: /<-=>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.main_legal\",\n            regex: /<=->/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.legal_forced\",\n            regex: /<-~>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.forced_legal\",\n            regex: /<~->/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.main_forced\",\n            regex: /<=~>/,\n            comment: \"transitions\"\n        }, {\n            token: \"keyword.control.transition.jssmArrow.forced_main\",\n            regex: /<~=>/,\n            comment: \"transitions\"\n        }, {\n            token: \"constant.numeric.jssmProbability\",\n            regex: /[0-9]+%/,\n            comment: \"edge probability annotation\"\n        }, {\n            token: \"constant.character.jssmAction\",\n            regex: /\\'[^']*\\'/,\n            comment: \"action annotation\"\n        }, {\n            token: \"entity.name.tag.jssmLabel.doublequoted\",\n            regex: /\\\"[^\"]*\\\"/,\n            comment: \"jssm label annotation\"\n        }, {\n            token: \"entity.name.tag.jssmLabel.atom\",\n            regex: /[a-zA-Z0-9_.+&()#@!?,]/,\n            comment: \"jssm label annotation\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nJSSMHighlightRules.metaData = {\n    fileTypes: [\"jssm\", \"jssm_state\"],\n    name: \"JSSM\",\n    scopeName: \"source.jssm\"\n};\n\n\noop.inherits(JSSMHighlightRules, TextHighlightRules);\n\nexports.JSSMHighlightRules = JSSMHighlightRules;\n"
  },
  {
    "path": "src/mode/jsx.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar jsMode = require(\"./javascript\").Mode;\n\nfunction Mode() {\n    jsMode.call(this);\n    this.$highlightRuleConfig = {jsx: true};\n}\noop.inherits(Mode, jsMode);\n\n(function() {\n    // disable jshint\n    this.createWorker = function() {\n        return null;\n    };\n    this.$id = \"ace/mode/jsx\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/jsx_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\n\nvar JsxHighlightRules = function () {\n  JavaScriptHighlightRules.call(this, {\n    jsx: true\n  });\n};\noop.inherits(JsxHighlightRules, JavaScriptHighlightRules);\n\nexports.JsxHighlightRules = JsxHighlightRules;"
  },
  {
    "path": "src/mode/julia.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar JuliaHighlightRules = require(\"./julia_highlight_rules\").JuliaHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = JuliaHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.blockComment = \"\";\n    this.$id = \"ace/mode/julia\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/julia_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/JuliaLang/julia/master/contrib/Julia.tmbundle/Syntaxes/Julia.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar JuliaHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { include: '#function_decl' },\n         { include: '#function_call' },\n         { include: '#type_decl' },\n         { include: '#keyword' },\n         { include: '#operator' },\n         { include: '#number' },\n         { include: '#string' },\n         { include: '#comment' } ],\n      '#bracket': \n       [ { token: 'keyword.bracket.julia',\n           regex: '\\\\(|\\\\)|\\\\[|\\\\]|\\\\{|\\\\}|,' } ],\n      '#comment': \n       [ { token: \n            [ 'punctuation.definition.comment.julia',\n              'comment.line.number-sign.julia' ],\n           regex: '(#)(?!\\\\{)(.*$)'} ],\n      '#function_call': \n       [ { token: [ 'support.function.julia', 'text' ],\n           regex: '([a-zA-Z0-9_]+!?)([\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]*\\\\()'} ],\n      '#function_decl': \n       [ { token: [ 'keyword.other.julia', 'meta.function.julia',\n               'entity.name.function.julia', 'meta.function.julia','text' ],\n           regex: '(function|macro)(\\\\s*)([a-zA-Z0-9_\\\\{]+!?)([\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]*)([(\\\\\\\\{])'} ],\n      '#keyword':\n       [ { token: 'keyword.other.julia',\n           regex: '\\\\b(?:function|type|immutable|macro|quote|abstract|bitstype|typealias|module|baremodule|new)\\\\b' },\n         { token: 'keyword.control.julia',\n           regex: '\\\\b(?:if|else|elseif|while|for|in|begin|let|end|do|try|catch|finally|return|break|continue)\\\\b' },\n         { token: 'storage.modifier.variable.julia',\n           regex: '\\\\b(?:global|local|const|export|import|importall|using)\\\\b' },\n         { token: 'variable.macro.julia', regex: '@[\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]+\\\\b' } ],\n      '#number': \n       [ { token: 'constant.numeric.julia',\n           regex: '\\\\b0(?:x|X)[0-9a-fA-F]*|(?:\\\\b[0-9]+\\\\.?[0-9]*|\\\\.[0-9]+)(?:(?:e|E)(?:\\\\+|-)?[0-9]*)?(?:im)?|\\\\bInf(?:32)?\\\\b|\\\\bNaN(?:32)?\\\\b|\\\\btrue\\\\b|\\\\bfalse\\\\b' } ],\n      '#operator': \n       [ { token: 'keyword.operator.update.julia',\n           regex: '=|:=|\\\\+=|-=|\\\\*=|/=|//=|\\\\.//=|\\\\.\\\\*=|\\\\\\\\=|\\\\.\\\\\\\\=|^=|\\\\.^=|%=|\\\\|=|&=|\\\\$=|<<=|>>=' },\n         { token: 'keyword.operator.ternary.julia', regex: '\\\\?|:' },\n         { token: 'keyword.operator.boolean.julia',\n           regex: '\\\\|\\\\||&&|!' },\n         { token: 'keyword.operator.arrow.julia', regex: '->|<-|-->' },\n         { token: 'keyword.operator.relation.julia',\n           regex: '>|<|>=|<=|==|!=|\\\\.>|\\\\.<|\\\\.>=|\\\\.>=|\\\\.==|\\\\.!=|\\\\.=|\\\\.!|<:|:>' },\n         { token: 'keyword.operator.range.julia', regex: ':' },\n         { token: 'keyword.operator.shift.julia', regex: '<<|>>' },\n         { token: 'keyword.operator.bitwise.julia', regex: '\\\\||\\\\&|~' },\n         { token: 'keyword.operator.arithmetic.julia',\n           regex: '\\\\+|-|\\\\*|\\\\.\\\\*|/|\\\\./|//|\\\\.//|%|\\\\.%|\\\\\\\\|\\\\.\\\\\\\\|\\\\^|\\\\.\\\\^' },\n         { token: 'keyword.operator.isa.julia', regex: '::' },\n         { token: 'keyword.operator.dots.julia',\n           regex: '\\\\.(?=[a-zA-Z])|\\\\.\\\\.+' },\n         { token: 'keyword.operator.interpolation.julia',\n           regex: '\\\\$#?(?=.)' },\n         { token: [ 'variable', 'keyword.operator.transposed-variable.julia' ],\n           regex: '([\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]+)((?:\\'|\\\\.\\')*\\\\.?\\')' },\n         { token: 'text',\n           regex: '\\\\[|\\\\('},\n         { token: [ 'text', 'keyword.operator.transposed-matrix.julia' ],\n            regex: \"([\\\\]\\\\)])((?:'|\\\\.')*\\\\.?')\"} ],\n      '#string': \n       [ { token: 'punctuation.definition.string.begin.julia',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.julia',\n                regex: '\\'',\n                next: 'pop' },\n              { include: '#string_escaped_char' },\n              { defaultToken: 'string.quoted.single.julia' } ] },\n         { token: 'punctuation.definition.string.begin.julia',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.julia',\n                regex: '\"',\n                next: 'pop' },\n              { include: '#string_escaped_char' },\n              { defaultToken: 'string.quoted.double.julia' } ] },\n         { token: 'punctuation.definition.string.begin.julia',\n           regex: '\\\\b[\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]+\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.julia',\n                regex: '\"[\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]*',\n                next: 'pop' },\n              { include: '#string_custom_escaped_char' },\n              { defaultToken: 'string.quoted.custom-double.julia' } ] },\n         { token: 'punctuation.definition.string.begin.julia',\n           regex: '`',\n           push: \n            [ { token: 'punctuation.definition.string.end.julia',\n                regex: '`',\n                next: 'pop' },\n              { include: '#string_escaped_char' },\n              { defaultToken: 'string.quoted.backtick.julia' } ] } ],\n      '#string_custom_escaped_char': [ { token: 'constant.character.escape.julia', regex: '\\\\\\\\\"' } ],\n      '#string_escaped_char': \n       [ { token: 'constant.character.escape.julia',\n           regex: '\\\\\\\\(?:\\\\\\\\|[0-3]\\\\d{,2}|[4-7]\\\\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8}|.)' } ],\n      '#type_decl': \n       [ { token: \n            [ 'keyword.control.type.julia',\n              'meta.type.julia',\n              'entity.name.type.julia',\n              'entity.other.inherited-class.julia',\n              'punctuation.separator.inheritance.julia',\n              'entity.other.inherited-class.julia' ],\n           regex: '(type|immutable)(\\\\s+)([a-zA-Z0-9_]+)(?:(\\\\s*)(<:)(\\\\s*[.a-zA-Z0-9_:]+))?' },\n         { token: [ 'other.typed-variable.julia', 'support.type.julia' ],\n           regex: '([a-zA-Z0-9_]+)(::[a-zA-Z0-9_{}]+)' } ] };\n    \n    this.normalizeRules();\n};\n\nJuliaHighlightRules.metaData = { fileTypes: [ 'jl' ],\n      firstLineMatch: '^#!.*\\\\bjulia\\\\s*$',\n      foldingStartMarker: '^\\\\s*(?:if|while|for|begin|function|macro|module|baremodule|type|immutable|let)\\\\b(?!.*\\\\bend\\\\b).*$',\n      foldingStopMarker: '^\\\\s*(?:end)\\\\b.*$',\n      name: 'Julia',\n      scopeName: 'source.julia' };\n\n\noop.inherits(JuliaHighlightRules, TextHighlightRules);\n\nexports.JuliaHighlightRules = JuliaHighlightRules;\n"
  },
  {
    "path": "src/mode/kotlin.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar KotlinHighlightRules = require(\"./kotlin_highlight_rules\").KotlinHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = KotlinHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/kotlin\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/kotlin_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar KotlinHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var keywordMapper = this.$keywords = this.createKeywordMapper({\n        \"storage.modifier.kotlin\": \"var|val|public|private|protected|abstract|final|enum|open|attribute|\"\n            + \"annotation|override|inline|var|val|vararg|lazy|in|out|internal|data|tailrec|operator|infix|const|\"\n            + \"yield|typealias|typeof|sealed|inner|value|lateinit|external|suspend|noinline|crossinline|reified|\"\n            + \"expect|actual\",\n        \"keyword\": \"companion|class|object|interface|namespace|type|fun|constructor|if|else|while|for|do|return|when|\"\n            + \"where|break|continue|try|catch|finally|throw|in|is|as|assert|constructor\",\n        \"constant.language.kotlin\": \"true|false|null|this|super\",\n        \"entity.name.function.kotlin\": \"get|set\"\n    }, \"identifier\");\n\n    this.$rules = {\n        start: [{\n            include: \"#comments\"\n        }, {\n            token: [\n                \"text\",\n                \"keyword.other.kotlin\",\n                \"text\",\n                \"entity.name.package.kotlin\",\n                \"text\"\n            ],\n            regex: /^(\\s*)(package)\\b(?:(\\s*)([^ ;$]+)(\\s*))?/\n        }, {\n            token: \"comment\",\n            regex: /^\\s*#!.*$/\n        }, {\n            include: \"#imports\"\n        }, {\n            include: \"#expressions\"\n        }, {\n            token: \"string\",\n            regex: /@[a-zA-Z][a-zA-Z:]*\\b/\n        }, {\n            token: [\"keyword.other.kotlin\", \"text\", \"entity.name.variable.kotlin\"],\n            regex: /\\b(var|val)(\\s+)([a-zA-Z_][\\w]*)\\b/\n        }, {\n            token: [\"keyword.other.kotlin\", \"text\", \"entity.name.variable.kotlin\", \"paren.lparen\"],\n            regex: /(fun)(\\s+)(\\w+)(\\()/,\n            push: [{\n                token: [\"variable.parameter.function.kotlin\", \"text\", \"keyword.operator\"],\n                regex: /(\\w+)(\\s*)(:)/\n            }, {\n                token: \"paren.rparen\",\n                regex: /\\)/,\n                next: \"pop\"\n            }, {\n                include: \"#comments\"\n            }, {\n                include: \"#types\"\n            }, {\n                include: \"#expressions\"\n            }]\n        }, {\n            token: [\"text\", \"keyword\",\"text\", \"identifier\"],\n            regex: /^(\\s*)(class)(\\s*)([a-zA-Z]+)/,\n            next: \"#classes\"\n        }, {\n            token: [\"identifier\", \"punctuaction\"],\n            regex: /([a-zA-Z_][\\w]*)(<)/,\n            push: [{\n                include: \"#generics\"\n            }, {\n                include: \"#defaultTypes\"\n            }, {\n                token: \"punctuation\",\n                regex: />/,\n                next: \"pop\"\n            }]\n        }, {\n            token: keywordMapper,\n            regex: /[a-zA-Z_][\\w]*\\b/\n        }, {\n            token: \"paren.lparen\",\n            regex: /[{(\\[]/\n        }, {\n            token: \"paren.rparen\",\n            regex: /[})\\]]/\n        }],\n        \"#comments\": [{\n            token: \"comment\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"comment\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment\"\n            }]\n        }, {\n            token: [\n                \"text\",\n                \"comment\"\n            ],\n            regex: /(\\s*)(\\/\\/.*$)/\n        }],\n        \"#constants\": [{\n            token: \"constant.numeric.kotlin\",\n            regex: /\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\\b/\n        }, {\n            token: \"constant.other.kotlin\",\n            regex: /\\b[A-Z][A-Z0-9_]+\\b/\n        }],\n        \"#expressions\": [{\n            include: \"#strings\"\n        }, {\n            include: \"#constants\"\n        }, {\n            include: \"#keywords\"\n        }],\n        \"#imports\": [{\n            token: [\n                \"text\",\n                \"keyword.other.kotlin\",\n                \"text\",\n                \"keyword.other.kotlin\"\n            ],\n            regex: /^(\\s*)(import)(\\s+[^ $]+\\s+)((?:as)?)/\n        }],\n        \"#generics\": [{\n            token: \"punctuation\",\n            regex: /</,\n            push: [{\n                token: \"punctuation\",\n                regex: />/,\n                next: \"pop\"\n            }, {\n                token: \"storage.type.generic.kotlin\",\n                regex: /\\w+/\n            }, {\n                token: \"keyword.operator\",\n                regex: /:/\n            }, {\n                token: \"punctuation\",\n                regex: /,/\n            }, {\n                include: \"#generics\"\n            }]\n        }],\n        \"#classes\": [{\n            include: \"#generics\"\n        }, {\n            token: \"keyword\",\n            regex: /public|private|constructor/\n        }, {\n            token: \"string\",\n            regex: /@[a-zA-Z][a-zA-Z:]*\\b/\n        }, {\n            token: \"text\",\n            regex: /(?=$|\\(|{)/,\n            next: \"start\"\n        }],\n        \"#keywords\": [{\n            token: \"keyword.operator.kotlin\",\n            regex: /==|!=|===|!==|<=|>=|<|>|=>|->|::|\\?:/\n        }, {\n            token: \"keyword.operator.assignment.kotlin\",\n            regex: /=/\n        }, {\n            token: \"keyword.operator.declaration.kotlin\",\n            regex: /:/,\n            push: [{\n                token: \"text\",\n                regex: /(?=$|{|=|,)/,\n                next: \"pop\"\n            }, {\n                include: \"#types\"\n            }]\n        }, {\n            token: \"keyword.operator.dot.kotlin\",\n            regex: /\\./\n        }, {\n            token: \"keyword.operator.increment-decrement.kotlin\",\n            regex: /\\-\\-|\\+\\+/\n        }, {\n            token: \"keyword.operator.arithmetic.kotlin\",\n            regex: /\\-|\\+|\\*|\\/|%/\n        }, {\n            token: \"keyword.operator.arithmetic.assign.kotlin\",\n            regex: /\\+=|\\-=|\\*=|\\/=/\n        }, {\n            token: \"keyword.operator.logical.kotlin\",\n            regex: /!|&&|\\|\\|/\n        }, {\n            token: \"keyword.operator.range.kotlin\",\n            regex: /\\.\\./\n        }, {\n            token: \"punctuation.kotlin\",\n            regex: /[;,]/\n        }],\n        \"#types\": [{\n            include: \"#defaultTypes\"\n        }, {\n            token: \"paren.lparen\",\n            regex: /\\(/,\n            push: [{\n                token: \"paren.rparen\",\n                regex: /\\)/,\n                next: \"pop\"\n            }, {\n                include: \"#defaultTypes\"\n            }, {\n                token: \"punctuation\",\n                regex: /,/\n            }]\n        }, {\n            include: \"#generics\"\n        }, {\n            token: \"keyword.operator.declaration.kotlin\",\n            regex: /->/\n        }, {\n            token: \"paren.rparen\",\n            regex: /\\)/\n        }, {\n            token: \"keyword.operator.declaration.kotlin\",\n            regex: /:/,\n            push: [{\n                token: \"text\",\n                regex: /(?=$|{|=|,)/,\n                next: \"pop\"\n            }, {\n                include: \"#types\"\n            }]\n        }],\n        \"#defaultTypes\": [{\n            token: \"storage.type.buildin.kotlin\",\n            regex: /\\b(Any|Unit|String|Int|Boolean|Char|Long|Double|Float|Short|Byte|dynamic|IntArray|BooleanArray|CharArray|LongArray|DoubleArray|FloatArray|ShortArray|ByteArray|Array|List|Map|Nothing|Enum|Throwable|Comparable)\\b/\n        }],\n        \"#strings\": [{\n            token: \"string\",\n            regex: /\"\"\"/,\n            push: [{\n                token: \"string\",\n                regex: /\"\"\"/,\n                next: \"pop\"\n            }, {\n                token: \"variable.parameter.template.kotlin\",\n                regex: /\\$\\w+|\\${[^}]+}/\n            }, {\n                token: \"constant.character.escape.kotlin\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: /\"/,\n            push: [{\n                token: \"string\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"variable.parameter.template.kotlin\",\n                regex: /\\$\\w+|\\$\\{[^\\}]+\\}/\n            }, {\n                token: \"constant.character.escape.kotlin\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: /'/,\n            push: [{\n                token: \"string\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.kotlin\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: /`/,\n            push: [{\n                token: \"string\",\n                regex: /`/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nKotlinHighlightRules.metaData = {\n    fileTypes: [\"kt\", \"kts\"],\n    name: \"Kotlin\",\n    scopeName: \"source.Kotlin\"\n};\n\n\noop.inherits(KotlinHighlightRules, TextHighlightRules);\n\nexports.KotlinHighlightRules = KotlinHighlightRules;\n"
  },
  {
    "path": "src/mode/latex.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LatexHighlightRules = require(\"./latex_highlight_rules\").LatexHighlightRules;\nvar CstyleBehaviour = require(\"./behaviour/cstyle\").CstyleBehaviour;\nvar LatexFoldMode = require(\"./folding/latex\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = LatexHighlightRules;\n    this.foldingRules = new LatexFoldMode();\n    this.$behaviour = new CstyleBehaviour({ braces: true });\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    \n    this.lineCommentStart = \"%\";\n\n    this.$id = \"ace/mode/latex\";\n    \n    this.getMatching = function(session, row, column) {\n        if (row == undefined)\n            row = session.selection.lead;\n        if (typeof row == \"object\") {\n            column = row.column;\n            row = row.row;\n        }\n\n        var startToken = session.getTokenAt(row, column);\n        if (!startToken)\n            return;\n        if (startToken.value == \"\\\\begin\" || startToken.value == \"\\\\end\") {\n            return this.foldingRules.latexBlock(session, row, column, true);\n        }\n    };\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/latex_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LatexHighlightRules = function() {  \n\n    this.$rules = {\n        \"start\" : [{\n            // A comment. Tex comments start with % and go to \n            // the end of the line\n            token : \"comment\",\n            regex : \"%.*$\"\n        }, {\n            // Documentclass and usepackage\n            token : [\"keyword\", \"lparen\", \"variable.parameter\", \"rparen\", \"lparen\", \"storage.type\", \"rparen\"],\n            regex : \"(\\\\\\\\(?:documentclass|usepackage|input))(?:(\\\\[)([^\\\\]]*)(\\\\]))?({)([^}]*)(})\"\n        }, {\n            // A label\n            token : [\"keyword\",\"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\(?:label|v?ref|cite(?:[^{]*)))(?:({)([^}]*)(}))?\"\n        }, {\n            // A Verbatim block\n            token : [\"storage.type\", \"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\begin)({)(verbatim)(})\",\n            next : \"verbatim\"\n        },  {\n            token : [\"storage.type\", \"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\begin)({)(lstlisting)(})\",\n            next : \"lstlisting\"\n        },  {\n            // A block\n            token : [\"storage.type\", \"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\(?:begin|end))({)([\\\\w*]*)(})\"\n        }, {\n            token : \"storage.type\",\n            regex : /\\\\verb\\b\\*?/,\n            next : [{\n                token : [\"keyword.operator\", \"string\", \"keyword.operator\"],\n                regex : \"(.)(.*?)(\\\\1|$)|\",\n                next : \"start\"\n            }]\n        }, {\n            // A tex command e.g. \\foo\n            token : \"storage.type\",\n            regex : \"\\\\\\\\[a-zA-Z]+\"\n        }, {\n            // Curly and square braces\n            token : \"lparen\",\n            regex : \"[[({]\"\n        }, {\n            // Curly and square braces\n            token : \"rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            // Escaped character (including new line)\n            token : \"constant.character.escape\",\n            regex : \"\\\\\\\\[^a-zA-Z]?\"\n        }, {\n            // An equation\n            token : \"string\",\n            regex : \"\\\\${1,2}\",\n            next  : \"equation\"\n        }],\n        \"equation\" : [{\n            token : \"comment\",\n            regex : \"%.*$\"\n        }, {\n            token : \"string\",\n            regex : \"\\\\${1,2}\",\n            next  : \"start\"\n        }, {\n            token : \"constant.character.escape\",\n            regex : \"\\\\\\\\(?:[^a-zA-Z]|[a-zA-Z]+)\"\n        }, {\n            token : \"error\", \n            regex : \"^\\\\s*$\", \n            next : \"start\" \n        }, {\n            defaultToken : \"string\"\n        }],\n        \"verbatim\": [{\n            token : [\"storage.type\", \"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\end)({)(verbatim)(})\",\n            next : \"start\"\n        }, {\n            defaultToken : \"text\"\n        }],\n        \"lstlisting\": [{\n            token : [\"storage.type\", \"lparen\", \"variable.parameter\", \"rparen\"],\n            regex : \"(\\\\\\\\end)({)(lstlisting)(})\",\n            next : \"start\"\n        }, {\n            defaultToken : \"text\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\noop.inherits(LatexHighlightRules, TextHighlightRules);\n\nexports.LatexHighlightRules = LatexHighlightRules;\n"
  },
  {
    "path": "src/mode/latte.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar LatteHighlightRules = require(\"./latte_highlight_rules\").LatteHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = LatteHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.blockComment = {start: \"{*\", end: \"*}\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*\\{(?:if|else|elseif|ifset|elseifset|ifchanged|switch|case|foreach|iterateWhile|for|while|first|last|sep|try|capture|spaceless|snippet|block|define|embed|snippetArea)\\b[^{]*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return /^\\s+\\{\\/$/.test(line + input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n    };\n\n    this.$id = \"ace/mode/latte\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/latte_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LatteHighlightRules = function() {\n    // inherit from html\n    HtmlHighlightRules.call(this);\n\n    // add latte start tags to the HTML\n    for (var rule in this.$rules) {\n        this.$rules[rule].unshift(\n            {\n                token : \"comment.start.latte\",\n                regex : \"\\\\{\\\\*\",\n                push : [{\n                    token : \"comment.end.latte\",\n                    regex : \".*\\\\*\\\\}\",\n                    next : \"pop\"\n                }, {\n                    defaultToken : \"comment\"\n                }]\n            }, {\n                token : \"meta.tag.punctuation.tag-open.latte\",\n                regex : \"\\\\{(?![\\\\s'\\\"{}]|$)/?\",\n                push : [{\n                    token : \"meta.tag.latte\",\n                    regex : \"(?:_|=|[a-z]\\\\w*(?:[.:-]\\\\w+)*)?\",\n                    next: [{\n                        token : \"meta.tag.punctuation.tag-close.latte\",\n                        regex : \"\\\\}\",\n                        next : \"pop\"\n                    }, {\n                        include: \"latte-content\"\n                    }]\n                }]\n        });\n    }\n\n    // add n:attribute to HTML tag\n    this.$rules['tag_stuff'].unshift({\n        token : \"meta.attribute.latte\",\n        regex : \"n:[\\\\w-]+\",\n        next : [{\n            include: \"tag_whitespace\"\n        }, {\n            token : \"keyword.operator.attribute-equals.xml\",\n            regex : \"=\",\n            next : [{\n                token : \"string.attribute-value.xml\",\n                regex : \"'\",\n                next : [\n                    {token : \"string.attribute-value.xml\", regex: \"'\", next: \"tag_stuff\"},\n                    {include : \"latte-content\"}\n                ]\n            }, {\n                token : \"string.attribute-value.xml\",\n                regex : '\"',\n                next : [\n                    {token : \"string.attribute-value.xml\", regex: '\"', next: \"tag_stuff\"},\n                    {include : \"latte-content\"}\n                ]\n            }, {\n                token : \"text.tag-whitespace.xml\",\n                regex : \"\\\\s\",\n                next: \"tag_stuff\"\n            }, {\n                token : \"meta.tag.punctuation.tag-close.xml\",\n                regex : \"/?>\",\n                next: \"tag_stuff\"\n            }, {\n               include : \"latte-content\"\n            }]\n        }, {\n            token : \"empty\",\n            regex : \"\",\n            next : \"tag_stuff\"\n        }]\n    });\n\n\n    // PHP content\n    this.$rules[\"latte-content\"] = [\n        {\n            token : \"comment.start.latte\", // multi line comment\n            regex : \"\\\\/\\\\*\",\n            push : [\n                {\n                    token : \"comment.end.latte\",\n                    regex : \"\\\\*\\\\/\",\n                    next : \"pop\"\n                }, {\n                    defaultToken : \"comment\"\n                }\n            ]\n        }, {\n            token : \"string.start\", // \" string start\n            regex : '\"',\n            push : [\n                {\n                    token : \"constant.language.escape\",\n                    regex : '\\\\\\\\(?:[nrtvef\\\\\\\\\"$]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})'\n                }, {\n                    token : \"variable\",\n                    regex : /\\$[\\w]+(?:\\[[\\w\\]+]|[=\\-]>\\w+)?/\n                }, {\n                    token : \"variable\",\n                    regex : /\\$\\{[^\"\\}]+\\}?/           // this is wrong but ok for now\n                },\n                {token : \"string.end\", regex : '\"', next : \"pop\"},\n                {defaultToken : \"string\"}\n            ]\n        }, {\n            token : \"string.start\", // ' string start\n            regex : \"'\",\n            push : [\n                {token : \"constant.language.escape\", regex : /\\\\['\\\\]/},\n                {token : \"string.end\", regex : \"'\", next : \"pop\"},\n                {defaultToken : \"string\"}\n            ]\n        }, {\n            token : \"keyword.control\",\n            regex : \"\\\\b(?:INF|NAN|and|or|xor|AND|OR|XOR|clone|new|instanceof|return|continue|break|as)\\\\b\"\n        }, {\n            token : \"constant.language\",\n            regex : \"\\\\b(?:true|false|null|TRUE|FALSE|NULL)\\\\b\"\n        }, {\n            token : \"variable\",\n            regex : /\\$\\w+/\n        }, {\n            token : \"constant.numeric\",\n            regex : \"[+-]?[0-9]+(?:\\\\.[0-9]+)?(?:e[0-9]+)?\"\n        }, {\n            token : [\"support.class\", \"keyword.operator\"],\n            regex : \"\\\\b(\\\\w+)(::)\"\n        }, {\n            token : \"constant.language\", // constants\n            regex : \"\\\\b(?:[A-Z0-9_]+)\\\\b\"\n        }, {\n            token : \"string.unquoted\",\n            regex : \"\\\\w+(?:-+\\\\w+)*\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[[({]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"::|=>|->|\\\\?->|\\\\?\\\\?->|\\\\+\\\\+|--|<<|>>|<=>|<=|>=|===|!==|==|!=|<>|&&|\\\\|\\\\||\\\\?\\\\?|\\\\?>|\\\\*\\\\*|\\\\.\\\\.\\\\.|[^'\\\"]\" // =>, any char except quotes\n        }\n    ];\n\n    this.normalizeRules();\n};\n\noop.inherits(LatteHighlightRules, TextHighlightRules);\n\nexports.LatteHighlightRules = LatteHighlightRules;\n"
  },
  {
    "path": "src/mode/less.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LessHighlightRules = require(\"./less_highlight_rules\").LessHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CssBehaviour = require(\"./behaviour/css\").CssBehaviour;\nvar CssCompletions = require(\"./css_completions\").CssCompletions;\n\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = LessHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = new CssBehaviour();\n    this.$completer = new CssCompletions();\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        // ignore braces in comments\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        var match = line.match(/^.*\\{\\s*$/);\n        if (match) {\n            indent += tab;\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        // CSS completions only work with single (not nested) rulesets\n        return this.$completer.getCompletions(\"ruleset\", session, pos, prefix);\n    };\n\n    this.$id = \"ace/mode/less\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/less_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CssHighlightRules = require('./css_highlight_rules');\n\nvar LessHighlightRules = function() {\n\n\n    var keywordList = \"@import|@media|@font-face|@keyframes|@-webkit-keyframes|@supports|\" + \n        \"@charset|@plugin|@namespace|@document|@page|@viewport|@-ms-viewport|\" +\n        \"or|and|when|not\";\n\n    var keywords = keywordList.split('|');\n\n    var properties = CssHighlightRules.supportType.split('|');\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.constant\": CssHighlightRules.supportConstant,\n        \"keyword\": keywordList,\n        \"support.constant.color\": CssHighlightRules.supportConstantColor,\n        \"support.constant.fonts\": CssHighlightRules.supportConstantFonts\n    }, \"identifier\", true);   \n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var numRe = \"\\\\-?(?:(?:[0-9]+)|(?:[0-9]*\\\\.[0-9]+))\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : [\"constant.numeric\", \"keyword\"],\n                regex : \"(\" + numRe + \")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)\"\n            }, {\n                token : \"constant.numeric\", // hex6 color\n                regex : \"#[a-f0-9]{6}\"\n            }, {\n                token : \"constant.numeric\", // hex3 color\n                regex : \"#[a-f0-9]{3}\"\n            }, {\n                token : \"constant.numeric\",\n                regex : numRe\n            }, {\n                token : [\"support.function\", \"paren.lparen\", \"string\", \"paren.rparen\"],\n                regex : \"(url)(\\\\()(.*)(\\\\))\"\n            }, {\n                token : [\"support.function\", \"paren.lparen\"],\n                regex : \"(:extend|[a-z0-9_\\\\-]+)(\\\\()\"\n            }, {\n                token : function(value) {\n                    if (keywords.indexOf(value.toLowerCase()) > -1)\n                        return \"keyword\";\n                    else\n                        return \"variable\";\n                },\n                regex : \"[@\\\\$][a-z0-9_\\\\-@\\\\$]*\\\\b\"\n            }, {\n                token : \"variable\",\n                regex : \"[@\\\\$]\\\\{[a-z0-9_\\\\-@\\\\$]*\\\\}\"\n            }, {\n                token : function(first, second) {\n                    if(properties.indexOf(first.toLowerCase()) > -1) {\n                        return [\"support.type.property\", \"text\"];\n                    }\n                    else {\n                        return [\"support.type.unknownProperty\", \"text\"];\n                    }\n                },\n                regex : \"([a-z0-9-_]+)(\\\\s*:)\"\n            }, {\n                token : \"keyword\",\n                regex : \"&\"   // special case - always treat as keyword\n            }, {\n                token : keywordMapper,\n                regex : \"\\\\-?[@a-z_][@a-z0-9_\\\\-]*\"\n            }, {\n                token: \"variable.language\",\n                regex: \"#[a-z0-9-_]+\"\n            }, {\n                token: \"variable.language\",\n                regex: \"\\\\.[a-z0-9-_]+\"\n            }, {\n                token: \"variable.language\",\n                regex: \":[a-z_][a-z0-9-_]*\"\n            }, {\n                token: \"constant\",\n                regex: \"[a-z0-9-_]+\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"<|>|<=|>=|=|!=|-|%|\\\\+|\\\\*\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }, {\n                caseInsensitive: true\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(LessHighlightRules, TextHighlightRules);\n\nexports.LessHighlightRules = LessHighlightRules;\n"
  },
  {
    "path": "src/mode/liquid.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HtmlMode = require(\"./html\").Mode;\nvar JavascriptMode = require(\"./javascript\").Mode;\nvar JsonMode = require(\"./json\").Mode;\nvar CssMode = require(\"./css\").Mode;\nvar LiquidHighlightRules = require(\"./liquid_highlight_rules\").LiquidHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\n/* -------------------------------------------- */\n/* FOLDS                                        */\n/* -------------------------------------------- */\n\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\n/* -------------------------------------------- */\n/* MODE                                         */\n/* -------------------------------------------- */\n\nvar Mode = function () {\n\n  JsonMode.call(this);\n  HtmlMode.call(this);\n  CssMode.call(this);\n  JavascriptMode.call(this);\n  this.HighlightRules = LiquidHighlightRules;\n  this.foldingRules = new FoldMode();\n\n};\n\noop.inherits(Mode, TextMode);\n\n(function () {\n\n    this.blockComment = {start: \"<!--\", end: \"-->\"};\n    this.voidElements = new HtmlMode().voidElements;\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/liquid\";\n    this.snippetFileId = \"ace/snippets/liquid\";\n\n}.call(Mode.prototype));\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/liquid_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\n\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CssHighlightRules = require(\"./css_highlight_rules\").CssHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar JsonHighlightRules = require(\"./json_highlight_rules\").JsonHighlightRules;\nvar JavaScriptHighlightRules =  require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nvar LiquidHighlightRules = function () {\n\n  HtmlHighlightRules.call(this);\n\n  /**\n   * Embedded Matches\n   *\n   * Handles `onMatch` tokens and correct parses the\n   * inner contents of the tag.\n   */\n  function onMatchEmbedded(name) {\n\n    const length = name.length;\n\n    return function (value) {\n\n      const idx = value.indexOf(name);\n\n      const x = [\n        {\n          type: \"meta.tag.punctuation.tag-open\",\n          value: \"{%\"\n        },\n        {\n          type: \"text\",\n          value: value.slice(2, idx)\n        },\n        {\n          type: \"keyword.tag\" + name + \".tag-name\",\n          value: value.slice(idx, idx + length)\n        },\n        {\n          type: \"text\",\n          value: value.slice(idx + length, value.indexOf(\"%}\"))\n        },\n        {\n          type: \"meta.tag.punctuation.tag-close\",\n          value: \"%}\"\n        }\n      ];\n\n      return x;\n    };\n  }\n\n\n  for (var rule in this.$rules) {\n\n    this.$rules[rule].unshift(\n      {\n        token: \"comment.block\",\n        regex: /{%-?\\s*comment\\s*-?%}/,\n        next: [\n          {\n            token: \"comment.block\",\n            regex: /{%-?\\s*endcomment\\s*-?%}/,\n            next: \"pop\"\n          },\n          {\n            defaultToken: \"comment\",\n            caseInsensitive: false\n          }\n        ]\n      },\n      {\n        token: \"comment.line\",\n        regex: /{%-?\\s*#/,\n        next: [\n          {\n            token: \"comment.line\",\n            regex: /-?%}/,\n            next: \"pop\"\n          },\n          {\n            defaultToken: \"comment\",\n            caseInsensitive: false\n          }\n        ]\n      },\n      {\n        token: 'style.embedded.start',\n        regex: /({%-?\\s*\\bstyle\\b\\s*-?%})/,\n        next: \"style-start\",\n        onMatch: onMatchEmbedded(\"style\")\n      },\n      {\n        regex: /({%-?\\s*\\bstylesheet\\b\\s*-?%})/,\n        next: \"stylesheet-start\",\n        onMatch: onMatchEmbedded(\"stylesheet\")\n      },\n      {\n        regex: /({%-?\\s*\\bschema\\b\\s*-?%})/,\n        next: \"schema-start\",\n        onMatch: onMatchEmbedded(\"schema\")\n      },\n      {\n        regex: /({%-?\\s*\\bjavascript\\b\\s*-?%})/,\n        next: \"javascript-start\",\n        onMatch: onMatchEmbedded(\"javascript\")\n      },\n      {\n        token: \"meta.tag.punctuation.tag-open\",\n        regex: /({%)/,\n        next: [\n          {\n              token: \"keyword.block\",\n              regex: /-?\\s*[a-zA-Z_$][a-zA-Z0-9_$]+\\b/,\n              next: 'liquid-start'\n          },\n          {\n            token: \"meta.tag.punctuation.tag-close\",\n            regex: /(-?)(%})/,\n            next: \"pop\"\n          }\n        ]\n      },\n      {\n        token: \"meta.tag.punctuation.ouput-open\",\n        regex: /({{)/,\n        push: \"liquid-start\"\n      }\n    );\n  }\n\n  /* -------------------------------------------- */\n  /* EMBEDDED REGIONS                             */\n  /* -------------------------------------------- */\n\n  this.embedRules(JsonHighlightRules, \"schema-\", [\n    {\n      token: \"schema-start\",\n      next: \"pop\",\n      regex: /({%-?\\s*\\bendschema\\b\\s*-?%})/,\n      onMatch: onMatchEmbedded(\"endschema\")\n    }\n  ]);\n\n  this.embedRules(JavaScriptHighlightRules, \"javascript-\", [\n    {\n      token: \"javascript-start\",\n      next: \"pop\",\n      regex: /({%-?\\s*\\bendjavascript\\b\\s*-?%})/,\n      onMatch: onMatchEmbedded(\"endjavascript\")\n    }\n  ]);\n\n\n\n  this.embedRules(CssHighlightRules, \"style-\", [\n    {\n      token: \"style-start\",\n      next: \"pop\",\n      regex: /({%-?\\s*\\bendstyle\\b\\s*-?%})/,\n      onMatch: onMatchEmbedded(\"endstyle\")\n    }\n  ]);\n\n  this.embedRules(CssHighlightRules, \"stylesheet-\", [\n    {\n      token: \"stylesheet-start\",\n      next: \"pop\",\n      regex: /({%-?\\s*\\bendstylesheet\\b\\s*-?%})/,\n      onMatch: onMatchEmbedded(\"endstylesheet\")\n    }\n  ]);\n\n  /* -------------------------------------------- */\n  /* LIQUID GRAMMARS                              */\n  /* -------------------------------------------- */\n\n  this.addRules({\n    \"liquid-start\": [\n      {\n        token: \"meta.tag.punctuation.ouput-close\",\n        regex: /}}/,\n        next: \"pop\"\n      },\n      {\n        token: \"meta.tag.punctuation.tag-close\",\n        regex: /%}/,\n        next: \"pop\"\n      },\n      {\n        token: \"string\",\n        regex: /['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']/\n      },\n      {\n        token: \"string\",\n        regex: /[\"](?:(?:\\\\.)|(?:[^'\\\\]))*?[\"]/\n      },\n      {\n        token: \"constant.numeric\",\n        regex: /0[xX][0-9a-fA-F]+\\b/\n      },\n      {\n        token: \"constant.numeric\",\n        regex: /[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/\n      },\n      {\n        token: \"keyword.operator\",\n        regex: /\\*|\\-|\\+|=|!=|\\?\\|\\:/\n      },\n      {\n        token: \"constant.language.boolean\",\n        regex: /(?:true|false|nil|empty)\\b/\n      },\n      {\n        token: \"keyword.operator\",\n        regex: /\\s+(?:and|contains|in|with)\\b\\s+/\n      },\n      {\n        token: [\"keyword.operator\", \"support.function\"],\n        regex: /(\\|\\s*)([a-zA-Z_]+)/\n\n      },\n      {\n        token: \"support.function\",\n        regex: /\\s*([a-zA-Z_]+\\b)(?=:)/\n      },\n      {\n        token: \"keyword.operator\",\n        regex:\n          /(:)\\s*(?=[a-zA-Z_])/\n      },\n      {\n        token: [\n          \"support.class\",\n          \"keyword.operator\",\n          \"support.object\",\n          \"keyword.operator\",\n          \"variable.parameter\"\n        ],\n        regex: /(\\w+)(\\.)(\\w+)(\\.)?(\\w+)?/\n      },\n      {\n        token: \"variable.parameter\",\n        regex: /\\.([a-zA-Z_$][a-zA-Z0-9_$]*\\b)$/\n      },\n      {\n        token: \"support.class\",\n        regex: /(?:additional_checkout_buttons|content_for_additional_checkout_buttons)\\b/\n      },\n      {\n        token: \"paren.lparen\",\n        regex: /[\\[\\({]/\n      },\n      {\n        token: \"paren.rparen\",\n        regex: /[\\])}]/\n      },\n      {\n        token: \"text\",\n        regex: /\\s+/\n      }\n    ]\n  });\n\n  this.normalizeRules();\n\n};\n\noop.inherits(LiquidHighlightRules, TextHighlightRules);\n\nexports.LiquidHighlightRules = LiquidHighlightRules;\n"
  },
  {
    "path": "src/mode/lisp.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LispHighlightRules = require(\"./lisp_highlight_rules\").LispHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = LispHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n       \n    this.lineCommentStart = \";\";\n    \n    this.$id = \"ace/mode/lisp\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/lisp_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY Lisp.tmlanguage (UUID: 00D451C9-6B1D-11D9-8DFA-000D93589AF6) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LispHighlightRules = function() {\n    var keywordControl = \"case|do|let|loop|if|else|when\";\n    var keywordOperator = \"eq|neq|and|or\";\n    var constantLanguage = \"null|nil\";\n    var supportFunctions = \"cons|car|cdr|cond|lambda|format|setq|setf|quote|eval|append|list|listp|memberp|t|load|progn\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control\": keywordControl,\n        \"keyword.operator\": keywordOperator,\n        \"constant.language\": constantLanguage,\n        \"support.function\": supportFunctions\n    }, \"identifier\", true);\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = \n        {\n    \"start\": [\n        {\n            token : \"comment\",\n            regex : \";.*$\"\n        },\n        {\n            token: [\"storage.type.function-type.lisp\", \"text\", \"entity.name.function.lisp\"],\n            regex: \"(?:\\\\b(?:(defun|defmethod|defmacro))\\\\b)(\\\\s+)((?:\\\\w|\\\\-|\\\\!|\\\\?)*)\"\n        },\n        {\n            token: [\"punctuation.definition.constant.character.lisp\", \"constant.character.lisp\"],\n            regex: \"(#)((?:\\\\w|[\\\\\\\\+-=<>'\\\"&#])+)\"\n        },\n        {\n            token: [\"punctuation.definition.variable.lisp\", \"variable.other.global.lisp\", \"punctuation.definition.variable.lisp\"],\n            regex: \"(\\\\*)(\\\\S*)(\\\\*)\"\n        },\n        {\n            token : \"constant.numeric\", // hex\n            regex : \"0[xX][0-9a-fA-F]+(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n        }, \n        {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n        },\n        {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        },\n        {\n            token : \"string\",\n            regex : '\"(?=.)',\n            next  : \"qqstring\"\n        }\n    ],\n    \"qqstring\": [\n        {\n            token: \"constant.character.escape.lisp\",\n            regex: \"\\\\\\\\.\"\n        },\n        {\n            token : \"string\",\n            regex : '[^\"\\\\\\\\]+'\n        }, {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        }, {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"start\"\n        }\n    ]\n};\n\n};\n\noop.inherits(LispHighlightRules, TextHighlightRules);\n\nexports.LispHighlightRules = LispHighlightRules;\n"
  },
  {
    "path": "src/mode/livescript.js",
    "content": "var identifier, LiveScriptMode, keywordend, stringfill;\n  identifier = '(?![\\\\d\\\\s])[$\\\\w\\\\xAA-\\\\uFFDC](?:(?!\\\\s)[$\\\\w\\\\xAA-\\\\uFFDC]|-[A-Za-z])*';\n  exports.Mode = LiveScriptMode = (function(superclass){\n    var indenter, prototype = extend$((import$(LiveScriptMode, superclass).displayName = 'LiveScriptMode', LiveScriptMode), superclass).prototype, constructor = LiveScriptMode;\n    function LiveScriptMode(){\n      var that;\n      this.$tokenizer = new (require('../tokenizer')).Tokenizer(LiveScriptMode.Rules);\n      if (that = require('../mode/matching_brace_outdent')) {\n        this.$outdent = new that.MatchingBraceOutdent;\n      }\n      this.$id = \"ace/mode/livescript\";\n      this.$behaviour = new (require(\"./behaviour/cstyle\").CstyleBehaviour)();\n    }\n    indenter = RegExp('(?:[({[=:]|[-~]>|\\\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\\\s*all)?|const|var|let|new|catch(?:\\\\s*' + identifier + ')?))\\\\s*$');\n    prototype.getNextLineIndent = function(state, line, tab){\n      var indent, tokens;\n      indent = this.$getIndent(line);\n      tokens = this.$tokenizer.getLineTokens(line, state).tokens;\n      if (!(tokens.length && tokens[tokens.length - 1].type === 'comment')) {\n        if (state === 'start' && indenter.test(line)) {\n          indent += tab;\n        }\n      }\n      return indent;\n    };\n    prototype.lineCommentStart = \"#\";\n    prototype.blockComment = {start: \"###\", end: \"###\"};\n    prototype.checkOutdent = function(state, line, input){\n      var ref$;\n      return (ref$ = this.$outdent) != null ? ref$.checkOutdent(line, input) : void 8;\n    };\n    prototype.autoOutdent = function(state, doc, row){\n      var ref$;\n      return (ref$ = this.$outdent) != null ? ref$.autoOutdent(doc, row) : void 8;\n    };\n    return LiveScriptMode;\n  }(require('../mode/text').Mode));\n  keywordend = '(?![$\\\\w]|-[A-Za-z]|\\\\s*:(?![:=]))';\n  stringfill = {\n    defaultToken: 'string'\n  };\n  LiveScriptMode.Rules = {\n    start: [\n      {\n        token: 'keyword',\n        regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend\n      }, {\n        token: 'constant.language',\n        regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend\n      }, {\n        token: 'invalid.illegal',\n        regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend\n      }, {\n        token: 'language.support.class',\n        regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend\n      }, {\n        token: 'language.support.function',\n        regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend\n      }, {\n        token: 'variable.language',\n        regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend\n      }, {\n        token: 'identifier',\n        regex: identifier + '\\\\s*:(?![:=])'\n      }, {\n        token: 'variable',\n        regex: identifier\n      }, {\n        token: 'keyword.operator',\n        regex: '(?:\\\\.{3}|\\\\s+\\\\?)'\n      }, {\n        token: 'keyword.variable',\n        regex: '(?:@+|::|\\\\.\\\\.)',\n        next: 'key'\n      }, {\n        token: 'keyword.operator',\n        regex: '\\\\.\\\\s*',\n        next: 'key'\n      }, {\n        token: 'string',\n        regex: '\\\\\\\\\\\\S[^\\\\s,;)}\\\\]]*'\n      }, {\n        token: 'string.doc',\n        regex: '\\'\\'\\'',\n        next: 'qdoc'\n      }, {\n        token: 'string.doc',\n        regex: '\"\"\"',\n        next: 'qqdoc'\n      }, {\n        token: 'string',\n        regex: '\\'',\n        next: 'qstring'\n      }, {\n        token: 'string',\n        regex: '\"',\n        next: 'qqstring'\n      }, {\n        token: 'string',\n        regex: '`',\n        next: 'js'\n      }, {\n        token: 'string',\n        regex: '<\\\\[',\n        next: 'words'\n      }, {\n        token: 'string.regex',\n        regex: '//',\n        next: 'heregex'\n      }, {\n        token: 'comment.doc',\n        regex: '/\\\\*',\n        next: 'comment'\n      }, {\n        token: 'comment',\n        regex: '#.*'\n      }, {\n        token: 'string.regex',\n        regex: '\\\\/(?:[^[\\\\/\\\\n\\\\\\\\]*(?:(?:\\\\\\\\.|\\\\[[^\\\\]\\\\n\\\\\\\\]*(?:\\\\\\\\.[^\\\\]\\\\n\\\\\\\\]*)*\\\\])[^[\\\\/\\\\n\\\\\\\\]*)*)\\\\/[gimy$]{0,4}',\n        next: 'key'\n      }, {\n        token: 'constant.numeric',\n        regex: '(?:0x[\\\\da-fA-F][\\\\da-fA-F_]*|(?:[2-9]|[12]\\\\d|3[0-6])r[\\\\da-zA-Z][\\\\da-zA-Z_]*|(?:\\\\d[\\\\d_]*(?:\\\\.\\\\d[\\\\d_]*)?|\\\\.\\\\d[\\\\d_]*)(?:e[+-]?\\\\d[\\\\d_]*)?[\\\\w$]*)'\n      }, {\n        token: 'lparen',\n        regex: '[({[]'\n      }, {\n        token: 'rparen',\n        regex: '[)}\\\\]]',\n        next: 'key'\n      }, {\n        token: 'keyword.operator',\n        regex: '[\\\\^!|&%+\\\\-]+'\n      }, {\n        token: 'text',\n        regex: '\\\\s+'\n      }\n    ],\n    heregex: [\n      {\n        token: 'string.regex',\n        regex: '.*?//[gimy$?]{0,4}',\n        next: 'start'\n      }, {\n        token: 'string.regex',\n        regex: '\\\\s*#{'\n      }, {\n        token: 'comment.regex',\n        regex: '\\\\s+(?:#.*)?'\n      }, {\n        defaultToken: 'string.regex'\n      }\n    ],\n    key: [\n      {\n        token: 'keyword.operator',\n        regex: '[.?@!]+'\n      }, {\n        token: 'identifier',\n        regex: identifier,\n        next: 'start'\n      }, {\n        token: 'text',\n        regex: '',\n        next: 'start'\n      }\n    ],\n    comment: [\n      {\n        token: 'comment.doc',\n        regex: '.*?\\\\*/',\n        next: 'start'\n      }, {\n        defaultToken: 'comment.doc'\n      }\n    ],\n    qdoc: [\n      {\n        token: 'string',\n        regex: \".*?'''\",\n        next: 'key'\n      }, stringfill\n    ],\n    qqdoc: [\n      {\n        token: 'string',\n        regex: '.*?\"\"\"',\n        next: 'key'\n      }, stringfill\n    ],\n    qstring: [\n      {\n        token: 'string',\n        regex: '[^\\\\\\\\\\']*(?:\\\\\\\\.[^\\\\\\\\\\']*)*\\'',\n        next: 'key'\n      }, stringfill\n    ],\n    qqstring: [\n      {\n        token: 'string',\n        regex: '[^\\\\\\\\\"]*(?:\\\\\\\\.[^\\\\\\\\\"]*)*\"',\n        next: 'key'\n      }, stringfill\n    ],\n    js: [\n      {\n        token: 'string',\n        regex: '[^\\\\\\\\`]*(?:\\\\\\\\.[^\\\\\\\\`]*)*`',\n        next: 'key'\n      }, stringfill\n    ],\n    words: [\n      {\n        token: 'string',\n        regex: '.*?\\\\]>',\n        next: 'key'\n      }, stringfill\n    ]\n  };\nfunction extend$(sub, sup){\n  function fun(){} fun.prototype = (sub.superclass = sup).prototype;\n  (sub.prototype = new fun).constructor = sub;\n  if (typeof sup.extended == 'function') sup.extended(sub);\n  return sub;\n}\nfunction import$(obj, src){\n  var own = {}.hasOwnProperty;\n  for (var key in src) if (own.call(src, key)) obj[key] = src[key];\n  return obj;\n}\n"
  },
  {
    "path": "src/mode/logiql.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LogiQLHighlightRules = require(\"./logiql_highlight_rules\").LogiQLHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar Range = require(\"../range\").Range;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = LogiQLHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n        if (/comment|string/.test(endState))  \n            return indent;\n        if (tokens.length && tokens[tokens.length - 1].type == \"comment.single\")\n            return indent;\n\n        var match = line.match();\n        if (/(-->|<--|<-|->|{)\\s*$/.test(line))\n            indent += tab;\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (this.$outdent.checkOutdent(line, input))\n            return true;\n\n        if (input !== \"\\n\" && input !== \"\\r\\n\")\n            return false;\n            \n        if (!/^\\s+/.test(line))\n            return false;\n\n        return true;\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        if (this.$outdent.autoOutdent(doc, row))\n            return;\n        var prevLine = doc.getLine(row);\n        var match = prevLine.match(/^\\s+/);\n        var column = prevLine.lastIndexOf(\".\") + 1;\n        if (!match || !row || !column) return 0;\n\n        var line = doc.getLine(row + 1);\n        var startRange = this.getMatching(doc, {row: row, column: column});\n        if (!startRange || startRange.start.row == row) return 0;\n\n        column = match[0].length;\n        var indent = this.$getIndent(doc.getLine(startRange.start.row));\n        doc.replace(new Range(row + 1, 0, row + 1, column), indent);\n    };\n\n    this.getMatching = function(session, row, column) {\n        if (row == undefined)\n            row = session.selection.lead;\n        if (typeof row == \"object\") {\n            column = row.column;\n            row = row.row;\n        }\n\n        var startToken = session.getTokenAt(row, column);\n        var KW_START = \"keyword.start\", KW_END = \"keyword.end\";\n        var tok;\n        if (!startToken)\n            return;\n        if (startToken.type == KW_START) {\n            var it = new TokenIterator(session, row, column);\n            it.step = it.stepForward;\n        } else if (startToken.type == KW_END) {\n            var it = new TokenIterator(session, row, column);\n            it.step = it.stepBackward;\n        } else\n            return;\n\n        while (tok = it.step()) {\n            if (tok.type == KW_START || tok.type == KW_END)\n                break;\n        }\n        if (!tok || tok.type == startToken.type)\n            return;\n\n        var col = it.getCurrentTokenColumn();\n        var row = it.getCurrentTokenRow();\n        return new Range(row, col, row, col + tok.value.length);\n    };\n    this.$id = \"ace/mode/logiql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/logiql_highlight_rules.js",
    "content": "/* THIS FILE WAS AUTOGENERATED FROM tool\\LogicBlox.tmbundle\\Syntaxes\\LogicBlox.tmLanguage (UUID: 59bf5022-e261-453f-b1cb-9f9fa0712413) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LogiQLHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'comment.block',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'comment.block', regex: '\\\\*/', next: 'pop' },\n              { defaultToken: 'comment.block' } ]\n           //A block comment.\n            },\n         { token: 'comment.single',\n           regex: '//.*'\n           //A single line comment.\n            },\n         { token: 'constant.numeric',\n           regex: '\\\\d+(?:\\\\.\\\\d+)?(?:[eE][+-]?\\\\d+)?[fd]?'\n           //An integer constant.\n           //Or a Real number.\n            },\n         { token: 'string',\n           regex: '\"',\n           push: \n            [ { token: 'string', regex: '\"', next: 'pop' },\n              { defaultToken: 'string' } ]\n           //Strings\n            },\n         { token: 'constant.language',\n           regex: '\\\\b(true|false)\\\\b'\n           //Boolean values.\n            },\n         { token: 'entity.name.type.logicblox',\n           regex: '`[a-zA-Z_:]+(\\\\d|\\\\a)*\\\\b'\n           //LogicBlox Symbol\n            },\n         { token: 'keyword.start', regex: '->',  comment: 'Constraint' },\n         { token: 'keyword.start', regex: '-->', comment: 'Level 1 Constraint'},\n         { token: 'keyword.start', regex: '<-',  comment: 'Rule' },\n         { token: 'keyword.start', regex: '<--', comment: 'Level 1 Rule' },\n         { token: 'keyword.end',   regex: '\\\\.', comment: 'Terminator' },\n         { token: 'keyword.other', regex: '!',   comment: 'Negation' },\n         { token: 'keyword.other', regex: ',',   comment: 'Conjunction' },\n         { token: 'keyword.other', regex: ';',   comment: 'Disjunction' },\n         { token: 'keyword.operator', regex: '<=|>=|!=|<|>', comment: 'Equality'},\n         { token: 'keyword.other', regex: '@', comment: 'Equality' },\n         { token: 'keyword.operator', regex: '\\\\+|-|\\\\*|/', comment: 'Arithmetic operations'},\n         { token: 'keyword', regex: '::', comment: 'Colon colon' },\n         { token: 'support.function',\n           regex: '\\\\b(agg\\\\s*<<)',\n           push: \n            [ { include: '$self' },\n              { token: 'support.function',\n                regex: '>>',\n                next: 'pop' } ]\n            //Aggregations\n            },\n         { token: 'storage.modifier',\n           regex: '\\\\b(lang:[\\\\w:]*)'\n           //All the lang system predicates\n            },\n         { token: [ 'storage.type', 'text' ],\n           regex: '(export|sealed|clauses|block|alias|alias_all)(\\\\s*\\\\()(?=`)'\n           //Module keywords\n            },\n         { token: 'entity.name',\n           regex: '[a-zA-Z_][a-zA-Z_0-9:]*(@prev|@init|@final)?(?=(\\\\(|\\\\[))'\n           //A predicate name.\n            },\n         { token: 'variable.parameter',\n           regex: '([a-zA-Z][a-zA-Z_0-9]*|_)\\\\s*(?=(,|\\\\.|<-|->|\\\\)|\\\\]|=))'\n           //A variable to a functional predicate.\n            } ] };\n    \n    this.normalizeRules();\n};\n\noop.inherits(LogiQLHighlightRules, TextHighlightRules);\n\nexports.LogiQLHighlightRules = LogiQLHighlightRules;\n"
  },
  {
    "path": "src/mode/logiql_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar LogiQLMode = require(\"./logiql\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {    \n        this.mode = new LogiQLMode();\n    },\n\n    \"test: toggle comment lines should prepend '//' to each line\" : function() {\n        var session = new EditSession([\"    abc\", \"cde\", \"fg\"]);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"//     abc\", \"// cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: auto indent after ->\" : function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"parent(a, b) ->\", \"  \"));\n    },\n    \n    \"test: auto indent after <--\" : function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"foo <--    \", \"  \"));\n    },\n\n    \"test: no auto indent in multi line comment\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"/* -->\", \"  \"));\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"  /* ->\", \"    \"));\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"comment.block\", \"  abcd\", \"  \"));\n    },\n\n    \"test: no auto indent after -> in single line comment\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"//->\", \"  \"));\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"  //->\", \"  \"));\n    },\n\n    \"test: trigger outdent if line ends with .\" : function() {\n        assert.ok(this.mode.checkOutdent(\"start\", \"   \", \"\\n\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \" a  \", \"\\r\\n\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"\", \"}\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"   \", \"a }\"));\n        assert.ok(!this.mode.checkOutdent(\"start\", \"   }\", \"}\"));\n    },\n\n    \"test: auto outdent should indent the line with the same indent as the line with the matching ->\" : function() {\n        var session = new EditSession([\"  bar (a, b) ->\", \"  foo(a)[1.2]\", \"    bla.\", \"    \"], new LogiQLMode());\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"  \", session.getLine(3));\n    },\n\n    \"test: no auto outdent if no matching brace is found\" : function() {\n        var session = new EditSession([\"  bar (a, b) ->\", \"  foo(a)[1.2].\", \"    bla.\", \"    \"], new LogiQLMode());\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"    \", session.getLine(3));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/logtalk.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar LogtalkHighlightRules = require(\"./logtalk_highlight_rules\").LogtalkHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = LogtalkHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"%\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/logtalk\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/logtalk_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LogtalkHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: 'punctuation.definition.comment.logtalk',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.logtalk',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.logtalk' } ] },\n         { todo: 'fix grouping',\n           token: \n            [ 'comment.line.percentage.logtalk',\n              'punctuation.definition.comment.logtalk' ],\n           regex: '%.*$\\\\n?' },\n         { todo: 'fix grouping',\n           token: \n            [ 'storage.type.opening.logtalk',\n              'punctuation.definition.storage.type.logtalk' ],\n           regex: ':-\\\\s(?:object|protocol|category|module)(?=[(])' },\n         { todo: 'fix grouping',\n           token: \n            [ 'storage.type.closing.logtalk',\n              'punctuation.definition.storage.type.logtalk' ],\n           regex: ':-\\\\send_(?:object|protocol|category)(?=[.])' },\n         { caseInsensitive: false,\n           token: 'storage.type.relations.logtalk',\n           regex: '\\\\b(?:complements|extends|i(?:nstantiates|mp(?:orts|lements))|specializes)(?=[(])' },\n         { caseInsensitive: false,\n           todo: 'fix grouping',\n           token: \n            [ 'storage.modifier.others.logtalk',\n              'punctuation.definition.storage.modifier.logtalk' ],\n           regex: ':-\\\\s(?:e(?:lse|ndif)|built_in|dynamic|synchronized|threaded)(?=[.])' },\n         { caseInsensitive: false,\n           todo: 'fix grouping',\n           token: \n            [ 'storage.modifier.others.logtalk',\n              'punctuation.definition.storage.modifier.logtalk' ],\n           regex: ':-\\\\s(?:c(?:alls|oinductive)|e(?:lif|n(?:coding|sure_loaded)|xport)|i(?:f|n(?:clude|itialization|fo))|reexport|set_(?:logtalk|prolog)_flag|uses)(?=[(])' },\n         { caseInsensitive: false,\n           todo: 'fix grouping',\n           token: \n            [ 'storage.modifier.others.logtalk',\n              'punctuation.definition.storage.modifier.logtalk' ],\n           regex: ':-\\\\s(?:alias|info|d(?:ynamic|iscontiguous)|m(?:eta_(?:non_terminal|predicate)|ode|ultifile)|p(?:ublic|r(?:otected|ivate))|op|use(?:s|_module)|synchronized)(?=[(])' },\n         { token: 'keyword.operator.message-sending.logtalk',\n           regex: '(:|::|\\\\^\\\\^)' },\n         { token: 'keyword.operator.external-call.logtalk',\n           regex: '([{}])' },\n         { token: 'keyword.operator.mode.logtalk', regex: '(\\\\?|@)' },\n         { token: 'keyword.operator.comparison.term.logtalk',\n           regex: '(@=<|@<|@>|@>=|==|\\\\\\\\==)' },\n         { token: 'keyword.operator.comparison.arithmetic.logtalk',\n           regex: '(=<|<|>|>=|=:=|=\\\\\\\\=)' },\n         { token: 'keyword.operator.bitwise.logtalk',\n           regex: '(<<|>>|/\\\\\\\\|\\\\\\\\/|\\\\\\\\)' },\n         { token: 'keyword.operator.evaluable.logtalk',\n           regex: '\\\\b(?:e|pi|div|mod|rem)\\\\b(?![-!(^~])' },\n         { token: 'keyword.operator.evaluable.logtalk',\n           regex: '(\\\\*\\\\*|\\\\+|-|\\\\*|/|//)' },\n         { token: 'keyword.operator.misc.logtalk',\n           regex: '(:-|!|\\\\\\\\+|,|;|-->|->|=|\\\\=|\\\\.|=\\\\.\\\\.|\\\\^|\\\\bas\\\\b|\\\\bis\\\\b)' },\n         { caseInsensitive: false,\n           token: 'support.function.evaluable.logtalk',\n           regex: '\\\\b(a(bs|cos|sin|tan|tan2)|c(eiling|os)|div|exp|flo(at(_(integer|fractional)_part)?|or)|log|m(ax|in|od)|r(em|ound)|s(i(n|gn)|qrt)|t(an|runcate)|xor)(?=[(])' },\n         { token: 'support.function.control.logtalk',\n           regex: '\\\\b(?:true|fa(?:il|lse)|repeat|(?:instantiation|system)_error)\\\\b(?![-!(^~])' },\n         { token: 'support.function.control.logtalk',\n           regex: '\\\\b((?:uninstantiation|type|domain|existence|permission|representation|evaluation|resource|syntax)_error)(?=[(])' },\n         { token: 'support.function.control.logtalk',\n           regex: '\\\\b(?:ca(?:ll|tch)|ignore|throw|once)(?=[(])' },\n         { token: 'support.function.chars-and-bytes-io.logtalk',\n           regex: '\\\\b(?:(?:get|p(?:eek|ut))_(c(?:har|ode)|byte)|nl)(?=[(])' },\n         { token: 'support.function.chars-and-bytes-io.logtalk',\n           regex: '\\\\bnl\\\\b' },\n         { token: 'support.function.atom-term-processing.logtalk',\n           regex: '\\\\b(?:atom_(?:length|c(?:hars|o(?:ncat|des)))|sub_atom|char_code|number_c(?:har|ode)s)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.term-testing.logtalk',\n           regex: '\\\\b(?:var|atom(ic)?|integer|float|c(?:allable|ompound)|n(?:onvar|umber)|ground|acyclic_term)(?=[(])' },\n         { token: 'support.function.term-comparison.logtalk',\n           regex: '\\\\b(compare)(?=[(])' },\n         { token: 'support.function.term-io.logtalk',\n           regex: '\\\\b(?:read(_term)?|write(?:q|_(?:canonical|term))?|(current_)?(?:char_conversion|op))(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.term-creation-and-decomposition.logtalk',\n           regex: '\\\\b(arg|copy_term|functor|numbervars|term_variables)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.term-unification.logtalk',\n           regex: '\\\\b(subsumes_term|unify_with_occurs_check)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.stream-selection-and-control.logtalk',\n           regex: '\\\\b(?:(?:se|curren)t_(?:in|out)put|open|close|flush_output|stream_property|at_end_of_stream|set_stream_position)(?=[(])' },\n         { token: 'support.function.stream-selection-and-control.logtalk',\n           regex: '\\\\b(?:flush_output|at_end_of_stream)\\\\b' },\n         { token: 'support.function.prolog-flags.logtalk',\n           regex: '\\\\b((?:se|curren)t_prolog_flag)(?=[(])' },\n         { token: 'support.function.compiling-and-loading.logtalk',\n           regex: '\\\\b(logtalk_(?:compile|l(?:ibrary_path|oad|oad_context)|make(_target_action)?))(?=[(])' },\n         { token: 'support.function.compiling-and-loading.logtalk',\n           regex: '\\\\b(logtalk_make)\\\\b' },\n         { caseInsensitive: false,\n           token: 'support.function.event-handling.logtalk',\n           regex: '\\\\b(?:(?:abolish|define)_events|current_event)(?=[(])' },\n         { token: 'support.function.implementation-defined-hooks.logtalk',\n           regex: '\\\\b(?:(?:create|current|set)_logtalk_flag|halt)(?=[(])' },\n         { token: 'support.function.implementation-defined-hooks.logtalk',\n           regex: '\\\\b(halt)\\\\b' },\n         { token: 'support.function.sorting.logtalk',\n           regex: '\\\\b((key)?(sort))(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.entity-creation-and-abolishing.logtalk',\n           regex: '\\\\b((c(?:reate|urrent)|abolish)_(?:object|protocol|category))(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.reflection.logtalk',\n           regex: '\\\\b((object|protocol|category)_property|co(mplements_object|nforms_to_protocol)|extends_(object|protocol|category)|imp(orts_category|lements_protocol)|(instantiat|specializ)es_class)(?=[(])' },\n         { token: 'support.function.logtalk',\n           regex: '\\\\b((?:for|retract)all)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.execution-context.logtalk',\n           regex: '\\\\b(?:context|parameter|se(?:lf|nder)|this)(?=[(])' },\n         { token: 'support.function.database.logtalk',\n           regex: '\\\\b(?:a(?:bolish|ssert(?:a|z))|clause|retract(all)?)(?=[(])' },\n         { token: 'support.function.all-solutions.logtalk',\n           regex: '\\\\b((?:bag|set)of|f(?:ind|or)all)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.multi-threading.logtalk',\n           regex: '\\\\b(threaded(_(ca(?:ll|ncel)|once|ignore|exit|peek|wait|notify))?)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.engines.logtalk',\n           regex: '\\\\b(threaded_engine(_(create|destroy|self|next(?:_reified)?|yield|post|fetch))?)(?=[(])' },\n         { caseInsensitive: false,\n           token: 'support.function.reflection.logtalk',\n           regex: '\\\\b(?:current_predicate|predicate_property)(?=[(])' },\n         { token: 'support.function.event-handler.logtalk',\n           regex: '\\\\b(?:before|after)(?=[(])' },\n         { token: 'support.function.message-forwarding-handler.logtalk',\n           regex: '\\\\b(forward)(?=[(])' },\n         { token: 'support.function.grammar-rule.logtalk',\n           regex: '\\\\b(?:expand_(?:goal|term)|(?:goal|term)_expansion|phrase)(?=[(])' },\n         { token: 'punctuation.definition.string.begin.logtalk',\n           regex: '\\'',\n           push: \n            [ { token: 'constant.character.escape.logtalk',\n                regex: '\\\\\\\\([\\\\\\\\abfnrtv\"\\']|(x[a-fA-F0-9]+|[0-7]+)\\\\\\\\)' },\n              { token: 'punctuation.definition.string.end.logtalk',\n                regex: '\\'',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.single.logtalk' } ] },\n         { token: 'punctuation.definition.string.begin.logtalk',\n           regex: '\"',\n           push: \n            [ { token: 'constant.character.escape.logtalk',\n                regex: '\\\\\\\\([\\\\\\\\abfnrtv\"\\']|(x[a-fA-F0-9]+|[0-7]+)\\\\\\\\)' },\n              { token: 'punctuation.definition.string.end.logtalk',\n                regex: '\"',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.double.logtalk' } ] },\n         { token: 'constant.numeric.logtalk',\n           regex: '\\\\b(0b[0-1]+|0o[0-7]+|0x[0-9a-fA-F]+)\\\\b' },\n         { token: 'constant.numeric.logtalk',\n           regex: '\\\\b(0\\'\\\\\\\\.|0\\'.|0\\'\\'|0\\'\")' },\n         { token: 'constant.numeric.logtalk',\n           regex: '\\\\b(\\\\d+\\\\.?\\\\d*((e|E)(\\\\+|-)?\\\\d+)?)\\\\b' },\n         { token: 'variable.other.logtalk',\n           regex: '\\\\b([A-Z_][A-Za-z0-9_]*)\\\\b' } ] };\n    \n    this.normalizeRules();\n};\n\noop.inherits(LogtalkHighlightRules, TextHighlightRules);\n\nexports.LogtalkHighlightRules = LogtalkHighlightRules;\n"
  },
  {
    "path": "src/mode/lsl.js",
    "content": "\"use strict\";\n\nvar Rules = require(\"./lsl_highlight_rules\").LSLHighlightRules;\nvar Outdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar TextMode = require(\"./text\").Mode;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar oop = require(\"../lib/oop\");\n\nvar Mode = function() {\n    this.HighlightRules = Rules;\n    this.$outdent = new Outdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = [\"//\"];\n\n    this.blockComment = {\n        start: \"/*\",\n        end: \"*/\"\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type === \"comment.block.lsl\") {\n            return indent;\n        }\n\n        if (state === \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/lsl\";\n    this.snippetFileId = \"ace/snippets/lsl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/lsl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\noop.inherits(LSLHighlightRules, TextHighlightRules);\n\nfunction LSLHighlightRules() {\n    var keywordMapper = this.createKeywordMapper({\n        \"constant.language.float.lsl\" : \"DEG_TO_RAD|PI|PI_BY_TWO|RAD_TO_DEG|SQRT2|TWO_PI\",\n        \"constant.language.integer.lsl\": \"ACTIVE|AGENT|AGENT_ALWAYS_RUN|AGENT_ATTACHMENTS|AGENT_AUTOPILOT|AGENT_AWAY|AGENT_BUSY|AGENT_BY_LEGACY_NAME|AGENT_BY_USERNAME|AGENT_CROUCHING|AGENT_FLYING|AGENT_IN_AIR|AGENT_LIST_PARCEL|AGENT_LIST_PARCEL_OWNER|AGENT_LIST_REGION|AGENT_MOUSELOOK|AGENT_ON_OBJECT|AGENT_SCRIPTED|AGENT_SITTING|AGENT_TYPING|AGENT_WALKING|ALL_SIDES|ANIM_ON|ATTACH_AVATAR_CENTER|ATTACH_BACK|ATTACH_BELLY|ATTACH_CHEST|ATTACH_CHIN|ATTACH_HEAD|ATTACH_HUD_BOTTOM|ATTACH_HUD_BOTTOM_LEFT|ATTACH_HUD_BOTTOM_RIGHT|ATTACH_HUD_CENTER_1|ATTACH_HUD_CENTER_2|ATTACH_HUD_TOP_CENTER|ATTACH_HUD_TOP_LEFT|ATTACH_HUD_TOP_RIGHT|ATTACH_LEAR|ATTACH_LEFT_PEC|ATTACH_LEYE|ATTACH_LFOOT|ATTACH_LHAND|ATTACH_LHIP|ATTACH_LLARM|ATTACH_LLLEG|ATTACH_LSHOULDER|ATTACH_LUARM|ATTACH_LULEG|ATTACH_MOUTH|ATTACH_NECK|ATTACH_NOSE|ATTACH_PELVIS|ATTACH_REAR|ATTACH_REYE|ATTACH_RFOOT|ATTACH_RHAND|ATTACH_RHIP|ATTACH_RIGHT_PEC|ATTACH_RLARM|ATTACH_RLLEG|ATTACH_RSHOULDER|ATTACH_RUARM|ATTACH_RULEG|AVOID_CHARACTERS|AVOID_DYNAMIC_OBSTACLES|AVOID_NONE|CAMERA_ACTIVE|CAMERA_BEHINDNESS_ANGLE|CAMERA_BEHINDNESS_LAG|CAMERA_DISTANCE|CAMERA_FOCUS|CAMERA_FOCUS_LAG|CAMERA_FOCUS_LOCKED|CAMERA_FOCUS_OFFSET|CAMERA_FOCUS_THRESHOLD|CAMERA_PITCH|CAMERA_POSITION|CAMERA_POSITION_LAG|CAMERA_POSITION_LOCKED|CAMERA_POSITION_THRESHOLD|CHANGED_ALLOWED_DROP|CHANGED_COLOR|CHANGED_INVENTORY|CHANGED_LINK|CHANGED_MEDIA|CHANGED_OWNER|CHANGED_REGION|CHANGED_REGION_START|CHANGED_SCALE|CHANGED_SHAPE|CHANGED_TELEPORT|CHANGED_TEXTURE|CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES|CHARACTER_AVOIDANCE_MODE|CHARACTER_CMD_JUMP|CHARACTER_CMD_SMOOTH_STOP|CHARACTER_CMD_STOP|CHARACTER_DESIRED_SPEED|CHARACTER_DESIRED_TURN_SPEED|CHARACTER_LENGTH|CHARACTER_MAX_ACCEL|CHARACTER_MAX_DECEL|CHARACTER_MAX_SPEED|CHARACTER_MAX_TURN_RADIUS|CHARACTER_ORIENTATION|CHARACTER_RADIUS|CHARACTER_STAY_WITHIN_PARCEL|CHARACTER_TYPE|CHARACTER_TYPE_A|CHARACTER_TYPE_B|CHARACTER_TYPE_C|CHARACTER_TYPE_D|CHARACTER_TYPE_NONE|CLICK_ACTION_BUY|CLICK_ACTION_NONE|CLICK_ACTION_OPEN|CLICK_ACTION_OPEN_MEDIA|CLICK_ACTION_PAY|CLICK_ACTION_PLAY|CLICK_ACTION_SIT|CLICK_ACTION_TOUCH|CONTENT_TYPE_ATOM|CONTENT_TYPE_FORM|CONTENT_TYPE_HTML|CONTENT_TYPE_JSON|CONTENT_TYPE_LLSD|CONTENT_TYPE_RSS|CONTENT_TYPE_TEXT|CONTENT_TYPE_XHTML|CONTENT_TYPE_XML|CONTROL_BACK|CONTROL_DOWN|CONTROL_FWD|CONTROL_LBUTTON|CONTROL_LEFT|CONTROL_ML_LBUTTON|CONTROL_RIGHT|CONTROL_ROT_LEFT|CONTROL_ROT_RIGHT|CONTROL_UP|DATA_BORN|DATA_NAME|DATA_ONLINE|DATA_PAYINFO|DATA_SIM_POS|DATA_SIM_RATING|DATA_SIM_STATUS|DEBUG_CHANNEL|DENSITY|ERR_GENERIC|ERR_MALFORMED_PARAMS|ERR_PARCEL_PERMISSIONS|ERR_RUNTIME_PERMISSIONS|ERR_THROTTLED|ESTATE_ACCESS_ALLOWED_AGENT_ADD|ESTATE_ACCESS_ALLOWED_AGENT_REMOVE|ESTATE_ACCESS_ALLOWED_GROUP_ADD|ESTATE_ACCESS_ALLOWED_GROUP_REMOVE|ESTATE_ACCESS_BANNED_AGENT_ADD|ESTATE_ACCESS_BANNED_AGENT_REMOVE|FALSE|FORCE_DIRECT_PATH|FRICTION|GCNP_RADIUS|GCNP_STATIC|GRAVITY_MULTIPLIER|HORIZONTAL|HTTP_BODY_MAXLENGTH|HTTP_BODY_TRUNCATED|HTTP_CUSTOM_HEADER|HTTP_METHOD|HTTP_MIMETYPE|HTTP_PRAGMA_NO_CACHE|HTTP_VERBOSE_THROTTLE|HTTP_VERIFY_CERT|INVENTORY_ALL|INVENTORY_ANIMATION|INVENTORY_BODYPART|INVENTORY_CLOTHING|INVENTORY_GESTURE|INVENTORY_LANDMARK|INVENTORY_NONE|INVENTORY_NOTECARD|INVENTORY_OBJECT|INVENTORY_SCRIPT|INVENTORY_SOUND|INVENTORY_TEXTURE|JSON_APPEND|KFM_CMD_PAUSE|KFM_CMD_PLAY|KFM_CMD_SET_MODE|KFM_CMD_STOP|KFM_COMMAND|KFM_DATA|KFM_FORWARD|KFM_LOOP|KFM_MODE|KFM_PING_PONG|KFM_REVERSE|KFM_ROTATION|KFM_TRANSLATION|LAND_LEVEL|LAND_LOWER|LAND_NOISE|LAND_RAISE|LAND_REVERT|LAND_SMOOTH|LINK_ALL_CHILDREN|LINK_ALL_OTHERS|LINK_ROOT|LINK_SET|LINK_THIS|LIST_STAT_GEOMETRIC_MEAN|LIST_STAT_MAX|LIST_STAT_MEAN|LIST_STAT_MEDIAN|LIST_STAT_MIN|LIST_STAT_NUM_COUNT|LIST_STAT_RANGE|LIST_STAT_STD_DEV|LIST_STAT_SUM|LIST_STAT_SUM_SQUARES|LOOP|MASK_BASE|MASK_EVERYONE|MASK_GROUP|MASK_NEXT|MASK_OWNER|OBJECT_ATTACHED_POINT|OBJECT_BODY_SHAPE_TYPE|OBJECT_CHARACTER_TIME|OBJECT_CLICK_ACTION|OBJECT_CREATOR|OBJECT_DESC|OBJECT_GROUP|OBJECT_HOVER_HEIGHT|OBJECT_LAST_OWNER_ID|OBJECT_NAME|OBJECT_OWNER|OBJECT_PATHFINDING_TYPE|OBJECT_PHANTOM|OBJECT_PHYSICS|OBJECT_PHYSICS_COST|OBJECT_POS|OBJECT_PRIM_EQUIVALENCE|OBJECT_RENDER_WEIGHT|OBJECT_RETURN_PARCEL|OBJECT_RETURN_PARCEL_OWNER|OBJECT_RETURN_REGION|OBJECT_ROOT|OBJECT_ROT|OBJECT_RUNNING_SCRIPT_COUNT|OBJECT_SCRIPT_MEMORY|OBJECT_SCRIPT_TIME|OBJECT_SERVER_COST|OBJECT_STREAMING_COST|OBJECT_TEMP_ON_REZ|OBJECT_TOTAL_SCRIPT_COUNT|OBJECT_UNKNOWN_DETAIL|OBJECT_VELOCITY|OPT_AVATAR|OPT_CHARACTER|OPT_EXCLUSION_VOLUME|OPT_LEGACY_LINKSET|OPT_MATERIAL_VOLUME|OPT_OTHER|OPT_STATIC_OBSTACLE|OPT_WALKABLE|PARCEL_COUNT_GROUP|PARCEL_COUNT_OTHER|PARCEL_COUNT_OWNER|PARCEL_COUNT_SELECTED|PARCEL_COUNT_TEMP|PARCEL_COUNT_TOTAL|PARCEL_DETAILS_AREA|PARCEL_DETAILS_DESC|PARCEL_DETAILS_GROUP|PARCEL_DETAILS_ID|PARCEL_DETAILS_NAME|PARCEL_DETAILS_OWNER|PARCEL_DETAILS_SEE_AVATARS|PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS|PARCEL_FLAG_ALLOW_CREATE_OBJECTS|PARCEL_FLAG_ALLOW_DAMAGE|PARCEL_FLAG_ALLOW_FLY|PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_GROUP_SCRIPTS|PARCEL_FLAG_ALLOW_LANDMARK|PARCEL_FLAG_ALLOW_SCRIPTS|PARCEL_FLAG_ALLOW_TERRAFORM|PARCEL_FLAG_LOCAL_SOUND_ONLY|PARCEL_FLAG_RESTRICT_PUSHOBJECT|PARCEL_FLAG_USE_ACCESS_GROUP|PARCEL_FLAG_USE_ACCESS_LIST|PARCEL_FLAG_USE_BAN_LIST|PARCEL_FLAG_USE_LAND_PASS_LIST|PARCEL_MEDIA_COMMAND_AGENT|PARCEL_MEDIA_COMMAND_AUTO_ALIGN|PARCEL_MEDIA_COMMAND_DESC|PARCEL_MEDIA_COMMAND_LOOP|PARCEL_MEDIA_COMMAND_LOOP_SET|PARCEL_MEDIA_COMMAND_PAUSE|PARCEL_MEDIA_COMMAND_PLAY|PARCEL_MEDIA_COMMAND_SIZE|PARCEL_MEDIA_COMMAND_STOP|PARCEL_MEDIA_COMMAND_TEXTURE|PARCEL_MEDIA_COMMAND_TIME|PARCEL_MEDIA_COMMAND_TYPE|PARCEL_MEDIA_COMMAND_UNLOAD|PARCEL_MEDIA_COMMAND_URL|PASS_ALWAYS|PASS_IF_NOT_HANDLED|PASS_NEVER|PASSIVE|PATROL_PAUSE_AT_WAYPOINTS|PAYMENT_INFO_ON_FILE|PAYMENT_INFO_USED|PAY_DEFAULT|PAY_HIDE|PERMISSION_ATTACH|PERMISSION_CHANGE_LINKS|PERMISSION_CONTROL_CAMERA|PERMISSION_DEBIT|PERMISSION_OVERRIDE_ANIMATIONS|PERMISSION_RETURN_OBJECTS|PERMISSION_SILENT_ESTATE_MANAGEMENT|PERMISSION_TAKE_CONTROLS|PERMISSION_TELEPORT|PERMISSION_TRACK_CAMERA|PERMISSION_TRIGGER_ANIMATION|PERM_ALL|PERM_COPY|PERM_MODIFY|PERM_MOVE|PERM_TRANSFER|PING_PONG|PRIM_ALPHA_MODE|PRIM_ALPHA_MODE_BLEND|PRIM_ALPHA_MODE_EMISSIVE|PRIM_ALPHA_MODE_MASK|PRIM_ALPHA_MODE_NONE|PRIM_BUMP_BARK|PRIM_BUMP_BLOBS|PRIM_BUMP_BRICKS|PRIM_BUMP_BRIGHT|PRIM_BUMP_CHECKER|PRIM_BUMP_CONCRETE|PRIM_BUMP_DARK|PRIM_BUMP_DISKS|PRIM_BUMP_GRAVEL|PRIM_BUMP_LARGETILE|PRIM_BUMP_NONE|PRIM_BUMP_SHINY|PRIM_BUMP_SIDING|PRIM_BUMP_STONE|PRIM_BUMP_STUCCO|PRIM_BUMP_SUCTION|PRIM_BUMP_TILE|PRIM_BUMP_WEAVE|PRIM_BUMP_WOOD|PRIM_COLOR|PRIM_DESC|PRIM_FLEXIBLE|PRIM_FULLBRIGHT|PRIM_GLOW|PRIM_HOLE_CIRCLE|PRIM_HOLE_DEFAULT|PRIM_HOLE_SQUARE|PRIM_HOLE_TRIANGLE|PRIM_LINK_TARGET|PRIM_MATERIAL|PRIM_MATERIAL_FLESH|PRIM_MATERIAL_GLASS|PRIM_MATERIAL_METAL|PRIM_MATERIAL_PLASTIC|PRIM_MATERIAL_RUBBER|PRIM_MATERIAL_STONE|PRIM_MATERIAL_WOOD|PRIM_MEDIA_ALT_IMAGE_ENABLE|PRIM_MEDIA_AUTO_LOOP|PRIM_MEDIA_AUTO_PLAY|PRIM_MEDIA_AUTO_SCALE|PRIM_MEDIA_AUTO_ZOOM|PRIM_MEDIA_CONTROLS|PRIM_MEDIA_CONTROLS_MINI|PRIM_MEDIA_CONTROLS_STANDARD|PRIM_MEDIA_CURRENT_URL|PRIM_MEDIA_FIRST_CLICK_INTERACT|PRIM_MEDIA_HEIGHT_PIXELS|PRIM_MEDIA_HOME_URL|PRIM_MEDIA_MAX_HEIGHT_PIXELS|PRIM_MEDIA_MAX_URL_LENGTH|PRIM_MEDIA_MAX_WHITELIST_COUNT|PRIM_MEDIA_MAX_WHITELIST_SIZE|PRIM_MEDIA_MAX_WIDTH_PIXELS|PRIM_MEDIA_PARAM_MAX|PRIM_MEDIA_PERMS_CONTROL|PRIM_MEDIA_PERMS_INTERACT|PRIM_MEDIA_PERM_ANYONE|PRIM_MEDIA_PERM_GROUP|PRIM_MEDIA_PERM_NONE|PRIM_MEDIA_PERM_OWNER|PRIM_MEDIA_WHITELIST|PRIM_MEDIA_WHITELIST_ENABLE|PRIM_MEDIA_WIDTH_PIXELS|PRIM_NAME|PRIM_NORMAL|PRIM_OMEGA|PRIM_PHANTOM|PRIM_PHYSICS|PRIM_PHYSICS_SHAPE_CONVEX|PRIM_PHYSICS_SHAPE_NONE|PRIM_PHYSICS_SHAPE_PRIM|PRIM_PHYSICS_SHAPE_TYPE|PRIM_POINT_LIGHT|PRIM_POSITION|PRIM_POS_LOCAL|PRIM_ROTATION|PRIM_ROT_LOCAL|PRIM_SCULPT_FLAG_INVERT|PRIM_SCULPT_FLAG_MIRROR|PRIM_SCULPT_TYPE_CYLINDER|PRIM_SCULPT_TYPE_MASK|PRIM_SCULPT_TYPE_PLANE|PRIM_SCULPT_TYPE_SPHERE|PRIM_SCULPT_TYPE_TORUS|PRIM_SHINY_HIGH|PRIM_SHINY_LOW|PRIM_SHINY_MEDIUM|PRIM_SHINY_NONE|PRIM_SIZE|PRIM_SLICE|PRIM_SPECULAR|PRIM_TEMP_ON_REZ|PRIM_TEXGEN|PRIM_TEXGEN_DEFAULT|PRIM_TEXGEN_PLANAR|PRIM_TEXT|PRIM_TEXTURE|PRIM_TYPE|PRIM_TYPE_BOX|PRIM_TYPE_CYLINDER|PRIM_TYPE_PRISM|PRIM_TYPE_RING|PRIM_TYPE_SCULPT|PRIM_TYPE_SPHERE|PRIM_TYPE_TORUS|PRIM_TYPE_TUBE|PROFILE_NONE|PROFILE_SCRIPT_MEMORY|PSYS_PART_BF_DEST_COLOR|PSYS_PART_BF_ONE|PSYS_PART_BF_ONE_MINUS_DEST_COLOR|PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA|PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR|PSYS_PART_BF_SOURCE_ALPHA|PSYS_PART_BF_SOURCE_COLOR|PSYS_PART_BF_ZERO|PSYS_PART_BLEND_FUNC_DEST|PSYS_PART_BLEND_FUNC_SOURCE|PSYS_PART_BOUNCE_MASK|PSYS_PART_EMISSIVE_MASK|PSYS_PART_END_ALPHA|PSYS_PART_END_COLOR|PSYS_PART_END_GLOW|PSYS_PART_END_SCALE|PSYS_PART_FLAGS|PSYS_PART_FOLLOW_SRC_MASK|PSYS_PART_FOLLOW_VELOCITY_MASK|PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK|PSYS_PART_MAX_AGE|PSYS_PART_RIBBON_MASK|PSYS_PART_START_ALPHA|PSYS_PART_START_COLOR|PSYS_PART_START_GLOW|PSYS_PART_START_SCALE|PSYS_PART_TARGET_LINEAR_MASK|PSYS_PART_TARGET_POS_MASK|PSYS_PART_WIND_MASK|PSYS_SRC_ACCEL|PSYS_SRC_ANGLE_BEGIN|PSYS_SRC_ANGLE_END|PSYS_SRC_BURST_PART_COUNT|PSYS_SRC_BURST_RADIUS|PSYS_SRC_BURST_RATE|PSYS_SRC_BURST_SPEED_MAX|PSYS_SRC_BURST_SPEED_MIN|PSYS_SRC_MAX_AGE|PSYS_SRC_OMEGA|PSYS_SRC_PATTERN|PSYS_SRC_PATTERN_ANGLE|PSYS_SRC_PATTERN_ANGLE_CONE|PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY|PSYS_SRC_PATTERN_DROP|PSYS_SRC_PATTERN_EXPLODE|PSYS_SRC_TARGET_KEY|PSYS_SRC_TEXTURE|PUBLIC_CHANNEL|PURSUIT_FUZZ_FACTOR|PURSUIT_GOAL_TOLERANCE|PURSUIT_INTERCEPT|PURSUIT_OFFSET|PU_EVADE_HIDDEN|PU_EVADE_SPOTTED|PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED|PU_FAILURE_INVALID_GOAL|PU_FAILURE_INVALID_START|PU_FAILURE_NO_NAVMESH|PU_FAILURE_NO_VALID_DESTINATION|PU_FAILURE_OTHER|PU_FAILURE_PARCEL_UNREACHABLE|PU_FAILURE_TARGET_GONE|PU_FAILURE_UNREACHABLE|PU_GOAL_REACHED|PU_SLOWDOWN_DISTANCE_REACHED|RCERR_CAST_TIME_EXCEEDED|RCERR_SIM_PERF_LOW|RCERR_UNKNOWN|RC_DATA_FLAGS|RC_DETECT_PHANTOM|RC_GET_LINK_NUM|RC_GET_NORMAL|RC_GET_ROOT_KEY|RC_MAX_HITS|RC_REJECT_AGENTS|RC_REJECT_LAND|RC_REJECT_NONPHYSICAL|RC_REJECT_PHYSICAL|RC_REJECT_TYPES|REGION_FLAG_ALLOW_DAMAGE|REGION_FLAG_ALLOW_DIRECT_TELEPORT|REGION_FLAG_BLOCK_FLY|REGION_FLAG_BLOCK_TERRAFORM|REGION_FLAG_DISABLE_COLLISIONS|REGION_FLAG_DISABLE_PHYSICS|REGION_FLAG_FIXED_SUN|REGION_FLAG_RESTRICT_PUSHOBJECT|REGION_FLAG_SANDBOX|REMOTE_DATA_CHANNEL|REMOTE_DATA_REPLY|REMOTE_DATA_REQUEST|REQUIRE_LINE_OF_SIGHT|RESTITUTION|REVERSE|ROTATE|SCALE|SCRIPTED|SIM_STAT_PCT_CHARS_STEPPED|SMOOTH|STATUS_BLOCK_GRAB|STATUS_BLOCK_GRAB_OBJECT|STATUS_BOUNDS_ERROR|STATUS_CAST_SHADOWS|STATUS_DIE_AT_EDGE|STATUS_INTERNAL_ERROR|STATUS_MALFORMED_PARAMS|STATUS_NOT_FOUND|STATUS_NOT_SUPPORTED|STATUS_OK|STATUS_PHANTOM|STATUS_PHYSICS|STATUS_RETURN_AT_EDGE|STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z|STATUS_SANDBOX|STATUS_TYPE_MISMATCH|STATUS_WHITELIST_FAILED|STRING_TRIM|STRING_TRIM_HEAD|STRING_TRIM_TAIL|TOUCH_INVALID_FACE|TRAVERSAL_TYPE|TRAVERSAL_TYPE_FAST|TRAVERSAL_TYPE_NONE|TRAVERSAL_TYPE_SLOW|TRUE|TYPE_FLOAT|TYPE_INTEGER|TYPE_INVALID|TYPE_KEY|TYPE_ROTATION|TYPE_STRING|TYPE_VECTOR|VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY|VEHICLE_ANGULAR_DEFLECTION_TIMESCALE|VEHICLE_ANGULAR_FRICTION_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DIRECTION|VEHICLE_ANGULAR_MOTOR_TIMESCALE|VEHICLE_BANKING_EFFICIENCY|VEHICLE_BANKING_MIX|VEHICLE_BANKING_TIMESCALE|VEHICLE_BUOYANCY|VEHICLE_FLAG_CAMERA_DECOUPLED|VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT|VEHICLE_FLAG_HOVER_TERRAIN_ONLY|VEHICLE_FLAG_HOVER_UP_ONLY|VEHICLE_FLAG_HOVER_WATER_ONLY|VEHICLE_FLAG_LIMIT_MOTOR_UP|VEHICLE_FLAG_LIMIT_ROLL_ONLY|VEHICLE_FLAG_MOUSELOOK_BANK|VEHICLE_FLAG_MOUSELOOK_STEER|VEHICLE_FLAG_NO_DEFLECTION_UP|VEHICLE_HOVER_EFFICIENCY|VEHICLE_HOVER_HEIGHT|VEHICLE_HOVER_TIMESCALE|VEHICLE_LINEAR_DEFLECTION_EFFICIENCY|VEHICLE_LINEAR_DEFLECTION_TIMESCALE|VEHICLE_LINEAR_FRICTION_TIMESCALE|VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE|VEHICLE_LINEAR_MOTOR_DIRECTION|VEHICLE_LINEAR_MOTOR_OFFSET|VEHICLE_LINEAR_MOTOR_TIMESCALE|VEHICLE_REFERENCE_FRAME|VEHICLE_TYPE_AIRPLANE|VEHICLE_TYPE_BALLOON|VEHICLE_TYPE_BOAT|VEHICLE_TYPE_CAR|VEHICLE_TYPE_NONE|VEHICLE_TYPE_SLED|VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY|VEHICLE_VERTICAL_ATTRACTION_TIMESCALE|VERTICAL|WANDER_PAUSE_AT_WAYPOINTS|XP_ERROR_EXPERIENCES_DISABLED|XP_ERROR_EXPERIENCE_DISABLED|XP_ERROR_EXPERIENCE_SUSPENDED|XP_ERROR_INVALID_EXPERIENCE|XP_ERROR_INVALID_PARAMETERS|XP_ERROR_KEY_NOT_FOUND|XP_ERROR_MATURITY_EXCEEDED|XP_ERROR_NONE|XP_ERROR_NOT_FOUND|XP_ERROR_NOT_PERMITTED|XP_ERROR_NO_EXPERIENCE|XP_ERROR_QUOTA_EXCEEDED|XP_ERROR_RETRY_UPDATE|XP_ERROR_STORAGE_EXCEPTION|XP_ERROR_STORE_DISABLED|XP_ERROR_THROTTLED|XP_ERROR_UNKNOWN_ERROR\",\n        \"constant.language.integer.boolean.lsl\" : \"FALSE|TRUE\",\n        \"constant.language.quaternion.lsl\" : \"ZERO_ROTATION\",\n        \"constant.language.string.lsl\" : \"EOF|JSON_ARRAY|JSON_DELETE|JSON_FALSE|JSON_INVALID|JSON_NULL|JSON_NUMBER|JSON_OBJECT|JSON_STRING|JSON_TRUE|NULL_KEY|TEXTURE_BLANK|TEXTURE_DEFAULT|TEXTURE_MEDIA|TEXTURE_PLYWOOD|TEXTURE_TRANSPARENT|URL_REQUEST_DENIED|URL_REQUEST_GRANTED\",\n        \"constant.language.vector.lsl\" : \"TOUCH_INVALID_TEXCOORD|TOUCH_INVALID_VECTOR|ZERO_VECTOR\",\n        \"invalid.broken.lsl\": \"LAND_LARGE_BRUSH|LAND_MEDIUM_BRUSH|LAND_SMALL_BRUSH\",\n        \"invalid.deprecated.lsl\" : \"ATTACH_LPEC|ATTACH_RPEC|DATA_RATING|OBJECT_ATTACHMENT_GEOMETRY_BYTES|OBJECT_ATTACHMENT_SURFACE_AREA|PRIM_CAST_SHADOWS|PRIM_MATERIAL_LIGHT|PRIM_TYPE_LEGACY|PSYS_SRC_INNERANGLE|PSYS_SRC_OUTERANGLE|VEHICLE_FLAG_NO_FLY_UP|llClearExperiencePermissions|llCloud|llGetExperienceList|llMakeExplosion|llMakeFire|llMakeFountain|llMakeSmoke|llRemoteDataSetRegion|llSound|llSoundPreload|llXorBase64Strings|llXorBase64StringsCorrect\",\n        \"invalid.illegal.lsl\": \"event\",\n        \"invalid.unimplemented.lsl\": \"CHARACTER_MAX_ANGULAR_ACCEL|CHARACTER_MAX_ANGULAR_SPEED|CHARACTER_TURN_SPEED_MULTIPLIER|PERMISSION_CHANGE_JOINTS|PERMISSION_CHANGE_PERMISSIONS|PERMISSION_EXPERIENCE|PERMISSION_RELEASE_OWNERSHIP|PERMISSION_REMAP_CONTROLS|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|llCollisionSprite|llPointAt|llRefreshPrimURL|llReleaseCamera|llRemoteLoadScript|llSetPrimURL|llStopPointAt|llTakeCamera\",\n        \"reserved.godmode.lsl\": \"llGodLikeRezObject|llSetInventoryPermMask|llSetObjectPermMask\",\n        \"reserved.log.lsl\" : \"print\",\n        \"keyword.control.lsl\" : \"do|else|for|if|jump|return|while\",\n        \"storage.type.lsl\" : \"float|integer|key|list|quaternion|rotation|string|vector\",\n        \"support.function.lsl\": \"llAbs|llAcos|llAddToLandBanList|llAddToLandPassList|llAdjustSoundVolume|llAgentInExperience|llAllowInventoryDrop|llAngleBetween|llApplyImpulse|llApplyRotationalImpulse|llAsin|llAtan2|llAttachToAvatar|llAttachToAvatarTemp|llAvatarOnLinkSitTarget|llAvatarOnSitTarget|llAxes2Rot|llAxisAngle2Rot|llBase64ToInteger|llBase64ToString|llBreakAllLinks|llBreakLink|llCSV2List|llCastRay|llCeil|llClearCameraParams|llClearLinkMedia|llClearPrimMedia|llCloseRemoteDataChannel|llCollisionFilter|llCollisionSound|llCos|llCreateCharacter|llCreateKeyValue|llCreateLink|llDataSizeKeyValue|llDeleteCharacter|llDeleteKeyValue|llDeleteSubList|llDeleteSubString|llDetachFromAvatar|llDetectedGrab|llDetectedGroup|llDetectedKey|llDetectedLinkNumber|llDetectedName|llDetectedOwner|llDetectedPos|llDetectedRot|llDetectedTouchBinormal|llDetectedTouchFace|llDetectedTouchNormal|llDetectedTouchPos|llDetectedTouchST|llDetectedTouchUV|llDetectedType|llDetectedVel|llDialog|llDie|llDumpList2String|llEdgeOfWorld|llEjectFromLand|llEmail|llEscapeURL|llEuler2Rot|llEvade|llExecCharacterCmd|llFabs|llFleeFrom|llFloor|llForceMouselook|llFrand|llGenerateKey|llGetAccel|llGetAgentInfo|llGetAgentLanguage|llGetAgentList|llGetAgentSize|llGetAlpha|llGetAndResetTime|llGetAnimation|llGetAnimationList|llGetAnimationOverride|llGetAttached|llGetAttachedList|llGetBoundingBox|llGetCameraPos|llGetCameraRot|llGetCenterOfMass|llGetClosestNavPoint|llGetColor|llGetCreator|llGetDate|llGetDisplayName|llGetEnergy|llGetEnv|llGetExperienceDetails|llGetExperienceErrorMessage|llGetForce|llGetFreeMemory|llGetFreeURLs|llGetGMTclock|llGetGeometricCenter|llGetHTTPHeader|llGetInventoryCreator|llGetInventoryKey|llGetInventoryName|llGetInventoryNumber|llGetInventoryPermMask|llGetInventoryType|llGetKey|llGetLandOwnerAt|llGetLinkKey|llGetLinkMedia|llGetLinkName|llGetLinkNumber|llGetLinkNumberOfSides|llGetLinkPrimitiveParams|llGetListEntryType|llGetListLength|llGetLocalPos|llGetLocalRot|llGetMass|llGetMassMKS|llGetMaxScaleFactor|llGetMemoryLimit|llGetMinScaleFactor|llGetNextEmail|llGetNotecardLine|llGetNumberOfNotecardLines|llGetNumberOfPrims|llGetNumberOfSides|llGetObjectDesc|llGetObjectDetails|llGetObjectMass|llGetObjectName|llGetObjectPermMask|llGetObjectPrimCount|llGetOmega|llGetOwner|llGetOwnerKey|llGetParcelDetails|llGetParcelFlags|llGetParcelMaxPrims|llGetParcelMusicURL|llGetParcelPrimCount|llGetParcelPrimOwners|llGetPermissions|llGetPermissionsKey|llGetPhysicsMaterial|llGetPos|llGetPrimMediaParams|llGetPrimitiveParams|llGetRegionAgentCount|llGetRegionCorner|llGetRegionFPS|llGetRegionFlags|llGetRegionName|llGetRegionTimeDilation|llGetRootPosition|llGetRootRotation|llGetRot|llGetSPMaxMemory|llGetScale|llGetScriptName|llGetScriptState|llGetSimStats|llGetSimulatorHostname|llGetStartParameter|llGetStaticPath|llGetStatus|llGetSubString|llGetSunDirection|llGetTexture|llGetTextureOffset|llGetTextureRot|llGetTextureScale|llGetTime|llGetTimeOfDay|llGetTimestamp|llGetTorque|llGetUnixTime|llGetUsedMemory|llGetUsername|llGetVel|llGetWallclock|llGiveInventory|llGiveInventoryList|llGiveMoney|llGround|llGroundContour|llGroundNormal|llGroundRepel|llGroundSlope|llHTTPRequest|llHTTPResponse|llInsertString|llInstantMessage|llIntegerToBase64|llJson2List|llJsonGetValue|llJsonSetValue|llJsonValueType|llKey2Name|llKeyCountKeyValue|llKeysKeyValue|llLinkParticleSystem|llLinkSitTarget|llList2CSV|llList2Float|llList2Integer|llList2Json|llList2Key|llList2List|llList2ListStrided|llList2Rot|llList2String|llList2Vector|llListFindList|llListInsertList|llListRandomize|llListReplaceList|llListSort|llListStatistics|llListen|llListenControl|llListenRemove|llLoadURL|llLog|llLog10|llLookAt|llLoopSound|llLoopSoundMaster|llLoopSoundSlave|llMD5String|llManageEstateAccess|llMapDestination|llMessageLinked|llMinEventDelay|llModPow|llModifyLand|llMoveToTarget|llNavigateTo|llOffsetTexture|llOpenRemoteDataChannel|llOverMyLand|llOwnerSay|llParcelMediaCommandList|llParcelMediaQuery|llParseString2List|llParseStringKeepNulls|llParticleSystem|llPassCollisions|llPassTouches|llPatrolPoints|llPlaySound|llPlaySoundSlave|llPow|llPreloadSound|llPursue|llPushObject|llReadKeyValue|llRegionSay|llRegionSayTo|llReleaseControls|llReleaseURL|llRemoteDataReply|llRemoteLoadScriptPin|llRemoveFromLandBanList|llRemoveFromLandPassList|llRemoveInventory|llRemoveVehicleFlags|llRequestAgentData|llRequestDisplayName|llRequestExperiencePermissions|llRequestInventoryData|llRequestPermissions|llRequestSecureURL|llRequestSimulatorData|llRequestURL|llRequestUsername|llResetAnimationOverride|llResetLandBanList|llResetLandPassList|llResetOtherScript|llResetScript|llResetTime|llReturnObjectsByID|llReturnObjectsByOwner|llRezAtRoot|llRezObject|llRot2Angle|llRot2Axis|llRot2Euler|llRot2Fwd|llRot2Left|llRot2Up|llRotBetween|llRotLookAt|llRotTarget|llRotTargetRemove|llRotateTexture|llRound|llSHA1String|llSameGroup|llSay|llScaleByFactor|llScaleTexture|llScriptDanger|llScriptProfiler|llSendRemoteData|llSensor|llSensorRemove|llSensorRepeat|llSetAlpha|llSetAngularVelocity|llSetAnimationOverride|llSetBuoyancy|llSetCameraAtOffset|llSetCameraEyeOffset|llSetCameraParams|llSetClickAction|llSetColor|llSetContentType|llSetDamage|llSetForce|llSetForceAndTorque|llSetHoverHeight|llSetKeyframedMotion|llSetLinkAlpha|llSetLinkCamera|llSetLinkColor|llSetLinkMedia|llSetLinkPrimitiveParams|llSetLinkPrimitiveParamsFast|llSetLinkTexture|llSetLinkTextureAnim|llSetLocalRot|llSetMemoryLimit|llSetObjectDesc|llSetObjectName|llSetParcelMusicURL|llSetPayPrice|llSetPhysicsMaterial|llSetPos|llSetPrimMediaParams|llSetPrimitiveParams|llSetRegionPos|llSetRemoteScriptAccessPin|llSetRot|llSetScale|llSetScriptState|llSetSitText|llSetSoundQueueing|llSetSoundRadius|llSetStatus|llSetText|llSetTexture|llSetTextureAnim|llSetTimerEvent|llSetTorque|llSetTouchText|llSetVehicleFlags|llSetVehicleFloatParam|llSetVehicleRotationParam|llSetVehicleType|llSetVehicleVectorParam|llSetVelocity|llShout|llSin|llSitTarget|llSleep|llSqrt|llStartAnimation|llStopAnimation|llStopHover|llStopLookAt|llStopMoveToTarget|llStopSound|llStringLength|llStringToBase64|llStringTrim|llSubStringIndex|llTakeControls|llTan|llTarget|llTargetOmega|llTargetRemove|llTeleportAgent|llTeleportAgentGlobalCoords|llTeleportAgentHome|llTextBox|llToLower|llToUpper|llTransferLindenDollars|llTriggerSound|llTriggerSoundLimited|llUnSit|llUnescapeURL|llUpdateCharacter|llUpdateKeyValue|llVecDist|llVecMag|llVecNorm|llVolumeDetect|llWanderWithin|llWater|llWhisper|llWind|llXorBase64\",\n        \"support.function.event.lsl\" : \"at_rot_target|at_target|attach|changed|collision|collision_end|collision_start|control|dataserver|email|experience_permissions|experience_permissions_denied|http_request|http_response|land_collision|land_collision_end|land_collision_start|link_message|listen|money|moving_end|moving_start|no_sensor|not_at_rot_target|not_at_target|object_rez|on_rez|path_update|remote_data|run_time_permissions|sensor|state_entry|state_exit|timer|touch|touch_end|touch_start|transaction_result\"\n        }, \"identifier\");\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment.line.double-slash.lsl\",\n                regex : \"\\\\/\\\\/.*$\"\n            }, {\n                token : \"comment.block.begin.lsl\",\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string.quoted.double.lsl\",\n                start : '\"',\n                end : '\"',\n                next : [{\n                    token : \"constant.character.escape.lsl\",\n                    regex : /\\\\[tn\"\\\\]/\n                }]\n            }, {\n                token : \"constant.numeric.lsl\",\n                regex : \"(0[xX][0-9a-fA-F]+|[+-]?[0-9]+(?:(?:\\\\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)?)\\\\b\"\n            }, {\n                token : \"entity.name.state.lsl\",\n                regex : \"\\\\b((state)\\\\s+[A-Za-z_]\\\\w*|default)\\\\b\"\n            }, {\n                token : keywordMapper,\n                regex : \"\\\\b[a-zA-Z_][a-zA-Z0-9_]*\\\\b\"\n            }, {\n                token : \"support.function.user-defined.lsl\",\n                regex : /\\b([a-zA-Z_]\\w*)(?=\\(.*?\\))/\n            }, {\n                token : \"keyword.operator.lsl\",\n                regex : \"\\\\+\\\\+|\\\\-\\\\-|<<|>>|&&?|\\\\|\\\\|?|\\\\^|~|[!%<>=*+\\\\-\\\\/]=?\"\n            }, {\n                token : \"invalid.illegal.keyword.operator.lsl\",\n                regex : \":=?\"\n            }, {\n                token : \"punctuation.operator.lsl\",\n                regex : \"\\\\,|\\\\;\"\n            }, {\n                token : \"paren.lparen.lsl\",\n                regex : \"[\\\\[\\\\(\\\\{]\"\n            }, {\n                token : \"paren.rparen.lsl\",\n                regex : \"[\\\\]\\\\)\\\\}]\"\n            }, {\n                token : \"text.lsl\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment.block.end.lsl\",\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment.block.lsl\"\n            }\n        ]\n    };\n    this.normalizeRules();\n}\n\nexports.LSLHighlightRules = LSLHighlightRules;\n"
  },
  {
    "path": "src/mode/lua.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LuaHighlightRules = require(\"./lua_highlight_rules\").LuaHighlightRules;\nvar LuaFoldMode = require(\"./folding/lua\").FoldMode;\nvar Range = require(\"../range\").Range;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\n\nvar Mode = function() {\n    this.HighlightRules = LuaHighlightRules;\n    \n    this.foldingRules = new LuaFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n   \n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"--[[\", end: \"--]]\"};\n    \n    var indentKeywords = {\n        \"function\": 1,\n        \"then\": 1,\n        \"do\": 1,\n        \"else\": 1,\n        \"elseif\": 1,\n        \"repeat\": 1,\n        \"end\": -1,\n        \"until\": -1\n    };\n    var outdentKeywords = [\n        \"else\",\n        \"elseif\",\n        \"end\",\n        \"until\"\n    ];\n\n    function getNetIndentLevel(tokens) {\n        var level = 0;\n        // Support single-line blocks by decrementing the indent level if\n        // an ending token is found\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            if (token.type == \"keyword\") {\n                if (token.value in indentKeywords) {\n                    level += indentKeywords[token.value];\n                }\n            } else if (token.type == \"paren.lparen\") {\n                level += token.value.length;\n            } else if (token.type == \"paren.rparen\") {\n                level -= token.value.length;\n            }\n        }\n        // Limit the level to +/- 1 since usually users only indent one level\n        // at a time regardless of the logical nesting level\n        if (level < 0) {\n            return -1;\n        } else if (level > 0) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        var level = 0;\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (state == \"start\") {\n            level = getNetIndentLevel(tokens);\n        }\n        if (level > 0) {\n            return indent + tab;\n        } else if (level < 0 && indent.substr(indent.length - tab.length) == tab) {\n            // Don't do a next-line outdent if we're going to do a real outdent of this line\n            if (!this.checkOutdent(state, line, \"\\n\")) {\n                return indent.substr(0, indent.length - tab.length);\n            }\n        }\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (input != \"\\n\" && input != \"\\r\" && input != \"\\r\\n\")\n            return false;\n\n        if (line.match(/^\\s*[\\)\\}\\]]$/))\n            return true;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n\n        if (!tokens || !tokens.length)\n            return false;\n\n        return (tokens[0].type == \"keyword\" && outdentKeywords.indexOf(tokens[0].value) != -1);\n    };\n\n    this.getMatching = function(session, row, column) {\n        if (row == undefined) {\n            var pos = session.selection.lead;\n            column = pos.column;\n            row = pos.row;\n        }\n\n        var startToken = session.getTokenAt(row, column);\n        if (startToken && startToken.value in indentKeywords)\n            return this.foldingRules.luaBlock(session, row, column, true);\n    };\n\n    this.autoOutdent = function(state, session, row) {\n        var line = session.getLine(row);\n        var column = line.match(/^\\s*/)[0].length;\n        if (!column || !row) return;\n\n        var startRange = this.getMatching(session, row, column + 1);\n        if (!startRange || startRange.start.row == row)\n             return;\n        var indent = this.$getIndent(session.getLine(startRange.start.row));\n        if (indent.length != column) {\n            session.replace(new Range(row, 0, row, column), indent);\n            session.outdentRows(new Range(row + 1, 0, row + 1, 0));\n        }\n    };\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/lua_worker\", \"Worker\");\n        worker.attachToDocument(session.getDocument());\n        \n        worker.on(\"annotate\", function(e) {\n            session.setAnnotations(e.data);\n        });\n        \n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n        \n        return worker;\n    };\n\n    this.$id = \"ace/mode/lua\";\n    this.snippetFileId = \"ace/snippets/lua\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/lua_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LuaHighlightRules = function() {\n\n    var keywords = (\n        \"break|do|else|elseif|end|for|function|if|in|local|repeat|\"+\n         \"return|then|until|while|or|and|not\"\n    );\n\n    var builtinConstants = (\"true|false|nil|_G|_VERSION\");\n\n    var functions = (\n      // builtinFunctions\n        \"string|xpcall|package|tostring|print|os|unpack|require|\"+\n        \"getfenv|setmetatable|next|assert|tonumber|io|rawequal|\"+\n        \"collectgarbage|getmetatable|module|rawset|math|debug|\"+\n        \"pcall|table|newproxy|type|coroutine|_G|select|gcinfo|\"+\n        \"pairs|rawget|loadstring|ipairs|_VERSION|dofile|setfenv|\"+\n        \"load|error|loadfile|\"+\n\n        \"sub|upper|len|gfind|rep|find|match|char|dump|gmatch|\"+\n        \"reverse|byte|format|gsub|lower|preload|loadlib|loaded|\"+\n        \"loaders|cpath|config|path|seeall|exit|setlocale|date|\"+\n        \"getenv|difftime|remove|time|clock|tmpname|rename|execute|\"+\n        \"lines|write|close|flush|open|output|type|read|stderr|\"+\n        \"stdin|input|stdout|popen|tmpfile|log|max|acos|huge|\"+\n        \"ldexp|pi|cos|tanh|pow|deg|tan|cosh|sinh|random|randomseed|\"+\n        \"frexp|ceil|floor|rad|abs|sqrt|modf|asin|min|mod|fmod|log10|\"+\n        \"atan2|exp|sin|atan|getupvalue|debug|sethook|getmetatable|\"+\n        \"gethook|setmetatable|setlocal|traceback|setfenv|getinfo|\"+\n        \"setupvalue|getlocal|getregistry|getfenv|setn|insert|getn|\"+\n        \"foreachi|maxn|foreach|concat|sort|remove|resume|yield|\"+\n        \"status|wrap|create|running|\"+\n      // metatableMethods\n        \"__add|__sub|__mod|__unm|__concat|__lt|__index|__call|__gc|__metatable|\"+\n         \"__mul|__div|__pow|__len|__eq|__le|__newindex|__tostring|__mode|__tonumber\"\n    );\n\n    var stdLibaries = (\"string|package|os|io|math|debug|table|coroutine\");\n\n    var deprecatedIn5152 = (\"setn|foreach|foreachi|gcinfo|log10|maxn\");\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"support.function\": functions,\n        \"keyword.deprecated\": deprecatedIn5152,\n        \"constant.library\": stdLibaries,\n        \"constant.language\": builtinConstants,\n        \"variable.language\": \"self\"\n    }, \"identifier\");\n\n    var decimalInteger = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    var hexInteger = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n    var integer = \"(?:\" + decimalInteger + \"|\" + hexInteger + \")\";\n\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var floatNumber = \"(?:\" + pointFloat + \")\";\n\n    this.$rules = {\n        \"start\" : [{\n            stateName: \"bracketedComment\",\n            onMatch : function(value, currentState, stack){\n                stack.unshift(this.next, value.length - 2, currentState);\n                return \"comment\";\n            },\n            regex : /\\-\\-\\[=*\\[/,\n            next  : [\n                {\n                    onMatch : function(value, currentState, stack) {\n                        if (value.length == stack[1]) {\n                            stack.shift();\n                            stack.shift();\n                            this.next = stack.shift();\n                        } else {\n                            this.next = \"\";\n                        }\n                        return \"comment\";\n                    },\n                    regex : /\\]=*\\]/,\n                    next  : \"start\"\n                }, {\n                    defaultToken: \"comment.body\"\n                }\n            ]\n        },\n\n        {\n            token : \"comment\",\n            regex : \"\\\\-\\\\-.*$\"\n        },\n        {\n            stateName: \"bracketedString\",\n            onMatch : function(value, currentState, stack){\n                stack.unshift(this.next, value.length, currentState);\n                return \"string.start\";\n            },\n            regex : /\\[=*\\[/,\n            next  : [\n                {\n                    onMatch : function(value, currentState, stack) {\n                        if (value.length == stack[1]) {\n                            stack.shift();\n                            stack.shift();\n                            this.next = stack.shift();\n                        } else {\n                            this.next = \"\";\n                        }\n                        return \"string.end\";\n                    },\n                    \n                    regex : /\\]=*\\]/,\n                    next  : \"start\"\n                }, {\n                    defaultToken : \"string\"\n                }\n            ]\n        },\n        {\n            token : \"string\",           // \" string\n            regex : '\"(?:[^\\\\\\\\]|\\\\\\\\.)*?\"'\n        }, {\n            token : \"string\",           // ' string\n            regex : \"'(?:[^\\\\\\\\]|\\\\\\\\.)*?'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : floatNumber\n        }, {\n            token : \"constant.numeric\", // integer\n            regex : integer + \"\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\*|\\\\/|%|\\\\#|\\\\^|~|<|>|<=|=>|==|~=|=|\\\\:|\\\\.\\\\.\\\\.|\\\\.\\\\.\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\[\\\\(\\\\{]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\]\\\\)\\\\}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+|\\\\w+\"\n        } ]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(LuaHighlightRules, TextHighlightRules);\n\nexports.LuaHighlightRules = LuaHighlightRules;\n"
  },
  {
    "path": "src/mode/luapage.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar LuaMode = require(\"./lua\").Mode;\nvar LuaPageHighlightRules = require(\"./luapage_highlight_rules\").LuaPageHighlightRules;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    \n    this.HighlightRules = LuaPageHighlightRules;\n    this.createModeDelegates({\n        \"lua-\": LuaMode\n    });\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.$id = \"ace/mode/luapage\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/luapage_highlight_rules.js",
    "content": "// LuaPage implements the LuaPage markup as described by the Kepler Project's CGILua\n// documentation: http://keplerproject.github.com/cgilua/manual.html#templates\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar LuaHighlightRules = require(\"./lua_highlight_rules\").LuaHighlightRules;\n\nvar LuaPageHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    var startRules = [\n        {\n            token: \"keyword\",\n            regex: \"<\\\\%\\\\=?\",\n            push: \"lua-start\"\n        }, {\n            token: \"keyword\",\n            regex: \"<\\\\?lua\\\\=?\",\n            push: \"lua-start\"\n        }\n    ];\n\n    var endRules = [\n        {\n            token: \"keyword\",\n            regex: \"\\\\%>\",\n            next: \"pop\"\n        }, {\n            token: \"keyword\",\n            regex: \"\\\\?>\",\n            next: \"pop\"\n        }\n    ];\n\n    this.embedRules(LuaHighlightRules, \"lua-\", endRules, [\"start\"]);\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n    this.normalizeRules();\n};\n\noop.inherits(LuaPageHighlightRules, HtmlHighlightRules);\n\nexports.LuaPageHighlightRules = LuaPageHighlightRules;\n"
  },
  {
    "path": "src/mode/lucene.js",
    "content": "'use strict';\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar LuceneHighlightRules = require(\"./lucene_highlight_rules\").LuceneHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = LuceneHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\n\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/lucene\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/lucene_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar LuceneHighlightRules = function() {\n    this.$rules = {\n        \"start\" : [\n            {\n                token: \"constant.language.escape\",\n                regex: /\\\\[\\-+&|!(){}\\[\\]^\"~*?:\\\\]/\n            }, {\n                token: \"constant.character.negation\",\n                regex: \"\\\\-\"\n            }, {\n                token: \"constant.character.interro\",\n                regex: \"\\\\?\"\n            }, {\n                token: \"constant.character.required\",\n                regex: \"\\\\+\"\n            }, {\n                token: \"constant.character.asterisk\",\n                regex: \"\\\\*\"\n            }, {\n                token: 'constant.character.proximity',\n                regex: '~(?:0\\\\.[0-9]+|[0-9]+)?'\n            }, {\n                token: 'keyword.operator',\n                regex: '(AND|OR|NOT|TO)\\\\b'\n            }, {\n                token: \"paren.lparen\",\n                regex: \"[\\\\(\\\\{\\\\[]\"\n            }, {\n                token: \"paren.rparen\",\n                regex: \"[\\\\)\\\\}\\\\]]\"\n            }, {\n                token: \"keyword.operator\",\n                regex: /[><=^]/\n            }, {\n                token: \"constant.numeric\",\n                regex: /\\d[\\d.-]*/\n            }, {\n                token: \"string\",\n                regex: /\"(?:\\\\\"|[^\"])*\"/\n            }, {\n                token: \"keyword\",\n                regex: /(?:\\\\.|[^\\s\\-+&|!(){}\\[\\]^\"~*?:\\\\])+:/,\n                next: \"maybeRegex\"\n            }, {\n                token: \"term\",\n                regex: /\\w+/\n            }, {\n                token: \"text\",\n                regex: /\\s+/\n            }\n        ],\n        \"maybeRegex\": [{\n            token: \"text\",\n            regex: /\\s+/\n        }, {\n            token: \"string.regexp.start\",\n            regex: \"/\",\n            next: \"regex\"\n        }, {\n            regex: \"\",\n            next: \"start\"\n        }],\n        \"regex\": [\n            {\n                token: \"regexp.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                // flag\n                token: \"string.regexp.end\",\n                regex: \"/[sxngimy]*\",\n                next: \"start\"\n            }, {\n                // invalid operators\n                token : \"invalid\",\n                regex: /\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/\n            }, {\n                // operators\n                token : \"constant.language.escape\",\n                regex: /\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/\n            }, {\n                // optional operators\n                token: \"constant.language.escape\",\n                regex: \"<\\d+-\\d+>|[~&@]\"\n            }, {\n                token : \"constant.language.delimiter\",\n                regex: /\\|/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\[\\^?/,\n                next: \"regex_character_class\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"start\"\n            }, {\n                defaultToken: \"string.regexp\"\n            }\n        ],\n        \"regex_character_class\": [\n            {\n                token: \"regexp.charclass.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"]\",\n                next: \"regex\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"-\"\n            }, {\n                token: \"empty\",\n                regex: \"$\",\n                next: \"start\"\n            }, {\n                defaultToken: \"string.regexp.characterclass\"\n            }\n        ]\n    };\n};\n\noop.inherits(LuceneHighlightRules, TextHighlightRules);\n\nexports.LuceneHighlightRules = LuceneHighlightRules;\n"
  },
  {
    "path": "src/mode/makefile.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MakefileHighlightRules = require(\"./makefile_highlight_rules\").MakefileHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MakefileHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n       \n    this.lineCommentStart = \"#\";    \n    this.$indentWithTabs = true;\n    \n    this.$id = \"ace/mode/makefile\";\n    this.snippetFileId = \"ace/snippets/makefile\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/makefile_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ShHighlightFile = require(\"./sh_highlight_rules\");\n\nvar MakefileHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": ShHighlightFile.reservedKeywords,\n        \"support.function.builtin\": ShHighlightFile.languageConstructs,\n        \"invalid.deprecated\": \"debugger\"\n    }, \"string\");\n\n    this.$rules = \n        {\n    \"start\": [\n        {\n            token: \"string.interpolated.backtick.makefile\",\n            regex: \"`\",\n            next: \"shell-start\"\n        },\n        {\n            token: \"punctuation.definition.comment.makefile\",\n            regex: /#(?=.)/,\n            next: \"comment\"\n        },\n        {\n            token: [ \"keyword.control.makefile\"],\n            regex: \"^(?:\\\\s*\\\\b)(\\\\-??include|ifeq|ifneq|ifdef|ifndef|else|endif|vpath|export|unexport|define|endef|override)(?:\\\\b)\"\n        },\n        {// ^([^\\t ]+(\\s[^\\t ]+)*:(?!\\=))\\s*.*\n            token: [\"entity.name.function.makefile\", \"text\"],\n            regex: \"^([^\\\\t ]+(?:\\\\s[^\\\\t ]+)*:)(\\\\s*.*)\"\n        }\n    ],\n    \"comment\": [\n        {\n            token : \"punctuation.definition.comment.makefile\",\n            regex : /.+\\\\/\n        },\n        {\n            token : \"punctuation.definition.comment.makefile\",\n            regex : \".+\",\n            next  : \"start\"\n        }\n    ],\n    \"shell-start\": [\n        {\n            token: keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, \n        {\n            token: \"string\",\n            regex : \"\\\\w+\"\n        }, \n        {\n            token : \"string.interpolated.backtick.makefile\",\n            regex : \"`\",\n            next  : \"start\"\n        }\n    ]\n};\n\n};\n\noop.inherits(MakefileHighlightRules, TextHighlightRules);\n\nexports.MakefileHighlightRules = MakefileHighlightRules;\n"
  },
  {
    "path": "src/mode/markdown.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar CstyleBehaviour = require(\"./behaviour/cstyle\").CstyleBehaviour;\nvar TextMode = require(\"./text\").Mode;\nvar MarkdownHighlightRules = require(\"./markdown_highlight_rules\").MarkdownHighlightRules;\nvar MarkdownFoldMode = require(\"./folding/markdown\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MarkdownHighlightRules;\n\n    this.createModeDelegates({\n        javascript: require(\"./javascript\").Mode,\n        html: require(\"./html\").Mode,\n        bash: require(\"./sh\").Mode,\n        sh: require(\"./sh\").Mode,\n        xml: require(\"./xml\").Mode,\n        css: require(\"./css\").Mode\n    });\n\n    this.foldingRules = new MarkdownFoldMode();\n    this.$behaviour = new CstyleBehaviour({ braces: true });\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    this.blockComment = {start: \"<!--\", end: \"-->\"};\n    this.$quotes = {'\"': '\"', \"`\": \"`\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        if (state == \"listblock\") {\n            var match = /^(\\s*)(?:([-+*])|(\\d+)\\.)(\\s+)/.exec(line);\n            if (!match)\n                return \"\";\n            var marker = match[2];\n            if (!marker)\n                marker = parseInt(match[3], 10) + 1 + \".\";\n            return match[1] + marker + match[4];\n        } else {\n            return this.$getIndent(line);\n        }\n    };\n    this.$id = \"ace/mode/markdown\";\n    this.snippetFileId = \"ace/snippets/markdown\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/markdown_highlight_rules.js",
    "content": "\"use strict\";\n\nvar modes = require(\"../config\").$modes;\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar escaped = function(ch) {\n    return \"(?:[^\" + lang.escapeRegExp(ch) + \"\\\\\\\\]|\\\\\\\\.)*\";\n};\n\nvar MarkdownHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    // regexp must not have capturing parentheses\n    // regexps are ordered -> the first match is used\n    var codeBlockStartRule = {\n        token : \"support.function\",\n        regex : /^\\s*(```+[^`]*|~~~+[^~]*)$/,\n        onMatch: function(value, state, stack, line) {\n            var m = value.match(/^(\\s*)([`~]+)(.*)/);\n            var language = /[\\w-]+|$/.exec(m[3])[0];\n            // TODO lazy-load modes\n            if (!modes[language])\n                language = \"\";\n            stack.unshift(\"githubblock\", [], [m[1], m[2], language], state);\n            return this.token;\n        },\n        next  : \"githubblock\"\n    };\n    var codeBlockRules = [{\n        token : \"support.function\",\n        regex : \".*\",\n        onMatch: function(value, state, stack, line) {\n            var embedState = stack[1];\n            var indent = stack[2][0];\n            var endMarker = stack[2][1];\n            var language = stack[2][2];\n            \n            var m = /^(\\s*)(`+|~+)\\s*$/.exec(value);\n            if (\n                m && m[1].length < indent.length + 3\n                && m[2].length >= endMarker.length && m[2][0] == endMarker[0]\n            ) {\n                stack.splice(0, 3);\n                this.next = stack.shift();\n                return this.token;\n            }\n            this.next = \"\";\n            if (language && modes[language]) {\n                var data = modes[language].getTokenizer().getLineTokens(value, embedState.slice(0));\n                stack[1] = data.state;\n                return data.tokens;\n            }\n            return this.token;\n        }\n    }];\n\n    this.$rules[\"start\"].unshift({\n        token : \"empty_line\",\n        regex : '^$',\n        next: \"allowBlock\"\n    }, { // h1\n        token: \"markup.heading.1\",\n        regex: \"^=+(?=\\\\s*$)\"\n    }, { // h2\n        token: \"markup.heading.2\",\n        regex: \"^\\\\-+(?=\\\\s*$)\"\n    }, {\n        token : function(value) {\n            return \"markup.heading.\" + value.length;\n        },\n        regex : /^#{1,6}(?=\\s|$)/,\n        next : \"header\"\n    },\n    codeBlockStartRule,\n    { // block quote\n        token : \"string.blockquote\",\n        regex : \"^\\\\s*>\\\\s*(?:[*+-]|\\\\d+\\\\.)?\\\\s+\",\n        next  : \"blockquote\"\n    }, { // HR * - _\n        token : \"constant\",\n        regex : \"^ {0,3}(?:(?:\\\\* ?){3,}|(?:\\\\- ?){3,}|(?:\\\\_ ?){3,})\\\\s*$\",\n        next: \"allowBlock\"\n    }, { // list\n        token : \"markup.list\",\n        regex : \"^\\\\s{0,3}(?:[*+-]|\\\\d+\\\\.)\\\\s+\",\n        next  : \"listblock-start\"\n    }, {\n        include : \"basic\"\n    });\n\n    this.addRules({\n        \"basic\" : [{\n            token : \"constant.language.escape\",\n            regex : /\\\\[\\\\`*_{}\\[\\]()#+\\-.!]/\n        }, { // code span `\n            token : \"support.function\",\n            regex : \"(`+)(.*?[^`])(\\\\1)\"\n        }, { // reference\n            token : [\"text\", \"constant\", \"text\", \"url\", \"string\", \"text\"],\n            regex : \"^([ ]{0,3}\\\\[)([^\\\\]]+)(\\\\]:\\\\s*)([^ ]+)(\\\\s*(?:[\\\"][^\\\"]+[\\\"])?(\\\\s*))$\"\n        }, { // link by reference\n            token : [\"text\", \"string\", \"text\", \"constant\", \"text\"],\n            regex : \"(\\\\[)(\" + escaped(\"]\") + \")(\\\\]\\\\s*\\\\[)(\"+ escaped(\"]\") + \")(\\\\])\"\n        }, { // link by url\n            token : [\"text\", \"string\", \"text\", \"markup.underline\", \"string\", \"text\"],\n            regex : \"(\\\\!?\\\\[)(\" +                                        // [\n                    escaped(\"]\") +                                    // link text or alt text\n                    \")(\\\\]\\\\()\"+                                      // ](\n                    '((?:[^\\\\)\\\\s\\\\\\\\]|\\\\\\\\.|\\\\s(?=[^\"]))*)' +        // href or image\n                    '(\\\\s*\"' +  escaped('\"') + '\"\\\\s*)?' +            // \"title\"\n                    \"(\\\\))\"                                           // )\n        }, { // strong ** __\n            token : \"string.strong\",\n            regex : \"([*]{2}|[_]{2}(?=\\\\S))(.*?\\\\S[*_]*)(\\\\1)\"\n        }, { // emphasis * _\n            token : \"string.emphasis\",\n            regex : \"([*]|[_](?=\\\\S))(.*?\\\\S[*_]*)(\\\\1)\"\n        }, { //\n            token : [\"text\", \"url\", \"text\"],\n            regex : \"(<)(\"+\n                      \"(?:https?|ftp|dict):[^'\\\">\\\\s]+\"+\n                      \"|\"+\n                      \"(?:mailto:)?[-.\\\\w]+\\\\@[-a-z0-9]+(?:\\\\.[-a-z0-9]+)*\\\\.[a-z]+\"+\n                    \")(>)\"\n        }],\n\n        // code block\n        \"allowBlock\": [\n            {token : \"support.function\", regex : \"^ {4}.+\", next : \"allowBlock\"},\n            {token : \"empty_line\", regex : '^$', next: \"allowBlock\"},\n            {token : \"empty\", regex : \"\", next : \"start\"}\n        ],\n\n        \"header\" : [{\n            regex: \"$\",\n            next : \"start\"\n        }, {\n            include: \"basic\"\n        }, {\n            defaultToken : \"heading\"\n        } ],\n\n        \"listblock-start\" : [{\n            token : \"support.variable\",\n            regex : /(?:\\[[ x]\\])?/,\n            next  : \"listblock\"\n        }],\n\n        \"listblock\" : [ { // Lists only escape on completely blank lines.\n            token : \"empty_line\",\n            regex : \"^$\",\n            next  : \"start\"\n        }, { // list\n            token : \"markup.list\",\n            regex : \"^\\\\s{0,3}(?:[*+-]|\\\\d+\\\\.)\\\\s+\",\n            next  : \"listblock-start\"\n        }, {\n            include : \"basic\", noEscape: true\n        },\n        codeBlockStartRule,\n        {\n            defaultToken : \"list\" //do not use markup.list to allow stling leading `*` differntly\n        } ],\n\n        \"blockquote\" : [ { // Blockquotes only escape on blank lines.\n            token : \"empty_line\",\n            regex : \"^\\\\s*$\",\n            next  : \"start\"\n        }, { // block quote\n            token : \"string.blockquote\",\n            regex : \"^\\\\s*>\\\\s*(?:[*+-]|\\\\d+\\\\.)?\\\\s+\",\n            next  : \"blockquote\"\n        }, {\n            include : \"basic\", noEscape: true\n        }, {\n            defaultToken : \"string.blockquote\"\n        } ],\n\n        \"githubblock\" : codeBlockRules\n    });\n\n    this.normalizeRules();\n};\noop.inherits(MarkdownHighlightRules, TextHighlightRules);\n\nexports.MarkdownHighlightRules = MarkdownHighlightRules;\n"
  },
  {
    "path": "src/mode/mask.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MaskHighlightRules = require(\"./mask_highlight_rules\").MaskHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CssBehaviour = require(\"./behaviour/css\").CssBehaviour;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MaskHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = new CssBehaviour();\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n   \n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        // ignore braces in comments\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        var match = line.match(/^.*\\{\\s*$/);\n        if (match) {\n            indent += tab;\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/mask\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mask_highlight_rules.js",
    "content": "\"use strict\";\n\nexports.MaskHighlightRules = MaskHighlightRules;\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextRules   = require(\"./text_highlight_rules\").TextHighlightRules;\nvar JSRules     = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar CssRules    = require(\"./css_highlight_rules\").CssHighlightRules;\nvar MDRules     = require(\"./markdown_highlight_rules\").MarkdownHighlightRules;\nvar HTMLRules   = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar token_TAG       = \"keyword.support.constant.language\",\n    token_COMPO     = \"support.function.markup.bold\",\n    token_KEYWORD   = \"keyword\",\n    token_LANG      = \"constant.language\",\n    token_UTIL      = \"keyword.control.markup.italic\",\n    token_ATTR      = \"support.variable.class\",\n    token_PUNKT     = \"keyword.operator\",\n    token_ITALIC    = \"markup.italic\",\n    token_BOLD      = \"markup.bold\",\n    token_LPARE     = \"paren.lparen\",\n    token_RPARE     = \"paren.rparen\";\n\nvar const_FUNCTIONS,\n    const_KEYWORDS,\n    const_CONST,\n    const_TAGS;\n(function(){\n    const_FUNCTIONS = lang.arrayToMap(\n        (\"log\").split(\"|\")\n    );\n    const_CONST = lang.arrayToMap(\n        (\":dualbind|:bind|:import|slot|event|style|html|markdown|md\").split(\"|\")\n    );\n    const_KEYWORDS = lang.arrayToMap(\n        (\"debugger|define|var|if|each|for|of|else|switch|case|with|visible|+if|+each|+for|+switch|+with|+visible|include|import\").split(\"|\")\n    );\n    const_TAGS = lang.arrayToMap(\n        (\"a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|\" + \n         \"big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|\" + \n         \"command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|\" + \n         \"figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|\" + \n         \"header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|\" + \n         \"link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|\" + \n         \"option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|\" + \n         \"small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|\" + \n         \"textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp\").split(\"|\")\n    );\n}());\n\nfunction MaskHighlightRules () {\n\n    this.$rules = {\n        \"start\" : [\n            Token(\"comment\", \"\\\\/\\\\/.*$\"),\n            Token(\"comment\", \"\\\\/\\\\*\", [\n                Token(\"comment\", \".*?\\\\*\\\\/\", \"start\"),\n                Token(\"comment\", \".+\")\n            ]),\n            \n            Blocks.string(\"'''\"),\n            Blocks.string('\"\"\"'),\n            Blocks.string('\"'),\n            Blocks.string(\"'\"),\n            \n            Blocks.syntax(/(markdown|md)\\b/, \"md-multiline\", \"multiline\"),\n            Blocks.syntax(/html\\b/, \"html-multiline\", \"multiline\"),\n            Blocks.syntax(/(slot|event)\\b/, \"js-block\", \"block\"),\n            Blocks.syntax(/style\\b/, \"css-block\", \"block\"),\n            Blocks.syntax(/var\\b/, \"js-statement\", \"attr\"),\n            \n            Blocks.tag(),\n            \n            Token(token_LPARE, \"[[({>]\"),\n            Token(token_RPARE, \"[\\\\])};]\", \"start\"),\n            {\n                caseInsensitive: true\n            }\n        ]\n    };\n    var rules = this;\n    \n    addJavaScript(\"interpolation\", /\\]/, token_RPARE + \".\" + token_ITALIC);\n    addJavaScript(\"statement\", /\\)|}|;/);\n    addJavaScript(\"block\", /\\}/);\n    addCss();\n    addMarkdown();\n    addHtml();\n    \n    function addJavaScript(name, escape, closeType) {\n        var prfx  =  \"js-\" + name + \"-\",\n            rootTokens = name === \"block\" ? [\"start\"] : [\"start\", \"no_regex\"];\n        add(\n            JSRules\n            , prfx\n            , escape\n            , rootTokens\n            , closeType\n        );\n    }\n    function addCss() {\n        add(CssRules, \"css-block-\", /\\}/);\n    }\n    function addMarkdown() {\n        add(MDRules, \"md-multiline-\", /(\"\"\"|''')/, []);\n    }\n    function addHtml() {\n        add(HTMLRules, \"html-multiline-\", /(\"\"\"|''')/);\n    }\n    function add(Rules, strPrfx, rgxEnd, rootTokens, closeType) {\n        var next = \"pop\";\n        var tokens = rootTokens || [ \"start\" ];\n        if (tokens.length === 0) {\n            tokens = null;\n        }\n        if (/block|multiline/.test(strPrfx)) {\n            next = strPrfx + \"end\";\n            rules.$rules[next] = [\n                Token(\"empty\", \"\", \"start\")\n            ];\n        }\n        rules.embedRules(\n            Rules\n            , strPrfx\n            , [ Token(closeType || token_RPARE, rgxEnd, next) ]\n            , tokens\n            , tokens == null ? true : false\n        );\n    }\n\n    this.normalizeRules();\n}\noop.inherits(MaskHighlightRules, TextRules);\n\nvar Blocks = {\n    string: function(str, next){\n        var token = Token(\n            \"string.start\"\n            , str\n            , [\n                Token(token_LPARE + \".\" + token_ITALIC, /~\\[/, Blocks.interpolation()),\n                Token(\"string.end\", str, \"pop\"),\n                {\n                    defaultToken: \"string\"\n                }\n            ]\n            , next\n        );\n        if (str.length === 1){\n            var escaped = Token(\"string.escape\", \"\\\\\\\\\" + str);\n            token.push.unshift(escaped);\n        }\n        return token;\n    },\n    interpolation: function(){\n        return [\n            Token(token_UTIL, /\\s*\\w*\\s*:/),\n            \"js-interpolation-start\"\n        ];\n    },\n    tagHead: function (rgx) {\n      return Token(token_ATTR, rgx, [\n            Token(token_ATTR, /[\\w\\-_]+/),\n            Token(token_LPARE + \".\" + token_ITALIC, /~\\[/, Blocks.interpolation()),\n            Blocks.goUp()\n        ]);\n    },\n    tag: function () {\n        return {\n            token: 'tag',\n            onMatch :  function(value) {\n                if (void 0 !== const_KEYWORDS[value])\n                    return token_KEYWORD;\n                if (void 0 !== const_CONST[value])\n                    return token_LANG;\n                if (void 0 !== const_FUNCTIONS[value])\n                    return \"support.function\";\n                if (void 0 !== const_TAGS[value.toLowerCase()])\n                    return token_TAG;\n                \n                return token_COMPO;\n            },\n            regex : /([@\\w\\-_:+]+)|((^|\\s)(?=\\s*(\\.|#)))/,\n            push: [\n                Blocks.tagHead(/\\./) ,\n                Blocks.tagHead(/#/) ,\n                Blocks.expression(),\n                Blocks.attribute(),\n                \n                Token(token_LPARE, /[;>{]/, \"pop\")\n            ]\n        };\n    },\n    syntax: function(rgx, next, type){\n        return {\n            token: token_LANG,\n            regex : rgx,\n            push: ({\n                \"attr\": [\n                    next + \"-start\",\n                    Token(token_PUNKT, /;/, \"start\")\n                ],\n                \"multiline\": [\n                    Blocks.tagHead(/\\./) ,\n                    Blocks.tagHead(/#/) ,\n                    Blocks.attribute(),\n                    Blocks.expression(),\n                    Token(token_LPARE, /[>\\{]/),\n                    Token(token_PUNKT, /;/, \"start\"),\n                    Token(token_LPARE, /'''|\"\"\"/, [ next + \"-start\" ])\n                ],\n                \"block\": [\n                    Blocks.tagHead(/\\./) ,\n                    Blocks.tagHead(/#/) ,\n                    Blocks.attribute(),\n                    Blocks.expression(),\n                    Token(token_LPARE, /\\{/, [ next + \"-start\" ])\n                ]\n            })[type]\n        };\n    },\n    attribute: function(){\n        return Token(function(value){\n            return  /^x\\-/.test(value)\n                ? token_ATTR + \".\" + token_BOLD\n                : token_ATTR;\n        }, /[\\w_-]+/, [\n            Token(token_PUNKT, /\\s*=\\s*/, [\n                Blocks.string('\"'),\n                Blocks.string(\"'\"),\n                Blocks.word(),\n                Blocks.goUp()\n            ]),\n            Blocks.goUp()\n        ]);\n    },\n    expression: function(){\n        return Token(token_LPARE, /\\(/, [ \"js-statement-start\" ]);\n    },\n    word: function(){\n        return Token(\"string\", /[\\w-_]+/);\n    },\n    goUp: function(){\n        return Token(\"text\", \"\", \"pop\");\n    },\n    goStart: function(){\n        return Token(\"text\", \"\", \"start\");\n    }\n};\n\n\nfunction Token(token, rgx, mix) {\n    var push, next, onMatch;\n    if (arguments.length === 4) {\n        push = mix;\n        next = arguments[3];\n    }\n    else if (typeof mix === \"string\") {\n        next = mix;\n    }\n    else {\n        push = mix;\n    }\n    if (typeof token === \"function\") {\n        onMatch = token;\n        token   = \"empty\";\n    }\n    return {\n        token: token,\n        regex: rgx,\n        push: push,\n        next: next,\n        onMatch: onMatch\n    };\n}\n"
  },
  {
    "path": "src/mode/matching_brace_outdent.js",
    "content": "\"use strict\";\n\nvar Range = require(\"../range\").Range;\n\nvar MatchingBraceOutdent = function() {};\n\n(function() {\n\n    this.checkOutdent = function(line, input) {\n        if (! /^\\s+$/.test(line))\n            return false;\n\n        return /^\\s*\\}/.test(input);\n    };\n\n    this.autoOutdent = function(doc, row) {\n        var line = doc.getLine(row);\n        var match = line.match(/^(\\s*\\})/);\n\n        if (!match) return 0;\n\n        var column = match[1].length;\n        var openBracePos = doc.findMatchingBracket({row: row, column: column});\n\n        if (!openBracePos || openBracePos.row == row) return 0;\n\n        var indent = this.$getIndent(doc.getLine(openBracePos.row));\n        doc.replace(new Range(row, 0, row, column-1), indent);\n    };\n\n    this.$getIndent = function(line) {\n        return line.match(/^\\s*/)[0];\n    };\n\n}).call(MatchingBraceOutdent.prototype);\n\nexports.MatchingBraceOutdent = MatchingBraceOutdent;\n"
  },
  {
    "path": "src/mode/matching_parens_outdent.js",
    "content": "\"use strict\";\n\nvar Range = require(\"../range\").Range;\n\nvar MatchingParensOutdent = function() {};\n\n(function() {\n\n    this.checkOutdent = function(line, input) {\n        if (! /^\\s+$/.test(line))\n            return false;\n\n        return /^\\s*\\)/.test(input);\n    };\n\n    this.autoOutdent = function(doc, row) {\n        var line = doc.getLine(row);\n        var match = line.match(/^(\\s*\\))/);\n\n        if (!match) return 0;\n\n        var column = match[1].length;\n        var openBracePos = doc.findMatchingBracket({row: row, column: column});\n\n        if (!openBracePos || openBracePos.row == row) return 0;\n\n        var indent = this.$getIndent(doc.getLine(openBracePos.row));\n        doc.replace(new Range(row, 0, row, column-1), indent);\n    };\n\n    this.$getIndent = function(line) {\n        var match = line.match(/^(\\s+)/);\n        if (match) {\n            return match[1];\n        }\n\n        return \"\";\n    };\n\n}).call(MatchingParensOutdent.prototype);\n\nexports.MatchingParensOutdent = MatchingParensOutdent;\n"
  },
  {
    "path": "src/mode/matlab.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MatlabHighlightRules = require(\"./matlab_highlight_rules\").MatlabHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = MatlabHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"%\";\n    this.blockComment = {start: \"%{\", end: \"%}\"};\n\n    this.$id = \"ace/mode/matlab\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/matlab_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MatlabHighlightRules = function() {\n\nvar keywords = (\n        \"break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while\"\n    );\n\n    var builtinConstants = (\n        \"true|false|inf|Inf|nan|NaN|eps|pi|ans|nargin|nargout|varargin|varargout\"\n    );\n\n    var builtinFunctions = (\n        \"abs|accumarray|acos(?:d|h)?|acot(?:d|h)?|acsc(?:d|h)?|actxcontrol(?:list|select)?|actxGetRunningServer|actxserver|addlistener|addpath|addpref|addtodate|\"+\n\t\t\"airy|align|alim|all|allchild|alpha|alphamap|amd|ancestor|and|angle|annotation|any|area|arrayfun|asec(?:d|h)?|asin(?:d|h)?|assert|assignin|atan(?:2|d|h)?|\" +\n\t\t\"audiodevinfo|audioplayer|audiorecorder|aufinfo|auread|autumn|auwrite|avifile|aviinfo|aviread|axes|axis|balance|bar(?:3|3h|h)?|base2dec|beep|BeginInvoke|bench|\"+\n\t\t\"bessel(?:h|i|j|k|y)|beta|betainc|betaincinv|betaln|bicg|bicgstab|bicgstabl|bin2dec|bitand|bitcmp|bitget|bitmax|bitnot|bitor|bitset|bitshift|bitxor|blanks|blkdiag|\"+\n\t\t\"bone|box|brighten|brush|bsxfun|builddocsearchdb|builtin|bvp4c|bvp5c|bvpget|bvpinit|bvpset|bvpxtend|calendar|calllib|callSoapService|camdolly|cameratoolbar|camlight|\"+\n\t\t\"camlookat|camorbit|campan|campos|camproj|camroll|camtarget|camup|camva|camzoom|cart2pol|cart2sph|cast|cat|caxis|cd|cdf2rdf|cdfepoch|cdfinfo|cdflib(?:.(?:close|closeVar|\"+\n\t\t\"computeEpoch|computeEpoch16|create|createAttr|createVar|delete|deleteAttr|deleteAttrEntry|deleteAttrgEntry|deleteVar|deleteVarRecords|epoch16Breakdown|epochBreakdown|getAttrEntry|\"+\n\t\t\"getAttrgEntry|getAttrMaxEntry|getAttrMaxgEntry|getAttrName|getAttrNum|getAttrScope|getCacheSize|getChecksum|getCompression|getCompressionCacheSize|getConstantNames|\"+\n\t\t\"getConstantValue|getCopyright|getFileBackward|getFormat|getLibraryCopyright|getLibraryVersion|getMajority|getName|getNumAttrEntries|getNumAttrgEntries|getNumAttributes|\"+\n\t\t\"getNumgAttributes|getReadOnlyMode|getStageCacheSize|getValidate|getVarAllocRecords|getVarBlockingFactor|getVarCacheSize|getVarCompression|getVarData|getVarMaxAllocRecNum|\"+\n\t\t\"getVarMaxWrittenRecNum|getVarName|getVarNum|getVarNumRecsWritten|getVarPadValue|getVarRecordData|getVarReservePercent|getVarsMaxWrittenRecNum|getVarSparseRecords|getVersion|\"+\n\t\t\"hyperGetVarData|hyperPutVarData|inquire|inquireAttr|inquireAttrEntry|inquireAttrgEntry|inquireVar|open|putAttrEntry|putAttrgEntry|putVarData|putVarRecordData|renameAttr|\"+\n\t\t\"renameVar|setCacheSize|setChecksum|setCompression|setCompressionCacheSize|setFileBackward|setFormat|setMajority|setReadOnlyMode|setStageCacheSize|setValidate|\"+\n\t\t\"setVarAllocBlockRecords|setVarBlockingFactor|setVarCacheSize|setVarCompression|setVarInitialRecs|setVarPadValue|SetVarReservePercent|setVarsCacheSize|setVarSparseRecords))?|\"+\n\t\t\"cdfread|cdfwrite|ceil|cell2mat|cell2struct|celldisp|cellfun|cellplot|cellstr|cgs|checkcode|checkin|checkout|chol|cholinc|cholupdate|circshift|cla|clabel|class|clc|clear|\"+\n\t\t\"clearvars|clf|clipboard|clock|close|closereq|cmopts|cmpermute|cmunique|colamd|colon|colorbar|colordef|colormap|colormapeditor|colperm|Combine|comet|comet3|commandhistory|\"+\n\t\t\"commandwindow|compan|compass|complex|computer|cond|condeig|condest|coneplot|conj|containers.Map|contour(?:3|c|f|slice)?|contrast|conv|conv2|convhull|convhulln|convn|cool|\"+\n\t\t\"copper|copyfile|copyobj|corrcoef|cos(?:d|h)?|cot(?:d|h)?|cov|cplxpair|cputime|createClassFromWsdl|createSoapMessage|cross|csc(?:d|h)?|csvread|csvwrite|ctranspose|cumprod|\"+\n\t\t\"cumsum|cumtrapz|curl|customverctrl|cylinder|daqread|daspect|datacursormode|datatipinfo|date|datenum|datestr|datetick|datevec|dbclear|dbcont|dbdown|dblquad|dbmex|dbquit|\"+\n\t\t\"dbstack|dbstatus|dbstep|dbstop|dbtype|dbup|dde23|ddeget|ddesd|ddeset|deal|deblank|dec2base|dec2bin|dec2hex|decic|deconv|del2|delaunay|delaunay3|delaunayn|DelaunayTri|delete|\"+\n\t\t\"demo|depdir|depfun|det|detrend|deval|diag|dialog|diary|diff|diffuse|dir|disp|display|dither|divergence|dlmread|dlmwrite|dmperm|doc|docsearch|dos|dot|dragrect|drawnow|dsearch|\"+\n\t\t\"dsearchn|dynamicprops|echo|echodemo|edit|eig|eigs|ellipj|ellipke|ellipsoid|empty|enableNETfromNetworkDrive|enableservice|EndInvoke|enumeration|eomday|eq|erf|erfc|erfcinv|\"+\n\t\t\"erfcx|erfinv|error|errorbar|errordlg|etime|etree|etreeplot|eval|evalc|evalin|event.(?:EventData|listener|PropertyEvent|proplistener)|exifread|exist|exit|exp|expint|expm|\"+\n\t\t\"expm1|export2wsdlg|eye|ezcontour|ezcontourf|ezmesh|ezmeshc|ezplot|ezplot3|ezpolar|ezsurf|ezsurfc|factor|factorial|fclose|feather|feature|feof|ferror|feval|fft|fft2|fftn|\"+\n\t\t\"fftshift|fftw|fgetl|fgets|fieldnames|figure|figurepalette|fileattrib|filebrowser|filemarker|fileparts|fileread|filesep|fill|fill3|filter|filter2|find|findall|findfigs|\"+\n\t\t\"findobj|findstr|finish|fitsdisp|fitsinfo|fitsread|fitswrite|fix|flag|flipdim|fliplr|flipud|floor|flow|fminbnd|fminsearch|fopen|format|fplot|fprintf|frame2im|fread|freqspace|\"+\n\t\t\"frewind|fscanf|fseek|ftell|FTP|full|fullfile|func2str|functions|funm|fwrite|fzero|gallery|gamma|gammainc|gammaincinv|gammaln|gca|gcbf|gcbo|gcd|gcf|gco|ge|genpath|genvarname|\"+\n\t\t\"get|getappdata|getenv|getfield|getframe|getpixelposition|getpref|ginput|gmres|gplot|grabcode|gradient|gray|graymon|grid|griddata(?:3|n)?|griddedInterpolant|gsvd|gt|gtext|\"+\n\t\t\"guidata|guide|guihandles|gunzip|gzip|h5create|h5disp|h5info|h5read|h5readatt|h5write|h5writeatt|hadamard|handle|hankel|hdf|hdf5|hdf5info|hdf5read|hdf5write|hdfinfo|\"+\n\t\t\"hdfread|hdftool|help|helpbrowser|helpdesk|helpdlg|helpwin|hess|hex2dec|hex2num|hgexport|hggroup|hgload|hgsave|hgsetget|hgtransform|hidden|hilb|hist|histc|hold|home|horzcat|\"+\n\t\t\"hostid|hot|hsv|hsv2rgb|hypot|ichol|idivide|ifft|ifft2|ifftn|ifftshift|ilu|im2frame|im2java|imag|image|imagesc|imapprox|imfinfo|imformats|import|importdata|imread|imwrite|\"+\n\t\t\"ind2rgb|ind2sub|inferiorto|info|inline|inmem|inpolygon|input|inputdlg|inputname|inputParser|inspect|instrcallback|instrfind|instrfindall|int2str|integral(?:2|3)?|interp(?:1|\"+\n\t\t\"1q|2|3|ft|n)|interpstreamspeed|intersect|intmax|intmin|inv|invhilb|ipermute|isa|isappdata|iscell|iscellstr|ischar|iscolumn|isdir|isempty|isequal|isequaln|isequalwithequalnans|\"+\n\t\t\"isfield|isfinite|isfloat|isglobal|ishandle|ishghandle|ishold|isinf|isinteger|isjava|iskeyword|isletter|islogical|ismac|ismatrix|ismember|ismethod|isnan|isnumeric|isobject|\"+\n\t\t\"isocaps|isocolors|isonormals|isosurface|ispc|ispref|isprime|isprop|isreal|isrow|isscalar|issorted|isspace|issparse|isstr|isstrprop|isstruct|isstudent|isunix|isvarname|\"+\n\t\t\"isvector|javaaddpath|javaArray|javachk|javaclasspath|javacomponent|javaMethod|javaMethodEDT|javaObject|javaObjectEDT|javarmpath|jet|keyboard|kron|lasterr|lasterror|\"+\n\t\t\"lastwarn|lcm|ldivide|ldl|le|legend|legendre|length|libfunctions|libfunctionsview|libisloaded|libpointer|libstruct|license|light|lightangle|lighting|lin2mu|line|lines|\"+\n\t\t\"linkaxes|linkdata|linkprop|linsolve|linspace|listdlg|listfonts|load|loadlibrary|loadobj|log|log10|log1p|log2|loglog|logm|logspace|lookfor|lower|ls|lscov|lsqnonneg|lsqr|\"+\n\t\t\"lt|lu|luinc|magic|makehgtform|mat2cell|mat2str|material|matfile|matlab.io.MatFile|matlab.mixin.(?:Copyable|Heterogeneous(?:.getDefaultScalarElement)?)|matlabrc|\"+\n\t\t\"matlabroot|max|maxNumCompThreads|mean|median|membrane|memmapfile|memory|menu|mesh|meshc|meshgrid|meshz|meta.(?:class(?:.fromName)?|DynamicProperty|EnumeratedValue|event|\"+\n\t\t\"MetaData|method|package(?:.(?:fromName|getAllPackages))?|property)|metaclass|methods|methodsview|mex(?:.getCompilerConfigurations)?|MException|mexext|mfilename|min|minres|\"+\n\t\t\"minus|mislocked|mkdir|mkpp|mldivide|mlint|mlintrpt|mlock|mmfileinfo|mmreader|mod|mode|more|move|movefile|movegui|movie|movie2avi|mpower|mrdivide|msgbox|mtimes|mu2lin|\"+\n\t\t\"multibandread|multibandwrite|munlock|namelengthmax|nargchk|narginchk|nargoutchk|native2unicode|nccreate|ncdisp|nchoosek|ncinfo|ncread|ncreadatt|ncwrite|ncwriteatt|\"+\n\t\t\"ncwriteschema|ndgrid|ndims|ne|NET(?:.(?:addAssembly|Assembly|convertArray|createArray|createGeneric|disableAutoRelease|enableAutoRelease|GenericClass|invokeGenericMethod|\"+\n\t\t\"NetException|setStaticProperty))?|netcdf.(?:abort|close|copyAtt|create|defDim|defGrp|defVar|defVarChunking|defVarDeflate|defVarFill|defVarFletcher32|delAtt|endDef|getAtt|\"+\n\t\t\"getChunkCache|getConstant|getConstantNames|getVar|inq|inqAtt|inqAttID|inqAttName|inqDim|inqDimID|inqDimIDs|inqFormat|inqGrpName|inqGrpNameFull|inqGrpParent|inqGrps|\"+\n\t\t\"inqLibVers|inqNcid|inqUnlimDims|inqVar|inqVarChunking|inqVarDeflate|inqVarFill|inqVarFletcher32|inqVarID|inqVarIDs|open|putAtt|putVar|reDef|renameAtt|renameDim|renameVar|\"+\n\t\t\"setChunkCache|setDefaultFormat|setFill|sync)|newplot|nextpow2|nnz|noanimate|nonzeros|norm|normest|not|notebook|now|nthroot|null|num2cell|num2hex|num2str|numel|nzmax|\"+\n\t\t\"ode(?:113|15i|15s|23|23s|23t|23tb|45)|odeget|odeset|odextend|onCleanup|ones|open|openfig|opengl|openvar|optimget|optimset|or|ordeig|orderfields|ordqz|ordschur|orient|\"+\n\t\t\"orth|pack|padecoef|pagesetupdlg|pan|pareto|parseSoapResponse|pascal|patch|path|path2rc|pathsep|pathtool|pause|pbaspect|pcg|pchip|pcode|pcolor|pdepe|pdeval|peaks|perl|perms|\"+\n\t\t\"permute|pie|pink|pinv|planerot|playshow|plot|plot3|plotbrowser|plotedit|plotmatrix|plottools|plotyy|plus|pol2cart|polar|poly|polyarea|polyder|polyeig|polyfit|polyint|polyval|\"+\n\t\t\"polyvalm|pow2|power|ppval|prefdir|preferences|primes|print|printdlg|printopt|printpreview|prod|profile|profsave|propedit|propertyeditor|psi|publish|PutCharArray|PutFullMatrix|\"+\n\t\t\"PutWorkspaceData|pwd|qhull|qmr|qr|qrdelete|qrinsert|qrupdate|quad|quad2d|quadgk|quadl|quadv|questdlg|quit|quiver|quiver3|qz|rand|randi|randn|randperm|RandStream(?:.(?:create|\"+\n\t\t\"getDefaultStream|getGlobalStream|list|setDefaultStream|setGlobalStream))?|rank|rat|rats|rbbox|rcond|rdivide|readasync|real|reallog|realmax|realmin|realpow|realsqrt|record|\"+\n\t\t\"rectangle|rectint|recycle|reducepatch|reducevolume|refresh|refreshdata|regexp|regexpi|regexprep|regexptranslate|rehash|rem|Remove|RemoveAll|repmat|reset|reshape|residue|\"+\n\t\t\"restoredefaultpath|rethrow|rgb2hsv|rgb2ind|rgbplot|ribbon|rmappdata|rmdir|rmfield|rmpath|rmpref|rng|roots|rose|rosser|rot90|rotate|rotate3d|round|rref|rsf2csf|run|save|saveas|\"+\n\t\t\"saveobj|savepath|scatter|scatter3|schur|sec|secd|sech|selectmoveresize|semilogx|semilogy|sendmail|serial|set|setappdata|setdiff|setenv|setfield|setpixelposition|setpref|setstr|\"+\n\t\t\"setxor|shading|shg|shiftdim|showplottool|shrinkfaces|sign|sin(?:d|h)?|size|slice|smooth3|snapnow|sort|sortrows|sound|soundsc|spalloc|spaugment|spconvert|spdiags|specular|speye|\"+\n\t\t\"spfun|sph2cart|sphere|spinmap|spline|spones|spparms|sprand|sprandn|sprandsym|sprank|spring|sprintf|spy|sqrt|sqrtm|squeeze|ss2tf|sscanf|stairs|startup|std|stem|stem3|stopasync|\"+\n\t\t\"str2double|str2func|str2mat|str2num|strcat|strcmp|strcmpi|stream2|stream3|streamline|streamparticles|streamribbon|streamslice|streamtube|strfind|strjust|strmatch|strncmp|\"+\n\t\t\"strncmpi|strread|strrep|strtok|strtrim|struct2cell|structfun|strvcat|sub2ind|subplot|subsasgn|subsindex|subspace|subsref|substruct|subvolume|sum|summer|superclasses|superiorto|\"+\n\t\t\"support|surf|surf2patch|surface|surfc|surfl|surfnorm|svd|svds|swapbytes|symamd|symbfact|symmlq|symrcm|symvar|system|tan(?:d|h)?|tar|tempdir|tempname|tetramesh|texlabel|text|\"+\n\t\t\"textread|textscan|textwrap|tfqmr|throw|tic|Tiff(?:.(?:getTagNames|getVersion))?|timer|timerfind|timerfindall|times|timeseries|title|toc|todatenum|toeplitz|toolboxdir|trace|\"+\n\t\t\"transpose|trapz|treelayout|treeplot|tril|trimesh|triplequad|triplot|TriRep|TriScatteredInterp|trisurf|triu|tscollection|tsearch|tsearchn|tstool|type|typecast|uibuttongroup|\"+\n\t\t\"uicontextmenu|uicontrol|uigetdir|uigetfile|uigetpref|uiimport|uimenu|uiopen|uipanel|uipushtool|uiputfile|uiresume|uisave|uisetcolor|uisetfont|uisetpref|uistack|uitable|\"+\n\t\t\"uitoggletool|uitoolbar|uiwait|uminus|undocheckout|unicode2native|union|unique|unix|unloadlibrary|unmesh|unmkpp|untar|unwrap|unzip|uplus|upper|urlread|urlwrite|usejava|\"+\n\t\t\"userpath|validateattributes|validatestring|vander|var|vectorize|ver|verctrl|verLessThan|version|vertcat|VideoReader(?:.isPlatformSupported)?|VideoWriter(?:.getProfiles)?|\"+\n\t\t\"view|viewmtx|visdiff|volumebounds|voronoi|voronoin|wait|waitbar|waitfor|waitforbuttonpress|warndlg|warning|waterfall|wavfinfo|wavplay|wavread|wavrecord|wavwrite|web|weekday|\"+\n\t\t\"what|whatsnew|which|whitebg|who|whos|wilkinson|winopen|winqueryreg|winter|wk1finfo|wk1read|wk1write|workspace|xlabel|xlim|xlsfinfo|xlsread|xlswrite|xmlread|xmlwrite|xor|xslt|\"+\n\t\t\"ylabel|ylim|zeros|zip|zlabel|zlim|zoom|addedvarplot|andrewsplot|anova(?:1|2|n)|ansaribradley|aoctool|barttest|bbdesign|beta(?:cdf|fit|inv|like|pdf|rnd|stat)|bino(?:cdf|fit|inv|\"+\n\t\t\"pdf|rnd|stat)|biplot|bootci|bootstrp|boxplot|candexch|candgen|canoncorr|capability|capaplot|caseread|casewrite|categorical|ccdesign|cdfplot|chi2(?:cdf|gof|inv|pdf|rnd|stat)|\"+\n\t\t\"cholcov|Classification(?:BaggedEnsemble|Discriminant(?:.(?:fit|make|template))?|Ensemble|KNN(?:.(?:fit|template))?|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|\"+\n\t\t\"template))?)|classify|classregtree|cluster|clusterdata|cmdscale|combnk|Compact(?:Classification(?:Discriminant|Ensemble|Tree)|Regression(?:Ensemble|Tree)|TreeBagger)|confusionmat|\"+\n\t\t\"controlchart|controlrules|cophenet|copula(?:cdf|fit|param|pdf|rnd|stat)|cordexch|corr|corrcov|coxphfit|createns|crosstab|crossval|cvpartition|datasample|dataset|daugment|dcovary|\"+\n\t\t\"dendrogram|dfittool|disttool|dummyvar|dwtest|ecdf|ecdfhist|ev(?:cdf|fit|inv|like|pdf|rnd|stat)|ExhaustiveSearcher|exp(?:cdf|fit|inv|like|pdf|rnd|stat)|factoran|fcdf|ff2n|finv|\"+\n\t\t\"fitdist|fitensemble|fpdf|fracfact|fracfactgen|friedman|frnd|fstat|fsurfht|fullfact|gagerr|gam(?:cdf|fit|inv|like|pdf|rnd|stat)|GeneralizedLinearModel(?:.fit)?|geo(?:cdf|inv|mean|\"+\n\t\t\"pdf|rnd|stat)|gev(?:cdf|fit|inv|like|pdf|rnd|stat)|gline|glmfit|glmval|glyphplot|gmdistribution(?:.fit)?|gname|gp(?:cdf|fit|inv|like|pdf|rnd|stat)|gplotmatrix|grp2idx|grpstats|\"+\n\t\t\"gscatter|haltonset|harmmean|hist3|histfit|hmm(?:decode|estimate|generate|train|viterbi)|hougen|hyge(?:cdf|inv|pdf|rnd|stat)|icdf|inconsistent|interactionplot|invpred|iqr|iwishrnd|\"+\n\t\t\"jackknife|jbtest|johnsrnd|KDTreeSearcher|kmeans|knnsearch|kruskalwallis|ksdensity|kstest|kstest2|kurtosis|lasso|lassoglm|lassoPlot|leverage|lhsdesign|lhsnorm|lillietest|\"+\n\t\t\"LinearModel(?:.fit)?|linhyptest|linkage|logn(?:cdf|fit|inv|like|pdf|rnd|stat)|lsline|mad|mahal|maineffectsplot|manova1|manovacluster|mdscale|mhsample|mle|mlecov|mnpdf|\"+\n\t\t\"mnrfit|mnrnd|mnrval|moment|multcompare|multivarichart|mvn(?:cdf|pdf|rnd)|mvregress|mvregresslike|mvt(?:cdf|pdf|rnd)|NaiveBayes(?:.fit)?|nan(?:cov|max|mean|median|min|std|\"+\n\t\t\"sum|var)|nbin(?:cdf|fit|inv|pdf|rnd|stat)|ncf(?:cdf|inv|pdf|rnd|stat)|nct(?:cdf|inv|pdf|rnd|stat)|ncx2(?:cdf|inv|pdf|rnd|stat)|NeighborSearcher|nlinfit|nlintool|nlmefit|nlmefitsa|\"+\n\t\t\"nlparci|nlpredci|nnmf|nominal|NonLinearModel(?:.fit)?|norm(?:cdf|fit|inv|like|pdf|rnd|stat)|normplot|normspec|ordinal|outlierMeasure|parallelcoords|paretotails|partialcorr|\"+\n\t\t\"pcacov|pcares|pdf|pdist|pdist2|pearsrnd|perfcurve|perms|piecewisedistribution|plsregress|poiss(?:cdf|fit|inv|pdf|rnd|tat)|polyconf|polytool|prctile|princomp|ProbDist(?:Kernel|\"+\n\t\t\"Parametric|UnivKernel|UnivParam)?|probplot|procrustes|qqplot|qrandset|qrandstream|quantile|randg|random|randsample|randtool|range|rangesearch|ranksum|rayl(?:cdf|fit|inv|pdf|\"+\n\t\t\"rnd|stat)|rcoplot|refcurve|refline|regress|Regression(?:BaggedEnsemble|Ensemble|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|template))?)|regstats|relieff|ridge|\"+\n\t\t\"robustdemo|robustfit|rotatefactors|rowexch|rsmdemo|rstool|runstest|sampsizepwr|scatterhist|sequentialfs|signrank|signtest|silhouette|skewness|slicesample|sobolset|squareform|\"+\n\t\t\"statget|statset|stepwise|stepwisefit|surfht|tabulate|tblread|tblwrite|tcdf|tdfread|tiedrank|tinv|tpdf|TreeBagger|treedisp|treefit|treeprune|treetest|treeval|trimmean|trnd|tstat|\"+\n\t\t\"ttest|ttest2|unid(?:cdf|inv|pdf|rnd|stat)|unif(?:cdf|inv|it|pdf|rnd|stat)|vartest(?:2|n)?|wbl(?:cdf|fit|inv|like|pdf|rnd|stat)|wblplot|wishrnd|x2fx|xptread|zscore|ztest\"+\n\t\t\"adapthisteq|analyze75info|analyze75read|applycform|applylut|axes2pix|bestblk|blockproc|bwarea|bwareaopen|bwboundaries|bwconncomp|bwconvhull|bwdist|bwdistgeodesic|bweuler|\"+\n\t\t\"bwhitmiss|bwlabel|bwlabeln|bwmorph|bwpack|bwperim|bwselect|bwtraceboundary|bwulterode|bwunpack|checkerboard|col2im|colfilt|conndef|convmtx2|corner|cornermetric|corr2|cp2tform|\"+\n\t\t\"cpcorr|cpselect|cpstruct2pairs|dct2|dctmtx|deconvblind|deconvlucy|deconvreg|deconvwnr|decorrstretch|demosaic|dicom(?:anon|dict|info|lookup|read|uid|write)|edge|edgetaper|entropy|\"+\n\t\t\"entropyfilt|fan2para|fanbeam|findbounds|fliptform|freqz2|fsamp2|fspecial|ftrans2|fwind1|fwind2|getheight|getimage|getimagemodel|getline|getneighbors|getnhood|getpts|\"+\n\t\t\"getrangefromclass|getrect|getsequence|gray2ind|graycomatrix|graycoprops|graydist|grayslice|graythresh|hdrread|hdrwrite|histeq|hough|houghlines|houghpeaks|iccfind|iccread|\"+\n\t\t\"iccroot|iccwrite|idct2|ifanbeam|im2bw|im2col|im2double|im2int16|im2java2d|im2single|im2uint16|im2uint8|imabsdiff|imadd|imadjust|ImageAdapter|imageinfo|imagemodel|imapplymatrix|\"+\n\t\t\"imattributes|imbothat|imclearborder|imclose|imcolormaptool|imcomplement|imcontour|imcontrast|imcrop|imdilate|imdisplayrange|imdistline|imdivide|imellipse|imerode|imextendedmax|\"+\n\t\t\"imextendedmin|imfill|imfilter|imfindcircles|imfreehand|imfuse|imgca|imgcf|imgetfile|imhandles|imhist|imhmax|imhmin|imimposemin|imlincomb|imline|immagbox|immovie|immultiply|imnoise|\"+\n\t\t\"imopen|imoverview|imoverviewpanel|impixel|impixelinfo|impixelinfoval|impixelregion|impixelregionpanel|implay|impoint|impoly|impositionrect|improfile|imputfile|impyramid|\"+\n\t\t\"imreconstruct|imrect|imregconfig|imregionalmax|imregionalmin|imregister|imresize|imroi|imrotate|imsave|imscrollpanel|imshow|imshowpair|imsubtract|imtool|imtophat|imtransform|\"+\n\t\t\"imview|ind2gray|ind2rgb|interfileinfo|interfileread|intlut|ippl|iptaddcallback|iptcheckconn|iptcheckhandle|iptcheckinput|iptcheckmap|iptchecknargin|iptcheckstrs|iptdemos|iptgetapi|\"+\n\t\t\"iptGetPointerBehavior|iptgetpref|ipticondir|iptnum2ordinal|iptPointerManager|iptprefs|iptremovecallback|iptSetPointerBehavior|iptsetpref|iptwindowalign|iradon|isbw|isflat|isgray|\"+\n\t\t\"isicc|isind|isnitf|isrgb|isrset|lab2double|lab2uint16|lab2uint8|label2rgb|labelmatrix|makecform|makeConstrainToRectFcn|makehdr|makelut|makeresampler|maketform|mat2gray|mean2|\"+\n\t\t\"medfilt2|montage|nitfinfo|nitfread|nlfilter|normxcorr2|ntsc2rgb|openrset|ordfilt2|otf2psf|padarray|para2fan|phantom|poly2mask|psf2otf|qtdecomp|qtgetblk|qtsetblk|radon|rangefilt|\"+\n\t\t\"reflect|regionprops|registration.metric.(?:MattesMutualInformation|MeanSquares)|registration.optimizer.(?:OnePlusOneEvolutionary|RegularStepGradientDescent)|rgb2gray|\"+\n\t\t\"rgb2ntsc|rgb2ycbcr|roicolor|roifill|roifilt2|roipoly|rsetwrite|std2|stdfilt|strel|stretchlim|subimage|tformarray|tformfwd|tforminv|tonemap|translate|truesize|uintlut|viscircles|\"+\n\t\t\"warp|watershed|whitepoint|wiener2|xyz2double|xyz2uint16|ycbcr2rgb|bintprog|color|fgoalattain|fminbnd|fmincon|fminimax|fminsearch|fminunc|fseminf|fsolve|fzero|fzmult|gangstr|ktrlink|\"+\n\t\t\"linprog|lsqcurvefit|lsqlin|lsqnonlin|lsqnonneg|optimget|optimset|optimtool|quadprog\"\n    );\n    var storageType = (\n        \"cell|struct|char|double|single|logical|u?int(?:8|16|32|64)|sparse\"\n    );\n    var keywordMapper = this.createKeywordMapper({\n        \"storage.type\": storageType,\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants\n    }, \"identifier\", true);\n\n    this.$rules = {\n        // allowQstring\n        start: [{ \n            token : \"string\",\n            regex : \"'\",\n            stateName : \"qstring\",\n            next  : [{\n                token : \"constant.language.escape\",\n                regex : \"''\"\n            }, {\n                token : \"string\",\n                regex : \"'|$\",\n                next  : \"start\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }, {\n            regex: \"\",\n            next: \"noQstring\"\n        }],        \n        noQstring : [{\n            regex: \"^\\\\s*%{\\\\s*$\",\n            token: \"comment.start\",\n            push: \"blockComment\"\n        }, {\n            token : \"comment\",\n            regex : \"%[^\\r\\n]*\"\n        }, {\n            token : \"string\",\n            regex : '\"',\n            stateName : \"qqstring\",\n            next  : [{\n                token : \"constant.language.escape\",\n                regex : /\\\\./\n            }, {\n                token : \"string\",\n                regex : \"\\\\\\\\$\",\n                next  : \"qqstring\"\n            }, {\n                token : \"string\",\n                regex : '\"|$',\n                next  : \"start\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\",\n            next: \"start\"\n        }, {\n            token : \"punctuation.operator\",\n            regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\",\n            next: \"start\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[({\\\\[]\",\n            next: \"start\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\]})]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }, {\n            token : \"text\",\n            regex : \"$\",\n            next  : \"start\"\n        }],\n        blockComment: [{\n            regex: \"^\\\\s*%{\\\\s*$\",\n            token: \"comment.start\",\n            push: \"blockComment\"\n        }, {\n            regex: \"^\\\\s*%}\\\\s*$\",\n            token: \"comment.end\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(MatlabHighlightRules, TextHighlightRules);\n\nexports.MatlabHighlightRules = MatlabHighlightRules;\n"
  },
  {
    "path": "src/mode/maze.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MazeHighlightRules = require(\"./maze_highlight_rules\").MazeHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MazeHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.$id = \"ace/mode/maze\";\n    this.snippetFileId = \"ace/snippets/maze\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/maze_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MazeHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"keyword.control\",\n            regex: /##|``/,\n            comment: \"Wall\"\n        }, {\n            token: \"entity.name.tag\",\n            regex: /\\.\\./,\n            comment: \"Path\"\n        }, {\n            token: \"keyword.control\",\n            regex: /<>/,\n            comment: \"Splitter\"\n        }, {\n            token: \"entity.name.tag\",\n            regex: /\\*[\\*A-Za-z0-9]/,\n            comment: \"Signal\"\n        }, {\n            token: \"constant.numeric\",\n            regex: /[0-9]{2}/,\n            comment: \"Pause\"\n        }, {\n            token: \"keyword.control\",\n            regex: /\\^\\^/,\n            comment: \"Start\"\n        }, {\n            token: \"keyword.control\",\n            regex: /\\(\\)/,\n            comment: \"Hole\"\n        }, {\n            token: \"support.function\",\n            regex: />>/,\n            comment: \"Out\"\n        }, {\n            token: \"support.function\",\n            regex: />\\//,\n            comment: \"Ln Out\"\n        }, {\n            token: \"support.function\",\n            regex: /<</,\n            comment: \"In\"\n        }, {\n            token: \"keyword.control\",\n            regex: /--/,\n            comment: \"One use\"\n        }, {\n            token: \"constant.language\",\n            regex: /%[LRUDNlrudn]/,\n            comment: \"Direction\"\n        }, {\n            token: [\n                \"entity.name.function\",\n                \"keyword.other\",\n                \"keyword.operator\",\n                \"keyword.other\",\n                \"keyword.operator\",\n                \"constant.numeric\",\n                \"keyword.operator\",\n                \"keyword.other\",\n                \"keyword.operator\",\n                \"constant.numeric\",\n                \"string.quoted.double\",\n                \"string.quoted.single\"\n            ],\n            regex: /([A-Za-z][A-Za-z0-9])( *-> *)(?:([-+*\\/]=)( *)((?:-)?)([0-9]+)|(=)( *)(?:((?:-)?)([0-9]+)|(\"[^\"]*\")|('[^']*')))/,\n            comment: \"Assignment function\"\n        }, {\n            token: [\n                \"entity.name.function\",\n                \"keyword.other\",\n                \"keyword.control\",\n                \"keyword.other\",\n                \"keyword.operator\",\n                \"keyword.other\",\n                \"keyword.operator\",\n                \"constant.numeric\",\n                \"entity.name.tag\",\n                \"keyword.other\",\n                \"keyword.control\",\n                \"keyword.other\",\n                \"constant.language\",\n                \"keyword.other\",\n                \"keyword.control\",\n                \"keyword.other\",\n                \"constant.language\"\n            ],\n            regex: /([A-Za-z][A-Za-z0-9])( *-> *)(IF|if)( *)(?:([<>]=?|==)( *)((?:-)?)([0-9]+)|(\\*[\\*A-Za-z0-9]))( *)(THEN|then)( *)(%[LRUDNlrudn])(?:( *)(ELSE|else)( *)(%[LRUDNlrudn]))?/,\n            comment: \"Equality Function\"\n        }, {\n            token: \"entity.name.function\",\n            regex: /[A-Za-z][A-Za-z0-9]/,\n            comment: \"Function cell\"\n        }, {\n            token: \"comment.line.double-slash\",\n            regex: / *\\/\\/.*/,\n            comment: \"Comment\"\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nMazeHighlightRules.metaData = {\n    fileTypes: [\"mz\"],\n    name: \"Maze\",\n    scopeName: \"source.maze\"\n};\n\n\noop.inherits(MazeHighlightRules, TextHighlightRules);\n\nexports.MazeHighlightRules = MazeHighlightRules;\n"
  },
  {
    "path": "src/mode/mediawiki.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MediaWikiHighlightRules = require(\"./mediawiki_highlight_rules\").MediaWikiHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = MediaWikiHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    this.blockComment = {start: \"<!--\", end: \"-->\"};\n    this.$id = \"ace/mode/mediawiki\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mediawiki_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MediaWikiHighlightRules = function() {\n    this.$rules = {\n        start: [{\n            include: \"#switch\"\n        }, {\n            include: \"#redirect\"\n        }, {\n            include: \"#variable\"\n        }, {\n            include: \"#comment\"\n        }, {\n            include: \"#entity\"\n        }, {\n            include: \"#emphasis\"\n        }, {\n            include: \"#tag\"\n        }, {\n            include: \"#table\"\n        }, {\n            include: \"#hr\"\n        }, {\n            include: \"#heading\"\n        }, {\n            include: \"#link\"\n        }, {\n            include: \"#list\"\n        }, {\n            include: \"#template\"\n        }],\n        \"#hr\": [{\n            token: \"markup.bold\",\n            regex: /^[-]{4,}/\n        }],\n        \"#switch\": [{\n            token: \"constant.language\",\n            regex: /(__NOTOC__|__FORCETOC__|__TOC__|__NOEDITSECTION__|__NEWSECTIONLINK__|__NONEWSECTIONLINK__|__NOWYSIWYG__|__NOGALLERY__|__HIDDENCAT__|__EXPECTUNUSEDCATEGORY__|__NOCONTENTCONVERT__|__NOCC__|__NOTITLECONVERT__|__NOTC__|__START__|__END__|__INDEX__|__NOINDEX__|__STATICREDIRECT__|__NOGLOBAL__|__DISAMBIG__)/\n        }],\n        \"#redirect\": [{\n            token: [\n                \"keyword.control.redirect\",\n                \"meta.keyword.control\"\n            ],\n            regex: /(^#REDIRECT|^#redirect|^#Redirect)(\\s+)/\n        }],\n        \"#variable\": [{\n            token: \"storage.type.variable\",\n            regex: /{{{/,\n            push: [{\n                token: \"storage.type.variable\",\n                regex: /}}}/,\n                next: \"pop\"\n            }, {\n                token: [\n                    \"text\",\n                    \"variable.other\",\n                    \"text\",\n                    \"keyword.operator\"\n                ],\n                regex: /(\\s*)(\\w+)(\\s*)((?:\\|)?)/\n            }, {\n                defaultToken: \"storage.type.variable\"\n            }]\n        }],\n        \"#entity\": [{\n            token: \"constant.character.entity\",\n            regex: /&\\w+;/\n        }],\n        \"#list\": [{\n            token: \"markup.bold\",\n            regex: /^[#*;:]+/,\n            push: [{\n                token: \"markup.list\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                include: \"$self\"\n            }, {\n                defaultToken: \"markup.list\"\n            }]\n        }],\n        \"#template\": [{\n            token: [\n                \"storage.type.function\",\n                \"meta.template\",\n                \"entity.name.function\",\n                \"meta.template\"\n            ],\n            regex: /({{)(\\s*)([#\\w: ]+)(\\s*)/,\n            push: [{\n                token: \"storage.type.function\",\n                regex: /}}/,\n                next: \"pop\"\n            }, {\n                token: [\n                    \"storage\",\n                    \"meta.structure.dictionary\",\n                    \"support.type.property-name\",\n                    \"meta.structure.dictionary\",\n                    \"punctuation.separator.dictionary.key-value\",\n                    \"meta.structure.dictionary\",\n                    \"meta.structure.dictionary.value\"\n                ],\n                regex: /(\\|)(\\s*)([a-zA-Z-]*)(\\s*)(=)(\\s*)([^|}]*)/,\n                push: [{\n                    token: \"meta.structure.dictionary\",\n                    regex: /(?=}}|[|])/,\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"meta.structure.dictionary\"\n                }]\n            }, {\n                token: [\"storage\", \"meta.template.value\"],\n                regex: /(\\|)(.*?)/,\n                push: [{\n                    token: [],\n                    regex: /(?=}}|[|])/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    defaultToken: \"meta.template.value\"\n                }]\n            }, {\n                defaultToken: \"meta.template\"\n            }]\n        }],\n        \"#link\": [{\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"meta.tag.link.internal\",\n                \"entity.name.tag\",\n                \"meta.tag.link.internal\",\n                \"string.other.link.title\",\n                \"meta.tag.link.internal\",\n                \"punctuation.definition.tag\"\n            ],\n            regex: /(\\[\\[)(\\s*)((?:Category|Wikipedia)?)(:?)([^\\]\\]\\|]+)(\\s*)((?:\\|)*)/,\n            push: [{\n                token: \"punctuation.definition.tag.end\",\n                regex: /\\]\\]/,\n                next: \"pop\"\n            }, {\n                include: \"$self\"\n            }, {\n                defaultToken: \"meta.tag.link.internal\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"meta.tag.link.external\",\n                \"meta.tag.link.external\",\n                \"string.unquoted\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /(\\[)(.*?)([\\s]+)(.*?)(\\])/\n        }],\n        \"#comment\": [{\n            token: \"punctuation.definition.comment.html\",\n            regex: /<!--/,\n            push: [{\n                token: \"punctuation.definition.comment.html\",\n                regex: /-->/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.html\"\n            }]\n        }],\n        \"#emphasis\": [{\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"markup.italic.bold\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /(''''')(?!')(.*?)('''''|$)/\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"markup.bold\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /(''')(?!')(.*?)('''|$)/\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"markup.italic\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /('')(?!')(.*?)(''|$)/\n        }],\n        \"#heading\": [{\n            token: [\n                \"punctuation.definition.heading\",\n                \"entity.name.section\",\n                \"punctuation.definition.heading\"\n            ],\n            regex: /(={1,6})(.+?)(\\1)(?!=)/\n        }],\n        \"#tag\": [{\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"entity.name.tag\",\n                \"meta.tag.block.ref\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /(<)(ref)((?:\\s+.*?)?)(>)/,\n            caseInsensitive: true,\n            push: [{\n                token: [\n                    \"punctuation.definition.tag.begin\",\n                    \"entity.name.tag\",\n                    \"meta.tag.block.ref\",\n                    \"punctuation.definition.tag.end\"\n                ],\n                regex: /(<\\/)(ref)(\\s*)(>)/,\n                caseInsensitive: true,\n                next: \"pop\"\n            }, {\n                include: \"$self\"\n            }, {\n                defaultToken: \"meta.tag.block.ref\"\n            }]\n        },\n        {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"entity.name.tag\",\n                \"meta.tag.block.nowiki\",\n                \"punctuation.definition.tag.end\"\n            ],\n            regex: /(<)(nowiki)((?:\\s+.*?)?)(>)/,\n            caseInsensitive: true,\n            push: [{\n                token: [\n                    \"punctuation.definition.tag.begin\",\n                    \"entity.name.tag\",\n                    \"meta.tag.block.nowiki\",\n                    \"punctuation.definition.tag.end\"\n                ],\n                regex: /(<\\/)(nowiki)(\\s*)(>)/,\n                caseInsensitive: true,\n                next: \"pop\"\n            }, {\n                defaultToken: \"meta.tag.block.nowiki\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"entity.name.tag\"\n            ],\n            regex: /(<\\/?)(noinclude|includeonly|onlyinclude)(?=\\W)/,\n            caseInsensitive: true,\n            push: [{\n                token: [\n                    \"invalid.illegal\",\n                    \"punctuation.definition.tag.end\"\n                ],\n                regex: /((?:\\/)?)(>)/,\n                next: \"pop\"\n            }, {\n                include: \"#attribute\"\n            }, {\n                defaultToken: \"meta.tag.block.any\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"entity.name.tag\"\n            ],\n            regex: /(<)(br|wbr|hr|meta|link)(?=\\W)/,\n            caseInsensitive: true,\n            push: [{\n                token: \"punctuation.definition.tag.end\",\n                regex: /\\/?>/,\n                next: \"pop\"\n            }, {\n                include: \"#attribute\"\n            }, {\n                defaultToken: \"meta.tag.other\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"entity.name.tag\"\n            ],\n            regex: /(<\\/?)(div|center|span|h1|h2|h3|h4|h5|h6|bdo|em|strong|cite|dfn|code|samp|kbd|var|abbr|blockquote|q|sub|sup|p|pre|ins|del|ul|ol|li|dl|dd|dt|table|caption|thead|tfoot|tbody|colgroup|col|tr|td|th|a|img|video|source|track|tt|b|i|big|small|strike|s|u|font|ruby|rb|rp|rt|rtc|math|figure|figcaption|bdi|data|time|mark|html)(?=\\W)/,\n            caseInsensitive: true,\n            push: [{\n                token: [\n                    \"invalid.illegal\",\n                    \"punctuation.definition.tag.end\"\n                ],\n                regex: /((?:\\/)?)(>)/,\n                next: \"pop\"\n            }, {\n                include: \"#attribute\"\n            }, {\n                defaultToken: \"meta.tag.block\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.tag.begin\",\n                \"invalid.illegal\"\n            ],\n            regex: /(<\\/)(br|wbr|hr|meta|link)(?=\\W)/,\n            caseInsensitive: true,\n            push: [{\n                token: \"punctuation.definition.tag.end\",\n                regex: /\\/?>/,\n                next: \"pop\"\n            }, {\n                include: \"#attribute\"\n            }, {\n                defaultToken: \"meta.tag.other\"\n            }]\n        }],\n        \"#caption\": [{\n            token: [\n                \"meta.tag.block.table-caption\",\n                \"punctuation.definition.tag.begin\"\n            ],\n            regex: /^(\\s*)(\\|\\+)/,\n            push: [{\n                token: \"meta.tag.block.table-caption\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"meta.tag.block.table-caption\"\n            }]\n        }],\n        \"#tr\": [{\n            token: [\n                \"meta.tag.block.tr\",\n                \"punctuation.definition.tag.begin\",\n                \"meta.tag.block.tr\",\n                \"invalid.illegal\"\n            ],\n            regex: /^(\\s*)(\\|\\-)([\\s]*)(.*)/\n        }],\n        \"#th\": [{\n            token: [\n                \"meta.tag.block.th.heading\",\n                \"punctuation.definition.tag.begin\",\n                \"meta.tag.block.th.heading\",\n                \"punctuation.definition.tag\",\n                \"markup.bold\"\n            ],\n            regex: /^(\\s*)(!)(?:(.*?)(\\|))?(.*?)(?=!!|$)/,\n            push: [{\n                token: \"meta.tag.block.th.heading\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                token: [\n                    \"punctuation.definition.tag.begin\",\n                    \"meta.tag.block.th.inline\",\n                    \"punctuation.definition.tag\",\n                    \"markup.bold\"\n                ],\n                regex: /(!!)(?:(.*?)(\\|))?(.*?)(?=!!|$)/\n            }, {\n                include: \"$self\"\n            }, {\n                defaultToken: \"meta.tag.block.th.heading\"\n            }]\n        }],\n        \"#td\": [{\n            token: [\n                \"meta.tag.block.td\",\n                \"punctuation.definition.tag.begin\"\n            ],\n            regex: /^(\\s*)(\\|)/,\n            push: [{\n                token: \"meta.tag.block.td\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                include: \"$self\"\n            }, {\n                defaultToken: \"meta.tag.block.td\"\n            }]\n        }],\n        \"#table\": [{\n            patterns: [{\n                name: \"meta.tag.block.table\",\n                begin: \"^\\\\s*({\\\\|)(.*?)$\",\n                end: \"^\\\\s*\\\\|}\",\n                beginCaptures: {\n                    1: {\n                        name: \"punctuation.definition.tag.begin\"\n                    },\n                    2: {\n                        patterns: [{\n                            include: \"#attribute\"\n                        }]\n                    },\n                    3: {\n                        name: \"invalid.illegal\"\n                    }\n                },\n                endCaptures: {\n                    0: {\n                        name: \"punctuation.definition.tag.end\"\n                    }\n                },\n                patterns: [{\n                    include: \"#comment\"\n                }, {\n                    include: \"#template\"\n                }, {\n                    include: \"#caption\"\n                }, {\n                    include: \"#tr\"\n                }, {\n                    include: \"#th\"\n                }, {\n                    include: \"#td\"\n                }]\n            }],\n            repository: {\n                caption: {\n                    name: \"meta.tag.block.table-caption\",\n                    begin: \"^\\\\s*(\\\\|\\\\+)\",\n                    end: \"$\",\n                    beginCaptures: {\n                        1: {\n                            name: \"punctuation.definition.tag.begin\"\n                        }\n                    }\n                },\n                tr: {\n                    name: \"meta.tag.block.tr\",\n                    match: \"^\\\\s*(\\\\|\\\\-)[\\\\s]*(.*)\",\n                    captures: {\n                        1: {\n                            name: \"punctuation.definition.tag.begin\"\n                        },\n                        2: {\n                            name: \"invalid.illegal\"\n                        }\n                    }\n                },\n                th: {\n                    name: \"meta.tag.block.th.heading\",\n                    begin: \"^\\\\s*(!)((.*?)(\\\\|))?(.*?)(?=(!!)|$)\",\n                    end: \"$\",\n                    beginCaptures: {\n                        1: {\n                            name: \"punctuation.definition.tag.begin\"\n                        },\n                        3: {\n                            patterns: [{\n                                include: \"#attribute\"\n                            }]\n                        },\n                        4: {\n                            name: \"punctuation.definition.tag\"\n                        },\n                        5: {\n                            name: \"markup.bold\"\n                        }\n                    },\n                    patterns: [{\n                        name: \"meta.tag.block.th.inline\",\n                        match: \"(!!)((.*?)(\\\\|))?(.*?)(?=(!!)|$)\",\n                        captures: {\n                            1: {\n                                name: \"punctuation.definition.tag.begin\"\n                            },\n                            3: {\n                                patterns: [{\n                                    include: \"#attribute\"\n                                }]\n                            },\n                            4: {\n                                name: \"punctuation.definition.tag\"\n                            },\n                            5: {\n                                name: \"markup.bold\"\n                            }\n                        }\n                    }, {\n                        include: \"$self\"\n                    }]\n                },\n                td: {\n                    name: \"meta.tag.block.td\",\n                    begin: \"^\\\\s*(\\\\|)\",\n                    end: \"$\",\n                    beginCaptures: {\n                        1: {\n                            name: \"punctuation.definition.tag.begin\"\n                        },\n                        2: {\n                            patterns: [{\n                                include: \"#attribute\"\n                            }]\n                        },\n                        3: {\n                            name: \"punctuation.definition.tag\"\n                        }\n                    },\n                    patterns: [{\n                        include: \"$self\"\n                    }]\n                }\n            }\n        }],\n        \"#attribute\": [{\n            include: \"#string\"\n        }, {\n            token: \"entity.other.attribute-name\",\n            regex: /\\w+/\n        }],\n        \"#string\": [{\n            token: \"string.quoted.double\",\n            regex: /\\\"/,\n            push: [{\n                token: \"string.quoted.double\",\n                regex: /\\\"/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.double\"\n            }]\n        }, {\n            token: \"string.quoted.single\",\n            regex: /\\'/,\n            push: [{\n                token: \"string.quoted.single\",\n                regex: /\\'/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.single\"\n            }]\n        }],\n        \"#url\": [{\n            token: \"markup.underline.link\",\n            regex: /(?:http(?:s)?:\\/\\/)?[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:\\/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+/\n        }, {\n            token: \"invalid.illegal\",\n            regex: /.*/\n        }]\n    };\n    \n\n    this.normalizeRules();\n};\n\nMediaWikiHighlightRules.metaData = {\n    name: \"MediaWiki\",\n    scopeName: \"text.html.mediawiki\",\n    fileTypes: [\"mediawiki\", \"wiki\"]\n};\n\n\noop.inherits(MediaWikiHighlightRules, TextHighlightRules);\n\nexports.MediaWikiHighlightRules = MediaWikiHighlightRules;\n"
  },
  {
    "path": "src/mode/mel.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MELHighlightRules = require(\"./mel_highlight_rules\").MELHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MELHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/mel\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mel_highlight_rules.js",
    "content": "/* THIS FILE WAS AUTOGENERATED FROM MEL.tmLanguage (UUID: 69554E52-391D-42BC-9F65-7A77444BA1CF) */\n/****************************************************************\n * IT MIGHT NOT BE PERFECT, PARTICULARLY:                       *\n * IN DECIDING STATES TO TRANSITION TO,                         *\n * IGNORING WHITESPACE,                                         *\n * IGNORING GROUPS WITH ?:,                                     *\n * EXTENDING EXISTING MODES,                                    *\n * GATHERING KEYWORDS, OR                                       *\n * DECIDING WHEN TO USE PUSH.                                   *\n * ...But it's a good start from an existing *.tmlanguage file. *\n ****************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MELHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { caseInsensitive: true,\n           token: 'storage.type.mel',\n           regex: '\\\\b(matrix|string|vector|float|int|void)\\\\b' },\n         { caseInsensitive: true,\n           token: 'support.function.mel',\n           regex: '\\\\b((s(h(ow(ManipCtx|S(hadingGroupAttrEditor|electionInTitle)|H(idden|elp)|Window)|el(f(Button|TabLayout|Layout)|lField)|ading(GeometryRelCtx|Node|Connection|LightRelCtx))|y(s(tem|File)|mbol(Button|CheckBox))|nap(shot|Mode|2to2 |TogetherCtx|Key)|c(ulpt|ene(UIReplacement|Editor)|ale(BrushBrightness |Constraint|Key(Ctx)?)?|r(ipt(Node|Ctx|Table|edPanel(Type)?|Job|EditorInfo)|oll(Field|Layout))|mh)|t(itch(Surface(Points)?|AndExplodeShell )|a(ckTrace|rt(sWith |String ))|r(cmp|i(ng(ToStringArray |Array(Remove(Duplicates | )|C(ount |atenate )|ToString |Intersector))|p )|oke))|i(n(gleProfileBirailSurface)?|ze|gn|mplify)|o(u(nd(Control)?|rce)|ft(Mod(Ctx)?)?|rt)|u(perCtx|rface(S(haderList|ampler))?|b(st(itute(Geometry|AllString )?|ring)|d(M(irror|a(tchTopology|p(SewMove|Cut)))|iv(Crease|DisplaySmoothness)?|C(ollapse|leanTopology)|T(o(Blind|Poly)|ransferUVsToCache)|DuplicateAndConnect|EditUV|ListComponentConversion|AutoProjection)))|p(h(ere|rand)|otLight(PreviewPort)?|aceLocator|r(ing|eadSheetEditor))|e(t(s|MenuMode|Sta(te |rtupMessage|mpDensity )|NodeTypeFlag|ConstraintRestPosition |ToolTo|In(putDeviceMapping|finity)|D(ynamic|efaultShadingGroup|rivenKeyframe)|UITemplate|P(ar(ticleAttr|ent)|roject )|E(scapeCtx|dit(or|Ctx))|Key(Ctx|frame|Path)|F(ocus|luidAttr)|Attr(Mapping)?)|parator|ed|l(ect(Mode|ionConnection|Context|Type|edNodes|Pr(iority|ef)|Key(Ctx)?)?|LoadSettings)|archPathArray )|kin(Cluster|Percent)|q(uareSurface|rt)|w(itchTable|atchDisplayPort)|a(ve(Menu|Shelf|ToolSettings|I(nitialState|mage)|Pref(s|Objects)|Fluid|A(ttrPreset |llShelves))|mpleImage)|rtContext|mooth(step|Curve|TangentSurface))|h(sv_to_rgb|yp(ot|er(Graph|Shade|Panel))|i(tTest|de|lite)|ot(Box|key(Check)?)|ud(Button|Slider(Button)?)|e(lp(Line)?|adsUpDisplay|rmite)|wRe(nder(Load)?|flectionMap)|ard(enPointCurve|ware(RenderPanel)?))|n(o(nLinear|ise|de(Type|IconButton|Outliner|Preset)|rmal(ize |Constraint))|urbs(Boolean|S(elect|quare)|C(opyUVSet|ube)|To(Subdiv|Poly(gonsPref)?)|Plane|ViewDirectionVector )|ew(ton|PanelItems)|ame(space(Info)?|Command|Field))|c(h(oice|dir|eck(Box(Grp)?|DefaultRenderGlobals)|a(n(nelBox|geSubdiv(Region|ComponentDisplayLevel))|racter(Map|OutlineEditor)?))|y(cleCheck|linder)|tx(Completion|Traverse|EditMode|Abort)|irc(ularFillet|le)|o(s|n(str(uctionHistory|ain(Value)?)|nect(ionInfo|Control|Dynamic|Joint|Attr)|t(extInfo|rol)|dition|e|vert(SolidTx|Tessellation|Unit|FromOldLayers |Lightmap)|firmDialog)|py(SkinWeights|Key|Flexor|Array )|l(or(Slider(Grp|ButtonGrp)|Index(SliderGrp)?|Editor|AtPoint)?|umnLayout|lision)|arsenSubdivSelectionList|m(p(onentEditor|utePolysetVolume |actHairSystem )|mand(Port|Echo|Line)))|u(tKey|r(ve(MoveEPCtx|SketchCtx|CVCtx|Intersect|OnSurface|E(ditorCtx|PCtx)|AddPtCtx)?|rent(Ctx|Time(Ctx)?|Unit)))|p(GetSolverAttr|Button|S(olver(Types)?|e(t(SolverAttr|Edit)|am))|C(o(nstraint|llision)|ache)|Tool|P(anel|roperty))|eil|l(ip(Schedule(rOutliner)?|TrimBefore |Editor(CurrentTimeCtx)?)?|ose(Surface|Curve)|uster|ear(Cache)?|amp)|a(n(CreateManip|vas)|tch(Quiet)?|pitalizeString |mera(View)?)|r(oss(Product )?|eate(RenderLayer|MotionField |SubdivRegion|N(ode|ewShelf )|D(isplayLayer|rawCtx)|Editor))|md(Shell|FileOutput))|M(R(ender(ShadowData|Callback|Data|Util|View|Line(Array)?)|ampAttribute)|G(eometryData|lobal)|M(odelMessage|essage|a(nipData|t(erial|rix)))|BoundingBox|S(yntax|ceneMessage|t(atus|ring(Array)?)|imple|pace|elect(ion(Mask|List)|Info)|watchRender(Register|Base))|H(ardwareRenderer|WShaderSwatchGenerator)|NodeMessage|C(o(nditionMessage|lor(Array)?|m(putation|mand(Result|Message)))|ursor|loth(Material|S(ystem|olverRegister)|Con(straint|trol)|Triangle|Particle|Edge|Force)|allbackIdArray)|T(ypeId|ime(r(Message)?|Array)?|oolsInfo|esselationParams|r(imBoundaryArray|ansformationMatrix))|I(ntArray|t(Geometry|Mesh(Polygon|Edge|Vertex|FaceVertex)|S(urfaceCV|electionList)|CurveCV|Instancer|eratorType|D(ependency(Graph|Nodes)|ag)|Keyframe)|k(System|HandleGroup)|mage)|3dView|Object(SetMessage|Handle|Array)?|D(G(M(odifier|essage)|Context)|ynSwept(Triangle|Line)|istance|oubleArray|evice(State|Channel)|a(ta(Block|Handle)|g(M(odifier|essage)|Path(Array)?))|raw(Request(Queue)?|Info|Data|ProcedureBase))|U(serEventMessage|i(nt(Array|64Array)|Message))|P(o(int(Array)?|lyMessage)|lug(Array)?|rogressWindow|x(G(eometry(Iterator|Data)|lBuffer)|M(idiInputDevice|odelEditorCommand|anipContainer)|S(urfaceShape(UI)?|pringNode|electionContext)|HwShaderNode|Node|Co(ntext(Command)?|m(ponentShape|mand))|T(oolCommand|ransform(ationMatrix)?)|IkSolver(Node)?|3dModelView|ObjectSet|D(eformerNode|ata|ragAndDropBehavior)|PolyT(weakUVCommand|rg)|EmitterNode|F(i(eldNode|leTranslator)|luidEmitterNode)|LocatorNode))|E(ulerRotation|vent(Message)?)|ayatomr|Vector(Array)?|Quaternion|F(n(R(otateManip|eflectShader|adialField)|G(e(nericAttribute|ometry(Data|Filter))|ravityField)|M(otionPath|es(sageAttribute|h(Data)?)|a(nip3D|trix(Data|Attribute)))|B(l(innShader|endShapeDeformer)|ase)|S(caleManip|t(ateManip|ring(Data|ArrayData))|ingleIndexedComponent|ubd(Names|Data)?|p(hereData|otLight)|et|kinCluster)|HikEffector|N(on(ExtendedLight|AmbientLight)|u(rbs(Surface(Data)?|Curve(Data)?)|meric(Data|Attribute))|ewtonField)|C(haracter|ircleSweepManip|ompo(nent(ListData)?|undAttribute)|urveSegmentManip|lip|amera)|T(ypedAttribute|oggleManip|urbulenceField|r(ipleIndexedComponent|ansform))|I(ntArrayData|k(Solver|Handle|Joint|Effector))|D(ynSweptGeometryData|i(s(cManip|tanceManip)|rection(Manip|alLight))|ouble(IndexedComponent|ArrayData)|ependencyNode|a(ta|gNode)|ragField)|U(ni(tAttribute|formField)|Int64ArrayData)|P(hong(Shader|EShader)|oint(On(SurfaceManip|CurveManip)|Light|ArrayData)|fxGeometry|lugin(Data)?|arti(cleSystem|tion))|E(numAttribute|xpression)|V(o(lume(Light|AxisField)|rtexField)|ectorArrayData)|KeyframeDelta(Move|B(lockAddRemove|reakdown)|Scale|Tangent|InfType|Weighted|AddRemove)?|F(ield|luid|reePointTriadManip)|W(ireDeformer|eightGeometryFilter)|L(ight(DataAttribute)?|a(yeredShader|ttice(D(eformer|ata))?|mbertShader))|A(ni(sotropyShader|mCurve)|ttribute|irField|r(eaLight|rayAttrsData)|mbientLight))?|ile(IO|Object)|eedbackLine|loat(Matrix|Point(Array)?|Vector(Array)?|Array))|L(i(ghtLinks|brary)|ockMessage)|A(n(im(Message|C(ontrol|urveC(hange|lipboard(Item(Array)?)?))|Util)|gle)|ttribute(Spec(Array)?|Index)|r(rayData(Builder|Handle)|g(Database|Parser|List))))|t(hreePointArcCtx|ime(Control|Port|rX)|o(ol(Button|HasOptions|Collection|Dropped|PropertyWindow)|NativePath |upper|kenize(List )?|l(ower|erance)|rus|ggle(WindowVisibility|Axis)?)|u(rbulence|mble(Ctx)?)|ex(RotateContext|M(oveContext|anipContext)|t(ScrollList|Curves|ure(HairColor |DisplacePlane |PlacementContext|Window)|ToShelf |Field(Grp|ButtonGrp)?)?|S(caleContext|electContext|mudgeUVContext)|WinToolCtx)|woPointArcCtx|a(n(gentConstraint)?|bLayout)|r(im|unc(ate(HairCache|FluidCache))?|a(ns(formLimits|lator)|c(e|k(Ctx)?))))|i(s(olateSelect|Connected|True|Dirty|ParentOf |Valid(String |ObjectName |UiName )|AnimCurve )|n(s(tance(r)?|ert(Joint(Ctx)?|K(not(Surface|Curve)|eyCtx)))|heritTransform|t(S(crollBar|lider(Grp)?)|er(sect|nalVar|ToUI )|Field(Grp)?))|conText(Radio(Button|Collection)|Button|StaticLabel|CheckBox)|temFilter(Render|Type|Attr)?|prEngine|k(S(ystem(Info)?|olver|plineHandleCtx)|Handle(Ctx|DisplayScale)?|fkDisplayMethod)|m(portComposerCurves |fPlugins|age))|o(ceanNurbsPreviewPlane |utliner(Panel|Editor)|p(tion(Menu(Grp)?|Var)|en(GLExtension|MayaPref))|verrideModifier|ffset(Surface|Curve(OnSurface)?)|r(ientConstraint|bit(Ctx)?)|b(soleteProc |j(ect(Center|Type(UI)?|Layer )|Exists)))|d(yn(RelEd(itor|Panel)|Globals|C(ontrol|ache)|P(a(intEditor|rticleCtx)|ref)|Exp(ort|ression)|amicLoad)|i(s(connect(Joint|Attr)|tanceDim(Context|ension)|pla(y(RGBColor|S(tats|urface|moothness)|C(olor|ull)|Pref|LevelOfDetail|Affected)|cementToPoly)|kCache|able)|r(name |ect(ionalLight|KeyCtx)|map)|mWhen)|o(cServer|Blur|t(Product )?|ubleProfileBirailSurface|peSheetEditor|lly(Ctx)?)|uplicate(Surface|Curve)?|e(tach(Surface|Curve|DeviceAttr)|vice(Panel|Editor)|f(ine(DataServer|VirtualDevice)|ormer|ault(Navigation|LightListCheckBox))|l(ete(Sh(elfTab |adingGroupsAndMaterials )|U(nusedBrushes |I)|Attr)?|randstr)|g_to_rad)|agPose|r(opoffLocator|ag(gerContext)?)|g(timer|dirty|Info|eval))|CBG |u(serCtx|n(t(angleUV|rim)|i(t|form)|do(Info)?|loadPlugin|assignInputDevice|group)|iTemplate|p(dateAE |Axis)|v(Snapshot|Link))|joint(C(tx|luster)|DisplayScale|Lattice)?|p(sd(ChannelOutliner|TextureFile|E(ditTextureFile|xport))|close|i(c(ture|kWalk)|xelMove)|o(se|int(MatrixMult |C(onstraint|urveConstraint)|On(Surface|Curve)|Position|Light)|p(upMenu|en)|w|l(y(Reduce|GeoSampler|M(irrorFace|ove(UV|Edge|Vertex|Facet(UV)?)|erge(UV|Edge(Ctx)?|Vertex|Facet(Ctx)?)|ap(Sew(Move)?|Cut|Del))|B(oolOp|evel|l(indData|endColor))|S(traightenUVBorder|oftEdge|u(perCtx|bdivide(Edge|Facet))|p(her(icalProjection|e)|lit(Ring|Ctx|Edge|Vertex)?)|e(tToFaceNormal|parate|wEdge|lect(Constraint(Monitor)?|EditCtx))|mooth)|Normal(izeUV|PerVertex)?|C(hipOff|ylind(er|ricalProjection)|o(ne|pyUV|l(or(BlindData|Set|PerVertex)|lapse(Edge|Facet)))|u(t(Ctx)?|be)|l(ipboard|oseBorder)|acheMonitor|rea(seEdge|teFacet(Ctx)?))|T(o(Subdiv|rus)|r(iangulate|ansfer))|In(stallAction|fo)|Options|D(uplicate(Edge|AndConnect)|el(Edge|Vertex|Facet))|U(nite|VSet)|P(yramid|oke|lan(e|arProjection)|r(ism|ojection))|E(ditUV|valuate|xtrude(Edge|Facet))|Qu(eryBlindData|ad)|F(orceUV|lip(UV|Edge))|WedgeFace|L(istComponentConversion|ayoutUV)|A(utoProjection|ppend(Vertex|FacetCtx)?|verage(Normal|Vertex)))|eVectorConstraint))|utenv|er(cent|formanceOptions)|fxstrokes|wd|l(uginInfo|a(y(b(last|ackOptions))?|n(e|arSrf)))|a(steKey|ne(l(History|Configuration)?|Layout)|thAnimation|irBlend|use|lettePort|r(ti(cle(RenderInfo|Instancer|Exists)?|tion)|ent(Constraint)?|am(Dim(Context|ension)|Locator)))|r(int|o(j(ect(ion(Manip|Context)|Curve|Tangent)|FileViewer)|pMo(dCtx|ve)|gress(Bar|Window)|mptDialog)|eloadRefEd))|e(n(codeString|d(sWith |String )|v|ableDevice)|dit(RenderLayer(Globals|Members)|or(Template)?|DisplayLayer(Globals|Members)|AttrLimits )|v(ent|al(Deferred|Echo)?)|quivalent(Tol | )|ffector|r(f|ror)|x(clusiveLightCheckBox|t(end(Surface|Curve)|rude)|ists|p(ortComposerCurves |ression(EditorListen)?)?|ec(uteForEachObject )?|actWorldBoundingBox)|mit(ter)?)|v(i(sor|ew(Set|HeadOn|2dToolCtx|C(lipPlane|amera)|Place|Fit|LookAt))|o(lumeAxis|rtex)|e(ctorize|rifyCmd )|alidateShelfName )|key(Tangent|frame(Region(MoveKeyCtx|S(caleKeyCtx|e(tKeyCtx|lectKeyCtx))|CurrentTimeCtx|TrackCtx|InsertKeyCtx|D(irectKeyCtx|ollyCtx))|Stats|Outliner)?)|qu(it|erySubdiv)|f(c(heck|lose)|i(nd(RelatedSkinCluster |MenuItem |er|Keyframe|AllIntersections )|tBspline|l(ter(StudioImport|Curve|Expand)?|e(BrowserDialog|test|Info|Dialog|Extension )?|letCurve)|rstParentOf )|o(ntDialog|pen|rmLayout)|print|eof|flush|write|l(o(or|w|at(S(crollBar|lider(Grp|ButtonGrp|2)?)|Eq |Field(Grp)?))|u(shUndo|id(CacheInfo|Emitter|VoxelInfo))|exor)|r(omNativePath |e(eFormFillet|wind|ad)|ameLayout)|get(word|line)|mod)|w(hatIs|i(ndow(Pref)?|re(Context)?)|orkspace|ebBrowser(Prefs)?|a(itCursor|rning)|ri(nkle(Context)?|teTake))|l(s(T(hroughFilter|ype )|UI)?|i(st(Relatives|MenuAnnotation |Sets|History|NodeTypes|C(onnections|ameras)|Transforms |InputDevice(s|Buttons|Axes)|erEditor|DeviceAttachments|Unselected |A(nimatable|ttr))|n(step|eIntersection )|ght(link|List(Panel|Editor)?))|o(ckNode|okThru|ft|ad(NewShelf |P(lugin|refObjects)|Fluid)|g)|a(ssoContext|y(out|er(Button|ed(ShaderPort|TexturePort)))|ttice(DeformKeyCtx)?|unch(ImageEditor)?))|a(ssign(Command|InputDevice)|n(notate|im(C(one|urveEditor)|Display|View)|gle(Between)?)|tt(ach(Surface|Curve|DeviceAttr)|r(ibute(Menu|Info|Exists|Query)|NavigationControlGrp|Co(ntrolGrp|lorSliderGrp|mpatibility)|PresetEditWin|EnumOptionMenu(Grp)?|Field(Grp|SliderGrp)))|i(r|mConstraint)|d(d(NewShelfTab|Dynamic|PP|Attr(ibuteEditorNodeHelp)?)|vanceToNextDrivenKey)|uto(Place|Keyframe)|pp(endStringArray|l(y(Take|AttrPreset)|icationName))|ffect(s|edNet)|l(i(as(Attr)?|gn(Surface|C(tx|urve))?)|lViewFit)|r(c(len|Len(DimContext|gthDimension))|t(BuildPaintMenu|Se(tPaintCtx|lectCtx)|3dPaintCtx|UserPaintCtx|PuttyCtx|FluidAttrCtx|Attr(SkinPaintCtx|Ctx|PaintVertexCtx))|rayMapper)|mbientLight|b(s|out))|r(igid(Body|Solver)|o(t(at(ionInterpolation|e))?|otOf |undConstantRadius|w(ColumnLayout|Layout)|ll(Ctx)?)|un(up|TimeCommand)|e(s(olutionNode|et(Tool|AE )|ampleFluid)|hash|n(der(GlobalsNode|Manip|ThumbnailUpdate|Info|er|Partition|QualityNode|Window(SelectContext|Editor)|LayerButton)?|ame(SelectionList |UI|Attr)?)|cord(Device|Attr)|target|order(Deformers)?|do|v(olve|erse(Surface|Curve))|quires|f(ineSubdivSelectionList|erence(Edit|Query)?|resh(AE )?)|loadImage|adTake|root|move(MultiInstance|Joint)|build(Surface|Curve))|a(n(d(state|omizeFollicles )?|geControl)|d(i(o(MenuItemCollection|Button(Grp)?|Collection)|al)|_to_deg)|mpColorPort)|gb_to_hsv)|g(o(toBindPose |al)|e(t(M(odifiers|ayaPanelTypes )|Classification|InputDeviceRange|pid|env|DefaultBrush|Pa(nel|rticleAttr)|F(ileList|luidAttr)|A(ttr|pplicationVersionAsFloat ))|ometryConstraint)|l(Render(Editor)?|obalStitch)|a(uss|mma)|r(id(Layout)?|oup(ObjectsByName )?|a(dientControl(NoAttr)?|ph(SelectContext|TrackCtx|DollyCtx)|vity|bColor))|match)|x(pmPicker|form|bmLangPathList )|m(i(n(imizeApp)?|rrorJoint)|o(del(CurrentTimeCtx|Panel|Editor)|use|v(In|e(IKtoFK |VertexAlongDirection|KeyCtx)?|Out))|u(te|ltiProfileBirailSurface)|e(ssageLine|nu(BarLayout|Item(ToShelf )?|Editor)?|mory)|a(nip(Rotate(Context|LimitsCtx)|Move(Context|LimitsCtx)|Scale(Context|LimitsCtx)|Options)|tch|ke(Roll |SingleSurface|TubeOn |Identity|Paintable|bot|Live)|rker|g|x))|b(in(Membership|d(Skin|Pose))|o(neLattice|undary|x(ZoomCtx|DollyCtx))|u(tton(Manip)?|ild(BookmarkMenu|KeyframeMenu)|fferCurve)|e(ssel|vel(Plus)?)|l(indDataType|end(Shape(Panel|Editor)?|2|TwoAttr))|a(sename(Ex | )|tchRender|ke(Results|Simulation|Clip|PartialHistory|FluidShading )))))\\\\b' },\n         { caseInsensitive: true,\n           token: 'support.constant.mel',\n           regex: '\\\\b(s(h(ellTessellate|a(d(ing(Map|Engine)|erGlow)|pe))|n(ow|apshot(Shape)?)|c(ulpt|aleConstraint|ript)|t(yleCurve|itch(Srf|AsNurbsShell)|u(cco|dioClearCoat)|encil|roke(Globals)?)|i(ngleShadingSwitch|mpleVolumeShader)|o(ftMod(Manip|Handle)?|lidFractal)|u(rface(Sha(der|pe)|Info|EdManip|VarGroup|Luminance)|b(Surface|d(M(odifier(UV|World)?|ap(SewMove|Cut|pingManip))|B(lindData|ase)|iv(ReverseFaces|SurfaceVarGroup|Co(llapse|mponentId)|To(Nurbs|Poly))?|HierBlind|CleanTopology|Tweak(UV)?|P(lanarProj|rojManip)|LayoutUV|A(ddTopology|utoProj))|Curve))|p(BirailSrf|otLight|ring)|e(tRange|lectionListOperator)|k(inCluster|etchPlane)|quareSrf|ampler(Info)?|m(ooth(Curve|TangentSrf)|ear))|h(svToRgb|yper(GraphInfo|View|Layout)|ik(Solver|Handle|Effector)|oldMatrix|eightField|w(Re(nderGlobals|flectionMap)|Shader)|a(ir(System|Constraint|TubeShader)|rd(enPoint|wareRenderGlobals)))|n(o(n(ExtendedLightShapeNode|Linear|AmbientLightShapeNode)|ise|rmalConstraint)|urbs(Surface|Curve|T(oSubdiv(Proc)?|essellate)|DimShape)|e(twork|wtonField))|c(h(o(ice|oser)|ecker|aracter(Map|Offset)?)|o(n(straint|tr(olPoint|ast)|dition)|py(ColorSet|UVSet))|urve(Range|Shape|Normalizer(Linear|Angle)?|In(tersect|fo)|VarGroup|From(Mesh(CoM|Edge)?|Su(rface(Bnd|CoS|Iso)?|bdiv(Edge|Face)?)))|l(ip(Scheduler|Library)|o(se(stPointOnSurface|Surface|Curve)|th|ud)|uster(Handle)?|amp)|amera(View)?|r(eate(BPManip|ColorSet|UVSet)|ater))|t(ime(ToUnitConversion|Function)?|oo(nLineAttributes|lDrawManip)|urbulenceField|ex(BaseDeformManip|ture(BakeSet|2d|ToGeom|3d|Env)|SmudgeUVManip|LatticeDeformManip)|weak|angentConstraint|r(i(pleShadingSwitch|m(WithBoundaries)?)|ansform(Geometry)?))|i(n(s(tancer|ertKnot(Surface|Curve))|tersectSurface)|k(RPsolver|MCsolver|S(ystem|olver|Csolver|plineSolver)|Handle|PASolver|Effector)|m(plicit(Box|Sphere|Cone)|agePlane))|o(cean(Shader)?|pticalFX|ffset(Surface|C(os|urve))|ldBlindDataBase|rient(Constraint|ationMarker)|bject(RenderFilter|MultiFilter|BinFilter|S(criptFilter|et)|NameFilter|TypeFilter|Filter|AttrFilter))|d(yn(Globals|Base)|i(s(tance(Between|DimShape)|pla(yLayer(Manager)?|cementShader)|kCache)|rect(ionalLight|edDisc)|mensionShape)|o(ubleShadingSwitch|f)|pBirailSrf|e(tach(Surface|Curve)|pendNode|f(orm(Bend|S(ine|quash)|Twist|ableShape|F(unc|lare)|Wave)|ault(RenderUtilityList|ShaderList|TextureList|LightList))|lete(Co(lorSet|mponent)|UVSet))|ag(Node|Pose)|r(opoffLocator|agField))|u(seBackground|n(trim|i(t(Conversion|ToTimeConversion)|formField)|known(Transform|Dag)?)|vChooser)|j(iggle|oint(Cluster|Ffd|Lattice)?)|p(sdFileTex|hong(E)?|o(s(tProcessList|itionMarker)|int(MatrixMult|Constraint|On(SurfaceInfo|CurveInfo)|Emitter|Light)|l(y(Reduce|M(irror|o(difier(UV|World)?|ve(UV|Edge|Vertex|Face(tUV)?))|erge(UV|Edge|Vert|Face)|ap(Sew(Move)?|Cut|Del))|B(oolOp|evel|lindData|ase)|S(traightenUVBorder|oftEdge|ubd(Edge|Face)|p(h(ere|Proj)|lit(Ring|Edge|Vert)?)|e(parate|wEdge)|mooth(Proxy|Face)?)|Normal(izeUV|PerVertex)?|C(hipOff|yl(inder|Proj)|o(ne|pyUV|l(orPerVertex|lapse(Edge|F)))|u(t(Manip(Container)?)?|be)|loseBorder|rea(seEdge|t(or|eFace)))|T(o(Subdiv|rus)|weak(UV)?|r(iangulate|ansfer))|OptUvs|D(uplicateEdge|el(Edge|Vertex|Facet))|Unite|P(yramid|oke(Manip)?|lan(e|arProj)|r(i(sm|mitive)|oj))|Extrude(Edge|Vertex|Face)|VertexNormalManip|Quad|Flip(UV|Edge)|WedgeFace|LayoutUV|A(utoProj|ppend(Vertex)?|verageVertex))|eVectorConstraint))|fx(Geometry|Hair|Toon)|l(usMinusAverage|a(n(e|arTrimSurface)|ce(2dTexture|3dTexture)))|a(ssMatrix|irBlend|r(ti(cle(SamplerInfo|C(olorMapper|loud)|TranspMapper|IncandMapper|AgeMapper)?|tion)|ent(Constraint|Tessellate)|amDimension))|r(imitive|o(ject(ion|Curve|Tangent)|xyManager)))|e(n(tity|v(Ball|ironmentFog|S(phere|ky)|C(hrome|ube)|Fog))|x(t(end(Surface|Curve)|rude)|p(lodeNurbsShell|ression)))|v(iewManip|o(lume(Shader|Noise|Fog|Light|AxisField)|rtexField)|e(ctor(RenderGlobals|Product)|rtexBakeSet))|quadShadingSwitch|f(i(tBspline|eld|l(ter(Resample|Simplify|ClosestSample|Euler)?|e|letCurve))|o(urByFourMatrix|llicle)|urPointOn(MeshInfo|Subd)|f(BlendSrf(Obsolete)?|d|FilletSrf)|l(ow|uid(S(hape|liceManip)|Texture(2D|3D)|Emitter)|exorShape)|ra(ctal|meCache))|w(tAddMatrix|ire|ood|eightGeometryFilter|ater|rap)|l(ight(Info|Fog|Li(st|nker))?|o(cator|okAt|d(Group|Thresholds)|ft)|uminance|ea(stSquaresModifier|ther)|a(yered(Shader|Texture)|ttice|mbert))|a(n(notationShape|i(sotropic|m(Blend(InOut)?|C(urve(T(T|U|L|A)|U(T|U|L|A))?|lip)))|gleBetween)|tt(ach(Surface|Curve)|rHierarchyTest)|i(rField|mConstraint)|dd(Matrix|DoubleLinear)|udio|vg(SurfacePoints|NurbsSurfacePoints|Curves)|lign(Manip|Surface|Curve)|r(cLengthDimension|tAttrPaintTest|eaLight|rayMapper)|mbientLight|bstractBase(NurbsConversion|Create))|r(igid(Body|Solver|Constraint)|o(ck|undConstantRadius)|e(s(olution|ultCurve(TimeTo(Time|Unitless|Linear|Angular))?)|nder(Rect|Globals(List)?|Box|Sphere|Cone|Quality|L(ight|ayer(Manager)?))|cord|v(olve(dPrimitive)?|erse(Surface|Curve)?)|f(erence|lect)|map(Hsv|Color|Value)|build(Surface|Curve))|a(dialField|mp(Shader)?)|gbToHsv|bfSrf)|g(uide|eo(Connect(or|able)|metry(Shape|Constraint|VarGroup|Filter))|lobal(Stitch|CacheControl)|ammaCorrect|r(id|oup(Id|Parts)|a(nite|vityField)))|Fur(Globals|Description|Feedback|Attractors)|xformManip|m(o(tionPath|untain|vie)|u(te|lt(Matrix|i(plyDivide|listerLight)|DoubleLinear))|pBirailSrf|e(sh(VarGroup)?|ntalray(Texture|IblShape))|a(terialInfo|ke(Group|Nurb(sSquare|Sphere|C(ylinder|ircle|one|ube)|Torus|Plane)|CircularArc|T(hreePointCircularArc|extCurves|woPointCircularArc))|rble))|b(irailSrf|o(neLattice|olean|undary(Base)?)|u(lge|mp(2d|3d))|evel(Plus)?|l(in(n|dDataTemplate)|end(Shape|Color(s|Sets)|TwoAttr|Device|Weighted)?)|a(se(GeometryVarGroup|ShadingSwitch|Lattice)|keSet)|r(ownian|ush)))\\\\b' },\n         { caseInsensitive: true,\n           token: 'keyword.control.mel',\n           regex: '\\\\b(if|in|else|for|while|break|continue|case|default|do|switch|return|switch|case|source|catch|alias)\\\\b' },\n         { token: 'keyword.other.mel', regex: '\\\\b(global)\\\\b' },\n         { caseInsensitive: true,\n           token: 'constant.language.mel',\n           regex: '\\\\b(null|undefined)\\\\b' },\n         { token: 'constant.numeric.mel',\n           regex: '\\\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\\\.?[0-9]*)|(\\\\.[0-9]+))((e|E)(\\\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\\\b' },\n         { token: 'punctuation.definition.string.begin.mel',\n           regex: '\"',\n           push: \n            [ { token: 'constant.character.escape.mel', regex: '\\\\\\\\.' },\n              { token: 'punctuation.definition.string.end.mel',\n                regex: '\"',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.double.mel' } ] },\n         \n         { token: [ 'variable.other.mel', 'punctuation.definition.variable.mel' ],\n           regex: '(\\\\$)([a-zA-Z_\\\\x7f-\\\\xff][a-zA-Z0-9_\\\\x7f-\\\\xff]*?\\\\b)' },\n           \n         { token: 'punctuation.definition.string.begin.mel',\n           regex: '\\'',\n           push: \n            [ { token: 'constant.character.escape.mel', regex: '\\\\\\\\.' },\n              { token: 'punctuation.definition.string.end.mel',\n                regex: '\\'',\n                next: 'pop' },\n              { defaultToken: 'string.quoted.single.mel' } ] },\n         \n         { token: 'constant.language.mel',\n           regex: '\\\\b(false|true|yes|no|on|off)\\\\b' },\n           \n         { token: 'punctuation.definition.comment.mel',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.mel',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.mel' } ] },\n         \n         { token: [ 'comment.line.double-slash.mel', 'punctuation.definition.comment.mel' ],\n           regex: '(//)(.*$\\\\n?)' },\n           \n         { caseInsensitive: true,\n           token: 'keyword.operator.mel',\n           regex: '\\\\b(instanceof)\\\\b' },\n         { token: 'keyword.operator.symbolic.mel',\n           regex: '[-\\\\!\\\\%\\\\&\\\\*\\\\+\\\\=\\\\/\\\\?\\\\:]' },\n         \n         { token: [ 'meta.preprocessor.mel', 'punctuation.definition.preprocessor.mel' ],\n           regex: '(^[ \\\\t]*)((?:#)[a-zA-Z]+)' },\n         \n         { token: [ 'meta.function.mel', 'keyword.other.mel', 'storage.type.mel', 'entity.name.function.mel', 'punctuation.section.function.mel' ],\n           regex: '(global\\\\s*)?(proc\\\\s*)(\\\\w+\\\\s*\\\\[?\\\\]?\\\\s+|\\\\s+)([A-Za-z_][A-Za-z0-9_\\\\.]*)(\\\\s*\\\\()',\n           push: \n            [ { include: '$self' },\n              { token: 'punctuation.section.function.mel',\n                regex: '\\\\)',\n                next: 'pop' },\n              { defaultToken: 'meta.function.mel' } ] }\n              \n              ] };\n    \n    this.normalizeRules();\n};\n\noop.inherits(MELHighlightRules, TextHighlightRules);\n\nexports.MELHighlightRules = MELHighlightRules;\n"
  },
  {
    "path": "src/mode/mips.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MIPSHighlightRules = require(\"./mips_highlight_rules\").MIPSHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = MIPSHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = [\"#\"];\n    this.$id = \"ace/mode/mips\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mips_highlight_rules.js",
    "content": "/* This file was autogenerated from mips.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MIPSHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var escapeRe = /\\\\(?:['\"?\\\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\\d]{2}|u[a-fA-F\\d]{4}U[a-fA-F\\d]{8}|.)/.source;\n\n    this.$rules = {\n        start: [{\n            token: \"storage.modifier.mips\",\n            regex: /\\.\\b(?:align|ascii|asciiz|byte|double|extern|float|globl|space|word)\\b/,\n            comment: \"Assembler directives for data storage\"\n        }, {\n            token: \"entity.name.section.mips\",\n            regex: /\\.\\b(?:data|text|kdata|ktext|)\\b/,\n            comment: \"Segements: .data .text\"\n        }, {\n            token: \"variable.parameter.mips\",\n            regex: /\\$(?:(?:3[01]|[12]?[0-9]|[0-9])|zero|at|v[01]|a[0-3]|s[0-7]|t[0-9]|k[01]|gp|sp|fp|ra)/,\n            comment: \"Registers by id $1, $2, ...\"\n        }, {\n            token: \"variable.parameter.mips\",\n            regex: /\\$f(?:[0-9]|[1-2][0-9]|3[0-1])/,\n            comment: \"Floating point registers\"\n        }, {\n            token: \"support.function.source.mips\",\n            regex: /\\b(?:(?:add|sub|div|l|mov|mult|neg|s|c\\.eq|c\\.le|c\\.lt)\\.[ds]|cvt\\.s\\.[dw]|cvt\\.d\\.[sw]|cvt\\.w\\.[ds]|bc1[tf])\\b/,\n            comment: \"The MIPS floating-point instruction set\"\n        }, {\n            token: \"support.function.source.mips\",\n            regex: /\\b(?:add|addu|addi|addiu|sub|subu|and|andi|or|not|ori|nor|xor|xori|slt|sltu|slti|sltiu|sll|sllv|rol|srl|sra|srlv|ror|j|jr|jal|beq|bne|lw|sw|lb|sb|lui|move|mfhi|mflo|mthi|mtlo)\\b/,\n            comment: \"Just the hardcoded instructions provided by the MIPS assembly language\"\n        }, {\n            token: \"support.function.other.mips\",\n            regex: /\\b(?:abs|b|beqz|bge|bgt|bgtu|ble|bleu|blt|bltu|bnez|div|divu|la|li|move|mul|neg|not|rem|remu|seq|sge|sgt|sle|sne)\\b/,\n            comment: \"Pseudo instructions\"\n        }, {\n            token: \"entity.name.function.mips\",\n            regex: /\\bsyscall\\b/,\n            comment: \"Other\"\n        }, {\n            token : \"string\", // character\n            regex : \"(?:'\\\")(?:\" + escapeRe + \"|.)?(?:'\\\")\"\n        }, {\n            token : \"string.start\",\n            regex : '\\'',\n            stateName: \"qstring\",\n            next: [\n                { token: \"string\", regex: /\\\\\\s*$/, next: \"qqstring\" },\n                { token: \"constant.language.escape\", regex: escapeRe },\n                { token: \"string.end\", regex: '\\'|$', next: \"start\" },\n                { defaultToken: \"string\"}\n            ]\n        }, {\n            token : \"string.start\",\n            regex : '\"',\n            stateName: \"qqstring\",\n            next: [\n                { token: \"string\", regex: /\\\\\\s*$/, next: \"qqstring\" },\n                { token: \"constant.language.escape\", regex: escapeRe },\n                { token: \"string.end\", regex: '\"|$', next: \"start\" },\n                { defaultToken: \"string\"}\n            ]\n        }, {\n            token: \"constant.numeric.mips\",\n            regex: /\\b(?:\\d+|0(?:x|X)[a-fA-F0-9]+)\\b/,\n            comment: \"Numbers like +12, -3, 55, 0x3F\"\n        }, {\n            token: \"entity.name.tag.mips\",\n            regex: /\\b[\\w]+\\b:/,\n            comment: \"Labels at line start: begin_repeat: add ...\"\n        }, {\n            token: \"comment.assembly\",\n            regex: /#.*$/,\n            comment: \"Single line comments\"\n        }]\n    };\n\n    this.normalizeRules();\n};\n\nMIPSHighlightRules.metaData = {\n    fileTypes: [\"s\", \"asm\"],\n    name: \"MIPS\",\n    scopeName: \"source.mips\"\n};\n\n\noop.inherits(MIPSHighlightRules, TextHighlightRules);\n\nexports.MIPSHighlightRules = MIPSHighlightRules;\n"
  },
  {
    "path": "src/mode/mixal.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MixalHighlightRules = require(\"./mixal_highlight_rules\").MixalHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = MixalHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/mixal\";\n    this.lineCommentStart = \"*\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mixal_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MixalHighlightRules = function() {\n    var isValidSymbol = function(string) {\n        return string && string.search(/^[A-Z\\u0394\\u03a0\\u03a30-9]{1,10}$/) > -1 && string.search(/[A-Z\\u0394\\u03a0\\u03a3]/) > -1;\n    };\n\n    var isValidOp = function(op) {\n        return op && [\n            'NOP', 'ADD', 'FADD', 'SUB', 'FSUB', 'MUL', 'FMUL', 'DIV', 'FDIV', 'NUM', 'CHAR', 'HLT',\n            'SLA', 'SRA', 'SLAX', 'SRAX', 'SLC', 'SRC', 'MOVE', 'LDA', 'LD1', 'LD2', 'LD3', 'LD4',\n            'LD5', 'LD6', 'LDX', 'LDAN', 'LD1N', 'LD2N', 'LD3N', 'LD4N', 'LD5N', 'LD6N', 'LDXN',\n            'STA', 'ST1', 'ST2', 'ST3', 'ST4', 'ST5', 'ST6', 'STX', 'STJ', 'STZ', 'JBUS', 'IOC',\n            'IN', 'OUT', 'JRED', 'JMP', 'JSJ', 'JOV', 'JNOV', 'JL', 'JE', 'JG', 'JGE', 'JNE', 'JLE',\n            'JAN', 'JAZ', 'JAP', 'JANN', 'JANZ', 'JANP', 'J1N', 'J1Z', 'J1P', 'J1NN', 'J1NZ',\n            'J1NP', 'J2N', 'J2Z', 'J2P', 'J2NN', 'J2NZ', 'J2NP','J3N', 'J3Z', 'J3P', 'J3NN', 'J3NZ',\n            'J3NP', 'J4N', 'J4Z', 'J4P', 'J4NN', 'J4NZ', 'J4NP', 'J5N', 'J5Z', 'J5P', 'J5NN',\n            'J5NZ', 'J5NP','J6N', 'J6Z', 'J6P', 'J6NN', 'J6NZ', 'J6NP', 'JXN', 'JXZ', 'JXP',\n            'JXNN', 'JXNZ', 'JXNP', 'INCA', 'DECA', 'ENTA', 'ENNA', 'INC1', 'DEC1', 'ENT1', 'ENN1',\n            'INC2', 'DEC2', 'ENT2', 'ENN2', 'INC3', 'DEC3', 'ENT3', 'ENN3', 'INC4', 'DEC4', 'ENT4',\n            'ENN4', 'INC5', 'DEC5', 'ENT5', 'ENN5', 'INC6', 'DEC6', 'ENT6', 'ENN6', 'INCX', 'DECX',\n            'ENTX', 'ENNX', 'CMPA', 'FCMP', 'CMP1', 'CMP2', 'CMP3', 'CMP4', 'CMP5', 'CMP6', 'CMPX',\n            'EQU', 'ORIG', 'CON', 'ALF', 'END'\n        ].indexOf(op) > -1;\n    };\n\n    var containsOnlySupportedCharacters = function(string) {\n        return string && string.search(/[^ A-Z\\u0394\\u03a0\\u03a30-9.,()+*/=$<>@;:'-]/) == -1;\n    };\n\n    this.$rules = {\n        \"start\" : [{\n            token: \"comment.line.character\",\n            regex: /^ *\\*.*$/\n        }, {\n            token: function(label, space0, keyword, space1, literal, comment) {\n                return [\n                    isValidSymbol(label) ? \"variable.other\" : \"invalid.illegal\",\n                    \"text\",\n                    \"keyword.control\",\n                    \"text\",\n                    containsOnlySupportedCharacters(literal) ? \"text\" : \"invalid.illegal\",\n                    \"comment.line.character\"\n                ];\n            },\n            regex: /^(\\S+)?( +)(ALF)(  )(.{5})(\\s+.*)?$/\n        }, {\n            token: function(label, space0, keyword, space1, literal, comment) {\n                return [\n                    isValidSymbol(label) ? \"variable.other\" : \"invalid.illegal\",\n                    \"text\",\n                    \"keyword.control\",\n                    \"text\",\n                    containsOnlySupportedCharacters(literal) ? \"text\" : \"invalid.illegal\",\n                    \"comment.line.character\"\n                ];\n            },\n            regex: /^(\\S+)?( +)(ALF)( )(\\S.{4})(\\s+.*)?$/\n        }, {\n            token: function(label, space0, op, comment) {\n                return [\n                    isValidSymbol(label) ? \"variable.other\" : \"invalid.illegal\",\n                    \"text\",\n                    isValidOp(op) ? \"keyword.control\" : \"invalid.illegal\",\n                    \"comment.line.character\"\n                ];\n            },\n            regex: /^(\\S+)?( +)(\\S+)(?:\\s*)$/\n        }, {\n            token: function(label, space0, op, space1, address, comment) {\n                return [\n                    isValidSymbol(label) ? \"variable.other\" : \"invalid.illegal\",\n                    \"text\",\n                    isValidOp(op) ? \"keyword.control\" : \"invalid.illegal\",\n                    \"text\",\n                    containsOnlySupportedCharacters(address) ? \"text\" : \"invalid.illegal\",\n                    \"comment.line.character\"\n                ];\n            },\n            regex: /^(\\S+)?( +)(\\S+)( +)(\\S+)(\\s+.*)?$/\n        }, {\n            defaultToken: \"text\"\n        }]\n    };\n};\n\noop.inherits(MixalHighlightRules, TextHighlightRules);\n\nexports.MixalHighlightRules = MixalHighlightRules;\n"
  },
  {
    "path": "src/mode/mushcode.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar MushCodeRules = require(\"./mushcode_highlight_rules\").MushCodeRules;\nvar PythonFoldMode = require(\"./folding/pythonic\").FoldMode;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = MushCodeRules;\n    this.foldingRules = new PythonFoldMode(\"\\\\:\");\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n   var outdents = {\n        \"pass\": 1,\n        \"return\": 1,\n        \"raise\": 1,\n        \"break\": 1,\n        \"continue\": 1\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (input !== \"\\r\\n\" && input !== \"\\r\" && input !== \"\\n\")\n            return false;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n\n        if (!tokens)\n            return false;\n\n        // ignore trailing comments\n        do {\n            var last = tokens.pop();\n        } while (last && (last.type == \"comment\" || (last.type == \"text\" && last.value.match(/^\\s+$/))));\n\n        if (!last)\n            return false;\n\n        return (last.type == \"keyword\" && outdents[last.value]);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        // outdenting in python is slightly different because it always applies\n        // to the next line and only of a new line is inserted\n\n        row += 1;\n        var indent = this.$getIndent(doc.getLine(row));\n        var tab = doc.getTabString();\n        if (indent.slice(-tab.length) == tab)\n            doc.remove(new Range(row, indent.length-tab.length, row, indent.length));\n    };\n\n    this.$id = \"ace/mode/mushcode\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mushcode_highlight_rules.js",
    "content": "/*\n * MUSHCodeMode\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MushCodeRules = function() {\n\n\n    var keywords = (\n \"@if|\"+\n \"@ifelse|\"+\n \"@switch|\"+\n \"@halt|\"+\n \"@dolist|\"+\n \"@create|\"+\n \"@scent|\"+\n \"@sound|\"+\n \"@touch|\"+\n \"@ataste|\"+\n \"@osound|\"+\n \"@ahear|\"+\n \"@aahear|\"+\n \"@amhear|\"+\n \"@otouch|\"+\n \"@otaste|\"+\n \"@drop|\"+\n \"@odrop|\"+\n \"@adrop|\"+\n \"@dropfail|\"+\n \"@odropfail|\"+\n \"@smell|\"+\n \"@oemit|\"+\n \"@emit|\"+\n \"@pemit|\"+\n \"@parent|\"+\n \"@clone|\"+\n \"@taste|\"+\n \"whisper|\"+\n \"page|\"+\n \"say|\"+\n \"pose|\"+\n \"semipose|\"+\n \"teach|\"+\n \"touch|\"+\n \"taste|\"+\n \"smell|\"+\n \"listen|\"+\n \"look|\"+\n \"move|\"+\n \"go|\"+\n \"home|\"+\n \"follow|\"+\n \"unfollow|\"+\n \"desert|\"+\n \"dismiss|\"+\n \"@tel\"\n    );\n\n    var builtinConstants = (\n        \"=#0\"\n    );\n\n    var builtinFunctions = (\n \"default|\"+\n \"edefault|\"+\n \"eval|\"+\n \"get_eval|\"+\n \"get|\"+\n \"grep|\"+\n \"grepi|\"+\n \"hasattr|\"+\n \"hasattrp|\"+\n \"hasattrval|\"+\n \"hasattrpval|\"+\n \"lattr|\"+\n \"nattr|\"+\n \"poss|\"+\n \"udefault|\"+\n \"ufun|\"+\n \"u|\"+\n \"v|\"+\n \"uldefault|\"+\n \"xget|\"+\n \"zfun|\"+\n \"band|\"+\n \"bnand|\"+\n \"bnot|\"+\n \"bor|\"+\n \"bxor|\"+\n \"shl|\"+\n \"shr|\"+\n \"and|\"+\n \"cand|\"+\n \"cor|\"+\n \"eq|\"+\n \"gt|\"+\n \"gte|\"+\n \"lt|\"+\n \"lte|\"+\n \"nand|\"+\n \"neq|\"+\n \"nor|\"+\n \"not|\"+\n \"or|\"+\n \"t|\"+\n \"xor|\"+\n \"con|\"+\n \"entrances|\"+\n \"exit|\"+\n \"followers|\"+\n \"home|\"+\n \"lcon|\"+\n \"lexits|\"+\n \"loc|\"+\n \"locate|\"+\n \"lparent|\"+\n \"lsearch|\"+\n \"next|\"+\n \"num|\"+\n \"owner|\"+\n \"parent|\"+\n \"pmatch|\"+\n \"rloc|\"+\n \"rnum|\"+\n \"room|\"+\n \"where|\"+\n \"zone|\"+\n \"worn|\"+\n \"held|\"+\n \"carried|\"+\n \"acos|\"+\n \"asin|\"+\n \"atan|\"+\n \"ceil|\"+\n \"cos|\"+\n \"e|\"+\n \"exp|\"+\n \"fdiv|\"+\n \"fmod|\"+\n \"floor|\"+\n \"log|\"+\n \"ln|\"+\n \"pi|\"+\n \"power|\"+\n \"round|\"+\n \"sin|\"+\n \"sqrt|\"+\n \"tan|\"+\n \"aposs|\"+\n \"andflags|\"+\n \"conn|\"+\n \"commandssent|\"+\n \"controls|\"+\n \"doing|\"+\n \"elock|\"+\n \"findable|\"+\n \"flags|\"+\n \"fullname|\"+\n \"hasflag|\"+\n \"haspower|\"+\n \"hastype|\"+\n \"hidden|\"+\n \"idle|\"+\n \"isbaker|\"+\n \"lock|\"+\n \"lstats|\"+\n \"money|\"+\n \"who|\"+\n \"name|\"+\n \"nearby|\"+\n \"obj|\"+\n \"objflags|\"+\n \"photo|\"+\n \"poll|\"+\n \"powers|\"+\n \"pendingtext|\"+\n \"receivedtext|\"+\n \"restarts|\"+\n \"restarttime|\"+\n \"subj|\"+\n \"shortestpath|\"+\n \"tmoney|\"+\n \"type|\"+\n \"visible|\"+\n \"cat|\"+\n \"element|\"+\n \"elements|\"+\n \"extract|\"+\n \"filter|\"+\n \"filterbool|\"+\n \"first|\"+\n \"foreach|\"+\n \"fold|\"+\n \"grab|\"+\n \"graball|\"+\n \"index|\"+\n \"insert|\"+\n \"itemize|\"+\n \"items|\"+\n \"iter|\"+\n \"last|\"+\n \"ldelete|\"+\n \"map|\"+\n \"match|\"+\n \"matchall|\"+\n \"member|\"+\n \"mix|\"+\n \"munge|\"+\n \"pick|\"+\n \"remove|\"+\n \"replace|\"+\n \"rest|\"+\n \"revwords|\"+\n \"setdiff|\"+\n \"setinter|\"+\n \"setunion|\"+\n \"shuffle|\"+\n \"sort|\"+\n \"sortby|\"+\n \"splice|\"+\n \"step|\"+\n \"wordpos|\"+\n \"words|\"+\n \"add|\"+\n \"lmath|\"+\n \"max|\"+\n \"mean|\"+\n \"median|\"+\n \"min|\"+\n \"mul|\"+\n \"percent|\"+\n \"sign|\"+\n \"stddev|\"+\n \"sub|\"+\n \"val|\"+\n \"bound|\"+\n \"abs|\"+\n \"inc|\"+\n \"dec|\"+\n \"dist2d|\"+\n \"dist3d|\"+\n \"div|\"+\n \"floordiv|\"+\n \"mod|\"+\n \"modulo|\"+\n \"remainder|\"+\n \"vadd|\"+\n \"vdim|\"+\n \"vdot|\"+\n \"vmag|\"+\n \"vmax|\"+\n \"vmin|\"+\n \"vmul|\"+\n \"vsub|\"+\n \"vunit|\"+\n \"regedit|\"+\n \"regeditall|\"+\n \"regeditalli|\"+\n \"regediti|\"+\n \"regmatch|\"+\n \"regmatchi|\"+\n \"regrab|\"+\n \"regraball|\"+\n \"regraballi|\"+\n \"regrabi|\"+\n \"regrep|\"+\n \"regrepi|\"+\n \"after|\"+\n \"alphamin|\"+\n \"alphamax|\"+\n \"art|\"+\n \"before|\"+\n \"brackets|\"+\n \"capstr|\"+\n \"case|\"+\n \"caseall|\"+\n \"center|\"+\n \"containsfansi|\"+\n \"comp|\"+\n \"decompose|\"+\n \"decrypt|\"+\n \"delete|\"+\n \"edit|\"+\n \"encrypt|\"+\n \"escape|\"+\n \"if|\"+\n \"ifelse|\"+\n \"lcstr|\"+\n \"left|\"+\n \"lit|\"+\n \"ljust|\"+\n \"merge|\"+\n \"mid|\"+\n \"ostrlen|\"+\n \"pos|\"+\n \"repeat|\"+\n \"reverse|\"+\n \"right|\"+\n \"rjust|\"+\n \"scramble|\"+\n \"secure|\"+\n \"space|\"+\n \"spellnum|\"+\n \"squish|\"+\n \"strcat|\"+\n \"strmatch|\"+\n \"strinsert|\"+\n \"stripansi|\"+\n \"stripfansi|\"+\n \"strlen|\"+\n \"switch|\"+\n \"switchall|\"+\n \"table|\"+\n \"tr|\"+\n \"trim|\"+\n \"ucstr|\"+\n \"unsafe|\"+\n \"wrap|\"+\n \"ctitle|\"+\n \"cwho|\"+\n \"channels|\"+\n \"clock|\"+\n \"cflags|\"+\n \"ilev|\"+\n \"itext|\"+\n \"inum|\"+\n \"convsecs|\"+\n \"convutcsecs|\"+\n \"convtime|\"+\n \"ctime|\"+\n \"etimefmt|\"+\n \"isdaylight|\"+\n \"mtime|\"+\n \"secs|\"+\n \"msecs|\"+\n \"starttime|\"+\n \"time|\"+\n \"timefmt|\"+\n \"timestring|\"+\n \"utctime|\"+\n \"atrlock|\"+\n \"clone|\"+\n \"create|\"+\n \"cook|\"+\n \"dig|\"+\n \"emit|\"+\n \"lemit|\"+\n \"link|\"+\n \"oemit|\"+\n \"open|\"+\n \"pemit|\"+\n \"remit|\"+\n \"set|\"+\n \"tel|\"+\n \"wipe|\"+\n \"zemit|\"+\n \"fbcreate|\"+\n \"fbdestroy|\"+\n \"fbwrite|\"+\n \"fbclear|\"+\n \"fbcopy|\"+\n \"fbcopyto|\"+\n \"fbclip|\"+\n \"fbdump|\"+\n \"fbflush|\"+\n \"fbhset|\"+\n \"fblist|\"+\n \"fbstats|\"+\n \"qentries|\"+\n \"qentry|\"+\n \"play|\"+\n \"ansi|\"+\n \"break|\"+\n \"c|\"+\n \"asc|\"+\n \"die|\"+\n \"isdbref|\"+\n \"isint|\"+\n \"isnum|\"+\n \"isletters|\"+\n \"linecoords|\"+\n \"localize|\"+\n \"lnum|\"+\n \"nameshort|\"+\n \"null|\"+\n \"objeval|\"+\n \"r|\"+\n \"rand|\"+\n \"s|\"+\n \"setq|\"+\n \"setr|\"+\n \"soundex|\"+\n \"soundslike|\"+\n \"valid|\"+\n \"vchart|\"+\n \"vchart2|\"+\n \"vlabel|\"+\n \"@@|\"+\n \"bakerdays|\"+\n \"bodybuild|\"+\n \"box|\"+\n \"capall|\"+\n \"catalog|\"+\n \"children|\"+\n \"ctrailer|\"+\n \"darttime|\"+\n \"debt|\"+\n \"detailbar|\"+\n \"exploredroom|\"+\n \"fansitoansi|\"+\n \"fansitoxansi|\"+\n \"fullbar|\"+\n \"halfbar|\"+\n \"isdarted|\"+\n \"isnewbie|\"+\n \"isword|\"+\n \"lambda|\"+\n \"lobjects|\"+\n \"lplayers|\"+\n \"lthings|\"+\n \"lvexits|\"+\n \"lvobjects|\"+\n \"lvplayers|\"+\n \"lvthings|\"+\n \"newswrap|\"+\n \"numsuffix|\"+\n \"playerson|\"+\n \"playersthisweek|\"+\n \"randomad|\"+\n \"randword|\"+\n \"realrandword|\"+\n \"replacechr|\"+\n \"second|\"+\n \"splitamount|\"+\n \"strlenall|\"+\n \"text|\"+\n \"third|\"+\n \"tofansi|\"+\n \"totalac|\"+\n \"unique|\"+\n \"getaddressroom|\"+\n \"listpropertycomm|\"+\n \"listpropertyres|\"+\n \"lotowner|\"+\n \"lotrating|\"+\n \"lotratingcount|\"+\n \"lotvalue|\"+\n \"boughtproduct|\"+\n \"companyabb|\"+\n \"companyicon|\"+\n \"companylist|\"+\n \"companyname|\"+\n \"companyowners|\"+\n \"companyvalue|\"+\n \"employees|\"+\n \"invested|\"+\n \"productlist|\"+\n \"productname|\"+\n \"productowners|\"+\n \"productrating|\"+\n \"productratingcount|\"+\n \"productsoldat|\"+\n \"producttype|\"+\n \"ratedproduct|\"+\n \"soldproduct|\"+\n \"topproducts|\"+\n \"totalspentonproduct|\"+\n \"totalstock|\"+\n \"transfermoney|\"+\n \"uniquebuyercount|\"+\n \"uniqueproductsbought|\"+\n \"validcompany|\"+\n \"deletepicture|\"+\n \"fbsave|\"+\n \"getpicturesecurity|\"+\n \"haspicture|\"+\n \"listpictures|\"+\n \"picturesize|\"+\n \"replacecolor|\"+\n \"rgbtocolor|\"+\n \"savepicture|\"+\n \"setpicturesecurity|\"+\n \"showpicture|\"+\n \"piechart|\"+\n \"piechartlabel|\"+\n \"createmaze|\"+\n \"drawmaze|\"+\n \"drawwireframe\"\n    );\n    var keywordMapper = this.createKeywordMapper({\n        \"invalid.deprecated\": \"debugger\",\n        \"support.function\": builtinFunctions,\n        \"constant.language\": builtinConstants,\n        \"keyword\": keywords\n    }, \"identifier\");\n\n    var strPre = \"(?:r|u|ur|R|U|UR|Ur|uR)?\";\n\n    var decimalInteger = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    var octInteger = \"(?:0[oO]?[0-7]+)\";\n    var hexInteger = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n    var binInteger = \"(?:0[bB][01]+)\";\n    var integer = \"(?:\" + decimalInteger + \"|\" + octInteger + \"|\" + hexInteger + \"|\" + binInteger + \")\";\n\n    var exponent = \"(?:[eE][+-]?\\\\d+)\";\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var exponentFloat = \"(?:(?:\" + pointFloat + \"|\" +  intPart + \")\" + exponent + \")\";\n    var floatNumber = \"(?:\" + exponentFloat + \"|\" + pointFloat + \")\";\n\n    this.$rules = {\n        \"start\" : [\n         {\n                token : \"variable\", // mush substitution register\n                regex : \"%[0-9]{1}\"\n         },\n         {\n                token : \"variable\", // mush substitution register\n                regex : \"%q[0-9A-Za-z]{1}\"\n         },\n         {\n                token : \"variable\", // mush special character register\n                regex : \"%[a-zA-Z]{1}\"\n         },\n         {\n                token: \"variable.language\",\n                regex: \"%[a-z0-9-_]+\"\n         },\n        {\n            token : \"constant.numeric\", // imaginary\n            regex : \"(?:\" + floatNumber + \"|\\\\d+)[jJ]\\\\b\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : floatNumber\n        }, {\n            token : \"constant.numeric\", // long integer\n            regex : integer + \"[lL]\\\\b\"\n        }, {\n            token : \"constant.numeric\", // integer\n            regex : integer + \"\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|#|%|<<|>>|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\[\\\\(\\\\{]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\]\\\\)\\\\}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n};\n\noop.inherits(MushCodeRules, TextHighlightRules);\n\nexports.MushCodeRules = MushCodeRules;\n"
  },
  {
    "path": "src/mode/mysql.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"../mode/text\").Mode;\nvar MysqlHighlightRules = require(\"./mysql_highlight_rules\").MysqlHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = MysqlHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {       \n    this.lineCommentStart = [\"--\", \"#\"]; // todo space\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/mysql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/mysql_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar MysqlHighlightRules = function() {\n    var mySqlKeywords = /*sql*/ \"alter|and|as|asc|between|count|create|delete|desc|distinct|drop|from|lateral|having|in|insert|into|is|join|like|not|on|or|order|select|set|table|union|intersect|except|update|values|where\"\n        /*mysql*/ + \"|accessible|action|add|after|algorithm|all|analyze|asensitive|at|authors|auto_increment|autocommit|avg|avg_row_length|before|binary|binlog|both|btree|cache|call|cascade|cascaded|case|catalog_name|chain|change|changed|character|check|checkpoint|checksum|class_origin|client_statistics|close|code|collate|collation|collations|column|columns|comment|commit|committed|completion|concurrent|condition|connection|consistent|constraint|contains|continue|contributors|convert|cross|current_date|current_time|current_timestamp|current_user|cursor|data|database|databases|day_hour|day_microsecond|day_minute|day_second|deallocate|dec|declare|default|delay_key_write|delayed|delimiter|des_key_file|describe|deterministic|dev_pop|dev_samp|deviance|directory|disable|discard|distinctrow|div|dual|dumpfile|each|elseif|enable|enclosed|end|ends|engine|engines|enum|errors|escape|escaped|even|event|events|every|execute|exists|exit|explain|extended|fast|fetch|field|fields|first|flush|for|force|foreign|found_rows|full|fulltext|function|general|global|grant|grants|group|by|group_concat|handler|hash|help|high_priority|hosts|hour_microsecond|hour_minute|hour_second|if|ignore|ignore_server_ids|import|index|index_statistics|infile|inner|innodb|inout|insensitive|insert_method|install|interval|invoker|isolation|iterate|key|keys|kill|language|last|leading|leave|left|level|limit|linear|lines|list|load|local|localtime|localtimestamp|lock|logs|low_priority|master|master_heartbeat_period|master_ssl_verify_server_cert|masters|match|max|max_rows|maxvalue|message_text|middleint|migrate|min|min_rows|minute_microsecond|minute_second|mod|mode|modifies|modify|mutex|mysql_errno|natural|next|no|no_write_to_binlog|offline|offset|one|online|open|optimize|option|optionally|out|outer|outfile|pack_keys|parser|partition|partitions|password|phase|plugin|plugins|prepare|preserve|prev|primary|privileges|procedure|processlist|profile|profiles|purge|query|quick|range|read|read_write|reads|real|rebuild|recover|references|regexp|relaylog|release|remove|rename|reorganize|repair|repeatable|replace|require|resignal|restrict|resume|return|returns|revoke|right|rlike|rollback|rollup|row|row_format|rtree|savepoint|schedule|schema|schema_name|schemas|second_microsecond|security|sensitive|separator|serializable|server|session|share|show|signal|slave|slow|smallint|snapshot|soname|spatial|specific|sql|sql_big_result|sql_buffer_result|sql_cache|sql_calc_found_rows|sql_no_cache|sql_small_result|sqlexception|sqlstate|sqlwarning|ssl|start|starting|starts|status|std|stddev|stddev_pop|stddev_samp|storage|straight_join|subclass_origin|sum|suspend|table_name|table_statistics|tables|tablespace|temporary|terminated|to|trailing|transaction|trigger|triggers|truncate|uncommitted|undo|uninstall|unique|unlock|upgrade|usage|use|use_frm|user|user_resources|user_statistics|using|utc_date|utc_time|utc_timestamp|value|variables|varying|view|views|warnings|when|while|with|work|write|xa|xor|year_month|zerofill|begin|do|then|else|loop|repeat\";\n    var builtins = \"rank|coalesce|ifnull|isnull|nvl\";\n    var variable = \"charset|clear|connect|edit|ego|exit|go|help|nopager|notee|nowarning|pager|print|prompt|quit|rehash|source|status|system|tee\";\n    var datetimeFunctions = 'adddate|addtime|convert_tz|curdate|current_date|current_time|current_timestamp|curtime|date|date_add|date_format|date_sub|datediff|day|dayname|dayofmonth|dayofweek|dayofyear|extract|from_days|from_unixtime|get_format|hour|last_day|localtime|localtimestamp|makedate|maketime|microsecond|minute|month|monthname|now|period_add|period_diff|quarter|sec_to_time|second|str_to_date|subdate|subtime|sysdate|time|time_format|time_to_sec|timediff|timestamp|timestampadd|timestampdiff|to_days|to_seconds|unix_timestamp|utc_date|utc_time|utc_timestamp|week|weekday|weekofyear|year|yearweek';\n    var encryptionFunctions = 'aes_decrypt|aes_encrypt|compress|md|random_bytes|sha|sha|statement_digest|statement_digest_text|uncompress|uncompressed_length|validate_password_strength';\n    var mathFunctions = 'abs|acos|asin|atan|atan|ceil|ceiling|conv|cos|cot|crc|degrees|div|exp|floor|ln|log|log10|log2|mod|pi|pow|power|radians|rand|round|sign|sin|sqrt|tan|truncate';\n    var stringFunctions = 'ascii|bin|bit_length|char|char_length|character_length|concat|concat_ws|elt|export_set|field|find_in_set|format|from_base|hex|insert|instr|lcase|left|length|like|load_file|locate|lower|lpad|ltrim|make_set|match|mid|not|not|oct|octet_length|ord|position|quote|regexp|regexp_instr|regexp_like|regexp_replace|regexp_substr|repeat|replace|reverse|right|rlike|rpad|rtrim|soundex|sounds|space|strcmp|substr|substring|substring_index|to_base|trim|ucase|unhex|upper|weight_string';\n    //operatorChars: /^[*+\\-%<>!=&|^]/,\n    var dataTypes = (\n        \"bool|boolean|bit|blob|decimal|double|enum|float|long|longblob|longtext|medium|mediumblob|mediumint|mediumtext|time|timestamp|tinyblob|tinyint|tinytext|text|\" +\n        \"bigint|int|int1|int2|int3|int4|int8|integer|float|float4|float8|double|char|varbinary|varchar|varcharacter|precision|date|datetime|year|unsigned|signed|numeric\"\n    );\n    \n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": [builtins, datetimeFunctions, encryptionFunctions, mathFunctions, stringFunctions].join('|'),\n        \"keyword\": mySqlKeywords,\n        \"storage.type\": dataTypes,\n        \"constant\": \"false|true|null|unknown|ODBCdotTable|zerolessFloat\",\n        \"variable.language\": variable\n    }, \"identifier\", true);\n\n    \n    function string(rule) {\n        var start = rule.start;\n        var escapeSeq = rule.escape;\n        return {\n            token: \"string.start\",\n            regex: start,\n            next: [\n                {token: \"constant.language.escape\", regex: escapeSeq},\n                {token: \"string.end\", next: \"start\", regex: start},\n                {defaultToken: \"string\"}\n            ]\n        };\n    }\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\", regex : \"(?:-- |#).*$\"\n        },  \n        string({start: '\"', escape: /\\\\[0'\"bnrtZ\\\\%_]?/}),\n        string({start: \"'\", escape: /\\\\[0'\"bnrtZ\\\\%_]?/}),\n        DocCommentHighlightRules.getStartRule(\"doc-start\"),\n        {\n            token : \"comment\", // multi line comment\n            regex : /\\/\\*/,\n            next : \"comment\"\n        }, {\n            token : \"constant.numeric\", // hex\n            regex : /0[xX][0-9a-fA-F]+|[xX]'[0-9a-fA-F]+'|0[bB][01]+|[bB]'[01]+'/\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"constant.class\",\n            regex : \"@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"constant.buildin\",\n            regex : \"`[^`]*`\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ],\n        \"comment\" : [\n            {token : \"comment\", regex : \"\\\\*\\\\/\", next : \"start\"},\n            {defaultToken : \"comment\"}\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\", [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.normalizeRules();\n};\n\noop.inherits(MysqlHighlightRules, TextHighlightRules);\n\nexports.MysqlHighlightRules = MysqlHighlightRules;\n"
  },
  {
    "path": "src/mode/nasal.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar NasalHighlightRules = require(\"./nasal_highlight_rules\").NasalHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = NasalHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // this.lineCommentStart = \"\"//\"\";\n    // this.blockComment = {start: \"\"/*\"\", end: \"\"*/\"\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/nasal\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/nasal_highlight_rules.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/* This file was autogenerated from https://github.com/BobDotCom/Nasal.tmbundle/blob/95113f60db7cb7ac7b6c3d854683773879407a48/Syntaxes/Nasal.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar NasalHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"constant.other.allcaps.nasal\",\n            regex: /\\b[[:upper:]_][[:upper:][:digit:]_]*\\b(?![\\.\\(\\'\\\"])/,\n            comment: \"Match identifiers in ALL_CAPS as constants, except when followed by `.`, `(`, `'`, or `\\\"`.\"\n        }, {\n            todo: {\n                token: [\n                    \"support.class.nasal\",\n                    \"meta.function.nasal\",\n                    \"entity.name.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"keyword.operator.nasal\",\n                    \"meta.function.nasal\",\n                    \"storage.type.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"punctuation.definition.parameters.begin.nasal\"\n                ],\n                regex: /([a-zA-Z_?.$][\\w?.$]*)(\\.)([a-zA-Z_?.$][\\w?.$]*)(\\s*)(=)(\\s*)(func)(\\s*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.parameters.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    token: \"variable.parameter.nasal\",\n                    regex: /\\w/\n                }, {\n                    defaultToken: \"meta.function.nasal\"\n                }]\n            },\n            comment: \"match stuff like: Sound.play = func() { … }\"\n        }, {\n            todo: {\n                token: [\n                    \"entity.name.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"keyword.operator.nasal\",\n                    \"meta.function.nasal\",\n                    \"storage.type.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"punctuation.definition.parameters.begin.nasal\"\n                ],\n                regex: /([a-zA-Z_?$][\\w?$]*)(\\s*)(=)(\\s*)(func)(\\s*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.parameters.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    token: \"variable.parameter.nasal\",\n                    regex: /\\w/\n                }, {\n                    defaultToken: \"meta.function.nasal\"\n                }]\n            },\n            comment: \"match stuff like: play = func() { … }\"\n        }, {\n            todo: {\n                token: [\n                    \"entity.name.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"keyword.operator.nasal\",\n                    \"meta.function.nasal\",\n                    \"storage.type.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"punctuation.definition.parameters.begin.nasal\"\n                ],\n                regex: /([a-zA-Z_?$][\\w?$]*)(\\s*)(=)(\\s*\\(\\s*)(func)(\\s*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.parameters.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    token: \"variable.parameter.nasal\",\n                    regex: /\\w/\n                }, {\n                    defaultToken: \"meta.function.nasal\"\n                }]\n            },\n            comment: \"match stuff like: play = (func() { … }\"\n        }, {\n            todo: {\n                token: [\n                    \"entity.name.function.nasal\",\n                    \"meta.function.hash.nasal\",\n                    \"storage.type.function.nasal\",\n                    \"meta.function.hash.nasal\",\n                    \"punctuation.definition.parameters.begin.nasal\"\n                ],\n                regex: /\\b([a-zA-Z_?.$][\\w?.$]*)(\\s*:\\s*\\b)(func)(\\s*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.parameters.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    token: \"variable.parameter.nasal\",\n                    regex: /\\w/\n                }, {\n                    defaultToken: \"meta.function.hash.nasal\"\n                }]\n            },\n            comment: \"match stuff like: foobar: func() { … }\"\n        }, {\n            todo: {\n                token: [\n                    \"storage.type.function.nasal\",\n                    \"meta.function.nasal\",\n                    \"punctuation.definition.parameters.begin.nasal\"\n                ],\n                regex: /\\b(func)(\\s*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.parameters.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    token: \"variable.parameter.nasal\",\n                    regex: /\\w/\n                }, {\n                    defaultToken: \"meta.function.nasal\"\n                }]\n            },\n            comment: \"match stuff like: func() { … }\"\n        }, {\n            token: [\n                \"keyword.operator.new.nasal\",\n                \"meta.class.instance.constructor\",\n                \"entity.name.type.instance.nasal\"\n            ],\n            regex: /(new)(\\s+)(\\w+(?:\\.\\w*)?)/\n        }, {\n            token: \"keyword.control.nasal\",\n            regex: /\\b(?:if|else|elsif|while|for|foreach|forindex)\\b/\n        }, {\n            token: \"keyword.control.nasal\",\n            regex: /\\b(?:break(?:\\s+[A-Z]{2,16})?(?=\\s*(?:;|\\}))|continue(?:\\s+[A-Z]{2,16})?(?=\\s*(?:;|\\}))|[A-Z]{2,16}(?=\\s*;(?:[^\\)#;]*?;){0,2}[^\\)#;]*?\\)))\\b/\n        }, {\n            token: \"keyword.operator.nasal\",\n            regex: /!|\\*|\\-|\\+|~|\\/|==|=|!=|<=|>=|<|>|!|\\?|\\:|\\*=|\\/=|\\+=|\\-=|~=|\\.\\.\\.|\\b(?:and|or)\\b/\n        }, {\n            token: \"variable.language.nasal\",\n            regex: /\\b(?:me|arg|parents|obj)\\b/\n        }, {\n            token: \"storage.type.nasal\",\n            regex: /\\b(?:return|var)\\b/\n        }, {\n            token: \"constant.language.nil.nasal\",\n            regex: /\\bnil\\b/\n        }, {\n            token: \"punctuation.definition.string.begin.nasal\",\n            regex: /'/,\n            push: [{\n                token: \"punctuation.definition.string.end.nasal\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.nasal\",\n                regex: /\\\\'/\n            }, {\n                defaultToken: \"string.quoted.single.nasal\"\n            }],\n            comment: \"Single quoted strings\"\n        }, {\n            token: \"punctuation.definition.string.begin.nasal\",\n            regex: /\"/,\n            push: [{\n                token: \"punctuation.definition.string.end.nasal\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.nasal\",\n                regex: /\\\\(?:x[\\da-fA-F]{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|r|n|t|\\\\|\")/\n            }, {\n                token: \"constant.character.escape.nasal\",\n                regex: /%(?:%|(?:\\d+\\$)?[+-]?(?:[ 0]|'.{1})?-?\\d*(?:\\.\\d+)?[bcdeEufFgGosxX])/\n            }, {\n                defaultToken: \"string.quoted.double.nasal\"\n            }],\n            comment: \"Double quoted strings\"\n        }, {\n            token: [\n                \"punctuation.definition.string.begin.nasal\",\n                \"string.other\",\n                \"punctuation.definition.string.end.nasal\"\n            ],\n            regex: /(`)(.)(`)/,\n            comment: \"Single-byte ASCII character constants\"\n        }, {\n            token: [\n                \"punctuation.definition.comment.nasal\",\n                \"comment.line.hash.nasal\"\n            ],\n            regex: /(#)(.*$)/,\n            comment: \"Comments\"\n        }, {\n            token: \"constant.numeric.nasal\",\n            regex: /(?:(?:\\b[0-9]+)?\\.)?\\b[0-9]+(?:[eE][-+]?[0-9]+)?\\b/,\n            comment: \"Integers, floats, and scientific format\"\n        }, {\n            token: \"constant.numeric.nasal\",\n            regex: /0[x|X][0-9a-fA-F]+/,\n            comment: \"Hex codes\"\n        }, {\n            token: \"punctuation.terminator.statement.nasal\",\n            regex: /\\;/\n        }, {\n            token: [\n                \"punctuation.section.scope.begin.nasal\",\n                \"punctuation.section.scope.end.nasal\"\n            ],\n            regex: /(\\[)(\\])/\n        }, {\n            todo: {\n                token: \"punctuation.section.scope.begin.nasal\",\n                regex: /\\{/,\n                push: [{\n                    token: \"punctuation.section.scope.end.nasal\",\n                    regex: /\\}/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }]\n            }\n        }, {\n            todo: {\n                token: \"punctuation.section.scope.begin.nasal\",\n                regex: /\\(/,\n                push: [{\n                    token: \"punctuation.section.scope.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }]\n            }\n        }, {\n            token: \"invalid.illegal\",\n            regex: /%|\\$|@|&|\\^|\\||\\\\|`/,\n            comment: \"Illegal characters\"\n        }, {\n            todo: {\n                comment: \"TODO: Symbols in hash keys\"\n            },\n            comment: \"TODO: Symbols in hash keys\"\n        }, {\n            token: \"variable.language.nasal\",\n            regex: /\\b(?:append|bind|call|caller|chr|closure|cmp|compile|contains|delete|die|find|ghosttype|id|int|keys|left|num|pop|right|setsize|size|sort|split|sprintf|streq|substr|subvec|typeof|readline)\\b/,\n            comment: \"Core functions\"\n        }, {\n            token: \"variable.language.nasal\",\n            regex: /\\b(?:abort|abs|aircraftToCart|addcommand|airportinfo|airwaysRoute|assert|carttogeod|cmdarg|courseAndDistance|createDiscontinuity|createViaTo|createWP|createWPFrom|defined|directory|fgcommand|findAirportsByICAO|findAirportsWithinRange|findFixesByID|findNavaidByFrequency|findNavaidsByFrequency|findNavaidsByID|findNavaidsWithinRange|finddata|flightplan|geodinfo|geodtocart|get_cart_ground_intersection|getprop|greatCircleMove|interpolate|isa|logprint|magvar|maketimer|start|stop|restart|maketimestamp|md5|navinfo|parse_markdown|parsexml|print|printf|printlog|rand|registerFlightPlanDelegate|removecommand|removelistener|resolvepath|setlistener|_setlistener|setprop|srand|systime|thisfunc|tileIndex|tilePath|values)\\b/,\n            comment: \"FG ext core functions\"\n        }, {\n            token: \"variable.language.nasal\",\n            regex: /\\b(?:singleShot|isRunning|simulatedTime)\\b/,\n            comment: \"FG ext core functions\"\n        }, {\n            token: \"constant.language.nasal\",\n            regex: /\\b(?:D2R|FPS2KT|FT2M|GAL2L|IN2M|KG2LB|KT2FPS|KT2MPS|LG2GAL|LB2KG|M2FT|M2IN|M2NM|MPS2KT|NM2M|R2D)\\b/,\n            comment: \"FG ext core constants\"\n        }, {\n            token: \"support.function.nasal\",\n            regex: /\\b(?:addChild|addChildren|alias|clearValue|equals|getAliasTarget|getAttribute|getBoolValue|getChild|getChildren|getIndex|getName|getNode|getParent|getPath|getType|getValue|getValues|initNode|remove|removeAllChildren|removeChild|removeChildren|setAttribute|setBoolValue|setDoubleValue|setIntValue|setValue|setValues|unalias|compileCondition|condition|copy|dump|getNode|nodeList|runBinding|setAll|wrap|wrapNode)\\b/,\n            comment: \"FG func props\"\n        }, {\n            token: \"support.class.nasal\",\n            regex: /\\bNode\\b/,\n            comment: \"FG node class\"\n        }, {\n            token: \"variable.language.nasal\",\n            regex: /\\b(?:props|globals)\\b/,\n            comment: \"FG func props variables\"\n        }, {\n            todo: {\n                token: [\n                    \"support.function.nasal\",\n                    \"punctuation.definition.arguments.begin.nasal\"\n                ],\n                regex: /\\b([a-zA-Z_?$][\\w?$]*)(\\()/,\n                push: [{\n                    token: \"punctuation.definition.arguments.end.nasal\",\n                    regex: /\\)/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }, {\n                    defaultToken: \"meta.function-call.nasal\"\n                }]\n            },\n            comment: \"function call\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nNasalHighlightRules.metaData = {\n    fileTypes: [\"nas\"],\n    name: \"Nasal\",\n    scopeName: \"source.nasal\"\n};\n\n\noop.inherits(NasalHighlightRules, TextHighlightRules);\n\nexports.NasalHighlightRules = NasalHighlightRules;"
  },
  {
    "path": "src/mode/nginx.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar NginxHighlightRules = require(\"./nginx_highlight_rules\").NginxHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    TextMode.call(this);\n    this.HighlightRules = NginxHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\n\noop.inherits(Mode, TextMode);\n\n\n(function () {\n    this.lineCommentStart = \"#\";\n\n    this.$id = \"ace/mode/nginx\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/nginx_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar NginxHighlightRules = function () {\n    var keywords = \"include|index|absolute_redirect|aio|output_buffers|directio|sendfile|aio_write|alias|root|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|default_type|disable_symlinks|directio_alignment|error_page|etag|if_modified_since|ignore_invalid_headers|internal|keepalive_requests|keepalive_disable|keepalive_timeout|limit_except|large_client_header_buffers|limit_rate|limit_rate_after|lingering_close|lingering_time|lingering_timeout|listen|log_not_found|log_subrequest|max_ranges|merge_slashes|msie_padding|msie_refresh|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|output_buffers|port_in_redirect|postpone_output|read_ahead|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|satisfy|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|subrequest_output_buffer_size|tcp_nodelay|tcp_nopush|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|variables_hash_bucket_size|variables_hash_max_size|accept_mutex|accept_mutex_delay|debug_connection|error_log|daemon|debug_points|env|load_module|lock_file|master_process|multi_accept|pcre_jit|pid|ssl_engine|thread_pool|timer_resolution|use|user|worker_aio_requests|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_shutdown_timeout|working_directory|allow|deny|add_before_body|add_after_body|addition_types|api|status_zone|auth_basic|auth_basic_user_file|auth_jwt|auth_jwt|auth_jwt_claim_set|auth_jwt_header_set|auth_jwt_key_file|auth_jwt_key_request|auth_jwt_leeway|auth_request|auth_request_set|autoindex|autoindex_exact_size|autoindex_format|autoindex_localtime|ancient_browser|ancient_browser_value|modern_browser|modern_browser_value|charset|charset_map|charset_types|override_charset|source_charset|create_full_put_path|dav_access|dav_methods|min_delete_depth|empty_gif|f4f|f4f_buffer_size|fastcgi_bind|fastcgi_buffer_size|fastcgi_buffering|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_background_update|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_age|fastcgi_cache_lock_timeout|fastcgi_cache_max_range_offset|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_revalidate|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_catch_stderr|fastcgi_connect_timeout|fastcgi_force_ranges|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_limit_rate|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_next_upstream_timeout|fastcgi_next_upstream_tries|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_pass_request_body|fastcgi_pass_request_headers|fastcgi_read_timeout|fastcgi_request_buffering|fastcgi_send_lowat|fastcgi_send_timeout|fastcgi_socket_keepalive|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geoip_country|geoip_city|geoip_org|geoip_proxy|geoip_proxy_recursive|grpc_bind|grpc_buffer_size|grpc_connect_timeout|grpc_hide_header|grpc_ignore_headers|grpc_intercept_errors|grpc_next_upstream|grpc_next_upstream_timeout|grpc_next_upstream_tries|grpc_pass|grpc_pass_header|grpc_read_timeout|grpc_send_timeout|grpc_set_header|grpc_socket_keepalive|grpc_ssl_certificate|grpc_ssl_certificate_key|grpc_ssl_ciphers|grpc_ssl_crl|grpc_ssl_name|grpc_ssl_password_file|grpc_ssl_protocols|grpc_ssl_server_name|grpc_ssl_session_reuse|grpc_ssl_trusted_certificate|grpc_ssl_verify|grpc_ssl_verify_depth|gunzip|gunzip_buffers|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_types|gzip_vary|gzip_static|add_header|add_trailer|expires|hlshls_buffers|hls_forward_args|hls_fragment|hls_mp4_buffer_size|hls_mp4_max_buffer_size|image_filter|image_filter_buffer|image_filter_interlace|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|image_filter_webp_quality|js_content|js_include|js_set|keyval|keyval_zone|limit_conn|limit_conn_log_level|limit_conn_status|limit_conn_zone|limit_zone|limit_req|limit_req_log_level|limit_req_status|limit_req_zone|access_log|log_format|open_log_file_cache|map_hash_bucket_size|map_hash_max_size|memcached_bind|memcached_buffer_size|memcached_connect_timeout|memcached_force_ranges|memcached_gzip_flag|memcached_next_upstream|memcached_next_upstream_timeout|memcached_next_upstream_tries|memcached_pass|memcached_read_timeout|memcached_send_timeout|memcached_socket_keepalive|mirror|mirror_request_body|mp4|mp4_buffer_size|mp4_max_buffer_size|mp4_limit_rate|mp4_limit_rate_after|perl_modules|perl_require|perl_set|proxy_bind|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_background_update|proxy_cache_bypass|proxy_cache_convert_head|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_age|proxy_cache_lock_timeout|proxy_cache_max_range_offset|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_purge|proxy_cache_revalidate|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_force_ranges|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_limit_rate|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_next_upstream_timeout|proxy_next_upstream_tries|proxy_no_cache|proxy_pass|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_socket_keepalive|proxy_ssl_certificate|proxy_ssl_certificate_key|proxy_ssl_ciphers|proxy_ssl_crl|proxy_ssl_name|proxy_ssl_password_file|proxy_ssl_protocols|proxy_ssl_server_name|proxy_ssl_session_reuse|proxy_ssl_trusted_certificate|proxy_ssl_verify|proxy_ssl_verify_depth|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|random_index|set_real_ip_from|real_ip_header|real_ip_recursive|referer_hash_bucket_size|referer_hash_max_size|valid_referers|break|return|rewrite_log|set|uninitialized_variable_warn|scgi_bind|scgi_buffer_size|scgi_buffering|scgi_buffers|scgi_busy_buffers_size|scgi_cache|scgi_cache_background_update|scgi_cache_key|scgi_cache_lock|scgi_cache_lock_age|scgi_cache_lock_timeout|scgi_cache_max_range_offset|scgi_cache_methods|scgi_cache_min_uses|scgi_cache_path|scgi_cache_purge|scgi_cache_revalidate|scgi_cache_use_stale|scgi_cache_valid|scgi_connect_timeout|scgi_force_ranges|scgi_hide_header|scgi_ignore_client_abort|scgi_ignore_headers|scgi_intercept_errors|scgi_limit_rate|scgi_max_temp_file_size|scgi_next_upstream|scgi_next_upstream_timeout|scgi_next_upstream_tries|scgi_no_cache|scgi_param|scgi_pass|scgi_pass_header|scgi_pass_request_body|scgi_pass_request_headers|scgi_read_timeout|scgi_request_buffering|scgi_send_timeout|scgi_socket_keepalive|scgi_store|scgi_store_access|scgi_temp_file_write_size|scgi_temp_path|secure_link|secure_link_md5|secure_link_secret|session_log|session_log_format|session_log_zone|slice|spdy_chunk_size|spdy_headers_comp|ssi|ssi_last_modified|ssi_min_file_chunk|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_buffer_size|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_early_data|ssl_ecdh_curve|ssl_password_file|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_ticket_key|ssl_session_tickets|ssl_session_timeout|ssl_stapling|ssl_stapling_file|ssl_stapling_responder|ssl_stapling_verify|ssl_trusted_certificate|ssl_verify_client|ssl_verify_depth|status|status_format|status_zone|stub_status|sub_filter|sub_filter_last_modified|sub_filter_once|sub_filter_types|server|zone|state|hash|ip_hash|keepalive|keepalive_requests|keepalive_timeout|ntlm|least_conn|least_time|queue|random|sticky|sticky_cookie_insert|upstream_conf|health_check|userid|userid_domain|userid_expires|userid_mark|userid_name|userid_p3p|userid_path|userid_service|uwsgi_bind|uwsgi_buffer_size|uwsgi_buffering|uwsgi_buffers|uwsgi_busy_buffers_size|uwsgi_cache|uwsgi_cache_background_update|uwsgi_cache_bypass|uwsgi_cache_key|uwsgi_cache_lock|uwsgi_cache_lock_age|uwsgi_cache_lock_timeout|uwsgi_cache_max_range_offset|uwsgi_cache_methods|uwsgi_cache_min_uses|uwsgi_cache_path|uwsgi_cache_purge|uwsgi_cache_revalidate|uwsgi_cache_use_stale|uwsgi_cache_valid|uwsgi_connect_timeout|uwsgi_force_ranges|uwsgi_hide_header|uwsgi_ignore_client_abort|uwsgi_ignore_headers|uwsgi_intercept_errors|uwsgi_limit_rate|uwsgi_max_temp_file_size|uwsgi_modifier1|uwsgi_modifier2|uwsgi_next_upstream|uwsgi_next_upstream_timeout|uwsgi_next_upstream_tries|uwsgi_no_cache|uwsgi_param|uwsgi_pass|uwsgi_pass_header|uwsgi_pass_request_body|uwsgi_pass_request_headers|uwsgi_read_timeout|uwsgi_request_buffering|uwsgi_send_timeout|uwsgi_socket_keepalive|uwsgi_ssl_certificate|uwsgi_ssl_certificate_key|uwsgi_ssl_ciphers|uwsgi_ssl_crl|uwsgi_ssl_name|uwsgi_ssl_password_file|uwsgi_ssl_protocols|uwsgi_ssl_server_name|uwsgi_ssl_session_reuse|uwsgi_ssl_trusted_certificate|uwsgi_ssl_verify|uwsgi_ssl_verify_depth|uwsgi_store|uwsgi_store_access|uwsgi_temp_file_write_size|uwsgi_temp_path|http2_body_preread_size|http2_chunk_size|http2_idle_timeout|http2_max_concurrent_pushes|http2_max_concurrent_streams|http2_max_field_size|http2_max_header_size|http2_max_requests|http2_push|http2_push_preload|http2_recv_buffer_size|http2_recv_timeout|xml_entities|xslt_last_modified|xslt_param|xslt_string_param|xslt_stylesheet|xslt_types|listen|protocol|resolver|resolver_timeout|timeout|auth_http|auth_http_header|auth_http_pass_client_cert|auth_http_timeout|proxy_buffer|proxy_pass_error_message|proxy_timeout|xclient|starttls|imap_auth|imap_capabilities|imap_client_buffer|pop3_auth|pop3_capabilities|smtp_auth|smtp_capabilities|smtp_client_buffer|smtp_greeting_delay|preread_buffer_size|preread_timeout|proxy_protocol_timeout|js_access|js_filter|js_preread|proxy_download_rate|proxy_requests|proxy_responses|proxy_upload_rate|ssl_handshake_timeout|ssl_preread|health_check_timeout|zone_sync|zone_sync_buffers|zone_sync_connect_retry_interval|zone_sync_connect_timeout|zone_sync_interval|zone_sync_recv_buffer_size|zone_sync_server|zone_sync_ssl|zone_sync_ssl_certificate|zone_sync_ssl_certificate_key|zone_sync_ssl_ciphers|zone_sync_ssl_crl|zone_sync_ssl_name|zone_sync_ssl_password_file|zone_sync_ssl_protocols|zone_sync_ssl_server_name|zone_sync_ssl_trusted_certificate|zone_sync_ssl_verify_depth|zone_sync_timeout|google_perftools_profiles|proxy|perl\";\n\n    this.$rules = {\n        \"start\": [{\n            token: [\"storage.type\", \"text\", \"string.regexp\", \"paren.lparen\"],\n            regex: \"\\\\b(location)(\\\\s+)([\\\\^]?~[\\\\*]?\\\\s+.*?)({)\"\n        }, {\n            token: [\"storage.type\", \"text\", \"text\", \"paren.lparen\"],\n            regex: \"\\\\b(location|match|upstream)(\\\\s+)(.*?)({)\"\n        }, {\n            token: [\"storage.type\", \"text\", \"string\", \"text\", \"variable\", \"text\", \"paren.lparen\"],\n            regex: '\\\\b(split_clients|map)(\\\\s+)(\\\\\".*\\\\\")(\\\\s+)(\\\\$[\\\\w_]+)(\\\\s*)({)'\n        }, {\n            token: [\"storage.type\", \"text\", \"paren.lparen\"],\n            regex: \"\\\\b(http|events|server|mail|stream)(\\\\s*)({)\"\n        }, {\n            token: [\"storage.type\", \"text\", \"variable\", \"text\", \"variable\", \"text\", \"paren.lparen\"],\n            regex: '\\\\b(geo|map)(\\\\s+)(\\\\$[\\\\w_]+)?(\\\\s*)(\\\\$[\\\\w_]+)(\\\\s*)({)'\n        }, {\n            token: \"paren.rparen\",\n            regex: \"(})\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"({)\"\n        }, {\n            token: [\"storage.type\", \"text\", \"paren.lparen\"],\n            regex: \"\\\\b(if)(\\\\s+)(\\\\()\",\n            push: [{\n                token: \"paren.rparen\",\n                regex: \"\\\\)|$\",\n                next: \"pop\"\n            }, {\n                include: \"lexical\"\n            }]\n        }, {\n            token: \"keyword\",\n            regex: \"\\\\b(\" + keywords + \")\\\\b\",\n            push: [{\n                token: \"punctuation\",\n                regex: \";\",\n                next: \"pop\"\n            }, {\n                include: \"lexical\"\n            }]\n        }, {\n            token: [\"keyword\", \"text\", \"string.regexp\", \"text\", \"punctuation\"],\n            regex: \"\\\\b(rewrite)(\\\\s)(\\\\S*)(\\\\s.*)(;)\"\n        }, {\n            include: \"lexical\"\n        }, {\n            include: \"comments\"\n        }],\n        comments: [{\n            token: \"comment\",\n            regex: '#.*$'\n        }],\n        lexical: [{\n            token: \"string\",\n            regex: \"'\",\n            push: [{\n                token: \"string\",\n                regex: \"'\",\n                next: \"pop\"\n            }, {\n                include: \"variables\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: '\"',\n            push: [{\n                token: \"string\",\n                regex: '\"',\n                next: \"pop\"\n            }, {\n                include: \"variables\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string.regexp\",\n            regex: /[!]?[~][*]?\\s+.*(?=\\))/\n        }, {\n            token: \"string.regexp\",\n            regex: /[\\^]\\S*(?=;$)/\n        }, {\n            token: \"string.regexp\",\n            regex: /[\\^]\\S*(?=;|\\s|$)/\n        }, {\n            token: \"keyword.operator\",\n            regex: \"\\\\B(\\\\+|\\\\-|\\\\*|\\\\=|!=)\\\\B\"\n        }, {\n            token: \"constant.language\",\n            regex: \"\\\\b(true|false|on|off|all|any|main|always)\\\\b\"\n        }, {\n            token: \"text\",\n            regex: \"\\\\s+\"\n        }, {\n            include: \"variables\"\n        }\n        ],\n        variables: [{\n            token: \"variable\",\n            regex: \"\\\\$[\\\\w_]+\"\n        }, {\n            token: \"variable.language\",\n            regex: \"\\\\b(GET|POST|HEAD)\\\\b\"\n        }]\n    };\n    this.normalizeRules();\n};\n\n\noop.inherits(NginxHighlightRules, TextHighlightRules);\n\nexports.NginxHighlightRules = NginxHighlightRules;\n"
  },
  {
    "path": "src/mode/nim.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar NimHighlightRules = require(\"./nim_highlight_rules\").NimHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    TextMode.call(this);\n    this.HighlightRules = NimHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\n\noop.inherits(Mode, TextMode);\n\n\n(function () {\n    this.lineCommentStart = \"#\";\n    this.blockComment = {start: \"#[\", end: \"]#\", nestable: true};\n\n\n    this.$id = \"ace/mode/nim\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/nim_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar NimHighlightRules = function () {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable\": \"var|let|const\",\n        \"keyword\": \"assert|parallel|spawn|export|include|from|template|mixin|bind|import|concept|raise|defer|try|finally|except|converter|proc|func|macro|method|and|or|not|xor|shl|shr|div|mod|in|notin|is|isnot|of|static|if|elif|else|case|of|discard|when|return|yield|block|break|while|echo|continue|asm|using|cast|addr|unsafeAddr|type|ref|ptr|do|declared|defined|definedInScope|compiles|sizeOf|is|shallowCopy|getAst|astToStr|spawn|procCall|for|iterator|as\",\n        \"storage.type\": \"newSeq|int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|char|bool|string|set|pointer|float32|float64|enum|object|cstring|array|seq|openArray|varargs|UncheckedArray|tuple|set|distinct|void|auto|openarray|range\",\n        \"support.function\": \"lock|ze|toU8|toU16|toU32|ord|low|len|high|add|pop|contains|card|incl|excl|dealloc|inc\",\n        \"constant.language\": \"nil|true|false\"\n    }, \"identifier\");\n\n    var hexNumber = \"(?:0[xX][\\\\dA-Fa-f][\\\\dA-Fa-f_]*)\";\n    var decNumber = \"(?:[0-9][\\\\d_]*)\";\n    var octNumber = \"(?:0o[0-7][0-7_]*)\";\n    var binNumber = \"(?:0[bB][01][01_]*)\";\n    var intNumber = \"(?:\" + hexNumber + \"|\" + decNumber + \"|\" + octNumber + \"|\" + binNumber + \")(?:'?[iIuU](?:8|16|32|64)|u)?\\\\b\";\n    var exponent = \"(?:[eE][+-]?[\\\\d][\\\\d_]*)\";\n    var floatNumber = \"(?:[\\\\d][\\\\d_]*(?:[.][\\\\d](?:[\\\\d_]*)\" + exponent + \"?)|\" + exponent + \")\";\n    var floatNumberExt = \"(?:\" + hexNumber + \"(?:'(?:(?:[fF](?:32|64)?)|[dD])))|(?:\" + floatNumber + \"|\" + decNumber + \"|\" + octNumber + \"|\" + binNumber + \")(?:'(?:(?:[fF](?:32|64)?)|[dD]))\";\n    var stringEscape = \"\\\\\\\\([abeprcnlftv\\\\\\\"']|x[0-9A-Fa-f]{2}|[0-2][0-9]{2}|u[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";\n    var identifier = '[a-zA-Z][a-zA-Z0-9_]*';\n    this.$rules = {\n        \"start\": [{\n            token: [\"identifier\", \"keyword.operator\", \"support.function\"],\n            regex: \"(\" + identifier + \")([.]{1})(\" + identifier + \")(?=\\\\()\"\n        }, {//pragmas\n            token: \"paren.lparen\",\n            regex: \"(\\\\{\\\\.)\",\n            next: [{\n                token: \"paren.rparen\",\n                regex: '(\\\\.\\\\}|\\\\})',\n                next: \"start\"\n            }, {\n                include: \"methods\"\n            }, {\n                token: \"identifier\",\n                regex: identifier\n            }, {\n                token: \"punctuation\",\n                regex: /[,]/\n            }, {\n                token: \"keyword.operator\",\n                regex: /[=:.]/\n            }, {\n                token: \"paren.lparen\",\n                regex: /[[(]/\n            }, {\n                token: \"paren.rparen\",\n                regex: /[\\])]/\n            }, {\n                include: \"math\"\n            }, {\n                include: \"strings\"\n            }, {\n                defaultToken: \"text\"\n            }]\n        }, {\n            token: \"comment.doc.start\",\n            regex: /##\\[(?!])/,\n            push: \"docBlockComment\"\n        }, {\n            token: \"comment.start\",\n            regex: /#\\[(?!])/,\n            push: \"blockComment\"\n        }, {\n            token: \"comment.doc\",\n            regex: '##.*$'\n        }, {\n            token: \"comment\",\n            regex: '#.*$'\n        }, {\n            include: \"strings\"\n        }, {// character\n            token: \"string\",\n            regex: \"'(?:\\\\\\\\(?:[abercnlftv]|x[0-9A-Fa-f]{2}|[0-2][0-9]{2}|u[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})|.{1})?'\"\n        }, {\n            include: \"methods\"\n        }, {\n            token: keywordMapper,\n            regex: \"[a-zA-Z][a-zA-Z0-9_]*\\\\b\"\n        }, {\n            token: [\"keyword.operator\", \"text\", \"storage.type\"],\n            regex: \"([:])(\\\\s+)(\" + identifier + \")(?=$|\\\\)|\\\\[|,|\\\\s+=|;|\\\\s+\\\\{)\"\n        }, {\n            token: \"paren.lparen\",\n            regex: /\\[\\.|{\\||\\(\\.|\\[:|[[({`]/\n        }, {\n            token: \"paren.rparen\",\n            regex: /\\.\\)|\\|}|\\.]|[\\])}]/\n        }, {\n            token: \"keyword.operator\",\n            regex: /[=+\\-*\\/<>@$~&%|!?^.:\\\\]/\n        }, {\n            token: \"punctuation\",\n            regex: /[,;]/\n        }, {\n            include: \"math\"\n        }],\n        blockComment: [{\n            regex: /#\\[]/,\n            token: \"comment\"\n        }, {\n            regex: /#\\[(?!])/,\n            token: \"comment.start\",\n            push: \"blockComment\"\n        }, {\n            regex: /]#/,\n            token: \"comment.end\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }],\n        docBlockComment: [{\n            regex: /##\\[]/,\n            token: \"comment.doc\"\n        }, {\n            regex: /##\\[(?!])/,\n            token: \"comment.doc.start\",\n            push: \"docBlockComment\"\n        }, {\n            regex: /]##/,\n            token: \"comment.doc.end\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment.doc\"\n        }],\n        math: [{\n            token: \"constant.float\",\n            regex: floatNumberExt\n        }, {\n            token: \"constant.float\",\n            regex: floatNumber\n        }, {\n            token: \"constant.integer\",\n            regex: intNumber\n        }],\n        methods: [{\n            token: \"support.function\",\n            regex: \"(\\\\w+)(?=\\\\()\"\n        }],\n        strings: [{\n            token: \"string\",\n            regex: '(\\\\b' + identifier + ')?\"\"\"',\n            push: [{\n                token: \"string\",\n                regex: '\"\"\"',\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: \"\\\\b\" + identifier + '\"(?=.)',\n            push: [{\n                token: \"string\",\n                regex: '\"|$',\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token: \"string\",\n            regex: '\"',\n            push: [{\n                token: \"string\",\n                regex: '\"|$',\n                next: \"pop\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: stringEscape\n            }, {\n                defaultToken: \"string\"\n            }]\n        }]\n    };\n    this.normalizeRules();\n};\n\n\noop.inherits(NimHighlightRules, TextHighlightRules);\n\nexports.NimHighlightRules = NimHighlightRules;\n"
  },
  {
    "path": "src/mode/nix.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar CMode = require(\"./c_cpp\").Mode;\nvar NixHighlightRules = require(\"./nix_highlight_rules\").NixHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    CMode.call(this);\n    this.HighlightRules = NixHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, CMode);\n\n(function() { \n    this.lineCommentStart = \"#\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/nix\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/nix_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var NixHighlightRules = function() {\n\n        var constantLanguage = \"true|false\";\n        var keywordControl = \"with|import|if|else|then|inherit\";\n        var keywordDeclaration = \"let|in|rec\";\n\n        var keywordMapper = this.createKeywordMapper({\n            \"constant.language.nix\": constantLanguage,\n            \"keyword.control.nix\": keywordControl,\n            \"keyword.declaration.nix\": keywordDeclaration\n        }, \"identifier\");\n\n        this.$rules = {\n            \"start\": [{\n                    token: \"comment\",\n                    regex: /#.*$/\n                }, {\n                    token: \"comment\",\n                    regex: /\\/\\*/,\n                    next: \"comment\"\n                }, {\n                    token: \"constant\",\n                    regex: \"<[^>]+>\"\n                }, {\n                    regex: \"(==|!=|<=?|>=?)\",\n                    token: [\"keyword.operator.comparison.nix\"]\n                }, {\n                    regex: \"((?:[+*/%-]|\\\\~)=)\",\n                    token: [\"keyword.operator.assignment.arithmetic.nix\"]\n                }, {\n                    regex: \"=\",\n                    token: \"keyword.operator.assignment.nix\"\n                }, {\n                    token: \"string\",\n                    regex: \"''\",\n                    next: \"qqdoc\"\n                }, {\n                    token: \"string\",\n                    regex: \"'\",\n                    next: \"qstring\"\n                }, {\n                    token: \"string\",\n                    regex: '\"',\n                    push: \"qqstring\"\n                }, {\n                    token: \"constant.numeric\", // hex\n                    regex: \"0[xX][0-9a-fA-F]+\\\\b\"\n                }, {\n                    token: \"constant.numeric\", // float\n                    regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n                }, {\n                    token: keywordMapper,\n                    regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                }, {\n                    regex: \"}\",\n                    token: function(val, start, stack) {\n                        return stack[1] && stack[1].charAt(0) == \"q\" ? \"constant.language.escape\" : \"text\";\n                    },\n                    next: \"pop\"\n                }],\n            \"comment\": [{\n                token: \"comment\", // closing comment\n                regex: \"\\\\*\\\\/\",\n                next: \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }],\n            \"qqdoc\": [\n                {\n                    token: \"constant.language.escape\",\n                    regex: /\\$\\{/,\n                    push: \"start\"\n                }, {\n                    token: \"string\",\n                    regex: \"''\",\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }],\n            \"qqstring\": [\n                {\n                    token: \"constant.language.escape\",\n                    regex: /\\$\\{/,\n                    push: \"start\"\n                }, {\n                    token: \"string\",\n                    regex: '\"',\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }],\n            \"qstring\": [\n                {\n                    token: \"constant.language.escape\",\n                    regex: /\\$\\{/,\n                    push: \"start\"\n                }, {\n                    token: \"string\",\n                    regex: \"'\",\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n        };\n\n        this.normalizeRules();\n    };\n\n    oop.inherits(NixHighlightRules, TextHighlightRules);\n\n    exports.NixHighlightRules = NixHighlightRules;\n"
  },
  {
    "path": "src/mode/nsis.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar NSISHighlightRules = require(\"./nsis_highlight_rules\").NSISHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = NSISHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = [\";\", \"#\"];\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/nsis\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/nsis_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar NSISHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"keyword.compiler.nsis\",\n            regex: /^\\s*!(?:include|addincludedir|addplugindir|appendfile|assert|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|gettlbversion|system|tempfile|warning|verbose|define|undef|insertmacro|macro|macroend|makensis|searchparse|searchreplace|uninstfinalize)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"keyword.command.nsis\",\n            regex: /^\\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetKnownFolderPath|GetLabelAddress|GetTempFileName|GetWinVer|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfRtlLanguage|IfShellVarContextAll|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"keyword.control.nsis\",\n            regex: /^\\s*!(?:ifdef|ifndef|if|ifmacrodef|ifmacrondef|else|endif)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"keyword.plugin.nsis\",\n            regex: /^\\s*\\w+::\\w+/,\n            caseInsensitive: true\n        }, {\n            token: \"keyword.operator.comparison.nsis\",\n            regex: /[!<>]?=|<>|<|>/\n        }, {\n            token: \"support.function.nsis\",\n            regex: /(?:\\b|^\\s*)(?:Function|FunctionEnd|Section|SectionEnd|SectionGroup|SectionGroupEnd|PageEx|PageExEnd)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"support.library.nsis\",\n            regex: /\\${[\\w\\.:-]+}/\n        }, {\n            token: \"constant.nsis\",\n            regex: /\\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR(32|64)?|HKCU(32|64)?|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM(32|64)?|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"constant.library.nsis\",\n            regex: /\\${(?:AtLeastServicePack|AtLeastWin7|AtLeastWin8|AtLeastWin10|AtLeastWin95|AtLeastWin98|AtLeastWin2000|AtLeastWin2003|AtLeastWin2008|AtLeastWin2008R2|AtLeastWinME|AtLeastWinNT4|AtLeastWinVista|AtLeastWinXP|AtMostServicePack|AtMostWin7|AtMostWin8|AtMostWin10|AtMostWin95|AtMostWin98|AtMostWin2000|AtMostWin2003|AtMostWin2008|AtMostWin2008R2|AtMostWinME|AtMostWinNT4|AtMostWinVista|AtMostWinXP|IsDomainController|IsNT|IsServer|IsServicePack|IsWin7|IsWin8|IsWin10|IsWin95|IsWin98|IsWin2000|IsWin2003|IsWin2008|IsWin2008R2|IsWinME|IsWinNT4|IsWinVista|IsWinXP)}/\n        }, {\n            token: \"constant.language.boolean.true.nsis\",\n            regex: /\\b(?:true|on)\\b/\n        }, {\n            token: \"constant.language.boolean.false.nsis\",\n            regex: /\\b(?:false|off)\\b/\n        }, {\n            token: \"constant.language.option.nsis\",\n            regex: /(?:\\b|^\\s*)(?:(?:un\\.)?components|(?:un\\.)?custom|(?:un\\.)?directory|(?:un\\.)?instfiles|(?:un\\.)?license|uninstConfirm|admin|all|amd64-unicode|auto|both|bottom|bzip2|current|force|hide|highest|ifdiff|ifnewer|lastused|leave|left|listonly|lzma|nevershow|none|normal|notset|right|show|silent|silentlog|textonly|top|try|user|Win10|Win7|Win8|WinVista|x86-(ansi|unicode)|zlib)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"constant.language.slash-option.nsis\",\n            regex: /\\b\\/(?:a|BRANDING|CENTER|COMPONENTSONLYONCUSTOM|CUSTOMSTRING=|date|e|ENABLECANCEL|FILESONLY|file|FINAL|GLOBAL|gray|ifempty|ifndef|ignorecase|IMGID=|ITALIC|LANG=|NOCUSTOM|noerrors|NONFATAL|nonfatal|oname=|o|REBOOTOK|redef|RESIZETOFIT|r|SHORT|SILENT|SOLID|STRIKE|TRIM|UNDERLINE|utcdate|windows|x)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"constant.numeric.nsis\",\n            regex: /\\b(?:0(?:x|X)[0-9a-fA-F]+|[0-9]+(?:\\.[0-9]+)?)\\b/\n        }, {\n            token: \"entity.name.function.nsis\",\n            regex: /\\$\\([\\w\\.:-]+\\)/\n        }, {\n            token: \"storage.type.function.nsis\",\n            regex: /\\$\\w+/\n        }, {\n            token: \"punctuation.definition.string.begin.nsis\",\n            regex: /`/,\n            push: [{\n                token: \"punctuation.definition.string.end.nsis\",\n                regex: /`/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.nsis\",\n                regex: /\\$\\\\./\n            }, {\n                defaultToken: \"string.quoted.back.nsis\"\n            }]\n        }, {\n            token: \"punctuation.definition.string.begin.nsis\",\n            regex: /\"/,\n            push: [{\n                token: \"punctuation.definition.string.end.nsis\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.nsis\",\n                regex: /\\$\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.nsis\"\n            }]\n        }, {\n            token: \"punctuation.definition.string.begin.nsis\",\n            regex: /'/,\n            push: [{\n                token: \"punctuation.definition.string.end.nsis\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.nsis\",\n                regex: /\\$\\\\./\n            }, {\n                defaultToken: \"string.quoted.single.nsis\"\n            }]\n        }, {\n            token: [\n                \"punctuation.definition.comment.nsis\",\n                \"comment.line.nsis\"\n            ],\n            regex: /(;|#)(.*$)/\n        }, {\n            token: \"punctuation.definition.comment.nsis\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"punctuation.definition.comment.nsis\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.nsis\"\n            }]\n        }, {\n            token: \"text\",\n            regex: /(?:!include|!insertmacro)\\b/\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nNSISHighlightRules.metaData = {\n    comment: \"\\n\\ttodo: - highlight functions\\n\\t\",\n    fileTypes: [\"nsi\", \"nsh\"],\n    name: \"NSIS\",\n    scopeName: \"source.nsis\"\n};\n\n\noop.inherits(NSISHighlightRules, TextHighlightRules);\n\nexports.NSISHighlightRules = NSISHighlightRules;\n"
  },
  {
    "path": "src/mode/nunjucks.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar NunjucksFoldMode = require(\"./folding/nunjucks\").FoldMode;\nvar lang = require(\"../lib/lang\");\nvar HtmlMode = require(\"./html\").Mode;\nvar NunjucksHighlightRules = require(\"./nunjucks_highlight_rules\").NunjucksHighlightRules;\n\n// http://www.w3.org/TR/html5/syntax.html#void-elements\nvar voidElements = [\n    \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"menuitem\", \"param\", \"source\",\n    \"track\", \"wbr\"\n];\nvar optionalEndTags = [\"li\", \"dt\", \"dd\", \"p\", \"rt\", \"rp\", \"optgroup\", \"option\", \"colgroup\", \"td\", \"th\"];\n\nvar Mode = function () {\n    this.HighlightRules = NunjucksHighlightRules;\n    this.foldingRules = new NunjucksFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags));\n};\n\noop.inherits(Mode, HtmlMode);\n\n(function () {\n    this.$id = \"ace/mode/nunjucks\";\n    this.voidElements = lang.arrayToMap(voidElements);\n\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/nunjucks_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar NunjucksHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    this.$rules[\"start\"].unshift({\n        token: \"punctuation.begin\",\n        regex: /{{-?/,\n        push: [{\n            token: \"punctuation.end\",\n            regex: /-?}}/,\n            next: \"pop\"\n        },\n            {include: \"expression\"}\n        ]\n    }, {\n        token: \"punctuation.begin\",\n        regex: /{%-?/,\n        push: [{\n            token: \"punctuation.end\",\n            regex: /-?%}/,\n            next: \"pop\"\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\b(r\\/.*\\/[gimy]?)\\b/\n        },\n            {include: \"statement\"}\n        ]\n    }, {\n        token: \"comment.begin\",\n        regex: /{#/,\n        push: [{\n            token: \"comment.end\",\n            regex: /#}/,\n            next: \"pop\"\n        },\n            {defaultToken: \"comment\"}\n        ]\n    });\n    this.addRules({\n        attribute_value: [{\n            token: \"string.attribute-value.xml\",\n            regex: \"'\",\n            push: [\n                {token: \"string.attribute-value.xml\", regex: \"'\", next: \"pop\"},\n                {\n                    token: \"punctuation.begin\",\n                    regex: /{{-?/,\n                    push: [{\n                        token: \"punctuation.end\",\n                        regex: /-?}}/,\n                        next: \"pop\"\n                    },\n                        {include: \"expression\"}\n                    ]\n                },\n                {include: \"attr_reference\"},\n                {defaultToken: \"string.attribute-value.xml\"}\n            ]\n        }, {\n            token: \"string.attribute-value.xml\",\n            regex: '\"',\n            push: [\n                {token: \"string.attribute-value.xml\", regex: '\"', next: \"pop\"},\n                {\n                    token: \"punctuation.begin\",\n                    regex: /{{-?/,\n                    push: [{\n                        token: \"punctuation.end\",\n                        regex: /-?}}/,\n                        next: \"pop\"\n                    },\n                        {include: \"expression\"}\n                    ]\n                },\n                {include: \"attr_reference\"},\n                {defaultToken: \"string.attribute-value.xml\"}\n            ]\n        }],\n        \"statement\": [{\n            token: \"keyword.control\",\n            regex: /\\b(block|endblock|extends|endif|elif|for|endfor|asyncEach|endeach|include|asyncAll|endall|macro|endmacro|set|endset|ignore missing|as|from|raw|verbatim|filter|endfilter)\\b/\n        },\n            {include: \"expression\"}\n        ],\n        \"expression\": [{\n            token: \"constant.language\",\n            regex: /\\b(true|false|none)\\b/\n        }, {\n            token: \"string\",\n            regex: /\"/,\n            push: [{\n                token: \"string\",\n                regex: /\"/,\n                next: \"pop\"\n            },\n                {include: \"escapeStrings\"},\n                {defaultToken: \"string\"}\n            ]\n        }, {\n            token: \"string\",\n            regex: /'/,\n            push: [{\n                token: \"string\",\n                regex: /'/,\n                next: \"pop\"\n            },\n                {include: \"escapeStrings\"},\n                {defaultToken: \"string\"}\n            ]\n        }, {\n            token: \"constant.numeric\", // hexadecimal, octal and binary\n            regex: /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\\b/\n        }, {\n            token: \"constant.numeric\", // decimal integers and floats\n            regex: /(?:\\d\\d*(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+\\b)?/\n        }, {\n            token: \"keyword.operator\",\n            regex: /\\+|-|\\/\\/|\\/|%|\\*\\*|\\*|===|==|!==|!=|>=|>|<=|</\n        }, {\n            token: \"keyword.control\",\n            regex: /\\b(and|else|if|in|import|not|or)\\b/\n        }, {\n            token: \"support.function\",\n            regex: /[a-zA-Z_]+(?=\\()/\n        }, {\n            token: \"paren.lpar\",\n            regex: /[(\\[{]/\n        }, {\n            token: \"paren.rpar\",\n            regex: /[)\\]}]/\n        }, {\n            token: \"punctuation\",\n            regex: /[,]/\n        }, {\n            token: [\"punctuation\", \"support.function\"],\n            regex: /(\\.)([a-zA-Z_][a-zA-Z0-9_]*)(?=\\()/\n        }, {\n            token: [\"punctuation\", \"variable.parameter\"],\n            regex: /(\\.)([a-zA-Z_][a-zA-Z0-9_]*)/\n        }, {\n            token: [\"punctuation\", \"text\", \"support.other\"],\n            regex: /(\\|)(\\s)*([a-zA-Z_][a-zA-Z0-9_]*)/\n        }, {\n            token: \"variable\",\n            regex: /[a-zA-Z_][a-zA-Z0-9_]*/\n        }\n        ],\n        \"escapeStrings\": [{\n            token: \"constant.language.escape\",\n            regex: /(\\\\\\\\n)|(\\\\\\\\)|(\\\\\")|(\\\\')|(\\\\a)|(\\\\b)|(\\\\f)|(\\\\n)|(\\\\r)|(\\\\t)|(\\\\v)/\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\\\(?:x[0-9A-F]{2}|(?:U[0-9A-Fa-f]{8})|(?:u[0-9A-Fa-f]{4})|(?:N{[a-zA-Z ]+}))/\n        }]\n    });\n\n    this.normalizeRules();\n};\n\noop.inherits(NunjucksHighlightRules, TextHighlightRules);\n\nexports.NunjucksHighlightRules = NunjucksHighlightRules;\n"
  },
  {
    "path": "src/mode/objectivec.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ObjectiveCHighlightRules = require(\"./objectivec_highlight_rules\").ObjectiveCHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ObjectiveCHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/objectivec\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/objectivec_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar CHighlightRules = require(\"./c_cpp_highlight_rules\").c_cppHighlightRules;\n\nvar ObjectiveCHighlightRules = function() {\n    var NSKeywords = {\n        \"support.function.cocoa.leopard\": \"NSRectToCGRect|NSRectFromCGRect|NSMakeCollectable|NSStringFromProtocol|NSSizeToCGSize|NSSizeFromCGSize|NSDrawNinePartImage|NSDrawThreePartImage|NSPointToCGPoint|NSPointFromCGPoint|NSProtocolFromString|NSEventMaskFromType|NSValue\",\n        \"support.function.cocoa\": \"NSRoundDownToMultipleOfPageSize|NSRoundUpToMultipleOfPageSize|NSRunCriticalAlertPanel|NSRunCriticalAlertPanelRelativeToWindow|NSRunInformationalAlertPanel|NSRunInformationalAlertPanelRelativeToWindow|NSRunAlertPanel|NSRunAlertPanelRelativeToWindow|NSResetMapTable|NSResetHashTable|NSRecycleZone|NSRectClip|NSRectClipList|NSRectFill|NSRectFillUsingOperation|NSRectFillList|NSRectFillListUsingOperation|NSRectFillListWithGrays|NSRectFillListWithColors|NSRectFillListWithColorsUsingOperation|NSRectFromString|NSRecordAllocationEvent|NSReturnAddress|NSReleaseAlertPanel|NSReadPixel|NSRealMemoryAvailable|NSReallocateCollectable|NSRegisterServicesProvider|NSRangeFromString|NSGetSizeAndAlignment|NSGetCriticalAlertPanel|NSGetInformationalAlertPanel|NSGetUncaughtExceptionHandler|NSGetFileType|NSGetFileTypes|NSGetWindowServerMemory|NSGetAlertPanel|NSMinX|NSMinY|NSMidX|NSMidY|NSMouseInRect|NSMapRemove|NSMapGet|NSMapMember|NSMapInsert|NSMapInsertIfAbsent|NSMapInsertKnownAbsent|NSMakeRect|NSMakeRange|NSMakeSize|NSMakePoint|NSMaxRange|NSMaxX|NSMaxY|NSBitsPerSampleFromDepth|NSBitsPerPixelFromDepth|NSBestDepth|NSBeep|NSBeginCriticalAlertSheet|NSBeginInformationalAlertSheet|NSBeginAlertSheet|NSShouldRetainWithZone|NSShowsServicesMenuItem|NSShowAnimationEffect|NSStringFromRect|NSStringFromRange|NSStringFromMapTable|NSStringFromSize|NSStringFromSelector|NSStringFromHashTable|NSStringFromClass|NSStringFromPoint|NSSizeFromString|NSSetShowsServicesMenuItem|NSSetZoneName|NSSetUncaughtExceptionHandler|NSSetFocusRingStyle|NSSelectorFromString|NSSearchPathForDirectoriesInDomains|NSSwapBigShortToHost|NSSwapBigIntToHost|NSSwapBigDoubleToHost|NSSwapBigFloatToHost|NSSwapBigLongToHost|NSSwapBigLongLongToHost|NSSwapShort|NSSwapHostShortToBig|NSSwapHostShortToLittle|NSSwapHostIntToBig|NSSwapHostIntToLittle|NSSwapHostDoubleToBig|NSSwapHostDoubleToLittle|NSSwapHostFloatToBig|NSSwapHostFloatToLittle|NSSwapHostLongToBig|NSSwapHostLongToLittle|NSSwapHostLongLongToBig|NSSwapHostLongLongToLittle|NSSwapInt|NSSwapDouble|NSSwapFloat|NSSwapLittleShortToHost|NSSwapLittleIntToHost|NSSwapLittleDoubleToHost|NSSwapLittleFloatToHost|NSSwapLittleLongToHost|NSSwapLittleLongLongToHost|NSSwapLong|NSSwapLongLong|NSHighlightRect|NSHostByteOrder|NSHomeDirectory|NSHomeDirectoryForUser|NSHeight|NSHashRemove|NSHashGet|NSHashInsert|NSHashInsertIfAbsent|NSHashInsertKnownAbsent|NSHFSTypeCodeFromFileType|NSHFSTypeOfFile|NSNumberOfColorComponents|NSNextMapEnumeratorPair|NSNextHashEnumeratorItem|NSContainsRect|NSConvertGlyphsToPackedGlyphs|NSConvertSwappedDoubleToHost|NSConvertSwappedFloatToHost|NSConvertHostDoubleToSwapped|NSConvertHostFloatToSwapped|NSCountMapTable|NSCountHashTable|NSCountFrames|NSCountWindows|NSCountWindowsForContext|NSCopyMemoryPages|NSCopyMapTableWithZone|NSCopyBits|NSCopyHashTableWithZone|NSCopyObject|NSColorSpaceFromDepth|NSCompareMapTables|NSCompareHashTables|NSClassFromString|NSCreateMapTable|NSCreateMapTableWithZone|NSCreateHashTable|NSCreateHashTableWithZone|NSCreateZone|NSCreateFilenamePboardType|NSCreateFileContentsPboardType|NSTemporaryDirectory|NSIsControllerMarker|NSIsEmptyRect|NSIsFreedObject|NSInsetRect|NSIncrementExtraRefCount|NSIntersectsRect|NSIntersectionRect|NSIntersectionRange|NSInterfaceStyleForKey|NSIntegralRect|NSZoneRealloc|NSZoneMalloc|NSZoneName|NSZoneCalloc|NSZoneFromPointer|NSZoneFree|NSOpenStepRootDirectory|NSOffsetRect|NSDisableScreenUpdates|NSDivideRect|NSDottedFrameRect|NSDecimalRound|NSDecimalMultiply|NSDecimalString|NSDecimalSubtract|NSDecimalNormalize|NSDecimalCopy|NSDecimalCompact|NSDecimalCompare|NSDecimalIsNotANumber|NSDecimalDivide|NSDecimalPower|NSDecimalAdd|NSDecrementExtraRefCountWasZero|NSDefaultMallocZone|NSDeallocateMemoryPages|NSDeallocateObject|NSDrawGroove|NSDrawGrayBezel|NSDrawBitmap|NSDrawButton|NSDrawColorTiledRects|NSDrawTiledRects|NSDrawDarkBezel|NSDrawWhiteBezel|NSDrawWindowBackground|NSDrawLightBezel|NSUserName|NSUnionRect|NSUnionRange|NSUnregisterServicesProvider|NSUpdateDynamicServices|NSJavaBundleSetup|NSJavaBundleCleanup|NSJavaSetup|NSJavaSetupVirtualMachine|NSJavaNeedsToLoadClasses|NSJavaNeedsVirtualMachine|NSJavaClassesForBundle|NSJavaClassesFromPath|NSJavaObjectNamedInPath|NSJavaProvidesClasses|NSPointInRect|NSPointFromString|NSPerformService|NSPlanarFromDepth|NSPageSize|NSEndMapTableEnumeration|NSEndHashTableEnumeration|NSEnumerateMapTable|NSEnumerateHashTable|NSEnableScreenUpdates|NSEqualRects|NSEqualRanges|NSEqualSizes|NSEqualPoints|NSEraseRect|NSExtraRefCount|NSFileTypeForHFSTypeCode|NSFullUserName|NSFreeMapTable|NSFreeHashTable|NSFrameRect|NSFrameRectWithWidth|NSFrameRectWithWidthUsingOperation|NSFrameAddress|NSWindowList|NSWindowListForContext|NSWidth|NSLocationInRange|NSLog|NSLogv|NSLogPageSize|NSAccessibilityRoleDescription|NSAccessibilityRoleDescriptionForUIElement|NSAccessibilityRaiseBadArgumentException|NSAccessibilityUnignoredChildren|NSAccessibilityUnignoredChildrenForOnlyChild|NSAccessibilityUnignoredDescendant|NSAccessibilityUnignoredAncestor|NSAccessibilityPostNotification|NSAccessibilityActionDescription|NSApplicationMain|NSApplicationLoad|NSAvailableWindowDepths|NSAllMapTableValues|NSAllMapTableKeys|NSAllHashTableObjects|NSAllocateMemoryPages|NSAllocateCollectable|NSAllocateObject\",\n        \"support.class.cocoa.leopard\": \"NSRuleEditor|NSGarbageCollector|NSGradient|NSMapTable|NSHashTable|NSCondition|NSCollectionView|NSCollectionViewItem|NSToolbarItemGroup|NSTextInputClient|NSTreeNode|NSTrackingArea|NSInvocationOperation|NSOperation|NSOperationQueue|NSDictionaryController|NSDockTile|NSPointerFunctions|NSPointerArray|NSPathControl|NSPathControlDelegate|NSPathComponentCell|NSPathCell|NSPathCellDelegate|NSPrintPanelAccessorizing|NSPredicateEditor|NSPredicateEditorRowTemplate|NSViewController|NSFastEnumeration|NSAnimationContext|NSAnimatablePropertyContainer\",\n        \"support.class.cocoa\": \"NSRunLoop|NSRulerMarker|NSRulerView|NSResponder|NSRecursiveLock|NSRelativeSpecifier|NSRandomSpecifier|NSRangeSpecifier|NSGetCommand|NSGlyphGenerator|NSGlyphStorage|NSGlyphInfo|NSGraphicsContext|NSXMLNode|NSXMLDocument|NSXMLDTD|NSXMLDTDNode|NSXMLParser|NSXMLElement|NSMiddleSpecifier|NSMovie|NSMovieView|NSMoveCommand|NSMutableString|NSMutableSet|NSMutableCharacterSet|NSMutableCopying|NSMutableIndexSet|NSMutableDictionary|NSMutableData|NSMutableURLRequest|NSMutableParagraphStyle|NSMutableAttributedString|NSMutableArray|NSMessagePort|NSMessagePortNameServer|NSMenu|NSMenuItem|NSMenuItemCell|NSMenuView|NSMethodSignature|NSMetadataItem|NSMetadataQuery|NSMetadataQueryResultGroup|NSMetadataQueryAttributeValueTuple|NSMachBootstrapServer|NSMachPort|NSMatrix|NSBitmapImageRep|NSBox|NSBundle|NSButton|NSButtonCell|NSBezierPath|NSBrowser|NSBrowserCell|NSShadow|NSScanner|NSScriptSuiteRegistry|NSScriptCoercionHandler|NSScriptCommand|NSScriptCommandDescription|NSScriptClassDescription|NSScriptObjectSpecifier|NSScriptExecutionContext|NSScriptWhoseTest|NSScroller|NSScrollView|NSScreen|NSStepper|NSStepperCell|NSStatusBar|NSStatusItem|NSString|NSStream|NSSimpleHorizontalTypesetter|NSSimpleCString|NSSocketPort|NSSocketPortNameServer|NSSound|NSSortDescriptor|NSSpecifierTest|NSSpeechRecognizer|NSSpeechSynthesizer|NSSpellServer|NSSpellChecker|NSSplitView|NSSecureTextField|NSSecureTextFieldCell|NSSet|NSSetCommand|NSSearchField|NSSearchFieldCell|NSSerializer|NSSegmentedControl|NSSegmentedCell|NSSlider|NSSliderCell|NSSavePanel|NSHost|NSHTTPCookie|NSHTTPCookieStorage|NSHTTPURLResponse|NSHelpManager|NSNib|NSNibConnector|NSNibControlConnector|NSNibOutletConnector|NSNotification|NSNotificationCenter|NSNotificationQueue|NSNull|NSNumber|NSNumberFormatter|NSNetService|NSNetServiceBrowser|NSNameSpecifier|NSChangeSpelling|NSCharacterSet|NSConstantString|NSConnection|NSControl|NSController|NSConditionLock|NSCoding|NSCoder|NSCountCommand|NSCountedSet|NSCopying|NSColor|NSColorSpace|NSColorPickingCustom|NSColorPickingDefault|NSColorPicker|NSColorPanel|NSColorWell|NSColorList|NSCompoundPredicate|NSComparisonPredicate|NSComboBox|NSComboBoxCell|NSCustomImageRep|NSCursor|NSCIImageRep|NSCell|NSClipView|NSCloseCommand|NSCloneCommand|NSClassDescription|NSCachedImageRep|NSCachedURLResponse|NSCalendar|NSCalendarDate|NSCreateCommand|NSThread|NSTypesetter|NSTimeZone|NSTimer|NSToolbar|NSToolbarItem|NSToolbarItemValidations|NSTokenField|NSTokenFieldCell|NSText|NSTextBlock|NSTextStorage|NSTextContainer|NSTextTab|NSTextTable|NSTextTableBlock|NSTextInput|NSTextView|NSTextField|NSTextFieldCell|NSTextList|NSTextAttachment|NSTextAttachmentCell|NSTask|NSTableHeaderCell|NSTableHeaderView|NSTableColumn|NSTableView|NSTabView|NSTabViewItem|NSTreeController|NSIndexSpecifier|NSIndexSet|NSIndexPath|NSInputManager|NSInputStream|NSInputServiceProvider|NSInputServer|NSInputServerMouseTracker|NSInvocation|NSIgnoreMisspelledWords|NSImage|NSImageRep|NSImageCell|NSImageView|NSOutputStream|NSOutlineView|NSOpenGLContext|NSOpenGLPixelBuffer|NSOpenGLPixelFormat|NSOpenGLView|NSOpenPanel|NSObjCTypeSerializationCallBack|NSObject|NSObjectController|NSDistantObject|NSDistantObjectRequest|NSDistributedNotificationCenter|NSDistributedLock|NSDictionary|NSDirectoryEnumerator|NSDocument|NSDocumentController|NSDeserializer|NSDecimalNumber|NSDecimalNumberBehaviors|NSDecimalNumberHandler|NSDeleteCommand|NSDate|NSDateComponents|NSDatePicker|NSDatePickerCell|NSDateFormatter|NSData|NSDrawer|NSDraggingInfo|NSUserInterfaceValidations|NSUserDefaults|NSUserDefaultsController|NSURL|NSURLResponse|NSURLRequest|NSURLHandle|NSURLHandleClient|NSURLConnection|NSURLCache|NSURLCredential|NSURLCredentialStorage|NSURLDownload|NSURLDownloadDelegate|NSURLProtocol|NSURLProtocolClient|NSURLProtectionSpace|NSURLAuthenticationChallenge|NSURLAuthenticationChallengeSender|NSUniqueIDSpecifier|NSUndoManager|NSUnarchiver|NSPipe|NSPositionalSpecifier|NSPopUpButton|NSPopUpButtonCell|NSPort|NSPortMessage|NSPortNameServer|NSPortCoder|NSPICTImageRep|NSPersistentDocument|NSPDFImageRep|NSPasteboard|NSPanel|NSParagraphStyle|NSPageLayout|NSPrintInfo|NSPrinter|NSPrintOperation|NSPrintPanel|NSProcessInfo|NSProtocolChecker|NSPropertySpecifier|NSPropertyListSerialization|NSProgressIndicator|NSProxy|NSPredicate|NSEnumerator|NSEvent|NSEPSImageRep|NSError|NSException|NSExistsCommand|NSExpression|NSView|NSViewAnimation|NSValidatedToobarItem|NSValidatedUserInterfaceItem|NSValueTransformer|NSKeyedUnarchiver|NSKeyedArchiver|NSQuickDrawView|NSQuitCommand|NSFileManager|NSFileHandle|NSFileWrapper|NSFont|NSFontManager|NSFontDescriptor|NSFontPanel|NSFormCell|NSFormatter|NSWhoseSpecifier|NSWindow|NSWindowController|NSWorkspace|NSLock|NSLocking|NSLocale|NSLogicalTest|NSLevelIndicator|NSLevelIndicatorCell|NSLayoutManager|NSAssertionHandler|NSAnimation|NSActionCell|NSAttributedString|NSAutoreleasePool|NSATSTypesetter|NSApplication|NSAppleScript|NSAppleEventManager|NSAppleEventDescriptor|NSAffineTransform|NSAlert|NSArchiver|NSArray|NSArrayController\",\n        \"support.type.cocoa.leopard\": \"\",\n        \"support.class.quartz\": \"CISampler|CIContext|CIColor|CIImage|CIImageAccumulator|CIPlugIn|CIPlugInRegistration|CIVector|CIKernel|CIFilter|CIFilterGenerator|CIFilterShape|CARenderer|CAMediaTiming|CAMediaTimingFunction|CABasicAnimation|CAScrollLayer|CAConstraint|CAConstraintLayoutManager|CATiledLayer|CATextLayer|CATransition|CATransaction|CAOpenGLLayer|CAPropertyAnimation|CAKeyframeAnimation|CALayer|CAAnimation|CAAnimationGroup|CAAction\",\n        \"support.type.quartz\": \"CGFloat|CGPoint|CGSize|CGRect|CIFormat|CAConstraintAttribute\",\n        \"support.type.cocoa\": \"NSRect|NSRectEdge|NSRange|NSGlyph|NSGlyphRelation|NSGlyphLayoutMode|NSGradientType|NSModalSession|NSMatrixMode|NSMapEnumerator|NSBitmapImageFileType|NSBorderType|NSButtonType|NSBezelStyle|NSBackingStoreType|NSBrowserColumnResizingType|NSScrollerPart|NSScrollerArrow|NSScrollArrowPosition|NSScreenAuxiliaryOpaque|NSStringEncoding|NSSize|NSSocketNativeHandle|NSSelectionGranularity|NSSelectionDirection|NSSelectionAffinity|NSSwappedDouble|NSSwappedFloat|NSSaveOperationType|NSHashEnumerator|NSHandler|NSHandler2|NSControlSize|NSControlTint|NSCompositingOperation|NSComparisonResult|NSCellState|NSCellType|NSCellImagePosition|NSCellAttribute|NSThreadPrivate|NSTypesetterGlyphInfo|NSTickMarkPosition|NSTitlePosition|NSTimeInterval|NSToolTipTag|NSToolbarSizeMode|NSToolbarDisplayMode|NSTokenStyle|NSTIFFCompression|NSTextTabType|NSTextAlignment|NSTabState|NSTableViewDropOperation|NSTabViewType|NSTrackingRectTag|NSImageInterpolation|NSZone|NSOpenGLContextAuxiliary|NSOpenGLPixelFormatAuxiliary|NSDocumentChangeType|NSDatePickerElementFlags|NSDrawerState|NSDragOperation|NSUsableScrollerParts|NSPoint|NSPrintingPageOrder|NSProgressIndicatorStyle|NSProgressIndicatorThickness|NSProgressIndicatorThreadInfo|NSEventType|NSKeyValueObservingOptions|NSFontSymbolicTraits|NSFontTraitMask|NSFontAction|NSFocusRingType|NSWindowOrderingMode|NSWindowDepth|NSWorkspaceIconCreationOptions|NSWorkspaceLaunchOptions|NSWritingDirection|NSLineBreakMode|NSLayoutStatus|NSLayoutDirection|NSAnimationProgress|NSAnimationEffect|NSApplicationTerminateReply|NSApplicationDelegateReply|NSApplicationPrintReply|NSAppleEventManagerSuspensionID|NSAffineTransformStruct|NSAlertStyle\",\n        \"support.constant.cocoa\": \"NSRGBModeColorPanel|NSRGBColorSpaceModel|NSRightMouseDown|NSRightMouseDownMask|NSRightMouseDragged|NSRightMouseDraggedMask|NSRightMouseUp|NSRightMouseUpMask|NSRightTextMovement|NSRightTextAlignment|NSRightTabsBezelBorder|NSRightTabStopType|NSRightArrowFunctionKey|NSRoundRectBezelStyle|NSRoundBankers|NSRoundedBezelStyle|NSRoundedTokenStyle|NSRoundedDisclosureBezelStyle|NSRoundDown|NSRoundUp|NSRoundPlain|NSRoundLineCapStyle|NSRoundLineJoinStyle|NSRunStoppedResponse|NSRunContinuesResponse|NSRunAbortedResponse|NSResizableWindowMask|NSResetCursorRectsRunLoopOrdering|NSResetFunctionKey|NSRecessedBezelStyle|NSReceiversCantHandleCommandScriptError|NSReceiverEvaluationScriptError|NSReturnTextMovement|NSRedoFunctionKey|NSRequiredArgumentsMissingScriptError|NSRelevancyLevelIndicatorStyle|NSRelativeBefore|NSRelativeAfter|NSRegularSquareBezelStyle|NSRegularControlSize|NSRemoveTraitFontAction|NSRandomSubelement|NSRangeDateMode|NSRatingLevelIndicatorStyle|NSRadioModeMatrix|NSRadioButton|NSGIFFileType|NSGlyphBelow|NSGlyphInscribeBelow|NSGlyphInscribeBase|NSGlyphInscribeOverstrike|NSGlyphInscribeOverBelow|NSGlyphInscribeAbove|NSGlyphLayoutWithPrevious|NSGlyphLayoutAtAPoint|NSGlyphLayoutAgainstAPoint|NSGlyphAttributeBidiLevel|NSGlyphAttributeSoft|NSGlyphAttributeInscribe|NSGlyphAttributeElastic|NSGlyphAbove|NSGrooveBorder|NSGreaterThanComparison|NSGreaterThanOrEqualToComparison|NSGreaterThanOrEqualToPredicateOperatorType|NSGreaterThanPredicateOperatorType|NSGrayModeColorPanel|NSGrayColorSpaceModel|NSGradientNone|NSGradientConcaveStrong|NSGradientConcaveWeak|NSGradientConvexStrong|NSGradientConvexWeak|NSGraphiteControlTint|NSXMLNotationDeclarationKind|NSXMLNodeCompactEmptyElement|NSXMLNodeIsCDATA|NSXMLNodeOptionsNone|NSXMLNodeUseSingleQuotes|NSXMLNodeUseDoubleQuotes|NSXMLNodePreserveNamespaceOrder|NSXMLNodePreserveCharacterReferences|NSXMLNodePreserveCDATA|NSXMLNodePreserveDTD|NSXMLNodePreservePrefixes|NSXMLNodePreserveEntities|NSXMLNodePreserveEmptyElements|NSXMLNodePreserveQuotes|NSXMLNodePreserveWhitespace|NSXMLNodePreserveAttributeOrder|NSXMLNodePreserveAll|NSXMLNodePrettyPrint|NSXMLNodeExpandEmptyElement|NSXMLNamespaceKind|NSXMLCommentKind|NSXMLTextKind|NSXMLInvalidKind|NSXMLDocumentXMLKind|NSXMLDocumentXHTMLKind|NSXMLDocumentXInclude|NSXMLDocumentHTMLKind|NSXMLDocumentTidyXML|NSXMLDocumentTidyHTML|NSXMLDocumentTextKind|NSXMLDocumentIncludeContentTypeDeclaration|NSXMLDocumentValidate|NSXMLDocumentKind|NSXMLDTDKind|NSXMLParserGTRequiredError|NSXMLParserXMLDeclNotStartedError|NSXMLParserXMLDeclNotFinishedError|NSXMLParserMisplacedXMLDeclarationError|NSXMLParserMisplacedCDATAEndStringError|NSXMLParserMixedContentDeclNotStartedError|NSXMLParserMixedContentDeclNotFinishedError|NSXMLParserStandaloneValueError|NSXMLParserStringNotStartedError|NSXMLParserStringNotClosedError|NSXMLParserSpaceRequiredError|NSXMLParserSeparatorRequiredError|NSXMLParserNMTOKENRequiredError|NSXMLParserNotationNotStartedError|NSXMLParserNotationNotFinishedError|NSXMLParserNotWellBalancedError|NSXMLParserNoDTDError|NSXMLParserNamespaceDeclarationError|NSXMLParserNAMERequiredError|NSXMLParserCharacterRefInDTDError|NSXMLParserCharacterRefInPrologError|NSXMLParserCharacterRefInEpilogError|NSXMLParserCharacterRefAtEOFError|NSXMLParserConditionalSectionNotStartedError|NSXMLParserConditionalSectionNotFinishedError|NSXMLParserCommentNotFinishedError|NSXMLParserCommentContainsDoubleHyphenError|NSXMLParserCDATANotFinishedError|NSXMLParserTagNameMismatchError|NSXMLParserInternalError|NSXMLParserInvalidHexCharacterRefError|NSXMLParserInvalidCharacterRefError|NSXMLParserInvalidCharacterInEntityError|NSXMLParserInvalidCharacterError|NSXMLParserInvalidConditionalSectionError|NSXMLParserInvalidDecimalCharacterRefError|NSXMLParserInvalidURIError|NSXMLParserInvalidEncodingNameError|NSXMLParserInvalidEncodingError|NSXMLParserOutOfMemoryError|NSXMLParserDocumentStartError|NSXMLParserDelegateAbortedParseError|NSXMLParserDOCTYPEDeclNotFinishedError|NSXMLParserURIRequiredError|NSXMLParserURIFragmentError|NSXMLParserUndeclaredEntityError|NSXMLParserUnparsedEntityError|NSXMLParserUnknownEncodingError|NSXMLParserUnfinishedTagError|NSXMLParserPCDATARequiredError|NSXMLParserPublicIdentifierRequiredError|NSXMLParserParsedEntityRefMissingSemiError|NSXMLParserParsedEntityRefNoNameError|NSXMLParserParsedEntityRefInInternalSubsetError|NSXMLParserParsedEntityRefInInternalError|NSXMLParserParsedEntityRefInPrologError|NSXMLParserParsedEntityRefInEpilogError|NSXMLParserParsedEntityRefAtEOFError|NSXMLParserProcessingInstructionNotStartedError|NSXMLParserProcessingInstructionNotFinishedError|NSXMLParserPrematureDocumentEndError|NSXMLParserEncodingNotSupportedError|NSXMLParserEntityRefInDTDError|NSXMLParserEntityRefInPrologError|NSXMLParserEntityRefInEpilogError|NSXMLParserEntityReferenceMissingSemiError|NSXMLParserEntityReferenceWithoutNameError|NSXMLParserEntityRefLoopError|NSXMLParserEntityRefAtEOFError|NSXMLParserEntityBoundaryError|NSXMLParserEntityNotStartedError|NSXMLParserEntityNotFinishedError|NSXMLParserEntityIsParameterError|NSXMLParserEntityIsExternalError|NSXMLParserEntityValueRequiredError|NSXMLParserEqualExpectedError|NSXMLParserElementContentDeclNotStartedError|NSXMLParserElementContentDeclNotFinishedError|NSXMLParserExternalStandaloneEntityError|NSXMLParserExternalSubsetNotFinishedError|NSXMLParserExtraContentError|NSXMLParserEmptyDocumentError|NSXMLParserLiteralNotStartedError|NSXMLParserLiteralNotFinishedError|NSXMLParserLTRequiredError|NSXMLParserLTSlashRequiredError|NSXMLParserLessThanSymbolInAttributeError|NSXMLParserAttributeRedefinedError|NSXMLParserAttributeHasNoValueError|NSXMLParserAttributeNotStartedError|NSXMLParserAttributeNotFinishedError|NSXMLParserAttributeListNotStartedError|NSXMLParserAttributeListNotFinishedError|NSXMLProcessingInstructionKind|NSXMLEntityGeneralKind|NSXMLEntityDeclarationKind|NSXMLEntityUnparsedKind|NSXMLEntityParsedKind|NSXMLEntityParameterKind|NSXMLEntityPredefined|NSXMLElementDeclarationMixedKind|NSXMLElementDeclarationUndefinedKind|NSXMLElementDeclarationElementKind|NSXMLElementDeclarationEmptyKind|NSXMLElementDeclarationKind|NSXMLElementDeclarationAnyKind|NSXMLElementKind|NSXMLAttributeNMTokensKind|NSXMLAttributeNMTokenKind|NSXMLAttributeNotationKind|NSXMLAttributeCDATAKind|NSXMLAttributeIDRefsKind|NSXMLAttributeIDRefKind|NSXMLAttributeIDKind|NSXMLAttributeDeclarationKind|NSXMLAttributeEntityKind|NSXMLAttributeEntitiesKind|NSXMLAttributeEnumerationKind|NSXMLAttributeKind|NSMinXEdge|NSMiniaturizableWindowMask|NSMinYEdge|NSMinuteCalendarUnit|NSMiterLineJoinStyle|NSMiddleSubelement|NSMixedState|NSMonthCalendarUnit|NSModeSwitchFunctionKey|NSMouseMoved|NSMouseMovedMask|NSMouseEntered|NSMouseEnteredMask|NSMouseEventSubtype|NSMouseExited|NSMouseExitedMask|NSMoveToBezierPathElement|NSMomentaryChangeButton|NSMomentaryPushButton|NSMomentaryPushInButton|NSMomentaryLight|NSMomentaryLightButton|NSMenuFunctionKey|NSMacintoshInterfaceStyle|NSMacOSRomanStringEncoding|NSMatchesPredicateOperatorType|NSMappedRead|NSMaxXEdge|NSMaxYEdge|NSMACHOperatingSystem|NSBMPFileType|NSBottomTabsBezelBorder|NSBoldFontMask|NSBorderlessWindowMask|NSBoxSecondary|NSBoxSeparator|NSBoxOldStyle|NSBoxPrimary|NSButtLineCapStyle|NSBezelBorder|NSBevelLineJoinStyle|NSBelowBottom|NSBelowTop|NSBeginsWithComparison|NSBeginsWithPredicateOperatorType|NSBeginFunctionKey|NSBlueControlTint|NSBackspaceCharacter|NSBacktabTextMovement|NSBackingStoreRetained|NSBackingStoreBuffered|NSBackingStoreNonretained|NSBackTabCharacter|NSBackwardsSearch|NSBackgroundTab|NSBrowserNoColumnResizing|NSBrowserUserColumnResizing|NSBrowserAutoColumnResizing|NSBreakFunctionKey|NSShiftJISStringEncoding|NSShiftKeyMask|NSShowControlGlyphs|NSShowInvisibleGlyphs|NSShadowlessSquareBezelStyle|NSSysReqFunctionKey|NSSystemDomainMask|NSSystemDefined|NSSystemDefinedMask|NSSystemFunctionKey|NSSymbolStringEncoding|NSScannedOption|NSScaleNone|NSScaleToFit|NSScaleProportionally|NSScrollerNoPart|NSScrollerIncrementPage|NSScrollerIncrementLine|NSScrollerIncrementArrow|NSScrollerDecrementPage|NSScrollerDecrementLine|NSScrollerDecrementArrow|NSScrollerKnob|NSScrollerKnobSlot|NSScrollerArrowsMinEnd|NSScrollerArrowsMaxEnd|NSScrollerArrowsNone|NSScrollerArrowsDefaultSetting|NSScrollWheel|NSScrollWheelMask|NSScrollLockFunctionKey|NSScreenChangedEventType|NSStopFunctionKey|NSStringDrawingOneShot|NSStringDrawingDisableScreenFontSubstitution|NSStringDrawingUsesDeviceMetrics|NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStreamStatusReading|NSStreamStatusNotOpen|NSStreamStatusClosed|NSStreamStatusOpen|NSStreamStatusOpening|NSStreamStatusError|NSStreamStatusWriting|NSStreamStatusAtEnd|NSStreamEventHasBytesAvailable|NSStreamEventHasSpaceAvailable|NSStreamEventNone|NSStreamEventOpenCompleted|NSStreamEventEndEncountered|NSStreamEventErrorOccurred|NSSingleDateMode|NSSingleUnderlineStyle|NSSizeDownFontAction|NSSizeUpFontAction|NSSolarisOperatingSystem|NSSunOSOperatingSystem|NSSpecialPageOrder|NSSecondCalendarUnit|NSSelectByCharacter|NSSelectByParagraph|NSSelectByWord|NSSelectingNext|NSSelectingPrevious|NSSelectionAffinityDownstream|NSSelectionAffinityUpstream|NSSelectedTab|NSSelectFunctionKey|NSSegmentSwitchTrackingMomentary|NSSegmentSwitchTrackingSelectOne|NSSegmentSwitchTrackingSelectAny|NSSquareLineCapStyle|NSSwitchButton|NSSaveToOperation|NSSaveOptionsYes|NSSaveOptionsNo|NSSaveOptionsAsk|NSSaveOperation|NSSaveAsOperation|NSSmallSquareBezelStyle|NSSmallControlSize|NSSmallCapsFontMask|NSSmallIconButtonBezelStyle|NSHighlightModeMatrix|NSHSBModeColorPanel|NSHourMinuteSecondDatePickerElementFlag|NSHourMinuteDatePickerElementFlag|NSHourCalendarUnit|NSHorizontalRuler|NSHomeFunctionKey|NSHTTPCookieAcceptPolicyNever|NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain|NSHTTPCookieAcceptPolicyAlways|NSHelpButtonBezelStyle|NSHelpKeyMask|NSHelpFunctionKey|NSHeavierFontAction|NSHPUXOperatingSystem|NSYearMonthDayDatePickerElementFlag|NSYearMonthDatePickerElementFlag|NSYearCalendarUnit|NSNonStandardCharacterSetFontMask|NSNonZeroWindingRule|NSNonactivatingPanelMask|NSNonLossyASCIIStringEncoding|NSNoBorder|NSNotificationSuspensionBehaviorHold|NSNotificationSuspensionBehaviorCoalesce|NSNotificationSuspensionBehaviorDeliverImmediately|NSNotificationSuspensionBehaviorDrop|NSNotificationNoCoalescing|NSNotificationCoalescingOnSender|NSNotificationCoalescingOnName|NSNotificationDeliverImmediately|NSNotificationPostToAllSessions|NSNotPredicateType|NSNotEqualToPredicateOperatorType|NSNoScriptError|NSNoScrollerParts|NSNoSubelement|NSNoSpecifierError|NSNoCellMask|NSNoTitle|NSNoTopLevelContainersSpecifierError|NSNoTabsBezelBorder|NSNoTabsNoBorder|NSNoTabsLineBorder|NSNoInterfaceStyle|NSNoImage|NSNoUnderlineStyle|NSNoFontChangeAction|NSNullGlyph|NSNullCellType|NSNumericSearch|NSNumericPadKeyMask|NSNumberFormatterRoundHalfDown|NSNumberFormatterRoundHalfUp|NSNumberFormatterRoundHalfEven|NSNumberFormatterRoundCeiling|NSNumberFormatterRoundDown|NSNumberFormatterRoundUp|NSNumberFormatterRoundFloor|NSNumberFormatterBehavior10|NSNumberFormatterBehaviorDefault|NSNumberFormatterScientificStyle|NSNumberFormatterSpellOutStyle|NSNumberFormatterNoStyle|NSNumberFormatterCurrencyStyle|NSNumberFormatterDecimalStyle|NSNumberFormatterPercentStyle|NSNumberFormatterPadBeforeSuffix|NSNumberFormatterPadBeforePrefix|NSNumberFormatterPadAfterSuffix|NSNumberFormatterPadAfterPrefix|NSNetServicesBadArgumentError|NSNetServicesNotFoundError|NSNetServicesCollisionError|NSNetServicesCancelledError|NSNetServicesTimeoutError|NSNetServicesInvalidError|NSNetServicesUnknownError|NSNetServicesActivityInProgress|NSNetworkDomainMask|NSNewlineCharacter|NSNextStepInterfaceStyle|NSNextFunctionKey|NSNEXTSTEPStringEncoding|NSNativeShortGlyphPacking|NSNaturalTextAlignment|NSNarrowFontMask|NSChangeReadOtherContents|NSChangeGrayCell|NSChangeGrayCellMask|NSChangeBackgroundCell|NSChangeBackgroundCellMask|NSChangeCleared|NSChangeDone|NSChangeUndone|NSChangeAutosaved|NSCMYKModeColorPanel|NSCMYKColorSpaceModel|NSCircularBezelStyle|NSCircularSlider|NSConstantValueExpressionType|NSContinuousCapacityLevelIndicatorStyle|NSContentsCellMask|NSContainsComparison|NSContainerSpecifierError|NSControlGlyph|NSControlKeyMask|NSCondensedFontMask|NSColorPanelRGBModeMask|NSColorPanelGrayModeMask|NSColorPanelHSBModeMask|NSColorPanelCMYKModeMask|NSColorPanelColorListModeMask|NSColorPanelCustomPaletteModeMask|NSColorPanelCrayonModeMask|NSColorPanelWheelModeMask|NSColorPanelAllModesMask|NSColorListModeColorPanel|NSCoreServiceDirectory|NSCompositeXOR|NSCompositeSourceIn|NSCompositeSourceOut|NSCompositeSourceOver|NSCompositeSourceAtop|NSCompositeHighlight|NSCompositeCopy|NSCompositeClear|NSCompositeDestinationIn|NSCompositeDestinationOut|NSCompositeDestinationOver|NSCompositeDestinationAtop|NSCompositePlusDarker|NSCompositePlusLighter|NSCompressedFontMask|NSCommandKeyMask|NSCustomSelectorPredicateOperatorType|NSCustomPaletteModeColorPanel|NSCursorUpdate|NSCursorUpdateMask|NSCursorPointingDevice|NSCurveToBezierPathElement|NSCenterTextAlignment|NSCenterTabStopType|NSCellHighlighted|NSCellHasImageHorizontal|NSCellHasImageOnLeftOrBottom|NSCellHasOverlappingImage|NSCellChangesContents|NSCellIsBordered|NSCellIsInsetButton|NSCellDisabled|NSCellEditable|NSCellLightsByGray|NSCellLightsByBackground|NSCellLightsByContents|NSCellAllowsMixedState|NSClipPagination|NSClosePathBezierPathElement|NSClosableWindowMask|NSClockAndCalendarDatePickerStyle|NSClearControlTint|NSClearDisplayFunctionKey|NSClearLineFunctionKey|NSCaseInsensitiveSearch|NSCaseInsensitivePredicateOption|NSCannotCreateScriptCommandError|NSCancelButton|NSCancelTextMovement|NSCachesDirectory|NSCalculationNoError|NSCalculationOverflow|NSCalculationDivideByZero|NSCalculationUnderflow|NSCalculationLossOfPrecision|NSCarriageReturnCharacter|NSCriticalRequest|NSCriticalAlertStyle|NSCrayonModeColorPanel|NSThickSquareBezelStyle|NSThickerSquareBezelStyle|NSTypesetterBehavior|NSTypesetterHorizontalTabAction|NSTypesetterContainerBreakAction|NSTypesetterZeroAdvancementAction|NSTypesetterOriginalBehavior|NSTypesetterParagraphBreakAction|NSTypesetterWhitespaceAction|NSTypesetterLineBreakAction|NSTypesetterLatestBehavior|NSTickMarkRight|NSTickMarkBelow|NSTickMarkLeft|NSTickMarkAbove|NSTitledWindowMask|NSTimeZoneDatePickerElementFlag|NSToolbarItemVisibilityPriorityStandard|NSToolbarItemVisibilityPriorityHigh|NSToolbarItemVisibilityPriorityUser|NSToolbarItemVisibilityPriorityLow|NSTopTabsBezelBorder|NSToggleButton|NSTIFFCompressionNone|NSTIFFCompressionNEXT|NSTIFFCompressionCCITTFAX3|NSTIFFCompressionCCITTFAX4|NSTIFFCompressionOldJPEG|NSTIFFCompressionJPEG|NSTIFFCompressionPackBits|NSTIFFCompressionLZW|NSTIFFFileType|NSTerminateNow|NSTerminateCancel|NSTerminateLater|NSTextReadInapplicableDocumentTypeError|NSTextReadWriteErrorMinimum|NSTextReadWriteErrorMaximum|NSTextBlockMinimumHeight|NSTextBlockMinimumWidth|NSTextBlockMiddleAlignment|NSTextBlockMargin|NSTextBlockMaximumHeight|NSTextBlockMaximumWidth|NSTextBlockBottomAlignment|NSTextBlockBorder|NSTextBlockBaselineAlignment|NSTextBlockHeight|NSTextBlockTopAlignment|NSTextBlockPercentageValueType|NSTextBlockPadding|NSTextBlockWidth|NSTextBlockAbsoluteValueType|NSTextStorageEditedCharacters|NSTextStorageEditedAttributes|NSTextCellType|NSTexturedRoundedBezelStyle|NSTexturedBackgroundWindowMask|NSTexturedSquareBezelStyle|NSTextTableFixedLayoutAlgorithm|NSTextTableAutomaticLayoutAlgorithm|NSTextFieldRoundedBezel|NSTextFieldSquareBezel|NSTextFieldAndStepperDatePickerStyle|NSTextWriteInapplicableDocumentTypeError|NSTextListPrependEnclosingMarker|NSTwoByteGlyphPacking|NSTabCharacter|NSTabTextMovement|NSTabletPoint|NSTabletPointMask|NSTabletPointEventSubtype|NSTabletProximity|NSTabletProximityMask|NSTabletProximityEventSubtype|NSTableColumnNoResizing|NSTableColumnUserResizingMask|NSTableColumnAutoresizingMask|NSTableViewReverseSequentialColumnAutoresizingStyle|NSTableViewGridNone|NSTableViewSolidHorizontalGridLineMask|NSTableViewSolidVerticalGridLineMask|NSTableViewSequentialColumnAutoresizingStyle|NSTableViewNoColumnAutoresizing|NSTableViewUniformColumnAutoresizingStyle|NSTableViewFirstColumnOnlyAutoresizingStyle|NSTableViewLastColumnOnlyAutoresizingStyle|NSTrackModeMatrix|NSInsertCharFunctionKey|NSInsertFunctionKey|NSInsertLineFunctionKey|NSIntType|NSInternalScriptError|NSInternalSpecifierError|NSIndexSubelement|NSInvalidIndexSpecifierError|NSInformationalRequest|NSInformationalAlertStyle|NSInPredicateOperatorType|NSItalicFontMask|NSISO2022JPStringEncoding|NSISOLatin1StringEncoding|NSISOLatin2StringEncoding|NSIdentityMappingCharacterCollection|NSIllegalTextMovement|NSImageRight|NSImageRepMatchesDevice|NSImageRepLoadStatusReadingHeader|NSImageRepLoadStatusCompleted|NSImageRepLoadStatusInvalidData|NSImageRepLoadStatusUnexpectedEOF|NSImageRepLoadStatusUnknownType|NSImageRepLoadStatusWillNeedAllData|NSImageBelow|NSImageCellType|NSImageCacheBySize|NSImageCacheNever|NSImageCacheDefault|NSImageCacheAlways|NSImageInterpolationHigh|NSImageInterpolationNone|NSImageInterpolationDefault|NSImageInterpolationLow|NSImageOnly|NSImageOverlaps|NSImageFrameGroove|NSImageFrameGrayBezel|NSImageFrameButton|NSImageFrameNone|NSImageFramePhoto|NSImageLoadStatusReadError|NSImageLoadStatusCompleted|NSImageLoadStatusCancelled|NSImageLoadStatusInvalidData|NSImageLoadStatusUnexpectedEOF|NSImageLeft|NSImageAlignRight|NSImageAlignBottom|NSImageAlignBottomRight|NSImageAlignBottomLeft|NSImageAlignCenter|NSImageAlignTop|NSImageAlignTopRight|NSImageAlignTopLeft|NSImageAlignLeft|NSImageAbove|NSOnState|NSOneByteGlyphPacking|NSOnOffButton|NSOnlyScrollerArrows|NSOtherMouseDown|NSOtherMouseDownMask|NSOtherMouseDragged|NSOtherMouseDraggedMask|NSOtherMouseUp|NSOtherMouseUpMask|NSOtherTextMovement|NSOSF1OperatingSystem|NSOpenGLGOResetLibrary|NSOpenGLGORetainRenderers|NSOpenGLGOClearFormatCache|NSOpenGLGOFormatCacheSize|NSOpenGLPFARobust|NSOpenGLPFARendererID|NSOpenGLPFAMinimumPolicy|NSOpenGLPFAMultisample|NSOpenGLPFAMultiScreen|NSOpenGLPFAMPSafe|NSOpenGLPFAMaximumPolicy|NSOpenGLPFABackingStore|NSOpenGLPFAScreenMask|NSOpenGLPFAStencilSize|NSOpenGLPFAStereo|NSOpenGLPFASingleRenderer|NSOpenGLPFASupersample|NSOpenGLPFASamples|NSOpenGLPFASampleBuffers|NSOpenGLPFASampleAlpha|NSOpenGLPFANoRecovery|NSOpenGLPFAColorSize|NSOpenGLPFAColorFloat|NSOpenGLPFACompliant|NSOpenGLPFAClosestPolicy|NSOpenGLPFAOffScreen|NSOpenGLPFADoubleBuffer|NSOpenGLPFADepthSize|NSOpenGLPFAPixelBuffer|NSOpenGLPFAVirtualScreenCount|NSOpenGLPFAFullScreen|NSOpenGLPFAWindow|NSOpenGLPFAAccumSize|NSOpenGLPFAAccelerated|NSOpenGLPFAAuxBuffers|NSOpenGLPFAAuxDepthStencil|NSOpenGLPFAAlphaSize|NSOpenGLPFAAllRenderers|NSOpenStepUnicodeReservedBase|NSOperationNotSupportedForKeyScriptError|NSOperationNotSupportedForKeySpecifierError|NSOffState|NSOKButton|NSOrPredicateType|NSObjCBitfield|NSObjCBoolType|NSObjCShortType|NSObjCStringType|NSObjCStructType|NSObjCSelectorType|NSObjCNoType|NSObjCCharType|NSObjCObjectType|NSObjCDoubleType|NSObjCUnionType|NSObjCPointerType|NSObjCVoidType|NSObjCFloatType|NSObjCLongType|NSObjCLonglongType|NSObjCArrayType|NSDisclosureBezelStyle|NSDiscreteCapacityLevelIndicatorStyle|NSDisplayWindowRunLoopOrdering|NSDiacriticInsensitivePredicateOption|NSDirectSelection|NSDirectPredicateModifier|NSDocModalWindowMask|NSDocumentDirectory|NSDocumentationDirectory|NSDoubleType|NSDownTextMovement|NSDownArrowFunctionKey|NSDescendingPageOrder|NSDesktopDirectory|NSDecimalTabStopType|NSDeviceNColorSpaceModel|NSDeviceIndependentModifierFlagsMask|NSDeveloperDirectory|NSDeveloperApplicationDirectory|NSDefaultControlTint|NSDefaultTokenStyle|NSDeleteCharacter|NSDeleteCharFunctionKey|NSDeleteFunctionKey|NSDeleteLineFunctionKey|NSDemoApplicationDirectory|NSDayCalendarUnit|NSDateFormatterMediumStyle|NSDateFormatterBehavior10|NSDateFormatterBehaviorDefault|NSDateFormatterShortStyle|NSDateFormatterNoStyle|NSDateFormatterFullStyle|NSDateFormatterLongStyle|NSDrawerClosingState|NSDrawerClosedState|NSDrawerOpeningState|NSDrawerOpenState|NSDragOperationGeneric|NSDragOperationMove|NSDragOperationNone|NSDragOperationCopy|NSDragOperationDelete|NSDragOperationPrivate|NSDragOperationEvery|NSDragOperationLink|NSDragOperationAll|NSUserCancelledError|NSUserDirectory|NSUserDomainMask|NSUserFunctionKey|NSURLHandleNotLoaded|NSURLHandleLoadSucceeded|NSURLHandleLoadInProgress|NSURLHandleLoadFailed|NSURLCredentialPersistenceNone|NSURLCredentialPersistencePermanent|NSURLCredentialPersistenceForSession|NSUnscaledWindowMask|NSUncachedRead|NSUnicodeStringEncoding|NSUnitalicFontMask|NSUnifiedTitleAndToolbarWindowMask|NSUndoCloseGroupingRunLoopOrdering|NSUndoFunctionKey|NSUndefinedDateComponent|NSUnderlineStyleSingle|NSUnderlineStyleNone|NSUnderlineStyleThick|NSUnderlineStyleDouble|NSUnderlinePatternSolid|NSUnderlinePatternDot|NSUnderlinePatternDash|NSUnderlinePatternDashDot|NSUnderlinePatternDashDotDot|NSUnknownColorSpaceModel|NSUnknownPointingDevice|NSUnknownPageOrder|NSUnknownKeyScriptError|NSUnknownKeySpecifierError|NSUnboldFontMask|NSUtilityWindowMask|NSUTF8StringEncoding|NSUpdateWindowsRunLoopOrdering|NSUpTextMovement|NSUpArrowFunctionKey|NSJustifiedTextAlignment|NSJPEG2000FileType|NSJPEGFileType|NSJapaneseEUCGlyphPacking|NSJapaneseEUCStringEncoding|NSPostNow|NSPosterFontMask|NSPostWhenIdle|NSPostASAP|NSPositionReplace|NSPositionBefore|NSPositionBeginning|NSPositionEnd|NSPositionAfter|NSPositiveIntType|NSPositiveDoubleType|NSPositiveFloatType|NSPopUpNoArrow|NSPopUpArrowAtBottom|NSPopUpArrowAtCenter|NSPowerOffEventType|NSPortraitOrientation|NSPNGFileType|NSPushInCell|NSPushInCellMask|NSPushOnPushOffButton|NSPenTipMask|NSPenUpperSideMask|NSPenPointingDevice|NSPenLowerSideMask|NSPeriodic|NSPeriodicMask|NSPPScaleField|NSPPStatusTitle|NSPPStatusField|NSPPSaveButton|NSPPNoteTitle|NSPPNoteField|NSPPNameTitle|NSPPNameField|NSPPCopiesField|NSPPTitleField|NSPPImageButton|NSPPOptionsButton|NSPPPaperFeedButton|NSPPPageRangeTo|NSPPPageRangeFrom|NSPPPageChoiceMatrix|NSPPPreviewButton|NSPPLayoutButton|NSPlainTextTokenStyle|NSPauseFunctionKey|NSParagraphSeparatorCharacter|NSPageDownFunctionKey|NSPageUpFunctionKey|NSPrintingReplyLater|NSPrintingSuccess|NSPrintingCancelled|NSPrintingFailure|NSPrintScreenFunctionKey|NSPrinterTableNotFound|NSPrinterTableOK|NSPrinterTableError|NSPrintFunctionKey|NSPropertyListXMLFormat|NSPropertyListMutableContainers|NSPropertyListMutableContainersAndLeaves|NSPropertyListBinaryFormat|NSPropertyListImmutable|NSPropertyListOpenStepFormat|NSProprietaryStringEncoding|NSProgressIndicatorBarStyle|NSProgressIndicatorSpinningStyle|NSProgressIndicatorPreferredSmallThickness|NSProgressIndicatorPreferredThickness|NSProgressIndicatorPreferredLargeThickness|NSProgressIndicatorPreferredAquaThickness|NSPressedTab|NSPrevFunctionKey|NSPLHeightForm|NSPLCancelButton|NSPLTitleField|NSPLImageButton|NSPLOKButton|NSPLOrientationMatrix|NSPLUnitsButton|NSPLPaperNameButton|NSPLWidthForm|NSEnterCharacter|NSEndsWithComparison|NSEndsWithPredicateOperatorType|NSEndFunctionKey|NSEvenOddWindingRule|NSEverySubelement|NSEvaluatedObjectExpressionType|NSEqualToComparison|NSEqualToPredicateOperatorType|NSEraserPointingDevice|NSEraCalendarUnit|NSEraDatePickerElementFlag|NSExclude10|NSExcludeQuickDrawElementsIconCreationOption|NSExpandedFontMask|NSExecuteFunctionKey|NSViewMinXMargin|NSViewMinYMargin|NSViewMaxXMargin|NSViewMaxYMargin|NSViewHeightSizable|NSViewNotSizable|NSViewWidthSizable|NSViaPanelFontAction|NSVerticalRuler|NSValidationErrorMinimum|NSValidationErrorMaximum|NSVariableExpressionType|NSKeySpecifierEvaluationScriptError|NSKeyDown|NSKeyDownMask|NSKeyUp|NSKeyUpMask|NSKeyPathExpressionType|NSKeyValueMinusSetMutation|NSKeyValueSetSetMutation|NSKeyValueChangeReplacement|NSKeyValueChangeRemoval|NSKeyValueChangeSetting|NSKeyValueChangeInsertion|NSKeyValueIntersectSetMutation|NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld|NSKeyValueUnionSetMutation|NSKeyValueValidationError|NSQTMovieNormalPlayback|NSQTMovieLoopingBackAndForthPlayback|NSQTMovieLoopingPlayback|NSF11FunctionKey|NSF17FunctionKey|NSF12FunctionKey|NSF18FunctionKey|NSF13FunctionKey|NSF19FunctionKey|NSF14FunctionKey|NSF15FunctionKey|NSF1FunctionKey|NSF10FunctionKey|NSF16FunctionKey|NSF7FunctionKey|NSFindPanelActionReplace|NSFindPanelActionReplaceAndFind|NSFindPanelActionReplaceAll|NSFindPanelActionReplaceAllInSelection|NSFindPanelActionShowFindPanel|NSFindPanelActionSetFindString|NSFindPanelActionSelectAll|NSFindPanelActionSelectAllInSelection|NSFindPanelActionNext|NSFindPanelActionPrevious|NSFindFunctionKey|NSFitPagination|NSFileReadNoSuchFileError|NSFileReadNoPermissionError|NSFileReadCorruptFileError|NSFileReadInvalidFileNameError|NSFileReadInapplicableStringEncodingError|NSFileReadUnsupportedSchemeError|NSFileReadUnknownError|NSFileHandlingPanelCancelButton|NSFileHandlingPanelOKButton|NSFileNoSuchFileError|NSFileErrorMinimum|NSFileErrorMaximum|NSFileWriteNoPermissionError|NSFileWriteInvalidFileNameError|NSFileWriteInapplicableStringEncodingError|NSFileWriteOutOfSpaceError|NSFileWriteUnsupportedSchemeError|NSFileWriteUnknownError|NSFileLockingError|NSFixedPitchFontMask|NSF21FunctionKey|NSF27FunctionKey|NSF22FunctionKey|NSF28FunctionKey|NSF23FunctionKey|NSF29FunctionKey|NSF24FunctionKey|NSF25FunctionKey|NSF2FunctionKey|NSF20FunctionKey|NSF26FunctionKey|NSFontMonoSpaceTrait|NSFontModernSerifsClass|NSFontBoldTrait|NSFontSymbolicClass|NSFontScriptsClass|NSFontSlabSerifsClass|NSFontSansSerifClass|NSFontCondensedTrait|NSFontCollectionApplicationOnlyMask|NSFontClarendonSerifsClass|NSFontTransitionalSerifsClass|NSFontIntegerAdvancementsRenderingMode|NSFontItalicTrait|NSFontOldStyleSerifsClass|NSFontOrnamentalsClass|NSFontDefaultRenderingMode|NSFontUnknownClass|NSFontUIOptimizedTrait|NSFontPanelShadowEffectModeMask|NSFontPanelStandardModesMask|NSFontPanelStrikethroughEffectModeMask|NSFontPanelSizeModeMask|NSFontPanelCollectionModeMask|NSFontPanelTextColorEffectModeMask|NSFontPanelDocumentColorEffectModeMask|NSFontPanelUnderlineEffectModeMask|NSFontPanelFaceModeMask|NSFontPanelAllModesMask|NSFontPanelAllEffectsModeMask|NSFontExpandedTrait|NSFontVerticalTrait|NSFontFamilyClassMask|NSFontFreeformSerifsClass|NSFontAntialiasedRenderingMode|NSFontAntialiasedIntegerAdvancementsRenderingMode|NSFocusRingBelow|NSFocusRingTypeNone|NSFocusRingTypeDefault|NSFocusRingTypeExterior|NSFocusRingOnly|NSFocusRingAbove|NSFourByteGlyphPacking|NSFormattingError|NSFormattingErrorMinimum|NSFormattingErrorMaximum|NSFormFeedCharacter|NSF8FunctionKey|NSFunctionExpressionType|NSFunctionKeyMask|NSF31FunctionKey|NSF32FunctionKey|NSF33FunctionKey|NSF34FunctionKey|NSF35FunctionKey|NSF3FunctionKey|NSF30FunctionKey|NSF9FunctionKey|NSF4FunctionKey|NSFPRevertButton|NSFPSizeTitle|NSFPSizeField|NSFPSetButton|NSFPCurrentField|NSFPPreviewButton|NSFPPreviewField|NSFloatingPointSamplesBitmapFormat|NSFloatType|NSFlagsChanged|NSFlagsChangedMask|NSFaxButton|NSF5FunctionKey|NSF6FunctionKey|NSWheelModeColorPanel|NSWindowsNTOperatingSystem|NSWindowsCP1251StringEncoding|NSWindowsCP1252StringEncoding|NSWindowsCP1253StringEncoding|NSWindowsCP1254StringEncoding|NSWindowsCP1250StringEncoding|NSWindows95InterfaceStyle|NSWindows95OperatingSystem|NSWindowMiniaturizeButton|NSWindowMovedEventType|NSWindowBelow|NSWindowCloseButton|NSWindowToolbarButton|NSWindowZoomButton|NSWindowOut|NSWindowDocumentIconButton|NSWindowExposedEventType|NSWindowAbove|NSWorkspaceLaunchNewInstance|NSWorkspaceLaunchInhibitingBackgroundOnly|NSWorkspaceLaunchDefault|NSWorkspaceLaunchPreferringClassic|NSWorkspaceLaunchWithoutActivation|NSWorkspaceLaunchWithoutAddingToRecents|NSWorkspaceLaunchAsync|NSWorkspaceLaunchAndHide|NSWorkspaceLaunchAndHideOthers|NSWorkspaceLaunchAndPrint|NSWorkspaceLaunchAllowingClassicStartup|NSWeekdayCalendarUnit|NSWeekdayOrdinalCalendarUnit|NSWeekCalendarUnit|NSWantsBidiLevels|NSWarningAlertStyle|NSWritingDirectionRightToLeft|NSWritingDirectionNatural|NSWritingDirectionLeftToRight|NSWrapCalendarComponents|NSListModeMatrix|NSLineMovesRight|NSLineMovesDown|NSLineMovesUp|NSLineMovesLeft|NSLineBorder|NSLineBreakByCharWrapping|NSLineBreakByClipping|NSLineBreakByTruncatingMiddle|NSLineBreakByTruncatingHead|NSLineBreakByTruncatingTail|NSLineBreakByWordWrapping|NSLineSeparatorCharacter|NSLineSweepRight|NSLineSweepDown|NSLineSweepUp|NSLineSweepLeft|NSLineToBezierPathElement|NSLineDoesntMove|NSLinearSlider|NSLiteralSearch|NSLikePredicateOperatorType|NSLighterFontAction|NSLibraryDirectory|NSLocalDomainMask|NSLessThanComparison|NSLessThanOrEqualToComparison|NSLessThanOrEqualToPredicateOperatorType|NSLessThanPredicateOperatorType|NSLeftMouseDown|NSLeftMouseDownMask|NSLeftMouseDragged|NSLeftMouseDraggedMask|NSLeftMouseUp|NSLeftMouseUpMask|NSLeftTextMovement|NSLeftTextAlignment|NSLeftTabsBezelBorder|NSLeftTabStopType|NSLeftArrowFunctionKey|NSLayoutRightToLeft|NSLayoutNotDone|NSLayoutCantFit|NSLayoutOutOfGlyphs|NSLayoutDone|NSLayoutLeftToRight|NSLandscapeOrientation|NSLABColorSpaceModel|NSAsciiWithDoubleByteEUCGlyphPacking|NSAscendingPageOrder|NSAnyType|NSAnyPredicateModifier|NSAnyEventMask|NSAnchoredSearch|NSAnimationBlocking|NSAnimationNonblocking|NSAnimationNonblockingThreaded|NSAnimationEffectDisappearingItemDefault|NSAnimationEffectPoof|NSAnimationEaseIn|NSAnimationEaseInOut|NSAnimationEaseOut|NSAnimationLinear|NSAndPredicateType|NSAtBottom|NSAttachmentCharacter|NSAtomicWrite|NSAtTop|NSASCIIStringEncoding|NSAdobeGB1CharacterCollection|NSAdobeCNS1CharacterCollection|NSAdobeJapan1CharacterCollection|NSAdobeJapan2CharacterCollection|NSAdobeKorea1CharacterCollection|NSAddTraitFontAction|NSAdminApplicationDirectory|NSAutosaveOperation|NSAutoPagination|NSApplicationSupportDirectory|NSApplicationDirectory|NSApplicationDefined|NSApplicationDefinedMask|NSApplicationDelegateReplySuccess|NSApplicationDelegateReplyCancel|NSApplicationDelegateReplyFailure|NSApplicationDeactivatedEventType|NSApplicationActivatedEventType|NSAppKitDefined|NSAppKitDefinedMask|NSAlternateKeyMask|NSAlphaShiftKeyMask|NSAlphaNonpremultipliedBitmapFormat|NSAlphaFirstBitmapFormat|NSAlertSecondButtonReturn|NSAlertThirdButtonReturn|NSAlertOtherReturn|NSAlertDefaultReturn|NSAlertErrorReturn|NSAlertFirstButtonReturn|NSAlertAlternateReturn|NSAllScrollerParts|NSAllDomainsMask|NSAllPredicateModifier|NSAllLibrariesDirectory|NSAllApplicationsDirectory|NSArgumentsWrongScriptError|NSArgumentEvaluationScriptError|NSAboveBottom|NSAboveTop|NSAWTEventType\",\n        \"support.constant.notification.cocoa.leopard\": \"NSMenuDidBeginTrackingNotification|NSViewDidUpdateTrackingAreasNotification\",\n        \"support.constant.notification.cocoa\": \"NSMenuDidRemoveItemNotification|NSMenuDidSendActionNotification|NSMenuDidChangeItemNotification|NSMenuDidEndTrackingNotification|NSMenuDidAddItemNotification|NSMenuWillSendActionNotification|NSSystemColorsDidChangeNotification|NSSplitViewDidResizeSubviewsNotification|NSSplitViewWillResizeSubviewsNotification|NSContextHelpModeDidDeactivateNotification|NSContextHelpModeDidActivateNotification|NSControlTintDidChangeNotification|NSControlTextDidBeginEditingNotification|NSControlTextDidChangeNotification|NSControlTextDidEndEditingNotification|NSColorPanelColorDidChangeNotification|NSColorListDidChangeNotification|NSComboBoxSelectionIsChangingNotification|NSComboBoxSelectionDidChangeNotification|NSComboBoxWillDismissNotification|NSComboBoxWillPopUpNotification|NSClassDescriptionNeededForClassNotification|NSToolbarDidRemoveItemNotification|NSToolbarWillAddItemNotification|NSTextStorageDidProcessEditingNotification|NSTextStorageWillProcessEditingNotification|NSTextDidBeginEditingNotification|NSTextDidChangeNotification|NSTextDidEndEditingNotification|NSTextViewDidChangeSelectionNotification|NSTextViewDidChangeTypingAttributesNotification|NSTextViewWillChangeNotifyingTextViewNotification|NSTableViewSelectionIsChangingNotification|NSTableViewSelectionDidChangeNotification|NSTableViewColumnDidResizeNotification|NSTableViewColumnDidMoveNotification|NSImageRepRegistryDidChangeNotification|NSOutlineViewSelectionIsChangingNotification|NSOutlineViewSelectionDidChangeNotification|NSOutlineViewColumnDidResizeNotification|NSOutlineViewColumnDidMoveNotification|NSOutlineViewItemDidCollapseNotification|NSOutlineViewItemDidExpandNotification|NSOutlineViewItemWillCollapseNotification|NSOutlineViewItemWillExpandNotification|NSDrawerDidCloseNotification|NSDrawerDidOpenNotification|NSDrawerWillCloseNotification|NSDrawerWillOpenNotification|NSPopUpButtonCellWillPopUpNotification|NSPopUpButtonWillPopUpNotification|NSViewGlobalFrameDidChangeNotification|NSViewBoundsDidChangeNotification|NSViewFocusDidChangeNotification|NSViewFrameDidChangeNotification|NSFontSetChangedNotification|NSWindowDidResizeNotification|NSWindowDidResignMainNotification|NSWindowDidResignKeyNotification|NSWindowDidMiniaturizeNotification|NSWindowDidMoveNotification|NSWindowDidBecomeMainNotification|NSWindowDidBecomeKeyNotification|NSWindowDidChangeScreenNotification|NSWindowDidChangeScreenProfileNotification|NSWindowDidDeminiaturizeNotification|NSWindowDidUpdateNotification|NSWindowDidEndSheetNotification|NSWindowDidExposeNotification|NSWindowWillMiniaturizeNotification|NSWindowWillMoveNotification|NSWindowWillBeginSheetNotification|NSWindowWillCloseNotification|NSWorkspaceSessionDidResignActiveNotification|NSWorkspaceSessionDidBecomeActiveNotification|NSWorkspaceDidMountNotification|NSWorkspaceDidTerminateApplicationNotification|NSWorkspaceDidUnmountNotification|NSWorkspaceDidPerformFileOperationNotification|NSWorkspaceDidWakeNotification|NSWorkspaceDidLaunchApplicationNotification|NSWorkspaceWillSleepNotification|NSWorkspaceWillUnmountNotification|NSWorkspaceWillPowerOffNotification|NSWorkspaceWillLaunchApplicationNotification|NSAntialiasThresholdChangedNotification|NSApplicationDidResignActiveNotification|NSApplicationDidBecomeActiveNotification|NSApplicationDidHideNotification|NSApplicationDidChangeScreenParametersNotification|NSApplicationDidUnhideNotification|NSApplicationDidUpdateNotification|NSApplicationDidFinishLaunchingNotification|NSApplicationWillResignActiveNotification|NSApplicationWillBecomeActiveNotification|NSApplicationWillHideNotification|NSApplicationWillTerminateNotification|NSApplicationWillUnhideNotification|NSApplicationWillUpdateNotification|NSApplicationWillFinishLaunchingNotification|NSAppleEventManagerWillProcessFirstEventNotification\",\n        \"support.constant.cocoa.leopard\": \"NSRuleEditorRowTypeSimple|NSRuleEditorRowTypeCompound|NSRuleEditorNestingModeSingle|NSRuleEditorNestingModeSimple|NSRuleEditorNestingModeCompound|NSRuleEditorNestingModeList|NSGradientDrawsBeforeStartingLocation|NSGradientDrawsAfterEndingLocation|NSMinusSetExpressionType|NSMachPortDeallocateReceiveRight|NSMachPortDeallocateSendRight|NSMachPortDeallocateNone|NSMapTableStrongMemory|NSMapTableCopyIn|NSMapTableZeroingWeakMemory|NSMapTableObjectPointerPersonality|NSBoxCustom|NSBundleExecutableArchitectureX86|NSBundleExecutableArchitectureI386|NSBundleExecutableArchitecturePPC|NSBundleExecutableArchitecturePPC64|NSBetweenPredicateOperatorType|NSBackgroundStyleRaised|NSBackgroundStyleDark|NSBackgroundStyleLight|NSBackgroundStyleLowered|NSStringDrawingTruncatesLastVisibleLine|NSStringEncodingConversionExternalRepresentation|NSStringEncodingConversionAllowLossy|NSSubqueryExpressionType|NSSpeechSentenceBoundary|NSSpeechImmediateBoundary|NSSpeechWordBoundary|NSSpellingStateGrammarFlag|NSSpellingStateSpellingFlag|NSSplitViewDividerStyleThin|NSSplitViewDividerStyleThick|NSServiceRequestTimedOutError|NSServiceMiscellaneousError|NSServiceMalformedServiceDictionaryError|NSServiceInvalidPasteboardDataError|NSServiceErrorMinimum|NSServiceErrorMaximum|NSServiceApplicationNotFoundError|NSServiceApplicationLaunchFailedError|NSSegmentStyleRoundRect|NSSegmentStyleRounded|NSSegmentStyleSmallSquare|NSSegmentStyleCapsule|NSSegmentStyleTexturedRounded|NSSegmentStyleTexturedSquare|NSSegmentStyleAutomatic|NSHUDWindowMask|NSHashTableStrongMemory|NSHashTableCopyIn|NSHashTableZeroingWeakMemory|NSHashTableObjectPointerPersonality|NSNoModeColorPanel|NSNetServiceNoAutoRename|NSChangeRedone|NSContainsPredicateOperatorType|NSColorRenderingIntentRelativeColorimetric|NSColorRenderingIntentSaturation|NSColorRenderingIntentDefault|NSColorRenderingIntentPerceptual|NSColorRenderingIntentAbsoluteColorimetric|NSCollectorDisabledOption|NSCellHitNone|NSCellHitContentArea|NSCellHitTrackableArea|NSCellHitEditableTextArea|NSTimeZoneNameStyleShortStandard|NSTimeZoneNameStyleShortDaylightSaving|NSTimeZoneNameStyleStandard|NSTimeZoneNameStyleDaylightSaving|NSTextFieldDatePickerStyle|NSTableViewSelectionHighlightStyleRegular|NSTableViewSelectionHighlightStyleSourceList|NSTrackingMouseMoved|NSTrackingMouseEnteredAndExited|NSTrackingCursorUpdate|NSTrackingInVisibleRect|NSTrackingEnabledDuringMouseDrag|NSTrackingAssumeInside|NSTrackingActiveInKeyWindow|NSTrackingActiveInActiveApp|NSTrackingActiveWhenFirstResponder|NSTrackingActiveAlways|NSIntersectSetExpressionType|NSIndexedColorSpaceModel|NSImageScaleNone|NSImageScaleProportionallyDown|NSImageScaleProportionallyUpOrDown|NSImageScaleAxesIndependently|NSOpenGLPFAAllowOfflineRenderers|NSOperationQueueDefaultMaxConcurrentOperationCount|NSOperationQueuePriorityHigh|NSOperationQueuePriorityNormal|NSOperationQueuePriorityVeryHigh|NSOperationQueuePriorityVeryLow|NSOperationQueuePriorityLow|NSDiacriticInsensitiveSearch|NSDownloadsDirectory|NSUnionSetExpressionType|NSUTF16BigEndianStringEncoding|NSUTF16StringEncoding|NSUTF16LittleEndianStringEncoding|NSUTF32BigEndianStringEncoding|NSUTF32StringEncoding|NSUTF32LittleEndianStringEncoding|NSPointerFunctionsMachVirtualMemory|NSPointerFunctionsMallocMemory|NSPointerFunctionsStrongMemory|NSPointerFunctionsStructPersonality|NSPointerFunctionsCStringPersonality|NSPointerFunctionsCopyIn|NSPointerFunctionsIntegerPersonality|NSPointerFunctionsZeroingWeakMemory|NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality|NSPointerFunctionsObjectPointerPersonality|NSPointerFunctionsObjectPersonality|NSPathStyleStandard|NSPathStyleNavigationBar|NSPathStylePopUp|NSPatternColorSpaceModel|NSPrintPanelShowsScaling|NSPrintPanelShowsCopies|NSPrintPanelShowsOrientation|NSPrintPanelShowsPaperSize|NSPrintPanelShowsPageRange|NSPrintPanelShowsPageSetupAccessory|NSPrintPanelShowsPreview|NSExecutableRuntimeMismatchError|NSExecutableNotLoadableError|NSExecutableErrorMinimum|NSExecutableErrorMaximum|NSExecutableLinkError|NSExecutableLoadError|NSExecutableArchitectureMismatchError|NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionPrior|NSFindPanelSubstringMatchTypeStartsWith|NSFindPanelSubstringMatchTypeContains|NSFindPanelSubstringMatchTypeEndsWith|NSFindPanelSubstringMatchTypeFullWord|NSFileReadTooLargeError|NSFileReadUnknownStringEncodingError|NSForcedOrderingSearch|NSWindowBackingLocationMainMemory|NSWindowBackingLocationDefault|NSWindowBackingLocationVideoMemory|NSWindowSharingReadOnly|NSWindowSharingReadWrite|NSWindowSharingNone|NSWindowCollectionBehaviorMoveToActiveSpace|NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorDefault|NSWidthInsensitiveSearch|NSAggregateExpressionType\"\n    };\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var escapedConstRe = \"\\\\\\\\(?:[abefnrtv'\\\"?\\\\\\\\]|\" + \n                         \"[0-3]\\\\d{1,2}|\" +\n                         \"[4-7]\\\\d?|\" +\n                         \"222|\" +\n                         \"x[a-zA-Z0-9]+)\";\n\n    var specialVariables = [{\n            regex: \"\\\\b_cmd\\\\b\",\n            token: \"variable.other.selector.objc\"\n        }, {\n            regex: \"\\\\b(?:self|super)\\\\b\",\n            token: \"variable.language.objc\"\n        }\n    ];\n\n    var cObj = new CHighlightRules(NSKeywords);\n    var cRules = cObj.getRules();\n    this.$keywordList = cObj.$keywordList;\n\n    this.$rules = {\n    \"start\": [ \n        {\n            token : \"comment\",\n            regex : \"\\\\/\\\\/.*$\"\n        },\n        DocCommentHighlightRules.getStartRule(\"doc-start\"),\n        {\n            token : \"comment\", // multi line comment\n            regex : \"\\\\/\\\\*\",\n            next : \"comment\"\n        }, \n        {\n            token: [ \"storage.type.objc\", \"punctuation.definition.storage.type.objc\", \n                       \"entity.name.type.objc\", \"text\", \"entity.other.inherited-class.objc\"\n                     ],\n            regex: \"(@)(interface|protocol)(?!.+;)(\\\\s+[A-Za-z_][A-Za-z0-9_]*)(\\\\s*:\\\\s*)([A-Za-z]+)\"\n        },\n        {\n            token: [ \"storage.type.objc\" ],\n            regex: \"(@end)\"\n        },\n        {\n            token: [ \"storage.type.objc\", \"entity.name.type.objc\", \n                        \"entity.other.inherited-class.objc\"\n                     ],\n            regex: \"(@implementation)(\\\\s+[A-Za-z_][A-Za-z0-9_]*)(\\\\s*?::\\\\s*(?:[A-Za-z][A-Za-z0-9]*))?\"\n        },\n        {\n            token: \"string.begin.objc\",\n            regex: '@\"',\n            next: \"constant_NSString\"\n        },\n        {\n            token: \"storage.type.objc\",\n            regex: \"\\\\bid\\\\s*<\",\n            next: \"protocol_list\"\n        },\n        {\n            token: \"keyword.control.macro.objc\",\n            regex: \"\\\\bNS_DURING|NS_HANDLER|NS_ENDHANDLER\\\\b\"\n        },\n        {\n            token: [\"punctuation.definition.keyword.objc\", \"keyword.control.exception.objc\"],\n            regex: \"(@)(try|catch|finally|throw)\\\\b\"\n        },\n        {\n            token: [\"punctuation.definition.keyword.objc\", \"keyword.other.objc\"],\n            regex: \"(@)(defs|encode)\\\\b\"\n        },\n        {\n            token: [\"storage.type.id.objc\", \"text\"],\n            regex: \"(\\\\bid\\\\b)(\\\\s|\\\\n)?\"\n        },\n        {\n            token: \"storage.type.objc\",\n            regex: \"\\\\bIBOutlet|IBAction|BOOL|SEL|id|unichar|IMP|Class\\\\b\"\n        },\n        {\n            token: [ \"punctuation.definition.storage.type.objc\", \"storage.type.objc\"],\n            regex: \"(@)(class|protocol)\\\\b\"\n        },\n        {\n            token: [ \"punctuation.definition.storage.type.objc\", \"punctuation\"],\n            regex: \"(@selector)(\\\\s*\\\\()\",\n            next: \"selectors\"\n        },\n        {\n            token: [ \"punctuation.definition.storage.modifier.objc\", \"storage.modifier.objc\"],\n            regex: \"(@)(synchronized|public|private|protected|package)\\\\b\"\n        },\n        {\n            token: \"constant.language.objc\",\n            regex: \"\\\\bYES|NO|Nil|nil\\\\b\"\n        },\n        {\n            token:  \"support.variable.foundation\",\n            regex: \"\\\\bNSApp\\\\b\"\n        },\n\n        {\n            token : cObj.getKeywords(),\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        },\n        {\n            token: \"punctuation.section.scope.begin.objc\",\n            regex: \"\\\\[\",\n            next: \"bracketed_content\"\n        },\n        {\n            token: \"meta.function.objc\",\n            regex: \"^(?:-|\\\\+)\\\\s*\"\n        }\n    ],\n    \"constant_NSString\": [\n        {\n            token: \"constant.character.escape.objc\",\n            regex: escapedConstRe\n        },\n        {\n            token: \"invalid.illegal.unknown-escape.objc\",\n            regex: \"\\\\\\\\.\"\n        },\n        {\n            token: \"string\",\n            regex: '[^\"\\\\\\\\]+'\n        },\n        {\n            token: \"punctuation.definition.string.end\",\n            regex: \"\\\"\",\n            next: \"start\"\n        }\n    ],\n    \"protocol_list\": [\n        {\n            token: \"punctuation.section.scope.end.objc\",\n            regex: \">\",\n            next: \"start\"\n        },\n        {\n            token: \"support.other.protocol.objc\",\n            regex: \"\\bNS(?:GlyphStorage|M(?:utableCopying|enuItem)|C(?:hangeSpelling|o(?:ding|pying|lorPicking(?:Custom|Default)))|T(?:oolbarItemValidations|ext(?:Input|AttachmentCell))|I(?:nputServ(?:iceProvider|erMouseTracker)|gnoreMisspelledWords)|Obj(?:CTypeSerializationCallBack|ect)|D(?:ecimalNumberBehaviors|raggingInfo)|U(?:serInterfaceValidations|RL(?:HandleClient|DownloadDelegate|ProtocolClient|AuthenticationChallengeSender))|Validated(?:ToobarItem|UserInterfaceItem)|Locking)\\b\"\n        }\n    ],\n    \"selectors\": [\n        {\n            token: \"support.function.any-method.name-of-parameter.objc\",\n            regex: \"\\\\b(?:[a-zA-Z_:][\\\\w]*)+\"\n        },\n        {\n            token: \"punctuation\",\n            regex: \"\\\\)\",\n            next: \"start\"\n        }\n    ],\n    \"bracketed_content\": [\n        {\n            token: \"punctuation.section.scope.end.objc\",\n            regex: \"]\",\n            next: \"start\"\n        },\n        {\n            token: [\"support.function.any-method.objc\"],\n            regex: \"(?:predicateWithFormat:| NSPredicate predicateWithFormat:)\",\n            next: \"start\"\n        },\n        {\n            token: \"support.function.any-method.objc\",\n            regex: \"\\\\w+(?::|(?=]))\",\n            next: \"start\"\n        }\n    ],\n    \"bracketed_strings\": [\n        {\n            token: \"punctuation.section.scope.end.objc\",\n            regex: \"]\",\n            next: \"start\"\n        },\n        {\n            token: \"keyword.operator.logical.predicate.cocoa\",\n            regex: \"\\\\b(?:AND|OR|NOT|IN)\\\\b\"\n        },\n        {\n            token: [\"invalid.illegal.unknown-method.objc\", \"punctuation.separator.arguments.objc\"],\n            regex: \"\\\\b(\\\\w+)(:)\"\n        },\n        {\n            regex: \"\\\\b(?:ALL|ANY|SOME|NONE)\\\\b\",\n            token: \"constant.language.predicate.cocoa\"\n        },\n        {\n            regex: \"\\\\b(?:NULL|NIL|SELF|TRUE|YES|FALSE|NO|FIRST|LAST|SIZE)\\\\b\",\n            token: \"constant.language.predicate.cocoa\"\n        },\n        {\n            regex: \"\\\\b(?:MATCHES|CONTAINS|BEGINSWITH|ENDSWITH|BETWEEN)\\\\b\",\n            token: \"keyword.operator.comparison.predicate.cocoa\"\n        },\n        {\n            regex: \"\\\\bC(?:ASEINSENSITIVE|I)\\\\b\",\n            token: \"keyword.other.modifier.predicate.cocoa\"\n        },\n        {\n            regex: \"\\\\b(?:ANYKEY|SUBQUERY|CAST|TRUEPREDICATE|FALSEPREDICATE)\\\\b\",\n            token: \"keyword.other.predicate.cocoa\"\n        },\n        {\n            regex: escapedConstRe,\n            token: \"constant.character.escape.objc\"\n        },\n        {\n            regex: \"\\\\\\\\.\",\n            token: \"invalid.illegal.unknown-escape.objc\"\n        },\n        {\n            token: \"string\",\n            regex: '[^\"\\\\\\\\]'\n        },\n        {\n            token: \"punctuation.definition.string.end.objc\",\n            regex: \"\\\"\",\n            next: \"predicates\"\n        }\n    ],\n    \"comment\" : [\n        {\n            token : \"comment\", // closing comment\n            regex : \".*?\\\\*\\\\/\",\n            next : \"start\"\n        }, {\n            defaultToken : \"comment\"\n        }\n    ],\n    \"methods\" : [\n        {\n            token : \"meta.function.objc\",\n            regex : \"(?=\\\\{|#)|;\",\n            next : \"start\"\n        }\n    ]\n};\n\n    // copy in C-Rules directly\n    for (var r in cRules) {\n        if (this.$rules[r]) {\n            if (this.$rules[r].push)\n                this.$rules[r].push.apply(this.$rules[r], cRules[r]);\n        } else {\n            this.$rules[r] = cRules[r];\n        }\n    }\n    \n    this.$rules.bracketed_content = this.$rules.bracketed_content.concat(\n        this.$rules.start, specialVariables\n    );\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(ObjectiveCHighlightRules, CHighlightRules);\n\nexports.ObjectiveCHighlightRules = ObjectiveCHighlightRules;\n"
  },
  {
    "path": "src/mode/ocaml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar OcamlHighlightRules = require(\"./ocaml_highlight_rules\").OcamlHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = OcamlHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n    \n    this.$outdent   = new MatchingBraceOutdent();\n};\noop.inherits(Mode, TextMode);\n\nvar indenter = /(?:[({[=:]|[-=]>|\\b(?:else|try|with))\\s*$/;\n\n(function() {\n\n    this.toggleCommentLines = function(state, doc, startRow, endRow) {\n        var i, line;\n        var outdent = true;\n        var re = /^\\s*\\(\\*(.*)\\*\\)/;\n\n        for (i=startRow; i<= endRow; i++) {\n            if (!re.test(doc.getLine(i))) {\n                outdent = false;\n                break;\n            }\n        }\n\n        var range = new Range(0, 0, 0, 0);\n        for (i=startRow; i<= endRow; i++) {\n            line = doc.getLine(i);\n            range.start.row  = i;\n            range.end.row    = i;\n            range.end.column = line.length;\n\n            doc.replace(range, outdent ? line.match(re)[1] : \"(*\" + line + \"*)\");\n        }\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n\n        if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&\n            state === 'start' && indenter.test(line))\n            indent += tab;\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/ocaml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ocaml_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar OcamlHighlightRules = function() {\n\n    var keywords = (\n        \"and|as|assert|begin|class|constraint|do|done|downto|else|end|\"  +\n        \"exception|external|for|fun|function|functor|if|in|include|\"     +\n        \"inherit|initializer|lazy|let|match|method|module|mutable|new|\"  +\n        \"object|of|open|or|private|rec|sig|struct|then|to|try|type|val|\" +\n        \"virtual|when|while|with\"\n    );\n\n    var builtinConstants = (\"true|false\");\n\n    var builtinFunctions = (\n        \"abs|abs_big_int|abs_float|abs_num|abstract_tag|accept|access|acos|add|\" +\n        \"add_available_units|add_big_int|add_buffer|add_channel|add_char|\" +\n        \"add_initializer|add_int_big_int|add_interfaces|add_num|add_string|\" +\n        \"add_substitute|add_substring|alarm|allocated_bytes|allow_only|\" +\n        \"allow_unsafe_modules|always|append|appname_get|appname_set|\" +\n        \"approx_num_exp|approx_num_fix|arg|argv|arith_status|array|\" +\n        \"array1_of_genarray|array2_of_genarray|array3_of_genarray|asin|asr|\" +\n        \"assoc|assq|at_exit|atan|atan2|auto_synchronize|background|basename|\" +\n        \"beginning_of_input|big_int_of_int|big_int_of_num|big_int_of_string|bind|\" +\n        \"bind_class|bind_tag|bits|bits_of_float|black|blit|blit_image|blue|bool|\" +\n        \"bool_of_string|bounded_full_split|bounded_split|bounded_split_delim|\" +\n        \"bprintf|break|broadcast|bscanf|button_down|c_layout|capitalize|cardinal|\" +\n        \"cardinal|catch|catch_break|ceil|ceiling_num|channel|char|char_of_int|\" +\n        \"chdir|check|check_suffix|chmod|choose|chop_extension|chop_suffix|chown|\" +\n        \"chown|chr|chroot|classify_float|clear|clear_available_units|\" +\n        \"clear_close_on_exec|clear_graph|clear_nonblock|clear_parser|\" +\n        \"close|close|closeTk|close_box|close_graph|close_in|close_in_noerr|\" +\n        \"close_out|close_out_noerr|close_process|close_process|\" +\n        \"close_process_full|close_process_in|close_process_out|close_subwindow|\" +\n        \"close_tag|close_tbox|closedir|closedir|closure_tag|code|combine|\" +\n        \"combine|combine|command|compact|compare|compare_big_int|compare_num|\" +\n        \"complex32|complex64|concat|conj|connect|contains|contains_from|contents|\" +\n        \"copy|cos|cosh|count|count|counters|create|create_alarm|create_image|\" +\n        \"create_matrix|create_matrix|create_matrix|create_object|\" +\n        \"create_object_and_run_initializers|create_object_opt|create_process|\" +\n        \"create_process|create_process_env|create_process_env|create_table|\" +\n        \"current|current_dir_name|current_point|current_x|current_y|curveto|\" +\n        \"custom_tag|cyan|data_size|decr|decr_num|default_available_units|delay|\" +\n        \"delete_alarm|descr_of_in_channel|descr_of_out_channel|destroy|diff|dim|\" +\n        \"dim1|dim2|dim3|dims|dirname|display_mode|div|div_big_int|div_num|\" +\n        \"double_array_tag|double_tag|draw_arc|draw_char|draw_circle|draw_ellipse|\" +\n        \"draw_image|draw_poly|draw_poly_line|draw_rect|draw_segments|draw_string|\" +\n        \"dummy_pos|dummy_table|dump_image|dup|dup2|elements|empty|end_of_input|\" +\n        \"environment|eprintf|epsilon_float|eq_big_int|eq_num|equal|err_formatter|\" +\n        \"error_message|escaped|establish_server|executable_name|execv|execve|execvp|\" +\n        \"execvpe|exists|exists2|exit|exp|failwith|fast_sort|fchmod|fchown|field|\" +\n        \"file|file_exists|fill|fill_arc|fill_circle|fill_ellipse|fill_poly|fill_rect|\" +\n        \"filter|final_tag|finalise|find|find_all|first_chars|firstkey|flatten|\" +\n        \"float|float32|float64|float_of_big_int|float_of_bits|float_of_int|\" +\n        \"float_of_num|float_of_string|floor|floor_num|flush|flush_all|flush_input|\" +\n        \"flush_str_formatter|fold|fold_left|fold_left2|fold_right|fold_right2|\" +\n        \"for_all|for_all2|force|force_newline|force_val|foreground|fork|\" +\n        \"format_of_string|formatter_of_buffer|formatter_of_out_channel|\" +\n        \"fortran_layout|forward_tag|fprintf|frexp|from|from_channel|from_file|\" +\n        \"from_file_bin|from_function|from_string|fscanf|fst|fstat|ftruncate|\" +\n        \"full_init|full_major|full_split|gcd_big_int|ge_big_int|ge_num|\" +\n        \"genarray_of_array1|genarray_of_array2|genarray_of_array3|get|\" +\n        \"get_all_formatter_output_functions|get_approx_printing|get_copy|\" +\n        \"get_ellipsis_text|get_error_when_null_denominator|get_floating_precision|\" +\n        \"get_formatter_output_functions|get_formatter_tag_functions|get_image|\" +\n        \"get_margin|get_mark_tags|get_max_boxes|get_max_indent|get_method|\" +\n        \"get_method_label|get_normalize_ratio|get_normalize_ratio_when_printing|\" +\n        \"get_print_tags|get_state|get_variable|getcwd|getegid|getegid|getenv|\" +\n        \"getenv|getenv|geteuid|geteuid|getgid|getgid|getgrgid|getgrgid|getgrnam|\" +\n        \"getgrnam|getgroups|gethostbyaddr|gethostbyname|gethostname|getitimer|\" +\n        \"getlogin|getpeername|getpid|getppid|getprotobyname|getprotobynumber|\" +\n        \"getpwnam|getpwuid|getservbyname|getservbyport|getsockname|getsockopt|\" +\n        \"getsockopt_float|getsockopt_int|getsockopt_optint|gettimeofday|getuid|\" +\n        \"global_replace|global_substitute|gmtime|green|grid|group_beginning|\" +\n        \"group_end|gt_big_int|gt_num|guard|handle_unix_error|hash|hash_param|\" +\n        \"hd|header_size|i|id|ignore|in_channel_length|in_channel_of_descr|incr|\" +\n        \"incr_num|index|index_from|inet_addr_any|inet_addr_of_string|infinity|\" +\n        \"infix_tag|init|init_class|input|input_binary_int|input_byte|input_char|\" +\n        \"input_line|input_value|int|int16_signed|int16_unsigned|int32|int64|\" +\n        \"int8_signed|int8_unsigned|int_of_big_int|int_of_char|int_of_float|\" +\n        \"int_of_num|int_of_string|integer_num|inter|interactive|inv|invalid_arg|\" +\n        \"is_block|is_empty|is_implicit|is_int|is_int_big_int|is_integer_num|\" +\n        \"is_relative|iter|iter2|iteri|join|junk|key_pressed|kill|kind|kprintf|\" +\n        \"kscanf|land|last_chars|layout|lazy_from_fun|lazy_from_val|lazy_is_val|\" +\n        \"lazy_tag|ldexp|le_big_int|le_num|length|lexeme|lexeme_char|lexeme_end|\" +\n        \"lexeme_end_p|lexeme_start|lexeme_start_p|lineto|link|list|listen|lnot|\" +\n        \"loadfile|loadfile_private|localtime|lock|lockf|log|log10|logand|lognot|\" +\n        \"logor|logxor|lor|lower_window|lowercase|lseek|lsl|lsr|lstat|lt_big_int|\" +\n        \"lt_num|lxor|magenta|magic|mainLoop|major|major_slice|make|make_formatter|\" +\n        \"make_image|make_lexer|make_matrix|make_self_init|map|map2|map_file|mapi|\" +\n        \"marshal|match_beginning|match_end|matched_group|matched_string|max|\" +\n        \"max_array_length|max_big_int|max_elt|max_float|max_int|max_num|\" +\n        \"max_string_length|mem|mem_assoc|mem_assq|memq|merge|min|min_big_int|\" +\n        \"min_elt|min_float|min_int|min_num|minor|minus_big_int|minus_num|\" +\n        \"minus_one|mkdir|mkfifo|mktime|mod|mod_big_int|mod_float|mod_num|modf|\" +\n        \"mouse_pos|moveto|mul|mult_big_int|mult_int_big_int|mult_num|nan|narrow|\" +\n        \"nat_of_num|nativeint|neg|neg_infinity|new_block|new_channel|new_method|\" +\n        \"new_variable|next|nextkey|nice|nice|no_scan_tag|norm|norm2|not|npeek|\" +\n        \"nth|nth_dim|num_digits_big_int|num_dims|num_of_big_int|num_of_int|\" +\n        \"num_of_nat|num_of_ratio|num_of_string|O|obj|object_tag|ocaml_version|\" +\n        \"of_array|of_channel|of_float|of_int|of_int32|of_list|of_nativeint|\" +\n        \"of_string|one|openTk|open_box|open_connection|open_graph|open_hbox|\" +\n        \"open_hovbox|open_hvbox|open_in|open_in_bin|open_in_gen|open_out|\" +\n        \"open_out_bin|open_out_gen|open_process|open_process_full|open_process_in|\" +\n        \"open_process_out|open_subwindow|open_tag|open_tbox|open_temp_file|\" +\n        \"open_vbox|opendbm|opendir|openfile|or|os_type|out_channel_length|\" +\n        \"out_channel_of_descr|output|output_binary_int|output_buffer|output_byte|\" +\n        \"output_char|output_string|output_value|over_max_boxes|pack|params|\" +\n        \"parent_dir_name|parse|parse_argv|partition|pause|peek|pipe|pixels|\" +\n        \"place|plot|plots|point_color|polar|poll|pop|pos_in|pos_out|pow|\" +\n        \"power_big_int_positive_big_int|power_big_int_positive_int|\" +\n        \"power_int_positive_big_int|power_int_positive_int|power_num|\" +\n        \"pp_close_box|pp_close_tag|pp_close_tbox|pp_force_newline|\" +\n        \"pp_get_all_formatter_output_functions|pp_get_ellipsis_text|\" +\n        \"pp_get_formatter_output_functions|pp_get_formatter_tag_functions|\" +\n        \"pp_get_margin|pp_get_mark_tags|pp_get_max_boxes|pp_get_max_indent|\" +\n        \"pp_get_print_tags|pp_open_box|pp_open_hbox|pp_open_hovbox|pp_open_hvbox|\" +\n        \"pp_open_tag|pp_open_tbox|pp_open_vbox|pp_over_max_boxes|pp_print_as|\" +\n        \"pp_print_bool|pp_print_break|pp_print_char|pp_print_cut|pp_print_float|\" +\n        \"pp_print_flush|pp_print_if_newline|pp_print_int|pp_print_newline|\" +\n        \"pp_print_space|pp_print_string|pp_print_tab|pp_print_tbreak|\" +\n        \"pp_set_all_formatter_output_functions|pp_set_ellipsis_text|\" +\n        \"pp_set_formatter_out_channel|pp_set_formatter_output_functions|\" +\n        \"pp_set_formatter_tag_functions|pp_set_margin|pp_set_mark_tags|\" +\n        \"pp_set_max_boxes|pp_set_max_indent|pp_set_print_tags|pp_set_tab|\" +\n        \"pp_set_tags|pred|pred_big_int|pred_num|prerr_char|prerr_endline|\" +\n        \"prerr_float|prerr_int|prerr_newline|prerr_string|print|print_as|\" +\n        \"print_bool|print_break|print_char|print_cut|print_endline|print_float|\" +\n        \"print_flush|print_if_newline|print_int|print_newline|print_space|\" +\n        \"print_stat|print_string|print_tab|print_tbreak|printf|prohibit|\" +\n        \"public_method_label|push|putenv|quo_num|quomod_big_int|quote|raise|\" +\n        \"raise_window|ratio_of_num|rcontains_from|read|read_float|read_int|\" +\n        \"read_key|read_line|readdir|readdir|readlink|really_input|receive|recv|\" +\n        \"recvfrom|red|ref|regexp|regexp_case_fold|regexp_string|\" +\n        \"regexp_string_case_fold|register|register_exception|rem|remember_mode|\" +\n        \"remove|remove_assoc|remove_assq|rename|replace|replace_first|\" +\n        \"replace_matched|repr|reset|reshape|reshape_1|reshape_2|reshape_3|rev|\" +\n        \"rev_append|rev_map|rev_map2|rewinddir|rgb|rhs_end|rhs_end_pos|rhs_start|\" +\n        \"rhs_start_pos|rindex|rindex_from|rlineto|rmdir|rmoveto|round_num|\" +\n        \"run_initializers|run_initializers_opt|scanf|search_backward|\" +\n        \"search_forward|seek_in|seek_out|select|self|self_init|send|sendto|set|\" +\n        \"set_all_formatter_output_functions|set_approx_printing|\" +\n        \"set_binary_mode_in|set_binary_mode_out|set_close_on_exec|\" +\n        \"set_close_on_exec|set_color|set_ellipsis_text|\" +\n        \"set_error_when_null_denominator|set_field|set_floating_precision|\" +\n        \"set_font|set_formatter_out_channel|set_formatter_output_functions|\" +\n        \"set_formatter_tag_functions|set_line_width|set_margin|set_mark_tags|\" +\n        \"set_max_boxes|set_max_indent|set_method|set_nonblock|set_nonblock|\" +\n        \"set_normalize_ratio|set_normalize_ratio_when_printing|set_print_tags|\" +\n        \"set_signal|set_state|set_tab|set_tag|set_tags|set_text_size|\" +\n        \"set_window_title|setgid|setgid|setitimer|setitimer|setsid|setsid|\" +\n        \"setsockopt|setsockopt|setsockopt_float|setsockopt_float|setsockopt_int|\" +\n        \"setsockopt_int|setsockopt_optint|setsockopt_optint|setuid|setuid|\" +\n        \"shift_left|shift_left|shift_left|shift_right|shift_right|shift_right|\" +\n        \"shift_right_logical|shift_right_logical|shift_right_logical|show_buckets|\" +\n        \"shutdown|shutdown|shutdown_connection|shutdown_connection|sigabrt|\" +\n        \"sigalrm|sigchld|sigcont|sigfpe|sighup|sigill|sigint|sigkill|sign_big_int|\" +\n        \"sign_num|signal|signal|sigpending|sigpending|sigpipe|sigprocmask|\" +\n        \"sigprocmask|sigprof|sigquit|sigsegv|sigstop|sigsuspend|sigsuspend|\" +\n        \"sigterm|sigtstp|sigttin|sigttou|sigusr1|sigusr2|sigvtalrm|sin|singleton|\" +\n        \"sinh|size|size|size_x|size_y|sleep|sleep|sleep|slice_left|slice_left|\" +\n        \"slice_left_1|slice_left_2|slice_right|slice_right|slice_right_1|\" +\n        \"slice_right_2|snd|socket|socket|socket|socketpair|socketpair|sort|sound|\" +\n        \"split|split_delim|sprintf|sprintf|sqrt|sqrt|sqrt_big_int|square_big_int|\" +\n        \"square_num|sscanf|stable_sort|stable_sort|stable_sort|stable_sort|stable_sort|\" +\n        \"stable_sort|stat|stat|stat|stat|stat|stats|stats|std_formatter|stdbuf|\" +\n        \"stderr|stderr|stderr|stdib|stdin|stdin|stdin|stdout|stdout|stdout|\" +\n        \"str_formatter|string|string_after|string_before|string_match|\" +\n        \"string_of_big_int|string_of_bool|string_of_float|string_of_format|\" +\n        \"string_of_inet_addr|string_of_inet_addr|string_of_int|string_of_num|\" +\n        \"string_partial_match|string_tag|sub|sub|sub_big_int|sub_left|sub_num|\" +\n        \"sub_right|subset|subset|substitute_first|substring|succ|succ|\" +\n        \"succ|succ|succ_big_int|succ_num|symbol_end|symbol_end_pos|symbol_start|\" +\n        \"symbol_start_pos|symlink|symlink|sync|synchronize|system|system|system|\" +\n        \"tag|take|tan|tanh|tcdrain|tcdrain|tcflow|tcflow|tcflush|tcflush|\" +\n        \"tcgetattr|tcgetattr|tcsendbreak|tcsendbreak|tcsetattr|tcsetattr|\" +\n        \"temp_file|text_size|time|time|time|timed_read|timed_write|times|times|\" +\n        \"tl|tl|tl|to_buffer|to_channel|to_float|to_hex|to_int|to_int32|to_list|\" +\n        \"to_list|to_list|to_nativeint|to_string|to_string|to_string|to_string|\" +\n        \"to_string|top|top|total_size|transfer|transp|truncate|truncate|truncate|\" +\n        \"truncate|truncate|truncate|try_lock|umask|umask|uncapitalize|uncapitalize|\" +\n        \"uncapitalize|union|union|unit_big_int|unlink|unlink|unlock|unmarshal|\" +\n        \"unsafe_blit|unsafe_fill|unsafe_get|unsafe_get|unsafe_set|unsafe_set|\" +\n        \"update|uppercase|uppercase|uppercase|uppercase|usage|utimes|utimes|wait|\" +\n        \"wait|wait|wait|wait_next_event|wait_pid|wait_read|wait_signal|\" +\n        \"wait_timed_read|wait_timed_write|wait_write|waitpid|white|\" +\n        \"widen|window_id|word_size|wrap|wrap_abort|write|yellow|yield|zero|zero_big_int|\" +\n\n        \"Arg|Arith_status|Array|Array1|Array2|Array3|ArrayLabels|Big_int|Bigarray|\" +\n        \"Buffer|Callback|CamlinternalOO|Char|Complex|Condition|Dbm|Digest|Dynlink|\" +\n        \"Event|Filename|Format|Gc|Genarray|Genlex|Graphics|GraphicsX11|Hashtbl|\" +\n        \"Int32|Int64|LargeFile|Lazy|Lexing|List|ListLabels|Make|Map|Marshal|\" +\n        \"MoreLabels|Mutex|Nativeint|Num|Obj|Oo|Parsing|Pervasives|Printexc|\" +\n        \"Printf|Queue|Random|Scanf|Scanning|Set|Sort|Stack|State|StdLabels|Str|\" +\n        \"Stream|String|StringLabels|Sys|Thread|ThreadUnix|Tk|Unix|UnixLabels|Weak\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants,\n        \"support.function\": builtinFunctions\n    }, \"identifier\");\n\n    var decimalInteger = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    var octInteger = \"(?:0[oO]?[0-7]+)\";\n    var hexInteger = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n    var binInteger = \"(?:0[bB][01]+)\";\n    var integer = \"(?:\" + decimalInteger + \"|\" + octInteger + \"|\" + hexInteger + \"|\" + binInteger + \")\";\n\n    var exponent = \"(?:[eE][+-]?\\\\d+)\";\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var exponentFloat = \"(?:(?:\" + pointFloat + \"|\" +  intPart + \")\" + exponent + \")\";\n    var floatNumber = \"(?:\" + exponentFloat + \"|\" + pointFloat + \")\";\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : '\\\\(\\\\*.*?\\\\*\\\\)\\\\s*?$'\n            },\n            {\n                token : \"comment\",\n                regex : '\\\\(\\\\*.*',\n                next : \"comment\"\n            },\n            {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            },\n            {\n                token : \"string\", // single char\n                regex : \"'.'\"\n            },\n            {\n                token : \"string\", // \" string\n                regex : '\"',\n                next  : \"qstring\"\n            },\n            {\n                token : \"constant.numeric\", // imaginary\n                regex : \"(?:\" + floatNumber + \"|\\\\d+)[jJ]\\\\b\"\n            },\n            {\n                token : \"constant.numeric\", // float\n                regex : floatNumber\n            },\n            {\n                token : \"constant.numeric\", // integer\n                regex : integer + \"\\\\b\"\n            },\n            {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            },\n            {\n                token : \"keyword.operator\",\n                regex : \"\\\\+\\\\.|\\\\-\\\\.|\\\\*\\\\.|\\\\/\\\\.|#|;;|\\\\+|\\\\-|\\\\*|\\\\*\\\\*\\\\/|\\\\/\\\\/|%|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|<-|=\"\n            },\n            {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            },\n            {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            },\n            {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\)\",\n                next : \"start\"\n            },\n            {\n                defaultToken : \"comment\"\n            }\n        ],\n\n        \"qstring\" : [\n            {\n                token : \"string\",\n                regex : '\"',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ]\n    };\n};\n\noop.inherits(OcamlHighlightRules, TextHighlightRules);\n\nexports.OcamlHighlightRules = OcamlHighlightRules;\n"
  },
  {
    "path": "src/mode/odin.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar OdinHighlightRules =\n  require(\"./odin_highlight_rules\").OdinHighlightRules;\nvar MatchingBraceOutdent =\n  require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n  this.HighlightRules = OdinHighlightRules;\n  this.$outdent = new MatchingBraceOutdent();\n  this.foldingRules = new CStyleFoldMode();\n  this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n  this.lineCommentStart = \"//\";\n  this.blockComment = { start: \"/*\", end: \"*/\" };\n\n  this.getNextLineIndent = function (state, line, tab) {\n    var indent = this.$getIndent(line);\n\n    var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n    var tokens = tokenizedLine.tokens;\n\n    if (tokens.length && tokens[tokens.length - 1].type == \"comment\") {\n      return indent;\n    }\n\n    if (state == \"start\") {\n      var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n      if (match) {\n        indent += tab;\n      }\n    }\n\n    return indent;\n  }; //end getNextLineIndent\n\n  this.checkOutdent = function (state, line, input) {\n    return this.$outdent.checkOutdent(line, input);\n  };\n\n  this.autoOutdent = function (state, doc, row) {\n    this.$outdent.autoOutdent(doc, row);\n  };\n\n  this.$id = \"ace/mode/odin\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/odin_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules =\n  require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar OdinHighlightRules = function () {\n  var keywords =\n    \"using|transmute|cast|distinct|opaque|where|\" +\n    \"struct|enum|union|bit_field|bit_set|\" +\n    \"if|when|else|do|switch|case|break|fallthrough|\" +\n    \"size_of|offset_of|type_info_if|typeid_of|type_of|align_of|\" +\n    \"or_return|or_else|inline|no_inline|\" +\n    \"import|package|foreign|defer|auto_cast|map|matrix|proc|\" +\n    \"for|continue|not_in|in\";\n\n  const cartesian = (...a) =>\n    a\n      .reduce((a, b) => a.flatMap((d) => b.map((e) => [d, e].flat())))\n      .map((parts) => parts.join(\"\"));\n\n  var builtinTypes = [\n    \"int\",\n    \"uint\",\n    \"uintptr\",\n    \"typeid\",\n    \"rawptr\",\n    \"string\",\n    \"cstring\",\n    \"i8\",\n    \"u8\",\n    \"any\",\n    \"byte\",\n    \"rune\",\n    \"bool\",\n    \"b8\",\n    \"b16\",\n    \"b32\",\n    \"b64\",\n    ...cartesian([\"i\", \"u\"], [\"16\", \"32\", \"64\", \"128\"], [\"\", \"le\", \"be\"]),\n    ...cartesian([\"f\"], [\"16\", \"32\", \"64\"], [\"\", \"le\", \"be\"]),\n    ...cartesian([\"complex\"], [\"32\", \"64\", \"128\"]),\n    ...cartesian([\"quaternion\"], [\"64\", \"128\", \"256\"])\n  ].join(\"|\");\n\n  var operators = [\n    \"\\\\*\",\n    \"/\",\n    \"%\",\n    \"%%\",\n    \"<<\",\n    \">>\",\n    \"&\",\n    \"&~\",\n    \"\\\\+\",\n    \"\\\\-\",\n    \"~\",\n    \"\\\\|\",\n    \">\",\n    \"<\",\n    \"<=\",\n    \">=\",\n    \"==\",\n    \"!=\"\n  ]\n    .concat(\":\")\n    .map((operator) => operator + \"=\")\n    .concat(\"=\", \":=\", \"::\", \"->\", \"\\\\^\", \"&\", \":\")\n    .join(\"|\");\n\n  var builtinFunctions = \"new|cap|copy|panic|len|make|delete|append|free\";\n  var builtinConstants = \"nil|true|false\";\n\n  var keywordMapper = this.createKeywordMapper(\n    {\n      keyword: keywords,\n      \"constant.language\": builtinConstants,\n      \"support.function\": builtinFunctions,\n      \"support.type\": builtinTypes\n    },\n    \"\"\n  );\n\n  var stringEscapeRe =\n    \"\\\\\\\\(?:[0-7]{3}|x\\\\h{2}|u{4}|U\\\\h{6}|[abfnrtv'\\\"\\\\\\\\])\".replace(\n      /\\\\h/g,\n      \"[a-fA-F\\\\d]\"\n    );\n\n  this.$rules = {\n    start: [\n      {\n        token: \"comment\",\n        regex: /\\/\\/.*$/\n      },\n      DocCommentHighlightRules.getStartRule(\"doc-start\"),\n      {\n        token: \"comment.start\", // multi line comment\n        regex: \"\\\\/\\\\*\",\n        next: \"comment\"\n      },\n      {\n        token: \"string\", // single line\n        regex: /\"(?:[^\"\\\\]|\\\\.)*?\"/\n      },\n      {\n        token: \"string\", // raw\n        regex: \"`\",\n        next: \"bqstring\"\n      },\n      {\n        token: \"support.constant\",\n        regex: /#[a-z_]+/\n      },\n      {\n        token: \"constant.numeric\", // rune\n        regex:\n          \"'(?:[^\\\\'\\uD800-\\uDBFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|\" +\n          stringEscapeRe.replace('\"', \"\") +\n          \")'\"\n      },\n      {\n        token: \"constant.numeric\", // hex\n        regex: \"0[xX][0-9a-fA-F]+\\\\b\"\n      },\n      {\n        token: \"constant.numeric\", // float\n        regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n      },\n      {\n        token: [\n          \"entity.name.function\",\n          \"text\",\n          \"keyword.operator\",\n          \"text\",\n          \"keyword\"\n        ],\n        regex: \"([a-zA-Z_$][a-zA-Z0-9_$]*)(\\\\s+)(::)(\\\\s+)(proc)\\\\b\"\n      },\n      {\n        token: function (val) {\n          if (val[val.length - 1] == \"(\") {\n            return [\n              {\n                type: keywordMapper(val.slice(0, -1)) || \"support.function\",\n                value: val.slice(0, -1)\n              },\n              {\n                type: \"paren.lparen\",\n                value: val.slice(-1)\n              }\n            ];\n          }\n\n          return keywordMapper(val) || \"identifier\";\n        },\n        regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\\\\(?\"\n      },\n      {\n        token: \"keyword.operator\",\n        regex: operators\n      },\n      {\n        token: \"punctuation.operator\",\n        regex: \"\\\\?|\\\\,|\\\\;|\\\\.\"\n      },\n      {\n        token: \"paren.lparen\",\n        regex: \"[[({]\"\n      },\n      {\n        token: \"paren.rparen\",\n        regex: \"[\\\\])}]\"\n      },\n      {\n        token: \"text\",\n        regex: \"\\\\s+\"\n      }\n    ],\n    comment: [\n      {\n        token: \"comment.end\",\n        regex: \"\\\\*\\\\/\",\n        next: \"start\"\n      },\n      {\n        defaultToken: \"comment\"\n      }\n    ],\n    bqstring: [\n      {\n        token: \"string\",\n        regex: \"`\",\n        next: \"start\"\n      },\n      {\n        defaultToken: \"string\"\n      }\n    ]\n  };\n\n  this.embedRules(DocCommentHighlightRules, \"doc-\", [\n    DocCommentHighlightRules.getEndRule(\"start\")\n  ]);\n};\noop.inherits(OdinHighlightRules, TextHighlightRules);\n\nexports.OdinHighlightRules = OdinHighlightRules;\n"
  },
  {
    "path": "src/mode/odin_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar OdinMode = require(\"./odin\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new OdinMode();\n    },\n\n    \"test: indent after opening function\": function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"main :: proc() {\", \"  \"));\n    },\n\n    \"test: indent after opening block\": function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"{\", \"  \"));\n    },\n\n    \"test: indent after opening array\": function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"foo := [\", \"  \"));\n    },\n\n    \"test: indent after opening parentheses\": function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"foo := (\", \"  \"));\n    },\n\n    \"test: indent after case:\": function() {\n        assert.equal(\"  \", this.mode.getNextLineIndent(\"start\", \"case bar:\", \"  \"));\n    },\n\n    \"test: auto outdent should indent the line with the same indent as the line with the matching opening brace\" : function() {\n        var session = new EditSession([\"  main :: proc() {\", \"    bla\", \"    }\"], this.mode);\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"  }\", session.getLine(2));\n    },\n\n    \"test: no auto outdent if no matching brace is found\" : function() {\n        var session = new EditSession([\"  main :: proc()\", \"    bla\", \"    }\"], this.mode);\n        this.mode.autoOutdent(\"start\", session, 2);\n        assert.equal(\"    }\", session.getLine(2));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/partiql.js",
    "content": "/*\n  THIS FILE WAS GENERATED BY 'ligand' USING 'mode.js'\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./partiql_highlight_rules\").PartiqlHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = HighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n\n    this.lineCommentStart = \"--\";\n    this.blockComment = {\n        start: \"/*\",\n        end: \"*/\",\n        nestable: true\n    };\n\n    this.getNextLineIndent = function (state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function (state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function (state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/partiql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/partiql_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS GENERATED BY 'ligand' USING 'mode_highlight_rules.js'\n*/\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var IonHighlightRules = require(\"./ion_highlight_rules\").IonHighlightRules;\n\n    var PartiqlHighlightRules = function() {\n        // constant.language.partiql\n        var k_partiql_constant =\n            \"MISSING\";\n        var k_sql_constant =\n            \"FALSE|NULL|TRUE\";\n        var k_constant = k_partiql_constant + \"|\" + k_sql_constant;\n\n        // keyword.other.partiql\n        var k_partiql_keyword =\n            \"PIVOT|UNPIVOT|LIMIT|TUPLE|REMOVE|INDEX|CONFLICT|DO|NOTHING|RETURNING|\"\n            +\"MODIFIED|NEW|OLD|LET\";\n        var k_sql_keyword =\n            \"ABSOLUTE|ACTION|ADD|ALL|ALLOCATE|ALTER|AND|ANY|ARE|AS|\"\n            +\"ASC|ASSERTION|AT|AUTHORIZATION|BEGIN|BETWEEN|BIT_LENGTH|BY|CASCADE|CASCADED|\"\n            +\"CASE|CATALOG|CHAR|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CLOSE|COLLATE|COLLATION|COLUMN|\"\n            +\"COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CROSS|\"\n            +\"CURRENT|CURSOR|DEALLOCATE|DEC|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESC|\"\n            +\"DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DISTINCT|DOMAIN|DROP|ELSE|END|END-EXEC|\"\n            +\"ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FETCH|FIRST|FOR|\"\n            +\"FOREIGN|FOUND|FROM|FULL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|\"\n            +\"HAVING|IDENTITY|IMMEDIATE|IN|INDICATOR|INITIALLY|INNER|INPUT|INSENSITIVE|INSERT|\"\n            +\"INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LANGUAGE|LAST|LEFT|\"\n            +\"LEVEL|LIKE|LOCAL|LOWER|MATCH|MODULE|NAMES|NATIONAL|NATURAL|NCHAR|\"\n            +\"NEXT|NO|NOT|OCTET_LENGTH|OF|ON|ONLY|OPEN|OPTION|OR|\"\n            +\"ORDER|OUTER|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|\"\n            +\"PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|\"\n            +\"REVOKE|RIGHT|ROLLBACK|ROWS|SCHEMA|SCROLL|SECTION|SELECT|SESSION|SET|\"\n            +\"SIZE|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|TABLE|TEMPORARY|THEN|\"\n            +\"TIME|TO|TRANSACTION|TRANSLATE|TRANSLATION|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|\"\n            +\"USAGE|USER|USING|VALUE|VALUES|VIEW|WHEN|WHENEVER|WHERE|WITH|\"\n            +\"WORK|WRITE|ZONE\";\n        var k_keyword = k_partiql_keyword + \"|\" + k_sql_keyword;\n\n        // storage.type.partiql\n        var k_partiql_type =\n            \"BOOL|BOOLEAN|STRING|SYMBOL|CLOB|BLOB|STRUCT|LIST|SEXP|BAG\";\n        var k_sql_type =\n            \"CHARACTER|DATE|DECIMAL|DOUBLE|FLOAT|INT|INTEGER|NUMERIC|SMALLINT|TIMESTAMP|\"\n            +\"VARCHAR|VARYING\";\n        var k_type = k_partiql_type + \"|\" + k_sql_type;\n\n        // support.function.aggregation.partiql\n        var k_sql_aggfn =\n            \"AVG|COUNT|MAX|MIN|SUM\";\n        var k_aggfn = k_sql_aggfn;\n\n        // support.function.partiql\n        var k_sql_fn =\n            \"CAST|COALESCE|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|EXISTS|DATE_ADD|DATE_DIFF|NULLIF|\"\n            +\"SESSION_USER|SUBSTRING|SYSTEM_USER|TRIM\";\n        var k_fn = k_sql_fn;\n\n\n        var keywordMapper = this.createKeywordMapper({\n            \"constant.language.partiql\": k_constant,\n            \"keyword.other.partiql\": k_keyword,\n            \"storage.type.partiql\": k_type,\n            \"support.function.aggregation.partiql\": k_aggfn,\n            \"support.function.partiql\": k_fn\n        }, \"variable.language.identifier.partiql\", true);\n\n        var keywordMapperRule = {\n            token : keywordMapper,\n            regex : \"\\\\b\\\\w+\\\\b\"\n        };\n\n        this.$rules = {\n          \"start\": [\n            {\n              \"include\": \"whitespace\"\n            },\n            {\n              \"include\": \"comment\"\n            },\n            {\n              \"include\": \"value\"\n            }\n          ],\n          \"value\": [\n            {\n              \"include\": \"whitespace\"\n            },\n            {\n              \"include\": \"comment\"\n            },\n            {\n              \"include\": \"tuple_value\"\n            },\n            {\n              \"include\": \"collection_value\"\n            },\n            {\n              \"include\": \"scalar_value\"\n            }\n          ],\n          \"scalar_value\": [\n            {\n              \"include\": \"string\"\n            },\n            {\n              \"include\": \"number\"\n            },\n            {\n              \"include\": \"keywords\"\n            },\n            {\n              \"include\": \"identifier\"\n            },\n            {\n              \"include\": \"embed-ion\"\n            },\n            {\n              \"include\": \"operator\"\n            },\n            {\n              \"include\": \"punctuation\"\n            }\n          ],\n          \"punctuation\": [\n            {\n              \"token\": \"punctuation.partiql\",\n              \"regex\": \"[;:()\\\\[\\\\]\\\\{\\\\},.]\"\n            }\n          ],\n          \"operator\": [\n            {\n              \"token\": \"keyword.operator.partiql\",\n              \"regex\": \"[+*/<>=~!@#%&|?^-]+\"\n            }\n          ],\n          \"identifier\": [\n            {\n              \"token\": \"variable.language.identifier.quoted.partiql\",\n              \"regex\": \"([\\\"])((?:(?:\\\\\\\\.)|(?:[^\\\"\\\\\\\\]))*?)([\\\"])\"\n            },\n            {\n              \"token\": \"variable.language.identifier.at.partiql\",\n              \"regex\": \"@\\\\w+\"\n            },\n            {\n              \"token\": \"variable.language.identifier.partiql\",\n              \"regex\": \"\\\\b\\\\w+(?:\\\\.\\\\w+)?\\\\b\"\n            }\n          ],\n          \"number\": [\n            {\n              \"token\": \"constant.numeric.partiql\",\n              \"regex\": \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }\n          ],\n          \"string\": [\n            {\n              \"token\": [\n                \"punctuation.definition.string.begin.partiql\",\n                \"string.quoted.single.partiql\",\n                \"punctuation.definition.string.end.partiql\"\n              ],\n              \"regex\": \"(['])((?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?)(['])\"\n            }\n          ],\n          \"collection_value\": [\n            {\n              \"include\": \"array_value\"\n            },\n            {\n              \"include\": \"bag_value\"\n            }\n          ],\n          \"bag_value\": [\n            {\n              \"token\": \"punctuation.definition.bag.begin.partiql\",\n              \"regex\": \"<<\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.bag.end.partiql\",\n                  \"regex\": \">>\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"token\": \"punctuation.definition.bag.separator.partiql\",\n                  \"regex\": \",\"\n                },\n                {\n                  \"include\": \"value\"\n                }\n              ]\n            }\n          ],\n          \"comment\": [\n            {\n              \"token\": \"comment.line.partiql\",\n              \"regex\": \"--.*\"\n            },\n            {\n              \"token\": \"comment.block.partiql\",\n              \"regex\": \"/\\\\*\",\n              \"push\": \"comment__1\"\n            }\n          ],\n          \"comment__1\": [\n            {\n              \"token\": \"comment.block.partiql\",\n              \"regex\": \"[*]/\",\n              \"next\": \"pop\"\n            },\n            {\n              \"token\": \"comment.block.partiql\",\n              \"regex\": \"[^*/]+\"\n            },\n            {\n              \"token\": \"comment.block.partiql\",\n              \"regex\": \"/\\\\*\",\n              \"push\": \"comment__1\"\n            },\n            {\n              \"token\": \"comment.block.partiql\",\n              \"regex\": \"[*/]+\"\n            }\n          ],\n          \"array_value\": [\n            {\n              \"token\": \"punctuation.definition.array.begin.partiql\",\n              \"regex\": \"\\\\[\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.array.end.partiql\",\n                  \"regex\": \"\\\\]\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"token\": \"punctuation.definition.array.separator.partiql\",\n                  \"regex\": \",\"\n                },\n                {\n                  \"include\": \"value\"\n                }\n              ]\n            }\n          ],\n          \"tuple_value\": [\n            {\n              \"token\": \"punctuation.definition.tuple.begin.partiql\",\n              \"regex\": \"\\\\{\",\n              \"push\": [\n                {\n                  \"token\": \"punctuation.definition.tuple.end.partiql\",\n                  \"regex\": \"\\\\}\",\n                  \"next\": \"pop\"\n                },\n                {\n                  \"include\": \"comment\"\n                },\n                {\n                  \"token\": \"punctuation.definition.tuple.separator.partiql\",\n                  \"regex\": \",|:\"\n                },\n                {\n                  \"include\": \"value\"\n                }\n              ]\n            }\n          ],\n          \"whitespace\": [\n            {\n              \"token\": \"text.partiql\",\n              \"regex\": \"\\\\s+\"\n            }\n          ]\n        } ;\n        this.$rules[\"keywords\"] = [keywordMapperRule];\n\n        this.$rules[\"embed-ion\"] = [{token : \"punctuation.definition.ion.begin.partiql\", regex : \"`\", next : \"ion-start\"}];\n        this.embedRules(IonHighlightRules, \"ion-\", [{token : \"punctuation.definition.ion.end.partiql\", regex : \"`\", next : \"start\"}]);\n\n        this.normalizeRules();\n    };\n\n    oop.inherits(PartiqlHighlightRules, TextHighlightRules);\n\n    exports.PartiqlHighlightRules = PartiqlHighlightRules;\n"
  },
  {
    "path": "src/mode/pascal.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PascalHighlightRules = require(\"./pascal_highlight_rules\").PascalHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PascalHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n       \n    this.lineCommentStart = [\"--\", \"//\"];\n    this.blockComment = [\n        {start: \"(*\", end: \"*)\"},\n        {start: \"{\", end: \"}\"}\n    ];\n    \n    this.$id = \"ace/mode/pascal\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/pascal_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PascalHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control\": \"absolute|abstract|all|and|and_then|array|as|asm|attribute|begin|bindable|case|class\" +\n            \"|const|constructor|destructor|div|do|do|else|end|except|export|exports|external|far|file|finalization\" +\n            \"|finally|for|forward|goto|if|implementation|import|in|inherited|initialization|interface|interrupt|is\" +\n            \"|label|library|mod|module|name|near|nil|not|object|of|only|operator|or|or_else|otherwise|packed|pow|private\" +\n            \"|program|property|protected|public|published|qualified|record|repeat|resident|restricted|segment|set|shl|shr\" +\n            \"|then|to|try|type|unit|until|uses|value|var|view|virtual|while|with|xor\"\n    }, \"identifier\", true);\n\n    this.$rules = {\n        start: [{\n                caseInsensitive: true,\n                token: ['variable', \"text\",\n                    'storage.type.prototype',\n                    'entity.name.function.prototype'\n                ],\n                regex: '\\\\b(function|procedure)(\\\\s+)(\\\\w+)(\\\\.\\\\w+)?(?=(?:\\\\(.*?\\\\))?;\\\\s*(?:attribute|forward|external))'\n            }, {\n                caseInsensitive: true,\n                token: ['variable', \"text\", 'storage.type.function', 'entity.name.function'],\n                regex: '\\\\b(function|procedure)(\\\\s+)(\\\\w+)(\\\\.\\\\w+)?'\n            }, {\n                caseInsensitive: true,\n                token: keywordMapper,\n                regex: /\\b[a-z_]+\\b/\n            }, {\n                token: 'constant.numeric',\n                regex: '\\\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\\\.?[0-9]*)|(\\\\.[0-9]+))((e|E)(\\\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b'\n            }, {\n                token: 'punctuation.definition.comment',\n                regex: '--.*$'\n            }, {\n                token: 'punctuation.definition.comment',\n                regex: '//.*$'\n            }, {\n                token: 'punctuation.definition.comment',\n                regex: '\\\\(\\\\*',\n                push: [{\n                        token: 'punctuation.definition.comment',\n                        regex: '\\\\*\\\\)',\n                        next: 'pop'\n                    },\n                    { defaultToken: 'comment.block.one' }\n                ]\n            }, {\n                token: 'punctuation.definition.comment',\n                regex: '\\\\{',\n                push: [{\n                        token: 'punctuation.definition.comment',\n                        regex: '\\\\}',\n                        next: 'pop'\n                    },\n                    { defaultToken: 'comment.block.two' }\n                ]\n            }, {\n                token: 'punctuation.definition.string.begin',\n                regex: '\"',\n                push: [{ token: 'constant.character.escape', regex: '\\\\\\\\.' },\n                    {\n                        token: 'punctuation.definition.string.end',\n                        regex: '\"',\n                        next: 'pop'\n                    },\n                    { defaultToken: 'string.quoted.double' }\n                ]\n                //Double quoted strings are an extension and (generally) support C-style escape sequences.\n            }, {\n                token: 'punctuation.definition.string.begin',\n                regex: '\\'',\n                push: [{\n                        token: 'constant.character.escape.apostrophe',\n                        regex: '\\'\\''\n                    },\n                    {\n                        token: 'punctuation.definition.string.end',\n                        regex: '\\'',\n                        next: 'pop'\n                    },\n                    { defaultToken: 'string.quoted.single' }\n                ]\n            }, {\n                token: 'keyword.operator',\n                regex: '[+\\\\-;,/*%]|:=|='\n            }\n        ]\n    };\n\n    this.normalizeRules();\n};\n\noop.inherits(PascalHighlightRules, TextHighlightRules);\n\nexports.PascalHighlightRules = PascalHighlightRules;\n"
  },
  {
    "path": "src/mode/perl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PerlHighlightRules = require(\"./perl_highlight_rules\").PerlHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PerlHighlightRules;\n    \n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new CStyleFoldMode({start: \"^=(begin|item)\\\\b\", end: \"^=(cut)\\\\b\"});\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n    this.blockComment = [\n        {start: \"=begin\", end: \"=cut\", lineStartOnly: true},\n        {start: \"=item\", end: \"=cut\", lineStartOnly: true}\n    ];\n\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/perl\";\n    this.snippetFileId = \"ace/snippets/perl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/perl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PerlHighlightRules = function() {\n\n    var keywords = (\n        \"base|constant|continue|else|elsif|for|foreach|format|goto|if|last|local|my|next|\" +\n         \"no|package|parent|redo|require|scalar|sub|unless|until|while|use|vars\"\n    );\n\n    var buildinConstants = (\"ARGV|ENV|INC|SIG\");\n\n    var builtinFunctions = (\n        \"getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|\" +\n         \"gethostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|\" +\n         \"getpeername|setpriority|getprotoent|setprotoent|getpriority|\" +\n         \"endprotoent|getservent|setservent|endservent|sethostent|socketpair|\" +\n         \"getsockopt|gethostent|endhostent|setsockopt|setnetent|quotemeta|\" +\n         \"localtime|prototype|getnetent|endnetent|rewinddir|wantarray|getpwuid|\" +\n         \"closedir|getlogin|readlink|endgrent|getgrgid|getgrnam|shmwrite|\" +\n         \"shutdown|readline|endpwent|setgrent|readpipe|formline|truncate|\" +\n         \"dbmclose|syswrite|setpwent|getpwnam|getgrent|getpwent|ucfirst|sysread|\" +\n         \"setpgrp|shmread|sysseek|sysopen|telldir|defined|opendir|connect|\" +\n         \"lcfirst|getppid|binmode|syscall|sprintf|getpgrp|readdir|seekdir|\" +\n         \"waitpid|reverse|unshift|symlink|dbmopen|semget|msgrcv|rename|listen|\" +\n         \"chroot|msgsnd|shmctl|accept|unpack|exists|fileno|shmget|system|\" +\n         \"unlink|printf|gmtime|msgctl|semctl|values|rindex|substr|splice|\" +\n         \"length|msgget|select|socket|return|caller|delete|alarm|ioctl|index|\" +\n         \"undef|lstat|times|srand|chown|fcntl|close|write|umask|rmdir|study|\" +\n         \"sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|chmod|\" +\n         \"BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|dump|\" +\n         \"join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|\" +\n         \"keys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|\" +\n         \"eof|chr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|\" +\n         \"map|die|uc|lc|do\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants,\n        \"support.function\": builtinFunctions\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment.doc\",\n                regex : \"^=(?:begin|item)\\\\b\",\n                next : \"block_comment\"\n            }, {\n                token : \"string.regexp\",\n                regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // multi line string start\n                regex : '[\"].*\\\\\\\\$',\n                next : \"qqstring\"\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"string\", // multi line string start\n                regex : \"['].*\\\\\\\\$\",\n                next : \"qstring\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0x[0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"%#|\\\\$#|\\\\.\\\\.\\\\.|\\\\|\\\\|=|>>=|<<=|<=>|&&=|=>|!~|\\\\^=|&=|\\\\|=|\\\\.=|x=|%=|\\\\/=|\\\\*=|\\\\-=|\\\\+=|=~|\\\\*\\\\*|\\\\-\\\\-|\\\\.\\\\.|\\\\|\\\\||&&|\\\\+\\\\+|\\\\->|!=|==|>=|<=|>>|<<|,|=|\\\\?\\\\:|\\\\^|\\\\||x|%|\\\\/|\\\\*|<|&|\\\\\\\\|~|!|>|\\\\.|\\\\-|\\\\+|\\\\-C|\\\\-b|\\\\-S|\\\\-u|\\\\-t|\\\\-p|\\\\-l|\\\\-d|\\\\-f|\\\\-g|\\\\-s|\\\\-z|\\\\-k|\\\\-e|\\\\-O|\\\\-T|\\\\-B|\\\\-M|\\\\-A|\\\\-X|\\\\-W|\\\\-c|\\\\-R|\\\\-o|\\\\-x|\\\\-w|\\\\-r|\\\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\"\n            }, {\n                token : \"comment\",\n                regex : \"#.*$\"\n            }, {\n                token : \"lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"string\",\n                regex : '(?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?\"',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"string\",\n                regex : \"(?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?'\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ],\n        \"block_comment\": [\n            {\n                token: \"comment.doc\", \n                regex: \"^=cut\\\\b\",\n                next: \"start\"\n            },\n            {\n                defaultToken: \"comment.doc\"\n            }\n        ]\n    };\n};\n\noop.inherits(PerlHighlightRules, TextHighlightRules);\n\nexports.PerlHighlightRules = PerlHighlightRules;\n"
  },
  {
    "path": "src/mode/pgsql.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"../mode/text\").Mode;\nvar PgsqlHighlightRules = require(\"./pgsql_highlight_rules\").PgsqlHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = PgsqlHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) { \n        if (state == \"start\" || state == \"keyword.statementEnd\") {\n            return \"\";\n        } else {\n            return this.$getIndent(line); // Keep whatever indent the previous line has\n        }\n    };\n\n    this.$id = \"ace/mode/pgsql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/pgsql_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n// Syntax highlighting for pl/languages and json.\nvar PerlHighlightRules = require(\"./perl_highlight_rules\").PerlHighlightRules;\nvar PythonHighlightRules = require(\"./python_highlight_rules\").PythonHighlightRules;\nvar JsonHighlightRules = require(\"./json_highlight_rules\").JsonHighlightRules;\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nvar PgsqlHighlightRules = function() {\n\n    // Keywords, functions, operators last updated for pg 9.3.\n    var keywords = (\n        \"abort|absolute|abstime|access|aclitem|action|add|admin|after|aggregate|all|also|alter|always|\" +\n        \"analyse|analyze|and|any|anyarray|anyelement|anyenum|anynonarray|anyrange|array|as|asc|\" +\n        \"assertion|assignment|asymmetric|at|attribute|authorization|backward|before|begin|between|\" +\n        \"bigint|binary|bit|bool|boolean|both|box|bpchar|by|bytea|cache|called|cascade|cascaded|case|cast|\" +\n        \"catalog|chain|char|character|characteristics|check|checkpoint|cid|cidr|circle|class|close|\" +\n        \"cluster|coalesce|collate|collation|column|comment|comments|commit|committed|concurrently|\" +\n        \"configuration|connection|constraint|constraints|content|continue|conversion|copy|cost|\" +\n        \"create|cross|cstring|csv|current|current_catalog|current_date|current_role|\" +\n        \"current_schema|current_time|current_timestamp|current_user|cursor|cycle|data|database|\" +\n        \"date|daterange|day|deallocate|dec|decimal|declare|default|defaults|deferrable|deferred|\" +\n        \"definer|delete|delimiter|delimiters|desc|dictionary|disable|discard|distinct|do|document|\" +\n        \"domain|double|drop|each|else|enable|encoding|encrypted|end|enum|escape|event|event_trigger|\" +\n        \"except|exclude|excluding|exclusive|execute|exists|explain|extension|external|extract|false|\" +\n        \"family|fdw_handler|fetch|first|float|float4|float8|following|for|force|foreign|forward|\" +\n        \"freeze|from|full|function|functions|global|grant|granted|greatest|group|gtsvector|handler|\" +\n        \"having|header|hold|hour|identity|if|ilike|immediate|immutable|implicit|in|including|\" +\n        \"increment|index|indexes|inet|inherit|inherits|initially|inline|inner|inout|input|\" +\n        \"insensitive|insert|instead|int|int2|int2vector|int4|int4range|int8|int8range|integer|\" +\n        \"internal|intersect|interval|into|invoker|is|isnull|isolation|join|json|key|label|language|\" +\n        \"language_handler|large|last|lateral|lc_collate|lc_ctype|leading|leakproof|least|left|level|\" +\n        \"like|limit|line|listen|load|local|localtime|localtimestamp|location|lock|lseg|macaddr|\" +\n        \"mapping|match|materialized|maxvalue|minute|minvalue|mode|money|month|move|name|names|\" +\n        \"national|natural|nchar|next|no|none|not|nothing|notify|notnull|nowait|null|nullif|nulls|\" +\n        \"numeric|numrange|object|of|off|offset|oid|oids|oidvector|on|only|opaque|operator|option|\" +\n        \"options|or|order|out|outer|over|overlaps|overlay|owned|owner|parser|partial|partition|passing|\" +\n        \"password|path|pg_attribute|pg_auth_members|pg_authid|pg_class|pg_database|pg_node_tree|\" +\n        \"pg_proc|pg_type|placing|plans|point|polygon|position|preceding|precision|prepare|prepared|\" +\n        \"preserve|primary|prior|privileges|procedural|procedure|program|quote|range|read|real|\" +\n        \"reassign|recheck|record|recursive|ref|refcursor|references|refresh|regclass|regconfig|\" +\n        \"regdictionary|regoper|regoperator|regproc|regprocedure|regtype|reindex|relative|release|\" +\n        \"reltime|rename|repeatable|replace|replica|reset|restart|restrict|returning|returns|revoke|\" +\n        \"right|role|rollback|row|rows|rule|savepoint|schema|scroll|search|second|security|select|\" +\n        \"sequence|sequences|serializable|server|session|session_user|set|setof|share|show|similar|\" +\n        \"simple|smallint|smgr|snapshot|some|stable|standalone|start|statement|statistics|stdin|\" +\n        \"stdout|storage|strict|strip|substring|symmetric|sysid|system|table|tables|tablespace|temp|\" +\n        \"template|temporary|text|then|tid|time|timestamp|timestamptz|timetz|tinterval|to|trailing|\" +\n        \"transaction|treat|trigger|trim|true|truncate|trusted|tsquery|tsrange|tstzrange|tsvector|\" +\n        \"txid_snapshot|type|types|unbounded|uncommitted|unencrypted|union|unique|unknown|unlisten|\" +\n        \"unlogged|until|update|user|using|uuid|vacuum|valid|validate|validator|value|values|varbit|\" +\n        \"varchar|variadic|varying|verbose|version|view|void|volatile|when|where|whitespace|window|\" +\n        \"with|without|work|wrapper|write|xid|xml|xmlattributes|xmlconcat|xmlelement|xmlexists|\" +\n        \"xmlforest|xmlparse|xmlpi|xmlroot|xmlserialize|year|yes|zone|ties\"\n    );\n\n\n    var builtinFunctions = (\n        \"RI_FKey_cascade_del|RI_FKey_cascade_upd|RI_FKey_check_ins|RI_FKey_check_upd|\" +\n        \"RI_FKey_noaction_del|RI_FKey_noaction_upd|RI_FKey_restrict_del|RI_FKey_restrict_upd|\" +\n        \"RI_FKey_setdefault_del|RI_FKey_setdefault_upd|RI_FKey_setnull_del|\" +\n        \"RI_FKey_setnull_upd|abbrev|abs|abstime|abstimeeq|abstimege|abstimegt|abstimein|abstimele|\" +\n        \"abstimelt|abstimene|abstimeout|abstimerecv|abstimesend|aclcontains|acldefault|\" +\n        \"aclexplode|aclinsert|aclitemeq|aclitemin|aclitemout|aclremove|acos|age|any_in|any_out|\" +\n        \"anyarray_in|anyarray_out|anyarray_recv|anyarray_send|anyelement_in|anyelement_out|\" +\n        \"anyenum_in|anyenum_out|anynonarray_in|anynonarray_out|anyrange_in|anyrange_out|\" +\n        \"anytextcat|area|areajoinsel|areasel|array_agg|array_agg_finalfn|array_agg_transfn|\" +\n        \"array_append|array_cat|array_dims|array_eq|array_fill|array_ge|array_gt|array_in|\" +\n        \"array_larger|array_le|array_length|array_lower|array_lt|array_ndims|array_ne|array_out|\" +\n        \"array_prepend|array_recv|array_remove|array_replace|array_send|array_smaller|\" +\n        \"array_to_json|array_to_string|array_typanalyze|array_upper|arraycontained|\" +\n        \"arraycontains|arraycontjoinsel|arraycontsel|arrayoverlap|ascii|ascii_to_mic|\" +\n        \"ascii_to_utf8|asin|atan|atan2|avg|big5_to_euc_tw|big5_to_mic|big5_to_utf8|bit_and|bit_in|\" +\n        \"bit_length|bit_or|bit_out|bit_recv|bit_send|bitand|bitcat|bitcmp|biteq|bitge|bitgt|bitle|\" +\n        \"bitlt|bitne|bitnot|bitor|bitshiftleft|bitshiftright|bittypmodin|bittypmodout|bitxor|bool|\" +\n        \"bool_and|bool_or|booland_statefunc|booleq|boolge|boolgt|boolin|boolle|boollt|boolne|\" +\n        \"boolor_statefunc|boolout|boolrecv|boolsend|box|box_above|box_above_eq|box_add|box_below|\" +\n        \"box_below_eq|box_center|box_contain|box_contain_pt|box_contained|box_distance|box_div|\" +\n        \"box_eq|box_ge|box_gt|box_in|box_intersect|box_le|box_left|box_lt|box_mul|box_out|\" +\n        \"box_overabove|box_overbelow|box_overlap|box_overleft|box_overright|box_recv|box_right|\" +\n        \"box_same|box_send|box_sub|bpchar_larger|bpchar_pattern_ge|bpchar_pattern_gt|\" +\n        \"bpchar_pattern_le|bpchar_pattern_lt|bpchar_smaller|bpcharcmp|bpchareq|bpcharge|\" +\n        \"bpchargt|bpchariclike|bpcharicnlike|bpcharicregexeq|bpcharicregexne|bpcharin|bpcharle|\" +\n        \"bpcharlike|bpcharlt|bpcharne|bpcharnlike|bpcharout|bpcharrecv|bpcharregexeq|\" +\n        \"bpcharregexne|bpcharsend|bpchartypmodin|bpchartypmodout|broadcast|btabstimecmp|\" +\n        \"btarraycmp|btbeginscan|btboolcmp|btbpchar_pattern_cmp|btbuild|btbuildempty|\" +\n        \"btbulkdelete|btcanreturn|btcharcmp|btcostestimate|btendscan|btfloat48cmp|btfloat4cmp|\" +\n        \"btfloat4sortsupport|btfloat84cmp|btfloat8cmp|btfloat8sortsupport|btgetbitmap|\" +\n        \"btgettuple|btinsert|btint24cmp|btint28cmp|btint2cmp|btint2sortsupport|btint42cmp|\" +\n        \"btint48cmp|btint4cmp|btint4sortsupport|btint82cmp|btint84cmp|btint8cmp|\" +\n        \"btint8sortsupport|btmarkpos|btnamecmp|btnamesortsupport|btoidcmp|btoidsortsupport|\" +\n        \"btoidvectorcmp|btoptions|btrecordcmp|btreltimecmp|btrescan|btrestrpos|btrim|\" +\n        \"bttext_pattern_cmp|bttextcmp|bttidcmp|bttintervalcmp|btvacuumcleanup|\" +\n        \"bytea_string_agg_finalfn|bytea_string_agg_transfn|byteacat|byteacmp|byteaeq|byteage|\" +\n        \"byteagt|byteain|byteale|bytealike|bytealt|byteane|byteanlike|byteaout|bytearecv|byteasend|\" +\n        \"cash_cmp|cash_div_cash|cash_div_flt4|cash_div_flt8|cash_div_int2|cash_div_int4|cash_eq|\" +\n        \"cash_ge|cash_gt|cash_in|cash_le|cash_lt|cash_mi|cash_mul_flt4|cash_mul_flt8|\" +\n        \"cash_mul_int2|cash_mul_int4|cash_ne|cash_out|cash_pl|cash_recv|cash_send|cash_words|\" +\n        \"cashlarger|cashsmaller|cbrt|ceil|ceiling|center|char|char_length|character_length|chareq|\" +\n        \"charge|chargt|charin|charle|charlt|charne|charout|charrecv|charsend|chr|cideq|cidin|cidout|\" +\n        \"cidr|cidr_in|cidr_out|cidr_recv|cidr_send|cidrecv|cidsend|circle|circle_above|\" +\n        \"circle_add_pt|circle_below|circle_center|circle_contain|circle_contain_pt|\" +\n        \"circle_contained|circle_distance|circle_div_pt|circle_eq|circle_ge|circle_gt|circle_in|\" +\n        \"circle_le|circle_left|circle_lt|circle_mul_pt|circle_ne|circle_out|circle_overabove|\" +\n        \"circle_overbelow|circle_overlap|circle_overleft|circle_overright|circle_recv|\" +\n        \"circle_right|circle_same|circle_send|circle_sub_pt|clock_timestamp|close_lb|close_ls|\" +\n        \"close_lseg|close_pb|close_pl|close_ps|close_sb|close_sl|col_description|concat|concat_ws|\" +\n        \"contjoinsel|contsel|convert|convert_from|convert_to|corr|cos|cot|count|covar_pop|\" +\n        \"covar_samp|cstring_in|cstring_out|cstring_recv|cstring_send|cume_dist|current_database|\" +\n        \"current_query|current_schema|current_schemas|current_setting|current_user|currtid|\" +\n        \"currtid2|currval|cursor_to_xml|cursor_to_xmlschema|database_to_xml|\" +\n        \"database_to_xml_and_xmlschema|database_to_xmlschema|date|date_cmp|date_cmp_timestamp|\" +\n        \"date_cmp_timestamptz|date_eq|date_eq_timestamp|date_eq_timestamptz|date_ge|\" +\n        \"date_ge_timestamp|date_ge_timestamptz|date_gt|date_gt_timestamp|date_gt_timestamptz|\" +\n        \"date_in|date_larger|date_le|date_le_timestamp|date_le_timestamptz|date_lt|\" +\n        \"date_lt_timestamp|date_lt_timestamptz|date_mi|date_mi_interval|date_mii|date_ne|\" +\n        \"date_ne_timestamp|date_ne_timestamptz|date_out|date_part|date_pl_interval|date_pli|\" +\n        \"date_recv|date_send|date_smaller|date_sortsupport|date_trunc|daterange|\" +\n        \"daterange_canonical|daterange_subdiff|datetime_pl|datetimetz_pl|dcbrt|decode|degrees|\" +\n        \"dense_rank|dexp|diagonal|diameter|dispell_init|dispell_lexize|dist_cpoly|dist_lb|dist_pb|\" +\n        \"dist_pc|dist_pl|dist_ppath|dist_ps|dist_sb|dist_sl|div|dlog1|dlog10|domain_in|domain_recv|\" +\n        \"dpow|dround|dsimple_init|dsimple_lexize|dsnowball_init|dsnowball_lexize|dsqrt|\" +\n        \"dsynonym_init|dsynonym_lexize|dtrunc|elem_contained_by_range|encode|enum_cmp|enum_eq|\" +\n        \"enum_first|enum_ge|enum_gt|enum_in|enum_larger|enum_last|enum_le|enum_lt|enum_ne|enum_out|\" +\n        \"enum_range|enum_recv|enum_send|enum_smaller|eqjoinsel|eqsel|euc_cn_to_mic|\" +\n        \"euc_cn_to_utf8|euc_jis_2004_to_shift_jis_2004|euc_jis_2004_to_utf8|euc_jp_to_mic|\" +\n        \"euc_jp_to_sjis|euc_jp_to_utf8|euc_kr_to_mic|euc_kr_to_utf8|euc_tw_to_big5|\" +\n        \"euc_tw_to_mic|euc_tw_to_utf8|event_trigger_in|event_trigger_out|every|exp|factorial|\" +\n        \"family|fdw_handler_in|fdw_handler_out|first_value|float4|float48div|float48eq|float48ge|\" +\n        \"float48gt|float48le|float48lt|float48mi|float48mul|float48ne|float48pl|float4_accum|\" +\n        \"float4abs|float4div|float4eq|float4ge|float4gt|float4in|float4larger|float4le|float4lt|\" +\n        \"float4mi|float4mul|float4ne|float4out|float4pl|float4recv|float4send|float4smaller|\" +\n        \"float4um|float4up|float8|float84div|float84eq|float84ge|float84gt|float84le|float84lt|\" +\n        \"float84mi|float84mul|float84ne|float84pl|float8_accum|float8_avg|float8_corr|\" +\n        \"float8_covar_pop|float8_covar_samp|float8_regr_accum|float8_regr_avgx|\" +\n        \"float8_regr_avgy|float8_regr_intercept|float8_regr_r2|float8_regr_slope|\" +\n        \"float8_regr_sxx|float8_regr_sxy|float8_regr_syy|float8_stddev_pop|float8_stddev_samp|\" +\n        \"float8_var_pop|float8_var_samp|float8abs|float8div|float8eq|float8ge|float8gt|float8in|\" +\n        \"float8larger|float8le|float8lt|float8mi|float8mul|float8ne|float8out|float8pl|float8recv|\" +\n        \"float8send|float8smaller|float8um|float8up|floor|flt4_mul_cash|flt8_mul_cash|\" +\n        \"fmgr_c_validator|fmgr_internal_validator|fmgr_sql_validator|format|format_type|\" +\n        \"gb18030_to_utf8|gbk_to_utf8|generate_series|generate_subscripts|get_bit|get_byte|\" +\n        \"get_current_ts_config|getdatabaseencoding|getpgusername|gin_cmp_prefix|\" +\n        \"gin_cmp_tslexeme|gin_extract_tsquery|gin_extract_tsvector|gin_tsquery_consistent|\" +\n        \"ginarrayconsistent|ginarrayextract|ginbeginscan|ginbuild|ginbuildempty|ginbulkdelete|\" +\n        \"gincostestimate|ginendscan|gingetbitmap|gininsert|ginmarkpos|ginoptions|\" +\n        \"ginqueryarrayextract|ginrescan|ginrestrpos|ginvacuumcleanup|gist_box_compress|\" +\n        \"gist_box_consistent|gist_box_decompress|gist_box_penalty|gist_box_picksplit|\" +\n        \"gist_box_same|gist_box_union|gist_circle_compress|gist_circle_consistent|\" +\n        \"gist_point_compress|gist_point_consistent|gist_point_distance|gist_poly_compress|\" +\n        \"gist_poly_consistent|gistbeginscan|gistbuild|gistbuildempty|gistbulkdelete|\" +\n        \"gistcostestimate|gistendscan|gistgetbitmap|gistgettuple|gistinsert|gistmarkpos|\" +\n        \"gistoptions|gistrescan|gistrestrpos|gistvacuumcleanup|gtsquery_compress|\" +\n        \"gtsquery_consistent|gtsquery_decompress|gtsquery_penalty|gtsquery_picksplit|\" +\n        \"gtsquery_same|gtsquery_union|gtsvector_compress|gtsvector_consistent|\" +\n        \"gtsvector_decompress|gtsvector_penalty|gtsvector_picksplit|gtsvector_same|\" +\n        \"gtsvector_union|gtsvectorin|gtsvectorout|has_any_column_privilege|\" +\n        \"has_column_privilege|has_database_privilege|has_foreign_data_wrapper_privilege|\" +\n        \"has_function_privilege|has_language_privilege|has_schema_privilege|\" +\n        \"has_sequence_privilege|has_server_privilege|has_table_privilege|\" +\n        \"has_tablespace_privilege|has_type_privilege|hash_aclitem|hash_array|hash_numeric|\" +\n        \"hash_range|hashbeginscan|hashbpchar|hashbuild|hashbuildempty|hashbulkdelete|hashchar|\" +\n        \"hashcostestimate|hashendscan|hashenum|hashfloat4|hashfloat8|hashgetbitmap|hashgettuple|\" +\n        \"hashinet|hashinsert|hashint2|hashint2vector|hashint4|hashint8|hashmacaddr|hashmarkpos|\" +\n        \"hashname|hashoid|hashoidvector|hashoptions|hashrescan|hashrestrpos|hashtext|\" +\n        \"hashvacuumcleanup|hashvarlena|height|host|hostmask|iclikejoinsel|iclikesel|\" +\n        \"icnlikejoinsel|icnlikesel|icregexeqjoinsel|icregexeqsel|icregexnejoinsel|icregexnesel|\" +\n        \"inet_client_addr|inet_client_port|inet_in|inet_out|inet_recv|inet_send|\" +\n        \"inet_server_addr|inet_server_port|inetand|inetmi|inetmi_int8|inetnot|inetor|inetpl|\" +\n        \"initcap|int2|int24div|int24eq|int24ge|int24gt|int24le|int24lt|int24mi|int24mul|int24ne|\" +\n        \"int24pl|int28div|int28eq|int28ge|int28gt|int28le|int28lt|int28mi|int28mul|int28ne|int28pl|\" +\n        \"int2_accum|int2_avg_accum|int2_mul_cash|int2_sum|int2abs|int2and|int2div|int2eq|int2ge|\" +\n        \"int2gt|int2in|int2larger|int2le|int2lt|int2mi|int2mod|int2mul|int2ne|int2not|int2or|int2out|\" +\n        \"int2pl|int2recv|int2send|int2shl|int2shr|int2smaller|int2um|int2up|int2vectoreq|\" +\n        \"int2vectorin|int2vectorout|int2vectorrecv|int2vectorsend|int2xor|int4|int42div|int42eq|\" +\n        \"int42ge|int42gt|int42le|int42lt|int42mi|int42mul|int42ne|int42pl|int48div|int48eq|int48ge|\" +\n        \"int48gt|int48le|int48lt|int48mi|int48mul|int48ne|int48pl|int4_accum|int4_avg_accum|\" +\n        \"int4_mul_cash|int4_sum|int4abs|int4and|int4div|int4eq|int4ge|int4gt|int4in|int4inc|\" +\n        \"int4larger|int4le|int4lt|int4mi|int4mod|int4mul|int4ne|int4not|int4or|int4out|int4pl|\" +\n        \"int4range|int4range_canonical|int4range_subdiff|int4recv|int4send|int4shl|int4shr|\" +\n        \"int4smaller|int4um|int4up|int4xor|int8|int82div|int82eq|int82ge|int82gt|int82le|int82lt|\" +\n        \"int82mi|int82mul|int82ne|int82pl|int84div|int84eq|int84ge|int84gt|int84le|int84lt|int84mi|\" +\n        \"int84mul|int84ne|int84pl|int8_accum|int8_avg|int8_avg_accum|int8_sum|int8abs|int8and|\" +\n        \"int8div|int8eq|int8ge|int8gt|int8in|int8inc|int8inc_any|int8inc_float8_float8|int8larger|\" +\n        \"int8le|int8lt|int8mi|int8mod|int8mul|int8ne|int8not|int8or|int8out|int8pl|int8pl_inet|\" +\n        \"int8range|int8range_canonical|int8range_subdiff|int8recv|int8send|int8shl|int8shr|\" +\n        \"int8smaller|int8um|int8up|int8xor|integer_pl_date|inter_lb|inter_sb|inter_sl|internal_in|\" +\n        \"internal_out|interval_accum|interval_avg|interval_cmp|interval_div|interval_eq|\" +\n        \"interval_ge|interval_gt|interval_hash|interval_in|interval_larger|interval_le|\" +\n        \"interval_lt|interval_mi|interval_mul|interval_ne|interval_out|interval_pl|\" +\n        \"interval_pl_date|interval_pl_time|interval_pl_timestamp|interval_pl_timestamptz|\" +\n        \"interval_pl_timetz|interval_recv|interval_send|interval_smaller|interval_transform|\" +\n        \"interval_um|intervaltypmodin|intervaltypmodout|intinterval|isclosed|isempty|isfinite|\" +\n        \"ishorizontal|iso8859_1_to_utf8|iso8859_to_utf8|iso_to_koi8r|iso_to_mic|iso_to_win1251|\" +\n        \"iso_to_win866|isopen|isparallel|isperp|isvertical|johab_to_utf8|json_agg|\" +\n        \"json_agg_finalfn|json_agg_transfn|json_array_element|json_array_element_text|\" +\n        \"json_array_elements|json_array_length|json_each|json_each_text|json_extract_path|\" +\n        \"json_extract_path_op|json_extract_path_text|json_extract_path_text_op|json_in|\" +\n        \"json_object_field|json_object_field_text|json_object_keys|json_out|\" +\n        \"json_populate_record|json_populate_recordset|json_recv|json_send|justify_days|\" +\n        \"justify_hours|justify_interval|koi8r_to_iso|koi8r_to_mic|koi8r_to_utf8|\" +\n        \"koi8r_to_win1251|koi8r_to_win866|koi8u_to_utf8|lag|language_handler_in|\" +\n        \"language_handler_out|last_value|lastval|latin1_to_mic|latin2_to_mic|latin2_to_win1250|\" +\n        \"latin3_to_mic|latin4_to_mic|lead|left|length|like|like_escape|likejoinsel|likesel|line|\" +\n        \"line_distance|line_eq|line_horizontal|line_in|line_interpt|line_intersect|line_out|\" +\n        \"line_parallel|line_perp|line_recv|line_send|line_vertical|ln|lo_close|lo_creat|lo_create|\" +\n        \"lo_export|lo_import|lo_lseek|lo_lseek64|lo_open|lo_tell|lo_tell64|lo_truncate|\" +\n        \"lo_truncate64|lo_unlink|log|loread|lower|lower_inc|lower_inf|lowrite|lpad|lseg|lseg_center|\" +\n        \"lseg_distance|lseg_eq|lseg_ge|lseg_gt|lseg_horizontal|lseg_in|lseg_interpt|\" +\n        \"lseg_intersect|lseg_le|lseg_length|lseg_lt|lseg_ne|lseg_out|lseg_parallel|lseg_perp|\" +\n        \"lseg_recv|lseg_send|lseg_vertical|ltrim|macaddr_and|macaddr_cmp|macaddr_eq|macaddr_ge|\" +\n        \"macaddr_gt|macaddr_in|macaddr_le|macaddr_lt|macaddr_ne|macaddr_not|macaddr_or|\" +\n        \"macaddr_out|macaddr_recv|macaddr_send|makeaclitem|masklen|max|md5|mic_to_ascii|\" +\n        \"mic_to_big5|mic_to_euc_cn|mic_to_euc_jp|mic_to_euc_kr|mic_to_euc_tw|mic_to_iso|\" +\n        \"mic_to_koi8r|mic_to_latin1|mic_to_latin2|mic_to_latin3|mic_to_latin4|mic_to_sjis|\" +\n        \"mic_to_win1250|mic_to_win1251|mic_to_win866|min|mktinterval|mod|money|mul_d_interval|\" +\n        \"name|nameeq|namege|namegt|nameiclike|nameicnlike|nameicregexeq|nameicregexne|namein|\" +\n        \"namele|namelike|namelt|namene|namenlike|nameout|namerecv|nameregexeq|nameregexne|namesend|\" +\n        \"neqjoinsel|neqsel|netmask|network|network_cmp|network_eq|network_ge|network_gt|\" +\n        \"network_le|network_lt|network_ne|network_sub|network_subeq|network_sup|network_supeq|\" +\n        \"nextval|nlikejoinsel|nlikesel|notlike|now|npoints|nth_value|ntile|numeric_abs|\" +\n        \"numeric_accum|numeric_add|numeric_avg|numeric_avg_accum|numeric_cmp|numeric_div|\" +\n        \"numeric_div_trunc|numeric_eq|numeric_exp|numeric_fac|numeric_ge|numeric_gt|numeric_in|\" +\n        \"numeric_inc|numeric_larger|numeric_le|numeric_ln|numeric_log|numeric_lt|numeric_mod|\" +\n        \"numeric_mul|numeric_ne|numeric_out|numeric_power|numeric_recv|numeric_send|\" +\n        \"numeric_smaller|numeric_sqrt|numeric_stddev_pop|numeric_stddev_samp|numeric_sub|\" +\n        \"numeric_transform|numeric_uminus|numeric_uplus|numeric_var_pop|numeric_var_samp|\" +\n        \"numerictypmodin|numerictypmodout|numnode|numrange|numrange_subdiff|obj_description|\" +\n        \"octet_length|oid|oideq|oidge|oidgt|oidin|oidlarger|oidle|oidlt|oidne|oidout|oidrecv|oidsend|\" +\n        \"oidsmaller|oidvectoreq|oidvectorge|oidvectorgt|oidvectorin|oidvectorle|oidvectorlt|\" +\n        \"oidvectorne|oidvectorout|oidvectorrecv|oidvectorsend|oidvectortypes|on_pb|on_pl|\" +\n        \"on_ppath|on_ps|on_sb|on_sl|opaque_in|opaque_out|overlaps|overlay|path|path_add|path_add_pt|\" +\n        \"path_center|path_contain_pt|path_distance|path_div_pt|path_in|path_inter|path_length|\" +\n        \"path_mul_pt|path_n_eq|path_n_ge|path_n_gt|path_n_le|path_n_lt|path_npoints|path_out|\" +\n        \"path_recv|path_send|path_sub_pt|pclose|percent_rank|pg_advisory_lock|\" +\n        \"pg_advisory_lock_shared|pg_advisory_unlock|pg_advisory_unlock_all|\" +\n        \"pg_advisory_unlock_shared|pg_advisory_xact_lock|pg_advisory_xact_lock_shared|\" +\n        \"pg_available_extension_versions|pg_available_extensions|pg_backend_pid|\" +\n        \"pg_backup_start_time|pg_cancel_backend|pg_char_to_encoding|pg_client_encoding|\" +\n        \"pg_collation_for|pg_collation_is_visible|pg_column_is_updatable|pg_column_size|\" +\n        \"pg_conf_load_time|pg_conversion_is_visible|pg_create_restore_point|\" +\n        \"pg_current_xlog_insert_location|pg_current_xlog_location|pg_cursor|pg_database_size|\" +\n        \"pg_describe_object|pg_encoding_max_length|pg_encoding_to_char|\" +\n        \"pg_event_trigger_dropped_objects|pg_export_snapshot|pg_extension_config_dump|\" +\n        \"pg_extension_update_paths|pg_function_is_visible|pg_get_constraintdef|pg_get_expr|\" +\n        \"pg_get_function_arguments|pg_get_function_identity_arguments|\" +\n        \"pg_get_function_result|pg_get_functiondef|pg_get_indexdef|pg_get_keywords|\" +\n        \"pg_get_multixact_members|pg_get_ruledef|pg_get_serial_sequence|pg_get_triggerdef|\" +\n        \"pg_get_userbyid|pg_get_viewdef|pg_has_role|pg_identify_object|pg_indexes_size|\" +\n        \"pg_is_in_backup|pg_is_in_recovery|pg_is_other_temp_schema|pg_is_xlog_replay_paused|\" +\n        \"pg_last_xact_replay_timestamp|pg_last_xlog_receive_location|\" +\n        \"pg_last_xlog_replay_location|pg_listening_channels|pg_lock_status|pg_ls_dir|\" +\n        \"pg_my_temp_schema|pg_node_tree_in|pg_node_tree_out|pg_node_tree_recv|\" +\n        \"pg_node_tree_send|pg_notify|pg_opclass_is_visible|pg_operator_is_visible|\" +\n        \"pg_opfamily_is_visible|pg_options_to_table|pg_postmaster_start_time|\" +\n        \"pg_prepared_statement|pg_prepared_xact|pg_read_binary_file|pg_read_file|\" +\n        \"pg_relation_filenode|pg_relation_filepath|pg_relation_is_updatable|pg_relation_size|\" +\n        \"pg_reload_conf|pg_rotate_logfile|pg_sequence_parameters|pg_show_all_settings|\" +\n        \"pg_size_pretty|pg_sleep|pg_start_backup|pg_stat_clear_snapshot|pg_stat_file|\" +\n        \"pg_stat_get_activity|pg_stat_get_analyze_count|pg_stat_get_autoanalyze_count|\" +\n        \"pg_stat_get_autovacuum_count|pg_stat_get_backend_activity|\" +\n        \"pg_stat_get_backend_activity_start|pg_stat_get_backend_client_addr|\" +\n        \"pg_stat_get_backend_client_port|pg_stat_get_backend_dbid|pg_stat_get_backend_idset|\" +\n        \"pg_stat_get_backend_pid|pg_stat_get_backend_start|pg_stat_get_backend_userid|\" +\n        \"pg_stat_get_backend_waiting|pg_stat_get_backend_xact_start|\" +\n        \"pg_stat_get_bgwriter_buf_written_checkpoints|\" +\n        \"pg_stat_get_bgwriter_buf_written_clean|pg_stat_get_bgwriter_maxwritten_clean|\" +\n        \"pg_stat_get_bgwriter_requested_checkpoints|pg_stat_get_bgwriter_stat_reset_time|\" +\n        \"pg_stat_get_bgwriter_timed_checkpoints|pg_stat_get_blocks_fetched|\" +\n        \"pg_stat_get_blocks_hit|pg_stat_get_buf_alloc|pg_stat_get_buf_fsync_backend|\" +\n        \"pg_stat_get_buf_written_backend|pg_stat_get_checkpoint_sync_time|\" +\n        \"pg_stat_get_checkpoint_write_time|pg_stat_get_db_blk_read_time|\" +\n        \"pg_stat_get_db_blk_write_time|pg_stat_get_db_blocks_fetched|\" +\n        \"pg_stat_get_db_blocks_hit|pg_stat_get_db_conflict_all|\" +\n        \"pg_stat_get_db_conflict_bufferpin|pg_stat_get_db_conflict_lock|\" +\n        \"pg_stat_get_db_conflict_snapshot|pg_stat_get_db_conflict_startup_deadlock|\" +\n        \"pg_stat_get_db_conflict_tablespace|pg_stat_get_db_deadlocks|\" +\n        \"pg_stat_get_db_numbackends|pg_stat_get_db_stat_reset_time|\" +\n        \"pg_stat_get_db_temp_bytes|pg_stat_get_db_temp_files|pg_stat_get_db_tuples_deleted|\" +\n        \"pg_stat_get_db_tuples_fetched|pg_stat_get_db_tuples_inserted|\" +\n        \"pg_stat_get_db_tuples_returned|pg_stat_get_db_tuples_updated|\" +\n        \"pg_stat_get_db_xact_commit|pg_stat_get_db_xact_rollback|pg_stat_get_dead_tuples|\" +\n        \"pg_stat_get_function_calls|pg_stat_get_function_self_time|\" +\n        \"pg_stat_get_function_total_time|pg_stat_get_last_analyze_time|\" +\n        \"pg_stat_get_last_autoanalyze_time|pg_stat_get_last_autovacuum_time|\" +\n        \"pg_stat_get_last_vacuum_time|pg_stat_get_live_tuples|pg_stat_get_numscans|\" +\n        \"pg_stat_get_tuples_deleted|pg_stat_get_tuples_fetched|\" +\n        \"pg_stat_get_tuples_hot_updated|pg_stat_get_tuples_inserted|\" +\n        \"pg_stat_get_tuples_returned|pg_stat_get_tuples_updated|pg_stat_get_vacuum_count|\" +\n        \"pg_stat_get_wal_senders|pg_stat_get_xact_blocks_fetched|\" +\n        \"pg_stat_get_xact_blocks_hit|pg_stat_get_xact_function_calls|\" +\n        \"pg_stat_get_xact_function_self_time|pg_stat_get_xact_function_total_time|\" +\n        \"pg_stat_get_xact_numscans|pg_stat_get_xact_tuples_deleted|\" +\n        \"pg_stat_get_xact_tuples_fetched|pg_stat_get_xact_tuples_hot_updated|\" +\n        \"pg_stat_get_xact_tuples_inserted|pg_stat_get_xact_tuples_returned|\" +\n        \"pg_stat_get_xact_tuples_updated|pg_stat_reset|pg_stat_reset_shared|\" +\n        \"pg_stat_reset_single_function_counters|pg_stat_reset_single_table_counters|\" +\n        \"pg_stop_backup|pg_switch_xlog|pg_table_is_visible|pg_table_size|\" +\n        \"pg_tablespace_databases|pg_tablespace_location|pg_tablespace_size|\" +\n        \"pg_terminate_backend|pg_timezone_abbrevs|pg_timezone_names|pg_total_relation_size|\" +\n        \"pg_trigger_depth|pg_try_advisory_lock|pg_try_advisory_lock_shared|\" +\n        \"pg_try_advisory_xact_lock|pg_try_advisory_xact_lock_shared|pg_ts_config_is_visible|\" +\n        \"pg_ts_dict_is_visible|pg_ts_parser_is_visible|pg_ts_template_is_visible|\" +\n        \"pg_type_is_visible|pg_typeof|pg_xlog_location_diff|pg_xlog_replay_pause|\" +\n        \"pg_xlog_replay_resume|pg_xlogfile_name|pg_xlogfile_name_offset|pi|plainto_tsquery|\" +\n        \"plpgsql_call_handler|plpgsql_inline_handler|plpgsql_validator|point|point_above|\" +\n        \"point_add|point_below|point_distance|point_div|point_eq|point_horiz|point_in|point_left|\" +\n        \"point_mul|point_ne|point_out|point_recv|point_right|point_send|point_sub|point_vert|\" +\n        \"poly_above|poly_below|poly_center|poly_contain|poly_contain_pt|poly_contained|\" +\n        \"poly_distance|poly_in|poly_left|poly_npoints|poly_out|poly_overabove|poly_overbelow|\" +\n        \"poly_overlap|poly_overleft|poly_overright|poly_recv|poly_right|poly_same|poly_send|\" +\n        \"polygon|popen|position|positionjoinsel|positionsel|postgresql_fdw_validator|pow|power|\" +\n        \"prsd_end|prsd_headline|prsd_lextype|prsd_nexttoken|prsd_start|pt_contained_circle|\" +\n        \"pt_contained_poly|query_to_xml|query_to_xml_and_xmlschema|query_to_xmlschema|\" +\n        \"querytree|quote_ident|quote_literal|quote_nullable|radians|radius|random|range_adjacent|\" +\n        \"range_after|range_before|range_cmp|range_contained_by|range_contains|\" +\n        \"range_contains_elem|range_eq|range_ge|range_gist_compress|range_gist_consistent|\" +\n        \"range_gist_decompress|range_gist_penalty|range_gist_picksplit|range_gist_same|\" +\n        \"range_gist_union|range_gt|range_in|range_intersect|range_le|range_lt|range_minus|\" +\n        \"range_ne|range_out|range_overlaps|range_overleft|range_overright|range_recv|range_send|\" +\n        \"range_typanalyze|range_union|rangesel|rank|record_eq|record_ge|record_gt|record_in|\" +\n        \"record_le|record_lt|record_ne|record_out|record_recv|record_send|regclass|regclassin|\" +\n        \"regclassout|regclassrecv|regclasssend|regconfigin|regconfigout|regconfigrecv|\" +\n        \"regconfigsend|regdictionaryin|regdictionaryout|regdictionaryrecv|regdictionarysend|\" +\n        \"regexeqjoinsel|regexeqsel|regexnejoinsel|regexnesel|regexp_matches|regexp_replace|\" +\n        \"regexp_split_to_array|regexp_split_to_table|regoperatorin|regoperatorout|\" +\n        \"regoperatorrecv|regoperatorsend|regoperin|regoperout|regoperrecv|regopersend|\" +\n        \"regprocedurein|regprocedureout|regprocedurerecv|regproceduresend|regprocin|regprocout|\" +\n        \"regprocrecv|regprocsend|regr_avgx|regr_avgy|regr_count|regr_intercept|regr_r2|\" +\n        \"regr_slope|regr_sxx|regr_sxy|regr_syy|regtypein|regtypeout|regtyperecv|regtypesend|\" +\n        \"reltime|reltimeeq|reltimege|reltimegt|reltimein|reltimele|reltimelt|reltimene|reltimeout|\" +\n        \"reltimerecv|reltimesend|repeat|replace|reverse|right|round|row_number|row_to_json|rpad|\" +\n        \"rtrim|scalargtjoinsel|scalargtsel|scalarltjoinsel|scalarltsel|schema_to_xml|\" +\n        \"schema_to_xml_and_xmlschema|schema_to_xmlschema|session_user|set_bit|set_byte|\" +\n        \"set_config|set_masklen|setseed|setval|setweight|shell_in|shell_out|\" +\n        \"shift_jis_2004_to_euc_jis_2004|shift_jis_2004_to_utf8|shobj_description|sign|\" +\n        \"similar_escape|sin|sjis_to_euc_jp|sjis_to_mic|sjis_to_utf8|slope|smgreq|smgrin|smgrne|\" +\n        \"smgrout|spg_kd_choose|spg_kd_config|spg_kd_inner_consistent|spg_kd_picksplit|\" +\n        \"spg_quad_choose|spg_quad_config|spg_quad_inner_consistent|spg_quad_leaf_consistent|\" +\n        \"spg_quad_picksplit|spg_range_quad_choose|spg_range_quad_config|\" +\n        \"spg_range_quad_inner_consistent|spg_range_quad_leaf_consistent|\" +\n        \"spg_range_quad_picksplit|spg_text_choose|spg_text_config|spg_text_inner_consistent|\" +\n        \"spg_text_leaf_consistent|spg_text_picksplit|spgbeginscan|spgbuild|spgbuildempty|\" +\n        \"spgbulkdelete|spgcanreturn|spgcostestimate|spgendscan|spggetbitmap|spggettuple|\" +\n        \"spginsert|spgmarkpos|spgoptions|spgrescan|spgrestrpos|spgvacuumcleanup|split_part|sqrt|\" +\n        \"statement_timestamp|stddev|stddev_pop|stddev_samp|string_agg|string_agg_finalfn|\" +\n        \"string_agg_transfn|string_to_array|strip|strpos|substr|substring|sum|\" +\n        \"suppress_redundant_updates_trigger|table_to_xml|table_to_xml_and_xmlschema|\" +\n        \"table_to_xmlschema|tan|text|text_ge|text_gt|text_larger|text_le|text_lt|text_pattern_ge|\" +\n        \"text_pattern_gt|text_pattern_le|text_pattern_lt|text_smaller|textanycat|textcat|texteq|\" +\n        \"texticlike|texticnlike|texticregexeq|texticregexne|textin|textlen|textlike|textne|\" +\n        \"textnlike|textout|textrecv|textregexeq|textregexne|textsend|thesaurus_init|\" +\n        \"thesaurus_lexize|tideq|tidge|tidgt|tidin|tidlarger|tidle|tidlt|tidne|tidout|tidrecv|tidsend|\" +\n        \"tidsmaller|time_cmp|time_eq|time_ge|time_gt|time_hash|time_in|time_larger|time_le|time_lt|\" +\n        \"time_mi_interval|time_mi_time|time_ne|time_out|time_pl_interval|time_recv|time_send|\" +\n        \"time_smaller|time_transform|timedate_pl|timemi|timenow|timeofday|timepl|timestamp_cmp|\" +\n        \"timestamp_cmp_date|timestamp_cmp_timestamptz|timestamp_eq|timestamp_eq_date|\" +\n        \"timestamp_eq_timestamptz|timestamp_ge|timestamp_ge_date|timestamp_ge_timestamptz|\" +\n        \"timestamp_gt|timestamp_gt_date|timestamp_gt_timestamptz|timestamp_hash|timestamp_in|\" +\n        \"timestamp_larger|timestamp_le|timestamp_le_date|timestamp_le_timestamptz|\" +\n        \"timestamp_lt|timestamp_lt_date|timestamp_lt_timestamptz|timestamp_mi|\" +\n        \"timestamp_mi_interval|timestamp_ne|timestamp_ne_date|timestamp_ne_timestamptz|\" +\n        \"timestamp_out|timestamp_pl_interval|timestamp_recv|timestamp_send|timestamp_smaller|\" +\n        \"timestamp_sortsupport|timestamp_transform|timestamptypmodin|timestamptypmodout|\" +\n        \"timestamptz_cmp|timestamptz_cmp_date|timestamptz_cmp_timestamp|timestamptz_eq|\" +\n        \"timestamptz_eq_date|timestamptz_eq_timestamp|timestamptz_ge|timestamptz_ge_date|\" +\n        \"timestamptz_ge_timestamp|timestamptz_gt|timestamptz_gt_date|\" +\n        \"timestamptz_gt_timestamp|timestamptz_in|timestamptz_larger|timestamptz_le|\" +\n        \"timestamptz_le_date|timestamptz_le_timestamp|timestamptz_lt|timestamptz_lt_date|\" +\n        \"timestamptz_lt_timestamp|timestamptz_mi|timestamptz_mi_interval|timestamptz_ne|\" +\n        \"timestamptz_ne_date|timestamptz_ne_timestamp|timestamptz_out|\" +\n        \"timestamptz_pl_interval|timestamptz_recv|timestamptz_send|timestamptz_smaller|\" +\n        \"timestamptztypmodin|timestamptztypmodout|timetypmodin|timetypmodout|timetz_cmp|\" +\n        \"timetz_eq|timetz_ge|timetz_gt|timetz_hash|timetz_in|timetz_larger|timetz_le|timetz_lt|\" +\n        \"timetz_mi_interval|timetz_ne|timetz_out|timetz_pl_interval|timetz_recv|timetz_send|\" +\n        \"timetz_smaller|timetzdate_pl|timetztypmodin|timetztypmodout|timezone|tinterval|\" +\n        \"tintervalct|tintervalend|tintervaleq|tintervalge|tintervalgt|tintervalin|tintervalle|\" +\n        \"tintervalleneq|tintervallenge|tintervallengt|tintervallenle|tintervallenlt|\" +\n        \"tintervallenne|tintervallt|tintervalne|tintervalout|tintervalov|tintervalrecv|\" +\n        \"tintervalrel|tintervalsame|tintervalsend|tintervalstart|to_ascii|to_char|to_date|to_hex|\" +\n        \"to_json|to_number|to_timestamp|to_tsquery|to_tsvector|transaction_timestamp|translate|\" +\n        \"trigger_in|trigger_out|trunc|ts_debug|ts_headline|ts_lexize|ts_match_qv|ts_match_tq|\" +\n        \"ts_match_tt|ts_match_vq|ts_parse|ts_rank|ts_rank_cd|ts_rewrite|ts_stat|ts_token_type|\" +\n        \"ts_typanalyze|tsmatchjoinsel|tsmatchsel|tsq_mcontained|tsq_mcontains|tsquery_and|\" +\n        \"tsquery_cmp|tsquery_eq|tsquery_ge|tsquery_gt|tsquery_le|tsquery_lt|tsquery_ne|\" +\n        \"tsquery_not|tsquery_or|tsqueryin|tsqueryout|tsqueryrecv|tsquerysend|tsrange|\" +\n        \"tsrange_subdiff|tstzrange|tstzrange_subdiff|tsvector_cmp|tsvector_concat|tsvector_eq|\" +\n        \"tsvector_ge|tsvector_gt|tsvector_le|tsvector_lt|tsvector_ne|tsvector_update_trigger|\" +\n        \"tsvector_update_trigger_column|tsvectorin|tsvectorout|tsvectorrecv|tsvectorsend|\" +\n        \"txid_current|txid_current_snapshot|txid_snapshot_in|txid_snapshot_out|\" +\n        \"txid_snapshot_recv|txid_snapshot_send|txid_snapshot_xip|txid_snapshot_xmax|\" +\n        \"txid_snapshot_xmin|txid_visible_in_snapshot|uhc_to_utf8|unique_key_recheck|unknownin|\" +\n        \"unknownout|unknownrecv|unknownsend|unnest|upper|upper_inc|upper_inf|utf8_to_ascii|\" +\n        \"utf8_to_big5|utf8_to_euc_cn|utf8_to_euc_jis_2004|utf8_to_euc_jp|utf8_to_euc_kr|\" +\n        \"utf8_to_euc_tw|utf8_to_gb18030|utf8_to_gbk|utf8_to_iso8859|utf8_to_iso8859_1|\" +\n        \"utf8_to_johab|utf8_to_koi8r|utf8_to_koi8u|utf8_to_shift_jis_2004|utf8_to_sjis|\" +\n        \"utf8_to_uhc|utf8_to_win|uuid_cmp|uuid_eq|uuid_ge|uuid_gt|uuid_hash|uuid_in|uuid_le|\" +\n        \"uuid_lt|uuid_ne|uuid_out|uuid_recv|uuid_send|var_pop|var_samp|varbit_in|varbit_out|\" +\n        \"varbit_recv|varbit_send|varbit_transform|varbitcmp|varbiteq|varbitge|varbitgt|varbitle|\" +\n        \"varbitlt|varbitne|varbittypmodin|varbittypmodout|varchar_transform|varcharin|\" +\n        \"varcharout|varcharrecv|varcharsend|varchartypmodin|varchartypmodout|variance|version|\" +\n        \"void_in|void_out|void_recv|void_send|width|width_bucket|win1250_to_latin2|\" +\n        \"win1250_to_mic|win1251_to_iso|win1251_to_koi8r|win1251_to_mic|win1251_to_win866|\" +\n        \"win866_to_iso|win866_to_koi8r|win866_to_mic|win866_to_win1251|win_to_utf8|xideq|\" +\n        \"xideqint4|xidin|xidout|xidrecv|xidsend|xml|xml_in|xml_is_well_formed|\" +\n        \"xml_is_well_formed_content|xml_is_well_formed_document|xml_out|xml_recv|xml_send|\" +\n        \"xmlagg|xmlcomment|xmlconcat2|xmlexists|xmlvalidate|xpath|xpath_exists\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords\n    }, \"identifier\", true);\n\n\n    var sqlRules = [{\n            token : \"string\", // single line string -- assume dollar strings if multi-line for now\n            regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n        }, {\n            token : \"variable.language\", // pg identifier\n            regex : '\".*?\"'\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_][a-zA-Z0-9_$]*\\\\b\" // TODO - Unicode in identifiers\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|!!|!~|!~\\\\*|!~~|!~~\\\\*|#|##|#<|#<=|#<>|#=|#>|#>=|%|\\\\&|\\\\&\\\\&|\\\\&<|\\\\&<\\\\||\\\\&>|\\\\*|\\\\+|\" +\n                    \"\\\\-|/|<|<#>|<\\\\->|<<|<<=|<<\\\\||<=|<>|<\\\\?>|<@|<\\\\^|=|>|>=|>>|>>=|>\\\\^|\\\\?#|\\\\?\\\\-|\\\\?\\\\-\\\\||\" +\n                    \"\\\\?\\\\||\\\\?\\\\|\\\\||@|@\\\\-@|@>|@@|@@@|\\\\^|\\\\||\\\\|\\\\&>|\\\\|/|\\\\|>>|\\\\|\\\\||\\\\|\\\\|/|~|~\\\\*|~<=~|~<~|\" +\n                    \"~=|~>=~|~>~|~~|~~\\\\*\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }\n    ];\n\n\n    this.$rules = {\n        \"start\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            },{\n                token : \"keyword.statementBegin\",\n                regex : \"[a-zA-Z]+\", // Could enumerate starting keywords but this allows things to work when new statements are added.\n                next : \"statement\"\n            },{\n                token : \"support.buildin\", // psql directive\n                regex : \"^\\\\\\\\[\\\\S]+.*$\"\n            }\n        ],\n\n        \"statement\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            }, {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"commentStatement\"\n            }, {\n                token : \"statementEnd\",\n                regex : \";\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$perl\\\\$\",\n                next : \"perl-start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$python\\\\$\",\n                next : \"python-start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$json\\\\$\",\n                next : \"json-start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$(js|javascript)\\\\$\",\n                next : \"javascript-start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$\\\\$$\",\n                next : \"dollarSql\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarStatementString\"\n            }\n        ].concat(sqlRules),\n\n        \"dollarSql\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            }, {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"commentDollarSql\"\n            }, {\n                token : [\"keyword\", \"statementEnd\", \"text\", \"string\"], // end quoting with dollar at the start of a line\n                regex : \"(^|END)(;)?(\\\\s*)(\\\\$\\\\$)\",\n                next : \"statement\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarSqlString\"\n            }\n        ].concat(sqlRules),\n\n        \"comment\" : [{\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n\n        \"commentStatement\" : [{\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"statement\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n\n        \"commentDollarSql\" : [{\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"dollarSql\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n\n        \"dollarStatementString\" : [{\n                token : \"string\", // closing dollarstring\n                regex : \".*?\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"statement\"\n            }, {\n                token : \"string\", // dollarstring spanning whole line\n                regex : \".+\"\n            }\n        ],\n\n        \"dollarSqlString\" : [{\n                token : \"string\", // closing dollarstring\n                regex : \".*?\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarSql\"\n            }, {\n                token : \"string\", // dollarstring spanning whole line\n                regex : \".+\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\", [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.embedRules(PerlHighlightRules, \"perl-\", [{token : \"string\", regex : \"\\\\$perl\\\\$\", next : \"statement\"}]);\n    this.embedRules(PythonHighlightRules, \"python-\", [{token : \"string\", regex : \"\\\\$python\\\\$\", next : \"statement\"}]);\n    this.embedRules(JsonHighlightRules, \"json-\", [{token : \"string\", regex : \"\\\\$json\\\\$\", next : \"statement\"}]);\n    this.embedRules(JavaScriptHighlightRules, \"javascript-\", [{token : \"string\", regex : \"\\\\$(js|javascript)\\\\$\", next : \"statement\"}]);\n};\n\noop.inherits(PgsqlHighlightRules, TextHighlightRules);\n\nexports.PgsqlHighlightRules = PgsqlHighlightRules;\n"
  },
  {
    "path": "src/mode/php.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PhpHighlightRules = require(\"./php_highlight_rules\").PhpHighlightRules;\nvar PhpLangHighlightRules = require(\"./php_highlight_rules\").PhpLangHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\nvar PhpCompletions = require(\"./php_completions\").PhpCompletions;\nvar PhpFoldMode = require(\"./folding/php\").FoldMode;\nvar unicode = require(\"../unicode\");\nvar MixedFoldMode = require(\"./folding/mixed\").FoldMode;\nvar HtmlFoldMode = require(\"./folding/html\").FoldMode;\nvar CstyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar HtmlMode = require(\"./html\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar CssMode = require(\"./css\").Mode;\n\nvar PhpMode = function(opts) {\n    this.HighlightRules = PhpLangHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.$completer = new PhpCompletions();\n    this.foldingRules = new MixedFoldMode(new HtmlFoldMode(), {\n        \"js-\": new CstyleFoldMode(),\n        \"css-\": new CstyleFoldMode(),\n        \"php-\": new PhpFoldMode()\n    });\n};\noop.inherits(PhpMode, TextMode);\n\n(function() {\n\n    this.tokenRe = new RegExp(\"^[\" + unicode.wordChars + \"_]+\", \"g\");\n    this.nonTokenRe = new RegExp(\"^(?:[^\" + unicode.wordChars + \"_]|\\\\s])+\", \"g\");\n\n    this.lineCommentStart = [\"//\", \"#\"];\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState != \"doc-start\") {\n                return \"\";\n            }\n            var match = line.match(/^\\s*(\\/?)\\*/);\n            if (match) {\n                if (match[1]) {\n                    indent += \" \";\n                }\n                indent += \"* \";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        return this.$completer.getCompletions(state, session, pos, prefix);\n    };\n\n    this.$id = \"ace/mode/php-inline\";\n}).call(PhpMode.prototype);\n\nvar Mode = function(opts) {\n    if (opts && opts.inline) {\n        var mode = new PhpMode();\n        mode.createWorker = this.createWorker;\n        mode.inlinePhp = true;\n        return mode;\n    }\n    HtmlMode.call(this);\n    this.HighlightRules = PhpHighlightRules;\n    this.createModeDelegates({\n        \"js-\": JavaScriptMode,\n        \"css-\": CssMode,\n        \"php-\": PhpMode\n    });\n    this.foldingRules = new MixedFoldMode(new HtmlFoldMode(), {\n        \"js-\": new CstyleFoldMode(),\n        \"css-\": new CstyleFoldMode(),\n        \"php-\": new PhpFoldMode()\n    });\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/php_worker\", \"PhpWorker\");\n        worker.attachToDocument(session.getDocument());\n\n        if (this.inlinePhp)\n            worker.call(\"setOptions\", [{inline: true}]);\n\n        worker.on(\"annotate\", function(e) {\n            session.setAnnotations(e.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n    this.$id = \"ace/mode/php\";\n    this.snippetFileId = \"ace/snippets/php\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/php_completions.js",
    "content": "/**\n * ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK *****\n */\n\n\"use strict\";\n\nvar functionMap = {\n    \"abs\": [\n        \"int abs(int number)\",\n        \"Return the absolute value of the number\"\n    ],\n    \"acos\": [\n        \"float acos(float number)\",\n        \"Return the arc cosine of the number in radians\"\n    ],\n    \"acosh\": [\n        \"float acosh(float number)\",\n        \"Returns the inverse hyperbolic cosine of the number, i.e. the value whose hyperbolic cosine is number\"\n    ],\n    \"addGlob\": [\n        \"bool addGlob(string pattern[,int flags [, array options]])\",\n        \"Add files matching the glob pattern. See php's glob for the pattern syntax.\"\n    ],\n    \"addPattern\": [\n        \"bool addPattern(string pattern[, string path [, array options]])\",\n        \"Add files matching the pcre pattern. See php's pcre for the pattern syntax.\"\n    ],\n    \"addcslashes\": [\n        \"string addcslashes(string str, string charlist)\",\n        \"Escapes all chars mentioned in charlist with backslash. It creates octal representations if asked to backslash characters with 8th bit set or with ASCII<32 (except '\\\\n', '\\\\r', '\\\\t' etc...)\"\n    ],\n    \"addslashes\": [\n        \"string addslashes(string str)\",\n        \"Escapes single quote, double quotes and backslash characters in a string with backslashes\"\n    ],\n    \"apache_child_terminate\": [\n        \"bool apache_child_terminate()\",\n        \"Terminate apache process after this request\"\n    ],\n    \"apache_get_modules\": [\n        \"array apache_get_modules()\",\n        \"Get a list of loaded Apache modules\"\n    ],\n    \"apache_get_version\": [\n        \"string apache_get_version()\",\n        \"Fetch Apache version\"\n    ],\n    \"apache_getenv\": [\n        \"bool apache_getenv(string variable [, bool walk_to_top])\",\n        \"Get an Apache subprocess_env variable\"\n    ],\n    \"apache_lookup_uri\": [\n        \"object apache_lookup_uri(string URI)\",\n        \"Perform a partial request of the given URI to obtain information about it\"\n    ],\n    \"apache_note\": [\n        \"string apache_note(string note_name [, string note_value])\",\n        \"Get and set Apache request notes\"\n    ],\n    \"apache_request_auth_name\": [\n        \"string apache_request_auth_name()\",\n        \"\"\n    ],\n    \"apache_request_auth_type\": [\n        \"string apache_request_auth_type()\",\n        \"\"\n    ],\n    \"apache_request_discard_request_body\": [\n        \"long apache_request_discard_request_body()\",\n        \"\"\n    ],\n    \"apache_request_err_headers_out\": [\n        \"array apache_request_err_headers_out([{string name|array list} [, string value [, bool replace = false]]])\",\n        \"* fetch all headers that go out in case of an error or a subrequest\"\n    ],\n    \"apache_request_headers\": [\n        \"array apache_request_headers()\",\n        \"Fetch all HTTP request headers\"\n    ],\n    \"apache_request_headers_in\": [\n        \"array apache_request_headers_in()\",\n        \"* fetch all incoming request headers\"\n    ],\n    \"apache_request_headers_out\": [\n        \"array apache_request_headers_out([{string name|array list} [, string value [, bool replace = false]]])\",\n        \"* fetch all outgoing request headers\"\n    ],\n    \"apache_request_is_initial_req\": [\n        \"bool apache_request_is_initial_req()\",\n        \"\"\n    ],\n    \"apache_request_log_error\": [\n        \"bool apache_request_log_error(string message, [long facility])\",\n        \"\"\n    ],\n    \"apache_request_meets_conditions\": [\n        \"long apache_request_meets_conditions()\",\n        \"\"\n    ],\n    \"apache_request_remote_host\": [\n        \"int apache_request_remote_host([int type])\",\n        \"\"\n    ],\n    \"apache_request_run\": [\n        \"long apache_request_run()\",\n        \"This is a wrapper for ap_sub_run_req and ap_destory_sub_req.  It takes      sub_request, runs it, destroys it, and returns it's status.\"\n    ],\n    \"apache_request_satisfies\": [\n        \"long apache_request_satisfies()\",\n        \"\"\n    ],\n    \"apache_request_server_port\": [\n        \"int apache_request_server_port()\",\n        \"\"\n    ],\n    \"apache_request_set_etag\": [\n        \"void apache_request_set_etag()\",\n        \"\"\n    ],\n    \"apache_request_set_last_modified\": [\n        \"void apache_request_set_last_modified()\",\n        \"\"\n    ],\n    \"apache_request_some_auth_required\": [\n        \"bool apache_request_some_auth_required()\",\n        \"\"\n    ],\n    \"apache_request_sub_req_lookup_file\": [\n        \"object apache_request_sub_req_lookup_file(string file)\",\n        \"Returns sub-request for the specified file.  You would     need to run it yourself with run().\"\n    ],\n    \"apache_request_sub_req_lookup_uri\": [\n        \"object apache_request_sub_req_lookup_uri(string uri)\",\n        \"Returns sub-request for the specified uri.  You would     need to run it yourself with run()\"\n    ],\n    \"apache_request_sub_req_method_uri\": [\n        \"object apache_request_sub_req_method_uri(string method, string uri)\",\n        \"Returns sub-request for the specified file.  You would     need to run it yourself with run().\"\n    ],\n    \"apache_request_update_mtime\": [\n        \"long apache_request_update_mtime([int dependency_mtime])\",\n        \"\"\n    ],\n    \"apache_reset_timeout\": [\n        \"bool apache_reset_timeout()\",\n        \"Reset the Apache write timer\"\n    ],\n    \"apache_response_headers\": [\n        \"array apache_response_headers()\",\n        \"Fetch all HTTP response headers\"\n    ],\n    \"apache_setenv\": [\n        \"bool apache_setenv(string variable, string value [, bool walk_to_top])\",\n        \"Set an Apache subprocess_env variable\"\n    ],\n    \"array_change_key_case\": [\n        \"array array_change_key_case(array input [, int case=CASE_LOWER])\",\n        \"Retuns an array with all string keys lowercased [or uppercased]\"\n    ],\n    \"array_chunk\": [\n        \"array array_chunk(array input, int size [, bool preserve_keys])\",\n        \"Split array into chunks\"\n    ],\n    \"array_combine\": [\n        \"array array_combine(array keys, array values)\",\n        \"Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values\"\n    ],\n    \"array_count_values\": [\n        \"array array_count_values(array input)\",\n        \"Return the value as key and the frequency of that value in input as value\"\n    ],\n    \"array_diff\": [\n        \"array array_diff(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments.\"\n    ],\n    \"array_diff_assoc\": [\n        \"array array_diff_assoc(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal\"\n    ],\n    \"array_diff_key\": [\n        \"array array_diff_key(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have keys which are not present in any of the others arguments. This function is like array_diff() but works on the keys instead of the values. The associativity is preserved.\"\n    ],\n    \"array_diff_uassoc\": [\n        \"array array_diff_uassoc(array arr1, array arr2 [, array ...], callback data_comp_func)\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Elements are compared by user supplied function.\"\n    ],\n    \"array_diff_ukey\": [\n        \"array array_diff_ukey(array arr1, array arr2 [, array ...], callback key_comp_func)\",\n        \"Returns the entries of arr1 that have keys which are not present in any of the others arguments. User supplied function is used for comparing the keys. This function is like array_udiff() but works on the keys instead of the values. The associativity is preserved.\"\n    ],\n    \"array_fill\": [\n        \"array array_fill(int start_key, int num, mixed val)\",\n        \"Create an array containing num elements starting with index start_key each initialized to val\"\n    ],\n    \"array_fill_keys\": [\n        \"array array_fill_keys(array keys, mixed val)\",\n        \"Create an array using the elements of the first parameter as keys each initialized to val\"\n    ],\n    \"array_filter\": [\n        \"array array_filter(array input [, mixed callback])\",\n        \"Filters elements from the array via the callback.\"\n    ],\n    \"array_flip\": [\n        \"array array_flip(array input)\",\n        \"Return array with key <-> value flipped\"\n    ],\n    \"array_intersect\": [\n        \"array array_intersect(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments\"\n    ],\n    \"array_intersect_assoc\": [\n        \"array array_intersect_assoc(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check\"\n    ],\n    \"array_intersect_key\": [\n        \"array array_intersect_key(array arr1, array arr2 [, array ...])\",\n        \"Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). Equivalent of array_intersect_assoc() but does not do compare of the data.\"\n    ],\n    \"array_intersect_uassoc\": [\n        \"array array_intersect_uassoc(array arr1, array arr2 [, array ...], callback key_compare_func)\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check and they are compared by using an user-supplied callback.\"\n    ],\n    \"array_intersect_ukey\": [\n        \"array array_intersect_ukey(array arr1, array arr2 [, array ...], callback key_compare_func)\",\n        \"Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). The comparison of the keys is performed by a user supplied function. Equivalent of array_intersect_uassoc() but does not do compare of the data.\"\n    ],\n    \"array_key_exists\": [\n        \"bool array_key_exists(mixed key, array search)\",\n        \"Checks if the given key or index exists in the array\"\n    ],\n    \"array_keys\": [\n        \"array array_keys(array input [, mixed search_value[, bool strict]])\",\n        \"Return just the keys from the input array, optionally only for the specified search_value\"\n    ],\n    \"array_key_first\": [\n        \"mixed array_key_first(array arr)\",\n        \"Returns the first key of arr if the array is not empty; NULL otherwise\"\n    ],\n    \"array_key_last\": [\n        \"mixed array_key_last(array arr)\",\n        \"Returns the last key of arr if the array is not empty; NULL otherwise\"\n    ],\n    \"array_map\": [\n        \"array array_map(mixed callback, array input1 [, array input2 ,...])\",\n        \"Applies the callback to the elements in given arrays.\"\n    ],\n    \"array_merge\": [\n        \"array array_merge(array arr1, array arr2 [, array ...])\",\n        \"Merges elements from passed arrays into one array\"\n    ],\n    \"array_merge_recursive\": [\n        \"array array_merge_recursive(array arr1, array arr2 [, array ...])\",\n        \"Recursively merges elements from passed arrays into one array\"\n    ],\n    \"array_multisort\": [\n        \"bool array_multisort(array ar1 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]], ...])\",\n        \"Sort multiple arrays at once similar to how ORDER BY clause works in SQL\"\n    ],\n    \"array_pad\": [\n        \"array array_pad(array input, int pad_size, mixed pad_value)\",\n        \"Returns a copy of input array padded with pad_value to size pad_size\"\n    ],\n    \"array_pop\": [\n        \"mixed array_pop(array stack)\",\n        \"Pops an element off the end of the array\"\n    ],\n    \"array_product\": [\n        \"mixed array_product(array input)\",\n        \"Returns the product of the array entries\"\n    ],\n    \"array_push\": [\n        \"int array_push(array stack, mixed var [, mixed ...])\",\n        \"Pushes elements onto the end of the array\"\n    ],\n    \"array_rand\": [\n        \"mixed array_rand(array input [, int num_req])\",\n        \"Return key/keys for random entry/entries in the array\"\n    ],\n    \"array_reduce\": [\n        \"mixed array_reduce(array input, mixed callback [, mixed initial])\",\n        \"Iteratively reduce the array to a single value via the callback.\"\n    ],\n    \"array_replace\": [\n        \"array array_replace(array arr1, array arr2 [, array ...])\",\n        \"Replaces elements from passed arrays into one array\"\n    ],\n    \"array_replace_recursive\": [\n        \"array array_replace_recursive(array arr1, array arr2 [, array ...])\",\n        \"Recursively replaces elements from passed arrays into one array\"\n    ],\n    \"array_reverse\": [\n        \"array array_reverse(array input [, bool preserve keys])\",\n        \"Return input as a new array with the order of the entries reversed\"\n    ],\n    \"array_search\": [\n        \"mixed array_search(mixed needle, array haystack [, bool strict])\",\n        \"Searches the array for a given value and returns the corresponding key if successful\"\n    ],\n    \"array_shift\": [\n        \"mixed array_shift(array stack)\",\n        \"Pops an element off the beginning of the array\"\n    ],\n    \"array_slice\": [\n        \"array array_slice(array input, int offset [, int length [, bool preserve_keys]])\",\n        \"Returns elements specified by offset and length\"\n    ],\n    \"array_splice\": [\n        \"array array_splice(array input, int offset [, int length [, array replacement]])\",\n        \"Removes the elements designated by offset and length and replace them with supplied array\"\n    ],\n    \"array_sum\": [\n        \"mixed array_sum(array input)\",\n        \"Returns the sum of the array entries\"\n    ],\n    \"array_udiff\": [\n        \"array array_udiff(array arr1, array arr2 [, array ...], callback data_comp_func)\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments. Elements are compared by user supplied function.\"\n    ],\n    \"array_udiff_assoc\": [\n        \"array array_udiff_assoc(array arr1, array arr2 [, array ...], callback key_comp_func)\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Keys are compared by user supplied function.\"\n    ],\n    \"array_udiff_uassoc\": [\n        \"array array_udiff_uassoc(array arr1, array arr2 [, array ...], callback data_comp_func, callback key_comp_func)\",\n        \"Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Keys and elements are compared by user supplied functions.\"\n    ],\n    \"array_uintersect\": [\n        \"array array_uintersect(array arr1, array arr2 [, array ...], callback data_compare_func)\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments. Data is compared by using an user-supplied callback.\"\n    ],\n    \"array_uintersect_assoc\": [\n        \"array array_uintersect_assoc(array arr1, array arr2 [, array ...], callback data_compare_func)\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check. Data is compared by using an user-supplied callback.\"\n    ],\n    \"array_uintersect_uassoc\": [\n        \"array array_uintersect_uassoc(array arr1, array arr2 [, array ...], callback data_compare_func, callback key_compare_func)\",\n        \"Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check. Both data and keys are compared by using user-supplied callbacks.\"\n    ],\n    \"array_unique\": [\n        \"array array_unique(array input [, int sort_flags])\",\n        \"Removes duplicate values from array\"\n    ],\n    \"array_unshift\": [\n        \"int array_unshift(array stack, mixed var [, mixed ...])\",\n        \"Pushes elements onto the beginning of the array\"\n    ],\n    \"array_values\": [\n        \"array array_values(array input)\",\n        \"Return just the values from the input array\"\n    ],\n    \"array_walk\": [\n        \"bool array_walk(array input, string funcname [, mixed userdata])\",\n        \"Apply a user function to every member of an array\"\n    ],\n    \"array_walk_recursive\": [\n        \"bool array_walk_recursive(array input, string funcname [, mixed userdata])\",\n        \"Apply a user function recursively to every member of an array\"\n    ],\n    \"arsort\": [\n        \"bool arsort(array &array_arg [, int sort_flags])\",\n        \"Sort an array in reverse order and maintain index association\"\n    ],\n    \"asin\": [\n        \"float asin(float number)\",\n        \"Returns the arc sine of the number in radians\"\n    ],\n    \"asinh\": [\n        \"float asinh(float number)\",\n        \"Returns the inverse hyperbolic sine of the number, i.e. the value whose hyperbolic sine is number\"\n    ],\n    \"asort\": [\n        \"bool asort(array &array_arg [, int sort_flags])\",\n        \"Sort an array and maintain index association\"\n    ],\n    \"assert\": [\n        \"int assert(string|bool assertion)\",\n        \"Checks if assertion is false\"\n    ],\n    \"assert_options\": [\n        \"mixed assert_options(int what [, mixed value])\",\n        \"Set/get the various assert flags\"\n    ],\n    \"atan\": [\n        \"float atan(float number)\",\n        \"Returns the arc tangent of the number in radians\"\n    ],\n    \"atan2\": [\n        \"float atan2(float y, float x)\",\n        \"Returns the arc tangent of y/x, with the resulting quadrant determined by the signs of y and x\"\n    ],\n    \"atanh\": [\n        \"float atanh(float number)\",\n        \"Returns the inverse hyperbolic tangent of the number, i.e. the value whose hyperbolic tangent is number\"\n    ],\n    \"attachIterator\": [\n        \"void attachIterator(Iterator iterator[, mixed info])\",\n        \"Attach a new iterator\"\n    ],\n    \"base64_decode\": [\n        \"string base64_decode(string str[, bool strict])\",\n        \"Decodes string using MIME base64 algorithm\"\n    ],\n    \"base64_encode\": [\n        \"string base64_encode(string str)\",\n        \"Encodes string using MIME base64 algorithm\"\n    ],\n    \"base_convert\": [\n        \"string base_convert(string number, int frombase, int tobase)\",\n        \"Converts a number in a string from any base <= 36 to any base <= 36\"\n    ],\n    \"basename\": [\n        \"string basename(string path [, string suffix])\",\n        \"Returns the filename component of the path\"\n    ],\n    \"bcadd\": [\n        \"string bcadd(string left_operand, string right_operand [, int scale])\",\n        \"Returns the sum of two arbitrary precision numbers\"\n    ],\n    \"bccomp\": [\n        \"int bccomp(string left_operand, string right_operand [, int scale])\",\n        \"Compares two arbitrary precision numbers\"\n    ],\n    \"bcdiv\": [\n        \"string bcdiv(string left_operand, string right_operand [, int scale])\",\n        \"Returns the quotient of two arbitrary precision numbers (division)\"\n    ],\n    \"bcmod\": [\n        \"string bcmod(string left_operand, string right_operand)\",\n        \"Returns the modulus of the two arbitrary precision operands\"\n    ],\n    \"bcmul\": [\n        \"string bcmul(string left_operand, string right_operand [, int scale])\",\n        \"Returns the multiplication of two arbitrary precision numbers\"\n    ],\n    \"bcpow\": [\n        \"string bcpow(string x, string y [, int scale])\",\n        \"Returns the value of an arbitrary precision number raised to the power of another\"\n    ],\n    \"bcpowmod\": [\n        \"string bcpowmod(string x, string y, string mod [, int scale])\",\n        \"Returns the value of an arbitrary precision number raised to the power of another reduced by a modulous\"\n    ],\n    \"bcscale\": [\n        \"bool bcscale(int scale)\",\n        \"Sets default scale parameter for all bc math functions\"\n    ],\n    \"bcsqrt\": [\n        \"string bcsqrt(string operand [, int scale])\",\n        \"Returns the square root of an arbitray precision number\"\n    ],\n    \"bcsub\": [\n        \"string bcsub(string left_operand, string right_operand [, int scale])\",\n        \"Returns the difference between two arbitrary precision numbers\"\n    ],\n    \"bin2hex\": [\n        \"string bin2hex(string data)\",\n        \"Converts the binary representation of data to hex\"\n    ],\n    \"bind_textdomain_codeset\": [\n        \"string bind_textdomain_codeset (string domain, string codeset)\",\n        \"Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.\"\n    ],\n    \"bindec\": [\n        \"int bindec(string binary_number)\",\n        \"Returns the decimal equivalent of the binary number\"\n    ],\n    \"bindtextdomain\": [\n        \"string bindtextdomain(string domain_name, string dir)\",\n        \"Bind to the text domain domain_name, looking for translations in dir. Returns the current domain\"\n    ],\n    \"birdstep_autocommit\": [\n        \"bool birdstep_autocommit(int index)\",\n        \"\"\n    ],\n    \"birdstep_close\": [\n        \"bool birdstep_close(int id)\",\n        \"\"\n    ],\n    \"birdstep_commit\": [\n        \"bool birdstep_commit(int index)\",\n        \"\"\n    ],\n    \"birdstep_connect\": [\n        \"int birdstep_connect(string server, string user, string pass)\",\n        \"\"\n    ],\n    \"birdstep_exec\": [\n        \"int birdstep_exec(int index, string exec_str)\",\n        \"\"\n    ],\n    \"birdstep_fetch\": [\n        \"bool birdstep_fetch(int index)\",\n        \"\"\n    ],\n    \"birdstep_fieldname\": [\n        \"string birdstep_fieldname(int index, int col)\",\n        \"\"\n    ],\n    \"birdstep_fieldnum\": [\n        \"int birdstep_fieldnum(int index)\",\n        \"\"\n    ],\n    \"birdstep_freeresult\": [\n        \"bool birdstep_freeresult(int index)\",\n        \"\"\n    ],\n    \"birdstep_off_autocommit\": [\n        \"bool birdstep_off_autocommit(int index)\",\n        \"\"\n    ],\n    \"birdstep_result\": [\n        \"mixed birdstep_result(int index, mixed col)\",\n        \"\"\n    ],\n    \"birdstep_rollback\": [\n        \"bool birdstep_rollback(int index)\",\n        \"\"\n    ],\n    \"bzcompress\": [\n        \"string bzcompress(string source [, int blocksize100k [, int workfactor]])\",\n        \"Compresses a string into BZip2 encoded data\"\n    ],\n    \"bzdecompress\": [\n        \"string bzdecompress(string source [, int small])\",\n        \"Decompresses BZip2 compressed data\"\n    ],\n    \"bzerrno\": [\n        \"int bzerrno(resource bz)\",\n        \"Returns the error number\"\n    ],\n    \"bzerror\": [\n        \"array bzerror(resource bz)\",\n        \"Returns the error number and error string in an associative array\"\n    ],\n    \"bzerrstr\": [\n        \"string bzerrstr(resource bz)\",\n        \"Returns the error string\"\n    ],\n    \"bzopen\": [\n        \"resource bzopen(string|int file|fp, string mode)\",\n        \"Opens a new BZip2 stream\"\n    ],\n    \"bzread\": [\n        \"string bzread(resource bz[, int length])\",\n        \"Reads up to length bytes from a BZip2 stream, or 1024 bytes if length is not specified\"\n    ],\n    \"cal_days_in_month\": [\n        \"int cal_days_in_month(int calendar, int month, int year)\",\n        \"Returns the number of days in a month for a given year and calendar\"\n    ],\n    \"cal_from_jd\": [\n        \"array cal_from_jd(int jd, int calendar)\",\n        \"Converts from Julian Day Count to a supported calendar and return extended information\"\n    ],\n    \"cal_info\": [\n        \"array cal_info([int calendar])\",\n        \"Returns information about a particular calendar\"\n    ],\n    \"cal_to_jd\": [\n        \"int cal_to_jd(int calendar, int month, int day, int year)\",\n        \"Converts from a supported calendar to Julian Day Count\"\n    ],\n    \"call_user_func\": [\n        \"mixed call_user_func(mixed function_name [, mixed parmeter] [, mixed ...])\",\n        \"Call a user function which is the first parameter\"\n    ],\n    \"call_user_func_array\": [\n        \"mixed call_user_func_array(string function_name, array parameters)\",\n        \"Call a user function which is the first parameter with the arguments contained in array\"\n    ],\n    \"call_user_method\": [\n        \"mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...])\",\n        \"Call a user method on a specific object or class\"\n    ],\n    \"call_user_method_array\": [\n        \"mixed call_user_method_array(string method_name, mixed object, array params)\",\n        \"Call a user method on a specific object or class using a parameter array\"\n    ],\n    \"ceil\": [\n        \"float ceil(float number)\",\n        \"Returns the next highest integer value of the number\"\n    ],\n    \"chdir\": [\n        \"bool chdir(string directory)\",\n        \"Change the current directory\"\n    ],\n    \"checkdate\": [\n        \"bool checkdate(int month, int day, int year)\",\n        \"Returns true(1) if it is a valid date in gregorian calendar\"\n    ],\n    \"chgrp\": [\n        \"bool chgrp(string filename, mixed group)\",\n        \"Change file group\"\n    ],\n    \"chmod\": [\n        \"bool chmod(string filename, int mode)\",\n        \"Change file mode\"\n    ],\n    \"chown\": [\n        \"bool chown(string filename, mixed user)\",\n        \"Change file owner\"\n    ],\n    \"chr\": [\n        \"string chr(int ascii)\",\n        \"Converts ASCII code to a character\"\n    ],\n    \"chroot\": [\n        \"bool chroot(string directory)\",\n        \"Change root directory\"\n    ],\n    \"chunk_split\": [\n        \"string chunk_split(string str [, int chunklen [, string ending]])\",\n        \"Returns split line\"\n    ],\n    \"class_alias\": [\n        \"bool class_alias(string user_class_name , string alias_name [, bool autoload])\",\n        \"Creates an alias for user defined class\"\n    ],\n    \"class_exists\": [\n        \"bool class_exists(string classname [, bool autoload])\",\n        \"Checks if the class exists\"\n    ],\n    \"class_implements\": [\n        \"array class_implements(mixed what [, bool autoload ])\",\n        \"Return all classes and interfaces implemented by SPL\"\n    ],\n    \"class_parents\": [\n        \"array class_parents(object instance [, bool autoload = true])\",\n        \"Return an array containing the names of all parent classes\"\n    ],\n    \"clearstatcache\": [\n        \"void clearstatcache([bool clear_realpath_cache[, string filename]])\",\n        \"Clear file stat cache\"\n    ],\n    \"closedir\": [\n        \"void closedir([resource dir_handle])\",\n        \"Close directory connection identified by the dir_handle\"\n    ],\n    \"closelog\": [\n        \"bool closelog()\",\n        \"Close connection to system logger\"\n    ],\n    \"collator_asort\": [\n        \"bool collator_asort( Collator $coll, array(string) $arr )\",\n        \"* Sort array using specified collator, maintaining index association.\"\n    ],\n    \"collator_compare\": [\n        \"int collator_compare( Collator $coll, string $str1, string $str2 )\",\n        \"* Compare two strings.\"\n    ],\n    \"collator_create\": [\n        \"Collator collator_create( string $locale )\",\n        \"* Create collator.\"\n    ],\n    \"collator_get_attribute\": [\n        \"int collator_get_attribute( Collator $coll, int $attr )\",\n        \"* Get collation attribute value.\"\n    ],\n    \"collator_get_error_code\": [\n        \"int collator_get_error_code( Collator $coll )\",\n        \"* Get collator's last error code.\"\n    ],\n    \"collator_get_error_message\": [\n        \"string collator_get_error_message( Collator $coll )\",\n        \"* Get text description for collator's last error code.\"\n    ],\n    \"collator_get_locale\": [\n        \"string collator_get_locale( Collator $coll, int $type )\",\n        \"* Gets the locale name of the collator.\"\n    ],\n    \"collator_get_sort_key\": [\n        \"bool collator_get_sort_key( Collator $coll, string $str )\",\n        \"* Get a sort key for a string from a Collator. }}}\"\n    ],\n    \"collator_get_strength\": [\n        \"int collator_get_strength(Collator coll)\",\n        \"* Returns the current collation strength.\"\n    ],\n    \"collator_set_attribute\": [\n        \"bool collator_set_attribute( Collator $coll, int $attr, int $val )\",\n        \"* Set collation attribute.\"\n    ],\n    \"collator_set_strength\": [\n        \"bool collator_set_strength(Collator coll, int strength)\",\n        \"* Set the collation strength.\"\n    ],\n    \"collator_sort\": [\n        \"bool collator_sort(  Collator $coll, array(string) $arr [, int $sort_flags] )\",\n        \"* Sort array using specified collator.\"\n    ],\n    \"collator_sort_with_sort_keys\": [\n        \"bool collator_sort_with_sort_keys( Collator $coll, array(string) $arr )\",\n        \"* Equivalent to standard PHP sort using Collator.  * Uses ICU ucol_getSortKey for performance.\"\n    ],\n    \"com_create_guid\": [\n        \"string com_create_guid()\",\n        \"Generate a globally unique identifier (GUID)\"\n    ],\n    \"com_event_sink\": [\n        \"bool com_event_sink(object comobject, object sinkobject [, mixed sinkinterface])\",\n        \"Connect events from a COM object to a PHP object\"\n    ],\n    \"com_get_active_object\": [\n        \"object com_get_active_object(string progid [, int code_page ])\",\n        \"Returns a handle to an already running instance of a COM object\"\n    ],\n    \"com_load_typelib\": [\n        \"bool com_load_typelib(string typelib_name [, int case_insensitive])\",\n        \"Loads a Typelibrary and registers its constants\"\n    ],\n    \"com_message_pump\": [\n        \"bool com_message_pump([int timeoutms])\",\n        \"Process COM messages, sleeping for up to timeoutms milliseconds\"\n    ],\n    \"com_print_typeinfo\": [\n        \"bool com_print_typeinfo(object comobject | string typelib, string dispinterface, bool wantsink)\",\n        \"Print out a PHP class definition for a dispatchable interface\"\n    ],\n    \"compact\": [\n        \"array compact(mixed var_names [, mixed ...])\",\n        \"Creates a hash containing variables and their values\"\n    ],\n    \"compose_locale\": [\n        \"static string compose_locale($array)\",\n        \"* Creates a locale by combining the parts of locale-ID passed  * }}}\"\n    ],\n    \"confirm_extname_compiled\": [\n        \"string confirm_extname_compiled(string arg)\",\n        \"Return a string to confirm that the module is compiled in\"\n    ],\n    \"connection_aborted\": [\n        \"int connection_aborted()\",\n        \"Returns true if client disconnected\"\n    ],\n    \"connection_status\": [\n        \"int connection_status()\",\n        \"Returns the connection status bitfield\"\n    ],\n    \"constant\": [\n        \"mixed constant(string const_name)\",\n        \"Given the name of a constant this function will return the constant's associated value\"\n    ],\n    \"convert_cyr_string\": [\n        \"string convert_cyr_string(string str, string from, string to)\",\n        \"Convert from one Cyrillic character set to another\"\n    ],\n    \"convert_uudecode\": [\n        \"string convert_uudecode(string data)\",\n        \"decode a uuencoded string\"\n    ],\n    \"convert_uuencode\": [\n        \"string convert_uuencode(string data)\",\n        \"uuencode a string\"\n    ],\n    \"copy\": [\n        \"bool copy(string source_file, string destination_file [, resource context])\",\n        \"Copy a file\"\n    ],\n    \"cos\": [\n        \"float cos(float number)\",\n        \"Returns the cosine of the number in radians\"\n    ],\n    \"cosh\": [\n        \"float cosh(float number)\",\n        \"Returns the hyperbolic cosine of the number, defined as (exp(number) + exp(-number))/2\"\n    ],\n    \"count\": [\n        \"int count(mixed var [, int mode])\",\n        \"Count the number of elements in a variable (usually an array)\"\n    ],\n    \"count_chars\": [\n        \"mixed count_chars(string input [, int mode])\",\n        \"Returns info about what characters are used in input\"\n    ],\n    \"crc32\": [\n        \"string crc32(string str)\",\n        \"Calculate the crc32 polynomial of a string\"\n    ],\n    \"create_function\": [\n        \"string create_function(string args, string code)\",\n        \"Creates an anonymous function, and returns its name\"\n    ],\n    \"crypt\": [\n        \"string crypt(string str [, string salt])\",\n        \"Hash a string\"\n    ],\n    \"ctype_alnum\": [\n        \"bool ctype_alnum(mixed c)\",\n        \"Checks for alphanumeric character(s)\"\n    ],\n    \"ctype_alpha\": [\n        \"bool ctype_alpha(mixed c)\",\n        \"Checks for alphabetic character(s)\"\n    ],\n    \"ctype_cntrl\": [\n        \"bool ctype_cntrl(mixed c)\",\n        \"Checks for control character(s)\"\n    ],\n    \"ctype_digit\": [\n        \"bool ctype_digit(mixed c)\",\n        \"Checks for numeric character(s)\"\n    ],\n    \"ctype_graph\": [\n        \"bool ctype_graph(mixed c)\",\n        \"Checks for any printable character(s) except space\"\n    ],\n    \"ctype_lower\": [\n        \"bool ctype_lower(mixed c)\",\n        \"Checks for lowercase character(s)\"\n    ],\n    \"ctype_print\": [\n        \"bool ctype_print(mixed c)\",\n        \"Checks for printable character(s)\"\n    ],\n    \"ctype_punct\": [\n        \"bool ctype_punct(mixed c)\",\n        \"Checks for any printable character which is not whitespace or an alphanumeric character\"\n    ],\n    \"ctype_space\": [\n        \"bool ctype_space(mixed c)\",\n        \"Checks for whitespace character(s)\"\n    ],\n    \"ctype_upper\": [\n        \"bool ctype_upper(mixed c)\",\n        \"Checks for uppercase character(s)\"\n    ],\n    \"ctype_xdigit\": [\n        \"bool ctype_xdigit(mixed c)\",\n        \"Checks for character(s) representing a hexadecimal digit\"\n    ],\n    \"curl_close\": [\n        \"void curl_close(resource ch)\",\n        \"Close a cURL session\"\n    ],\n    \"curl_copy_handle\": [\n        \"resource curl_copy_handle(resource ch)\",\n        \"Copy a cURL handle along with all of it's preferences\"\n    ],\n    \"curl_errno\": [\n        \"int curl_errno(resource ch)\",\n        \"Return an integer containing the last error number\"\n    ],\n    \"curl_error\": [\n        \"string curl_error(resource ch)\",\n        \"Return a string contain the last error for the current session\"\n    ],\n    \"curl_exec\": [\n        \"bool curl_exec(resource ch)\",\n        \"Perform a cURL session\"\n    ],\n    \"curl_getinfo\": [\n        \"mixed curl_getinfo(resource ch [, int option])\",\n        \"Get information regarding a specific transfer\"\n    ],\n    \"curl_init\": [\n        \"resource curl_init([string url])\",\n        \"Initialize a cURL session\"\n    ],\n    \"curl_multi_add_handle\": [\n        \"int curl_multi_add_handle(resource mh, resource ch)\",\n        \"Add a normal cURL handle to a cURL multi handle\"\n    ],\n    \"curl_multi_close\": [\n        \"void curl_multi_close(resource mh)\",\n        \"Close a set of cURL handles\"\n    ],\n    \"curl_multi_exec\": [\n        \"int curl_multi_exec(resource mh, int &still_running)\",\n        \"Run the sub-connections of the current cURL handle\"\n    ],\n    \"curl_multi_getcontent\": [\n        \"string curl_multi_getcontent(resource ch)\",\n        \"Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set\"\n    ],\n    \"curl_multi_info_read\": [\n        \"array curl_multi_info_read(resource mh [, long msgs_in_queue])\",\n        \"Get information about the current transfers\"\n    ],\n    \"curl_multi_init\": [\n        \"resource curl_multi_init()\",\n        \"Returns a new cURL multi handle\"\n    ],\n    \"curl_multi_remove_handle\": [\n        \"int curl_multi_remove_handle(resource mh, resource ch)\",\n        \"Remove a multi handle from a set of cURL handles\"\n    ],\n    \"curl_multi_select\": [\n        \"int curl_multi_select(resource mh[, double timeout])\",\n        \"Get all the sockets associated with the cURL extension, which can then be \\\"selected\\\"\"\n    ],\n    \"curl_setopt\": [\n        \"bool curl_setopt(resource ch, int option, mixed value)\",\n        \"Set an option for a cURL transfer\"\n    ],\n    \"curl_setopt_array\": [\n        \"bool curl_setopt_array(resource ch, array options)\",\n        \"Set an array of option for a cURL transfer\"\n    ],\n    \"curl_version\": [\n        \"array curl_version([int version])\",\n        \"Return cURL version information.\"\n    ],\n    \"current\": [\n        \"mixed current(array array_arg)\",\n        \"Return the element currently pointed to by the internal array pointer\"\n    ],\n    \"date\": [\n        \"string date(string format [, long timestamp])\",\n        \"Format a local date/time\"\n    ],\n    \"date_add\": [\n        \"DateTime date_add(DateTime object, DateInterval interval)\",\n        \"Adds an interval to the current date in object.\"\n    ],\n    \"date_create\": [\n        \"DateTime date_create([string time[, DateTimeZone object]])\",\n        \"Returns new DateTime object\"\n    ],\n    \"date_create_from_format\": [\n        \"DateTime date_create_from_format(string format, string time[, DateTimeZone object])\",\n        \"Returns new DateTime object formatted according to the specified format\"\n    ],\n    \"date_date_set\": [\n        \"DateTime date_date_set(DateTime object, long year, long month, long day)\",\n        \"Sets the date.\"\n    ],\n    \"date_default_timezone_get\": [\n        \"string date_default_timezone_get()\",\n        \"Gets the default timezone used by all date/time functions in a script\"\n    ],\n    \"date_default_timezone_set\": [\n        \"bool date_default_timezone_set(string timezone_identifier)\",\n        \"Sets the default timezone used by all date/time functions in a script\"\n    ],\n    \"date_diff\": [\n        \"DateInterval date_diff(DateTime object [, bool absolute])\",\n        \"Returns the difference between two DateTime objects.\"\n    ],\n    \"date_format\": [\n        \"string date_format(DateTime object, string format)\",\n        \"Returns date formatted according to given format\"\n    ],\n    \"date_get_last_errors\": [\n        \"array date_get_last_errors()\",\n        \"Returns the warnings and errors found while parsing a date/time string.\"\n    ],\n    \"date_interval_create_from_date_string\": [\n        \"DateInterval date_interval_create_from_date_string(string time)\",\n        \"Uses the normal date parsers and sets up a DateInterval from the relative parts of the parsed string\"\n    ],\n    \"date_interval_format\": [\n        \"string date_interval_format(DateInterval object, string format)\",\n        \"Formats the interval.\"\n    ],\n    \"date_isodate_set\": [\n        \"DateTime date_isodate_set(DateTime object, long year, long week[, long day])\",\n        \"Sets the ISO date.\"\n    ],\n    \"date_modify\": [\n        \"DateTime date_modify(DateTime object, string modify)\",\n        \"Alters the timestamp.\"\n    ],\n    \"date_offset_get\": [\n        \"long date_offset_get(DateTime object)\",\n        \"Returns the DST offset.\"\n    ],\n    \"date_parse\": [\n        \"array date_parse(string date)\",\n        \"Returns associative array with detailed info about given date\"\n    ],\n    \"date_parse_from_format\": [\n        \"array date_parse_from_format(string format, string date)\",\n        \"Returns associative array with detailed info about given date\"\n    ],\n    \"date_sub\": [\n        \"DateTime date_sub(DateTime object, DateInterval interval)\",\n        \"Subtracts an interval to the current date in object.\"\n    ],\n    \"date_sun_info\": [\n        \"array date_sun_info(long time, float latitude, float longitude)\",\n        \"Returns an array with information about sun set/rise and twilight begin/end\"\n    ],\n    \"date_sunrise\": [\n        \"mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])\",\n        \"Returns time of sunrise for a given day and location\"\n    ],\n    \"date_sunset\": [\n        \"mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])\",\n        \"Returns time of sunset for a given day and location\"\n    ],\n    \"date_time_set\": [\n        \"DateTime date_time_set(DateTime object, long hour, long minute[, long second])\",\n        \"Sets the time.\"\n    ],\n    \"date_timestamp_get\": [\n        \"long date_timestamp_get(DateTime object)\",\n        \"Gets the Unix timestamp.\"\n    ],\n    \"date_timestamp_set\": [\n        \"DateTime date_timestamp_set(DateTime object, long unixTimestamp)\",\n        \"Sets the date and time based on an Unix timestamp.\"\n    ],\n    \"date_timezone_get\": [\n        \"DateTimeZone date_timezone_get(DateTime object)\",\n        \"Return new DateTimeZone object relative to give DateTime\"\n    ],\n    \"date_timezone_set\": [\n        \"DateTime date_timezone_set(DateTime object, DateTimeZone object)\",\n        \"Sets the timezone for the DateTime object.\"\n    ],\n    \"datefmt_create\": [\n        \"IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )\",\n        \"* Create formatter.\"\n    ],\n    \"datefmt_format\": [\n        \"string datefmt_format( [mixed]int $args or array $args )\",\n        \"* Format the time value as a string. }}}\"\n    ],\n    \"datefmt_get_calendar\": [\n        \"string datefmt_get_calendar( IntlDateFormatter $mf )\",\n        \"* Get formatter calendar.\"\n    ],\n    \"datefmt_get_datetype\": [\n        \"string datefmt_get_datetype( IntlDateFormatter $mf )\",\n        \"* Get formatter datetype.\"\n    ],\n    \"datefmt_get_error_code\": [\n        \"int datefmt_get_error_code( IntlDateFormatter $nf )\",\n        \"* Get formatter's last error code.\"\n    ],\n    \"datefmt_get_error_message\": [\n        \"string datefmt_get_error_message( IntlDateFormatter $coll )\",\n        \"* Get text description for formatter's last error code.\"\n    ],\n    \"datefmt_get_locale\": [\n        \"string datefmt_get_locale(IntlDateFormatter $mf)\",\n        \"* Get formatter locale.\"\n    ],\n    \"datefmt_get_pattern\": [\n        \"string datefmt_get_pattern( IntlDateFormatter $mf )\",\n        \"* Get formatter pattern.\"\n    ],\n    \"datefmt_get_timetype\": [\n        \"string datefmt_get_timetype( IntlDateFormatter $mf )\",\n        \"* Get formatter timetype.\"\n    ],\n    \"datefmt_get_timezone_id\": [\n        \"string datefmt_get_timezone_id( IntlDateFormatter $mf )\",\n        \"* Get formatter timezone_id.\"\n    ],\n    \"datefmt_isLenient\": [\n        \"string datefmt_isLenient(IntlDateFormatter $mf)\",\n        \"* Get formatter locale.\"\n    ],\n    \"datefmt_localtime\": [\n        \"integer datefmt_localtime( IntlDateFormatter $fmt, string $text_to_parse[, int $parse_pos ])\",\n        \"* Parse the string $value to a localtime array  }}}\"\n    ],\n    \"datefmt_parse\": [\n        \"integer datefmt_parse( IntlDateFormatter $fmt, string $text_to_parse [, int $parse_pos] )\",\n        \"* Parse the string $value starting at parse_pos to a Unix timestamp -int }}}\"\n    ],\n    \"datefmt_setLenient\": [\n        \"string datefmt_setLenient(IntlDateFormatter $mf)\",\n        \"* Set formatter lenient.\"\n    ],\n    \"datefmt_set_calendar\": [\n        \"bool datefmt_set_calendar( IntlDateFormatter $mf, int $calendar )\",\n        \"* Set formatter calendar.\"\n    ],\n    \"datefmt_set_pattern\": [\n        \"bool datefmt_set_pattern( IntlDateFormatter $mf, string $pattern )\",\n        \"* Set formatter pattern.\"\n    ],\n    \"datefmt_set_timezone_id\": [\n        \"bool datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)\",\n        \"* Set formatter timezone_id.\"\n    ],\n    \"dba_close\": [\n        \"void dba_close(resource handle)\",\n        \"Closes database\"\n    ],\n    \"dba_delete\": [\n        \"bool dba_delete(string key, resource handle)\",\n        \"Deletes the entry associated with key    If inifile: remove all other key lines\"\n    ],\n    \"dba_exists\": [\n        \"bool dba_exists(string key, resource handle)\",\n        \"Checks, if the specified key exists\"\n    ],\n    \"dba_fetch\": [\n        \"string dba_fetch(string key, [int skip ,] resource handle)\",\n        \"Fetches the data associated with key\"\n    ],\n    \"dba_firstkey\": [\n        \"string dba_firstkey(resource handle)\",\n        \"Resets the internal key pointer and returns the first key\"\n    ],\n    \"dba_handlers\": [\n        \"array dba_handlers([bool full_info])\",\n        \"List configured database handlers\"\n    ],\n    \"dba_insert\": [\n        \"bool dba_insert(string key, string value, resource handle)\",\n        \"If not inifile: Insert value as key, return false, if key exists already     If inifile: Add vakue as key (next instance of key)\"\n    ],\n    \"dba_key_split\": [\n        \"array|false dba_key_split(string key)\",\n        \"Splits an inifile key into an array of the form array(0=>group,1=>value_name) but returns false if input is false or null\"\n    ],\n    \"dba_list\": [\n        \"array dba_list()\",\n        \"List opened databases\"\n    ],\n    \"dba_nextkey\": [\n        \"string dba_nextkey(resource handle)\",\n        \"Returns the next key\"\n    ],\n    \"dba_open\": [\n        \"resource dba_open(string path, string mode [, string handlername, string ...])\",\n        \"Opens path using the specified handler in mode\"\n    ],\n    \"dba_optimize\": [\n        \"bool dba_optimize(resource handle)\",\n        \"Optimizes (e.g. clean up, vacuum) database\"\n    ],\n    \"dba_popen\": [\n        \"resource dba_popen(string path, string mode [, string handlername, string ...])\",\n        \"Opens path using the specified handler in mode persistently\"\n    ],\n    \"dba_replace\": [\n        \"bool dba_replace(string key, string value, resource handle)\",\n        \"Inserts value as key, replaces key, if key exists already    If inifile: remove all other key lines\"\n    ],\n    \"dba_sync\": [\n        \"bool dba_sync(resource handle)\",\n        \"Synchronizes database\"\n    ],\n    \"dcgettext\": [\n        \"string dcgettext(string domain_name, string msgid, long category)\",\n        \"Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist\"\n    ],\n    \"dcngettext\": [\n        \"string dcngettext(string domain, string msgid1, string msgid2, int n, int category)\",\n        \"Plural version of dcgettext()\"\n    ],\n    \"debug_backtrace\": [\n        \"array debug_backtrace([bool provide_object])\",\n        \"Return backtrace as array\"\n    ],\n    \"debug_print_backtrace\": [\n        \"void debug_print_backtrace()\",\n        \"Prints a PHP backtrace\"\n    ],\n    \"debug_zval_dump\": [\n        \"void debug_zval_dump(mixed var)\",\n        \"Dumps a string representation of an internal Zend value to output\"\n    ],\n    \"decbin\": [\n        \"string decbin(int decimal_number)\",\n        \"Returns a string containing a binary representation of the number\"\n    ],\n    \"dechex\": [\n        \"string dechex(int decimal_number)\",\n        \"Returns a string containing a hexadecimal representation of the given number\"\n    ],\n    \"decoct\": [\n        \"string decoct(int decimal_number)\",\n        \"Returns a string containing an octal representation of the given number\"\n    ],\n    \"define\": [\n        \"bool define(string constant_name, mixed value, bool case_insensitive=false)\",\n        \"Define a new constant\"\n    ],\n    \"define_syslog_variables\": [\n        \"void define_syslog_variables()\",\n        \"Initializes all syslog-related variables\"\n    ],\n    \"defined\": [\n        \"bool defined(string constant_name)\",\n        \"Check whether a constant exists\"\n    ],\n    \"deg2rad\": [\n        \"float deg2rad(float number)\",\n        \"Converts the number in degrees to the radian equivalent\"\n    ],\n    \"dgettext\": [\n        \"string dgettext(string domain_name, string msgid)\",\n        \"Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist\"\n    ],\n    \"die\": [\n        \"void die([mixed status])\",\n        \"Output a message and terminate the current script\"\n    ],\n    \"dir\": [\n        \"object dir(string directory[, resource context])\",\n        \"Directory class with properties, handle and class and methods read, rewind and close\"\n    ],\n    \"dirname\": [\n        \"string dirname(string path)\",\n        \"Returns the directory name component of the path\"\n    ],\n    \"disk_free_space\": [\n        \"float disk_free_space(string path)\",\n        \"Get free disk space for filesystem that path is on\"\n    ],\n    \"disk_total_space\": [\n        \"float disk_total_space(string path)\",\n        \"Get total disk space for filesystem that path is on\"\n    ],\n    \"display_disabled_function\": [\n        \"void display_disabled_function()\",\n        \"Dummy function which displays an error when a disabled function is called.\"\n    ],\n    \"dl\": [\n        \"int dl(string extension_filename)\",\n        \"Load a PHP extension at runtime\"\n    ],\n    \"dngettext\": [\n        \"string dngettext(string domain, string msgid1, string msgid2, int count)\",\n        \"Plural version of dgettext()\"\n    ],\n    \"dns_check_record\": [\n        \"bool dns_check_record(string host [, string type])\",\n        \"Check DNS records corresponding to a given Internet host name or IP address\"\n    ],\n    \"dns_get_mx\": [\n        \"bool dns_get_mx(string hostname, array mxhosts [, array weight])\",\n        \"Get MX records corresponding to a given Internet host name\"\n    ],\n    \"dns_get_record\": [\n        \"array|false dns_get_record(string hostname [, int type[, array authns, array addtl]])\",\n        \"Get any Resource Record corresponding to a given Internet host name\"\n    ],\n    \"dom_attr_is_id\": [\n        \"bool dom_attr_is_id()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId Since: DOM Level 3\"\n    ],\n    \"dom_characterdata_append_data\": [\n        \"void dom_characterdata_append_data(string arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F Since:\"\n    ],\n    \"dom_characterdata_delete_data\": [\n        \"void dom_characterdata_delete_data(int offset, int count)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 Since:\"\n    ],\n    \"dom_characterdata_insert_data\": [\n        \"void dom_characterdata_insert_data(int offset, string arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F Since:\"\n    ],\n    \"dom_characterdata_replace_data\": [\n        \"void dom_characterdata_replace_data(int offset, int count, string arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB Since:\"\n    ],\n    \"dom_characterdata_substring_data\": [\n        \"string dom_characterdata_substring_data(int offset, int count)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF Since:\"\n    ],\n    \"dom_document_adopt_node\": [\n        \"DOMNode dom_document_adopt_node(DOMNode source)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode Since: DOM Level 3\"\n    ],\n    \"dom_document_create_attribute\": [\n        \"DOMAttr dom_document_create_attribute(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198 Since:\"\n    ],\n    \"dom_document_create_attribute_ns\": [\n        \"DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS Since: DOM Level 2\"\n    ],\n    \"dom_document_create_cdatasection\": [\n        \"DOMCdataSection dom_document_create_cdatasection(string data)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8 Since:\"\n    ],\n    \"dom_document_create_comment\": [\n        \"DOMComment dom_document_create_comment(string data)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328 Since:\"\n    ],\n    \"dom_document_create_document_fragment\": [\n        \"DOMDocumentFragment dom_document_create_document_fragment()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5 Since:\"\n    ],\n    \"dom_document_create_element\": [\n        \"DOMElement dom_document_create_element(string tagName [, string value])\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since:\"\n    ],\n    \"dom_document_create_element_ns\": [\n        \"DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value])\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS Since: DOM Level 2\"\n    ],\n    \"dom_document_create_entity_reference\": [\n        \"DOMEntityReference dom_document_create_entity_reference(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE Since:\"\n    ],\n    \"dom_document_create_processing_instruction\": [\n        \"DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439 Since:\"\n    ],\n    \"dom_document_create_text_node\": [\n        \"DOMText dom_document_create_text_node(string data)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127 Since:\"\n    ],\n    \"dom_document_get_element_by_id\": [\n        \"DOMElement dom_document_get_element_by_id(string elementId)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId Since: DOM Level 2\"\n    ],\n    \"dom_document_get_elements_by_tag_name\": [\n        \"DOMNodeList dom_document_get_elements_by_tag_name(string tagname)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094 Since:\"\n    ],\n    \"dom_document_get_elements_by_tag_name_ns\": [\n        \"DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS Since: DOM Level 2\"\n    ],\n    \"dom_document_import_node\": [\n        \"DOMNode dom_document_import_node(DOMNode importedNode, bool deep)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode Since: DOM Level 2\"\n    ],\n    \"dom_document_load\": [\n        \"DOMNode dom_document_load(string source [, int options])\",\n        \"URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load Since: DOM Level 3\"\n    ],\n    \"dom_document_load_html\": [\n        \"DOMNode dom_document_load_html(string source)\",\n        \"Since: DOM extended\"\n    ],\n    \"dom_document_load_html_file\": [\n        \"DOMNode dom_document_load_html_file(string source)\",\n        \"Since: DOM extended\"\n    ],\n    \"dom_document_loadxml\": [\n        \"DOMNode dom_document_loadxml(string source [, int options])\",\n        \"URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML Since: DOM Level 3\"\n    ],\n    \"dom_document_normalize_document\": [\n        \"void dom_document_normalize_document()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument Since: DOM Level 3\"\n    ],\n    \"dom_document_relaxNG_validate_file\": [\n        \"bool dom_document_relaxNG_validate_file(string filename); */\",\n        \"PHP_FUNCTION(dom_document_relaxNG_validate_file) {  _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_relaxNG_validate_file\"\n    ],\n    \"dom_document_relaxNG_validate_xml\": [\n        \"bool dom_document_relaxNG_validate_xml(string source); */\",\n        \"PHP_FUNCTION(dom_document_relaxNG_validate_xml) {  _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_relaxNG_validate_xml\"\n    ],\n    \"dom_document_rename_node\": [\n        \"DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode Since: DOM Level 3\"\n    ],\n    \"dom_document_save\": [\n        \"int dom_document_save(string file)\",\n        \"Convenience method to save to file\"\n    ],\n    \"dom_document_save_html\": [\n        \"string dom_document_save_html()\",\n        \"Convenience method to output as html\"\n    ],\n    \"dom_document_save_html_file\": [\n        \"int dom_document_save_html_file(string file)\",\n        \"Convenience method to save to file as html\"\n    ],\n    \"dom_document_savexml\": [\n        \"string dom_document_savexml([node n])\",\n        \"URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML Since: DOM Level 3\"\n    ],\n    \"dom_document_schema_validate\": [\n        \"bool dom_document_schema_validate(string source); */\",\n        \"PHP_FUNCTION(dom_document_schema_validate_xml) {  _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_schema_validate\"\n    ],\n    \"dom_document_schema_validate_file\": [\n        \"bool dom_document_schema_validate_file(string filename); */\",\n        \"PHP_FUNCTION(dom_document_schema_validate_file) {  _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_schema_validate_file\"\n    ],\n    \"dom_document_validate\": [\n        \"bool dom_document_validate()\",\n        \"Since: DOM extended\"\n    ],\n    \"dom_document_xinclude\": [\n        \"int dom_document_xinclude([int options])\",\n        \"Substitutues xincludes in a DomDocument\"\n    ],\n    \"dom_domconfiguration_can_set_parameter\": [\n        \"bool dom_domconfiguration_can_set_parameter(string name, domuserdata value)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter Since:\"\n    ],\n    \"dom_domconfiguration_get_parameter\": [\n        \"domdomuserdata dom_domconfiguration_get_parameter(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter Since:\"\n    ],\n    \"dom_domconfiguration_set_parameter\": [\n        \"dom_void dom_domconfiguration_set_parameter(string name, domuserdata value)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-property Since:\"\n    ],\n    \"dom_domerrorhandler_handle_error\": [\n        \"dom_bool dom_domerrorhandler_handle_error(domerror error)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-ERRORS-DOMErrorHandler-handleError Since:\"\n    ],\n    \"dom_domimplementation_create_document\": [\n        \"DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument Since: DOM Level 2\"\n    ],\n    \"dom_domimplementation_create_document_type\": [\n        \"DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType Since: DOM Level 2\"\n    ],\n    \"dom_domimplementation_get_feature\": [\n        \"DOMNode dom_domimplementation_get_feature(string feature, string version)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature Since: DOM Level 3\"\n    ],\n    \"dom_domimplementation_has_feature\": [\n        \"bool dom_domimplementation_has_feature(string feature, string version)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7 Since:\"\n    ],\n    \"dom_domimplementationlist_item\": [\n        \"domdomimplementation dom_domimplementationlist_item(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item Since:\"\n    ],\n    \"dom_domimplementationsource_get_domimplementation\": [\n        \"domdomimplementation dom_domimplementationsource_get_domimplementation(string features)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl Since:\"\n    ],\n    \"dom_domimplementationsource_get_domimplementations\": [\n        \"domimplementationlist dom_domimplementationsource_get_domimplementations(string features)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls Since:\"\n    ],\n    \"dom_domstringlist_item\": [\n        \"domstring dom_domstringlist_item(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item Since:\"\n    ],\n    \"dom_element_get_attribute\": [\n        \"string dom_element_get_attribute(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9 Since:\"\n    ],\n    \"dom_element_get_attribute_node\": [\n        \"DOMAttr dom_element_get_attribute_node(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8 Since:\"\n    ],\n    \"dom_element_get_attribute_node_ns\": [\n        \"DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS Since: DOM Level 2\"\n    ],\n    \"dom_element_get_attribute_ns\": [\n        \"string dom_element_get_attribute_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS Since: DOM Level 2\"\n    ],\n    \"dom_element_get_elements_by_tag_name\": [\n        \"DOMNodeList dom_element_get_elements_by_tag_name(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D Since:\"\n    ],\n    \"dom_element_get_elements_by_tag_name_ns\": [\n        \"DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942 Since: DOM Level 2\"\n    ],\n    \"dom_element_has_attribute\": [\n        \"bool dom_element_has_attribute(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr Since: DOM Level 2\"\n    ],\n    \"dom_element_has_attribute_ns\": [\n        \"bool dom_element_has_attribute_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS Since: DOM Level 2\"\n    ],\n    \"dom_element_remove_attribute\": [\n        \"void dom_element_remove_attribute(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9 Since:\"\n    ],\n    \"dom_element_remove_attribute_node\": [\n        \"DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198 Since:\"\n    ],\n    \"dom_element_remove_attribute_ns\": [\n        \"void dom_element_remove_attribute_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS Since: DOM Level 2\"\n    ],\n    \"dom_element_set_attribute\": [\n        \"void dom_element_set_attribute(string name, string value)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082 Since:\"\n    ],\n    \"dom_element_set_attribute_node\": [\n        \"DOMAttr dom_element_set_attribute_node(DOMAttr newAttr)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154 Since:\"\n    ],\n    \"dom_element_set_attribute_node_ns\": [\n        \"DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS Since: DOM Level 2\"\n    ],\n    \"dom_element_set_attribute_ns\": [\n        \"void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS Since: DOM Level 2\"\n    ],\n    \"dom_element_set_id_attribute\": [\n        \"void dom_element_set_id_attribute(string name, bool isId)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr Since: DOM Level 3\"\n    ],\n    \"dom_element_set_id_attribute_node\": [\n        \"void dom_element_set_id_attribute_node(attr idAttr, bool isId)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode Since: DOM Level 3\"\n    ],\n    \"dom_element_set_id_attribute_ns\": [\n        \"void dom_element_set_id_attribute_ns(string namespaceURI, string localName, bool isId)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS Since: DOM Level 3\"\n    ],\n    \"dom_import_simplexml\": [\n        \"somNode dom_import_simplexml(sxeobject node)\",\n        \"Get a simplexml_element object from dom to allow for processing\"\n    ],\n    \"dom_namednodemap_get_named_item\": [\n        \"DOMNode dom_namednodemap_get_named_item(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549 Since:\"\n    ],\n    \"dom_namednodemap_get_named_item_ns\": [\n        \"DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS Since: DOM Level 2\"\n    ],\n    \"dom_namednodemap_item\": [\n        \"DOMNode dom_namednodemap_item(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9 Since:\"\n    ],\n    \"dom_namednodemap_remove_named_item\": [\n        \"DOMNode dom_namednodemap_remove_named_item(string name)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193 Since:\"\n    ],\n    \"dom_namednodemap_remove_named_item_ns\": [\n        \"DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS Since: DOM Level 2\"\n    ],\n    \"dom_namednodemap_set_named_item\": [\n        \"DOMNode dom_namednodemap_set_named_item(DOMNode arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788 Since:\"\n    ],\n    \"dom_namednodemap_set_named_item_ns\": [\n        \"DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS Since: DOM Level 2\"\n    ],\n    \"dom_namelist_get_name\": [\n        \"string dom_namelist_get_name(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName Since:\"\n    ],\n    \"dom_namelist_get_namespace_uri\": [\n        \"string dom_namelist_get_namespace_uri(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI Since:\"\n    ],\n    \"dom_node_append_child\": [\n        \"DomNode dom_node_append_child(DomNode newChild)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107 Since:\"\n    ],\n    \"dom_node_clone_node\": [\n        \"DomNode dom_node_clone_node(bool deep)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4 Since:\"\n    ],\n    \"dom_node_compare_document_position\": [\n        \"short dom_node_compare_document_position(DomNode other)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition Since: DOM Level 3\"\n    ],\n    \"dom_node_get_feature\": [\n        \"DomNode dom_node_get_feature(string feature, string version)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature Since: DOM Level 3\"\n    ],\n    \"dom_node_get_user_data\": [\n        \"mixed dom_node_get_user_data(string key)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData Since: DOM Level 3\"\n    ],\n    \"dom_node_has_attributes\": [\n        \"bool dom_node_has_attributes()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs Since: DOM Level 2\"\n    ],\n    \"dom_node_has_child_nodes\": [\n        \"bool dom_node_has_child_nodes()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187 Since:\"\n    ],\n    \"dom_node_insert_before\": [\n        \"domnode dom_node_insert_before(DomNode newChild, DomNode refChild)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727 Since:\"\n    ],\n    \"dom_node_is_default_namespace\": [\n        \"bool dom_node_is_default_namespace(string namespaceURI)\",\n        \"URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace Since: DOM Level 3\"\n    ],\n    \"dom_node_is_equal_node\": [\n        \"bool dom_node_is_equal_node(DomNode arg)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode Since: DOM Level 3\"\n    ],\n    \"dom_node_is_same_node\": [\n        \"bool dom_node_is_same_node(DomNode other)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode Since: DOM Level 3\"\n    ],\n    \"dom_node_is_supported\": [\n        \"bool dom_node_is_supported(string feature, string version)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports Since: DOM Level 2\"\n    ],\n    \"dom_node_lookup_namespace_uri\": [\n        \"string dom_node_lookup_namespace_uri(string prefix)\",\n        \"URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI Since: DOM Level 3\"\n    ],\n    \"dom_node_lookup_prefix\": [\n        \"string dom_node_lookup_prefix(string namespaceURI)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix Since: DOM Level 3\"\n    ],\n    \"dom_node_normalize\": [\n        \"void dom_node_normalize()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize Since:\"\n    ],\n    \"dom_node_remove_child\": [\n        \"DomNode dom_node_remove_child(DomNode oldChild)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066 Since:\"\n    ],\n    \"dom_node_replace_child\": [\n        \"DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307 Since:\"\n    ],\n    \"dom_node_set_user_data\": [\n        \"mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData Since: DOM Level 3\"\n    ],\n    \"dom_nodelist_item\": [\n        \"DOMNode dom_nodelist_item(int index)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136 Since:\"\n    ],\n    \"dom_string_extend_find_offset16\": [\n        \"int dom_string_extend_find_offset16(int offset32)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16 Since:\"\n    ],\n    \"dom_string_extend_find_offset32\": [\n        \"int dom_string_extend_find_offset32(int offset16)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32 Since:\"\n    ],\n    \"dom_text_is_whitespace_in_element_content\": [\n        \"bool dom_text_is_whitespace_in_element_content()\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent Since: DOM Level 3\"\n    ],\n    \"dom_text_replace_whole_text\": [\n        \"DOMText dom_text_replace_whole_text(string content)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText Since: DOM Level 3\"\n    ],\n    \"dom_text_split_text\": [\n        \"DOMText dom_text_split_text(int offset)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D Since:\"\n    ],\n    \"dom_userdatahandler_handle\": [\n        \"dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst)\",\n        \"URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-handleUserDataEvent Since:\"\n    ],\n    \"dom_xpath_evaluate\": [\n        \"mixed dom_xpath_evaluate(string expr [,DOMNode context])\",\n        \"\"\n    ],\n    \"dom_xpath_query\": [\n        \"DOMNodeList dom_xpath_query(string expr [,DOMNode context])\",\n        \"\"\n    ],\n    \"dom_xpath_register_ns\": [\n        \"bool dom_xpath_register_ns(string prefix, string uri)\",\n        \"\"\n    ],\n    \"dom_xpath_register_php_functions\": [\n        \"void dom_xpath_register_php_functions()\",\n        \"\"\n    ],\n    \"each\": [\n        \"array each(array arr)\",\n        \"Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element\"\n    ],\n    \"easter_date\": [\n        \"int easter_date([int year])\",\n        \"Return the timestamp of midnight on Easter of a given year (defaults to current year)\"\n    ],\n    \"easter_days\": [\n        \"int easter_days([int year, [int method]])\",\n        \"Return the number of days after March 21 that Easter falls on for a given year (defaults to current year)\"\n    ],\n    \"echo\": [\n        \"void echo(string arg1 [, string ...])\",\n        \"Output one or more strings\"\n    ],\n    \"empty\": [\n        \"bool empty(mixed var)\",\n        \"Determine whether a variable is empty\"\n    ],\n    \"enchant_broker_describe\": [\n        \"array enchant_broker_describe(resource broker)\",\n        \"Enumerates the Enchant providers and tells you some rudimentary information about them. The same info is provided through phpinfo()\"\n    ],\n    \"enchant_broker_dict_exists\": [\n        \"bool enchant_broker_dict_exists(resource broker, string tag)\",\n        \"Whether a dictionary exists or not. Using non-empty tag\"\n    ],\n    \"enchant_broker_free\": [\n        \"bool enchant_broker_free(resource broker)\",\n        \"Destroys the broker object and its dictionnaries\"\n    ],\n    \"enchant_broker_free_dict\": [\n        \"resource enchant_broker_free_dict(resource dict)\",\n        \"Free the dictionary resource\"\n    ],\n    \"enchant_broker_get_dict_path\": [\n        \"string enchant_broker_get_dict_path(resource broker, int dict_type)\",\n        \"Get the directory path for a given backend, works with ispell and myspell\"\n    ],\n    \"enchant_broker_get_error\": [\n        \"string enchant_broker_get_error(resource broker)\",\n        \"Returns the last error of the broker\"\n    ],\n    \"enchant_broker_init\": [\n        \"resource enchant_broker_init()\",\n        \"create a new broker object capable of requesting\"\n    ],\n    \"enchant_broker_list_dicts\": [\n        \"string enchant_broker_list_dicts(resource broker)\",\n        \"Lists the dictionaries available for the given broker\"\n    ],\n    \"enchant_broker_request_dict\": [\n        \"resource enchant_broker_request_dict(resource broker, string tag)\",\n        \"create a new dictionary using tag, the non-empty language tag you wish to request  a dictionary for (\\\"en_US\\\", \\\"de_DE\\\", ...)\"\n    ],\n    \"enchant_broker_request_pwl_dict\": [\n        \"resource enchant_broker_request_pwl_dict(resource broker, string filename)\",\n        \"creates a dictionary using a PWL file. A PWL file is personal word file one word per line. It must exist before the call.\"\n    ],\n    \"enchant_broker_set_dict_path\": [\n        \"bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)\",\n        \"Set the directory path for a given backend, works with ispell and myspell\"\n    ],\n    \"enchant_broker_set_ordering\": [\n        \"bool enchant_broker_set_ordering(resource broker, string tag, string ordering)\",\n        \"Declares a preference of dictionaries to use for the language  described/referred to by 'tag'. The ordering is a comma delimited  list of provider names. As a special exception, the \\\"*\\\" tag can  be used as a language tag to declare a default ordering for any  language that does not explictly declare an ordering.\"\n    ],\n    \"enchant_dict_add_to_personal\": [\n        \"void enchant_dict_add_to_personal(resource dict, string word)\",\n        \"add 'word' to personal word list\"\n    ],\n    \"enchant_dict_add_to_session\": [\n        \"void enchant_dict_add_to_session(resource dict, string word)\",\n        \"add 'word' to this spell-checking session\"\n    ],\n    \"enchant_dict_check\": [\n        \"bool enchant_dict_check(resource dict, string word)\",\n        \"If the word is correctly spelled return true, otherwise return false\"\n    ],\n    \"enchant_dict_describe\": [\n        \"array enchant_dict_describe(resource dict)\",\n        \"Describes an individual dictionary 'dict'\"\n    ],\n    \"enchant_dict_get_error\": [\n        \"string enchant_dict_get_error(resource dict)\",\n        \"Returns the last error of the current spelling-session\"\n    ],\n    \"enchant_dict_is_in_session\": [\n        \"bool enchant_dict_is_in_session(resource dict, string word)\",\n        \"whether or not 'word' exists in this spelling-session\"\n    ],\n    \"enchant_dict_quick_check\": [\n        \"bool enchant_dict_quick_check(resource dict, string word [, array &suggestions])\",\n        \"If the word is correctly spelled return true, otherwise return false, if suggestions variable     is provided, fill it with spelling alternatives.\"\n    ],\n    \"enchant_dict_store_replacement\": [\n        \"void enchant_dict_store_replacement(resource dict, string mis, string cor)\",\n        \"add a correction for 'mis' using 'cor'.  Notes that you replaced @mis with @cor, so it's possibly more likely  that future occurrences of @mis will be replaced with @cor. So it might  bump @cor up in the suggestion list.\"\n    ],\n    \"enchant_dict_suggest\": [\n        \"array enchant_dict_suggest(resource dict, string word)\",\n        \"Will return a list of values if any of those pre-conditions are not met.\"\n    ],\n    \"end\": [\n        \"mixed end(array array_arg)\",\n        \"Advances array argument's internal pointer to the last element and return it\"\n    ],\n    \"ereg\": [\n        \"int ereg(string pattern, string string [, array registers])\",\n        \"Regular expression match\"\n    ],\n    \"ereg_replace\": [\n        \"string ereg_replace(string pattern, string replacement, string string)\",\n        \"Replace regular expression\"\n    ],\n    \"eregi\": [\n        \"int eregi(string pattern, string string [, array registers])\",\n        \"Case-insensitive regular expression match\"\n    ],\n    \"eregi_replace\": [\n        \"string eregi_replace(string pattern, string replacement, string string)\",\n        \"Case insensitive replace regular expression\"\n    ],\n    \"error_get_last\": [\n        \"array error_get_last()\",\n        \"Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet.\"\n    ],\n    \"error_log\": [\n        \"bool error_log(string message [, int message_type [, string destination [, string extra_headers]]])\",\n        \"Send an error message somewhere\"\n    ],\n    \"error_reporting\": [\n        \"int error_reporting([int new_error_level])\",\n        \"Return the current error_reporting level, and if an argument was passed - change to the new level\"\n    ],\n    \"escapeshellarg\": [\n        \"string escapeshellarg(string arg)\",\n        \"Quote and escape an argument for use in a shell command\"\n    ],\n    \"escapeshellcmd\": [\n        \"string escapeshellcmd(string command)\",\n        \"Escape shell metacharacters\"\n    ],\n    \"exec\": [\n        \"string exec(string command [, array &output [, int &return_value]])\",\n        \"Execute an external program\"\n    ],\n    \"exif_imagetype\": [\n        \"int exif_imagetype(string imagefile)\",\n        \"Get the type of an image\"\n    ],\n    \"exif_read_data\": [\n        \"array exif_read_data(string filename [, sections_needed [, sub_arrays[, read_thumbnail]]])\",\n        \"Reads header data from the JPEG/TIFF image filename and optionally reads the internal thumbnails\"\n    ],\n    \"exif_tagname\": [\n        \"string exif_tagname(index)\",\n        \"Get headername for index or false if not defined\"\n    ],\n    \"exif_thumbnail\": [\n        \"string exif_thumbnail(string filename [, &width, &height [, &imagetype]])\",\n        \"Reads the embedded thumbnail\"\n    ],\n    \"exit\": [\n        \"void exit([mixed status])\",\n        \"Output a message and terminate the current script\"\n    ],\n    \"exp\": [\n        \"float exp(float number)\",\n        \"Returns e raised to the power of the number\"\n    ],\n    \"explode\": [\n        \"array explode(string separator, string str [, int limit])\",\n        \"Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned.\"\n    ],\n    \"expm1\": [\n        \"float expm1(float number)\",\n        \"Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero\"\n    ],\n    \"extension_loaded\": [\n        \"bool extension_loaded(string extension_name)\",\n        \"Returns true if the named extension is loaded\"\n    ],\n    \"extract\": [\n        \"int extract(array var_array [, int extract_type [, string prefix]])\",\n        \"Imports variables into symbol table from an array\"\n    ],\n    \"ezmlm_hash\": [\n        \"int ezmlm_hash(string addr)\",\n        \"Calculate EZMLM list hash value.\"\n    ],\n    \"fclose\": [\n        \"bool fclose(resource fp)\",\n        \"Close an open file pointer\"\n    ],\n    \"feof\": [\n        \"bool feof(resource fp)\",\n        \"Test for end-of-file on a file pointer\"\n    ],\n    \"fflush\": [\n        \"bool fflush(resource fp)\",\n        \"Flushes output\"\n    ],\n    \"fgetc\": [\n        \"string fgetc(resource fp)\",\n        \"Get a character from file pointer\"\n    ],\n    \"fgetcsv\": [\n        \"array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure [, string escape]]]])\",\n        \"Get line from file pointer and parse for CSV fields\"\n    ],\n    \"fgets\": [\n        \"string fgets(resource fp[, int length])\",\n        \"Get a line from file pointer\"\n    ],\n    \"fgetss\": [\n        \"string fgetss(resource fp [, int length [, string allowable_tags]])\",\n        \"Get a line from file pointer and strip HTML tags\"\n    ],\n    \"file\": [\n        \"array file(string filename [, int flags[, resource context]])\",\n        \"Read entire file into an array\"\n    ],\n    \"file_exists\": [\n        \"bool file_exists(string filename)\",\n        \"Returns true if filename exists\"\n    ],\n    \"file_get_contents\": [\n        \"string file_get_contents(string filename [, bool use_include_path [, resource context [, long offset [, long maxlen]]]])\",\n        \"Read the entire file into a string\"\n    ],\n    \"file_put_contents\": [\n        \"int file_put_contents(string file, mixed data [, int flags [, resource context]])\",\n        \"Write/Create a file with contents data and return the number of bytes written\"\n    ],\n    \"fileatime\": [\n        \"int fileatime(string filename)\",\n        \"Get last access time of file\"\n    ],\n    \"filectime\": [\n        \"int filectime(string filename)\",\n        \"Get inode modification time of file\"\n    ],\n    \"filegroup\": [\n        \"int filegroup(string filename)\",\n        \"Get file group\"\n    ],\n    \"fileinode\": [\n        \"int fileinode(string filename)\",\n        \"Get file inode\"\n    ],\n    \"filemtime\": [\n        \"int filemtime(string filename)\",\n        \"Get last modification time of file\"\n    ],\n    \"fileowner\": [\n        \"int fileowner(string filename)\",\n        \"Get file owner\"\n    ],\n    \"fileperms\": [\n        \"int fileperms(string filename)\",\n        \"Get file permissions\"\n    ],\n    \"filesize\": [\n        \"int filesize(string filename)\",\n        \"Get file size\"\n    ],\n    \"filetype\": [\n        \"string filetype(string filename)\",\n        \"Get file type\"\n    ],\n    \"filter_has_var\": [\n        \"mixed filter_has_var(constant type, string variable_name)\",\n        \"* Returns true if the variable with the name 'name' exists in source.\"\n    ],\n    \"filter_input\": [\n        \"mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])\",\n        \"* Returns the filtered variable 'name'* from source `type`.\"\n    ],\n    \"filter_input_array\": [\n        \"mixed filter_input_array(constant type, [, mixed options]])\",\n        \"* Returns an array with all arguments defined in 'definition'.\"\n    ],\n    \"filter_var\": [\n        \"mixed filter_var(mixed variable [, long filter [, mixed options]])\",\n        \"* Returns the filtered version of the vriable.\"\n    ],\n    \"filter_var_array\": [\n        \"mixed filter_var_array(array data, [, mixed options]])\",\n        \"* Returns an array with all arguments defined in 'definition'.\"\n    ],\n    \"finfo_buffer\": [\n        \"string finfo_buffer(resource finfo, char *string [, int options [, resource context]])\",\n        \"Return infromation about a string buffer.\"\n    ],\n    \"finfo_close\": [\n        \"resource finfo_close(resource finfo)\",\n        \"Close fileinfo resource.\"\n    ],\n    \"finfo_file\": [\n        \"string finfo_file(resource finfo, char *file_name [, int options [, resource context]])\",\n        \"Return information about a file.\"\n    ],\n    \"finfo_open\": [\n        \"resource finfo_open([int options [, string arg]])\",\n        \"Create a new fileinfo resource.\"\n    ],\n    \"finfo_set_flags\": [\n        \"bool finfo_set_flags(resource finfo, int options)\",\n        \"Set libmagic configuration options.\"\n    ],\n    \"floatval\": [\n        \"float floatval(mixed var)\",\n        \"Get the float value of a variable\"\n    ],\n    \"flock\": [\n        \"bool flock(resource fp, int operation [, int &wouldblock])\",\n        \"Portable file locking\"\n    ],\n    \"floor\": [\n        \"float floor(float number)\",\n        \"Returns the next lowest integer value from the number\"\n    ],\n    \"flush\": [\n        \"void flush()\",\n        \"Flush the output buffer\"\n    ],\n    \"fmod\": [\n        \"float fmod(float x, float y)\",\n        \"Returns the remainder of dividing x by y as a float\"\n    ],\n    \"fnmatch\": [\n        \"bool fnmatch(string pattern, string filename [, int flags])\",\n        \"Match filename against pattern\"\n    ],\n    \"fopen\": [\n        \"resource fopen(string filename, string mode [, bool use_include_path [, resource context]])\",\n        \"Open a file or a URL and return a file pointer\"\n    ],\n    \"forward_static_call\": [\n        \"mixed forward_static_call(mixed function_name [, mixed parmeter] [, mixed ...])\",\n        \"Call a user function which is the first parameter\"\n    ],\n    \"fpassthru\": [\n        \"int fpassthru(resource fp)\",\n        \"Output all remaining data from a file pointer\"\n    ],\n    \"fprintf\": [\n        \"int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])\",\n        \"Output a formatted string into a stream\"\n    ],\n    \"fputcsv\": [\n        \"int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])\",\n        \"Format line as CSV and write to file pointer\"\n    ],\n    \"fread\": [\n        \"string fread(resource fp, int length)\",\n        \"Binary-safe file read\"\n    ],\n    \"frenchtojd\": [\n        \"int frenchtojd(int month, int day, int year)\",\n        \"Converts a french republic calendar date to julian day count\"\n    ],\n    \"fscanf\": [\n        \"mixed fscanf(resource stream, string format [, string ...])\",\n        \"Implements a mostly ANSI compatible fscanf()\"\n    ],\n    \"fseek\": [\n        \"int fseek(resource fp, int offset [, int whence])\",\n        \"Seek on a file pointer\"\n    ],\n    \"fsockopen\": [\n        \"resource fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])\",\n        \"Open Internet or Unix domain socket connection\"\n    ],\n    \"fstat\": [\n        \"array fstat(resource fp)\",\n        \"Stat() on a filehandle\"\n    ],\n    \"ftell\": [\n        \"int ftell(resource fp)\",\n        \"Get file pointer's read/write position\"\n    ],\n    \"ftok\": [\n        \"int ftok(string pathname, string proj)\",\n        \"Convert a pathname and a project identifier to a System V IPC key\"\n    ],\n    \"ftp_alloc\": [\n        \"bool ftp_alloc(resource stream, int size[, &response])\",\n        \"Attempt to allocate space on the remote FTP server\"\n    ],\n    \"ftp_cdup\": [\n        \"bool ftp_cdup(resource stream)\",\n        \"Changes to the parent directory\"\n    ],\n    \"ftp_chdir\": [\n        \"bool ftp_chdir(resource stream, string directory)\",\n        \"Changes directories\"\n    ],\n    \"ftp_chmod\": [\n        \"int ftp_chmod(resource stream, int mode, string filename)\",\n        \"Sets permissions on a file\"\n    ],\n    \"ftp_close\": [\n        \"bool ftp_close(resource stream)\",\n        \"Closes the FTP stream\"\n    ],\n    \"ftp_connect\": [\n        \"resource ftp_connect(string host [, int port [, int timeout]])\",\n        \"Opens a FTP stream\"\n    ],\n    \"ftp_delete\": [\n        \"bool ftp_delete(resource stream, string file)\",\n        \"Deletes a file\"\n    ],\n    \"ftp_exec\": [\n        \"bool ftp_exec(resource stream, string command)\",\n        \"Requests execution of a program on the FTP server\"\n    ],\n    \"ftp_fget\": [\n        \"bool ftp_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])\",\n        \"Retrieves a file from the FTP server and writes it to an open file\"\n    ],\n    \"ftp_fput\": [\n        \"bool ftp_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])\",\n        \"Stores a file from an open file to the FTP server\"\n    ],\n    \"ftp_get\": [\n        \"bool ftp_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])\",\n        \"Retrieves a file from the FTP server and writes it to a local file\"\n    ],\n    \"ftp_get_option\": [\n        \"mixed ftp_get_option(resource stream, int option)\",\n        \"Gets an FTP option\"\n    ],\n    \"ftp_login\": [\n        \"bool ftp_login(resource stream, string username, string password)\",\n        \"Logs into the FTP server\"\n    ],\n    \"ftp_mdtm\": [\n        \"int ftp_mdtm(resource stream, string filename)\",\n        \"Returns the last modification time of the file, or -1 on error\"\n    ],\n    \"ftp_mkdir\": [\n        \"string ftp_mkdir(resource stream, string directory)\",\n        \"Creates a directory and returns the absolute path for the new directory or false on error\"\n    ],\n    \"ftp_nb_continue\": [\n        \"int ftp_nb_continue(resource stream)\",\n        \"Continues retrieving/sending a file nbronously\"\n    ],\n    \"ftp_nb_fget\": [\n        \"int ftp_nb_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])\",\n        \"Retrieves a file from the FTP server asynchronly and writes it to an open file\"\n    ],\n    \"ftp_nb_fput\": [\n        \"int ftp_nb_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])\",\n        \"Stores a file from an open file to the FTP server nbronly\"\n    ],\n    \"ftp_nb_get\": [\n        \"int ftp_nb_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])\",\n        \"Retrieves a file from the FTP server nbhronly and writes it to a local file\"\n    ],\n    \"ftp_nb_put\": [\n        \"int ftp_nb_put(resource stream, string remote_file, string local_file, int mode[, int startpos])\",\n        \"Stores a file on the FTP server\"\n    ],\n    \"ftp_nlist\": [\n        \"array ftp_nlist(resource stream, string directory)\",\n        \"Returns an array of filenames in the given directory\"\n    ],\n    \"ftp_pasv\": [\n        \"bool ftp_pasv(resource stream, bool pasv)\",\n        \"Turns passive mode on or off\"\n    ],\n    \"ftp_put\": [\n        \"bool ftp_put(resource stream, string remote_file, string local_file, int mode[, int startpos])\",\n        \"Stores a file on the FTP server\"\n    ],\n    \"ftp_pwd\": [\n        \"string ftp_pwd(resource stream)\",\n        \"Returns the present working directory\"\n    ],\n    \"ftp_raw\": [\n        \"array ftp_raw(resource stream, string command)\",\n        \"Sends a literal command to the FTP server\"\n    ],\n    \"ftp_rawlist\": [\n        \"array ftp_rawlist(resource stream, string directory [, bool recursive])\",\n        \"Returns a detailed listing of a directory as an array of output lines\"\n    ],\n    \"ftp_rename\": [\n        \"bool ftp_rename(resource stream, string src, string dest)\",\n        \"Renames the given file to a new path\"\n    ],\n    \"ftp_rmdir\": [\n        \"bool ftp_rmdir(resource stream, string directory)\",\n        \"Removes a directory\"\n    ],\n    \"ftp_set_option\": [\n        \"bool ftp_set_option(resource stream, int option, mixed value)\",\n        \"Sets an FTP option\"\n    ],\n    \"ftp_site\": [\n        \"bool ftp_site(resource stream, string cmd)\",\n        \"Sends a SITE command to the server\"\n    ],\n    \"ftp_size\": [\n        \"int ftp_size(resource stream, string filename)\",\n        \"Returns the size of the file, or -1 on error\"\n    ],\n    \"ftp_ssl_connect\": [\n        \"resource ftp_ssl_connect(string host [, int port [, int timeout]])\",\n        \"Opens a FTP-SSL stream\"\n    ],\n    \"ftp_systype\": [\n        \"string ftp_systype(resource stream)\",\n        \"Returns the system type identifier\"\n    ],\n    \"ftruncate\": [\n        \"bool ftruncate(resource fp, int size)\",\n        \"Truncate file to 'size' length\"\n    ],\n    \"func_get_arg\": [\n        \"mixed func_get_arg(int arg_num)\",\n        \"Get the $arg_num'th argument that was passed to the function\"\n    ],\n    \"func_get_args\": [\n        \"array func_get_args()\",\n        \"Get an array of the arguments that were passed to the function\"\n    ],\n    \"func_num_args\": [\n        \"int func_num_args()\",\n        \"Get the number of arguments that were passed to the function\"\n    ],\n    \"function \": [\"\", \"\"],\n    \"foreach \": [\"\", \"\"],\n    \"function_exists\": [\n        \"bool function_exists(string function_name)\",\n        \"Checks if the function exists\"\n    ],\n    \"fwrite\": [\n        \"int fwrite(resource fp, string str [, int length])\",\n        \"Binary-safe file write\"\n    ],\n    \"gc_collect_cycles\": [\n        \"int gc_collect_cycles()\",\n        \"Forces collection of any existing garbage cycles.    Returns number of freed zvals\"\n    ],\n    \"gc_disable\": [\n        \"void gc_disable()\",\n        \"Deactivates the circular reference collector\"\n    ],\n    \"gc_enable\": [\n        \"void gc_enable()\",\n        \"Activates the circular reference collector\"\n    ],\n    \"gc_enabled\": [\n        \"void gc_enabled()\",\n        \"Returns status of the circular reference collector\"\n    ],\n    \"gd_info\": [\n        \"array gd_info()\",\n        \"\"\n    ],\n    \"getKeywords\": [\n        \"static array getKeywords(string $locale) {\",\n        \"* return an associative array containing keyword-value  * pairs for this locale. The keys are keys to the array  * }}}\"\n    ],\n    \"get_browser\": [\n        \"mixed get_browser([string browser_name [, bool return_array]])\",\n        \"Get information about the capabilities of a browser. If browser_name is omitted or null, HTTP_USER_AGENT is used. Returns an object by default; if return_array is true, returns an array.\"\n    ],\n    \"get_called_class\": [\n        \"string get_called_class()\",\n        \"Retrieves the \\\"Late Static Binding\\\" class name\"\n    ],\n    \"get_cfg_var\": [\n        \"mixed get_cfg_var(string option_name)\",\n        \"Get the value of a PHP configuration option\"\n    ],\n    \"get_class\": [\n        \"string get_class([object object])\",\n        \"Retrieves the class name\"\n    ],\n    \"get_class_methods\": [\n        \"array get_class_methods(mixed class)\",\n        \"Returns an array of method names for class or class instance.\"\n    ],\n    \"get_class_vars\": [\n        \"array get_class_vars(string class_name)\",\n        \"Returns an array of default properties of the class.\"\n    ],\n    \"get_current_user\": [\n        \"string get_current_user()\",\n        \"Get the name of the owner of the current PHP script\"\n    ],\n    \"get_declared_classes\": [\n        \"array get_declared_classes()\",\n        \"Returns an array of all declared classes.\"\n    ],\n    \"get_declared_interfaces\": [\n        \"array get_declared_interfaces()\",\n        \"Returns an array of all declared interfaces.\"\n    ],\n    \"get_defined_constants\": [\n        \"array get_defined_constants([bool categorize])\",\n        \"Return an array containing the names and values of all defined constants\"\n    ],\n    \"get_defined_functions\": [\n        \"array get_defined_functions()\",\n        \"Returns an array of all defined functions\"\n    ],\n    \"get_defined_vars\": [\n        \"array get_defined_vars()\",\n        \"Returns an associative array of names and values of all currently defined variable names (variables in the current scope)\"\n    ],\n    \"get_display_language\": [\n        \"static string get_display_language($locale[, $in_locale = null])\",\n        \"* gets the language for the $locale in $in_locale or default_locale\"\n    ],\n    \"get_display_name\": [\n        \"static string get_display_name($locale[, $in_locale = null])\",\n        \"* gets the name for the $locale in $in_locale or default_locale\"\n    ],\n    \"get_display_region\": [\n        \"static string get_display_region($locale, $in_locale = null)\",\n        \"* gets the region for the $locale in $in_locale or default_locale\"\n    ],\n    \"get_display_script\": [\n        \"static string get_display_script($locale, $in_locale = null)\",\n        \"* gets the script for the $locale in $in_locale or default_locale\"\n    ],\n    \"get_extension_funcs\": [\n        \"array get_extension_funcs(string extension_name)\",\n        \"Returns an array with the names of functions belonging to the named extension\"\n    ],\n    \"get_headers\": [\n        \"array get_headers(string url[, int format])\",\n        \"fetches all the headers sent by the server in response to a HTTP request\"\n    ],\n    \"get_html_translation_table\": [\n        \"array get_html_translation_table([int table [, int quote_style]])\",\n        \"Returns the internal translation table used by htmlspecialchars and htmlentities\"\n    ],\n    \"get_include_path\": [\n        \"string get_include_path()\",\n        \"Get the current include_path configuration option\"\n    ],\n    \"get_included_files\": [\n        \"array get_included_files()\",\n        \"Returns an array with the file names that were include_once()'d\"\n    ],\n    \"get_loaded_extensions\": [\n        \"array get_loaded_extensions([bool zend_extensions])\",\n        \"Return an array containing names of loaded extensions\"\n    ],\n    \"get_magic_quotes_gpc\": [\n        \"int get_magic_quotes_gpc()\",\n        \"Get the current active configuration setting of magic_quotes_gpc\"\n    ],\n    \"get_magic_quotes_runtime\": [\n        \"int get_magic_quotes_runtime()\",\n        \"Get the current active configuration setting of magic_quotes_runtime\"\n    ],\n    \"get_meta_tags\": [\n        \"array get_meta_tags(string filename [, bool use_include_path])\",\n        \"Extracts all meta tag content attributes from a file and returns an array\"\n    ],\n    \"get_object_vars\": [\n        \"array get_object_vars(object obj)\",\n        \"Returns an array of object properties\"\n    ],\n    \"get_parent_class\": [\n        \"string get_parent_class([mixed object])\",\n        \"Retrieves the parent class name for object or class or current scope.\"\n    ],\n    \"get_resource_type\": [\n        \"string get_resource_type(resource res)\",\n        \"Get the resource type name for a given resource\"\n    ],\n    \"getallheaders\": [\n        \"array getallheaders()\",\n        \"\"\n    ],\n    \"getcwd\": [\n        \"mixed getcwd()\",\n        \"Gets the current directory\"\n    ],\n    \"getdate\": [\n        \"array getdate([int timestamp])\",\n        \"Get date/time information\"\n    ],\n    \"getenv\": [\n        \"string getenv(string varname)\",\n        \"Get the value of an environment variable\"\n    ],\n    \"gethostbyaddr\": [\n        \"string gethostbyaddr(string ip_address)\",\n        \"Get the Internet host name corresponding to a given IP address\"\n    ],\n    \"gethostbyname\": [\n        \"string gethostbyname(string hostname)\",\n        \"Get the IP address corresponding to a given Internet host name\"\n    ],\n    \"gethostbynamel\": [\n        \"array gethostbynamel(string hostname)\",\n        \"Return a list of IP addresses that a given hostname resolves to.\"\n    ],\n    \"gethostname\": [\n        \"string gethostname()\",\n        \"Get the host name of the current machine\"\n    ],\n    \"getimagesize\": [\n        \"array getimagesize(string imagefile [, array info])\",\n        \"Get the size of an image as 4-element array\"\n    ],\n    \"getlastmod\": [\n        \"int getlastmod()\",\n        \"Get time of last page modification\"\n    ],\n    \"getmygid\": [\n        \"int getmygid()\",\n        \"Get PHP script owner's GID\"\n    ],\n    \"getmyinode\": [\n        \"int getmyinode()\",\n        \"Get the inode of the current script being parsed\"\n    ],\n    \"getmypid\": [\n        \"int getmypid()\",\n        \"Get current process ID\"\n    ],\n    \"getmyuid\": [\n        \"int getmyuid()\",\n        \"Get PHP script owner's UID\"\n    ],\n    \"getopt\": [\n        \"array getopt(string options [, array longopts])\",\n        \"Get options from the command line argument list\"\n    ],\n    \"getprotobyname\": [\n        \"int getprotobyname(string name)\",\n        \"Returns protocol number associated with name as per /etc/protocols\"\n    ],\n    \"getprotobynumber\": [\n        \"string getprotobynumber(int proto)\",\n        \"Returns protocol name associated with protocol number proto\"\n    ],\n    \"getrandmax\": [\n        \"int getrandmax()\",\n        \"Returns the maximum value a random number can have\"\n    ],\n    \"getrusage\": [\n        \"array getrusage([int who])\",\n        \"Returns an array of usage statistics\"\n    ],\n    \"getservbyname\": [\n        \"int getservbyname(string service, string protocol)\",\n        \"Returns port associated with service. Protocol must be \\\"tcp\\\" or \\\"udp\\\"\"\n    ],\n    \"getservbyport\": [\n        \"string getservbyport(int port, string protocol)\",\n        \"Returns service name associated with port. Protocol must be \\\"tcp\\\" or \\\"udp\\\"\"\n    ],\n    \"gettext\": [\n        \"string gettext(string msgid)\",\n        \"Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist\"\n    ],\n    \"gettimeofday\": [\n        \"array gettimeofday([bool get_as_float])\",\n        \"Returns the current time as array\"\n    ],\n    \"gettype\": [\n        \"string gettype(mixed var)\",\n        \"Returns the type of the variable\"\n    ],\n    \"glob\": [\n        \"array glob(string pattern [, int flags])\",\n        \"Find pathnames matching a pattern\"\n    ],\n    \"gmdate\": [\n        \"string gmdate(string format [, long timestamp])\",\n        \"Format a GMT date/time\"\n    ],\n    \"gmmktime\": [\n        \"int gmmktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])\",\n        \"Get UNIX timestamp for a GMT date\"\n    ],\n    \"gmp_abs\": [\n        \"resource gmp_abs(resource a)\",\n        \"Calculates absolute value\"\n    ],\n    \"gmp_add\": [\n        \"resource gmp_add(resource a, resource b)\",\n        \"Add a and b\"\n    ],\n    \"gmp_and\": [\n        \"resource gmp_and(resource a, resource b)\",\n        \"Calculates logical AND of a and b\"\n    ],\n    \"gmp_clrbit\": [\n        \"void gmp_clrbit(resource &a, int index)\",\n        \"Clears bit in a\"\n    ],\n    \"gmp_cmp\": [\n        \"int gmp_cmp(resource a, resource b)\",\n        \"Compares two numbers\"\n    ],\n    \"gmp_com\": [\n        \"resource gmp_com(resource a)\",\n        \"Calculates one's complement of a\"\n    ],\n    \"gmp_div_q\": [\n        \"resource gmp_div_q(resource a, resource b [, int round])\",\n        \"Divide a by b, returns quotient only\"\n    ],\n    \"gmp_div_qr\": [\n        \"array gmp_div_qr(resource a, resource b [, int round])\",\n        \"Divide a by b, returns quotient and reminder\"\n    ],\n    \"gmp_div_r\": [\n        \"resource gmp_div_r(resource a, resource b [, int round])\",\n        \"Divide a by b, returns reminder only\"\n    ],\n    \"gmp_divexact\": [\n        \"resource gmp_divexact(resource a, resource b)\",\n        \"Divide a by b using exact division algorithm\"\n    ],\n    \"gmp_fact\": [\n        \"resource gmp_fact(int a)\",\n        \"Calculates factorial function\"\n    ],\n    \"gmp_gcd\": [\n        \"resource gmp_gcd(resource a, resource b)\",\n        \"Computes greatest common denominator (gcd) of a and b\"\n    ],\n    \"gmp_gcdext\": [\n        \"array gmp_gcdext(resource a, resource b)\",\n        \"Computes G, S, and T, such that AS + BT = G = `gcd' (A, B)\"\n    ],\n    \"gmp_hamdist\": [\n        \"int gmp_hamdist(resource a, resource b)\",\n        \"Calculates hamming distance between a and b\"\n    ],\n    \"gmp_init\": [\n        \"resource gmp_init(mixed number [, int base])\",\n        \"Initializes GMP number\"\n    ],\n    \"gmp_intval\": [\n        \"int gmp_intval(resource gmpnumber)\",\n        \"Gets signed long value of GMP number\"\n    ],\n    \"gmp_invert\": [\n        \"resource gmp_invert(resource a, resource b)\",\n        \"Computes the inverse of a modulo b\"\n    ],\n    \"gmp_jacobi\": [\n        \"int gmp_jacobi(resource a, resource b)\",\n        \"Computes Jacobi symbol\"\n    ],\n    \"gmp_legendre\": [\n        \"int gmp_legendre(resource a, resource b)\",\n        \"Computes Legendre symbol\"\n    ],\n    \"gmp_mod\": [\n        \"resource gmp_mod(resource a, resource b)\",\n        \"Computes a modulo b\"\n    ],\n    \"gmp_mul\": [\n        \"resource gmp_mul(resource a, resource b)\",\n        \"Multiply a and b\"\n    ],\n    \"gmp_neg\": [\n        \"resource gmp_neg(resource a)\",\n        \"Negates a number\"\n    ],\n    \"gmp_nextprime\": [\n        \"resource gmp_nextprime(resource a)\",\n        \"Finds next prime of a\"\n    ],\n    \"gmp_or\": [\n        \"resource gmp_or(resource a, resource b)\",\n        \"Calculates logical OR of a and b\"\n    ],\n    \"gmp_perfect_square\": [\n        \"bool gmp_perfect_square(resource a)\",\n        \"Checks if a is an exact square\"\n    ],\n    \"gmp_popcount\": [\n        \"int gmp_popcount(resource a)\",\n        \"Calculates the population count of a\"\n    ],\n    \"gmp_pow\": [\n        \"resource gmp_pow(resource base, int exp)\",\n        \"Raise base to power exp\"\n    ],\n    \"gmp_powm\": [\n        \"resource gmp_powm(resource base, resource exp, resource mod)\",\n        \"Raise base to power exp and take result modulo mod\"\n    ],\n    \"gmp_prob_prime\": [\n        \"int gmp_prob_prime(resource a[, int reps])\",\n        \"Checks if a is \\\"probably prime\\\"\"\n    ],\n    \"gmp_random\": [\n        \"resource gmp_random([int limiter])\",\n        \"Gets random number\"\n    ],\n    \"gmp_scan0\": [\n        \"int gmp_scan0(resource a, int start)\",\n        \"Finds first zero bit\"\n    ],\n    \"gmp_scan1\": [\n        \"int gmp_scan1(resource a, int start)\",\n        \"Finds first non-zero bit\"\n    ],\n    \"gmp_setbit\": [\n        \"void gmp_setbit(resource &a, int index[, bool set_clear])\",\n        \"Sets or clear bit in a\"\n    ],\n    \"gmp_sign\": [\n        \"int gmp_sign(resource a)\",\n        \"Gets the sign of the number\"\n    ],\n    \"gmp_sqrt\": [\n        \"resource gmp_sqrt(resource a)\",\n        \"Takes integer part of square root of a\"\n    ],\n    \"gmp_sqrtrem\": [\n        \"array gmp_sqrtrem(resource a)\",\n        \"Square root with remainder\"\n    ],\n    \"gmp_strval\": [\n        \"string gmp_strval(resource gmpnumber [, int base])\",\n        \"Gets string representation of GMP number\"\n    ],\n    \"gmp_sub\": [\n        \"resource gmp_sub(resource a, resource b)\",\n        \"Subtract b from a\"\n    ],\n    \"gmp_testbit\": [\n        \"bool gmp_testbit(resource a, int index)\",\n        \"Tests if bit is set in a\"\n    ],\n    \"gmp_xor\": [\n        \"resource gmp_xor(resource a, resource b)\",\n        \"Calculates logical exclusive OR of a and b\"\n    ],\n    \"gmstrftime\": [\n        \"string gmstrftime(string format [, int timestamp])\",\n        \"Format a GMT/UCT time/date according to locale settings\"\n    ],\n    \"grapheme_extract\": [\n        \"string grapheme_extract(string str, int size[, int extract_type[, int start[, int next]]])\",\n        \"Function to extract a sequence of default grapheme clusters\"\n    ],\n    \"grapheme_stripos\": [\n        \"int grapheme_stripos(string haystack, string needle [, int offset ])\",\n        \"Find position of first occurrence of a string within another, ignoring case differences\"\n    ],\n    \"grapheme_stristr\": [\n        \"string grapheme_stristr(string haystack, string needle[, bool part])\",\n        \"Finds first occurrence of a string within another\"\n    ],\n    \"grapheme_strlen\": [\n        \"int grapheme_strlen(string str)\",\n        \"Get number of graphemes in a string\"\n    ],\n    \"grapheme_strpos\": [\n        \"int grapheme_strpos(string haystack, string needle [, int offset ])\",\n        \"Find position of first occurrence of a string within another\"\n    ],\n    \"grapheme_strripos\": [\n        \"int grapheme_strripos(string haystack, string needle [, int offset])\",\n        \"Find position of last occurrence of a string within another, ignoring case\"\n    ],\n    \"grapheme_strrpos\": [\n        \"int grapheme_strrpos(string haystack, string needle [, int offset])\",\n        \"Find position of last occurrence of a string within another\"\n    ],\n    \"grapheme_strstr\": [\n        \"string grapheme_strstr(string haystack, string needle[, bool part])\",\n        \"Finds first occurrence of a string within another\"\n    ],\n    \"grapheme_substr\": [\n        \"string grapheme_substr(string str, int start [, int length])\",\n        \"Returns part of a string\"\n    ],\n    \"gregoriantojd\": [\n        \"int gregoriantojd(int month, int day, int year)\",\n        \"Converts a gregorian calendar date to julian day count\"\n    ],\n    \"gzcompress\": [\n        \"string gzcompress(string data [, int level])\",\n        \"Gzip-compress a string\"\n    ],\n    \"gzdeflate\": [\n        \"string gzdeflate(string data [, int level])\",\n        \"Gzip-compress a string\"\n    ],\n    \"gzencode\": [\n        \"string gzencode(string data [, int level [, int encoding_mode]])\",\n        \"GZ encode a string\"\n    ],\n    \"gzfile\": [\n        \"array gzfile(string filename [, int use_include_path])\",\n        \"Read und uncompress entire .gz-file into an array\"\n    ],\n    \"gzinflate\": [\n        \"string gzinflate(string data [, int length])\",\n        \"Unzip a gzip-compressed string\"\n    ],\n    \"gzopen\": [\n        \"resource gzopen(string filename, string mode [, int use_include_path])\",\n        \"Open a .gz-file and return a .gz-file pointer\"\n    ],\n    \"gzuncompress\": [\n        \"string gzuncompress(string data [, int length])\",\n        \"Unzip a gzip-compressed string\"\n    ],\n    \"hash\": [\n        \"string hash(string algo, string data[, bool raw_output = false])\",\n        \"Generate a hash of a given input string Returns lowercase hexits by default\"\n    ],\n    \"hash_algos\": [\n        \"array hash_algos()\",\n        \"Return a list of registered hashing algorithms\"\n    ],\n    \"hash_copy\": [\n        \"resource hash_copy(resource context)\",\n        \"Copy hash resource\"\n    ],\n    \"hash_file\": [\n        \"string hash_file(string algo, string filename[, bool raw_output = false])\",\n        \"Generate a hash of a given file Returns lowercase hexits by default\"\n    ],\n    \"hash_final\": [\n        \"string hash_final(resource context[, bool raw_output=false])\",\n        \"Output resulting digest\"\n    ],\n    \"hash_hmac\": [\n        \"string hash_hmac(string algo, string data, string key[, bool raw_output = false])\",\n        \"Generate a hash of a given input string with a key using HMAC Returns lowercase hexits by default\"\n    ],\n    \"hash_hmac_file\": [\n        \"string hash_hmac_file(string algo, string filename, string key[, bool raw_output = false])\",\n        \"Generate a hash of a given file with a key using HMAC Returns lowercase hexits by default\"\n    ],\n    \"hash_init\": [\n        \"resource hash_init(string algo[, int options, string key])\",\n        \"Initialize a hashing context\"\n    ],\n    \"hash_update\": [\n        \"bool hash_update(resource context, string data)\",\n        \"Pump data into the hashing algorithm\"\n    ],\n    \"hash_update_file\": [\n        \"bool hash_update_file(resource context, string filename[, resource context])\",\n        \"Pump data into the hashing algorithm from a file\"\n    ],\n    \"hash_update_stream\": [\n        \"int hash_update_stream(resource context, resource handle[, integer length])\",\n        \"Pump data into the hashing algorithm from an open stream\"\n    ],\n    \"header\": [\n        \"void header(string header [, bool replace, [int http_response_code]])\",\n        \"Sends a raw HTTP header\"\n    ],\n    \"header_remove\": [\n        \"void header_remove([string name])\",\n        \"Removes an HTTP header previously set using header()\"\n    ],\n    \"headers_list\": [\n        \"array headers_list()\",\n        \"Return list of headers to be sent / already sent\"\n    ],\n    \"headers_sent\": [\n        \"bool headers_sent([string &$file [, int &$line]])\",\n        \"Returns true if headers have already been sent, false otherwise\"\n    ],\n    \"hebrev\": [\n        \"string hebrev(string str [, int max_chars_per_line])\",\n        \"Converts logical Hebrew text to visual text\"\n    ],\n    \"hebrevc\": [\n        \"string hebrevc(string str [, int max_chars_per_line])\",\n        \"Converts logical Hebrew text to visual text with newline conversion\"\n    ],\n    \"hexdec\": [\n        \"int hexdec(string hexadecimal_number)\",\n        \"Returns the decimal equivalent of the hexadecimal number\"\n    ],\n    \"highlight_file\": [\n        \"bool highlight_file(string file_name [, bool return] )\",\n        \"Syntax highlight a source file\"\n    ],\n    \"highlight_string\": [\n        \"bool highlight_string(string string [, bool return] )\",\n        \"Syntax highlight a string or optionally return it\"\n    ],\n    \"html_entity_decode\": [\n        \"string html_entity_decode(string string [, int quote_style][, string charset])\",\n        \"Convert all HTML entities to their applicable characters\"\n    ],\n    \"htmlentities\": [\n        \"string htmlentities(string string [, int quote_style[, string charset[, bool double_encode]]])\",\n        \"Convert all applicable characters to HTML entities\"\n    ],\n    \"htmlspecialchars\": [\n        \"string htmlspecialchars(string string [, int quote_style[, string charset[, bool double_encode]]])\",\n        \"Convert special characters to HTML entities\"\n    ],\n    \"htmlspecialchars_decode\": [\n        \"string htmlspecialchars_decode(string string [, int quote_style])\",\n        \"Convert special HTML entities back to characters\"\n    ],\n    \"http_build_query\": [\n        \"string http_build_query(mixed formdata [, string prefix [, string arg_separator]])\",\n        \"Generates a form-encoded query string from an associative array or object.\"\n    ],\n    \"hypot\": [\n        \"float hypot(float num1, float num2)\",\n        \"Returns sqrt(num1*num1 + num2*num2)\"\n    ],\n    \"ibase_add_user\": [\n        \"bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])\",\n        \"Add a user to security database\"\n    ],\n    \"ibase_affected_rows\": [\n        \"int ibase_affected_rows( [ resource link_identifier ] )\",\n        \"Returns the number of rows affected by the previous INSERT, UPDATE or DELETE statement\"\n    ],\n    \"ibase_backup\": [\n        \"mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]])\",\n        \"Initiates a backup task in the service manager and returns immediately\"\n    ],\n    \"ibase_blob_add\": [\n        \"bool ibase_blob_add(resource blob_handle, string data)\",\n        \"Add data into created blob\"\n    ],\n    \"ibase_blob_cancel\": [\n        \"bool ibase_blob_cancel(resource blob_handle)\",\n        \"Cancel creating blob\"\n    ],\n    \"ibase_blob_close\": [\n        \"string ibase_blob_close(resource blob_handle)\",\n        \"Close blob\"\n    ],\n    \"ibase_blob_create\": [\n        \"resource ibase_blob_create([resource link_identifier])\",\n        \"Create blob for adding data\"\n    ],\n    \"ibase_blob_echo\": [\n        \"bool ibase_blob_echo([ resource link_identifier, ] string blob_id)\",\n        \"Output blob contents to browser\"\n    ],\n    \"ibase_blob_get\": [\n        \"string ibase_blob_get(resource blob_handle, int len)\",\n        \"Get len bytes data from open blob\"\n    ],\n    \"ibase_blob_import\": [\n        \"string ibase_blob_import([ resource link_identifier, ] resource file)\",\n        \"Create blob, copy file in it, and close it\"\n    ],\n    \"ibase_blob_info\": [\n        \"array ibase_blob_info([ resource link_identifier, ] string blob_id)\",\n        \"Return blob length and other useful info\"\n    ],\n    \"ibase_blob_open\": [\n        \"resource ibase_blob_open([ resource link_identifier, ] string blob_id)\",\n        \"Open blob for retrieving data parts\"\n    ],\n    \"ibase_close\": [\n        \"bool ibase_close([resource link_identifier])\",\n        \"Close an InterBase connection\"\n    ],\n    \"ibase_commit\": [\n        \"bool ibase_commit( resource link_identifier )\",\n        \"Commit transaction\"\n    ],\n    \"ibase_commit_ret\": [\n        \"bool ibase_commit_ret( resource link_identifier )\",\n        \"Commit transaction and retain the transaction context\"\n    ],\n    \"ibase_connect\": [\n        \"resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])\",\n        \"Open a connection to an InterBase database\"\n    ],\n    \"ibase_db_info\": [\n        \"string ibase_db_info(resource service_handle, string db, int action [, int argument])\",\n        \"Request statistics about a database\"\n    ],\n    \"ibase_delete_user\": [\n        \"bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])\",\n        \"Delete a user from security database\"\n    ],\n    \"ibase_drop_db\": [\n        \"bool ibase_drop_db([resource link_identifier])\",\n        \"Drop an InterBase database\"\n    ],\n    \"ibase_errcode\": [\n        \"int ibase_errcode()\",\n        \"Return error code\"\n    ],\n    \"ibase_errmsg\": [\n        \"string ibase_errmsg()\",\n        \"Return error message\"\n    ],\n    \"ibase_execute\": [\n        \"mixed ibase_execute(resource query [, mixed bind_arg [, mixed bind_arg [, ...]]])\",\n        \"Execute a previously prepared query\"\n    ],\n    \"ibase_fetch_assoc\": [\n        \"array ibase_fetch_assoc(resource result [, int fetch_flags])\",\n        \"Fetch a row  from the results of a query\"\n    ],\n    \"ibase_fetch_object\": [\n        \"object ibase_fetch_object(resource result [, int fetch_flags])\",\n        \"Fetch a object from the results of a query\"\n    ],\n    \"ibase_fetch_row\": [\n        \"array ibase_fetch_row(resource result [, int fetch_flags])\",\n        \"Fetch a row  from the results of a query\"\n    ],\n    \"ibase_field_info\": [\n        \"array ibase_field_info(resource query_result, int field_number)\",\n        \"Get information about a field\"\n    ],\n    \"ibase_free_event_handler\": [\n        \"bool ibase_free_event_handler(resource event)\",\n        \"Frees the event handler set by ibase_set_event_handler()\"\n    ],\n    \"ibase_free_query\": [\n        \"bool ibase_free_query(resource query)\",\n        \"Free memory used by a query\"\n    ],\n    \"ibase_free_result\": [\n        \"bool ibase_free_result(resource result)\",\n        \"Free the memory used by a result\"\n    ],\n    \"ibase_gen_id\": [\n        \"int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])\",\n        \"Increments the named generator and returns its new value\"\n    ],\n    \"ibase_maintain_db\": [\n        \"bool ibase_maintain_db(resource service_handle, string db, int action [, int argument])\",\n        \"Execute a maintenance command on the database server\"\n    ],\n    \"ibase_modify_user\": [\n        \"bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])\",\n        \"Modify a user in security database\"\n    ],\n    \"ibase_name_result\": [\n        \"bool ibase_name_result(resource result, string name)\",\n        \"Assign a name to a result for use with ... WHERE CURRENT OF <name> statements\"\n    ],\n    \"ibase_num_fields\": [\n        \"int ibase_num_fields(resource query_result)\",\n        \"Get the number of fields in result\"\n    ],\n    \"ibase_num_params\": [\n        \"int ibase_num_params(resource query)\",\n        \"Get the number of params in a prepared query\"\n    ],\n    \"ibase_num_rows\": [\n        \"int ibase_num_rows( resource result_identifier )\",\n        \"Return the number of rows that are available in a result\"\n    ],\n    \"ibase_param_info\": [\n        \"array ibase_param_info(resource query, int field_number)\",\n        \"Get information about a parameter\"\n    ],\n    \"ibase_pconnect\": [\n        \"resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])\",\n        \"Open a persistent connection to an InterBase database\"\n    ],\n    \"ibase_prepare\": [\n        \"resource ibase_prepare(resource link_identifier[, string query [, resource trans_identifier ]])\",\n        \"Prepare a query for later execution\"\n    ],\n    \"ibase_query\": [\n        \"mixed ibase_query([resource link_identifier, [ resource link_identifier, ]] string query [, mixed bind_arg [, mixed bind_arg [, ...]]])\",\n        \"Execute a query\"\n    ],\n    \"ibase_restore\": [\n        \"mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]])\",\n        \"Initiates a restore task in the service manager and returns immediately\"\n    ],\n    \"ibase_rollback\": [\n        \"bool ibase_rollback( resource link_identifier )\",\n        \"Rollback transaction\"\n    ],\n    \"ibase_rollback_ret\": [\n        \"bool ibase_rollback_ret( resource link_identifier )\",\n        \"Rollback transaction and retain the transaction context\"\n    ],\n    \"ibase_server_info\": [\n        \"string ibase_server_info(resource service_handle, int action)\",\n        \"Request information about a database server\"\n    ],\n    \"ibase_service_attach\": [\n        \"resource ibase_service_attach(string host, string dba_username, string dba_password)\",\n        \"Connect to the service manager\"\n    ],\n    \"ibase_service_detach\": [\n        \"bool ibase_service_detach(resource service_handle)\",\n        \"Disconnect from the service manager\"\n    ],\n    \"ibase_set_event_handler\": [\n        \"resource ibase_set_event_handler([resource link_identifier,] callback handler, string event [, string event [, ...]])\",\n        \"Register the callback for handling each of the named events\"\n    ],\n    \"ibase_trans\": [\n        \"resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])\",\n        \"Start a transaction over one or several databases\"\n    ],\n    \"ibase_wait_event\": [\n        \"string ibase_wait_event([resource link_identifier,] string event [, string event [, ...]])\",\n        \"Waits for any one of the passed Interbase events to be posted by the database, and returns its name\"\n    ],\n    \"iconv\": [\n        \"string iconv(string in_charset, string out_charset, string str)\",\n        \"Returns str converted to the out_charset character set\"\n    ],\n    \"iconv_get_encoding\": [\n        \"mixed iconv_get_encoding([string type])\",\n        \"Get internal encoding and output encoding for ob_iconv_handler()\"\n    ],\n    \"iconv_mime_decode\": [\n        \"string iconv_mime_decode(string encoded_string [, int mode, string charset])\",\n        \"Decodes a mime header field\"\n    ],\n    \"iconv_mime_decode_headers\": [\n        \"array iconv_mime_decode_headers(string headers [, int mode, string charset])\",\n        \"Decodes multiple mime header fields\"\n    ],\n    \"iconv_mime_encode\": [\n        \"string iconv_mime_encode(string field_name, string field_value [, array preference])\",\n        \"Composes a mime header field with field_name and field_value in a specified scheme\"\n    ],\n    \"iconv_set_encoding\": [\n        \"bool iconv_set_encoding(string type, string charset)\",\n        \"Sets internal encoding and output encoding for ob_iconv_handler()\"\n    ],\n    \"iconv_strlen\": [\n        \"int iconv_strlen(string str [, string charset])\",\n        \"Returns the character count of str\"\n    ],\n    \"iconv_strpos\": [\n        \"int iconv_strpos(string haystack, string needle [, int offset [, string charset]])\",\n        \"Finds position of first occurrence of needle within part of haystack beginning with offset\"\n    ],\n    \"iconv_strrpos\": [\n        \"int iconv_strrpos(string haystack, string needle [, string charset])\",\n        \"Finds position of last occurrence of needle within part of haystack beginning with offset\"\n    ],\n    \"iconv_substr\": [\n        \"string iconv_substr(string str, int offset, [int length, string charset])\",\n        \"Returns specified part of a string\"\n    ],\n    \"idate\": [\n        \"int idate(string format [, int timestamp])\",\n        \"Format a local time/date as integer\"\n    ],\n    \"idn_to_ascii\": [\n        \"int idn_to_ascii(string domain[, int options])\",\n        \"Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC\"\n    ],\n    \"idn_to_utf8\": [\n        \"int idn_to_utf8(string domain[, int options])\",\n        \"Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC\"\n    ],\n    \"ignore_user_abort\": [\n        \"int ignore_user_abort([string value])\",\n        \"Set whether we want to ignore a user abort event or not\"\n    ],\n    \"image2wbmp\": [\n        \"bool image2wbmp(resource im [, string filename [, int threshold]])\",\n        \"Output WBMP image to browser or file\"\n    ],\n    \"image_type_to_extension\": [\n        \"string image_type_to_extension(int imagetype [, bool include_dot])\",\n        \"Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype\"\n    ],\n    \"image_type_to_mime_type\": [\n        \"string image_type_to_mime_type(int imagetype)\",\n        \"Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype\"\n    ],\n    \"imagealphablending\": [\n        \"bool imagealphablending(resource im, bool on)\",\n        \"Turn alpha blending mode on or off for the given image\"\n    ],\n    \"imageantialias\": [\n        \"bool imageantialias(resource im, bool on)\",\n        \"Should antialiased functions used or not\"\n    ],\n    \"imagearc\": [\n        \"bool imagearc(resource im, int cx, int cy, int w, int h, int s, int e, int col)\",\n        \"Draw a partial ellipse\"\n    ],\n    \"imagechar\": [\n        \"bool imagechar(resource im, int font, int x, int y, string c, int col)\",\n        \"Draw a character\"\n    ],\n    \"imagecharup\": [\n        \"bool imagecharup(resource im, int font, int x, int y, string c, int col)\",\n        \"Draw a character rotated 90 degrees counter-clockwise\"\n    ],\n    \"imagecolorallocate\": [\n        \"int imagecolorallocate(resource im, int red, int green, int blue)\",\n        \"Allocate a color for an image\"\n    ],\n    \"imagecolorallocatealpha\": [\n        \"int imagecolorallocatealpha(resource im, int red, int green, int blue, int alpha)\",\n        \"Allocate a color with an alpha level.  Works for true color and palette based images\"\n    ],\n    \"imagecolorat\": [\n        \"int imagecolorat(resource im, int x, int y)\",\n        \"Get the index of the color of a pixel\"\n    ],\n    \"imagecolorclosest\": [\n        \"int imagecolorclosest(resource im, int red, int green, int blue)\",\n        \"Get the index of the closest color to the specified color\"\n    ],\n    \"imagecolorclosestalpha\": [\n        \"int imagecolorclosestalpha(resource im, int red, int green, int blue, int alpha)\",\n        \"Find the closest matching colour with alpha transparency\"\n    ],\n    \"imagecolorclosesthwb\": [\n        \"int imagecolorclosesthwb(resource im, int red, int green, int blue)\",\n        \"Get the index of the color which has the hue, white and blackness nearest to the given color\"\n    ],\n    \"imagecolordeallocate\": [\n        \"bool imagecolordeallocate(resource im, int index)\",\n        \"De-allocate a color for an image\"\n    ],\n    \"imagecolorexact\": [\n        \"int imagecolorexact(resource im, int red, int green, int blue)\",\n        \"Get the index of the specified color\"\n    ],\n    \"imagecolorexactalpha\": [\n        \"int imagecolorexactalpha(resource im, int red, int green, int blue, int alpha)\",\n        \"Find exact match for colour with transparency\"\n    ],\n    \"imagecolormatch\": [\n        \"bool imagecolormatch(resource im1, resource im2)\",\n        \"Makes the colors of the palette version of an image more closely match the true color version\"\n    ],\n    \"imagecolorresolve\": [\n        \"int imagecolorresolve(resource im, int red, int green, int blue)\",\n        \"Get the index of the specified color or its closest possible alternative\"\n    ],\n    \"imagecolorresolvealpha\": [\n        \"int imagecolorresolvealpha(resource im, int red, int green, int blue, int alpha)\",\n        \"Resolve/Allocate a colour with an alpha level.  Works for true colour and palette based images\"\n    ],\n    \"imagecolorset\": [\n        \"void imagecolorset(resource im, int col, int red, int green, int blue)\",\n        \"Set the color for the specified palette index\"\n    ],\n    \"imagecolorsforindex\": [\n        \"array imagecolorsforindex(resource im, int col)\",\n        \"Get the colors for an index\"\n    ],\n    \"imagecolorstotal\": [\n        \"int imagecolorstotal(resource im)\",\n        \"Find out the number of colors in an image's palette\"\n    ],\n    \"imagecolortransparent\": [\n        \"int imagecolortransparent(resource im [, int col])\",\n        \"Define a color as transparent\"\n    ],\n    \"imageconvolution\": [\n        \"resource imageconvolution(resource src_im, array matrix3x3, double div, double offset)\",\n        \"Apply a 3x3 convolution matrix, using coefficient div and offset\"\n    ],\n    \"imagecopy\": [\n        \"bool imagecopy(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h)\",\n        \"Copy part of an image\"\n    ],\n    \"imagecopymerge\": [\n        \"bool imagecopymerge(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)\",\n        \"Merge one part of an image with another\"\n    ],\n    \"imagecopymergegray\": [\n        \"bool imagecopymergegray(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)\",\n        \"Merge one part of an image with another\"\n    ],\n    \"imagecopyresampled\": [\n        \"bool imagecopyresampled(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)\",\n        \"Copy and resize part of an image using resampling to help ensure clarity\"\n    ],\n    \"imagecopyresized\": [\n        \"bool imagecopyresized(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)\",\n        \"Copy and resize part of an image\"\n    ],\n    \"imagecreate\": [\n        \"resource imagecreate(int x_size, int y_size)\",\n        \"Create a new image\"\n    ],\n    \"imagecreatefromgd\": [\n        \"resource imagecreatefromgd(string filename)\",\n        \"Create a new image from GD file or URL\"\n    ],\n    \"imagecreatefromgd2\": [\n        \"resource imagecreatefromgd2(string filename)\",\n        \"Create a new image from GD2 file or URL\"\n    ],\n    \"imagecreatefromgd2part\": [\n        \"resource imagecreatefromgd2part(string filename, int srcX, int srcY, int width, int height)\",\n        \"Create a new image from a given part of GD2 file or URL\"\n    ],\n    \"imagecreatefromgif\": [\n        \"resource imagecreatefromgif(string filename)\",\n        \"Create a new image from GIF file or URL\"\n    ],\n    \"imagecreatefromjpeg\": [\n        \"resource imagecreatefromjpeg(string filename)\",\n        \"Create a new image from JPEG file or URL\"\n    ],\n    \"imagecreatefrompng\": [\n        \"resource imagecreatefrompng(string filename)\",\n        \"Create a new image from PNG file or URL\"\n    ],\n    \"imagecreatefromstring\": [\n        \"resource imagecreatefromstring(string image)\",\n        \"Create a new image from the image stream in the string\"\n    ],\n    \"imagecreatefromwbmp\": [\n        \"resource imagecreatefromwbmp(string filename)\",\n        \"Create a new image from WBMP file or URL\"\n    ],\n    \"imagecreatefromxbm\": [\n        \"resource imagecreatefromxbm(string filename)\",\n        \"Create a new image from XBM file or URL\"\n    ],\n    \"imagecreatefromxpm\": [\n        \"resource imagecreatefromxpm(string filename)\",\n        \"Create a new image from XPM file or URL\"\n    ],\n    \"imagecreatetruecolor\": [\n        \"resource imagecreatetruecolor(int x_size, int y_size)\",\n        \"Create a new true color image\"\n    ],\n    \"imagedashedline\": [\n        \"bool imagedashedline(resource im, int x1, int y1, int x2, int y2, int col)\",\n        \"Draw a dashed line\"\n    ],\n    \"imagedestroy\": [\n        \"bool imagedestroy(resource im)\",\n        \"Destroy an image\"\n    ],\n    \"imageellipse\": [\n        \"bool imageellipse(resource im, int cx, int cy, int w, int h, int color)\",\n        \"Draw an ellipse\"\n    ],\n    \"imagefill\": [\n        \"bool imagefill(resource im, int x, int y, int col)\",\n        \"Flood fill\"\n    ],\n    \"imagefilledarc\": [\n        \"bool imagefilledarc(resource im, int cx, int cy, int w, int h, int s, int e, int col, int style)\",\n        \"Draw a filled partial ellipse\"\n    ],\n    \"imagefilledellipse\": [\n        \"bool imagefilledellipse(resource im, int cx, int cy, int w, int h, int color)\",\n        \"Draw an ellipse\"\n    ],\n    \"imagefilledpolygon\": [\n        \"bool imagefilledpolygon(resource im, array point, int num_points, int col)\",\n        \"Draw a filled polygon\"\n    ],\n    \"imagefilledrectangle\": [\n        \"bool imagefilledrectangle(resource im, int x1, int y1, int x2, int y2, int col)\",\n        \"Draw a filled rectangle\"\n    ],\n    \"imagefilltoborder\": [\n        \"bool imagefilltoborder(resource im, int x, int y, int border, int col)\",\n        \"Flood fill to specific color\"\n    ],\n    \"imagefilter\": [\n        \"bool imagefilter(resource src_im, int filtertype, [args] )\",\n        \"Applies Filter an image using a custom angle\"\n    ],\n    \"imagefontheight\": [\n        \"int imagefontheight(int font)\",\n        \"Get font height\"\n    ],\n    \"imagefontwidth\": [\n        \"int imagefontwidth(int font)\",\n        \"Get font width\"\n    ],\n    \"imageftbbox\": [\n        \"array imageftbbox(float size, float angle, string font_file, string text [, array extrainfo])\",\n        \"Give the bounding box of a text using fonts via freetype2\"\n    ],\n    \"imagefttext\": [\n        \"array imagefttext(resource im, float size, float angle, int x, int y, int col, string font_file, string text [, array extrainfo])\",\n        \"Write text to the image using fonts via freetype2\"\n    ],\n    \"imagegammacorrect\": [\n        \"bool imagegammacorrect(resource im, float inputgamma, float outputgamma)\",\n        \"Apply a gamma correction to a GD image\"\n    ],\n    \"imagegd\": [\n        \"bool imagegd(resource im [, string filename])\",\n        \"Output GD image to browser or file\"\n    ],\n    \"imagegd2\": [\n        \"bool imagegd2(resource im [, string filename, [, int chunk_size, [, int type]]])\",\n        \"Output GD2 image to browser or file\"\n    ],\n    \"imagegif\": [\n        \"bool imagegif(resource im [, string filename])\",\n        \"Output GIF image to browser or file\"\n    ],\n    \"imagegrabscreen\": [\n        \"resource imagegrabscreen()\",\n        \"Grab a screenshot\"\n    ],\n    \"imagegrabwindow\": [\n        \"resource imagegrabwindow(int window_handle [, int client_area])\",\n        \"Grab a window or its client area using a windows handle (HWND property in COM instance)\"\n    ],\n    \"imageinterlace\": [\n        \"int imageinterlace(resource im [, int interlace])\",\n        \"Enable or disable interlace\"\n    ],\n    \"imageistruecolor\": [\n        \"bool imageistruecolor(resource im)\",\n        \"return true if the image uses truecolor\"\n    ],\n    \"imagejpeg\": [\n        \"bool imagejpeg(resource im [, string filename [, int quality]])\",\n        \"Output JPEG image to browser or file\"\n    ],\n    \"imagelayereffect\": [\n        \"bool imagelayereffect(resource im, int effect)\",\n        \"Set the alpha blending flag to use the bundled libgd layering effects\"\n    ],\n    \"imageline\": [\n        \"bool imageline(resource im, int x1, int y1, int x2, int y2, int col)\",\n        \"Draw a line\"\n    ],\n    \"imageloadfont\": [\n        \"int imageloadfont(string filename)\",\n        \"Load a new font\"\n    ],\n    \"imagepalettecopy\": [\n        \"void imagepalettecopy(resource dst, resource src)\",\n        \"Copy the palette from the src image onto the dst image\"\n    ],\n    \"imagepng\": [\n        \"bool imagepng(resource im [, string filename])\",\n        \"Output PNG image to browser or file\"\n    ],\n    \"imagepolygon\": [\n        \"bool imagepolygon(resource im, array point, int num_points, int col)\",\n        \"Draw a polygon\"\n    ],\n    \"imagepsbbox\": [\n        \"array imagepsbbox(string text, resource font, int size [, int space, int tightness, float angle])\",\n        \"Return the bounding box needed by a string if rasterized\"\n    ],\n    \"imagepscopyfont\": [\n        \"int imagepscopyfont(int font_index)\",\n        \"Make a copy of a font for purposes like extending or reenconding\"\n    ],\n    \"imagepsencodefont\": [\n        \"bool imagepsencodefont(resource font_index, string filename)\",\n        \"To change a fonts character encoding vector\"\n    ],\n    \"imagepsextendfont\": [\n        \"bool imagepsextendfont(resource font_index, float extend)\",\n        \"Extend or or condense if (extend < 1) a font\"\n    ],\n    \"imagepsfreefont\": [\n        \"bool imagepsfreefont(resource font_index)\",\n        \"Free memory used by a font\"\n    ],\n    \"imagepsloadfont\": [\n        \"resource imagepsloadfont(string pathname)\",\n        \"Load a new font from specified file\"\n    ],\n    \"imagepsslantfont\": [\n        \"bool imagepsslantfont(resource font_index, float slant)\",\n        \"Slant a font\"\n    ],\n    \"imagepstext\": [\n        \"array imagepstext(resource image, string text, resource font, int size, int foreground, int background, int xcoord, int ycoord [, int space [, int tightness [, float angle [, int antialias])\",\n        \"Rasterize a string over an image\"\n    ],\n    \"imagerectangle\": [\n        \"bool imagerectangle(resource im, int x1, int y1, int x2, int y2, int col)\",\n        \"Draw a rectangle\"\n    ],\n    \"imagerotate\": [\n        \"resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])\",\n        \"Rotate an image using a custom angle\"\n    ],\n    \"imagesavealpha\": [\n        \"bool imagesavealpha(resource im, bool on)\",\n        \"Include alpha channel to a saved image\"\n    ],\n    \"imagesetbrush\": [\n        \"bool imagesetbrush(resource image, resource brush)\",\n        \"Set the brush image to $brush when filling $image with the \\\"IMG_COLOR_BRUSHED\\\" color\"\n    ],\n    \"imagesetpixel\": [\n        \"bool imagesetpixel(resource im, int x, int y, int col)\",\n        \"Set a single pixel\"\n    ],\n    \"imagesetstyle\": [\n        \"bool imagesetstyle(resource im, array styles)\",\n        \"Set the line drawing styles for use with imageline and IMG_COLOR_STYLED.\"\n    ],\n    \"imagesetthickness\": [\n        \"bool imagesetthickness(resource im, int thickness)\",\n        \"Set line thickness for drawing lines, ellipses, rectangles, polygons etc.\"\n    ],\n    \"imagesettile\": [\n        \"bool imagesettile(resource image, resource tile)\",\n        \"Set the tile image to $tile when filling $image with the \\\"IMG_COLOR_TILED\\\" color\"\n    ],\n    \"imagestring\": [\n        \"bool imagestring(resource im, int font, int x, int y, string str, int col)\",\n        \"Draw a string horizontally\"\n    ],\n    \"imagestringup\": [\n        \"bool imagestringup(resource im, int font, int x, int y, string str, int col)\",\n        \"Draw a string vertically - rotated 90 degrees counter-clockwise\"\n    ],\n    \"imagesx\": [\n        \"int imagesx(resource im)\",\n        \"Get image width\"\n    ],\n    \"imagesy\": [\n        \"int imagesy(resource im)\",\n        \"Get image height\"\n    ],\n    \"imagetruecolortopalette\": [\n        \"void imagetruecolortopalette(resource im, bool ditherFlag, int colorsWanted)\",\n        \"Convert a true colour image to a palette based image with a number of colours, optionally using dithering.\"\n    ],\n    \"imagettfbbox\": [\n        \"array imagettfbbox(float size, float angle, string font_file, string text)\",\n        \"Give the bounding box of a text using TrueType fonts\"\n    ],\n    \"imagettftext\": [\n        \"array imagettftext(resource im, float size, float angle, int x, int y, int col, string font_file, string text)\",\n        \"Write text to the image using a TrueType font\"\n    ],\n    \"imagetypes\": [\n        \"int imagetypes()\",\n        \"Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM\"\n    ],\n    \"imagewbmp\": [\n        \"bool imagewbmp(resource im [, string filename, [, int foreground]])\",\n        \"Output WBMP image to browser or file\"\n    ],\n    \"imagexbm\": [\n        \"int imagexbm(int im, string filename [, int foreground])\",\n        \"Output XBM image to browser or file\"\n    ],\n    \"imap_8bit\": [\n        \"string imap_8bit(string text)\",\n        \"Convert an 8-bit string to a quoted-printable string\"\n    ],\n    \"imap_alerts\": [\n        \"array imap_alerts()\",\n        \"Returns an array of all IMAP alerts that have been generated since the last page load or since the last imap_alerts() call, whichever came last. The alert stack is cleared after imap_alerts() is called.\"\n    ],\n    \"imap_append\": [\n        \"bool imap_append(resource stream_id, string folder, string message [, string options [, string internal_date]])\",\n        \"Append a new message to a specified mailbox\"\n    ],\n    \"imap_base64\": [\n        \"string imap_base64(string text)\",\n        \"Decode BASE64 encoded text\"\n    ],\n    \"imap_binary\": [\n        \"string imap_binary(string text)\",\n        \"Convert an 8bit string to a base64 string\"\n    ],\n    \"imap_body\": [\n        \"string imap_body(resource stream_id, int msg_no [, int options])\",\n        \"Read the message body\"\n    ],\n    \"imap_bodystruct\": [\n        \"object imap_bodystruct(resource stream_id, int msg_no, string section)\",\n        \"Read the structure of a specified body section of a specific message\"\n    ],\n    \"imap_check\": [\n        \"object imap_check(resource stream_id)\",\n        \"Get mailbox properties\"\n    ],\n    \"imap_clearflag_full\": [\n        \"bool imap_clearflag_full(resource stream_id, string sequence, string flag [, int options])\",\n        \"Clears flags on messages\"\n    ],\n    \"imap_close\": [\n        \"bool imap_close(resource stream_id [, int options])\",\n        \"Close an IMAP stream\"\n    ],\n    \"imap_createmailbox\": [\n        \"bool imap_createmailbox(resource stream_id, string mailbox)\",\n        \"Create a new mailbox\"\n    ],\n    \"imap_delete\": [\n        \"bool imap_delete(resource stream_id, int msg_no [, int options])\",\n        \"Mark a message for deletion\"\n    ],\n    \"imap_deletemailbox\": [\n        \"bool imap_deletemailbox(resource stream_id, string mailbox)\",\n        \"Delete a mailbox\"\n    ],\n    \"imap_errors\": [\n        \"array imap_errors()\",\n        \"Returns an array of all IMAP errors generated since the last page load, or since the last imap_errors() call, whichever came last. The error stack is cleared after imap_errors() is called.\"\n    ],\n    \"imap_expunge\": [\n        \"bool imap_expunge(resource stream_id)\",\n        \"Permanently delete all messages marked for deletion\"\n    ],\n    \"imap_fetch_overview\": [\n        \"array imap_fetch_overview(resource stream_id, string sequence [, int options])\",\n        \"Read an overview of the information in the headers of the given message sequence\"\n    ],\n    \"imap_fetchbody\": [\n        \"string imap_fetchbody(resource stream_id, int msg_no, string section [, int options])\",\n        \"Get a specific body section\"\n    ],\n    \"imap_fetchheader\": [\n        \"string imap_fetchheader(resource stream_id, int msg_no [, int options])\",\n        \"Get the full unfiltered header for a message\"\n    ],\n    \"imap_fetchstructure\": [\n        \"object imap_fetchstructure(resource stream_id, int msg_no [, int options])\",\n        \"Read the full structure of a message\"\n    ],\n    \"imap_gc\": [\n        \"bool imap_gc(resource stream_id, int flags)\",\n        \"This function garbage collects (purges) the cache of entries of a specific type.\"\n    ],\n    \"imap_get_quota\": [\n        \"array imap_get_quota(resource stream_id, string qroot)\",\n        \"Returns the quota set to the mailbox account qroot\"\n    ],\n    \"imap_get_quotaroot\": [\n        \"array imap_get_quotaroot(resource stream_id, string mbox)\",\n        \"Returns the quota set to the mailbox account mbox\"\n    ],\n    \"imap_getacl\": [\n        \"array imap_getacl(resource stream_id, string mailbox)\",\n        \"Gets the ACL for a given mailbox\"\n    ],\n    \"imap_getmailboxes\": [\n        \"array imap_getmailboxes(resource stream_id, string ref, string pattern)\",\n        \"Reads the list of mailboxes and returns a full array of objects containing name, attributes, and delimiter\"\n    ],\n    \"imap_getsubscribed\": [\n        \"array imap_getsubscribed(resource stream_id, string ref, string pattern)\",\n        \"Return a list of subscribed mailboxes, in the same format as imap_getmailboxes()\"\n    ],\n    \"imap_headerinfo\": [\n        \"object imap_headerinfo(resource stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])\",\n        \"Read the headers of the message\"\n    ],\n    \"imap_headers\": [\n        \"array imap_headers(resource stream_id)\",\n        \"Returns headers for all messages in a mailbox\"\n    ],\n    \"imap_last_error\": [\n        \"string imap_last_error()\",\n        \"Returns the last error that was generated by an IMAP function. The error stack is NOT cleared after this call.\"\n    ],\n    \"imap_list\": [\n        \"array imap_list(resource stream_id, string ref, string pattern)\",\n        \"Read the list of mailboxes\"\n    ],\n    \"imap_listscan\": [\n        \"array imap_listscan(resource stream_id, string ref, string pattern, string content)\",\n        \"Read list of mailboxes containing a certain string\"\n    ],\n    \"imap_lsub\": [\n        \"array imap_lsub(resource stream_id, string ref, string pattern)\",\n        \"Return a list of subscribed mailboxes\"\n    ],\n    \"imap_mail\": [\n        \"bool imap_mail(string to, string subject, string message [, string additional_headers [, string cc [, string bcc [, string rpath]]]])\",\n        \"Send an email message\"\n    ],\n    \"imap_mail_compose\": [\n        \"string imap_mail_compose(array envelope, array body)\",\n        \"Create a MIME message based on given envelope and body sections\"\n    ],\n    \"imap_mail_copy\": [\n        \"bool imap_mail_copy(resource stream_id, string msglist, string mailbox [, int options])\",\n        \"Copy specified message to a mailbox\"\n    ],\n    \"imap_mail_move\": [\n        \"bool imap_mail_move(resource stream_id, string sequence, string mailbox [, int options])\",\n        \"Move specified message to a mailbox\"\n    ],\n    \"imap_mailboxmsginfo\": [\n        \"object imap_mailboxmsginfo(resource stream_id)\",\n        \"Returns info about the current mailbox\"\n    ],\n    \"imap_mime_header_decode\": [\n        \"array imap_mime_header_decode(string str)\",\n        \"Decode mime header element in accordance with RFC 2047 and return array of objects containing 'charset' encoding and decoded 'text'\"\n    ],\n    \"imap_msgno\": [\n        \"int imap_msgno(resource stream_id, int unique_msg_id)\",\n        \"Get the sequence number associated with a UID\"\n    ],\n    \"imap_mutf7_to_utf8\": [\n        \"string imap_mutf7_to_utf8(string in)\",\n        \"Decode a modified UTF-7 string to UTF-8\"\n    ],\n    \"imap_num_msg\": [\n        \"int imap_num_msg(resource stream_id)\",\n        \"Gives the number of messages in the current mailbox\"\n    ],\n    \"imap_num_recent\": [\n        \"int imap_num_recent(resource stream_id)\",\n        \"Gives the number of recent messages in current mailbox\"\n    ],\n    \"imap_open\": [\n        \"resource imap_open(string mailbox, string user, string password [, int options [, int n_retries]])\",\n        \"Open an IMAP stream to a mailbox\"\n    ],\n    \"imap_ping\": [\n        \"bool imap_ping(resource stream_id)\",\n        \"Check if the IMAP stream is still active\"\n    ],\n    \"imap_qprint\": [\n        \"string imap_qprint(string text)\",\n        \"Convert a quoted-printable string to an 8-bit string\"\n    ],\n    \"imap_renamemailbox\": [\n        \"bool imap_renamemailbox(resource stream_id, string old_name, string new_name)\",\n        \"Rename a mailbox\"\n    ],\n    \"imap_reopen\": [\n        \"bool imap_reopen(resource stream_id, string mailbox [, int options [, int n_retries]])\",\n        \"Reopen an IMAP stream to a new mailbox\"\n    ],\n    \"imap_rfc822_parse_adrlist\": [\n        \"array imap_rfc822_parse_adrlist(string address_string, string default_host)\",\n        \"Parses an address string\"\n    ],\n    \"imap_rfc822_parse_headers\": [\n        \"object imap_rfc822_parse_headers(string headers [, string default_host])\",\n        \"Parse a set of mail headers contained in a string, and return an object similar to imap_headerinfo()\"\n    ],\n    \"imap_rfc822_write_address\": [\n        \"string imap_rfc822_write_address(string mailbox, string host, string personal)\",\n        \"Returns a properly formatted email address given the mailbox, host, and personal info\"\n    ],\n    \"imap_savebody\": [\n        \"bool imap_savebody(resource stream_id, string|resource file, int msg_no[, string section = \\\"\\\"[, int options = 0]])\",\n        \"Save a specific body section to a file\"\n    ],\n    \"imap_search\": [\n        \"array imap_search(resource stream_id, string criteria [, int options [, string charset]])\",\n        \"Return a list of messages matching the given criteria\"\n    ],\n    \"imap_set_quota\": [\n        \"bool imap_set_quota(resource stream_id, string qroot, int mailbox_size)\",\n        \"Will set the quota for qroot mailbox\"\n    ],\n    \"imap_setacl\": [\n        \"bool imap_setacl(resource stream_id, string mailbox, string id, string rights)\",\n        \"Sets the ACL for a given mailbox\"\n    ],\n    \"imap_setflag_full\": [\n        \"bool imap_setflag_full(resource stream_id, string sequence, string flag [, int options])\",\n        \"Sets flags on messages\"\n    ],\n    \"imap_sort\": [\n        \"array imap_sort(resource stream_id, int criteria, int reverse [, int options [, string search_criteria [, string charset]]])\",\n        \"Sort an array of message headers, optionally including only messages that meet specified criteria.\"\n    ],\n    \"imap_status\": [\n        \"object imap_status(resource stream_id, string mailbox, int options)\",\n        \"Get status info from a mailbox\"\n    ],\n    \"imap_subscribe\": [\n        \"bool imap_subscribe(resource stream_id, string mailbox)\",\n        \"Subscribe to a mailbox\"\n    ],\n    \"imap_thread\": [\n        \"array imap_thread(resource stream_id [, int options])\",\n        \"Return threaded by REFERENCES tree\"\n    ],\n    \"imap_timeout\": [\n        \"mixed imap_timeout(int timeout_type [, int timeout])\",\n        \"Set or fetch imap timeout\"\n    ],\n    \"imap_uid\": [\n        \"int imap_uid(resource stream_id, int msg_no)\",\n        \"Get the unique message id associated with a standard sequential message number\"\n    ],\n    \"imap_undelete\": [\n        \"bool imap_undelete(resource stream_id, int msg_no [, int flags])\",\n        \"Remove the delete flag from a message\"\n    ],\n    \"imap_unsubscribe\": [\n        \"bool imap_unsubscribe(resource stream_id, string mailbox)\",\n        \"Unsubscribe from a mailbox\"\n    ],\n    \"imap_utf7_decode\": [\n        \"string imap_utf7_decode(string buf)\",\n        \"Decode a modified UTF-7 string\"\n    ],\n    \"imap_utf7_encode\": [\n        \"string imap_utf7_encode(string buf)\",\n        \"Encode a string in modified UTF-7\"\n    ],\n    \"imap_utf8\": [\n        \"string imap_utf8(string mime_encoded_text)\",\n        \"Convert a mime-encoded text to UTF-8\"\n    ],\n    \"imap_utf8_to_mutf7\": [\n        \"string imap_utf8_to_mutf7(string in)\",\n        \"Encode a UTF-8 string to modified UTF-7\"\n    ],\n    \"implode\": [\n        \"string implode([string glue,] array pieces)\",\n        \"Joins array elements placing glue string between items and return one string\"\n    ],\n    \"import_request_variables\": [\n        \"bool import_request_variables(string types [, string prefix])\",\n        \"Import GET/POST/Cookie variables into the global scope\"\n    ],\n    \"in_array\": [\n        \"bool in_array(mixed needle, array haystack [, bool strict])\",\n        \"Checks if the given value exists in the array\"\n    ],\n    \"include\": [\n        \"bool include(string path)\",\n        \"Includes and evaluates the specified file\"\n    ],\n    \"include_once\": [\n        \"bool include_once(string path)\",\n        \"Includes and evaluates the specified file\"\n    ],\n    \"inet_ntop\": [\n        \"string inet_ntop(string in_addr)\",\n        \"Converts a packed inet address to a human readable IP address string\"\n    ],\n    \"inet_pton\": [\n        \"string inet_pton(string ip_address)\",\n        \"Converts a human readable IP address to a packed binary string\"\n    ],\n    \"ini_get\": [\n        \"string ini_get(string varname)\",\n        \"Get a configuration option\"\n    ],\n    \"ini_get_all\": [\n        \"array ini_get_all([string extension[, bool details = true]])\",\n        \"Get all configuration options\"\n    ],\n    \"ini_restore\": [\n        \"void ini_restore(string varname)\",\n        \"Restore the value of a configuration option specified by varname\"\n    ],\n    \"ini_set\": [\n        \"string ini_set(string varname, string newvalue)\",\n        \"Set a configuration option, returns false on error and the old value of the configuration option on success\"\n    ],\n    \"interface_exists\": [\n        \"bool interface_exists(string classname [, bool autoload])\",\n        \"Checks if the class exists\"\n    ],\n    \"intl_error_name\": [\n        \"string intl_error_name()\",\n        \"* Return a string for a given error code.  * The string will be the same as the name of the error code constant.\"\n    ],\n    \"intl_get_error_code\": [\n        \"int intl_get_error_code()\",\n        \"* Get code of the last occured error.\"\n    ],\n    \"intl_get_error_message\": [\n        \"string intl_get_error_message()\",\n        \"* Get text description of the last occured error.\"\n    ],\n    \"intl_is_failure\": [\n        \"bool intl_is_failure()\",\n        \"* Check whether the given error code indicates a failure.  * Returns true if it does, and false if the code  * indicates success or a warning.\"\n    ],\n    \"intval\": [\n        \"int intval(mixed var [, int base])\",\n        \"Get the integer value of a variable using the optional base for the conversion\"\n    ],\n    \"ip2long\": [\n        \"int ip2long(string ip_address)\",\n        \"Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address\"\n    ],\n    \"iptcembed\": [\n        \"array iptcembed(string iptcdata, string jpeg_file_name [, int spool])\",\n        \"Embed binary IPTC data into a JPEG image.\"\n    ],\n    \"iptcparse\": [\n        \"array iptcparse(string iptcdata)\",\n        \"Parse binary IPTC-data into associative array\"\n    ],\n    \"is_a\": [\n        \"bool is_a(object object, string class_name)\",\n        \"Returns true if the object is of this class or has this class as one of its parents\"\n    ],\n    \"is_array\": [\n        \"bool is_array(mixed var)\",\n        \"Returns true if variable is an array\"\n    ],\n    \"is_bool\": [\n        \"bool is_bool(mixed var)\",\n        \"Returns true if variable is a boolean\"\n    ],\n    \"is_callable\": [\n        \"bool is_callable(mixed var [, bool syntax_only [, string callable_name]])\",\n        \"Returns true if var is callable.\"\n    ],\n    \"is_countable\": [\n        \"bool is_countable(mixed var)\",\n        \"Returns true if var is countable, false otherwise\"\n    ],\n    \"is_dir\": [\n        \"bool is_dir(string filename)\",\n        \"Returns true if file is directory\"\n    ],\n    \"is_executable\": [\n        \"bool is_executable(string filename)\",\n        \"Returns true if file is executable\"\n    ],\n    \"is_file\": [\n        \"bool is_file(string filename)\",\n        \"Returns true if file is a regular file\"\n    ],\n    \"is_finite\": [\n        \"bool is_finite(float val)\",\n        \"Returns whether argument is finite\"\n    ],\n    \"is_float\": [\n        \"bool is_float(mixed var)\",\n        \"Returns true if variable is float point\"\n    ],\n    \"is_infinite\": [\n        \"bool is_infinite(float val)\",\n        \"Returns whether argument is infinite\"\n    ],\n    \"is_link\": [\n        \"bool is_link(string filename)\",\n        \"Returns true if file is symbolic link\"\n    ],\n    \"is_long\": [\n        \"bool is_long(mixed var)\",\n        \"Returns true if variable is a long (integer)\"\n    ],\n    \"is_nan\": [\n        \"bool is_nan(float val)\",\n        \"Returns whether argument is not a number\"\n    ],\n    \"is_null\": [\n        \"bool is_null(mixed var)\",\n        \"Returns true if variable is null\"\n    ],\n    \"is_numeric\": [\n        \"bool is_numeric(mixed value)\",\n        \"Returns true if value is a number or a numeric string\"\n    ],\n    \"is_object\": [\n        \"bool is_object(mixed var)\",\n        \"Returns true if variable is an object\"\n    ],\n    \"is_readable\": [\n        \"bool is_readable(string filename)\",\n        \"Returns true if file can be read\"\n    ],\n    \"is_resource\": [\n        \"bool is_resource(mixed var)\",\n        \"Returns true if variable is a resource\"\n    ],\n    \"is_scalar\": [\n        \"bool is_scalar(mixed value)\",\n        \"Returns true if value is a scalar\"\n    ],\n    \"is_string\": [\n        \"bool is_string(mixed var)\",\n        \"Returns true if variable is a string\"\n    ],\n    \"is_subclass_of\": [\n        \"bool is_subclass_of(object object, string class_name)\",\n        \"Returns true if the object has this class as one of its parents\"\n    ],\n    \"is_uploaded_file\": [\n        \"bool is_uploaded_file(string path)\",\n        \"Check if file was created by rfc1867 upload\"\n    ],\n    \"is_writable\": [\n        \"bool is_writable(string filename)\",\n        \"Returns true if file can be written\"\n    ],\n    \"isset\": [\n        \"bool isset(mixed var [, mixed var])\",\n        \"Determine whether a variable is set\"\n    ],\n    \"iterator_apply\": [\n        \"int iterator_apply(Traversable iterator, callable function [, array args = null)\",\n        \"Calls a function for every element in an iterator\"\n    ],\n    \"iterator_count\": [\n        \"int iterator_count(Traversable iterator)\",\n        \"Count the elements in an iterator\"\n    ],\n    \"iterator_to_array\": [\n        \"array iterator_to_array(Traversable iterator [, bool use_keys = true])\",\n        \"Copy the iterator into an array\"\n    ],\n    \"jddayofweek\": [\n        \"mixed jddayofweek(int juliandaycount [, int mode])\",\n        \"Returns name or number of day of week from julian day count\"\n    ],\n    \"jdmonthname\": [\n        \"string jdmonthname(int juliandaycount, int mode)\",\n        \"Returns name of month for julian day count\"\n    ],\n    \"jdtofrench\": [\n        \"string jdtofrench(int juliandaycount)\",\n        \"Converts a julian day count to a french republic calendar date\"\n    ],\n    \"jdtogregorian\": [\n        \"string jdtogregorian(int juliandaycount)\",\n        \"Converts a julian day count to a gregorian calendar date\"\n    ],\n    \"jdtojewish\": [\n        \"string jdtojewish(int juliandaycount [, bool hebrew [, int fl]])\",\n        \"Converts a julian day count to a jewish calendar date\"\n    ],\n    \"jdtojulian\": [\n        \"string jdtojulian(int juliandaycount)\",\n        \"Convert a julian day count to a julian calendar date\"\n    ],\n    \"jdtounix\": [\n        \"int jdtounix(int jday)\",\n        \"Convert Julian Day to UNIX timestamp\"\n    ],\n    \"jewishtojd\": [\n        \"int jewishtojd(int month, int day, int year)\",\n        \"Converts a jewish calendar date to a julian day count\"\n    ],\n    \"join\": [\n        \"string join([string glue,] array pieces)\",\n        \"Returns a string containing a string representation of all the arrayelements in the same order, with the glue string between each element\"\n    ],\n    \"jpeg2wbmp\": [\n        \"bool jpeg2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)\",\n        \"Convert JPEG image to WBMP image\"\n    ],\n    \"json_decode\": [\n        \"mixed json_decode(string json [, bool assoc [, long depth]])\",\n        \"Decodes the JSON representation into a PHP value\"\n    ],\n    \"json_encode\": [\n        \"string json_encode(mixed data [, int options])\",\n        \"Returns the JSON representation of a value\"\n    ],\n    \"json_last_error\": [\n        \"int json_last_error()\",\n        \"Returns the error code of the last json_decode().\"\n    ],\n    \"juliantojd\": [\n        \"int juliantojd(int month, int day, int year)\",\n        \"Converts a julian calendar date to julian day count\"\n    ],\n    \"key\": [\n        \"mixed key(array array_arg)\",\n        \"Return the key of the element currently pointed to by the internal array pointer\"\n    ],\n    \"krsort\": [\n        \"bool krsort(array &array_arg [, int sort_flags])\",\n        \"Sort an array by key value in reverse order\"\n    ],\n    \"ksort\": [\n        \"bool ksort(array &array_arg [, int sort_flags])\",\n        \"Sort an array by key\"\n    ],\n    \"lcfirst\": [\n        \"string lcfirst(string str)\",\n        \"Make a string's first character lowercase\"\n    ],\n    \"lcg_value\": [\n        \"float lcg_value()\",\n        \"Returns a value from the combined linear congruential generator\"\n    ],\n    \"lchgrp\": [\n        \"bool lchgrp(string filename, mixed group)\",\n        \"Change symlink group\"\n    ],\n    \"ldap_8859_to_t61\": [\n        \"string ldap_8859_to_t61(string value)\",\n        \"Translate 8859 characters to t61 characters\"\n    ],\n    \"ldap_add\": [\n        \"bool ldap_add(resource link, string dn, array entry)\",\n        \"Add entries to LDAP directory\"\n    ],\n    \"ldap_bind\": [\n        \"bool ldap_bind(resource link [, string dn [, string password]])\",\n        \"Bind to LDAP directory\"\n    ],\n    \"ldap_compare\": [\n        \"bool ldap_compare(resource link, string dn, string attr, string value)\",\n        \"Determine if an entry has a specific value for one of its attributes\"\n    ],\n    \"ldap_connect\": [\n        \"resource ldap_connect([string host [, int port [, string wallet [, string wallet_passwd [, int authmode]]]]])\",\n        \"Connect to an LDAP server\"\n    ],\n    \"ldap_count_entries\": [\n        \"int ldap_count_entries(resource link, resource result)\",\n        \"Count the number of entries in a search result\"\n    ],\n    \"ldap_delete\": [\n        \"bool ldap_delete(resource link, string dn)\",\n        \"Delete an entry from a directory\"\n    ],\n    \"ldap_dn2ufn\": [\n        \"string ldap_dn2ufn(string dn)\",\n        \"Convert DN to User Friendly Naming format\"\n    ],\n    \"ldap_err2str\": [\n        \"string ldap_err2str(int errno)\",\n        \"Convert error number to error string\"\n    ],\n    \"ldap_errno\": [\n        \"int ldap_errno(resource link)\",\n        \"Get the current ldap error number\"\n    ],\n    \"ldap_error\": [\n        \"string ldap_error(resource link)\",\n        \"Get the current ldap error string\"\n    ],\n    \"ldap_explode_dn\": [\n        \"array ldap_explode_dn(string dn, int with_attrib)\",\n        \"Splits DN into its component parts\"\n    ],\n    \"ldap_first_attribute\": [\n        \"string ldap_first_attribute(resource link, resource result_entry)\",\n        \"Return first attribute\"\n    ],\n    \"ldap_first_entry\": [\n        \"resource ldap_first_entry(resource link, resource result)\",\n        \"Return first result id\"\n    ],\n    \"ldap_first_reference\": [\n        \"resource ldap_first_reference(resource link, resource result)\",\n        \"Return first reference\"\n    ],\n    \"ldap_free_result\": [\n        \"bool ldap_free_result(resource result)\",\n        \"Free result memory\"\n    ],\n    \"ldap_get_attributes\": [\n        \"array ldap_get_attributes(resource link, resource result_entry)\",\n        \"Get attributes from a search result entry\"\n    ],\n    \"ldap_get_dn\": [\n        \"string ldap_get_dn(resource link, resource result_entry)\",\n        \"Get the DN of a result entry\"\n    ],\n    \"ldap_get_entries\": [\n        \"array ldap_get_entries(resource link, resource result)\",\n        \"Get all result entries\"\n    ],\n    \"ldap_get_option\": [\n        \"bool ldap_get_option(resource link, int option, mixed retval)\",\n        \"Get the current value of various session-wide parameters\"\n    ],\n    \"ldap_get_values_len\": [\n        \"array ldap_get_values_len(resource link, resource result_entry, string attribute)\",\n        \"Get all values with lengths from a result entry\"\n    ],\n    \"ldap_list\": [\n        \"resource ldap_list(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])\",\n        \"Single-level search\"\n    ],\n    \"ldap_mod_add\": [\n        \"bool ldap_mod_add(resource link, string dn, array entry)\",\n        \"Add attribute values to current\"\n    ],\n    \"ldap_mod_del\": [\n        \"bool ldap_mod_del(resource link, string dn, array entry)\",\n        \"Delete attribute values\"\n    ],\n    \"ldap_mod_replace\": [\n        \"bool ldap_mod_replace(resource link, string dn, array entry)\",\n        \"Replace attribute values with new ones\"\n    ],\n    \"ldap_next_attribute\": [\n        \"string ldap_next_attribute(resource link, resource result_entry)\",\n        \"Get the next attribute in result\"\n    ],\n    \"ldap_next_entry\": [\n        \"resource ldap_next_entry(resource link, resource result_entry)\",\n        \"Get next result entry\"\n    ],\n    \"ldap_next_reference\": [\n        \"resource ldap_next_reference(resource link, resource reference_entry)\",\n        \"Get next reference\"\n    ],\n    \"ldap_parse_reference\": [\n        \"bool ldap_parse_reference(resource link, resource reference_entry, array referrals)\",\n        \"Extract information from reference entry\"\n    ],\n    \"ldap_parse_result\": [\n        \"bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals)\",\n        \"Extract information from result\"\n    ],\n    \"ldap_read\": [\n        \"resource ldap_read(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])\",\n        \"Read an entry\"\n    ],\n    \"ldap_rename\": [\n        \"bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn)\",\n        \"Modify the name of an entry\"\n    ],\n    \"ldap_sasl_bind\": [\n        \"bool ldap_sasl_bind(resource link [, string binddn [, string password [, string sasl_mech [, string sasl_realm [, string sasl_authc_id [, string sasl_authz_id [, string props]]]]]]])\",\n        \"Bind to LDAP directory using SASL\"\n    ],\n    \"ldap_search\": [\n        \"resource ldap_search(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])\",\n        \"Search LDAP tree under base_dn\"\n    ],\n    \"ldap_set_option\": [\n        \"bool ldap_set_option(resource link, int option, mixed newval)\",\n        \"Set the value of various session-wide parameters\"\n    ],\n    \"ldap_set_rebind_proc\": [\n        \"bool ldap_set_rebind_proc(resource link, string callback)\",\n        \"Set a callback function to do re-binds on referral chasing.\"\n    ],\n    \"ldap_sort\": [\n        \"bool ldap_sort(resource link, resource result, string sortfilter)\",\n        \"Sort LDAP result entries\"\n    ],\n    \"ldap_start_tls\": [\n        \"bool ldap_start_tls(resource link)\",\n        \"Start TLS\"\n    ],\n    \"ldap_t61_to_8859\": [\n        \"string ldap_t61_to_8859(string value)\",\n        \"Translate t61 characters to 8859 characters\"\n    ],\n    \"ldap_unbind\": [\n        \"bool ldap_unbind(resource link)\",\n        \"Unbind from LDAP directory\"\n    ],\n    \"leak\": [\n        \"void leak(int num_bytes=3)\",\n        \"Cause an intentional memory leak, for testing/debugging purposes\"\n    ],\n    \"levenshtein\": [\n        \"int levenshtein(string str1, string str2[, int cost_ins, int cost_rep, int cost_del])\",\n        \"Calculate Levenshtein distance between two strings\"\n    ],\n    \"libxml_clear_errors\": [\n        \"void libxml_clear_errors()\",\n        \"Clear last error from libxml\"\n    ],\n    \"libxml_disable_entity_loader\": [\n        \"bool libxml_disable_entity_loader([bool disable])\",\n        \"Disable/Enable ability to load external entities\"\n    ],\n    \"libxml_get_errors\": [\n        \"object libxml_get_errors()\",\n        \"Retrieve array of errors\"\n    ],\n    \"libxml_get_last_error\": [\n        \"object libxml_get_last_error()\",\n        \"Retrieve last error from libxml\"\n    ],\n    \"libxml_set_streams_context\": [\n        \"void libxml_set_streams_context(resource streams_context)\",\n        \"Set the streams context for the next libxml document load or write\"\n    ],\n    \"libxml_use_internal_errors\": [\n        \"bool libxml_use_internal_errors([bool use_errors])\",\n        \"Disable libxml errors and allow user to fetch error information as needed\"\n    ],\n    \"link\": [\n        \"int link(string target, string link)\",\n        \"Create a hard link\"\n    ],\n    \"linkinfo\": [\n        \"int linkinfo(string filename)\",\n        \"Returns the st_dev field of the UNIX C stat structure describing the link\"\n    ],\n    \"litespeed_request_headers\": [\n        \"array litespeed_request_headers()\",\n        \"Fetch all HTTP request headers\"\n    ],\n    \"litespeed_response_headers\": [\n        \"array litespeed_response_headers()\",\n        \"Fetch all HTTP response headers\"\n    ],\n    \"locale_accept_from_http\": [\n        \"string locale_accept_from_http(string $http_accept)\",\n        null\n    ],\n    \"locale_canonicalize\": [\n        \"static string locale_canonicalize(Locale $loc, string $locale)\",\n        \"* @param string $locale The locale string to canonicalize\"\n    ],\n    \"locale_filter_matches\": [\n        \"bool locale_filter_matches(string $langtag, string $locale[, bool $canonicalize])\",\n        \"* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm\"\n    ],\n    \"locale_get_all_variants\": [\n        \"static array locale_get_all_variants($locale)\",\n        \"* gets an array containing the list of variants, or null\"\n    ],\n    \"locale_get_default\": [\n        \"static string locale_get_default( )\",\n        \"Get default locale\"\n    ],\n    \"locale_get_keywords\": [\n        \"static array locale_get_keywords(string $locale) {\",\n        \"* return an associative array containing keyword-value  * pairs for this locale. The keys are keys to the array\"\n    ],\n    \"locale_get_primary_language\": [\n        \"static string locale_get_primary_language($locale)\",\n        \"* gets the primary language for the $locale\"\n    ],\n    \"locale_get_region\": [\n        \"static string locale_get_region($locale)\",\n        \"* gets the region for the $locale\"\n    ],\n    \"locale_get_script\": [\n        \"static string locale_get_script($locale)\",\n        \"* gets the script for the $locale\"\n    ],\n    \"locale_lookup\": [\n        \"string locale_lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]])\",\n        \"* Searchs the items in $langtag for the best match to the language * range\"\n    ],\n    \"locale_set_default\": [\n        \"static string locale_set_default( string $locale )\",\n        \"Set default locale\"\n    ],\n    \"localeconv\": [\n        \"array localeconv()\",\n        \"Returns numeric formatting information based on the current locale\"\n    ],\n    \"localtime\": [\n        \"array localtime([int timestamp [, bool associative_array]])\",\n        \"Returns the results of the C system call localtime as an associative array if the associative_array argument is set to 1 other wise it is a regular array\"\n    ],\n    \"log\": [\n        \"float log(float number, [float base])\",\n        \"Returns the natural logarithm of the number, or the base log if base is specified\"\n    ],\n    \"log10\": [\n        \"float log10(float number)\",\n        \"Returns the base-10 logarithm of the number\"\n    ],\n    \"log1p\": [\n        \"float log1p(float number)\",\n        \"Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero\"\n    ],\n    \"long2ip\": [\n        \"string long2ip(int proper_address)\",\n        \"Converts an (IPv4) Internet network address into a string in Internet standard dotted format\"\n    ],\n    \"lstat\": [\n        \"array lstat(string filename)\",\n        \"Give information about a file or symbolic link\"\n    ],\n    \"ltrim\": [\n        \"string ltrim(string str [, string character_mask])\",\n        \"Strips whitespace from the beginning of a string\"\n    ],\n    \"mail\": [\n        \"int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])\",\n        \"Send an email message\"\n    ],\n    \"max\": [\n        \"mixed max(mixed arg1 [, mixed arg2 [, mixed ...]])\",\n        \"Return the highest value in an array or a series of arguments\"\n    ],\n    \"mb_check_encoding\": [\n        \"bool mb_check_encoding([string var[, string encoding]])\",\n        \"Check if the string is valid for the specified encoding\"\n    ],\n    \"mb_convert_case\": [\n        \"string mb_convert_case(string sourcestring, int mode [, string encoding])\",\n        \"Returns a case-folded version of sourcestring\"\n    ],\n    \"mb_convert_encoding\": [\n        \"string mb_convert_encoding(string str, string to-encoding [, mixed from-encoding])\",\n        \"Returns converted string in desired encoding\"\n    ],\n    \"mb_convert_kana\": [\n        \"string mb_convert_kana(string str [, string option] [, string encoding])\",\n        \"Conversion between full-width character and half-width character (Japanese)\"\n    ],\n    \"mb_convert_variables\": [\n        \"string mb_convert_variables(string to-encoding, mixed from-encoding, mixed vars [, ...])\",\n        \"Converts the string resource in variables to desired encoding\"\n    ],\n    \"mb_decode_mimeheader\": [\n        \"string mb_decode_mimeheader(string string)\",\n        \"Decodes the MIME \\\"encoded-word\\\" in the string\"\n    ],\n    \"mb_decode_numericentity\": [\n        \"string mb_decode_numericentity(string string, array convmap [, string encoding])\",\n        \"Converts HTML numeric entities to character code\"\n    ],\n    \"mb_detect_encoding\": [\n        \"string mb_detect_encoding(string str [, mixed encoding_list [, bool strict]])\",\n        \"Encodings of the given string is returned (as a string)\"\n    ],\n    \"mb_detect_order\": [\n        \"bool|array mb_detect_order([mixed encoding-list])\",\n        \"Sets the current detect_order or Return the current detect_order as a array\"\n    ],\n    \"mb_encode_mimeheader\": [\n        \"string mb_encode_mimeheader(string str [, string charset [, string transfer-encoding [, string linefeed [, int indent]]]])\",\n        \"Converts the string to MIME \\\"encoded-word\\\" in the format of =?charset?(B|Q)?encoded_string?=\"\n    ],\n    \"mb_encode_numericentity\": [\n        \"string mb_encode_numericentity(string string, array convmap [, string encoding])\",\n        \"Converts specified characters to HTML numeric entities\"\n    ],\n    \"mb_encoding_aliases\": [\n        \"array mb_encoding_aliases(string encoding)\",\n        \"Returns an array of the aliases of a given encoding name\"\n    ],\n    \"mb_ereg\": [\n        \"int mb_ereg(string pattern, string string [, array registers])\",\n        \"Regular expression match for multibyte string\"\n    ],\n    \"mb_ereg_match\": [\n        \"bool mb_ereg_match(string pattern, string string [,string option])\",\n        \"Regular expression match for multibyte string\"\n    ],\n    \"mb_ereg_replace\": [\n        \"string mb_ereg_replace(string pattern, string replacement, string string [, string option])\",\n        \"Replace regular expression for multibyte string\"\n    ],\n    \"mb_ereg_search\": [\n        \"bool mb_ereg_search([string pattern[, string option]])\",\n        \"Regular expression search for multibyte string\"\n    ],\n    \"mb_ereg_search_getpos\": [\n        \"int mb_ereg_search_getpos()\",\n        \"Get search start position\"\n    ],\n    \"mb_ereg_search_getregs\": [\n        \"array mb_ereg_search_getregs()\",\n        \"Get matched substring of the last time\"\n    ],\n    \"mb_ereg_search_init\": [\n        \"bool mb_ereg_search_init(string string [, string pattern[, string option]])\",\n        \"Initialize string and regular expression for search.\"\n    ],\n    \"mb_ereg_search_pos\": [\n        \"array mb_ereg_search_pos([string pattern[, string option]])\",\n        \"Regular expression search for multibyte string\"\n    ],\n    \"mb_ereg_search_regs\": [\n        \"array mb_ereg_search_regs([string pattern[, string option]])\",\n        \"Regular expression search for multibyte string\"\n    ],\n    \"mb_ereg_search_setpos\": [\n        \"bool mb_ereg_search_setpos(int position)\",\n        \"Set search start position\"\n    ],\n    \"mb_eregi\": [\n        \"int mb_eregi(string pattern, string string [, array registers])\",\n        \"Case-insensitive regular expression match for multibyte string\"\n    ],\n    \"mb_eregi_replace\": [\n        \"string mb_eregi_replace(string pattern, string replacement, string string)\",\n        \"Case insensitive replace regular expression for multibyte string\"\n    ],\n    \"mb_get_info\": [\n        \"mixed mb_get_info([string type])\",\n        \"Returns the current settings of mbstring\"\n    ],\n    \"mb_http_input\": [\n        \"mixed mb_http_input([string type])\",\n        \"Returns the input encoding\"\n    ],\n    \"mb_http_output\": [\n        \"string mb_http_output([string encoding])\",\n        \"Sets the current output_encoding or returns the current output_encoding as a string\"\n    ],\n    \"mb_internal_encoding\": [\n        \"string mb_internal_encoding([string encoding])\",\n        \"Sets the current internal encoding or Returns the current internal encoding as a string\"\n    ],\n    \"mb_language\": [\n        \"string mb_language([string language])\",\n        \"Sets the current language or Returns the current language as a string\"\n    ],\n    \"mb_list_encodings\": [\n        \"mixed mb_list_encodings()\",\n        \"Returns an array of all supported entity encodings\"\n    ],\n    \"mb_output_handler\": [\n        \"string mb_output_handler(string contents, int status)\",\n        \"Returns string in output buffer converted to the http_output encoding\"\n    ],\n    \"mb_parse_str\": [\n        \"bool mb_parse_str(string encoded_string [, array result])\",\n        \"Parses GET/POST/COOKIE data and sets global variables\"\n    ],\n    \"mb_preferred_mime_name\": [\n        \"string mb_preferred_mime_name(string encoding)\",\n        \"Return the preferred MIME name (charset) as a string\"\n    ],\n    \"mb_regex_encoding\": [\n        \"string mb_regex_encoding([string encoding])\",\n        \"Returns the current encoding for regex as a string.\"\n    ],\n    \"mb_regex_set_options\": [\n        \"string mb_regex_set_options([string options])\",\n        \"Set or get the default options for mbregex functions\"\n    ],\n    \"mb_send_mail\": [\n        \"int mb_send_mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])\",\n        \"*  Sends an email message with MIME scheme\"\n    ],\n    \"mb_split\": [\n        \"array mb_split(string pattern, string string [, int limit])\",\n        \"split multibyte string into array by regular expression\"\n    ],\n    \"mb_strcut\": [\n        \"string mb_strcut(string str, int start [, int length [, string encoding]])\",\n        \"Returns part of a string\"\n    ],\n    \"mb_strimwidth\": [\n        \"string mb_strimwidth(string str, int start, int width [, string trimmarker [, string encoding]])\",\n        \"Trim the string in terminal width\"\n    ],\n    \"mb_stripos\": [\n        \"int mb_stripos(string haystack, string needle [, int offset [, string encoding]])\",\n        \"Finds position of first occurrence of a string within another, case insensitive\"\n    ],\n    \"mb_stristr\": [\n        \"string mb_stristr(string haystack, string needle[, bool part[, string encoding]])\",\n        \"Finds first occurrence of a string within another, case insensitive\"\n    ],\n    \"mb_strlen\": [\n        \"int mb_strlen(string str [, string encoding])\",\n        \"Get character numbers of a string\"\n    ],\n    \"mb_strpos\": [\n        \"int mb_strpos(string haystack, string needle [, int offset [, string encoding]])\",\n        \"Find position of first occurrence of a string within another\"\n    ],\n    \"mb_strrchr\": [\n        \"string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])\",\n        \"Finds the last occurrence of a character in a string within another\"\n    ],\n    \"mb_strrichr\": [\n        \"string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])\",\n        \"Finds the last occurrence of a character in a string within another, case insensitive\"\n    ],\n    \"mb_strripos\": [\n        \"int mb_strripos(string haystack, string needle [, int offset [, string encoding]])\",\n        \"Finds position of last occurrence of a string within another, case insensitive\"\n    ],\n    \"mb_strrpos\": [\n        \"int mb_strrpos(string haystack, string needle [, int offset [, string encoding]])\",\n        \"Find position of last occurrence of a string within another\"\n    ],\n    \"mb_strstr\": [\n        \"string mb_strstr(string haystack, string needle[, bool part[, string encoding]])\",\n        \"Finds first occurrence of a string within another\"\n    ],\n    \"mb_strtolower\": [\n        \"string mb_strtolower(string sourcestring [, string encoding])\",\n        \"*  Returns a lowercased version of sourcestring\"\n    ],\n    \"mb_strtoupper\": [\n        \"string mb_strtoupper(string sourcestring [, string encoding])\",\n        \"*  Returns a uppercased version of sourcestring\"\n    ],\n    \"mb_strwidth\": [\n        \"int mb_strwidth(string str [, string encoding])\",\n        \"Gets terminal width of a string\"\n    ],\n    \"mb_substitute_character\": [\n        \"mixed mb_substitute_character([mixed substchar])\",\n        \"Sets the current substitute_character or returns the current substitute_character\"\n    ],\n    \"mb_substr\": [\n        \"string mb_substr(string str, int start [, int length [, string encoding]])\",\n        \"Returns part of a string\"\n    ],\n    \"mb_substr_count\": [\n        \"int mb_substr_count(string haystack, string needle [, string encoding])\",\n        \"Count the number of substring occurrences\"\n    ],\n    \"mcrypt_cbc\": [\n        \"string mcrypt_cbc(int cipher, string key, string data, int mode, string iv)\",\n        \"CBC crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"mcrypt_cfb\": [\n        \"string mcrypt_cfb(int cipher, string key, string data, int mode, string iv)\",\n        \"CFB crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"mcrypt_create_iv\": [\n        \"string mcrypt_create_iv(int size, int source)\",\n        \"Create an initialization vector (IV)\"\n    ],\n    \"mcrypt_decrypt\": [\n        \"string mcrypt_decrypt(string cipher, string key, string data, string mode, string iv)\",\n        \"OFB crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"mcrypt_ecb\": [\n        \"string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)\",\n        \"ECB crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"mcrypt_enc_get_algorithms_name\": [\n        \"string mcrypt_enc_get_algorithms_name(resource td)\",\n        \"Returns the name of the algorithm specified by the descriptor td\"\n    ],\n    \"mcrypt_enc_get_block_size\": [\n        \"int mcrypt_enc_get_block_size(resource td)\",\n        \"Returns the block size of the cipher specified by the descriptor td\"\n    ],\n    \"mcrypt_enc_get_iv_size\": [\n        \"int mcrypt_enc_get_iv_size(resource td)\",\n        \"Returns the size of the IV in bytes of the algorithm specified by the descriptor td\"\n    ],\n    \"mcrypt_enc_get_key_size\": [\n        \"int mcrypt_enc_get_key_size(resource td)\",\n        \"Returns the maximum supported key size in bytes of the algorithm specified by the descriptor td\"\n    ],\n    \"mcrypt_enc_get_modes_name\": [\n        \"string mcrypt_enc_get_modes_name(resource td)\",\n        \"Returns the name of the mode specified by the descriptor td\"\n    ],\n    \"mcrypt_enc_get_supported_key_sizes\": [\n        \"array mcrypt_enc_get_supported_key_sizes(resource td)\",\n        \"This function decrypts the crypttext\"\n    ],\n    \"mcrypt_enc_is_block_algorithm\": [\n        \"bool mcrypt_enc_is_block_algorithm(resource td)\",\n        \"Returns TRUE if the alrogithm is a block algorithms\"\n    ],\n    \"mcrypt_enc_is_block_algorithm_mode\": [\n        \"bool mcrypt_enc_is_block_algorithm_mode(resource td)\",\n        \"Returns TRUE if the mode is for use with block algorithms\"\n    ],\n    \"mcrypt_enc_is_block_mode\": [\n        \"bool mcrypt_enc_is_block_mode(resource td)\",\n        \"Returns TRUE if the mode outputs blocks\"\n    ],\n    \"mcrypt_enc_self_test\": [\n        \"int mcrypt_enc_self_test(resource td)\",\n        \"This function runs the self test on the algorithm specified by the descriptor td\"\n    ],\n    \"mcrypt_encrypt\": [\n        \"string mcrypt_encrypt(string cipher, string key, string data, string mode, string iv)\",\n        \"OFB crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"mcrypt_generic\": [\n        \"string mcrypt_generic(resource td, string data)\",\n        \"This function encrypts the plaintext\"\n    ],\n    \"mcrypt_generic_deinit\": [\n        \"bool mcrypt_generic_deinit(resource td)\",\n        \"This function terminates encrypt specified by the descriptor td\"\n    ],\n    \"mcrypt_generic_init\": [\n        \"int mcrypt_generic_init(resource td, string key, string iv)\",\n        \"This function initializes all buffers for the specific module\"\n    ],\n    \"mcrypt_get_block_size\": [\n        \"int mcrypt_get_block_size(string cipher, string module)\",\n        \"Get the key size of cipher\"\n    ],\n    \"mcrypt_get_cipher_name\": [\n        \"string mcrypt_get_cipher_name(string cipher)\",\n        \"Get the key size of cipher\"\n    ],\n    \"mcrypt_get_iv_size\": [\n        \"int mcrypt_get_iv_size(string cipher, string module)\",\n        \"Get the IV size of cipher (Usually the same as the blocksize)\"\n    ],\n    \"mcrypt_get_key_size\": [\n        \"int mcrypt_get_key_size(string cipher, string module)\",\n        \"Get the key size of cipher\"\n    ],\n    \"mcrypt_list_algorithms\": [\n        \"array mcrypt_list_algorithms([string lib_dir])\",\n        \"List all algorithms in \\\"module_dir\\\"\"\n    ],\n    \"mcrypt_list_modes\": [\n        \"array mcrypt_list_modes([string lib_dir])\",\n        \"List all modes \\\"module_dir\\\"\"\n    ],\n    \"mcrypt_module_close\": [\n        \"bool mcrypt_module_close(resource td)\",\n        \"Free the descriptor td\"\n    ],\n    \"mcrypt_module_get_algo_block_size\": [\n        \"int mcrypt_module_get_algo_block_size(string algorithm [, string lib_dir])\",\n        \"Returns the block size of the algorithm\"\n    ],\n    \"mcrypt_module_get_algo_key_size\": [\n        \"int mcrypt_module_get_algo_key_size(string algorithm [, string lib_dir])\",\n        \"Returns the maximum supported key size of the algorithm\"\n    ],\n    \"mcrypt_module_get_supported_key_sizes\": [\n        \"array mcrypt_module_get_supported_key_sizes(string algorithm [, string lib_dir])\",\n        \"This function decrypts the crypttext\"\n    ],\n    \"mcrypt_module_is_block_algorithm\": [\n        \"bool mcrypt_module_is_block_algorithm(string algorithm [, string lib_dir])\",\n        \"Returns TRUE if the algorithm is a block algorithm\"\n    ],\n    \"mcrypt_module_is_block_algorithm_mode\": [\n        \"bool mcrypt_module_is_block_algorithm_mode(string mode [, string lib_dir])\",\n        \"Returns TRUE if the mode is for use with block algorithms\"\n    ],\n    \"mcrypt_module_is_block_mode\": [\n        \"bool mcrypt_module_is_block_mode(string mode [, string lib_dir])\",\n        \"Returns TRUE if the mode outputs blocks of bytes\"\n    ],\n    \"mcrypt_module_open\": [\n        \"resource mcrypt_module_open(string cipher, string cipher_directory, string mode, string mode_directory)\",\n        \"Opens the module of the algorithm and the mode to be used\"\n    ],\n    \"mcrypt_module_self_test\": [\n        \"bool mcrypt_module_self_test(string algorithm [, string lib_dir])\",\n        \"Does a self test of the module \\\"module\\\"\"\n    ],\n    \"mcrypt_ofb\": [\n        \"string mcrypt_ofb(int cipher, string key, string data, int mode, string iv)\",\n        \"OFB crypt/decrypt data using key key with cipher cipher starting with iv\"\n    ],\n    \"md5\": [\n        \"string md5(string str, [ bool raw_output])\",\n        \"Calculate the md5 hash of a string\"\n    ],\n    \"md5_file\": [\n        \"string md5_file(string filename [, bool raw_output])\",\n        \"Calculate the md5 hash of given filename\"\n    ],\n    \"mdecrypt_generic\": [\n        \"string mdecrypt_generic(resource td, string data)\",\n        \"This function decrypts the plaintext\"\n    ],\n    \"memory_get_peak_usage\": [\n        \"int memory_get_peak_usage([real_usage])\",\n        \"Returns the peak allocated by PHP memory\"\n    ],\n    \"memory_get_usage\": [\n        \"int memory_get_usage([real_usage])\",\n        \"Returns the allocated by PHP memory\"\n    ],\n    \"metaphone\": [\n        \"string metaphone(string text[, int phones])\",\n        \"Break english phrases down into their phonemes\"\n    ],\n    \"method_exists\": [\n        \"bool method_exists(object object, string method)\",\n        \"Checks if the class method exists\"\n    ],\n    \"mhash\": [\n        \"string mhash(int hash, string data [, string key])\",\n        \"Hash data with hash\"\n    ],\n    \"mhash_count\": [\n        \"int mhash_count()\",\n        \"Gets the number of available hashes\"\n    ],\n    \"mhash_get_block_size\": [\n        \"int mhash_get_block_size(int hash)\",\n        \"Gets the block size of hash\"\n    ],\n    \"mhash_get_hash_name\": [\n        \"string mhash_get_hash_name(int hash)\",\n        \"Gets the name of hash\"\n    ],\n    \"mhash_keygen_s2k\": [\n        \"string mhash_keygen_s2k(int hash, string input_password, string salt, int bytes)\",\n        \"Generates a key using hash functions\"\n    ],\n    \"microtime\": [\n        \"mixed microtime([bool get_as_float])\",\n        \"Returns either a string or a float containing the current time in seconds and microseconds\"\n    ],\n    \"mime_content_type\": [\n        \"string mime_content_type(string filename|resource stream)\",\n        \"Return content-type for file\"\n    ],\n    \"min\": [\n        \"mixed min(mixed arg1 [, mixed arg2 [, mixed ...]])\",\n        \"Return the lowest value in an array or a series of arguments\"\n    ],\n    \"mkdir\": [\n        \"bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])\",\n        \"Create a directory\"\n    ],\n    \"mktime\": [\n        \"int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])\",\n        \"Get UNIX timestamp for a date\"\n    ],\n    \"money_format\": [\n        \"string money_format(string format , float value)\",\n        \"Convert monetary value(s) to string\"\n    ],\n    \"move_uploaded_file\": [\n        \"bool move_uploaded_file(string path, string new_path)\",\n        \"Move a file if and only if it was created by an upload\"\n    ],\n    \"msg_get_queue\": [\n        \"resource msg_get_queue(int key [, int perms])\",\n        \"Attach to a message queue\"\n    ],\n    \"msg_queue_exists\": [\n        \"bool msg_queue_exists(int key)\",\n        \"Check whether a message queue exists\"\n    ],\n    \"msg_receive\": [\n        \"mixed msg_receive(resource queue, int desiredmsgtype, int &msgtype, int maxsize, mixed message [, bool unserialize=true [, int flags=0 [, int errorcode]]])\",\n        \"Send a message of type msgtype (must be > 0) to a message queue\"\n    ],\n    \"msg_remove_queue\": [\n        \"bool msg_remove_queue(resource queue)\",\n        \"Destroy the queue\"\n    ],\n    \"msg_send\": [\n        \"bool msg_send(resource queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])\",\n        \"Send a message of type msgtype (must be > 0) to a message queue\"\n    ],\n    \"msg_set_queue\": [\n        \"bool msg_set_queue(resource queue, array data)\",\n        \"Set information for a message queue\"\n    ],\n    \"msg_stat_queue\": [\n        \"array msg_stat_queue(resource queue)\",\n        \"Returns information about a message queue\"\n    ],\n    \"msgfmt_create\": [\n        \"MessageFormatter msgfmt_create( string $locale, string $pattern )\",\n        \"* Create formatter.\"\n    ],\n    \"msgfmt_format\": [\n        \"mixed msgfmt_format( MessageFormatter $nf, array $args )\",\n        \"* Format a message.\"\n    ],\n    \"msgfmt_format_message\": [\n        \"mixed msgfmt_format_message( string $locale, string $pattern, array $args )\",\n        \"* Format a message.\"\n    ],\n    \"msgfmt_get_error_code\": [\n        \"int msgfmt_get_error_code( MessageFormatter $nf )\",\n        \"* Get formatter's last error code.\"\n    ],\n    \"msgfmt_get_error_message\": [\n        \"string msgfmt_get_error_message( MessageFormatter $coll )\",\n        \"* Get text description for formatter's last error code.\"\n    ],\n    \"msgfmt_get_locale\": [\n        \"string msgfmt_get_locale(MessageFormatter $mf)\",\n        \"* Get formatter locale.\"\n    ],\n    \"msgfmt_get_pattern\": [\n        \"string msgfmt_get_pattern( MessageFormatter $mf )\",\n        \"* Get formatter pattern.\"\n    ],\n    \"msgfmt_parse\": [\n        \"array msgfmt_parse( MessageFormatter $nf, string $source )\",\n        \"* Parse a message.\"\n    ],\n    \"msgfmt_set_pattern\": [\n        \"bool msgfmt_set_pattern( MessageFormatter $mf, string $pattern )\",\n        \"* Set formatter pattern.\"\n    ],\n    \"mssql_bind\": [\n        \"bool mssql_bind(resource stmt, string param_name, mixed var, int type [, bool is_output [, bool is_null [, int maxlen]]])\",\n        \"Adds a parameter to a stored procedure or a remote stored procedure\"\n    ],\n    \"mssql_close\": [\n        \"bool mssql_close([resource conn_id])\",\n        \"Closes a connection to a MS-SQL server\"\n    ],\n    \"mssql_connect\": [\n        \"int mssql_connect([string servername [, string username [, string password [, bool new_link]]]])\",\n        \"Establishes a connection to a MS-SQL server\"\n    ],\n    \"mssql_data_seek\": [\n        \"bool mssql_data_seek(resource result_id, int offset)\",\n        \"Moves the internal row pointer of the MS-SQL result associated with the specified result identifier to pointer to the specified row number\"\n    ],\n    \"mssql_execute\": [\n        \"mixed mssql_execute(resource stmt [, bool skip_results = false])\",\n        \"Executes a stored procedure on a MS-SQL server database\"\n    ],\n    \"mssql_fetch_array\": [\n        \"array mssql_fetch_array(resource result_id [, int result_type])\",\n        \"Returns an associative array of the current row in the result set specified by result_id\"\n    ],\n    \"mssql_fetch_assoc\": [\n        \"array mssql_fetch_assoc(resource result_id)\",\n        \"Returns an associative array of the current row in the result set specified by result_id\"\n    ],\n    \"mssql_fetch_batch\": [\n        \"int mssql_fetch_batch(resource result_index)\",\n        \"Returns the next batch of records\"\n    ],\n    \"mssql_fetch_field\": [\n        \"object mssql_fetch_field(resource result_id [, int offset])\",\n        \"Gets information about certain fields in a query result\"\n    ],\n    \"mssql_fetch_object\": [\n        \"object mssql_fetch_object(resource result_id)\",\n        \"Returns a pseudo-object of the current row in the result set specified by result_id\"\n    ],\n    \"mssql_fetch_row\": [\n        \"array mssql_fetch_row(resource result_id)\",\n        \"Returns an array of the current row in the result set specified by result_id\"\n    ],\n    \"mssql_field_length\": [\n        \"int mssql_field_length(resource result_id [, int offset])\",\n        \"Get the length of a MS-SQL field\"\n    ],\n    \"mssql_field_name\": [\n        \"string mssql_field_name(resource result_id [, int offset])\",\n        \"Returns the name of the field given by offset in the result set given by result_id\"\n    ],\n    \"mssql_field_seek\": [\n        \"bool mssql_field_seek(resource result_id, int offset)\",\n        \"Seeks to the specified field offset\"\n    ],\n    \"mssql_field_type\": [\n        \"string mssql_field_type(resource result_id [, int offset])\",\n        \"Returns the type of a field\"\n    ],\n    \"mssql_free_result\": [\n        \"bool mssql_free_result(resource result_index)\",\n        \"Free a MS-SQL result index\"\n    ],\n    \"mssql_free_statement\": [\n        \"bool mssql_free_statement(resource result_index)\",\n        \"Free a MS-SQL statement index\"\n    ],\n    \"mssql_get_last_message\": [\n        \"string mssql_get_last_message()\",\n        \"Gets the last message from the MS-SQL server\"\n    ],\n    \"mssql_guid_string\": [\n        \"string mssql_guid_string(string binary [,bool short_format])\",\n        \"Converts a 16 byte binary GUID to a string\"\n    ],\n    \"mssql_init\": [\n        \"int mssql_init(string sp_name [, resource conn_id])\",\n        \"Initializes a stored procedure or a remote stored procedure\"\n    ],\n    \"mssql_min_error_severity\": [\n        \"void mssql_min_error_severity(int severity)\",\n        \"Sets the lower error severity\"\n    ],\n    \"mssql_min_message_severity\": [\n        \"void mssql_min_message_severity(int severity)\",\n        \"Sets the lower message severity\"\n    ],\n    \"mssql_next_result\": [\n        \"bool mssql_next_result(resource result_id)\",\n        \"Move the internal result pointer to the next result\"\n    ],\n    \"mssql_num_fields\": [\n        \"int mssql_num_fields(resource mssql_result_index)\",\n        \"Returns the number of fields fetched in from the result id specified\"\n    ],\n    \"mssql_num_rows\": [\n        \"int mssql_num_rows(resource mssql_result_index)\",\n        \"Returns the number of rows fetched in from the result id specified\"\n    ],\n    \"mssql_pconnect\": [\n        \"int mssql_pconnect([string servername [, string username [, string password [, bool new_link]]]])\",\n        \"Establishes a persistent connection to a MS-SQL server\"\n    ],\n    \"mssql_query\": [\n        \"resource mssql_query(string query [, resource conn_id [, int batch_size]])\",\n        \"Perform an SQL query on a MS-SQL server database\"\n    ],\n    \"mssql_result\": [\n        \"string mssql_result(resource result_id, int row, mixed field)\",\n        \"Returns the contents of one cell from a MS-SQL result set\"\n    ],\n    \"mssql_rows_affected\": [\n        \"int mssql_rows_affected(resource conn_id)\",\n        \"Returns the number of records affected by the query\"\n    ],\n    \"mssql_select_db\": [\n        \"bool mssql_select_db(string database_name [, resource conn_id])\",\n        \"Select a MS-SQL database\"\n    ],\n    \"mt_getrandmax\": [\n        \"int mt_getrandmax()\",\n        \"Returns the maximum value a random number from Mersenne Twister can have\"\n    ],\n    \"mt_rand\": [\n        \"int mt_rand([int min, int max])\",\n        \"Returns a random number from Mersenne Twister\"\n    ],\n    \"mt_srand\": [\n        \"void mt_srand([int seed])\",\n        \"Seeds Mersenne Twister random number generator\"\n    ],\n    \"mysql_affected_rows\": [\n        \"int mysql_affected_rows([int link_identifier])\",\n        \"Gets number of affected rows in previous MySQL operation\"\n    ],\n    \"mysql_client_encoding\": [\n        \"string mysql_client_encoding([int link_identifier])\",\n        \"Returns the default character set for the current connection\"\n    ],\n    \"mysql_close\": [\n        \"bool mysql_close([int link_identifier])\",\n        \"Close a MySQL connection\"\n    ],\n    \"mysql_connect\": [\n        \"resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])\",\n        \"Opens a connection to a MySQL Server\"\n    ],\n    \"mysql_create_db\": [\n        \"bool mysql_create_db(string database_name [, int link_identifier])\",\n        \"Create a MySQL database\"\n    ],\n    \"mysql_data_seek\": [\n        \"bool mysql_data_seek(resource result, int row_number)\",\n        \"Move internal result pointer\"\n    ],\n    \"mysql_db_query\": [\n        \"resource mysql_db_query(string database_name, string query [, int link_identifier])\",\n        \"Sends an SQL query to MySQL\"\n    ],\n    \"mysql_drop_db\": [\n        \"bool mysql_drop_db(string database_name [, int link_identifier])\",\n        \"Drops (delete) a MySQL database\"\n    ],\n    \"mysql_errno\": [\n        \"int mysql_errno([int link_identifier])\",\n        \"Returns the number of the error message from previous MySQL operation\"\n    ],\n    \"mysql_error\": [\n        \"string mysql_error([int link_identifier])\",\n        \"Returns the text of the error message from previous MySQL operation\"\n    ],\n    \"mysql_escape_string\": [\n        \"string mysql_escape_string(string to_be_escaped)\",\n        \"Escape string for mysql query\"\n    ],\n    \"mysql_fetch_array\": [\n        \"array mysql_fetch_array(resource result [, int result_type])\",\n        \"Fetch a result row as an array (associative, numeric or both)\"\n    ],\n    \"mysql_fetch_assoc\": [\n        \"array mysql_fetch_assoc(resource result)\",\n        \"Fetch a result row as an associative array\"\n    ],\n    \"mysql_fetch_field\": [\n        \"object mysql_fetch_field(resource result [, int field_offset])\",\n        \"Gets column information from a result and return as an object\"\n    ],\n    \"mysql_fetch_lengths\": [\n        \"array mysql_fetch_lengths(resource result)\",\n        \"Gets max data size of each column in a result\"\n    ],\n    \"mysql_fetch_object\": [\n        \"object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])\",\n        \"Fetch a result row as an object\"\n    ],\n    \"mysql_fetch_row\": [\n        \"array mysql_fetch_row(resource result)\",\n        \"Gets a result row as an enumerated array\"\n    ],\n    \"mysql_field_flags\": [\n        \"string mysql_field_flags(resource result, int field_offset)\",\n        \"Gets the flags associated with the specified field in a result\"\n    ],\n    \"mysql_field_len\": [\n        \"int mysql_field_len(resource result, int field_offset)\",\n        \"Returns the length of the specified field\"\n    ],\n    \"mysql_field_name\": [\n        \"string mysql_field_name(resource result, int field_index)\",\n        \"Gets the name of the specified field in a result\"\n    ],\n    \"mysql_field_seek\": [\n        \"bool mysql_field_seek(resource result, int field_offset)\",\n        \"Sets result pointer to a specific field offset\"\n    ],\n    \"mysql_field_table\": [\n        \"string mysql_field_table(resource result, int field_offset)\",\n        \"Gets name of the table the specified field is in\"\n    ],\n    \"mysql_field_type\": [\n        \"string mysql_field_type(resource result, int field_offset)\",\n        \"Gets the type of the specified field in a result\"\n    ],\n    \"mysql_free_result\": [\n        \"bool mysql_free_result(resource result)\",\n        \"Free result memory\"\n    ],\n    \"mysql_get_client_info\": [\n        \"string mysql_get_client_info()\",\n        \"Returns a string that represents the client library version\"\n    ],\n    \"mysql_get_host_info\": [\n        \"string mysql_get_host_info([int link_identifier])\",\n        \"Returns a string describing the type of connection in use, including the server host name\"\n    ],\n    \"mysql_get_proto_info\": [\n        \"int mysql_get_proto_info([int link_identifier])\",\n        \"Returns the protocol version used by current connection\"\n    ],\n    \"mysql_get_server_info\": [\n        \"string mysql_get_server_info([int link_identifier])\",\n        \"Returns a string that represents the server version number\"\n    ],\n    \"mysql_info\": [\n        \"string mysql_info([int link_identifier])\",\n        \"Returns a string containing information about the most recent query\"\n    ],\n    \"mysql_insert_id\": [\n        \"int mysql_insert_id([int link_identifier])\",\n        \"Gets the ID generated from the previous INSERT operation\"\n    ],\n    \"mysql_list_dbs\": [\n        \"resource mysql_list_dbs([int link_identifier])\",\n        \"List databases available on a MySQL server\"\n    ],\n    \"mysql_list_fields\": [\n        \"resource mysql_list_fields(string database_name, string table_name [, int link_identifier])\",\n        \"List MySQL result fields\"\n    ],\n    \"mysql_list_processes\": [\n        \"resource mysql_list_processes([int link_identifier])\",\n        \"Returns a result set describing the current server threads\"\n    ],\n    \"mysql_list_tables\": [\n        \"resource mysql_list_tables(string database_name [, int link_identifier])\",\n        \"List tables in a MySQL database\"\n    ],\n    \"mysql_num_fields\": [\n        \"int mysql_num_fields(resource result)\",\n        \"Gets number of fields in a result\"\n    ],\n    \"mysql_num_rows\": [\n        \"int mysql_num_rows(resource result)\",\n        \"Gets number of rows in a result\"\n    ],\n    \"mysql_pconnect\": [\n        \"resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])\",\n        \"Opens a persistent connection to a MySQL Server\"\n    ],\n    \"mysql_ping\": [\n        \"bool mysql_ping([int link_identifier])\",\n        \"Ping a server connection. If no connection then reconnect.\"\n    ],\n    \"mysql_query\": [\n        \"resource mysql_query(string query [, int link_identifier])\",\n        \"Sends an SQL query to MySQL\"\n    ],\n    \"mysql_real_escape_string\": [\n        \"string mysql_real_escape_string(string to_be_escaped [, int link_identifier])\",\n        \"Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection\"\n    ],\n    \"mysql_result\": [\n        \"mixed mysql_result(resource result, int row [, mixed field])\",\n        \"Gets result data\"\n    ],\n    \"mysql_select_db\": [\n        \"bool mysql_select_db(string database_name [, int link_identifier])\",\n        \"Selects a MySQL database\"\n    ],\n    \"mysql_set_charset\": [\n        \"bool mysql_set_charset(string csname [, int link_identifier])\",\n        \"sets client character set\"\n    ],\n    \"mysql_stat\": [\n        \"string mysql_stat([int link_identifier])\",\n        \"Returns a string containing status information\"\n    ],\n    \"mysql_thread_id\": [\n        \"int mysql_thread_id([int link_identifier])\",\n        \"Returns the thread id of current connection\"\n    ],\n    \"mysql_unbuffered_query\": [\n        \"resource mysql_unbuffered_query(string query [, int link_identifier])\",\n        \"Sends an SQL query to MySQL, without fetching and buffering the result rows\"\n    ],\n    \"mysqli_affected_rows\": [\n        \"mixed mysqli_affected_rows(object link)\",\n        \"Get number of affected rows in previous MySQL operation\"\n    ],\n    \"mysqli_autocommit\": [\n        \"bool mysqli_autocommit(object link, bool mode)\",\n        \"Turn auto commit on or of\"\n    ],\n    \"mysqli_cache_stats\": [\n        \"array mysqli_cache_stats()\",\n        \"Returns statistics about the zval cache\"\n    ],\n    \"mysqli_change_user\": [\n        \"bool mysqli_change_user(object link, string user, string password, string database)\",\n        \"Change logged-in user of the active connection\"\n    ],\n    \"mysqli_character_set_name\": [\n        \"string mysqli_character_set_name(object link)\",\n        \"Returns the name of the character set used for this connection\"\n    ],\n    \"mysqli_close\": [\n        \"bool mysqli_close(object link)\",\n        \"Close connection\"\n    ],\n    \"mysqli_commit\": [\n        \"bool mysqli_commit(object link)\",\n        \"Commit outstanding actions and close transaction\"\n    ],\n    \"mysqli_connect\": [\n        \"object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])\",\n        \"Open a connection to a mysql server\"\n    ],\n    \"mysqli_connect_errno\": [\n        \"int mysqli_connect_errno()\",\n        \"Returns the numerical value of the error message from last connect command\"\n    ],\n    \"mysqli_connect_error\": [\n        \"string mysqli_connect_error()\",\n        \"Returns the text of the error message from previous MySQL operation\"\n    ],\n    \"mysqli_data_seek\": [\n        \"bool mysqli_data_seek(object result, int offset)\",\n        \"Move internal result pointer\"\n    ],\n    \"mysqli_debug\": [\n        \"void mysqli_debug(string debug)\",\n        \"\"\n    ],\n    \"mysqli_dump_debug_info\": [\n        \"bool mysqli_dump_debug_info(object link)\",\n        \"\"\n    ],\n    \"mysqli_embedded_server_end\": [\n        \"void mysqli_embedded_server_end()\",\n        \"\"\n    ],\n    \"mysqli_embedded_server_start\": [\n        \"bool mysqli_embedded_server_start(bool start, array arguments, array groups)\",\n        \"initialize and start embedded server\"\n    ],\n    \"mysqli_errno\": [\n        \"int mysqli_errno(object link)\",\n        \"Returns the numerical value of the error message from previous MySQL operation\"\n    ],\n    \"mysqli_error\": [\n        \"string mysqli_error(object link)\",\n        \"Returns the text of the error message from previous MySQL operation\"\n    ],\n    \"mysqli_fetch_all\": [\n        \"mixed mysqli_fetch_all(object result [,int resulttype])\",\n        \"Fetches all result rows as an associative array, a numeric array, or both\"\n    ],\n    \"mysqli_fetch_array\": [\n        \"mixed mysqli_fetch_array(object result [,int resulttype])\",\n        \"Fetch a result row as an associative array, a numeric array, or both\"\n    ],\n    \"mysqli_fetch_assoc\": [\n        \"mixed mysqli_fetch_assoc(object result)\",\n        \"Fetch a result row as an associative array\"\n    ],\n    \"mysqli_fetch_field\": [\n        \"mixed mysqli_fetch_field(object result)\",\n        \"Get column information from a result and return as an object\"\n    ],\n    \"mysqli_fetch_field_direct\": [\n        \"mixed mysqli_fetch_field_direct(object result, int offset)\",\n        \"Fetch meta-data for a single field\"\n    ],\n    \"mysqli_fetch_fields\": [\n        \"mixed mysqli_fetch_fields(object result)\",\n        \"Return array of objects containing field meta-data\"\n    ],\n    \"mysqli_fetch_lengths\": [\n        \"mixed mysqli_fetch_lengths(object result)\",\n        \"Get the length of each output in a result\"\n    ],\n    \"mysqli_fetch_object\": [\n        \"mixed mysqli_fetch_object(object result [, string class_name [, NULL|array ctor_params]])\",\n        \"Fetch a result row as an object\"\n    ],\n    \"mysqli_fetch_row\": [\n        \"array mysqli_fetch_row(object result)\",\n        \"Get a result row as an enumerated array\"\n    ],\n    \"mysqli_field_count\": [\n        \"int mysqli_field_count(object link)\",\n        \"Fetch the number of fields returned by the last query for the given link\"\n    ],\n    \"mysqli_field_seek\": [\n        \"int mysqli_field_seek(object result, int fieldnr)\",\n        \"Set result pointer to a specified field offset\"\n    ],\n    \"mysqli_field_tell\": [\n        \"int mysqli_field_tell(object result)\",\n        \"Get current field offset of result pointer\"\n    ],\n    \"mysqli_free_result\": [\n        \"void mysqli_free_result(object result)\",\n        \"Free query result memory for the given result handle\"\n    ],\n    \"mysqli_get_charset\": [\n        \"object mysqli_get_charset(object link)\",\n        \"returns a character set object\"\n    ],\n    \"mysqli_get_client_info\": [\n        \"string mysqli_get_client_info()\",\n        \"Get MySQL client info\"\n    ],\n    \"mysqli_get_client_stats\": [\n        \"array mysqli_get_client_stats()\",\n        \"Returns statistics about the zval cache\"\n    ],\n    \"mysqli_get_client_version\": [\n        \"int mysqli_get_client_version()\",\n        \"Get MySQL client info\"\n    ],\n    \"mysqli_get_connection_stats\": [\n        \"array mysqli_get_connection_stats()\",\n        \"Returns statistics about the zval cache\"\n    ],\n    \"mysqli_get_host_info\": [\n        \"string mysqli_get_host_info(object link)\",\n        \"Get MySQL host info\"\n    ],\n    \"mysqli_get_proto_info\": [\n        \"int mysqli_get_proto_info(object link)\",\n        \"Get MySQL protocol information\"\n    ],\n    \"mysqli_get_server_info\": [\n        \"string mysqli_get_server_info(object link)\",\n        \"Get MySQL server info\"\n    ],\n    \"mysqli_get_server_version\": [\n        \"int mysqli_get_server_version(object link)\",\n        \"Return the MySQL version for the server referenced by the given link\"\n    ],\n    \"mysqli_get_warnings\": [\n        \"object mysqli_get_warnings(object link)\",\n        \"\"\n    ],\n    \"mysqli_info\": [\n        \"string mysqli_info(object link)\",\n        \"Get information about the most recent query\"\n    ],\n    \"mysqli_init\": [\n        \"resource mysqli_init()\",\n        \"Initialize mysqli and return a resource for use with mysql_real_connect\"\n    ],\n    \"mysqli_insert_id\": [\n        \"mixed mysqli_insert_id(object link)\",\n        \"Get the ID generated from the previous INSERT operation\"\n    ],\n    \"mysqli_kill\": [\n        \"bool mysqli_kill(object link, int processid)\",\n        \"Kill a mysql process on the server\"\n    ],\n    \"mysqli_link_construct\": [\n        \"object mysqli_link_construct()\",\n        \"\"\n    ],\n    \"mysqli_more_results\": [\n        \"bool mysqli_more_results(object link)\",\n        \"check if there any more query results from a multi query\"\n    ],\n    \"mysqli_multi_query\": [\n        \"bool mysqli_multi_query(object link, string query)\",\n        \"allows to execute multiple queries\"\n    ],\n    \"mysqli_next_result\": [\n        \"bool mysqli_next_result(object link)\",\n        \"read next result from multi_query\"\n    ],\n    \"mysqli_num_fields\": [\n        \"int mysqli_num_fields(object result)\",\n        \"Get number of fields in result\"\n    ],\n    \"mysqli_num_rows\": [\n        \"mixed mysqli_num_rows(object result)\",\n        \"Get number of rows in result\"\n    ],\n    \"mysqli_options\": [\n        \"bool mysqli_options(object link, int flags, mixed values)\",\n        \"Set options\"\n    ],\n    \"mysqli_ping\": [\n        \"bool mysqli_ping(object link)\",\n        \"Ping a server connection or reconnect if there is no connection\"\n    ],\n    \"mysqli_poll\": [\n        \"int mysqli_poll(array read, array write, array error, long sec [, long usec])\",\n        \"Poll connections\"\n    ],\n    \"mysqli_prepare\": [\n        \"mixed mysqli_prepare(object link, string query)\",\n        \"Prepare a SQL statement for execution\"\n    ],\n    \"mysqli_query\": [\n        \"mixed mysqli_query(object link, string query [,int resultmode])\",\n        \"\"\n    ],\n    \"mysqli_real_connect\": [\n        \"bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])\",\n        \"Open a connection to a mysql server\"\n    ],\n    \"mysqli_real_escape_string\": [\n        \"string mysqli_real_escape_string(object link, string escapestr)\",\n        \"Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection\"\n    ],\n    \"mysqli_real_query\": [\n        \"bool mysqli_real_query(object link, string query)\",\n        \"Binary-safe version of mysql_query()\"\n    ],\n    \"mysqli_reap_async_query\": [\n        \"int mysqli_reap_async_query(object link)\",\n        \"Poll connections\"\n    ],\n    \"mysqli_refresh\": [\n        \"bool mysqli_refresh(object link, long options)\",\n        \"Flush tables or caches, or reset replication server information\"\n    ],\n    \"mysqli_report\": [\n        \"bool mysqli_report(int flags)\",\n        \"sets report level\"\n    ],\n    \"mysqli_rollback\": [\n        \"bool mysqli_rollback(object link)\",\n        \"Undo actions from current transaction\"\n    ],\n    \"mysqli_select_db\": [\n        \"bool mysqli_select_db(object link, string dbname)\",\n        \"Select a MySQL database\"\n    ],\n    \"mysqli_set_charset\": [\n        \"bool mysqli_set_charset(object link, string csname)\",\n        \"sets client character set\"\n    ],\n    \"mysqli_set_local_infile_default\": [\n        \"void mysqli_set_local_infile_default(object link)\",\n        \"unsets user defined handler for load local infile command\"\n    ],\n    \"mysqli_set_local_infile_handler\": [\n        \"bool mysqli_set_local_infile_handler(object link, callback read_func)\",\n        \"Set callback functions for LOAD DATA LOCAL INFILE\"\n    ],\n    \"mysqli_sqlstate\": [\n        \"string mysqli_sqlstate(object link)\",\n        \"Returns the SQLSTATE error from previous MySQL operation\"\n    ],\n    \"mysqli_ssl_set\": [\n        \"bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher])\",\n        \"\"\n    ],\n    \"mysqli_stat\": [\n        \"mixed mysqli_stat(object link)\",\n        \"Get current system status\"\n    ],\n    \"mysqli_stmt_affected_rows\": [\n        \"mixed mysqli_stmt_affected_rows(object stmt)\",\n        \"Return the number of rows affected in the last query for the given link\"\n    ],\n    \"mysqli_stmt_attr_get\": [\n        \"int mysqli_stmt_attr_get(object stmt, long attr)\",\n        \"\"\n    ],\n    \"mysqli_stmt_attr_set\": [\n        \"int mysqli_stmt_attr_set(object stmt, long attr, long mode)\",\n        \"\"\n    ],\n    \"mysqli_stmt_bind_param\": [\n        \"bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....])\",\n        \"Bind variables to a prepared statement as parameters\"\n    ],\n    \"mysqli_stmt_bind_result\": [\n        \"bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...])\",\n        \"Bind variables to a prepared statement for result storage\"\n    ],\n    \"mysqli_stmt_close\": [\n        \"bool mysqli_stmt_close(object stmt)\",\n        \"Close statement\"\n    ],\n    \"mysqli_stmt_data_seek\": [\n        \"void mysqli_stmt_data_seek(object stmt, int offset)\",\n        \"Move internal result pointer\"\n    ],\n    \"mysqli_stmt_errno\": [\n        \"int mysqli_stmt_errno(object stmt)\",\n        \"\"\n    ],\n    \"mysqli_stmt_error\": [\n        \"string mysqli_stmt_error(object stmt)\",\n        \"\"\n    ],\n    \"mysqli_stmt_execute\": [\n        \"bool mysqli_stmt_execute(object stmt)\",\n        \"Execute a prepared statement\"\n    ],\n    \"mysqli_stmt_fetch\": [\n        \"mixed mysqli_stmt_fetch(object stmt)\",\n        \"Fetch results from a prepared statement into the bound variables\"\n    ],\n    \"mysqli_stmt_field_count\": [\n        \"int mysqli_stmt_field_count(object stmt) {\",\n        \"Return the number of result columns for the given statement\"\n    ],\n    \"mysqli_stmt_free_result\": [\n        \"void mysqli_stmt_free_result(object stmt)\",\n        \"Free stored result memory for the given statement handle\"\n    ],\n    \"mysqli_stmt_get_result\": [\n        \"object mysqli_stmt_get_result(object link)\",\n        \"Buffer result set on client\"\n    ],\n    \"mysqli_stmt_get_warnings\": [\n        \"object mysqli_stmt_get_warnings(object link)\",\n        \"\"\n    ],\n    \"mysqli_stmt_init\": [\n        \"mixed mysqli_stmt_init(object link)\",\n        \"Initialize statement object\"\n    ],\n    \"mysqli_stmt_insert_id\": [\n        \"mixed mysqli_stmt_insert_id(object stmt)\",\n        \"Get the ID generated from the previous INSERT operation\"\n    ],\n    \"mysqli_stmt_next_result\": [\n        \"bool mysqli_stmt_next_result(object link)\",\n        \"read next result from multi_query\"\n    ],\n    \"mysqli_stmt_num_rows\": [\n        \"mixed mysqli_stmt_num_rows(object stmt)\",\n        \"Return the number of rows in statements result set\"\n    ],\n    \"mysqli_stmt_param_count\": [\n        \"int mysqli_stmt_param_count(object stmt)\",\n        \"Return the number of parameter for the given statement\"\n    ],\n    \"mysqli_stmt_prepare\": [\n        \"bool mysqli_stmt_prepare(object stmt, string query)\",\n        \"prepare server side statement with query\"\n    ],\n    \"mysqli_stmt_reset\": [\n        \"bool mysqli_stmt_reset(object stmt)\",\n        \"reset a prepared statement\"\n    ],\n    \"mysqli_stmt_result_metadata\": [\n        \"mixed mysqli_stmt_result_metadata(object stmt)\",\n        \"return result set from statement\"\n    ],\n    \"mysqli_stmt_send_long_data\": [\n        \"bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)\",\n        \"\"\n    ],\n    \"mysqli_stmt_sqlstate\": [\n        \"string mysqli_stmt_sqlstate(object stmt)\",\n        \"\"\n    ],\n    \"mysqli_stmt_store_result\": [\n        \"bool mysqli_stmt_store_result(stmt)\",\n        \"\"\n    ],\n    \"mysqli_store_result\": [\n        \"object mysqli_store_result(object link)\",\n        \"Buffer result set on client\"\n    ],\n    \"mysqli_thread_id\": [\n        \"int mysqli_thread_id(object link)\",\n        \"Return the current thread ID\"\n    ],\n    \"mysqli_thread_safe\": [\n        \"bool mysqli_thread_safe()\",\n        \"Return whether thread safety is given or not\"\n    ],\n    \"mysqli_use_result\": [\n        \"mixed mysqli_use_result(object link)\",\n        \"Directly retrieve query results - do not buffer results on client side\"\n    ],\n    \"mysqli_warning_count\": [\n        \"int mysqli_warning_count(object link)\",\n        \"Return number of warnings from the last query for the given link\"\n    ],\n    \"natcasesort\": [\n        \"void natcasesort(array &array_arg)\",\n        \"Sort an array using case-insensitive natural sort\"\n    ],\n    \"natsort\": [\n        \"void natsort(array &array_arg)\",\n        \"Sort an array using natural sort\"\n    ],\n    \"next\": [\n        \"mixed next(array array_arg)\",\n        \"Move array argument's internal pointer to the next element and return it\"\n    ],\n    \"ngettext\": [\n        \"string ngettext(string MSGID1, string MSGID2, int N)\",\n        \"Plural version of gettext()\"\n    ],\n    \"nl2br\": [\n        \"string nl2br(string str [, bool is_xhtml])\",\n        \"Converts newlines to HTML line breaks\"\n    ],\n    \"nl_langinfo\": [\n        \"string nl_langinfo(int item)\",\n        \"Query language and locale information\"\n    ],\n    \"normalizer_is_normalize\": [\n        \"bool normalizer_is_normalize( string $input [, string $form = FORM_C] )\",\n        \"* Test if a string is in a given normalization form.\"\n    ],\n    \"normalizer_normalize\": [\n        \"string normalizer_normalize( string $input [, string $form = FORM_C] )\",\n        \"* Normalize a string.\"\n    ],\n    \"nsapi_request_headers\": [\n        \"array nsapi_request_headers()\",\n        \"Get all headers from the request\"\n    ],\n    \"nsapi_response_headers\": [\n        \"array nsapi_response_headers()\",\n        \"Get all headers from the response\"\n    ],\n    \"nsapi_virtual\": [\n        \"bool nsapi_virtual(string uri)\",\n        \"Perform an NSAPI sub-request\"\n    ],\n    \"number_format\": [\n        \"string number_format(float number [, int num_decimal_places [, string dec_seperator, string thousands_seperator]])\",\n        \"Formats a number with grouped thousands\"\n    ],\n    \"numfmt_create\": [\n        \"NumberFormatter numfmt_create( string $locale, int style[, string $pattern ] )\",\n        \"* Create number formatter.\"\n    ],\n    \"numfmt_format\": [\n        \"mixed numfmt_format( NumberFormatter $nf, mixed $num[, int type] )\",\n        \"* Format a number.\"\n    ],\n    \"numfmt_format_currency\": [\n        \"mixed numfmt_format_currency( NumberFormatter $nf, double $num, string $currency )\",\n        \"* Format a number as currency.\"\n    ],\n    \"numfmt_get_attribute\": [\n        \"mixed numfmt_get_attribute( NumberFormatter $nf, int $attr )\",\n        \"* Get formatter attribute value.\"\n    ],\n    \"numfmt_get_error_code\": [\n        \"int numfmt_get_error_code( NumberFormatter $nf )\",\n        \"* Get formatter's last error code.\"\n    ],\n    \"numfmt_get_error_message\": [\n        \"string numfmt_get_error_message( NumberFormatter $nf )\",\n        \"* Get text description for formatter's last error code.\"\n    ],\n    \"numfmt_get_locale\": [\n        \"string numfmt_get_locale( NumberFormatter $nf[, int type] )\",\n        \"* Get formatter locale.\"\n    ],\n    \"numfmt_get_pattern\": [\n        \"string numfmt_get_pattern( NumberFormatter $nf )\",\n        \"* Get formatter pattern.\"\n    ],\n    \"numfmt_get_symbol\": [\n        \"string numfmt_get_symbol( NumberFormatter $nf, int $attr )\",\n        \"* Get formatter symbol value.\"\n    ],\n    \"numfmt_get_text_attribute\": [\n        \"string numfmt_get_text_attribute( NumberFormatter $nf, int $attr )\",\n        \"* Get formatter attribute value.\"\n    ],\n    \"numfmt_parse\": [\n        \"mixed numfmt_parse( NumberFormatter $nf, string $str[, int $type, int &$position ])\",\n        \"* Parse a number.\"\n    ],\n    \"numfmt_parse_currency\": [\n        \"double numfmt_parse_currency( NumberFormatter $nf, string $str, string $&currency[, int $&position] )\",\n        \"* Parse a number as currency.\"\n    ],\n    \"numfmt_parse_message\": [\n        \"array numfmt_parse_message( string $locale, string $pattern, string $source )\",\n        \"* Parse a message.\"\n    ],\n    \"numfmt_set_attribute\": [\n        \"bool numfmt_set_attribute( NumberFormatter $nf, int $attr, mixed $value )\",\n        \"* Get formatter attribute value.\"\n    ],\n    \"numfmt_set_pattern\": [\n        \"bool numfmt_set_pattern( NumberFormatter $nf, string $pattern )\",\n        \"* Set formatter pattern.\"\n    ],\n    \"numfmt_set_symbol\": [\n        \"bool numfmt_set_symbol( NumberFormatter $nf, int $attr, string $symbol )\",\n        \"* Set formatter symbol value.\"\n    ],\n    \"numfmt_set_text_attribute\": [\n        \"bool numfmt_set_text_attribute( NumberFormatter $nf, int $attr, string $value )\",\n        \"* Get formatter attribute value.\"\n    ],\n    \"ob_clean\": [\n        \"bool ob_clean()\",\n        \"Clean (delete) the current output buffer\"\n    ],\n    \"ob_end_clean\": [\n        \"bool ob_end_clean()\",\n        \"Clean the output buffer, and delete current output buffer\"\n    ],\n    \"ob_end_flush\": [\n        \"bool ob_end_flush()\",\n        \"Flush (send) the output buffer, and delete current output buffer\"\n    ],\n    \"ob_flush\": [\n        \"bool ob_flush()\",\n        \"Flush (send) contents of the output buffer. The last buffer content is sent to next buffer\"\n    ],\n    \"ob_get_clean\": [\n        \"bool ob_get_clean()\",\n        \"Get current buffer contents and delete current output buffer\"\n    ],\n    \"ob_get_contents\": [\n        \"string ob_get_contents()\",\n        \"Return the contents of the output buffer\"\n    ],\n    \"ob_get_flush\": [\n        \"bool ob_get_flush()\",\n        \"Get current buffer contents, flush (send) the output buffer, and delete current output buffer\"\n    ],\n    \"ob_get_length\": [\n        \"int ob_get_length()\",\n        \"Return the length of the output buffer\"\n    ],\n    \"ob_get_level\": [\n        \"int ob_get_level()\",\n        \"Return the nesting level of the output buffer\"\n    ],\n    \"ob_get_status\": [\n        \"false|array ob_get_status([bool full_status])\",\n        \"Return the status of the active or all output buffers\"\n    ],\n    \"ob_gzhandler\": [\n        \"string ob_gzhandler(string str, int mode)\",\n        \"Encode str based on accept-encoding setting - designed to be called from ob_start()\"\n    ],\n    \"ob_iconv_handler\": [\n        \"string ob_iconv_handler(string contents, int status)\",\n        \"Returns str in output buffer converted to the iconv.output_encoding character set\"\n    ],\n    \"ob_implicit_flush\": [\n        \"void ob_implicit_flush([int flag])\",\n        \"Turn implicit flush on/off and is equivalent to calling flush() after every output call\"\n    ],\n    \"ob_list_handlers\": [\n        \"false|array ob_list_handlers()\",\n        \"*  List all output_buffers in an array\"\n    ],\n    \"ob_start\": [\n        \"bool ob_start([ string|array user_function [, int chunk_size [, bool erase]]])\",\n        \"Turn on Output Buffering (specifying an optional output handler).\"\n    ],\n    \"oci_bind_array_by_name\": [\n        \"bool oci_bind_array_by_name(resource stmt, string name, array &var, int max_table_length [, int max_item_length [, int type ]])\",\n        \"Bind a PHP array to an Oracle PL/SQL type by name\"\n    ],\n    \"oci_bind_by_name\": [\n        \"bool oci_bind_by_name(resource stmt, string name, mixed &var, [, int maxlength [, int type]])\",\n        \"Bind a PHP variable to an Oracle placeholder by name\"\n    ],\n    \"oci_cancel\": [\n        \"bool oci_cancel(resource stmt)\",\n        \"Cancel reading from a cursor\"\n    ],\n    \"oci_close\": [\n        \"bool oci_close(resource connection)\",\n        \"Disconnect from database\"\n    ],\n    \"oci_collection_append\": [\n        \"bool oci_collection_append(string value)\",\n        \"Append an object to the collection\"\n    ],\n    \"oci_collection_assign\": [\n        \"bool oci_collection_assign(object from)\",\n        \"Assign a collection from another existing collection\"\n    ],\n    \"oci_collection_element_assign\": [\n        \"bool oci_collection_element_assign(int index, string val)\",\n        \"Assign element val to collection at index ndx\"\n    ],\n    \"oci_collection_element_get\": [\n        \"string oci_collection_element_get(int ndx)\",\n        \"Retrieve the value at collection index ndx\"\n    ],\n    \"oci_collection_max\": [\n        \"int oci_collection_max()\",\n        \"Return the max value of a collection. For a varray this is the maximum length of the array\"\n    ],\n    \"oci_collection_size\": [\n        \"int oci_collection_size()\",\n        \"Return the size of a collection\"\n    ],\n    \"oci_collection_trim\": [\n        \"bool oci_collection_trim(int num)\",\n        \"Trim num elements from the end of a collection\"\n    ],\n    \"oci_commit\": [\n        \"bool oci_commit(resource connection)\",\n        \"Commit the current context\"\n    ],\n    \"oci_connect\": [\n        \"resource oci_connect(string user, string pass [, string db [, string charset [, int session_mode ]])\",\n        \"Connect to an Oracle database and log on. Returns a new session.\"\n    ],\n    \"oci_define_by_name\": [\n        \"bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])\",\n        \"Define a PHP variable to an Oracle column by name\"\n    ],\n    \"oci_error\": [\n        \"array oci_error([resource stmt|connection|global])\",\n        \"Return the last error of stmt|connection|global. If no error happened returns false.\"\n    ],\n    \"oci_execute\": [\n        \"bool oci_execute(resource stmt [, int mode])\",\n        \"Execute a parsed statement\"\n    ],\n    \"oci_fetch\": [\n        \"bool oci_fetch(resource stmt)\",\n        \"Prepare a new row of data for reading\"\n    ],\n    \"oci_fetch_all\": [\n        \"int oci_fetch_all(resource stmt, array &output[, int skip[, int maxrows[, int flags]]])\",\n        \"Fetch all rows of result data into an array\"\n    ],\n    \"oci_fetch_array\": [\n        \"array oci_fetch_array( resource stmt [, int mode ])\",\n        \"Fetch a result row as an array\"\n    ],\n    \"oci_fetch_assoc\": [\n        \"array oci_fetch_assoc( resource stmt )\",\n        \"Fetch a result row as an associative array\"\n    ],\n    \"oci_fetch_object\": [\n        \"object oci_fetch_object( resource stmt )\",\n        \"Fetch a result row as an object\"\n    ],\n    \"oci_fetch_row\": [\n        \"array oci_fetch_row( resource stmt )\",\n        \"Fetch a result row as an enumerated array\"\n    ],\n    \"oci_field_is_null\": [\n        \"bool oci_field_is_null(resource stmt, int col)\",\n        \"Tell whether a column is NULL\"\n    ],\n    \"oci_field_name\": [\n        \"string oci_field_name(resource stmt, int col)\",\n        \"Tell the name of a column\"\n    ],\n    \"oci_field_precision\": [\n        \"int oci_field_precision(resource stmt, int col)\",\n        \"Tell the precision of a column\"\n    ],\n    \"oci_field_scale\": [\n        \"int oci_field_scale(resource stmt, int col)\",\n        \"Tell the scale of a column\"\n    ],\n    \"oci_field_size\": [\n        \"int oci_field_size(resource stmt, int col)\",\n        \"Tell the maximum data size of a column\"\n    ],\n    \"oci_field_type\": [\n        \"mixed oci_field_type(resource stmt, int col)\",\n        \"Tell the data type of a column\"\n    ],\n    \"oci_field_type_raw\": [\n        \"int oci_field_type_raw(resource stmt, int col)\",\n        \"Tell the raw oracle data type of a column\"\n    ],\n    \"oci_free_collection\": [\n        \"bool oci_free_collection()\",\n        \"Deletes collection object\"\n    ],\n    \"oci_free_descriptor\": [\n        \"bool oci_free_descriptor()\",\n        \"Deletes large object description\"\n    ],\n    \"oci_free_statement\": [\n        \"bool oci_free_statement(resource stmt)\",\n        \"Free all resources associated with a statement\"\n    ],\n    \"oci_internal_debug\": [\n        \"void oci_internal_debug(int onoff)\",\n        \"Toggle internal debugging output for the OCI extension\"\n    ],\n    \"oci_lob_append\": [\n        \"bool oci_lob_append( object lob )\",\n        \"Appends data from a LOB to another LOB\"\n    ],\n    \"oci_lob_close\": [\n        \"bool oci_lob_close()\",\n        \"Closes lob descriptor\"\n    ],\n    \"oci_lob_copy\": [\n        \"bool oci_lob_copy( object lob_to, object lob_from [, int length ] )\",\n        \"Copies data from a LOB to another LOB\"\n    ],\n    \"oci_lob_eof\": [\n        \"bool oci_lob_eof()\",\n        \"Checks if EOF is reached\"\n    ],\n    \"oci_lob_erase\": [\n        \"int oci_lob_erase( [ int offset [, int length ] ] )\",\n        \"Erases a specified portion of the internal LOB, starting at a specified offset\"\n    ],\n    \"oci_lob_export\": [\n        \"bool oci_lob_export([string filename [, int start [, int length]]])\",\n        \"Writes a large object into a file\"\n    ],\n    \"oci_lob_flush\": [\n        \"bool oci_lob_flush( [ int flag ] )\",\n        \"Flushes the LOB buffer\"\n    ],\n    \"oci_lob_import\": [\n        \"bool oci_lob_import( string filename )\",\n        \"Loads file into a LOB\"\n    ],\n    \"oci_lob_is_equal\": [\n        \"bool oci_lob_is_equal( object lob1, object lob2 )\",\n        \"Tests to see if two LOB/FILE locators are equal\"\n    ],\n    \"oci_lob_load\": [\n        \"string oci_lob_load()\",\n        \"Loads a large object\"\n    ],\n    \"oci_lob_read\": [\n        \"string oci_lob_read( int length )\",\n        \"Reads particular part of a large object\"\n    ],\n    \"oci_lob_rewind\": [\n        \"bool oci_lob_rewind()\",\n        \"Rewind pointer of a LOB\"\n    ],\n    \"oci_lob_save\": [\n        \"bool oci_lob_save( string data [, int offset ])\",\n        \"Saves a large object\"\n    ],\n    \"oci_lob_seek\": [\n        \"bool oci_lob_seek( int offset [, int whence ])\",\n        \"Moves the pointer of a LOB\"\n    ],\n    \"oci_lob_size\": [\n        \"int oci_lob_size()\",\n        \"Returns size of a large object\"\n    ],\n    \"oci_lob_tell\": [\n        \"int oci_lob_tell()\",\n        \"Tells LOB pointer position\"\n    ],\n    \"oci_lob_truncate\": [\n        \"bool oci_lob_truncate( [ int length ])\",\n        \"Truncates a LOB\"\n    ],\n    \"oci_lob_write\": [\n        \"int oci_lob_write( string string [, int length ])\",\n        \"Writes data to current position of a LOB\"\n    ],\n    \"oci_lob_write_temporary\": [\n        \"bool oci_lob_write_temporary(string var [, int lob_type])\",\n        \"Writes temporary blob\"\n    ],\n    \"oci_new_collection\": [\n        \"object oci_new_collection(resource connection, string tdo [, string schema])\",\n        \"Initialize a new collection\"\n    ],\n    \"oci_new_connect\": [\n        \"resource oci_new_connect(string user, string pass [, string db])\",\n        \"Connect to an Oracle database and log on. Returns a new session.\"\n    ],\n    \"oci_new_cursor\": [\n        \"resource oci_new_cursor(resource connection)\",\n        \"Return a new cursor (Statement-Handle) - use this to bind ref-cursors!\"\n    ],\n    \"oci_new_descriptor\": [\n        \"object oci_new_descriptor(resource connection [, int type])\",\n        \"Initialize a new empty descriptor LOB/FILE (LOB is default)\"\n    ],\n    \"oci_num_fields\": [\n        \"int oci_num_fields(resource stmt)\",\n        \"Return the number of result columns in a statement\"\n    ],\n    \"oci_num_rows\": [\n        \"int oci_num_rows(resource stmt)\",\n        \"Return the row count of an OCI statement\"\n    ],\n    \"oci_parse\": [\n        \"resource oci_parse(resource connection, string query)\",\n        \"Parse a query and return a statement\"\n    ],\n    \"oci_password_change\": [\n        \"bool oci_password_change(resource connection, string username, string old_password, string new_password)\",\n        \"Changes the password of an account\"\n    ],\n    \"oci_pconnect\": [\n        \"resource oci_pconnect(string user, string pass [, string db [, string charset ]])\",\n        \"Connect to an Oracle database using a persistent connection and log on. Returns a new session.\"\n    ],\n    \"oci_result\": [\n        \"string oci_result(resource stmt, mixed column)\",\n        \"Return a single column of result data\"\n    ],\n    \"oci_rollback\": [\n        \"bool oci_rollback(resource connection)\",\n        \"Rollback the current context\"\n    ],\n    \"oci_server_version\": [\n        \"string oci_server_version(resource connection)\",\n        \"Return a string containing server version information\"\n    ],\n    \"oci_set_action\": [\n        \"bool oci_set_action(resource connection, string value)\",\n        \"Sets the action attribute on the connection\"\n    ],\n    \"oci_set_client_identifier\": [\n        \"bool oci_set_client_identifier(resource connection, string value)\",\n        \"Sets the client identifier attribute on the connection\"\n    ],\n    \"oci_set_client_info\": [\n        \"bool oci_set_client_info(resource connection, string value)\",\n        \"Sets the client info attribute on the connection\"\n    ],\n    \"oci_set_edition\": [\n        \"bool oci_set_edition(string value)\",\n        \"Sets the edition attribute for all subsequent connections created\"\n    ],\n    \"oci_set_module_name\": [\n        \"bool oci_set_module_name(resource connection, string value)\",\n        \"Sets the module attribute on the connection\"\n    ],\n    \"oci_set_prefetch\": [\n        \"bool oci_set_prefetch(resource stmt, int prefetch_rows)\",\n        \"Sets the number of rows to be prefetched on execute to prefetch_rows for stmt\"\n    ],\n    \"oci_statement_type\": [\n        \"string oci_statement_type(resource stmt)\",\n        \"Return the query type of an OCI statement\"\n    ],\n    \"ocifetchinto\": [\n        \"int ocifetchinto(resource stmt, array &output [, int mode])\",\n        \"Fetch a row of result data into an array\"\n    ],\n    \"ocigetbufferinglob\": [\n        \"bool ocigetbufferinglob()\",\n        \"Returns current state of buffering for a LOB\"\n    ],\n    \"ocisetbufferinglob\": [\n        \"bool ocisetbufferinglob( bool flag )\",\n        \"Enables/disables buffering for a LOB\"\n    ],\n    \"octdec\": [\n        \"int octdec(string octal_number)\",\n        \"Returns the decimal equivalent of an octal string\"\n    ],\n    \"odbc_autocommit\": [\n        \"mixed odbc_autocommit(resource connection_id [, int OnOff])\",\n        \"Toggle autocommit mode or get status\"\n    ],\n    \"odbc_binmode\": [\n        \"bool odbc_binmode(int result_id, int mode)\",\n        \"Handle binary column data\"\n    ],\n    \"odbc_close\": [\n        \"void odbc_close(resource connection_id)\",\n        \"Close an ODBC connection\"\n    ],\n    \"odbc_close_all\": [\n        \"void odbc_close_all()\",\n        \"Close all ODBC connections\"\n    ],\n    \"odbc_columnprivileges\": [\n        \"resource odbc_columnprivileges(resource connection_id, string catalog, string schema, string table, string column)\",\n        \"Returns a result identifier that can be used to fetch a list of columns and associated privileges for the specified table\"\n    ],\n    \"odbc_columns\": [\n        \"resource odbc_columns(resource connection_id [, string qualifier [, string owner [, string table_name [, string column_name]]]])\",\n        \"Returns a result identifier that can be used to fetch a list of column names in specified tables\"\n    ],\n    \"odbc_commit\": [\n        \"bool odbc_commit(resource connection_id)\",\n        \"Commit an ODBC transaction\"\n    ],\n    \"odbc_connect\": [\n        \"resource odbc_connect(string DSN, string user, string password [, int cursor_option])\",\n        \"Connect to a datasource\"\n    ],\n    \"odbc_cursor\": [\n        \"string odbc_cursor(resource result_id)\",\n        \"Get cursor name\"\n    ],\n    \"odbc_data_source\": [\n        \"array odbc_data_source(resource connection_id, int fetch_type)\",\n        \"Return information about the currently connected data source\"\n    ],\n    \"odbc_error\": [\n        \"string odbc_error([resource connection_id])\",\n        \"Get the last error code\"\n    ],\n    \"odbc_errormsg\": [\n        \"string odbc_errormsg([resource connection_id])\",\n        \"Get the last error message\"\n    ],\n    \"odbc_exec\": [\n        \"resource odbc_exec(resource connection_id, string query [, int flags])\",\n        \"Prepare and execute an SQL statement\"\n    ],\n    \"odbc_execute\": [\n        \"bool odbc_execute(resource result_id [, array parameters_array])\",\n        \"Execute a prepared statement\"\n    ],\n    \"odbc_fetch_array\": [\n        \"array odbc_fetch_array(int result [, int rownumber])\",\n        \"Fetch a result row as an associative array\"\n    ],\n    \"odbc_fetch_into\": [\n        \"int odbc_fetch_into(resource result_id, array &result_array, [, int rownumber])\",\n        \"Fetch one result row into an array\"\n    ],\n    \"odbc_fetch_object\": [\n        \"object odbc_fetch_object(int result [, int rownumber])\",\n        \"Fetch a result row as an object\"\n    ],\n    \"odbc_fetch_row\": [\n        \"bool odbc_fetch_row(resource result_id [, int row_number])\",\n        \"Fetch a row\"\n    ],\n    \"odbc_field_len\": [\n        \"int odbc_field_len(resource result_id, int field_number)\",\n        \"Get the length (precision) of a column\"\n    ],\n    \"odbc_field_name\": [\n        \"string odbc_field_name(resource result_id, int field_number)\",\n        \"Get a column name\"\n    ],\n    \"odbc_field_num\": [\n        \"int odbc_field_num(resource result_id, string field_name)\",\n        \"Return column number\"\n    ],\n    \"odbc_field_scale\": [\n        \"int odbc_field_scale(resource result_id, int field_number)\",\n        \"Get the scale of a column\"\n    ],\n    \"odbc_field_type\": [\n        \"string odbc_field_type(resource result_id, int field_number)\",\n        \"Get the datatype of a column\"\n    ],\n    \"odbc_foreignkeys\": [\n        \"resource odbc_foreignkeys(resource connection_id, string pk_qualifier, string pk_owner, string pk_table, string fk_qualifier, string fk_owner, string fk_table)\",\n        \"Returns a result identifier to either a list of foreign keys in the specified table or a list of foreign keys in other tables that refer to the primary key in the specified table\"\n    ],\n    \"odbc_free_result\": [\n        \"bool odbc_free_result(resource result_id)\",\n        \"Free resources associated with a result\"\n    ],\n    \"odbc_gettypeinfo\": [\n        \"resource odbc_gettypeinfo(resource connection_id [, int data_type])\",\n        \"Returns a result identifier containing information about data types supported by the data source\"\n    ],\n    \"odbc_longreadlen\": [\n        \"bool odbc_longreadlen(int result_id, int length)\",\n        \"Handle LONG columns\"\n    ],\n    \"odbc_next_result\": [\n        \"bool odbc_next_result(resource result_id)\",\n        \"Checks if multiple results are avaiable\"\n    ],\n    \"odbc_num_fields\": [\n        \"int odbc_num_fields(resource result_id)\",\n        \"Get number of columns in a result\"\n    ],\n    \"odbc_num_rows\": [\n        \"int odbc_num_rows(resource result_id)\",\n        \"Get number of rows in a result\"\n    ],\n    \"odbc_pconnect\": [\n        \"resource odbc_pconnect(string DSN, string user, string password [, int cursor_option])\",\n        \"Establish a persistent connection to a datasource\"\n    ],\n    \"odbc_prepare\": [\n        \"resource odbc_prepare(resource connection_id, string query)\",\n        \"Prepares a statement for execution\"\n    ],\n    \"odbc_primarykeys\": [\n        \"resource odbc_primarykeys(resource connection_id, string qualifier, string owner, string table)\",\n        \"Returns a result identifier listing the column names that comprise the primary key for a table\"\n    ],\n    \"odbc_procedurecolumns\": [\n        \"resource odbc_procedurecolumns(resource connection_id [, string qualifier, string owner, string proc, string column])\",\n        \"Returns a result identifier containing the list of input and output parameters, as well as the columns that make up the result set for the specified procedures\"\n    ],\n    \"odbc_procedures\": [\n        \"resource odbc_procedures(resource connection_id [, string qualifier, string owner, string name])\",\n        \"Returns a result identifier containg the list of procedure names in a datasource\"\n    ],\n    \"odbc_result\": [\n        \"mixed odbc_result(resource result_id, mixed field)\",\n        \"Get result data\"\n    ],\n    \"odbc_result_all\": [\n        \"int odbc_result_all(resource result_id [, string format])\",\n        \"Print result as HTML table\"\n    ],\n    \"odbc_rollback\": [\n        \"bool odbc_rollback(resource connection_id)\",\n        \"Rollback a transaction\"\n    ],\n    \"odbc_setoption\": [\n        \"bool odbc_setoption(resource conn_id|result_id, int which, int option, int value)\",\n        \"Sets connection or statement options\"\n    ],\n    \"odbc_specialcolumns\": [\n        \"resource odbc_specialcolumns(resource connection_id, int type, string qualifier, string owner, string table, int scope, int nullable)\",\n        \"Returns a result identifier containing either the optimal set of columns that uniquely identifies a row in the table or columns that are automatically updated when any value in the row is updated by a transaction\"\n    ],\n    \"odbc_statistics\": [\n        \"resource odbc_statistics(resource connection_id, string qualifier, string owner, string name, int unique, int accuracy)\",\n        \"Returns a result identifier that contains statistics about a single table and the indexes associated with the table\"\n    ],\n    \"odbc_tableprivileges\": [\n        \"resource odbc_tableprivileges(resource connection_id, string qualifier, string owner, string name)\",\n        \"Returns a result identifier containing a list of tables and the privileges associated with each table\"\n    ],\n    \"odbc_tables\": [\n        \"resource odbc_tables(resource connection_id [, string qualifier [, string owner [, string name [, string table_types]]]])\",\n        \"Call the SQLTables function\"\n    ],\n    \"opendir\": [\n        \"mixed opendir(string path[, resource context])\",\n        \"Open a directory and return a dir_handle\"\n    ],\n    \"openlog\": [\n        \"bool openlog(string ident, int option, int facility)\",\n        \"Open connection to system logger\"\n    ],\n    \"openssl_csr_export\": [\n        \"bool openssl_csr_export(resource csr, string &out [, bool notext=true])\",\n        \"Exports a CSR to file or a var\"\n    ],\n    \"openssl_csr_export_to_file\": [\n        \"bool openssl_csr_export_to_file(resource csr, string outfilename [, bool notext=true])\",\n        \"Exports a CSR to file\"\n    ],\n    \"openssl_csr_get_public_key\": [\n        \"mixed openssl_csr_get_public_key(mixed csr)\",\n        \"Returns the subject of a CERT or FALSE on error\"\n    ],\n    \"openssl_csr_get_subject\": [\n        \"mixed openssl_csr_get_subject(mixed csr)\",\n        \"Returns the subject of a CERT or FALSE on error\"\n    ],\n    \"openssl_csr_new\": [\n        \"bool openssl_csr_new(array dn, resource &privkey [, array configargs [, array extraattribs]])\",\n        \"Generates a privkey and CSR\"\n    ],\n    \"openssl_csr_sign\": [\n        \"resource openssl_csr_sign(mixed csr, mixed x509, mixed priv_key, long days [, array config_args [, long serial]])\",\n        \"Signs a cert with another CERT\"\n    ],\n    \"openssl_decrypt\": [\n        \"string openssl_decrypt(string data, string method, string password [, bool raw_input=false])\",\n        \"Takes raw or base64 encoded string and dectupt it using given method and key\"\n    ],\n    \"openssl_dh_compute_key\": [\n        \"string openssl_dh_compute_key(string pub_key, resource dh_key)\",\n        \"Computes shared sicret for public value of remote DH key and local DH key\"\n    ],\n    \"openssl_digest\": [\n        \"string openssl_digest(string data, string method [, bool raw_output=false])\",\n        \"Computes digest hash value for given data using given method, returns raw or binhex encoded string\"\n    ],\n    \"openssl_encrypt\": [\n        \"string openssl_encrypt(string data, string method, string password [, bool raw_output=false])\",\n        \"Encrypts given data with given method and key, returns raw or base64 encoded string\"\n    ],\n    \"openssl_error_string\": [\n        \"mixed openssl_error_string()\",\n        \"Returns a description of the last error, and alters the index of the error messages. Returns false when the are no more messages\"\n    ],\n    \"openssl_get_cipher_methods\": [\n        \"array openssl_get_cipher_methods([bool aliases = false])\",\n        \"Return array of available cipher methods\"\n    ],\n    \"openssl_get_md_methods\": [\n        \"array openssl_get_md_methods([bool aliases = false])\",\n        \"Return array of available digest methods\"\n    ],\n    \"openssl_open\": [\n        \"bool openssl_open(string data, &string opendata, string ekey, mixed privkey)\",\n        \"Opens data\"\n    ],\n    \"openssl_pkcs12_export\": [\n        \"bool openssl_pkcs12_export(mixed x509, string &out, mixed priv_key, string pass[, array args])\",\n        \"Creates and exports a PKCS12 to a var\"\n    ],\n    \"openssl_pkcs12_export_to_file\": [\n        \"bool openssl_pkcs12_export_to_file(mixed x509, string filename, mixed priv_key, string pass[, array args])\",\n        \"Creates and exports a PKCS to file\"\n    ],\n    \"openssl_pkcs12_read\": [\n        \"bool openssl_pkcs12_read(string PKCS12, array &certs, string pass)\",\n        \"Parses a PKCS12 to an array\"\n    ],\n    \"openssl_pkcs7_decrypt\": [\n        \"bool openssl_pkcs7_decrypt(string infilename, string outfilename, mixed recipcert [, mixed recipkey])\",\n        \"Decrypts the S/MIME message in the file name infilename and output the results to the file name outfilename.  recipcert is a CERT for one of the recipients. recipkey specifies the private key matching recipcert, if recipcert does not include the key\"\n    ],\n    \"openssl_pkcs7_encrypt\": [\n        \"bool openssl_pkcs7_encrypt(string infile, string outfile, mixed recipcerts, array headers [, long flags [, long cipher]])\",\n        \"Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile\"\n    ],\n    \"openssl_pkcs7_sign\": [\n        \"bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed signkey, array headers [, long flags [, string extracertsfilename]])\",\n        \"Signs the MIME message in the file named infile with signcert/signkey and output the result to file name outfile. headers lists plain text headers to exclude from the signed portion of the message, and should include to, from and subject as a minimum\"\n    ],\n    \"openssl_pkcs7_verify\": [\n        \"bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]])\",\n        \"Verifys that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers\"\n    ],\n    \"openssl_pkey_export\": [\n        \"bool openssl_pkey_export(mixed key, &mixed out [, string passphrase [, array config_args]])\",\n        \"Gets an exportable representation of a key into a string or file\"\n    ],\n    \"openssl_pkey_export_to_file\": [\n        \"bool openssl_pkey_export_to_file(mixed key, string outfilename [, string passphrase, array config_args)\",\n        \"Gets an exportable representation of a key into a file\"\n    ],\n    \"openssl_pkey_free\": [\n        \"void openssl_pkey_free(int key)\",\n        \"Frees a key\"\n    ],\n    \"openssl_pkey_get_details\": [\n        \"resource openssl_pkey_get_details(resource key)\",\n        \"returns an array with the key details (bits, pkey, type)\"\n    ],\n    \"openssl_pkey_get_private\": [\n        \"int openssl_pkey_get_private(string key [, string passphrase])\",\n        \"Gets private keys\"\n    ],\n    \"openssl_pkey_get_public\": [\n        \"int openssl_pkey_get_public(mixed cert)\",\n        \"Gets public key from X.509 certificate\"\n    ],\n    \"openssl_pkey_new\": [\n        \"resource openssl_pkey_new([array configargs])\",\n        \"Generates a new private key\"\n    ],\n    \"openssl_private_decrypt\": [\n        \"bool openssl_private_decrypt(string data, string &decrypted, mixed key [, int padding])\",\n        \"Decrypts data with private key\"\n    ],\n    \"openssl_private_encrypt\": [\n        \"bool openssl_private_encrypt(string data, string &crypted, mixed key [, int padding])\",\n        \"Encrypts data with private key\"\n    ],\n    \"openssl_public_decrypt\": [\n        \"bool openssl_public_decrypt(string data, string &crypted, resource key [, int padding])\",\n        \"Decrypts data with public key\"\n    ],\n    \"openssl_public_encrypt\": [\n        \"bool openssl_public_encrypt(string data, string &crypted, mixed key [, int padding])\",\n        \"Encrypts data with public key\"\n    ],\n    \"openssl_random_pseudo_bytes\": [\n        \"string openssl_random_pseudo_bytes(integer length [, &bool returned_strong_result])\",\n        \"Returns a string of the length specified filled with random pseudo bytes\"\n    ],\n    \"openssl_seal\": [\n        \"int openssl_seal(string data, &string sealdata, &array ekeys, array pubkeys)\",\n        \"Seals data\"\n    ],\n    \"openssl_sign\": [\n        \"bool openssl_sign(string data, &string signature, mixed key[, mixed method])\",\n        \"Signs data\"\n    ],\n    \"openssl_verify\": [\n        \"int openssl_verify(string data, string signature, mixed key[, mixed method])\",\n        \"Verifys data\"\n    ],\n    \"openssl_x509_check_private_key\": [\n        \"bool openssl_x509_check_private_key(mixed cert, mixed key)\",\n        \"Checks if a private key corresponds to a CERT\"\n    ],\n    \"openssl_x509_checkpurpose\": [\n        \"int openssl_x509_checkpurpose(mixed x509cert, int purpose, array cainfo [, string untrustedfile])\",\n        \"Checks the CERT to see if it can be used for the purpose in purpose. cainfo holds information about trusted CAs\"\n    ],\n    \"openssl_x509_export\": [\n        \"bool openssl_x509_export(mixed x509, string &out [, bool notext = true])\",\n        \"Exports a CERT to file or a var\"\n    ],\n    \"openssl_x509_export_to_file\": [\n        \"bool openssl_x509_export_to_file(mixed x509, string outfilename [, bool notext = true])\",\n        \"Exports a CERT to file or a var\"\n    ],\n    \"openssl_x509_free\": [\n        \"void openssl_x509_free(resource x509)\",\n        \"Frees X.509 certificates\"\n    ],\n    \"openssl_x509_parse\": [\n        \"array openssl_x509_parse(mixed x509 [, bool shortnames=true])\",\n        \"Returns an array of the fields/values of the CERT\"\n    ],\n    \"openssl_x509_read\": [\n        \"resource openssl_x509_read(mixed cert)\",\n        \"Reads X.509 certificates\"\n    ],\n    \"ord\": [\n        \"int ord(string character)\",\n        \"Returns ASCII value of character\"\n    ],\n    \"output_add_rewrite_var\": [\n        \"bool output_add_rewrite_var(string name, string value)\",\n        \"Add URL rewriter values\"\n    ],\n    \"output_reset_rewrite_vars\": [\n        \"bool output_reset_rewrite_vars()\",\n        \"Reset(clear) URL rewriter values\"\n    ],\n    \"pack\": [\n        \"string pack(string format, mixed arg1 [, mixed arg2 [, mixed ...]])\",\n        \"Takes one or more arguments and packs them into a binary string according to the format argument\"\n    ],\n    \"parse_ini_file\": [\n        \"array parse_ini_file(string filename [, bool process_sections [, int scanner_mode]])\",\n        \"Parse configuration file\"\n    ],\n    \"parse_ini_string\": [\n        \"array parse_ini_string(string ini_string [, bool process_sections [, int scanner_mode]])\",\n        \"Parse configuration string\"\n    ],\n    \"parse_locale\": [\n        \"static array parse_locale($locale)\",\n        \"* parses a locale-id into an array the different parts of it\"\n    ],\n    \"parse_str\": [\n        \"void parse_str(string encoded_string [, array result])\",\n        \"Parses GET/POST/COOKIE data and sets global variables\"\n    ],\n    \"parse_url\": [\n        \"mixed parse_url(string url, [int url_component])\",\n        \"Parse a URL and return its components\"\n    ],\n    \"passthru\": [\n        \"void passthru(string command [, int &return_value])\",\n        \"Execute an external program and display raw output\"\n    ],\n    \"pathinfo\": [\n        \"array pathinfo(string path[, int options])\",\n        \"Returns information about a certain string\"\n    ],\n    \"pclose\": [\n        \"int pclose(resource fp)\",\n        \"Close a file pointer opened by popen()\"\n    ],\n    \"pcnlt_sigwaitinfo\": [\n        \"int pcnlt_sigwaitinfo(array set[, array &siginfo])\",\n        \"Synchronously wait for queued signals\"\n    ],\n    \"pcntl_alarm\": [\n        \"int pcntl_alarm(int seconds)\",\n        \"Set an alarm clock for delivery of a signal\"\n    ],\n    \"pcntl_exec\": [\n        \"bool pcntl_exec(string path [, array args [, array envs]])\",\n        \"Executes specified program in current process space as defined by exec(2)\"\n    ],\n    \"pcntl_fork\": [\n        \"int pcntl_fork()\",\n        \"Forks the currently running process following the same behavior as the UNIX fork() system call\"\n    ],\n    \"pcntl_getpriority\": [\n        \"int pcntl_getpriority([int pid [, int process_identifier]])\",\n        \"Get the priority of any process\"\n    ],\n    \"pcntl_setpriority\": [\n        \"bool pcntl_setpriority(int priority [, int pid [, int process_identifier]])\",\n        \"Change the priority of any process\"\n    ],\n    \"pcntl_signal\": [\n        \"bool pcntl_signal(int signo, callback handle [, bool restart_syscalls])\",\n        \"Assigns a system signal handler to a PHP function\"\n    ],\n    \"pcntl_signal_dispatch\": [\n        \"bool pcntl_signal_dispatch()\",\n        \"Dispatch signals to signal handlers\"\n    ],\n    \"pcntl_sigprocmask\": [\n        \"bool pcntl_sigprocmask(int how, array set[, array &oldset])\",\n        \"Examine and change blocked signals\"\n    ],\n    \"pcntl_sigtimedwait\": [\n        \"int pcntl_sigtimedwait(array set[, array &siginfo[, int seconds[, int nanoseconds]]])\",\n        \"Wait for queued signals\"\n    ],\n    \"pcntl_wait\": [\n        \"int pcntl_wait(int &status)\",\n        \"Waits on or returns the status of a forked child as defined by the waitpid() system call\"\n    ],\n    \"pcntl_waitpid\": [\n        \"int pcntl_waitpid(int pid, int &status, int options)\",\n        \"Waits on or returns the status of a forked child as defined by the waitpid() system call\"\n    ],\n    \"pcntl_wexitstatus\": [\n        \"int pcntl_wexitstatus(int status)\",\n        \"Returns the status code of a child's exit\"\n    ],\n    \"pcntl_wifexited\": [\n        \"bool pcntl_wifexited(int status)\",\n        \"Returns true if the child status code represents a successful exit\"\n    ],\n    \"pcntl_wifsignaled\": [\n        \"bool pcntl_wifsignaled(int status)\",\n        \"Returns true if the child status code represents a process that was terminated due to a signal\"\n    ],\n    \"pcntl_wifstopped\": [\n        \"bool pcntl_wifstopped(int status)\",\n        \"Returns true if the child status code represents a stopped process (WUNTRACED must have been used with waitpid)\"\n    ],\n    \"pcntl_wstopsig\": [\n        \"int pcntl_wstopsig(int status)\",\n        \"Returns the number of the signal that caused the process to stop who's status code is passed\"\n    ],\n    \"pcntl_wtermsig\": [\n        \"int pcntl_wtermsig(int status)\",\n        \"Returns the number of the signal that terminated the process who's status code is passed\"\n    ],\n    \"pdo_drivers\": [\n        \"array pdo_drivers()\",\n        \"Return array of available PDO drivers\"\n    ],\n    \"pfsockopen\": [\n        \"resource pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])\",\n        \"Open persistent Internet or Unix domain socket connection\"\n    ],\n    \"pg_affected_rows\": [\n        \"int pg_affected_rows(resource result)\",\n        \"Returns the number of affected tuples\"\n    ],\n    \"pg_cancel_query\": [\n        \"bool pg_cancel_query(resource connection)\",\n        \"Cancel request\"\n    ],\n    \"pg_client_encoding\": [\n        \"string pg_client_encoding([resource connection])\",\n        \"Get the current client encoding\"\n    ],\n    \"pg_close\": [\n        \"bool pg_close([resource connection])\",\n        \"Close a PostgreSQL connection\"\n    ],\n    \"pg_connect\": [\n        \"resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)\",\n        \"Open a PostgreSQL connection\"\n    ],\n    \"pg_connection_busy\": [\n        \"bool pg_connection_busy(resource connection)\",\n        \"Get connection is busy or not\"\n    ],\n    \"pg_connection_reset\": [\n        \"bool pg_connection_reset(resource connection)\",\n        \"Reset connection (reconnect)\"\n    ],\n    \"pg_connection_status\": [\n        \"int pg_connection_status(resource connnection)\",\n        \"Get connection status\"\n    ],\n    \"pg_convert\": [\n        \"array pg_convert(resource db, string table, array values[, int options])\",\n        \"Check and convert values for PostgreSQL SQL statement\"\n    ],\n    \"pg_copy_from\": [\n        \"bool pg_copy_from(resource connection, string table_name , array rows [, string delimiter [, string null_as]])\",\n        \"Copy table from array\"\n    ],\n    \"pg_copy_to\": [\n        \"array pg_copy_to(resource connection, string table_name [, string delimiter [, string null_as]])\",\n        \"Copy table to array\"\n    ],\n    \"pg_dbname\": [\n        \"string pg_dbname([resource connection])\",\n        \"Get the database name\"\n    ],\n    \"pg_delete\": [\n        \"mixed pg_delete(resource db, string table, array ids[, int options])\",\n        \"Delete records has ids (id => value)\"\n    ],\n    \"pg_end_copy\": [\n        \"bool pg_end_copy([resource connection])\",\n        \"Sync with backend. Completes the Copy command\"\n    ],\n    \"pg_escape_bytea\": [\n        \"string pg_escape_bytea([resource connection,] string data)\",\n        \"Escape binary for bytea type\"\n    ],\n    \"pg_escape_string\": [\n        \"string pg_escape_string([resource connection,] string data)\",\n        \"Escape string for text/char type\"\n    ],\n    \"pg_execute\": [\n        \"resource pg_execute([resource connection,] string stmtname, array params)\",\n        \"Execute a prepared query\"\n    ],\n    \"pg_fetch_all\": [\n        \"array pg_fetch_all(resource result)\",\n        \"Fetch all rows into array\"\n    ],\n    \"pg_fetch_all_columns\": [\n        \"array pg_fetch_all_columns(resource result [, int column_number])\",\n        \"Fetch all rows into array\"\n    ],\n    \"pg_fetch_array\": [\n        \"array pg_fetch_array(resource result [, int row [, int result_type]])\",\n        \"Fetch a row as an array\"\n    ],\n    \"pg_fetch_assoc\": [\n        \"array pg_fetch_assoc(resource result [, int row])\",\n        \"Fetch a row as an assoc array\"\n    ],\n    \"pg_fetch_object\": [\n        \"object pg_fetch_object(resource result [, int row [, string class_name [, NULL|array ctor_params]]])\",\n        \"Fetch a row as an object\"\n    ],\n    \"pg_fetch_result\": [\n        \"mixed pg_fetch_result(resource result, [int row_number,] mixed field_name)\",\n        \"Returns values from a result identifier\"\n    ],\n    \"pg_fetch_row\": [\n        \"array pg_fetch_row(resource result [, int row [, int result_type]])\",\n        \"Get a row as an enumerated array\"\n    ],\n    \"pg_field_is_null\": [\n        \"int pg_field_is_null(resource result, [int row,] mixed field_name_or_number)\",\n        \"Test if a field is NULL\"\n    ],\n    \"pg_field_name\": [\n        \"string pg_field_name(resource result, int field_number)\",\n        \"Returns the name of the field\"\n    ],\n    \"pg_field_num\": [\n        \"int pg_field_num(resource result, string field_name)\",\n        \"Returns the field number of the named field\"\n    ],\n    \"pg_field_prtlen\": [\n        \"int pg_field_prtlen(resource result, [int row,] mixed field_name_or_number)\",\n        \"Returns the printed length\"\n    ],\n    \"pg_field_size\": [\n        \"int pg_field_size(resource result, int field_number)\",\n        \"Returns the internal size of the field\"\n    ],\n    \"pg_field_table\": [\n        \"mixed pg_field_table(resource result, int field_number[, bool oid_only])\",\n        \"Returns the name of the table field belongs to, or table's oid if oid_only is true\"\n    ],\n    \"pg_field_type\": [\n        \"string pg_field_type(resource result, int field_number)\",\n        \"Returns the type name for the given field\"\n    ],\n    \"pg_field_type_oid\": [\n        \"string pg_field_type_oid(resource result, int field_number)\",\n        \"Returns the type oid for the given field\"\n    ],\n    \"pg_free_result\": [\n        \"bool pg_free_result(resource result)\",\n        \"Free result memory\"\n    ],\n    \"pg_get_notify\": [\n        \"array pg_get_notify([resource connection[, result_type]])\",\n        \"Get asynchronous notification\"\n    ],\n    \"pg_get_pid\": [\n        \"int pg_get_pid([resource connection)\",\n        \"Get backend(server) pid\"\n    ],\n    \"pg_get_result\": [\n        \"resource pg_get_result(resource connection)\",\n        \"Get asynchronous query result\"\n    ],\n    \"pg_host\": [\n        \"string pg_host([resource connection])\",\n        \"Returns the host name associated with the connection\"\n    ],\n    \"pg_insert\": [\n        \"mixed pg_insert(resource db, string table, array values[, int options])\",\n        \"Insert values (filed => value) to table\"\n    ],\n    \"pg_last_error\": [\n        \"string pg_last_error([resource connection])\",\n        \"Get the error message string\"\n    ],\n    \"pg_last_notice\": [\n        \"string pg_last_notice(resource connection)\",\n        \"Returns the last notice set by the backend\"\n    ],\n    \"pg_last_oid\": [\n        \"string pg_last_oid(resource result)\",\n        \"Returns the last object identifier\"\n    ],\n    \"pg_lo_close\": [\n        \"bool pg_lo_close(resource large_object)\",\n        \"Close a large object\"\n    ],\n    \"pg_lo_create\": [\n        \"mixed pg_lo_create([resource connection],[mixed large_object_oid])\",\n        \"Create a large object\"\n    ],\n    \"pg_lo_export\": [\n        \"bool pg_lo_export([resource connection, ] int objoid, string filename)\",\n        \"Export large object direct to filesystem\"\n    ],\n    \"pg_lo_import\": [\n        \"int pg_lo_import([resource connection, ] string filename [, mixed oid])\",\n        \"Import large object direct from filesystem\"\n    ],\n    \"pg_lo_open\": [\n        \"resource pg_lo_open([resource connection,] int large_object_oid, string mode)\",\n        \"Open a large object and return fd\"\n    ],\n    \"pg_lo_read\": [\n        \"string pg_lo_read(resource large_object [, int len])\",\n        \"Read a large object\"\n    ],\n    \"pg_lo_read_all\": [\n        \"int pg_lo_read_all(resource large_object)\",\n        \"Read a large object and send straight to browser\"\n    ],\n    \"pg_lo_seek\": [\n        \"bool pg_lo_seek(resource large_object, int offset [, int whence])\",\n        \"Seeks position of large object\"\n    ],\n    \"pg_lo_tell\": [\n        \"int pg_lo_tell(resource large_object)\",\n        \"Returns current position of large object\"\n    ],\n    \"pg_lo_unlink\": [\n        \"bool pg_lo_unlink([resource connection,] string large_object_oid)\",\n        \"Delete a large object\"\n    ],\n    \"pg_lo_write\": [\n        \"int pg_lo_write(resource large_object, string buf [, int len])\",\n        \"Write a large object\"\n    ],\n    \"pg_meta_data\": [\n        \"array pg_meta_data(resource db, string table)\",\n        \"Get meta_data\"\n    ],\n    \"pg_num_fields\": [\n        \"int pg_num_fields(resource result)\",\n        \"Return the number of fields in the result\"\n    ],\n    \"pg_num_rows\": [\n        \"int pg_num_rows(resource result)\",\n        \"Return the number of rows in the result\"\n    ],\n    \"pg_options\": [\n        \"string pg_options([resource connection])\",\n        \"Get the options associated with the connection\"\n    ],\n    \"pg_parameter_status\": [\n        \"string|false pg_parameter_status([resource connection,] string param_name)\",\n        \"Returns the value of a server parameter\"\n    ],\n    \"pg_pconnect\": [\n        \"resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database)\",\n        \"Open a persistent PostgreSQL connection\"\n    ],\n    \"pg_ping\": [\n        \"bool pg_ping([resource connection])\",\n        \"Ping database. If connection is bad, try to reconnect.\"\n    ],\n    \"pg_port\": [\n        \"int pg_port([resource connection])\",\n        \"Return the port number associated with the connection\"\n    ],\n    \"pg_prepare\": [\n        \"resource pg_prepare([resource connection,] string stmtname, string query)\",\n        \"Prepare a query for future execution\"\n    ],\n    \"pg_put_line\": [\n        \"bool pg_put_line([resource connection,] string query)\",\n        \"Send null-terminated string to backend server\"\n    ],\n    \"pg_query\": [\n        \"resource pg_query([resource connection,] string query)\",\n        \"Execute a query\"\n    ],\n    \"pg_query_params\": [\n        \"resource pg_query_params([resource connection,] string query, array params)\",\n        \"Execute a query\"\n    ],\n    \"pg_result_error\": [\n        \"string pg_result_error(resource result)\",\n        \"Get error message associated with result\"\n    ],\n    \"pg_result_error_field\": [\n        \"string pg_result_error_field(resource result, int fieldcode)\",\n        \"Get error message field associated with result\"\n    ],\n    \"pg_result_seek\": [\n        \"bool pg_result_seek(resource result, int offset)\",\n        \"Set internal row offset\"\n    ],\n    \"pg_result_status\": [\n        \"mixed pg_result_status(resource result[, long result_type])\",\n        \"Get status of query result\"\n    ],\n    \"pg_select\": [\n        \"mixed pg_select(resource db, string table, array ids[, int options])\",\n        \"Select records that has ids (id => value)\"\n    ],\n    \"pg_send_execute\": [\n        \"bool pg_send_execute(resource connection, string stmtname, array params)\",\n        \"Executes prevriously prepared stmtname asynchronously\"\n    ],\n    \"pg_send_prepare\": [\n        \"bool pg_send_prepare(resource connection, string stmtname, string query)\",\n        \"Asynchronously prepare a query for future execution\"\n    ],\n    \"pg_send_query\": [\n        \"bool pg_send_query(resource connection, string query)\",\n        \"Send asynchronous query\"\n    ],\n    \"pg_send_query_params\": [\n        \"bool pg_send_query_params(resource connection, string query, array params)\",\n        \"Send asynchronous parameterized query\"\n    ],\n    \"pg_set_client_encoding\": [\n        \"int pg_set_client_encoding([resource connection,] string encoding)\",\n        \"Set client encoding\"\n    ],\n    \"pg_set_error_verbosity\": [\n        \"int pg_set_error_verbosity([resource connection,] int verbosity)\",\n        \"Set error verbosity\"\n    ],\n    \"pg_trace\": [\n        \"bool pg_trace(string filename [, string mode [, resource connection]])\",\n        \"Enable tracing a PostgreSQL connection\"\n    ],\n    \"pg_transaction_status\": [\n        \"int pg_transaction_status(resource connnection)\",\n        \"Get transaction status\"\n    ],\n    \"pg_tty\": [\n        \"string pg_tty([resource connection])\",\n        \"Return the tty name associated with the connection\"\n    ],\n    \"pg_unescape_bytea\": [\n        \"string pg_unescape_bytea(string data)\",\n        \"Unescape binary for bytea type\"\n    ],\n    \"pg_untrace\": [\n        \"bool pg_untrace([resource connection])\",\n        \"Disable tracing of a PostgreSQL connection\"\n    ],\n    \"pg_update\": [\n        \"mixed pg_update(resource db, string table, array fields, array ids[, int options])\",\n        \"Update table using values (field => value) and ids (id => value)\"\n    ],\n    \"pg_version\": [\n        \"array pg_version([resource connection])\",\n        \"Returns an array with client, protocol and server version (when available)\"\n    ],\n    \"php_egg_logo_guid\": [\n        \"string php_egg_logo_guid()\",\n        \"Return the special ID used to request the PHP logo in phpinfo screens\"\n    ],\n    \"php_ini_loaded_file\": [\n        \"string php_ini_loaded_file()\",\n        \"Return the actual loaded ini filename\"\n    ],\n    \"php_ini_scanned_files\": [\n        \"string php_ini_scanned_files()\",\n        \"Return comma-separated string of .ini files parsed from the additional ini dir\"\n    ],\n    \"php_logo_guid\": [\n        \"string php_logo_guid()\",\n        \"Return the special ID used to request the PHP logo in phpinfo screens\"\n    ],\n    \"php_real_logo_guid\": [\n        \"string php_real_logo_guid()\",\n        \"Return the special ID used to request the PHP logo in phpinfo screens\"\n    ],\n    \"php_sapi_name\": [\n        \"string php_sapi_name()\",\n        \"Return the current SAPI module name\"\n    ],\n    \"php_snmpv3\": [\n        \"void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)\",\n        \"* * Generic SNMPv3 object fetcher * From here is passed on the the common internal object fetcher. * * st=SNMP_CMD_GET   snmp3_get() - query an agent and return a single value. * st=SNMP_CMD_GETNEXT   snmp3_getnext() - query an agent and return the next single value. * st=SNMP_CMD_WALK   snmp3_walk() - walk the mib and return a single dimensional array  *                       containing the values. * st=SNMP_CMD_REALWALK   snmp3_real_walk() - walk the mib and return an  *                            array of oid,value pairs. * st=SNMP_CMD_SET  snmp3_set() - query an agent and set a single value *\"\n    ],\n    \"php_strip_whitespace\": [\n        \"string php_strip_whitespace(string file_name)\",\n        \"Return source with stripped comments and whitespace\"\n    ],\n    \"php_uname\": [\n        \"string php_uname()\",\n        \"Return information about the system PHP was built on\"\n    ],\n    \"phpcredits\": [\n        \"void phpcredits([int flag])\",\n        \"Prints the list of people who've contributed to the PHP project\"\n    ],\n    \"phpinfo\": [\n        \"void phpinfo([int what])\",\n        \"Output a page of useful information about PHP and the current request\"\n    ],\n    \"phpversion\": [\n        \"string phpversion([string extension])\",\n        \"Return the current PHP version\"\n    ],\n    \"pi\": [\n        \"float pi()\",\n        \"Returns an approximation of pi\"\n    ],\n    \"png2wbmp\": [\n        \"bool png2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)\",\n        \"Convert PNG image to WBMP image\"\n    ],\n    \"popen\": [\n        \"resource popen(string command, string mode)\",\n        \"Execute a command and open either a read or a write pipe to it\"\n    ],\n    \"posix_access\": [\n        \"bool posix_access(string file [, int mode])\",\n        \"Determine accessibility of a file (POSIX.1 5.6.3)\"\n    ],\n    \"posix_ctermid\": [\n        \"string posix_ctermid()\",\n        \"Generate terminal path name (POSIX.1, 4.7.1)\"\n    ],\n    \"posix_get_last_error\": [\n        \"int posix_get_last_error()\",\n        \"Retrieve the error number set by the last posix function which failed.\"\n    ],\n    \"posix_getcwd\": [\n        \"string posix_getcwd()\",\n        \"Get working directory pathname (POSIX.1, 5.2.2)\"\n    ],\n    \"posix_getegid\": [\n        \"int posix_getegid()\",\n        \"Get the current effective group id (POSIX.1, 4.2.1)\"\n    ],\n    \"posix_geteuid\": [\n        \"int posix_geteuid()\",\n        \"Get the current effective user id (POSIX.1, 4.2.1)\"\n    ],\n    \"posix_getgid\": [\n        \"int posix_getgid()\",\n        \"Get the current group id (POSIX.1, 4.2.1)\"\n    ],\n    \"posix_getgrgid\": [\n        \"array posix_getgrgid(long gid)\",\n        \"Group database access (POSIX.1, 9.2.1)\"\n    ],\n    \"posix_getgrnam\": [\n        \"array posix_getgrnam(string groupname)\",\n        \"Group database access (POSIX.1, 9.2.1)\"\n    ],\n    \"posix_getgroups\": [\n        \"array posix_getgroups()\",\n        \"Get supplementary group id's (POSIX.1, 4.2.3)\"\n    ],\n    \"posix_getlogin\": [\n        \"string posix_getlogin()\",\n        \"Get user name (POSIX.1, 4.2.4)\"\n    ],\n    \"posix_getpgid\": [\n        \"int posix_getpgid()\",\n        \"Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally)\"\n    ],\n    \"posix_getpgrp\": [\n        \"int posix_getpgrp()\",\n        \"Get current process group id (POSIX.1, 4.3.1)\"\n    ],\n    \"posix_getpid\": [\n        \"int posix_getpid()\",\n        \"Get the current process id (POSIX.1, 4.1.1)\"\n    ],\n    \"posix_getppid\": [\n        \"int posix_getppid()\",\n        \"Get the parent process id (POSIX.1, 4.1.1)\"\n    ],\n    \"posix_getpwnam\": [\n        \"array posix_getpwnam(string groupname)\",\n        \"User database access (POSIX.1, 9.2.2)\"\n    ],\n    \"posix_getpwuid\": [\n        \"array posix_getpwuid(long uid)\",\n        \"User database access (POSIX.1, 9.2.2)\"\n    ],\n    \"posix_getrlimit\": [\n        \"array posix_getrlimit()\",\n        \"Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally)\"\n    ],\n    \"posix_getsid\": [\n        \"int posix_getsid()\",\n        \"Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally)\"\n    ],\n    \"posix_getuid\": [\n        \"int posix_getuid()\",\n        \"Get the current user id (POSIX.1, 4.2.1)\"\n    ],\n    \"posix_initgroups\": [\n        \"bool posix_initgroups(string name, int base_group_id)\",\n        \"Calculate the group access list for the user specified in name.\"\n    ],\n    \"posix_isatty\": [\n        \"bool posix_isatty(int fd)\",\n        \"Determine if filedesc is a tty (POSIX.1, 4.7.1)\"\n    ],\n    \"posix_kill\": [\n        \"bool posix_kill(int pid, int sig)\",\n        \"Send a signal to a process (POSIX.1, 3.3.2)\"\n    ],\n    \"posix_mkfifo\": [\n        \"bool posix_mkfifo(string pathname, int mode)\",\n        \"Make a FIFO special file (POSIX.1, 5.4.2)\"\n    ],\n    \"posix_mknod\": [\n        \"bool posix_mknod(string pathname, int mode [, int major [, int minor]])\",\n        \"Make a special or ordinary file (POSIX.1)\"\n    ],\n    \"posix_setegid\": [\n        \"bool posix_setegid(long uid)\",\n        \"Set effective group id\"\n    ],\n    \"posix_seteuid\": [\n        \"bool posix_seteuid(long uid)\",\n        \"Set effective user id\"\n    ],\n    \"posix_setgid\": [\n        \"bool posix_setgid(int uid)\",\n        \"Set group id (POSIX.1, 4.2.2)\"\n    ],\n    \"posix_setpgid\": [\n        \"bool posix_setpgid(int pid, int pgid)\",\n        \"Set process group id for job control (POSIX.1, 4.3.3)\"\n    ],\n    \"posix_setsid\": [\n        \"int posix_setsid()\",\n        \"Create session and set process group id (POSIX.1, 4.3.2)\"\n    ],\n    \"posix_setuid\": [\n        \"bool posix_setuid(long uid)\",\n        \"Set user id (POSIX.1, 4.2.2)\"\n    ],\n    \"posix_strerror\": [\n        \"string posix_strerror(int errno)\",\n        \"Retrieve the system error message associated with the given errno.\"\n    ],\n    \"posix_times\": [\n        \"array posix_times()\",\n        \"Get process times (POSIX.1, 4.5.2)\"\n    ],\n    \"posix_ttyname\": [\n        \"string posix_ttyname(int fd)\",\n        \"Determine terminal device name (POSIX.1, 4.7.2)\"\n    ],\n    \"posix_uname\": [\n        \"array posix_uname()\",\n        \"Get system name (POSIX.1, 4.4.1)\"\n    ],\n    \"pow\": [\n        \"number pow(number base, number exponent)\",\n        \"Returns base raised to the power of exponent. Returns integer result when possible\"\n    ],\n    \"preg_filter\": [\n        \"mixed preg_filter(mixed regex, mixed replace, mixed subject [, int limit [, int &count]])\",\n        \"Perform Perl-style regular expression replacement and only return matches.\"\n    ],\n    \"preg_grep\": [\n        \"array preg_grep(string regex, array input [, int flags])\",\n        \"Searches array and returns entries which match regex\"\n    ],\n    \"preg_last_error\": [\n        \"int preg_last_error()\",\n        \"Returns the error code of the last regexp execution.\"\n    ],\n    \"preg_match\": [\n        \"int preg_match(string pattern, string subject [, array &subpatterns [, int flags [, int offset]]])\",\n        \"Perform a Perl-style regular expression match\"\n    ],\n    \"preg_match_all\": [\n        \"int preg_match_all(string pattern, string subject, array &subpatterns [, int flags [, int offset]])\",\n        \"Perform a Perl-style global regular expression match\"\n    ],\n    \"preg_quote\": [\n        \"string preg_quote(string str [, string delim_char])\",\n        \"Quote regular expression characters plus an optional character\"\n    ],\n    \"preg_replace\": [\n        \"mixed preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, int &count]])\",\n        \"Perform Perl-style regular expression replacement.\"\n    ],\n    \"preg_replace_callback\": [\n        \"mixed preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit [, int &count]])\",\n        \"Perform Perl-style regular expression replacement using replacement callback.\"\n    ],\n    \"preg_split\": [\n        \"array preg_split(string pattern, string subject [, int limit [, int flags]])\",\n        \"Split string into an array using a perl-style regular expression as a delimiter\"\n    ],\n    \"prev\": [\n        \"mixed prev(array array_arg)\",\n        \"Move array argument's internal pointer to the previous element and return it\"\n    ],\n    \"print\": [\n        \"int print(string arg)\",\n        \"Output a string\"\n    ],\n    \"print_r\": [\n        \"mixed print_r(mixed var [, bool return])\",\n        \"Prints out or returns information about the specified variable\"\n    ],\n    \"printf\": [\n        \"int printf(string format [, mixed arg1 [, mixed ...]])\",\n        \"Output a formatted string\"\n    ],\n    \"proc_close\": [\n        \"int proc_close(resource process)\",\n        \"close a process opened by proc_open\"\n    ],\n    \"proc_get_status\": [\n        \"array proc_get_status(resource process)\",\n        \"get information about a process opened by proc_open\"\n    ],\n    \"proc_nice\": [\n        \"bool proc_nice(int priority)\",\n        \"Change the priority of the current process\"\n    ],\n    \"proc_open\": [\n        \"resource proc_open(string command, array descriptorspec, array &pipes [, string cwd [, array env [, array other_options]]])\",\n        \"Run a process with more control over it's file descriptors\"\n    ],\n    \"proc_terminate\": [\n        \"bool proc_terminate(resource process [, long signal])\",\n        \"kill a process opened by proc_open\"\n    ],\n    \"property_exists\": [\n        \"bool property_exists(mixed object_or_class, string property_name)\",\n        \"Checks if the object or class has a property\"\n    ],\n    \"pspell_add_to_personal\": [\n        \"bool pspell_add_to_personal(int pspell, string word)\",\n        \"Adds a word to a personal list\"\n    ],\n    \"pspell_add_to_session\": [\n        \"bool pspell_add_to_session(int pspell, string word)\",\n        \"Adds a word to the current session\"\n    ],\n    \"pspell_check\": [\n        \"bool pspell_check(int pspell, string word)\",\n        \"Returns true if word is valid\"\n    ],\n    \"pspell_clear_session\": [\n        \"bool pspell_clear_session(int pspell)\",\n        \"Clears the current session\"\n    ],\n    \"pspell_config_create\": [\n        \"int pspell_config_create(string language [, string spelling [, string jargon [, string encoding]]])\",\n        \"Create a new config to be used later to create a manager\"\n    ],\n    \"pspell_config_data_dir\": [\n        \"bool pspell_config_data_dir(int conf, string directory)\",\n        \"location of language data files\"\n    ],\n    \"pspell_config_dict_dir\": [\n        \"bool pspell_config_dict_dir(int conf, string directory)\",\n        \"location of the main word list\"\n    ],\n    \"pspell_config_ignore\": [\n        \"bool pspell_config_ignore(int conf, int ignore)\",\n        \"Ignore words <= n chars\"\n    ],\n    \"pspell_config_mode\": [\n        \"bool pspell_config_mode(int conf, long mode)\",\n        \"Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS)\"\n    ],\n    \"pspell_config_personal\": [\n        \"bool pspell_config_personal(int conf, string personal)\",\n        \"Use a personal dictionary for this config\"\n    ],\n    \"pspell_config_repl\": [\n        \"bool pspell_config_repl(int conf, string repl)\",\n        \"Use a personal dictionary with replacement pairs for this config\"\n    ],\n    \"pspell_config_runtogether\": [\n        \"bool pspell_config_runtogether(int conf, bool runtogether)\",\n        \"Consider run-together words as valid components\"\n    ],\n    \"pspell_config_save_repl\": [\n        \"bool pspell_config_save_repl(int conf, bool save)\",\n        \"Save replacement pairs when personal list is saved for this config\"\n    ],\n    \"pspell_new\": [\n        \"int pspell_new(string language [, string spelling [, string jargon [, string encoding [, int mode]]]])\",\n        \"Load a dictionary\"\n    ],\n    \"pspell_new_config\": [\n        \"int pspell_new_config(int config)\",\n        \"Load a dictionary based on the given config\"\n    ],\n    \"pspell_new_personal\": [\n        \"int pspell_new_personal(string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]])\",\n        \"Load a dictionary with a personal wordlist\"\n    ],\n    \"pspell_save_wordlist\": [\n        \"bool pspell_save_wordlist(int pspell)\",\n        \"Saves the current (personal) wordlist\"\n    ],\n    \"pspell_store_replacement\": [\n        \"bool pspell_store_replacement(int pspell, string misspell, string correct)\",\n        \"Notify the dictionary of a user-selected replacement\"\n    ],\n    \"pspell_suggest\": [\n        \"array pspell_suggest(int pspell, string word)\",\n        \"Returns array of suggestions\"\n    ],\n    \"putenv\": [\n        \"bool putenv(string setting)\",\n        \"Set the value of an environment variable\"\n    ],\n    \"quoted_printable_decode\": [\n        \"string quoted_printable_decode(string str)\",\n        \"Convert a quoted-printable string to an 8 bit string\"\n    ],\n    \"quoted_printable_encode\": [\n        \"string quoted_printable_encode(string str)\",\n        \"\"\n    ],\n    \"quotemeta\": [\n        \"string quotemeta(string str)\",\n        \"Quotes meta characters\"\n    ],\n    \"rad2deg\": [\n        \"float rad2deg(float number)\",\n        \"Converts the radian number to the equivalent number in degrees\"\n    ],\n    \"rand\": [\n        \"int rand([int min, int max])\",\n        \"Returns a random number\"\n    ],\n    \"range\": [\n        \"array range(mixed low, mixed high[, int step])\",\n        \"Create an array containing the range of integers or characters from low to high (inclusive)\"\n    ],\n    \"rawurldecode\": [\n        \"string rawurldecode(string str)\",\n        \"Decodes URL-encodes string\"\n    ],\n    \"rawurlencode\": [\n        \"string rawurlencode(string str)\",\n        \"URL-encodes string\"\n    ],\n    \"readdir\": [\n        \"string readdir([resource dir_handle])\",\n        \"Read directory entry from dir_handle\"\n    ],\n    \"readfile\": [\n        \"int readfile(string filename [, bool use_include_path[, resource context]])\",\n        \"Output a file or a URL\"\n    ],\n    \"readgzfile\": [\n        \"int readgzfile(string filename [, int use_include_path])\",\n        \"Output a .gz-file\"\n    ],\n    \"readline\": [\n        \"string readline([string prompt])\",\n        \"Reads a line\"\n    ],\n    \"readline_add_history\": [\n        \"bool readline_add_history(string prompt)\",\n        \"Adds a line to the history\"\n    ],\n    \"readline_callback_handler_install\": [\n        \"void readline_callback_handler_install(string prompt, mixed callback)\",\n        \"Initializes the readline callback interface and terminal, prints the prompt and returns immediately\"\n    ],\n    \"readline_callback_handler_remove\": [\n        \"bool readline_callback_handler_remove()\",\n        \"Removes a previously installed callback handler and restores terminal settings\"\n    ],\n    \"readline_callback_read_char\": [\n        \"void readline_callback_read_char()\",\n        \"Informs the readline callback interface that a character is ready for input\"\n    ],\n    \"readline_clear_history\": [\n        \"bool readline_clear_history()\",\n        \"Clears the history\"\n    ],\n    \"readline_completion_function\": [\n        \"bool readline_completion_function(string funcname)\",\n        \"Readline completion function?\"\n    ],\n    \"readline_info\": [\n        \"mixed readline_info([string varname [, string newvalue]])\",\n        \"Gets/sets various internal readline variables.\"\n    ],\n    \"readline_list_history\": [\n        \"array readline_list_history()\",\n        \"Lists the history\"\n    ],\n    \"readline_on_new_line\": [\n        \"void readline_on_new_line()\",\n        \"Inform readline that the cursor has moved to a new line\"\n    ],\n    \"readline_read_history\": [\n        \"bool readline_read_history([string filename])\",\n        \"Reads the history\"\n    ],\n    \"readline_redisplay\": [\n        \"void readline_redisplay()\",\n        \"Ask readline to redraw the display\"\n    ],\n    \"readline_write_history\": [\n        \"bool readline_write_history([string filename])\",\n        \"Writes the history\"\n    ],\n    \"readlink\": [\n        \"string readlink(string filename)\",\n        \"Return the target of a symbolic link\"\n    ],\n    \"realpath\": [\n        \"string realpath(string path)\",\n        \"Return the resolved path\"\n    ],\n    \"realpath_cache_get\": [\n        \"bool realpath_cache_get()\",\n        \"Get current size of realpath cache\"\n    ],\n    \"realpath_cache_size\": [\n        \"bool realpath_cache_size()\",\n        \"Get current size of realpath cache\"\n    ],\n    \"recode_file\": [\n        \"bool recode_file(string request, resource input, resource output)\",\n        \"Recode file input into file output according to request\"\n    ],\n    \"recode_string\": [\n        \"string recode_string(string request, string str)\",\n        \"Recode string str according to request string\"\n    ],\n    \"register_shutdown_function\": [\n        \"void register_shutdown_function(string function_name)\",\n        \"Register a user-level function to be called on request termination\"\n    ],\n    \"register_tick_function\": [\n        \"bool register_tick_function(string function_name [, mixed arg [, mixed ... ]])\",\n        \"Registers a tick callback function\"\n    ],\n    \"rename\": [\n        \"bool rename(string old_name, string new_name[, resource context])\",\n        \"Rename a file\"\n    ],\n    \"require\": [\n        \"bool require(string path)\",\n        \"Includes and evaluates the specified file, erroring if the file cannot be included\"\n    ],\n    \"require_once\": [\n        \"bool require_once(string path)\",\n        \"Includes and evaluates the specified file, erroring if the file cannot be included\"\n    ],\n    \"reset\": [\n        \"mixed reset(array array_arg)\",\n        \"Set array argument's internal pointer to the first element and return it\"\n    ],\n    \"restore_error_handler\": [\n        \"void restore_error_handler()\",\n        \"Restores the previously defined error handler function\"\n    ],\n    \"restore_exception_handler\": [\n        \"void restore_exception_handler()\",\n        \"Restores the previously defined exception handler function\"\n    ],\n    \"restore_include_path\": [\n        \"void restore_include_path()\",\n        \"Restore the value of the include_path configuration option\"\n    ],\n    \"rewind\": [\n        \"bool rewind(resource fp)\",\n        \"Rewind the position of a file pointer\"\n    ],\n    \"rewinddir\": [\n        \"void rewinddir([resource dir_handle])\",\n        \"Rewind dir_handle back to the start\"\n    ],\n    \"rmdir\": [\n        \"bool rmdir(string dirname[, resource context])\",\n        \"Remove a directory\"\n    ],\n    \"round\": [\n        \"float round(float number [, int precision [, int mode]])\",\n        \"Returns the number rounded to specified precision\"\n    ],\n    \"rsort\": [\n        \"bool rsort(array &array_arg [, int sort_flags])\",\n        \"Sort an array in reverse order\"\n    ],\n    \"rtrim\": [\n        \"string rtrim(string str [, string character_mask])\",\n        \"Removes trailing whitespace\"\n    ],\n    \"scandir\": [\n        \"array scandir(string dir [, int sorting_order [, resource context]])\",\n        \"List files & directories inside the specified path\"\n    ],\n    \"sem_acquire\": [\n        \"bool sem_acquire(resource id)\",\n        \"Acquires the semaphore with the given id, blocking if necessary\"\n    ],\n    \"sem_get\": [\n        \"resource sem_get(int key [, int max_acquire [, int perm [, int auto_release]])\",\n        \"Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously\"\n    ],\n    \"sem_release\": [\n        \"bool sem_release(resource id)\",\n        \"Releases the semaphore with the given id\"\n    ],\n    \"sem_remove\": [\n        \"bool sem_remove(resource id)\",\n        \"Removes semaphore from Unix systems\"\n    ],\n    \"serialize\": [\n        \"string serialize(mixed variable)\",\n        \"Returns a string representation of variable (which can later be unserialized)\"\n    ],\n    \"session_cache_expire\": [\n        \"int session_cache_expire([int new_cache_expire])\",\n        \"Return the current cache expire. If new_cache_expire is given, the current cache_expire is replaced with new_cache_expire\"\n    ],\n    \"session_cache_limiter\": [\n        \"string session_cache_limiter([string new_cache_limiter])\",\n        \"Return the current cache limiter. If new_cache_limited is given, the current cache_limiter is replaced with new_cache_limiter\"\n    ],\n    \"session_decode\": [\n        \"bool session_decode(string data)\",\n        \"Deserializes data and reinitializes the variables\"\n    ],\n    \"session_destroy\": [\n        \"bool session_destroy()\",\n        \"Destroy the current session and all data associated with it\"\n    ],\n    \"session_encode\": [\n        \"string session_encode()\",\n        \"Serializes the current setup and returns the serialized representation\"\n    ],\n    \"session_get_cookie_params\": [\n        \"array session_get_cookie_params()\",\n        \"Return the session cookie parameters\"\n    ],\n    \"session_id\": [\n        \"string session_id([string newid])\",\n        \"Return the current session id. If newid is given, the session id is replaced with newid\"\n    ],\n    \"session_is_registered\": [\n        \"bool session_is_registered(string varname)\",\n        \"Checks if a variable is registered in session\"\n    ],\n    \"session_module_name\": [\n        \"string session_module_name([string newname])\",\n        \"Return the current module name used for accessing session data. If newname is given, the module name is replaced with newname\"\n    ],\n    \"session_name\": [\n        \"string session_name([string newname])\",\n        \"Return the current session name. If newname is given, the session name is replaced with newname\"\n    ],\n    \"session_regenerate_id\": [\n        \"bool session_regenerate_id([bool delete_old_session])\",\n        \"Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session.\"\n    ],\n    \"session_register\": [\n        \"bool session_register(mixed var_names [, mixed ...])\",\n        \"Adds varname(s) to the list of variables which are freezed at the session end\"\n    ],\n    \"session_save_path\": [\n        \"string session_save_path([string newname])\",\n        \"Return the current save path passed to module_name. If newname is given, the save path is replaced with newname\"\n    ],\n    \"session_set_cookie_params\": [\n        \"void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]])\",\n        \"Set session cookie parameters\"\n    ],\n    \"session_set_save_handler\": [\n        \"void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)\",\n        \"Sets user-level functions\"\n    ],\n    \"session_start\": [\n        \"bool session_start()\",\n        \"Begin session - reinitializes freezed variables, registers browsers etc\"\n    ],\n    \"session_unregister\": [\n        \"bool session_unregister(string varname)\",\n        \"Removes varname from the list of variables which are freezed at the session end\"\n    ],\n    \"session_unset\": [\n        \"void session_unset()\",\n        \"Unset all registered variables\"\n    ],\n    \"session_write_close\": [\n        \"void session_write_close()\",\n        \"Write session data and end session\"\n    ],\n    \"set_error_handler\": [\n        \"string set_error_handler(string error_handler [, int error_types])\",\n        \"Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error\"\n    ],\n    \"set_exception_handler\": [\n        \"string set_exception_handler(callable exception_handler)\",\n        \"Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error\"\n    ],\n    \"set_include_path\": [\n        \"string set_include_path(string new_include_path)\",\n        \"Sets the include_path configuration option\"\n    ],\n    \"set_magic_quotes_runtime\": [\n        \"bool set_magic_quotes_runtime(int new_setting)\",\n        \"Set the current active configuration setting of magic_quotes_runtime and return previous\"\n    ],\n    \"set_time_limit\": [\n        \"bool set_time_limit(int seconds)\",\n        \"Sets the maximum time a script can run\"\n    ],\n    \"setcookie\": [\n        \"bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])\",\n        \"Send a cookie\"\n    ],\n    \"setlocale\": [\n        \"string setlocale(mixed category, string locale [, string ...])\",\n        \"Set locale information\"\n    ],\n    \"setrawcookie\": [\n        \"bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])\",\n        \"Send a cookie with no url encoding of the value\"\n    ],\n    \"settype\": [\n        \"bool settype(mixed var, string type)\",\n        \"Set the type of the variable\"\n    ],\n    \"sha1\": [\n        \"string sha1(string str [, bool raw_output])\",\n        \"Calculate the sha1 hash of a string\"\n    ],\n    \"sha1_file\": [\n        \"string sha1_file(string filename [, bool raw_output])\",\n        \"Calculate the sha1 hash of given filename\"\n    ],\n    \"shell_exec\": [\n        \"string shell_exec(string cmd)\",\n        \"Execute command via shell and return complete output as string\"\n    ],\n    \"shm_attach\": [\n        \"int shm_attach(int key [, int memsize [, int perm]])\",\n        \"Creates or open a shared memory segment\"\n    ],\n    \"shm_detach\": [\n        \"bool shm_detach(resource shm_identifier)\",\n        \"Disconnects from shared memory segment\"\n    ],\n    \"shm_get_var\": [\n        \"mixed shm_get_var(resource id, int variable_key)\",\n        \"Returns a variable from shared memory\"\n    ],\n    \"shm_has_var\": [\n        \"bool shm_has_var(resource id, int variable_key)\",\n        \"Checks whether a specific entry exists\"\n    ],\n    \"shm_put_var\": [\n        \"bool shm_put_var(resource shm_identifier, int variable_key, mixed variable)\",\n        \"Inserts or updates a variable in shared memory\"\n    ],\n    \"shm_remove\": [\n        \"bool shm_remove(resource shm_identifier)\",\n        \"Removes shared memory from Unix systems\"\n    ],\n    \"shm_remove_var\": [\n        \"bool shm_remove_var(resource id, int variable_key)\",\n        \"Removes variable from shared memory\"\n    ],\n    \"shmop_close\": [\n        \"void shmop_close(int shmid)\",\n        \"closes a shared memory segment\"\n    ],\n    \"shmop_delete\": [\n        \"bool shmop_delete(int shmid)\",\n        \"mark segment for deletion\"\n    ],\n    \"shmop_open\": [\n        \"int shmop_open(int key, string flags, int mode, int size)\",\n        \"gets and attaches a shared memory segment\"\n    ],\n    \"shmop_read\": [\n        \"string shmop_read(int shmid, int start, int count)\",\n        \"reads from a shm segment\"\n    ],\n    \"shmop_size\": [\n        \"int shmop_size(int shmid)\",\n        \"returns the shm size\"\n    ],\n    \"shmop_write\": [\n        \"int shmop_write(int shmid, string data, int offset)\",\n        \"writes to a shared memory segment\"\n    ],\n    \"shuffle\": [\n        \"bool shuffle(array array_arg)\",\n        \"Randomly shuffle the contents of an array\"\n    ],\n    \"similar_text\": [\n        \"int similar_text(string str1, string str2 [, float percent])\",\n        \"Calculates the similarity between two strings\"\n    ],\n    \"simplexml_import_dom\": [\n        \"simplemxml_element simplexml_import_dom(domNode node [, string class_name])\",\n        \"Get a simplexml_element object from dom to allow for processing\"\n    ],\n    \"simplexml_load_file\": [\n        \"simplemxml_element simplexml_load_file(string filename [, string class_name [, int options [, string ns [, bool is_prefix]]]])\",\n        \"Load a filename and return a simplexml_element object to allow for processing\"\n    ],\n    \"simplexml_load_string\": [\n        \"simplemxml_element simplexml_load_string(string data [, string class_name [, int options [, string ns [, bool is_prefix]]]])\",\n        \"Load a string and return a simplexml_element object to allow for processing\"\n    ],\n    \"sin\": [\n        \"float sin(float number)\",\n        \"Returns the sine of the number in radians\"\n    ],\n    \"sinh\": [\n        \"float sinh(float number)\",\n        \"Returns the hyperbolic sine of the number, defined as (exp(number) - exp(-number))/2\"\n    ],\n    \"sleep\": [\n        \"void sleep(int seconds)\",\n        \"Delay for a given number of seconds\"\n    ],\n    \"smfi_addheader\": [\n        \"bool smfi_addheader(string headerf, string headerv)\",\n        \"Adds a header to the current message.\"\n    ],\n    \"smfi_addrcpt\": [\n        \"bool smfi_addrcpt(string rcpt)\",\n        \"Add a recipient to the message envelope.\"\n    ],\n    \"smfi_chgheader\": [\n        \"bool smfi_chgheader(string headerf, string headerv)\",\n        \"Changes a header's value for the current message.\"\n    ],\n    \"smfi_delrcpt\": [\n        \"bool smfi_delrcpt(string rcpt)\",\n        \"Removes the named recipient from the current message's envelope.\"\n    ],\n    \"smfi_getsymval\": [\n        \"string smfi_getsymval(string macro)\",\n        \"Returns the value of the given macro or NULL if the macro is not defined.\"\n    ],\n    \"smfi_replacebody\": [\n        \"bool smfi_replacebody(string body)\",\n        \"Replaces the body of the current message. If called more than once,    subsequent calls result in data being appended to the new body.\"\n    ],\n    \"smfi_setflags\": [\n        \"void smfi_setflags(long flags)\",\n        \"Sets the flags describing the actions the filter may take.\"\n    ],\n    \"smfi_setreply\": [\n        \"bool smfi_setreply(string rcode, string xcode, string message)\",\n        \"Directly set the SMTP error reply code for this connection.    This code will be used on subsequent error replies resulting from actions taken by this filter.\"\n    ],\n    \"smfi_settimeout\": [\n        \"void smfi_settimeout(long timeout)\",\n        \"Sets the number of seconds libmilter will wait for an MTA connection before timing out a socket.\"\n    ],\n    \"snmp2_get\": [\n        \"string snmp2_get(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Fetch a SNMP object\"\n    ],\n    \"snmp2_getnext\": [\n        \"string snmp2_getnext(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Fetch a SNMP object\"\n    ],\n    \"snmp2_real_walk\": [\n        \"array snmp2_real_walk(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Return all objects including their respective object id withing the specified one\"\n    ],\n    \"snmp2_set\": [\n        \"int snmp2_set(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])\",\n        \"Set the value of a SNMP object\"\n    ],\n    \"snmp2_walk\": [\n        \"array snmp2_walk(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Return all objects under the specified object id\"\n    ],\n    \"snmp3_get\": [\n        \"int snmp3_get(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])\",\n        \"Fetch the value of a SNMP object\"\n    ],\n    \"snmp3_getnext\": [\n        \"int snmp3_getnext(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])\",\n        \"Fetch the value of a SNMP object\"\n    ],\n    \"snmp3_real_walk\": [\n        \"int snmp3_real_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])\",\n        \"Fetch the value of a SNMP object\"\n    ],\n    \"snmp3_set\": [\n        \"int snmp3_set(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id, string type, mixed value [, int timeout [, int retries]])\",\n        \"Fetch the value of a SNMP object\"\n    ],\n    \"snmp3_walk\": [\n        \"int snmp3_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])\",\n        \"Fetch the value of a SNMP object\"\n    ],\n    \"snmp_get_quick_print\": [\n        \"bool snmp_get_quick_print()\",\n        \"Return the current status of quick_print\"\n    ],\n    \"snmp_get_valueretrieval\": [\n        \"int snmp_get_valueretrieval()\",\n        \"Return the method how the SNMP values will be returned\"\n    ],\n    \"snmp_read_mib\": [\n        \"int snmp_read_mib(string filename)\",\n        \"Reads and parses a MIB file into the active MIB tree.\"\n    ],\n    \"snmp_set_enum_print\": [\n        \"void snmp_set_enum_print(int enum_print)\",\n        \"Return all values that are enums with their enum value instead of the raw integer\"\n    ],\n    \"snmp_set_oid_output_format\": [\n        \"void snmp_set_oid_output_format(int oid_format)\",\n        \"Set the OID output format.\"\n    ],\n    \"snmp_set_quick_print\": [\n        \"void snmp_set_quick_print(int quick_print)\",\n        \"Return all objects including their respective object id withing the specified one\"\n    ],\n    \"snmp_set_valueretrieval\": [\n        \"void snmp_set_valueretrieval(int method)\",\n        \"Specify the method how the SNMP values will be returned\"\n    ],\n    \"snmpget\": [\n        \"string snmpget(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Fetch a SNMP object\"\n    ],\n    \"snmpgetnext\": [\n        \"string snmpgetnext(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Fetch a SNMP object\"\n    ],\n    \"snmprealwalk\": [\n        \"array snmprealwalk(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Return all objects including their respective object id withing the specified one\"\n    ],\n    \"snmpset\": [\n        \"int snmpset(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])\",\n        \"Set the value of a SNMP object\"\n    ],\n    \"snmpwalk\": [\n        \"array snmpwalk(string host, string community, string object_id [, int timeout [, int retries]])\",\n        \"Return all objects under the specified object id\"\n    ],\n    \"socket_accept\": [\n        \"resource socket_accept(resource socket)\",\n        \"Accepts a connection on the listening socket fd\"\n    ],\n    \"socket_bind\": [\n        \"bool socket_bind(resource socket, string addr [, int port])\",\n        \"Binds an open socket to a listening port, port is only specified in AF_INET family.\"\n    ],\n    \"socket_clear_error\": [\n        \"void socket_clear_error([resource socket])\",\n        \"Clears the error on the socket or the last error code.\"\n    ],\n    \"socket_close\": [\n        \"void socket_close(resource socket)\",\n        \"Closes a file descriptor\"\n    ],\n    \"socket_connect\": [\n        \"bool socket_connect(resource socket, string addr [, int port])\",\n        \"Opens a connection to addr:port on the socket specified by socket\"\n    ],\n    \"socket_create\": [\n        \"resource socket_create(int domain, int type, int protocol)\",\n        \"Creates an endpoint for communication in the domain specified by domain, of type specified by type\"\n    ],\n    \"socket_create_listen\": [\n        \"resource socket_create_listen(int port[, int backlog])\",\n        \"Opens a socket on port to accept connections\"\n    ],\n    \"socket_create_pair\": [\n        \"bool socket_create_pair(int domain, int type, int protocol, array &fd)\",\n        \"Creates a pair of indistinguishable sockets and stores them in fds.\"\n    ],\n    \"socket_get_option\": [\n        \"mixed socket_get_option(resource socket, int level, int optname)\",\n        \"Gets socket options for the socket\"\n    ],\n    \"socket_getpeername\": [\n        \"bool socket_getpeername(resource socket, string &addr[, int &port])\",\n        \"Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type.\"\n    ],\n    \"socket_getsockname\": [\n        \"bool socket_getsockname(resource socket, string &addr[, int &port])\",\n        \"Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type.\"\n    ],\n    \"socket_last_error\": [\n        \"int socket_last_error([resource socket])\",\n        \"Returns the last socket error (either the last used or the provided socket resource)\"\n    ],\n    \"socket_listen\": [\n        \"bool socket_listen(resource socket[, int backlog])\",\n        \"Sets the maximum number of connections allowed to be waited for on the socket specified by fd\"\n    ],\n    \"socket_read\": [\n        \"string socket_read(resource socket, int length [, int type])\",\n        \"Reads a maximum of length bytes from socket\"\n    ],\n    \"socket_recv\": [\n        \"int socket_recv(resource socket, string &buf, int len, int flags)\",\n        \"Receives data from a connected socket\"\n    ],\n    \"socket_recvfrom\": [\n        \"int socket_recvfrom(resource socket, string &buf, int len, int flags, string &name [, int &port])\",\n        \"Receives data from a socket, connected or not\"\n    ],\n    \"socket_select\": [\n        \"int socket_select(array &read_fds, array &write_fds, array &except_fds, int tv_sec[, int tv_usec])\",\n        \"Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec\"\n    ],\n    \"socket_send\": [\n        \"int socket_send(resource socket, string buf, int len, int flags)\",\n        \"Sends data to a connected socket\"\n    ],\n    \"socket_sendto\": [\n        \"int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port])\",\n        \"Sends a message to a socket, whether it is connected or not\"\n    ],\n    \"socket_set_block\": [\n        \"bool socket_set_block(resource socket)\",\n        \"Sets blocking mode on a socket resource\"\n    ],\n    \"socket_set_nonblock\": [\n        \"bool socket_set_nonblock(resource socket)\",\n        \"Sets nonblocking mode on a socket resource\"\n    ],\n    \"socket_set_option\": [\n        \"bool socket_set_option(resource socket, int level, int optname, int|array optval)\",\n        \"Sets socket options for the socket\"\n    ],\n    \"socket_shutdown\": [\n        \"bool socket_shutdown(resource socket[, int how])\",\n        \"Shuts down a socket for receiving, sending, or both.\"\n    ],\n    \"socket_strerror\": [\n        \"string socket_strerror(int errno)\",\n        \"Returns a string describing an error\"\n    ],\n    \"socket_write\": [\n        \"int socket_write(resource socket, string buf[, int length])\",\n        \"Writes the buffer to the socket resource, length is optional\"\n    ],\n    \"solid_fetch_prev\": [\n        \"bool solid_fetch_prev(resource result_id)\",\n        \"\"\n    ],\n    \"sort\": [\n        \"bool sort(array &array_arg [, int sort_flags])\",\n        \"Sort an array\"\n    ],\n    \"soundex\": [\n        \"string soundex(string str)\",\n        \"Calculate the soundex key of a string\"\n    ],\n    \"spl_autoload\": [\n        \"void spl_autoload(string class_name [, string file_extensions])\",\n        \"Default implementation for __autoload()\"\n    ],\n    \"spl_autoload_call\": [\n        \"void spl_autoload_call(string class_name)\",\n        \"Try all registerd autoload function to load the requested class\"\n    ],\n    \"spl_autoload_extensions\": [\n        \"string spl_autoload_extensions([string file_extensions])\",\n        \"Register and return default file extensions for spl_autoload\"\n    ],\n    \"spl_autoload_functions\": [\n        \"false|array spl_autoload_functions()\",\n        \"Return all registered __autoload() functionns\"\n    ],\n    \"spl_autoload_register\": [\n        \"bool spl_autoload_register([mixed autoload_function = \\\"spl_autoload\\\" [, throw = true [, prepend]]])\",\n        \"Register given function as __autoload() implementation\"\n    ],\n    \"spl_autoload_unregister\": [\n        \"bool spl_autoload_unregister(mixed autoload_function)\",\n        \"Unregister given function as __autoload() implementation\"\n    ],\n    \"spl_classes\": [\n        \"array spl_classes()\",\n        \"Return an array containing the names of all clsses and interfaces defined in SPL\"\n    ],\n    \"spl_object_hash\": [\n        \"string spl_object_hash(object obj)\",\n        \"Return hash id for given object\"\n    ],\n    \"split\": [\n        \"array split(string pattern, string string [, int limit])\",\n        \"Split string into array by regular expression\"\n    ],\n    \"spliti\": [\n        \"array spliti(string pattern, string string [, int limit])\",\n        \"Split string into array by regular expression case-insensitive\"\n    ],\n    \"sprintf\": [\n        \"string sprintf(string format [, mixed arg1 [, mixed ...]])\",\n        \"Return a formatted string\"\n    ],\n    \"sql_regcase\": [\n        \"string sql_regcase(string string)\",\n        \"Make regular expression for case insensitive match\"\n    ],\n    \"sqlite_array_query\": [\n        \"array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])\",\n        \"Executes a query against a given database and returns an array of arrays.\"\n    ],\n    \"sqlite_busy_timeout\": [\n        \"void sqlite_busy_timeout(resource db, int ms)\",\n        \"Set busy timeout duration. If ms <= 0, all busy handlers are disabled.\"\n    ],\n    \"sqlite_changes\": [\n        \"int sqlite_changes(resource db)\",\n        \"Returns the number of rows that were changed by the most recent SQL statement.\"\n    ],\n    \"sqlite_close\": [\n        \"void sqlite_close(resource db)\",\n        \"Closes an open sqlite database.\"\n    ],\n    \"sqlite_column\": [\n        \"mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])\",\n        \"Fetches a column from the current row of a result set.\"\n    ],\n    \"sqlite_create_aggregate\": [\n        \"bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])\",\n        \"Registers an aggregate function for queries.\"\n    ],\n    \"sqlite_create_function\": [\n        \"bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])\",\n        \"Registers a \\\"regular\\\" function for queries.\"\n    ],\n    \"sqlite_current\": [\n        \"array sqlite_current(resource result [, int result_type [, bool decode_binary]])\",\n        \"Fetches the current row from a result set as an array.\"\n    ],\n    \"sqlite_error_string\": [\n        \"string sqlite_error_string(int error_code)\",\n        \"Returns the textual description of an error code.\"\n    ],\n    \"sqlite_escape_string\": [\n        \"string sqlite_escape_string(string item)\",\n        \"Escapes a string for use as a query parameter.\"\n    ],\n    \"sqlite_exec\": [\n        \"bool sqlite_exec(string query, resource db[, string &error_message])\",\n        \"Executes a result-less query against a given database\"\n    ],\n    \"sqlite_factory\": [\n        \"object sqlite_factory(string filename [, int mode [, string &error_message]])\",\n        \"Opens a SQLite database and creates an object for it. Will create the database if it does not exist.\"\n    ],\n    \"sqlite_fetch_all\": [\n        \"array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])\",\n        \"Fetches all rows from a result set as an array of arrays.\"\n    ],\n    \"sqlite_fetch_array\": [\n        \"array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])\",\n        \"Fetches the next row from a result set as an array.\"\n    ],\n    \"sqlite_fetch_column_types\": [\n        \"resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])\",\n        \"Return an array of column types from a particular table.\"\n    ],\n    \"sqlite_fetch_object\": [\n        \"object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])\",\n        \"Fetches the next row from a result set as an object.\"\n    ],\n    \"sqlite_fetch_single\": [\n        \"string sqlite_fetch_single(resource result [, bool decode_binary])\",\n        \"Fetches the first column of a result set as a string.\"\n    ],\n    \"sqlite_field_name\": [\n        \"string sqlite_field_name(resource result, int field_index)\",\n        \"Returns the name of a particular field of a result set.\"\n    ],\n    \"sqlite_has_prev\": [\n        \"bool sqlite_has_prev(resource result)\",\n        \"* Returns whether a previous row is available.\"\n    ],\n    \"sqlite_key\": [\n        \"int sqlite_key(resource result)\",\n        \"Return the current row index of a buffered result.\"\n    ],\n    \"sqlite_last_error\": [\n        \"int sqlite_last_error(resource db)\",\n        \"Returns the error code of the last error for a database.\"\n    ],\n    \"sqlite_last_insert_rowid\": [\n        \"int sqlite_last_insert_rowid(resource db)\",\n        \"Returns the rowid of the most recently inserted row.\"\n    ],\n    \"sqlite_libencoding\": [\n        \"string sqlite_libencoding()\",\n        \"Returns the encoding (iso8859 or UTF-8) of the linked SQLite library.\"\n    ],\n    \"sqlite_libversion\": [\n        \"string sqlite_libversion()\",\n        \"Returns the version of the linked SQLite library.\"\n    ],\n    \"sqlite_next\": [\n        \"bool sqlite_next(resource result)\",\n        \"Seek to the next row number of a result set.\"\n    ],\n    \"sqlite_num_fields\": [\n        \"int sqlite_num_fields(resource result)\",\n        \"Returns the number of fields in a result set.\"\n    ],\n    \"sqlite_num_rows\": [\n        \"int sqlite_num_rows(resource result)\",\n        \"Returns the number of rows in a buffered result set.\"\n    ],\n    \"sqlite_open\": [\n        \"resource sqlite_open(string filename [, int mode [, string &error_message]])\",\n        \"Opens a SQLite database. Will create the database if it does not exist.\"\n    ],\n    \"sqlite_popen\": [\n        \"resource sqlite_popen(string filename [, int mode [, string &error_message]])\",\n        \"Opens a persistent handle to a SQLite database. Will create the database if it does not exist.\"\n    ],\n    \"sqlite_prev\": [\n        \"bool sqlite_prev(resource result)\",\n        \"* Seek to the previous row number of a result set.\"\n    ],\n    \"sqlite_query\": [\n        \"resource sqlite_query(string query, resource db [, int result_type [, string &error_message]])\",\n        \"Executes a query against a given database and returns a result handle.\"\n    ],\n    \"sqlite_rewind\": [\n        \"bool sqlite_rewind(resource result)\",\n        \"Seek to the first row number of a buffered result set.\"\n    ],\n    \"sqlite_seek\": [\n        \"bool sqlite_seek(resource result, int row)\",\n        \"Seek to a particular row number of a buffered result set.\"\n    ],\n    \"sqlite_single_query\": [\n        \"array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])\",\n        \"Executes a query and returns either an array for one single column or the value of the first row.\"\n    ],\n    \"sqlite_udf_decode_binary\": [\n        \"string sqlite_udf_decode_binary(string data)\",\n        \"Decode binary encoding on a string parameter passed to an UDF.\"\n    ],\n    \"sqlite_udf_encode_binary\": [\n        \"string sqlite_udf_encode_binary(string data)\",\n        \"Apply binary encoding (if required) to a string to return from an UDF.\"\n    ],\n    \"sqlite_unbuffered_query\": [\n        \"resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &error_message]])\",\n        \"Executes a query that does not prefetch and buffer all data.\"\n    ],\n    \"sqlite_valid\": [\n        \"bool sqlite_valid(resource result)\",\n        \"Returns whether more rows are available.\"\n    ],\n    \"sqrt\": [\n        \"float sqrt(float number)\",\n        \"Returns the square root of the number\"\n    ],\n    \"srand\": [\n        \"void srand([int seed])\",\n        \"Seeds random number generator\"\n    ],\n    \"sscanf\": [\n        \"mixed sscanf(string str, string format [, string ...])\",\n        \"Implements an ANSI C compatible sscanf\"\n    ],\n    \"stat\": [\n        \"array stat(string filename)\",\n        \"Give information about a file\"\n    ],\n    \"str_getcsv\": [\n        \"array str_getcsv(string input[, string delimiter[, string enclosure[, string escape]]])\",\n        \"Parse a CSV string into an array\"\n    ],\n    \"str_ireplace\": [\n        \"mixed str_ireplace(mixed search, mixed replace, mixed subject [, int &replace_count])\",\n        \"Replaces all occurrences of search in haystack with replace / case-insensitive\"\n    ],\n    \"str_pad\": [\n        \"string str_pad(string input, int pad_length [, string pad_string [, int pad_type]])\",\n        \"Returns input string padded on the left or right to specified length with pad_string\"\n    ],\n    \"str_repeat\": [\n        \"string str_repeat(string input, int mult)\",\n        \"Returns the input string repeat mult times\"\n    ],\n    \"str_replace\": [\n        \"mixed str_replace(mixed search, mixed replace, mixed subject [, int &replace_count])\",\n        \"Replaces all occurrences of search in haystack with replace\"\n    ],\n    \"str_rot13\": [\n        \"string str_rot13(string str)\",\n        \"Perform the rot13 transform on a string\"\n    ],\n    \"str_shuffle\": [\n        \"void str_shuffle(string str)\",\n        \"Shuffles string. One permutation of all possible is created\"\n    ],\n    \"str_split\": [\n        \"array str_split(string str [, int split_length])\",\n        \"Convert a string to an array. If split_length is specified, break the string down into chunks each split_length characters long.\"\n    ],\n    \"str_word_count\": [\n        \"mixed str_word_count(string str, [int format [, string charlist]])\",\n        \"Counts the number of words inside a string. If format of 1 is specified,     then the function will return an array containing all the words     found inside the string. If format of 2 is specified, then the function     will return an associated array where the position of the word is the key     and the word itself is the value.          For the purpose of this function, 'word' is defined as a locale dependent     string containing alphabetic characters, which also may contain, but not start     with \\\"'\\\" and \\\"-\\\" characters.\"\n    ],\n    \"strcasecmp\": [\n        \"int strcasecmp(string str1, string str2)\",\n        \"Binary safe case-insensitive string comparison\"\n    ],\n    \"strchr\": [\n        \"string strchr(string haystack, string needle)\",\n        \"An alias for strstr\"\n    ],\n    \"strcmp\": [\n        \"int strcmp(string str1, string str2)\",\n        \"Binary safe string comparison\"\n    ],\n    \"strcoll\": [\n        \"int strcoll(string str1, string str2)\",\n        \"Compares two strings using the current locale\"\n    ],\n    \"strcspn\": [\n        \"int strcspn(string str, string mask [, start [, len]])\",\n        \"Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars)\"\n    ],\n    \"stream_bucket_append\": [\n        \"void stream_bucket_append(resource brigade, resource bucket)\",\n        \"Append bucket to brigade\"\n    ],\n    \"stream_bucket_make_writeable\": [\n        \"object stream_bucket_make_writeable(resource brigade)\",\n        \"Return a bucket object from the brigade for operating on\"\n    ],\n    \"stream_bucket_new\": [\n        \"resource stream_bucket_new(resource stream, string buffer)\",\n        \"Create a new bucket for use on the current stream\"\n    ],\n    \"stream_bucket_prepend\": [\n        \"void stream_bucket_prepend(resource brigade, resource bucket)\",\n        \"Prepend bucket to brigade\"\n    ],\n    \"stream_context_create\": [\n        \"resource stream_context_create([array options[, array params]])\",\n        \"Create a file context and optionally set parameters\"\n    ],\n    \"stream_context_get_default\": [\n        \"resource stream_context_get_default([array options])\",\n        \"Get a handle on the default file/stream context and optionally set parameters\"\n    ],\n    \"stream_context_get_options\": [\n        \"array stream_context_get_options(resource context|resource stream)\",\n        \"Retrieve options for a stream/wrapper/context\"\n    ],\n    \"stream_context_get_params\": [\n        \"array stream_context_get_params(resource context|resource stream)\",\n        \"Get parameters of a file context\"\n    ],\n    \"stream_context_set_default\": [\n        \"resource stream_context_set_default(array options)\",\n        \"Set default file/stream context, returns the context as a resource\"\n    ],\n    \"stream_context_set_option\": [\n        \"bool stream_context_set_option(resource context|resource stream, string wrappername, string optionname, mixed value)\",\n        \"Set an option for a wrapper\"\n    ],\n    \"stream_context_set_params\": [\n        \"bool stream_context_set_params(resource context|resource stream, array options)\",\n        \"Set parameters for a file context\"\n    ],\n    \"stream_copy_to_stream\": [\n        \"long stream_copy_to_stream(resource source, resource dest [, long maxlen [, long pos]])\",\n        \"Reads up to maxlen bytes from source stream and writes them to dest stream.\"\n    ],\n    \"stream_filter_append\": [\n        \"resource stream_filter_append(resource stream, string filtername[, int read_write[, string filterparams]])\",\n        \"Append a filter to a stream\"\n    ],\n    \"stream_filter_prepend\": [\n        \"resource stream_filter_prepend(resource stream, string filtername[, int read_write[, string filterparams]])\",\n        \"Prepend a filter to a stream\"\n    ],\n    \"stream_filter_register\": [\n        \"bool stream_filter_register(string filtername, string classname)\",\n        \"Registers a custom filter handler class\"\n    ],\n    \"stream_filter_remove\": [\n        \"bool stream_filter_remove(resource stream_filter)\",\n        \"Flushes any data in the filter's internal buffer, removes it from the chain, and frees the resource\"\n    ],\n    \"stream_get_contents\": [\n        \"string stream_get_contents(resource source [, long maxlen [, long offset]])\",\n        \"Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string.\"\n    ],\n    \"stream_get_filters\": [\n        \"array stream_get_filters()\",\n        \"Returns a list of registered filters\"\n    ],\n    \"stream_get_line\": [\n        \"string stream_get_line(resource stream, int maxlen [, string ending])\",\n        \"Read up to maxlen bytes from a stream or until the ending string is found\"\n    ],\n    \"stream_get_meta_data\": [\n        \"array stream_get_meta_data(resource fp)\",\n        \"Retrieves header/meta data from streams/file pointers\"\n    ],\n    \"stream_get_transports\": [\n        \"array stream_get_transports()\",\n        \"Retrieves list of registered socket transports\"\n    ],\n    \"stream_get_wrappers\": [\n        \"array stream_get_wrappers()\",\n        \"Retrieves list of registered stream wrappers\"\n    ],\n    \"stream_is_local\": [\n        \"bool stream_is_local(resource stream|string url)\",\n        \"\"\n    ],\n    \"stream_resolve_include_path\": [\n        \"string stream_resolve_include_path(string filename)\",\n        \"Determine what file will be opened by calls to fopen() with a relative path\"\n    ],\n    \"stream_select\": [\n        \"int stream_select(array &read_streams, array &write_streams, array &except_streams, int tv_sec[, int tv_usec])\",\n        \"Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec\"\n    ],\n    \"stream_set_blocking\": [\n        \"bool stream_set_blocking(resource socket, int mode)\",\n        \"Set blocking/non-blocking mode on a socket or stream\"\n    ],\n    \"stream_set_timeout\": [\n        \"bool stream_set_timeout(resource stream, int seconds [, int microseconds])\",\n        \"Set timeout on stream read to seconds + microseonds\"\n    ],\n    \"stream_set_write_buffer\": [\n        \"int stream_set_write_buffer(resource fp, int buffer)\",\n        \"Set file write buffer\"\n    ],\n    \"stream_socket_accept\": [\n        \"resource stream_socket_accept(resource serverstream, [ double timeout [, string &peername ]])\",\n        \"Accept a client connection from a server socket\"\n    ],\n    \"stream_socket_client\": [\n        \"resource stream_socket_client(string remoteaddress [, long &errcode [, string &errstring [, double timeout [, long flags [, resource context]]]]])\",\n        \"Open a client connection to a remote address\"\n    ],\n    \"stream_socket_enable_crypto\": [\n        \"int stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind [, resource sessionstream]])\",\n        \"Enable or disable a specific kind of crypto on the stream\"\n    ],\n    \"stream_socket_get_name\": [\n        \"string stream_socket_get_name(resource stream, bool want_peer)\",\n        \"Returns either the locally bound or remote name for a socket stream\"\n    ],\n    \"stream_socket_pair\": [\n        \"array stream_socket_pair(int domain, int type, int protocol)\",\n        \"Creates a pair of connected, indistinguishable socket streams\"\n    ],\n    \"stream_socket_recvfrom\": [\n        \"string stream_socket_recvfrom(resource stream, long amount [, long flags [, string &remote_addr]])\",\n        \"Receives data from a socket stream\"\n    ],\n    \"stream_socket_sendto\": [\n        \"long stream_socket_sendto(resouce stream, string data [, long flags [, string target_addr]])\",\n        \"Send data to a socket stream.  If target_addr is specified it must be in dotted quad (or [ipv6]) format\"\n    ],\n    \"stream_socket_server\": [\n        \"resource stream_socket_server(string localaddress [, long &errcode [, string &errstring [, long flags [, resource context]]]])\",\n        \"Create a server socket bound to localaddress\"\n    ],\n    \"stream_socket_shutdown\": [\n        \"int stream_socket_shutdown(resource stream, int how)\",\n        \"causes all or part of a full-duplex connection on the socket associated  with stream to be shut down.  If how is SHUT_RD,  further receptions will  be disallowed. If how is SHUT_WR, further transmissions will be disallowed.  If how is SHUT_RDWR,  further  receptions and transmissions will be  disallowed.\"\n    ],\n    \"stream_supports_lock\": [\n        \"bool stream_supports_lock(resource stream)\",\n        \"Tells whether the stream supports locking through flock().\"\n    ],\n    \"stream_wrapper_register\": [\n        \"bool stream_wrapper_register(string protocol, string classname[, integer flags])\",\n        \"Registers a custom URL protocol handler class\"\n    ],\n    \"stream_wrapper_restore\": [\n        \"bool stream_wrapper_restore(string protocol)\",\n        \"Restore the original protocol handler, overriding if necessary\"\n    ],\n    \"stream_wrapper_unregister\": [\n        \"bool stream_wrapper_unregister(string protocol)\",\n        \"Unregister a wrapper for the life of the current request.\"\n    ],\n    \"strftime\": [\n        \"string strftime(string format [, int timestamp])\",\n        \"Format a local time/date according to locale settings\"\n    ],\n    \"strip_tags\": [\n        \"string strip_tags(string str [, string allowable_tags])\",\n        \"Strips HTML and PHP tags from a string\"\n    ],\n    \"stripcslashes\": [\n        \"string stripcslashes(string str)\",\n        \"Strips backslashes from a string. Uses C-style conventions\"\n    ],\n    \"stripos\": [\n        \"int stripos(string haystack, string needle [, int offset])\",\n        \"Finds position of first occurrence of a string within another, case insensitive\"\n    ],\n    \"stripslashes\": [\n        \"string stripslashes(string str)\",\n        \"Strips backslashes from a string\"\n    ],\n    \"stristr\": [\n        \"string stristr(string haystack, string needle[, bool part])\",\n        \"Finds first occurrence of a string within another, case insensitive\"\n    ],\n    \"strlen\": [\n        \"int strlen(string str)\",\n        \"Get string length\"\n    ],\n    \"strnatcasecmp\": [\n        \"int strnatcasecmp(string s1, string s2)\",\n        \"Returns the result of case-insensitive string comparison using 'natural' algorithm\"\n    ],\n    \"strnatcmp\": [\n        \"int strnatcmp(string s1, string s2)\",\n        \"Returns the result of string comparison using 'natural' algorithm\"\n    ],\n    \"strncasecmp\": [\n        \"int strncasecmp(string str1, string str2, int len)\",\n        \"Binary safe string comparison\"\n    ],\n    \"strncmp\": [\n        \"int strncmp(string str1, string str2, int len)\",\n        \"Binary safe string comparison\"\n    ],\n    \"strpbrk\": [\n        \"array strpbrk(string haystack, string char_list)\",\n        \"Search a string for any of a set of characters\"\n    ],\n    \"strpos\": [\n        \"int strpos(string haystack, string needle [, int offset])\",\n        \"Finds position of first occurrence of a string within another\"\n    ],\n    \"strptime\": [\n        \"string strptime(string timestamp, string format)\",\n        \"Parse a time/date generated with strftime()\"\n    ],\n    \"strrchr\": [\n        \"string strrchr(string haystack, string needle)\",\n        \"Finds the last occurrence of a character in a string within another\"\n    ],\n    \"strrev\": [\n        \"string strrev(string str)\",\n        \"Reverse a string\"\n    ],\n    \"strripos\": [\n        \"int strripos(string haystack, string needle [, int offset])\",\n        \"Finds position of last occurrence of a string within another string\"\n    ],\n    \"strrpos\": [\n        \"int strrpos(string haystack, string needle [, int offset])\",\n        \"Finds position of last occurrence of a string within another string\"\n    ],\n    \"strspn\": [\n        \"int strspn(string str, string mask [, start [, len]])\",\n        \"Finds length of initial segment consisting entirely of characters found in mask. If start or/and length is provided works like strspn(substr($s,$start,$len),$good_chars)\"\n    ],\n    \"strstr\": [\n        \"string strstr(string haystack, string needle[, bool part])\",\n        \"Finds first occurrence of a string within another\"\n    ],\n    \"strtok\": [\n        \"string strtok([string str,] string token)\",\n        \"Tokenize a string\"\n    ],\n    \"strtolower\": [\n        \"string strtolower(string str)\",\n        \"Makes a string lowercase\"\n    ],\n    \"strtotime\": [\n        \"int strtotime(string time [, int now ])\",\n        \"Convert string representation of date and time to a timestamp\"\n    ],\n    \"strtoupper\": [\n        \"string strtoupper(string str)\",\n        \"Makes a string uppercase\"\n    ],\n    \"strtr\": [\n        \"string strtr(string str, string from[, string to])\",\n        \"Translates characters in str using given translation tables\"\n    ],\n    \"strval\": [\n        \"string strval(mixed var)\",\n        \"Get the string value of a variable\"\n    ],\n    \"substr\": [\n        \"string substr(string str, int start [, int length])\",\n        \"Returns part of a string\"\n    ],\n    \"substr_compare\": [\n        \"int substr_compare(string main_str, string str, int offset [, int length [, bool case_sensitivity]])\",\n        \"Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters\"\n    ],\n    \"substr_count\": [\n        \"int substr_count(string haystack, string needle [, int offset [, int length]])\",\n        \"Returns the number of times a substring occurs in the string\"\n    ],\n    \"substr_replace\": [\n        \"mixed substr_replace(mixed str, mixed repl, mixed start [, mixed length])\",\n        \"Replaces part of a string with another string\"\n    ],\n    \"sybase_affected_rows\": [\n        \"int sybase_affected_rows([resource link_id])\",\n        \"Get number of affected rows in last query\"\n    ],\n    \"sybase_close\": [\n        \"bool sybase_close([resource link_id])\",\n        \"Close Sybase connection\"\n    ],\n    \"sybase_connect\": [\n        \"int sybase_connect([string host [, string user [, string password [, string charset [, string appname [, bool new]]]]]])\",\n        \"Open Sybase server connection\"\n    ],\n    \"sybase_data_seek\": [\n        \"bool sybase_data_seek(resource result, int offset)\",\n        \"Move internal row pointer\"\n    ],\n    \"sybase_deadlock_retry_count\": [\n        \"void sybase_deadlock_retry_count(int retry_count)\",\n        \"Sets deadlock retry count\"\n    ],\n    \"sybase_fetch_array\": [\n        \"array sybase_fetch_array(resource result)\",\n        \"Fetch row as array\"\n    ],\n    \"sybase_fetch_assoc\": [\n        \"array sybase_fetch_assoc(resource result)\",\n        \"Fetch row as array without numberic indices\"\n    ],\n    \"sybase_fetch_field\": [\n        \"object sybase_fetch_field(resource result [, int offset])\",\n        \"Get field information\"\n    ],\n    \"sybase_fetch_object\": [\n        \"object sybase_fetch_object(resource result [, mixed object])\",\n        \"Fetch row as object\"\n    ],\n    \"sybase_fetch_row\": [\n        \"array sybase_fetch_row(resource result)\",\n        \"Get row as enumerated array\"\n    ],\n    \"sybase_field_seek\": [\n        \"bool sybase_field_seek(resource result, int offset)\",\n        \"Set field offset\"\n    ],\n    \"sybase_free_result\": [\n        \"bool sybase_free_result(resource result)\",\n        \"Free result memory\"\n    ],\n    \"sybase_get_last_message\": [\n        \"string sybase_get_last_message()\",\n        \"Returns the last message from server (over min_message_severity)\"\n    ],\n    \"sybase_min_client_severity\": [\n        \"void sybase_min_client_severity(int severity)\",\n        \"Sets minimum client severity\"\n    ],\n    \"sybase_min_server_severity\": [\n        \"void sybase_min_server_severity(int severity)\",\n        \"Sets minimum server severity\"\n    ],\n    \"sybase_num_fields\": [\n        \"int sybase_num_fields(resource result)\",\n        \"Get number of fields in result\"\n    ],\n    \"sybase_num_rows\": [\n        \"int sybase_num_rows(resource result)\",\n        \"Get number of rows in result\"\n    ],\n    \"sybase_pconnect\": [\n        \"int sybase_pconnect([string host [, string user [, string password [, string charset [, string appname]]]]])\",\n        \"Open persistent Sybase connection\"\n    ],\n    \"sybase_query\": [\n        \"int sybase_query(string query [, resource link_id])\",\n        \"Send Sybase query\"\n    ],\n    \"sybase_result\": [\n        \"string sybase_result(resource result, int row, mixed field)\",\n        \"Get result data\"\n    ],\n    \"sybase_select_db\": [\n        \"bool sybase_select_db(string database [, resource link_id])\",\n        \"Select Sybase database\"\n    ],\n    \"sybase_set_message_handler\": [\n        \"bool sybase_set_message_handler(mixed error_func [, resource connection])\",\n        \"Set the error handler, to be called when a server message is raised.     If error_func is NULL the handler will be deleted\"\n    ],\n    \"sybase_unbuffered_query\": [\n        \"int sybase_unbuffered_query(string query [, resource link_id])\",\n        \"Send Sybase query\"\n    ],\n    \"symlink\": [\n        \"int symlink(string target, string link)\",\n        \"Create a symbolic link\"\n    ],\n    \"sys_get_temp_dir\": [\n        \"string sys_get_temp_dir()\",\n        \"Returns directory path used for temporary files\"\n    ],\n    \"sys_getloadavg\": [\n        \"array sys_getloadavg()\",\n        \"\"\n    ],\n    \"syslog\": [\n        \"bool syslog(int priority, string message)\",\n        \"Generate a system log message\"\n    ],\n    \"system\": [\n        \"int system(string command [, int &return_value])\",\n        \"Execute an external program and display output\"\n    ],\n    \"tan\": [\n        \"float tan(float number)\",\n        \"Returns the tangent of the number in radians\"\n    ],\n    \"tanh\": [\n        \"float tanh(float number)\",\n        \"Returns the hyperbolic tangent of the number, defined as sinh(number)/cosh(number)\"\n    ],\n    \"tempnam\": [\n        \"string tempnam(string dir, string prefix)\",\n        \"Create a unique filename in a directory\"\n    ],\n    \"textdomain\": [\n        \"string textdomain(string domain)\",\n        \"Set the textdomain to \\\"domain\\\". Returns the current domain\"\n    ],\n    \"tidy_access_count\": [\n        \"int tidy_access_count()\",\n        \"Returns the Number of Tidy accessibility warnings encountered for specified document.\"\n    ],\n    \"tidy_clean_repair\": [\n        \"bool tidy_clean_repair()\",\n        \"Execute configured cleanup and repair operations on parsed markup\"\n    ],\n    \"tidy_config_count\": [\n        \"int tidy_config_count()\",\n        \"Returns the Number of Tidy configuration errors encountered for specified document.\"\n    ],\n    \"tidy_diagnose\": [\n        \"bool tidy_diagnose()\",\n        \"Run configured diagnostics on parsed and repaired markup.\"\n    ],\n    \"tidy_error_count\": [\n        \"int tidy_error_count()\",\n        \"Returns the Number of Tidy errors encountered for specified document.\"\n    ],\n    \"tidy_get_body\": [\n        \"TidyNode tidy_get_body(resource tidy)\",\n        \"Returns a TidyNode Object starting from the <BODY> tag of the tidy parse tree\"\n    ],\n    \"tidy_get_config\": [\n        \"array tidy_get_config()\",\n        \"Get current Tidy configuarion\"\n    ],\n    \"tidy_get_error_buffer\": [\n        \"string tidy_get_error_buffer([bool detailed])\",\n        \"Return warnings and errors which occured parsing the specified document\"\n    ],\n    \"tidy_get_head\": [\n        \"TidyNode tidy_get_head()\",\n        \"Returns a TidyNode Object starting from the <HEAD> tag of the tidy parse tree\"\n    ],\n    \"tidy_get_html\": [\n        \"TidyNode tidy_get_html()\",\n        \"Returns a TidyNode Object starting from the <HTML> tag of the tidy parse tree\"\n    ],\n    \"tidy_get_html_ver\": [\n        \"int tidy_get_html_ver()\",\n        \"Get the Detected HTML version for the specified document.\"\n    ],\n    \"tidy_get_opt_doc\": [\n        \"string tidy_get_opt_doc(tidy resource, string optname)\",\n        \"Returns the documentation for the given option name\"\n    ],\n    \"tidy_get_output\": [\n        \"string tidy_get_output()\",\n        \"Return a string representing the parsed tidy markup\"\n    ],\n    \"tidy_get_release\": [\n        \"string tidy_get_release()\",\n        \"Get release date (version) for Tidy library\"\n    ],\n    \"tidy_get_root\": [\n        \"TidyNode tidy_get_root()\",\n        \"Returns a TidyNode Object representing the root of the tidy parse tree\"\n    ],\n    \"tidy_get_status\": [\n        \"int tidy_get_status()\",\n        \"Get status of specfied document.\"\n    ],\n    \"tidy_getopt\": [\n        \"mixed tidy_getopt(string option)\",\n        \"Returns the value of the specified configuration option for the tidy document.\"\n    ],\n    \"tidy_is_xhtml\": [\n        \"bool tidy_is_xhtml()\",\n        \"Indicates if the document is a XHTML document.\"\n    ],\n    \"tidy_is_xml\": [\n        \"bool tidy_is_xml()\",\n        \"Indicates if the document is a generic (non HTML/XHTML) XML document.\"\n    ],\n    \"tidy_parse_file\": [\n        \"bool tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])\",\n        \"Parse markup in file or URI\"\n    ],\n    \"tidy_parse_string\": [\n        \"bool tidy_parse_string(string input [, mixed config_options [, string encoding]])\",\n        \"Parse a document stored in a string\"\n    ],\n    \"tidy_repair_file\": [\n        \"bool tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])\",\n        \"Repair a file using an optionally provided configuration file\"\n    ],\n    \"tidy_repair_string\": [\n        \"bool tidy_repair_string(string data [, mixed config_file [, string encoding]])\",\n        \"Repair a string using an optionally provided configuration file\"\n    ],\n    \"tidy_warning_count\": [\n        \"int tidy_warning_count()\",\n        \"Returns the Number of Tidy warnings encountered for specified document.\"\n    ],\n    \"time\": [\n        \"int time()\",\n        \"Return current UNIX timestamp\"\n    ],\n    \"time_nanosleep\": [\n        \"mixed time_nanosleep(long seconds, long nanoseconds)\",\n        \"Delay for a number of seconds and nano seconds\"\n    ],\n    \"time_sleep_until\": [\n        \"mixed time_sleep_until(float timestamp)\",\n        \"Make the script sleep until the specified time\"\n    ],\n    \"timezone_abbreviations_list\": [\n        \"array timezone_abbreviations_list()\",\n        \"Returns associative array containing dst, offset and the timezone name\"\n    ],\n    \"timezone_identifiers_list\": [\n        \"array timezone_identifiers_list([long what[, string country]])\",\n        \"Returns numerically index array with all timezone identifiers.\"\n    ],\n    \"timezone_location_get\": [\n        \"array timezone_location_get()\",\n        \"Returns location information for a timezone, including country code, latitude/longitude and comments\"\n    ],\n    \"timezone_name_from_abbr\": [\n        \"string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])\",\n        \"Returns the timezone name from abbrevation\"\n    ],\n    \"timezone_name_get\": [\n        \"string timezone_name_get(DateTimeZone object)\",\n        \"Returns the name of the timezone.\"\n    ],\n    \"timezone_offset_get\": [\n        \"long timezone_offset_get(DateTimeZone object, DateTime object)\",\n        \"Returns the timezone offset.\"\n    ],\n    \"timezone_open\": [\n        \"DateTimeZone timezone_open(string timezone)\",\n        \"Returns new DateTimeZone object\"\n    ],\n    \"timezone_transitions_get\": [\n        \"array timezone_transitions_get(DateTimeZone object [, long timestamp_begin [, long timestamp_end ]])\",\n        \"Returns numerically indexed array containing associative array for all transitions in the specified range for the timezone.\"\n    ],\n    \"timezone_version_get\": [\n        \"array timezone_version_get()\",\n        \"Returns the Olson database version number.\"\n    ],\n    \"tmpfile\": [\n        \"resource tmpfile()\",\n        \"Create a temporary file that will be deleted automatically after use\"\n    ],\n    \"token_get_all\": [\n        \"array token_get_all(string source)\",\n        \"\"\n    ],\n    \"token_name\": [\n        \"string token_name(int type)\",\n        \"\"\n    ],\n    \"touch\": [\n        \"bool touch(string filename [, int time [, int atime]])\",\n        \"Set modification time of file\"\n    ],\n    \"trigger_error\": [\n        \"void trigger_error(string messsage [, int error_type])\",\n        \"Generates a user-level error/warning/notice message\"\n    ],\n    \"trim\": [\n        \"string trim(string str [, string character_mask])\",\n        \"Strips whitespace from the beginning and end of a string\"\n    ],\n    \"uasort\": [\n        \"bool uasort(array array_arg, string cmp_function)\",\n        \"Sort an array with a user-defined comparison function and maintain index association\"\n    ],\n    \"ucfirst\": [\n        \"string ucfirst(string str)\",\n        \"Make a string's first character lowercase\"\n    ],\n    \"ucwords\": [\n        \"string ucwords(string str)\",\n        \"Uppercase the first character of every word in a string\"\n    ],\n    \"uksort\": [\n        \"bool uksort(array array_arg, string cmp_function)\",\n        \"Sort an array by keys using a user-defined comparison function\"\n    ],\n    \"umask\": [\n        \"int umask([int mask])\",\n        \"Return or change the umask\"\n    ],\n    \"uniqid\": [\n        \"string uniqid([string prefix [, bool more_entropy]])\",\n        \"Generates a unique ID\"\n    ],\n    \"unixtojd\": [\n        \"int unixtojd([int timestamp])\",\n        \"Convert UNIX timestamp to Julian Day\"\n    ],\n    \"unlink\": [\n        \"bool unlink(string filename[, context context])\",\n        \"Delete a file\"\n    ],\n    \"unpack\": [\n        \"array unpack(string format, string input)\",\n        \"Unpack binary string into named array elements according to format argument\"\n    ],\n    \"unregister_tick_function\": [\n        \"void unregister_tick_function(string function_name)\",\n        \"Unregisters a tick callback function\"\n    ],\n    \"unserialize\": [\n        \"mixed unserialize(string variable_representation)\",\n        \"Takes a string representation of variable and recreates it\"\n    ],\n    \"unset\": [\n        \"void unset(mixed var [, mixed var])\",\n        \"Unset a given variable\"\n    ],\n    \"urldecode\": [\n        \"string urldecode(string str)\",\n        \"Decodes URL-encoded string\"\n    ],\n    \"urlencode\": [\n        \"string urlencode(string str)\",\n        \"URL-encodes string\"\n    ],\n    \"usleep\": [\n        \"void usleep(int micro_seconds)\",\n        \"Delay for a given number of micro seconds\"\n    ],\n    \"usort\": [\n        \"bool usort(array array_arg, string cmp_function)\",\n        \"Sort an array by values using a user-defined comparison function\"\n    ],\n    \"utf8_decode\": [\n        \"string utf8_decode(string data)\",\n        \"Converts a UTF-8 encoded string to ISO-8859-1\"\n    ],\n    \"utf8_encode\": [\n        \"string utf8_encode(string data)\",\n        \"Encodes an ISO-8859-1 string to UTF-8\"\n    ],\n    \"var_dump\": [\n        \"void var_dump(mixed var)\",\n        \"Dumps a string representation of variable to output\"\n    ],\n    \"var_export\": [\n        \"string var_export(mixed var [, bool return])\",\n        \"Outputs or returns a string representation of a variable\"\n    ],\n    \"variant_abs\": [\n        \"mixed variant_abs(mixed left)\",\n        \"Returns the absolute value of a variant\"\n    ],\n    \"variant_add\": [\n        \"mixed variant_add(mixed left, mixed right)\",\n        \"\\\"Adds\\\" two variant values together and returns the result\"\n    ],\n    \"variant_and\": [\n        \"mixed variant_and(mixed left, mixed right)\",\n        \"performs a bitwise AND operation between two variants and returns the result\"\n    ],\n    \"variant_cast\": [\n        \"object variant_cast(object variant, int type)\",\n        \"Convert a variant into a new variant object of another type\"\n    ],\n    \"variant_cat\": [\n        \"mixed variant_cat(mixed left, mixed right)\",\n        \"concatenates two variant values together and returns the result\"\n    ],\n    \"variant_cmp\": [\n        \"int variant_cmp(mixed left, mixed right [, int lcid [, int flags]])\",\n        \"Compares two variants\"\n    ],\n    \"variant_date_from_timestamp\": [\n        \"object variant_date_from_timestamp(int timestamp)\",\n        \"Returns a variant date representation of a unix timestamp\"\n    ],\n    \"variant_date_to_timestamp\": [\n        \"int variant_date_to_timestamp(object variant)\",\n        \"Converts a variant date/time value to unix timestamp\"\n    ],\n    \"variant_div\": [\n        \"mixed variant_div(mixed left, mixed right)\",\n        \"Returns the result from dividing two variants\"\n    ],\n    \"variant_eqv\": [\n        \"mixed variant_eqv(mixed left, mixed right)\",\n        \"Performs a bitwise equivalence on two variants\"\n    ],\n    \"variant_fix\": [\n        \"mixed variant_fix(mixed left)\",\n        \"Returns the integer part ? of a variant\"\n    ],\n    \"variant_get_type\": [\n        \"int variant_get_type(object variant)\",\n        \"Returns the VT_XXX type code for a variant\"\n    ],\n    \"variant_idiv\": [\n        \"mixed variant_idiv(mixed left, mixed right)\",\n        \"Converts variants to integers and then returns the result from dividing them\"\n    ],\n    \"variant_imp\": [\n        \"mixed variant_imp(mixed left, mixed right)\",\n        \"Performs a bitwise implication on two variants\"\n    ],\n    \"variant_int\": [\n        \"mixed variant_int(mixed left)\",\n        \"Returns the integer portion of a variant\"\n    ],\n    \"variant_mod\": [\n        \"mixed variant_mod(mixed left, mixed right)\",\n        \"Divides two variants and returns only the remainder\"\n    ],\n    \"variant_mul\": [\n        \"mixed variant_mul(mixed left, mixed right)\",\n        \"multiplies the values of the two variants and returns the result\"\n    ],\n    \"variant_neg\": [\n        \"mixed variant_neg(mixed left)\",\n        \"Performs logical negation on a variant\"\n    ],\n    \"variant_not\": [\n        \"mixed variant_not(mixed left)\",\n        \"Performs bitwise not negation on a variant\"\n    ],\n    \"variant_or\": [\n        \"mixed variant_or(mixed left, mixed right)\",\n        \"Performs a logical disjunction on two variants\"\n    ],\n    \"variant_pow\": [\n        \"mixed variant_pow(mixed left, mixed right)\",\n        \"Returns the result of performing the power function with two variants\"\n    ],\n    \"variant_round\": [\n        \"mixed variant_round(mixed left, int decimals)\",\n        \"Rounds a variant to the specified number of decimal places\"\n    ],\n    \"variant_set\": [\n        \"void variant_set(object variant, mixed value)\",\n        \"Assigns a new value for a variant object\"\n    ],\n    \"variant_set_type\": [\n        \"void variant_set_type(object variant, int type)\",\n        \"Convert a variant into another type.  Variant is modified \\\"in-place\\\"\"\n    ],\n    \"variant_sub\": [\n        \"mixed variant_sub(mixed left, mixed right)\",\n        \"subtracts the value of the right variant from the left variant value and returns the result\"\n    ],\n    \"variant_xor\": [\n        \"mixed variant_xor(mixed left, mixed right)\",\n        \"Performs a logical exclusion on two variants\"\n    ],\n    \"version_compare\": [\n        \"int version_compare(string ver1, string ver2 [, string oper])\",\n        \"Compares two \\\"PHP-standardized\\\" version number strings\"\n    ],\n    \"vfprintf\": [\n        \"int vfprintf(resource stream, string format, array args)\",\n        \"Output a formatted string into a stream\"\n    ],\n    \"virtual\": [\n        \"bool virtual(string filename)\",\n        \"Perform an Apache sub-request\"\n    ],\n    \"vprintf\": [\n        \"int vprintf(string format, array args)\",\n        \"Output a formatted string\"\n    ],\n    \"vsprintf\": [\n        \"string vsprintf(string format, array args)\",\n        \"Return a formatted string\"\n    ],\n    \"wddx_add_vars\": [\n        \"int wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])\",\n        \"Serializes given variables and adds them to packet given by packet_id\"\n    ],\n    \"wddx_deserialize\": [\n        \"mixed wddx_deserialize(mixed packet)\",\n        \"Deserializes given packet and returns a PHP value\"\n    ],\n    \"wddx_packet_end\": [\n        \"string wddx_packet_end(resource packet_id)\",\n        \"Ends specified WDDX packet and returns the string containing the packet\"\n    ],\n    \"wddx_packet_start\": [\n        \"resource wddx_packet_start([string comment])\",\n        \"Starts a WDDX packet with optional comment and returns the packet id\"\n    ],\n    \"wddx_serialize_value\": [\n        \"string wddx_serialize_value(mixed var [, string comment])\",\n        \"Creates a new packet and serializes the given value\"\n    ],\n    \"wddx_serialize_vars\": [\n        \"string wddx_serialize_vars(mixed var_name [, mixed ...])\",\n        \"Creates a new packet and serializes given variables into a struct\"\n    ],\n    \"wordwrap\": [\n        \"string wordwrap(string str [, int width [, string break [, bool cut]]])\",\n        \"Wraps buffer to selected number of characters using string break char\"\n    ],\n    \"xml_error_string\": [\n        \"string xml_error_string(int code)\",\n        \"Get XML parser error string\"\n    ],\n    \"xml_get_current_byte_index\": [\n        \"int xml_get_current_byte_index(resource parser)\",\n        \"Get current byte index for an XML parser\"\n    ],\n    \"xml_get_current_column_number\": [\n        \"int xml_get_current_column_number(resource parser)\",\n        \"Get current column number for an XML parser\"\n    ],\n    \"xml_get_current_line_number\": [\n        \"int xml_get_current_line_number(resource parser)\",\n        \"Get current line number for an XML parser\"\n    ],\n    \"xml_get_error_code\": [\n        \"int xml_get_error_code(resource parser)\",\n        \"Get XML parser error code\"\n    ],\n    \"xml_parse\": [\n        \"int xml_parse(resource parser, string data [, int isFinal])\",\n        \"Start parsing an XML document\"\n    ],\n    \"xml_parse_into_struct\": [\n        \"int xml_parse_into_struct(resource parser, string data, array &values [, array &index ])\",\n        \"Parsing a XML document\"\n    ],\n    \"xml_parser_create\": [\n        \"resource xml_parser_create([string encoding])\",\n        \"Create an XML parser\"\n    ],\n    \"xml_parser_create_ns\": [\n        \"resource xml_parser_create_ns([string encoding [, string sep]])\",\n        \"Create an XML parser\"\n    ],\n    \"xml_parser_free\": [\n        \"int xml_parser_free(resource parser)\",\n        \"Free an XML parser\"\n    ],\n    \"xml_parser_get_option\": [\n        \"int xml_parser_get_option(resource parser, int option)\",\n        \"Get options from an XML parser\"\n    ],\n    \"xml_parser_set_option\": [\n        \"int xml_parser_set_option(resource parser, int option, mixed value)\",\n        \"Set options in an XML parser\"\n    ],\n    \"xml_set_character_data_handler\": [\n        \"int xml_set_character_data_handler(resource parser, string hdl)\",\n        \"Set up character data handler\"\n    ],\n    \"xml_set_default_handler\": [\n        \"int xml_set_default_handler(resource parser, string hdl)\",\n        \"Set up default handler\"\n    ],\n    \"xml_set_element_handler\": [\n        \"int xml_set_element_handler(resource parser, string shdl, string ehdl)\",\n        \"Set up start and end element handlers\"\n    ],\n    \"xml_set_end_namespace_decl_handler\": [\n        \"int xml_set_end_namespace_decl_handler(resource parser, string hdl)\",\n        \"Set up character data handler\"\n    ],\n    \"xml_set_external_entity_ref_handler\": [\n        \"int xml_set_external_entity_ref_handler(resource parser, string hdl)\",\n        \"Set up external entity reference handler\"\n    ],\n    \"xml_set_notation_decl_handler\": [\n        \"int xml_set_notation_decl_handler(resource parser, string hdl)\",\n        \"Set up notation declaration handler\"\n    ],\n    \"xml_set_object\": [\n        \"int xml_set_object(resource parser, object &obj)\",\n        \"Set up object which should be used for callbacks\"\n    ],\n    \"xml_set_processing_instruction_handler\": [\n        \"int xml_set_processing_instruction_handler(resource parser, string hdl)\",\n        \"Set up processing instruction (PI) handler\"\n    ],\n    \"xml_set_start_namespace_decl_handler\": [\n        \"int xml_set_start_namespace_decl_handler(resource parser, string hdl)\",\n        \"Set up character data handler\"\n    ],\n    \"xml_set_unparsed_entity_decl_handler\": [\n        \"int xml_set_unparsed_entity_decl_handler(resource parser, string hdl)\",\n        \"Set up unparsed entity declaration handler\"\n    ],\n    \"xmlrpc_decode\": [\n        \"array xmlrpc_decode(string xml [, string encoding])\",\n        \"Decodes XML into native PHP types\"\n    ],\n    \"xmlrpc_decode_request\": [\n        \"array xmlrpc_decode_request(string xml, string& method [, string encoding])\",\n        \"Decodes XML into native PHP types\"\n    ],\n    \"xmlrpc_encode\": [\n        \"string xmlrpc_encode(mixed value)\",\n        \"Generates XML for a PHP value\"\n    ],\n    \"xmlrpc_encode_request\": [\n        \"string xmlrpc_encode_request(string method, mixed params [, array output_options])\",\n        \"Generates XML for a method request\"\n    ],\n    \"xmlrpc_get_type\": [\n        \"string xmlrpc_get_type(mixed value)\",\n        \"Gets xmlrpc type for a PHP value. Especially useful for base64 and datetime strings\"\n    ],\n    \"xmlrpc_is_fault\": [\n        \"bool xmlrpc_is_fault(array)\",\n        \"Determines if an array value represents an XMLRPC fault.\"\n    ],\n    \"xmlrpc_parse_method_descriptions\": [\n        \"array xmlrpc_parse_method_descriptions(string xml)\",\n        \"Decodes XML into a list of method descriptions\"\n    ],\n    \"xmlrpc_server_add_introspection_data\": [\n        \"int xmlrpc_server_add_introspection_data(resource server, array desc)\",\n        \"Adds introspection documentation\"\n    ],\n    \"xmlrpc_server_call_method\": [\n        \"mixed xmlrpc_server_call_method(resource server, string xml, mixed user_data [, array output_options])\",\n        \"Parses XML requests and call methods\"\n    ],\n    \"xmlrpc_server_create\": [\n        \"resource xmlrpc_server_create()\",\n        \"Creates an xmlrpc server\"\n    ],\n    \"xmlrpc_server_destroy\": [\n        \"int xmlrpc_server_destroy(resource server)\",\n        \"Destroys server resources\"\n    ],\n    \"xmlrpc_server_register_introspection_callback\": [\n        \"bool xmlrpc_server_register_introspection_callback(resource server, string function)\",\n        \"Register a PHP function to generate documentation\"\n    ],\n    \"xmlrpc_server_register_method\": [\n        \"bool xmlrpc_server_register_method(resource server, string method_name, string function)\",\n        \"Register a PHP function to handle method matching method_name\"\n    ],\n    \"xmlrpc_set_type\": [\n        \"bool xmlrpc_set_type(string value, string type)\",\n        \"Sets xmlrpc type, base64 or datetime, for a PHP string value\"\n    ],\n    \"xmlwriter_end_attribute\": [\n        \"bool xmlwriter_end_attribute(resource xmlwriter)\",\n        \"End attribute - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_cdata\": [\n        \"bool xmlwriter_end_cdata(resource xmlwriter)\",\n        \"End current CDATA - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_comment\": [\n        \"bool xmlwriter_end_comment(resource xmlwriter)\",\n        \"Create end comment - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_document\": [\n        \"bool xmlwriter_end_document(resource xmlwriter)\",\n        \"End current document - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_dtd\": [\n        \"bool xmlwriter_end_dtd(resource xmlwriter)\",\n        \"End current DTD - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_dtd_attlist\": [\n        \"bool xmlwriter_end_dtd_attlist(resource xmlwriter)\",\n        \"End current DTD AttList - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_dtd_element\": [\n        \"bool xmlwriter_end_dtd_element(resource xmlwriter)\",\n        \"End current DTD element - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_dtd_entity\": [\n        \"bool xmlwriter_end_dtd_entity(resource xmlwriter)\",\n        \"End current DTD Entity - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_element\": [\n        \"bool xmlwriter_end_element(resource xmlwriter)\",\n        \"End current element - returns FALSE on error\"\n    ],\n    \"xmlwriter_end_pi\": [\n        \"bool xmlwriter_end_pi(resource xmlwriter)\",\n        \"End current PI - returns FALSE on error\"\n    ],\n    \"xmlwriter_flush\": [\n        \"mixed xmlwriter_flush(resource xmlwriter [,bool empty])\",\n        \"Output current buffer\"\n    ],\n    \"xmlwriter_full_end_element\": [\n        \"bool xmlwriter_full_end_element(resource xmlwriter)\",\n        \"End current element - returns FALSE on error\"\n    ],\n    \"xmlwriter_open_memory\": [\n        \"resource xmlwriter_open_memory()\",\n        \"Create new xmlwriter using memory for string output\"\n    ],\n    \"xmlwriter_open_uri\": [\n        \"resource xmlwriter_open_uri(resource xmlwriter, string source)\",\n        \"Create new xmlwriter using source uri for output\"\n    ],\n    \"xmlwriter_output_memory\": [\n        \"string xmlwriter_output_memory(resource xmlwriter [,bool flush])\",\n        \"Output current buffer as string\"\n    ],\n    \"xmlwriter_set_indent\": [\n        \"bool xmlwriter_set_indent(resource xmlwriter, bool indent)\",\n        \"Toggle indentation on/off - returns FALSE on error\"\n    ],\n    \"xmlwriter_set_indent_string\": [\n        \"bool xmlwriter_set_indent_string(resource xmlwriter, string indentString)\",\n        \"Set string used for indenting - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_attribute\": [\n        \"bool xmlwriter_start_attribute(resource xmlwriter, string name)\",\n        \"Create start attribute - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_attribute_ns\": [\n        \"bool xmlwriter_start_attribute_ns(resource xmlwriter, string prefix, string name, string uri)\",\n        \"Create start namespaced attribute - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_cdata\": [\n        \"bool xmlwriter_start_cdata(resource xmlwriter)\",\n        \"Create start CDATA tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_comment\": [\n        \"bool xmlwriter_start_comment(resource xmlwriter)\",\n        \"Create start comment - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_document\": [\n        \"bool xmlwriter_start_document(resource xmlwriter, string version, string encoding, string standalone)\",\n        \"Create document tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_dtd\": [\n        \"bool xmlwriter_start_dtd(resource xmlwriter, string name, string pubid, string sysid)\",\n        \"Create start DTD tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_dtd_attlist\": [\n        \"bool xmlwriter_start_dtd_attlist(resource xmlwriter, string name)\",\n        \"Create start DTD AttList - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_dtd_element\": [\n        \"bool xmlwriter_start_dtd_element(resource xmlwriter, string name)\",\n        \"Create start DTD element - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_dtd_entity\": [\n        \"bool xmlwriter_start_dtd_entity(resource xmlwriter, string name, bool isparam)\",\n        \"Create start DTD Entity - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_element\": [\n        \"bool xmlwriter_start_element(resource xmlwriter, string name)\",\n        \"Create start element tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_element_ns\": [\n        \"bool xmlwriter_start_element_ns(resource xmlwriter, string prefix, string name, string uri)\",\n        \"Create start namespaced element tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_start_pi\": [\n        \"bool xmlwriter_start_pi(resource xmlwriter, string target)\",\n        \"Create start PI tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_text\": [\n        \"bool xmlwriter_text(resource xmlwriter, string content)\",\n        \"Write text - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_attribute\": [\n        \"bool xmlwriter_write_attribute(resource xmlwriter, string name, string content)\",\n        \"Write full attribute - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_attribute_ns\": [\n        \"bool xmlwriter_write_attribute_ns(resource xmlwriter, string prefix, string name, string uri, string content)\",\n        \"Write full namespaced attribute - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_cdata\": [\n        \"bool xmlwriter_write_cdata(resource xmlwriter, string content)\",\n        \"Write full CDATA tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_comment\": [\n        \"bool xmlwriter_write_comment(resource xmlwriter, string content)\",\n        \"Write full comment tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_dtd\": [\n        \"bool xmlwriter_write_dtd(resource xmlwriter, string name, string pubid, string sysid, string subset)\",\n        \"Write full DTD tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_dtd_attlist\": [\n        \"bool xmlwriter_write_dtd_attlist(resource xmlwriter, string name, string content)\",\n        \"Write full DTD AttList tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_dtd_element\": [\n        \"bool xmlwriter_write_dtd_element(resource xmlwriter, string name, string content)\",\n        \"Write full DTD element tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_dtd_entity\": [\n        \"bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, int pe [, string pubid [, string sysid [, string ndataid]]]])\",\n        \"Write full DTD Entity tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_element\": [\n        \"bool xmlwriter_write_element(resource xmlwriter, string name[, string content])\",\n        \"Write full element tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_element_ns\": [\n        \"bool xmlwriter_write_element_ns(resource xmlwriter, string prefix, string name, string uri[, string content])\",\n        \"Write full namespaced element tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_pi\": [\n        \"bool xmlwriter_write_pi(resource xmlwriter, string target, string content)\",\n        \"Write full PI tag - returns FALSE on error\"\n    ],\n    \"xmlwriter_write_raw\": [\n        \"bool xmlwriter_write_raw(resource xmlwriter, string content)\",\n        \"Write text - returns FALSE on error\"\n    ],\n    \"xsl_xsltprocessor_get_parameter\": [\n        \"string xsl_xsltprocessor_get_parameter(string namespace, string name)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_has_exslt_support\": [\n        \"bool xsl_xsltprocessor_has_exslt_support()\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_import_stylesheet\": [\n        \"void xsl_xsltprocessor_import_stylesheet(domdocument doc)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_register_php_functions\": [\n        \"void xsl_xsltprocessor_register_php_functions([mixed $restrict])\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_remove_parameter\": [\n        \"bool xsl_xsltprocessor_remove_parameter(string namespace, string name)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_set_parameter\": [\n        \"bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value])\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_set_profiling\": [\n        \"bool xsl_xsltprocessor_set_profiling(string filename)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_transform_to_doc\": [\n        \"domdocument xsl_xsltprocessor_transform_to_doc(domnode doc)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_transform_to_uri\": [\n        \"int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri)\",\n        \"\"\n    ],\n    \"xsl_xsltprocessor_transform_to_xml\": [\n        \"string xsl_xsltprocessor_transform_to_xml(domdocument doc)\",\n        \"\"\n    ],\n    \"zend_logo_guid\": [\n        \"string zend_logo_guid()\",\n        \"Return the special ID used to request the Zend logo in phpinfo screens\"\n    ],\n    \"zend_version\": [\n        \"string zend_version()\",\n        \"Get the version of the Zend Engine\"\n    ],\n    \"zip_close\": [\n        \"void zip_close(resource zip)\",\n        \"Close a Zip archive\"\n    ],\n    \"zip_entry_close\": [\n        \"void zip_entry_close(resource zip_ent)\",\n        \"Close a zip entry\"\n    ],\n    \"zip_entry_compressedsize\": [\n        \"int zip_entry_compressedsize(resource zip_entry)\",\n        \"Return the compressed size of a ZZip entry\"\n    ],\n    \"zip_entry_compressionmethod\": [\n        \"string zip_entry_compressionmethod(resource zip_entry)\",\n        \"Return a string containing the compression method used on a particular entry\"\n    ],\n    \"zip_entry_filesize\": [\n        \"int zip_entry_filesize(resource zip_entry)\",\n        \"Return the actual filesize of a ZZip entry\"\n    ],\n    \"zip_entry_name\": [\n        \"string zip_entry_name(resource zip_entry)\",\n        \"Return the name given a ZZip entry\"\n    ],\n    \"zip_entry_open\": [\n        \"bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])\",\n        \"Open a Zip File, pointed by the resource entry\"\n    ],\n    \"zip_entry_read\": [\n        \"mixed zip_entry_read(resource zip_entry [, int len])\",\n        \"Read from an open directory entry\"\n    ],\n    \"zip_open\": [\n        \"resource zip_open(string filename)\",\n        \"Create new zip using source uri for output\"\n    ],\n    \"zip_read\": [\n        \"resource zip_read(resource zip)\",\n        \"Returns the next file in the archive\"\n    ],\n    \"zlib_get_coding_type\": [\n        \"string zlib_get_coding_type()\",\n        \"Returns the coding type used for output compression\"\n    ],\n    \"array_column\": [\n        \"array_column(array $array, int|string|null $column_key, int|string|null $index_key = null): array\",\n        \"Return the values from a single column in the input array\"\n     ],\n     \"boolval\": [\n        \"boolval(mixed $value): bool\",\n        \"Get the boolean value of a variable\"\n     ],\n     \"bzclose\": [\n        \"bzclose(resource $bz): bool\",\n        \"Close a bzip2 file\"\n     ],\n     \"bzflush\": [\n        \"bzflush(resource $bz): bool\",\n        \"Do nothing\"\n     ],\n     \"bzwrite\": [\n        \"bzwrite(resource $bz, string $data, ?int $length = null): int|false\",\n        \"Binary safe bzip2 file write\"\n     ],\n     \"checkdnsrr\": [\n        \"checkdnsrr(string $hostname, string $type = &quot;MX&quot;): bool\",\n        \"Check DNS records corresponding to a given Internet host name or IP address\"\n     ],\n     \"chop\": [\n        \"chop()\",\n        \"Alias of rtrim()\"\n     ],\n     \"class_uses\": [\n        \"class_uses(object|string $object_or_class, bool $autoload = true): array|false\",\n        \"\"\n     ],\n     \"curl_escape\": [\n        \"curl_escape(CurlHandle $handle, string $string): string|false\",\n        \"URL encodes the given string\"\n     ],\n     \"curl_file_create\": [\n        \"curl_file_create()\",\n        \"Create a CURLFile object\"\n     ],\n     \"curl_multi_errno\": [\n        \"curl_multi_errno(CurlMultiHandle $multi_handle): int\",\n        \"Return the last multi curl error number\"\n     ],\n     \"curl_multi_setopt\": [\n        \"curl_multi_setopt(CurlMultiHandle $multi_handle, int $option, mixed $value): bool\",\n        \"Set an option for the cURL multi handle\"\n     ],\n     \"curl_multi_strerror\": [\n        \"curl_multi_strerror(int $error_code): ?string\",\n        \"Return string describing error code\"\n     ],\n     \"curl_pause\": [\n        \"curl_pause(CurlHandle $handle, int $flags): int\",\n        \"Pause and unpause a connection\"\n     ],\n     \"curl_reset\": [\n        \"curl_reset(CurlHandle $handle): void\",\n        \"Reset all options of a libcurl session handle\"\n     ],\n     \"curl_share_close\": [\n        \"curl_share_close(CurlShareHandle $share_handle): void\",\n        \"Close a cURL share handle\"\n     ],\n     \"curl_share_errno\": [\n        \"curl_share_errno(CurlShareHandle $share_handle): int\",\n        \"Return the last share curl error number\"\n     ],\n     \"curl_share_init\": [\n        \"curl_share_init(): CurlShareHandle\",\n        \"Initialize a cURL share handle\"\n     ],\n     \"curl_share_setopt\": [\n        \"curl_share_setopt(CurlShareHandle $share_handle, int $option, mixed $value): bool\",\n        \"Set an option for a cURL share handle\"\n     ],\n     \"curl_share_strerror\": [\n        \"curl_share_strerror(int $error_code): ?string\",\n        \"Return string describing the given error code\"\n     ],\n     \"curl_strerror\": [\n        \"curl_strerror(int $error_code): ?string\",\n        \"Return string describing the given error code\"\n     ],\n     \"curl_unescape\": [\n        \"curl_unescape(CurlHandle $handle, string $string): string|false\",\n        \"Decodes the given URL encoded string\"\n     ],\n     \"date_create_immutable_from_format\": [\n        \"date_create_immutable_from_format()\",\n        \"Alias of DateTimeImmutable::createFromFormat()\"\n     ],\n     \"date_create_immutable\": [\n        \"date_create_immutable()\",\n        \"Alias of DateTimeImmutable::__construct()\"\n     ],\n     \"deflate_add\": [\n        \"deflate_add(DeflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false\",\n        \"Incrementally deflate data\"\n     ],\n     \"deflate_init\": [\n        \"deflate_init(int $encoding, array $options = []): DeflateContext|false\",\n        \"Initialize an incremental deflate context\"\n     ],\n     \"delete\": [\n        \"delete()\",\n        \"See unlink()\"\n     ],\n     \"diskfreespace\": [\n        \"diskfreespace()\",\n        \"Alias of disk_free_space()\"\n     ],\n     \"doubleval\": [\n        \"doubleval()\",\n        \"Alias of floatval()\"\n     ],\n     \"enchant_dict_add\": [\n        \"enchant_dict_add(EnchantDictionary $dictionary, string $word): void\",\n        \"Add a word to personal word list\"\n     ],\n     \"enchant_dict_is_added\": [\n        \"enchant_dict_is_added(EnchantDictionary $dictionary, string $word): bool\",\n        \"Whether or not &#039;word&#039; exists in this spelling-session\"\n     ],\n     \"error_clear_last\": [\n        \"error_clear_last(): void\",\n        \"Clear the most recent error\"\n     ],\n     \"eval\": [\n        \"eval(string $code): mixed\",\n        \"Evaluate a string as PHP code\"\n     ],\n     \"expect_expectl\": [\n        \"expect_expectl(resource $expect, array $cases, array &$match = ?): int\",\n        \"\"\n     ],\n     \"expect_popen\": [\n        \"expect_popen(string $command): resource\",\n        \"\"\n     ],\n     \"fdiv\": [\n        \"fdiv(float $num1, float $num2): float\",\n        \"Divides two numbers, according to IEEE 754\"\n     ],\n     \"filter_id\": [\n        \"filter_id(string $name): int|false\",\n        \"Returns the filter ID belonging to a named filter\"\n     ],\n     \"filter_list\": [\n        \"filter_list(): array\",\n        \"Returns a list of all supported filters\"\n     ],\n     \"forward_static_call_array\": [\n        \"forward_static_call_array(callable $callback, array $args): mixed\",\n        \"Call a static method and pass the arguments as array\"\n     ],\n     \"fputs\": [\n        \"fputs()\",\n        \"Alias of fwrite()\"\n     ],\n     \"ftp_append\": [\n        \"ftp_append(FTP\\\\Connection $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY): bool\",\n        \"Append the contents of a file to another file on the FTP server\"\n     ],\n     \"ftp_mlsd\": [\n        \"ftp_mlsd(FTP\\\\Connection $ftp, string $directory): array|false\",\n        \"Returns a list of files in the given directory\"\n     ],\n     \"ftp_quit\": [\n        \"ftp_quit()\",\n        \"Alias of ftp_close()\"\n     ],\n     \"gc_mem_caches\": [\n        \"gc_mem_caches(): int\",\n        \"\"\n     ],\n     \"gc_status\": [\n        \"gc_status(): array\",\n        \"Gets information about the garbage collector\"\n     ],\n     \"get_debug_type\": [\n        \"get_debug_type(mixed $value): string\",\n        \"Gets the type name of a variable in a way that is suitable for debugging\"\n     ],\n     \"get_declared_traits\": [\n        \"get_declared_traits(): array\",\n        \"Returns an array of all declared traits\"\n     ],\n     \"get_required_files\": [\n        \"get_required_files()\",\n        \"Alias of get_included_files()\"\n     ],\n     \"get_resource_id\": [\n        \"get_resource_id(resource $resource): int\",\n        \"\"\n     ],\n     \"get_resources\": [\n        \"get_resources(?string $type = null): array\",\n        \"Returns active resources\"\n     ],\n     \"getimagesizefromstring\": [\n        \"getimagesizefromstring(string $string, array &$image_info = null): array|false\",\n        \"Get the size of an image from a string\"\n     ],\n     \"getmxrr\": [\n        \"getmxrr(string $hostname, array &$hosts, array &$weights = null): bool\",\n        \"Get MX records corresponding to a given Internet host name\"\n     ],\n     \"gmp_binomial\": [\n        \"gmp_binomial(GMP|int|string $n, int $k): GMP\",\n        \"Calculates binomial coefficient\"\n     ],\n     \"gmp_div\": [\n        \"gmp_div()\",\n        \"Alias of gmp_div_q()\"\n     ],\n     \"gmp_export\": [\n        \"gmp_export(GMP|int|string $num, int $word_size = 1, int $flags = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): string\",\n        \"Export to a binary string\"\n     ],\n     \"gmp_import\": [\n        \"gmp_import(string $data, int $word_size = 1, int $flags = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): GMP\",\n        \"Import from a binary string\"\n     ],\n     \"gmp_kronecker\": [\n        \"gmp_kronecker(GMP|int|string $num1, GMP|int|string $num2): int\",\n        \"Kronecker symbol\"\n     ],\n     \"gmp_lcm\": [\n        \"gmp_lcm(GMP|int|string $num1, GMP|int|string $num2): GMP\",\n        \"Calculate LCM\"\n     ],\n     \"gmp_perfect_power\": [\n        \"gmp_perfect_power(GMP|int|string $num): bool\",\n        \"Perfect power check\"\n     ],\n     \"gmp_random_bits\": [\n        \"gmp_random_bits(int $bits): GMP\",\n        \"Random number\"\n     ],\n     \"gmp_random_range\": [\n        \"gmp_random_range(GMP|int|string $min, GMP|int|string $max): GMP\",\n        \"Random number\"\n     ],\n     \"gmp_random_seed\": [\n        \"gmp_random_seed(GMP|int|string $seed): void\",\n        \"Sets the RNG seed\"\n     ],\n     \"gmp_root\": [\n        \"gmp_root(GMP|int|string $num, int $nth): GMP\",\n        \"Take the integer part of nth root\"\n     ],\n     \"gmp_rootrem\": [\n        \"gmp_rootrem(GMP|int|string $num, int $nth): array\",\n        \"Take the integer part and remainder of nth root\"\n     ],\n     \"gzclose\": [\n        \"gzclose(resource $stream): bool\",\n        \"Close an open gz-file pointer\"\n     ],\n     \"gzdecode\": [\n        \"gzdecode(string $data, int $max_length = 0): string|false\",\n        \"Decodes a gzip compressed string\"\n     ],\n     \"gzeof\": [\n        \"gzeof(resource $stream): bool\",\n        \"Test for EOF on a gz-file pointer\"\n     ],\n     \"gzgetc\": [\n        \"gzgetc(resource $stream): string|false\",\n        \"Get character from gz-file pointer\"\n     ],\n     \"gzgets\": [\n        \"gzgets(resource $stream, ?int $length = null): string|false\",\n        \"Get line from file pointer\"\n     ],\n     \"gzgetss\": [\n        \"gzgetss(resource $zp, int $length, string $allowable_tags = ?): string\",\n        \"\"\n     ],\n     \"gzpassthru\": [\n        \"gzpassthru(resource $stream): int\",\n        \"\"\n     ],\n     \"gzputs\": [\n        \"gzputs()\",\n        \"Alias of gzwrite()\"\n     ],\n     \"gzread\": [\n        \"gzread(resource $stream, int $length): string|false\",\n        \"Binary-safe gz-file read\"\n     ],\n     \"gzrewind\": [\n        \"gzrewind(resource $stream): bool\",\n        \"Rewind the position of a gz-file pointer\"\n     ],\n     \"gzseek\": [\n        \"gzseek(resource $stream, int $offset, int $whence = SEEK_SET): int\",\n        \"Seek on a gz-file pointer\"\n     ],\n     \"gztell\": [\n        \"gztell(resource $stream): int|false\",\n        \"Tell gz-file pointer read/write position\"\n     ],\n     \"gzwrite\": [\n        \"gzwrite(resource $stream, string $data, ?int $length = null): int|false\",\n        \"Binary-safe gz-file write\"\n     ],\n     \"halt_compiler\": [\n        \"__halt_compiler(): void\",\n        \"\"\n     ],\n     \"hash_equals\": [\n        \"hash_equals(string $known_string, string $user_string): bool\",\n        \"Timing attack safe string comparison\"\n     ],\n     \"hash_hkdf\": [\n        \"hash_hkdf(string $algo, string $key, int $length = 0, string $info = \\\"\\\", string $salt = \\\"\\\"): string\",\n        \"Generate a HKDF key derivation of a supplied key input\"\n     ],\n     \"hash_hmac_algos\": [\n        \"hash_hmac_algos(): array\",\n        \"Return a list of registered hashing algorithms suitable for hash_hmac\"\n     ],\n     \"hash_pbkdf2\": [\n        \"hash_pbkdf2(string $algo, string $password, string $salt, int $iterations, int $length = 0, bool $binary = false): string\",\n        \"Generate a PBKDF2 key derivation of a supplied password\"\n     ],\n     \"header_register_callback\": [\n        \"header_register_callback(callable $callback): bool\",\n        \"Call a header function\"\n     ],\n     \"hex2bin\": [\n        \"hex2bin(string $string): string|false\",\n        \"Decodes a hexadecimally encoded binary string\"\n     ],\n     \"hrtime\": [\n        \"hrtime(bool $as_number = false): array|int|float|false\",\n        \"Get the system&#039;s high resolution time\"\n     ],\n     \"http_response_code\": [\n        \"http_response_code(int $response_code = 0): int|bool\",\n        \"Get or Set the HTTP response code\"\n     ],\n     \"imageaffine\": [\n        \"imageaffine(GdImage $image, array $affine, ?array $clip = null): GdImage|false\",\n        \"Return an image containing the affine transformed src image, using an optional clipping area\"\n     ],\n     \"imageaffinematrixconcat\": [\n        \"imageaffinematrixconcat(array $matrix1, array $matrix2): array|false\",\n        \"Concatenate two affine transformation matrices\"\n     ],\n     \"imageaffinematrixget\": [\n        \"imageaffinematrixget(int $type, array|float $options): array|false\",\n        \"Get an affine transformation matrix\"\n     ],\n     \"imagebmp\": [\n        \"imagebmp(GdImage $image, resource|string|null $file = null, bool $compressed = true): bool\",\n        \"Output a BMP image to browser or file\"\n     ],\n     \"imagecreatefrombmp\": [\n        \"imagecreatefrombmp(string $filename): GdImage|false\",\n        \"Create a new image from file or URL\"\n     ],\n     \"imagecreatefromwebp\": [\n        \"imagecreatefromwebp(string $filename): GdImage|false\",\n        \"Create a new image from file or URL\"\n     ],\n     \"imagecrop\": [\n        \"imagecrop(GdImage $image, array $rectangle): GdImage|false\",\n        \"Crop an image to the given rectangle\"\n     ],\n     \"imagecropauto\": [\n        \"imagecropauto(GdImage $image, int $mode = IMG_CROP_DEFAULT, float $threshold = 0.5, int $color = -1): GdImage|false\",\n        \"Crop an image automatically using one of the available modes\"\n     ],\n     \"imageflip\": [\n        \"imageflip(GdImage $image, int $mode): bool\",\n        \"Flips an image using a given mode\"\n     ],\n     \"imagegetclip\": [\n        \"imagegetclip(GdImage $image): array\",\n        \"Get the clipping rectangle\"\n     ],\n     \"imagegetinterpolation\": [\n        \"imagegetinterpolation(GdImage $image): int\",\n        \"Get the interpolation method\"\n     ],\n     \"imageopenpolygon\": [\n        \"imageopenpolygon(GdImage $image, array $points, int $color): bool\",\n        \"Draws an open polygon\"\n     ],\n     \"imagepalettetotruecolor\": [\n        \"imagepalettetotruecolor(GdImage $image): bool\",\n        \"Converts a palette based image to true color\"\n     ],\n     \"imageresolution\": [\n        \"imageresolution(GdImage $image, ?int $resolution_x = null, ?int $resolution_y = null): array|bool\",\n        \"Get or set the resolution of the image\"\n     ],\n     \"imagescale\": [\n        \"imagescale(GdImage $image, int $width, int $height = -1, int $mode = IMG_BILINEAR_FIXED): GdImage|false\",\n        \"Scale an image using the given new width and height\"\n     ],\n     \"imagesetclip\": [\n        \"imagesetclip(GdImage $image, int $x1, int $y1, int $x2, int $y2): bool\",\n        \"Set the clipping rectangle\"\n     ],\n     \"imagesetinterpolation\": [\n        \"imagesetinterpolation(GdImage $image, int $method = IMG_BILINEAR_FIXED): bool\",\n        \"Set the interpolation method\"\n     ],\n     \"imagewebp\": [\n        \"imagewebp(GdImage $image, resource|string|null $file = null, int $quality = -1): bool\",\n        \"Output a WebP image to browser or file\"\n     ],\n     \"imap_create\": [\n        \"\",\n        \"Alias of imap_createmailbox()\"\n     ],\n     \"imap_fetchmime\": [\n        \"imap_fetchmime(IMAP\\\\Connection $imap, int $message_num, string $section, int $flags = 0): string|false\",\n        \"Fetch MIME headers for a particular section of the message\"\n     ],\n     \"imap_fetchtext\": [\n        \"imap_fetchtext()\",\n        \"Alias of imap_body()\"\n     ],\n     \"imap_header\": [\n        \"imap_header()\",\n        \"Alias of imap_headerinfo()\"\n     ],\n     \"imap_listmailbox\": [\n        \"imap_listmailbox()\",\n        \"Alias of imap_list()\"\n     ],\n     \"imap_listsubscribed\": [\n        \"imap_listsubscribed()\",\n        \"Alias of imap_lsub()\"\n     ],\n     \"imap_rename\": [\n        \"imap_rename()\",\n        \"Alias of imap_renamemailbox()\"\n     ],\n     \"imap_scan\": [\n        \"imap_scan()\",\n        \"Alias of imap_listscan()\"\n     ],\n     \"imap_scanmailbox\": [\n        \"imap_scanmailbox()\",\n        \"Alias of imap_listscan()\"\n     ],\n     \"ini_alter\": [\n        \"ini_alter()\",\n        \"Alias of ini_set()\"\n     ],\n     \"intdiv\": [\n        \"intdiv(int $num1, int $num2): int\",\n        \"Integer division\"\n     ],\n     \"is_double\": [\n        \"is_double()\",\n        \"Alias of is_float()\"\n     ],\n     \"is_int\": [\n        \"is_int(mixed $value): bool\",\n        \"Find whether the type of a variable is integer\"\n     ],\n     \"is_integer\": [\n        \"is_integer()\",\n        \"Alias of is_int()\"\n     ],\n     \"is_iterable\": [\n        \"is_iterable(mixed $value): bool\",\n        \"\"\n     ],\n     \"is_real\": [\n        \"is_real()\",\n        \"Alias of is_float()\"\n     ],\n     \"is_soap_fault\": [\n        \"is_soap_fault(mixed $object): bool\",\n        \"Checks if a SOAP call has failed\"\n     ],\n     \"is_tainted\": [\n        \"is_tainted(string $string): bool\",\n        \"Checks whether a string is tainted\"\n     ],\n     \"is_writeable\": [\n        \"is_writeable()\",\n        \"Alias of is_writable()\"\n     ],\n     \"json_last_error_msg\": [\n        \"json_last_error_msg(): string\",\n        \"Returns the error string of the last json_encode() or json_decode() call\"\n     ],\n     \"key_exists\": [\n        \"key_exists()\",\n        \"Alias of array_key_exists()\"\n     ],\n     \"lchown\": [\n        \"lchown(string $filename, string|int $user): bool\",\n        \"Changes user ownership of symlink\"\n     ],\n     \"libxml_set_external_entity_loader\": [\n        \"libxml_set_external_entity_loader(?callable $resolver_function): bool\",\n        \"Changes the default external entity loader\"\n     ],\n     \"mb_chr\": [\n        \"mb_chr(int $codepoint, ?string $encoding = null): string|false\",\n        \"Return character by Unicode code point value\"\n     ],\n     \"mb_ereg_replace_callback\": [\n        \"mb_ereg_replace_callback(string $pattern, callable $callback, string $string, ?string $options = null): string|false|null\",\n        \"\"\n     ],\n     \"mb_ord\": [\n        \"mb_ord(string $string, ?string $encoding = null): int|false\",\n        \"Get Unicode code point of character\"\n     ],\n     \"mb_scrub\": [\n        \"mb_scrub(string $string, ?string $encoding = null): string\",\n        \"Description\"\n     ],\n     \"mb_str_split\": [\n        \"mb_str_split(string $string, int $length = 1, ?string $encoding = null): array\",\n        \"Given a multibyte string, return an array of its characters\"\n     ],\n     \"memcache_debug\": [\n        \"memcache_debug(bool $on_off): bool\",\n        \"Turn debug output on/off\"\n     ],\n     \"mysql_db_name\": [\n        \"mysql_db_name(resource $result, int $row, mixed $field = NULL): string\",\n        \"Retrieves database name from the call to mysql_list_dbs()\"\n     ],\n     \"mysql_tablename\": [\n        \"mysql_tablename(resource $result, int $i): string|false\",\n        \"Get table name of field\"\n     ],\n     \"mysql_xdevapi_expression\": [\n        \"mysql_xdevapi\\\\expression(string $expression): object\",\n        \"Bind prepared statement variables as parameters\"\n     ],\n     \"mysql_xdevapi_getsession\": [\n        \"mysql_xdevapi\\\\getSession(string $uri): mysql_xdevapi\\\\Session\",\n        \"Connect to a MySQL server\"\n     ],\n     \"mysqli_escape_string\": [\n        \"mysqli_escape_string()\",\n        \"Alias of mysqli_real_escape_string()\"\n     ],\n     \"mysqli_execute\": [\n        \"mysqli_execute()\",\n        \"Alias for mysqli_stmt_execute()\"\n     ],\n     \"mysqli_get_links_stats\": [\n        \"mysqli_get_links_stats(): array\",\n        \"Return information about open and cached links\"\n     ],\n     \"mysqli_set_opt\": [\n        \"mysqli_set_opt()\",\n        \"Alias of mysqli_options()\"\n     ],\n     \"ob_tidyhandler\": [\n        \"ob_tidyhandler(string $input, int $mode = ?): string\",\n        \"ob_start callback function to repair the buffer\"\n     ],\n     \"odbc_do\": [\n        \"odbc_do()\",\n        \"Alias of odbc_exec()\"\n     ],\n     \"odbc_field_precision\": [\n        \"odbc_field_precision()\",\n        \"Alias of odbc_field_len()\"\n     ],\n     \"opcache_compile_file\": [\n        \"opcache_compile_file(string $filename): bool\",\n        \"Compiles and caches a PHP script without executing it\"\n     ],\n     \"opcache_get_configuration\": [\n        \"opcache_get_configuration(): array|false\",\n        \"Get configuration information about the cache\"\n     ],\n     \"opcache_get_status\": [\n        \"opcache_get_status(bool $include_scripts = true): array|false\",\n        \"Get status information about the cache\"\n     ],\n     \"opcache_invalidate\": [\n        \"opcache_invalidate(string $filename, bool $force = false): bool\",\n        \"Invalidates a cached script\"\n     ],\n     \"opcache_is_script_cached\": [\n        \"opcache_is_script_cached(string $filename): bool\",\n        \"Tells whether a script is cached in OPCache\"\n     ],\n     \"opcache_reset\": [\n        \"opcache_reset(): bool\",\n        \"Resets the contents of the opcode cache\"\n     ],\n     \"password_algos\": [\n        \"password_algos(): array\",\n        \"Get available password hashing algorithm IDs\"\n     ],\n     \"password_get_info\": [\n        \"password_get_info(string $hash): array\",\n        \"Returns information about the given hash\"\n     ],\n     \"password_hash\": [\n        \"password_hash(string $password, string|int|null $algo, array $options = []): string\",\n        \"Creates a password hash\"\n     ],\n     \"password_needs_rehash\": [\n        \"password_needs_rehash(string $hash, string|int|null $algo, array $options = []): bool\",\n        \"Checks if the given hash matches the given options\"\n     ],\n     \"password_verify\": [\n        \"password_verify(string $password, string $hash): bool\",\n        \"Verifies that a password matches a hash\"\n     ],\n     \"pcntl_async_signals\": [\n        \"pcntl_async_signals(?bool $enable = null): bool\",\n        \"Enable/disable asynchronous signal handling or return the old setting\"\n     ],\n     \"pcntl_errno\": [\n        \"pcntl_errno()\",\n        \"Alias of pcntl_get_last_error()\"\n     ],\n     \"pcntl_get_last_error\": [\n        \"pcntl_get_last_error(): int\",\n        \"Retrieve the error number set by the last pcntl function which failed\"\n     ],\n     \"pcntl_signal_get_handler\": [\n        \"pcntl_signal_get_handler(int $signal): callable|int\",\n        \"Get the current handler for specified signal\"\n     ],\n     \"pcntl_sigwaitinfo\": [\n        \"pcntl_sigwaitinfo(array $signals, array &$info = []): int|false\",\n        \"Waits for signals\"\n     ],\n     \"pcntl_strerror\": [\n        \"pcntl_strerror(int $error_code): string\",\n        \"Retrieve the system error message associated with the given errno\"\n     ],\n     \"pg_connect_poll\": [\n        \"pg_connect_poll(PgSql\\\\Connection $connection): int\",\n        \"\"\n     ],\n     \"pg_consume_input\": [\n        \"pg_consume_input(PgSql\\\\Connection $connection): bool\",\n        \"Reads input on the connection\"\n     ],\n     \"pg_escape_identifier\": [\n        \"pg_escape_identifier(PgSql\\\\Connection $connection = ?, string $data): string\",\n        \"\"\n     ],\n     \"pg_escape_literal\": [\n        \"pg_escape_literal(PgSql\\\\Connection $connection = ?, string $data): string\",\n        \"\"\n     ],\n     \"pg_flush\": [\n        \"pg_flush(PgSql\\\\Connection $connection): int|bool\",\n        \"Flush outbound query data on the connection\"\n     ],\n     \"pg_lo_truncate\": [\n        \"pg_lo_truncate(PgSql\\\\Lob $lob, int $size): bool\",\n        \"\"\n     ],\n     \"pg_socket\": [\n        \"pg_socket(PgSql\\\\Connection $connection): resource|false\",\n        \"\"\n     ],\n     \"pos\": [\n        \"pos()\",\n        \"Alias of current()\"\n     ],\n     \"posix_errno\": [\n        \"posix_errno()\",\n        \"Alias of posix_get_last_error()\"\n     ],\n     \"posix_setrlimit\": [\n        \"posix_setrlimit(int $resource, int $soft_limit, int $hard_limit): bool\",\n        \"Set system resource limits\"\n     ],\n     \"preg_last_error_msg\": [\n        \"preg_last_error_msg(): string\",\n        \"Returns the error message of the last PCRE regex execution\"\n     ],\n     \"preg_replace_callback_array\": [\n        \"preg_replace_callback_array(array $pattern, string|array $subject, int $limit = -1, int &$count = null, int $flags = 0): string|array|null\",\n        \"Perform a regular expression search and replace using callbacks\"\n     ],\n     \"ps_translate\": [\n        \"ps_translate(resource $psdoc, float $x, float $y): bool\",\n        \"Sets translation\"\n     ],\n     \"random_bytes\": [\n        \"random_bytes(int $length): string\",\n        \"Generates cryptographically secure pseudo-random bytes\"\n     ],\n     \"random_int\": [\n        \"random_int(int $min, int $max): int\",\n        \"Generates cryptographically secure pseudo-random integers\"\n     ],\n     \"read_exif_data\": [\n        \"read_exif_data()\",\n        \"Alias of exif_read_data()\"\n     ],\n     \"recode\": [\n        \"recode()\",\n        \"Alias of recode_string()\"\n     ],\n     \"session_abort\": [\n        \"session_abort(): bool\",\n        \"Discard session array changes and finish session\"\n     ],\n     \"session_commit\": [\n        \"session_commit()\",\n        \"Alias of session_write_close()\"\n     ],\n     \"session_create_id\": [\n        \"session_create_id(string $prefix = \\\"\\\"): string|false\",\n        \"Create new session id\"\n     ],\n     \"session_gc\": [\n        \"session_gc(): int|false\",\n        \"Perform session data garbage collection\"\n     ],\n     \"session_register_shutdown\": [\n        \"session_register_shutdown(): void\",\n        \"Session shutdown function\"\n     ],\n     \"session_reset\": [\n        \"session_reset(): bool\",\n        \"Re-initialize session array with original values\"\n     ],\n     \"session_status\": [\n        \"session_status(): int\",\n        \"Returns the current session status\"\n     ],\n     \"set_file_buffer\": [\n        \"set_file_buffer()\",\n        \"Alias of stream_set_write_buffer()\"\n     ],\n     \"show_source\": [\n        \"show_source()\",\n        \"Alias of highlight_file()\"\n     ],\n     \"sizeof\": [\n        \"sizeof()\",\n        \"Alias of count()\"\n     ],\n     \"snmp_set_oid_numeric_print\": [\n        \"snmp_set_oid_numeric_print(int $format): bool\",\n        \"\"\n     ],\n     \"snmpwalkoid\": [\n        \"snmpwalkoid(string $hostname, string $community, array|string $object_id, int $timeout = -1, int $retries = -1): array|false\",\n        \"\"\n     ],\n     \"socket_addrinfo_bind\": [\n        \"socket_addrinfo_bind(AddressInfo $address): Socket|false\",\n        \"Create and bind to a socket from a given addrinfo\"\n     ],\n     \"socket_addrinfo_connect\": [\n        \"socket_addrinfo_connect(AddressInfo $address): Socket|false\",\n        \"Create and connect to a socket from a given addrinfo\"\n     ],\n     \"socket_addrinfo_explain\": [\n        \"socket_addrinfo_explain(AddressInfo $address): array\",\n        \"Get information about addrinfo\"\n     ],\n     \"socket_addrinfo_lookup\": [\n        \"socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = []): array|false\",\n        \"Get array with contents of getaddrinfo about the given hostname\"\n     ],\n     \"socket_cmsg_space\": [\n        \"socket_cmsg_space(int $level, int $type, int $num = 0): ?int\",\n        \"Calculate message buffer size\"\n     ],\n     \"socket_export_stream\": [\n        \"socket_export_stream(Socket $socket): resource|false\",\n        \"Export a socket into a stream that encapsulates a socket\"\n     ],\n     \"socket_get_status\": [\n        \"socket_get_status()\",\n        \"Alias of stream_get_meta_data()\"\n     ],\n     \"socket_getopt\": [\n        \"socket_getopt()\",\n        \"Alias of socket_get_option()\"\n     ],\n     \"socket_import_stream\": [\n        \"socket_import_stream(resource $stream): Socket|false\",\n        \"Import a stream\"\n     ],\n     \"socket_recvmsg\": [\n        \"socket_recvmsg(Socket $socket, array &$message, int $flags = 0): int|false\",\n        \"Read a message\"\n     ],\n     \"socket_sendmsg\": [\n        \"socket_sendmsg(Socket $socket, array $message, int $flags = 0): int|false\",\n        \"Send a message\"\n     ],\n     \"socket_set_blocking\": [\n        \"socket_set_blocking()\",\n        \"Alias of stream_set_blocking()\"\n     ],\n     \"socket_set_timeout\": [\n        \"socket_set_timeout()\",\n        \"Alias of stream_set_timeout()\"\n     ],\n     \"socket_setopt\": [\n        \"socket_setopt()\",\n        \"Alias of socket_set_option()\"\n     ],\n     \"socket_wsaprotocol_info_export\": [\n        \"socket_wsaprotocol_info_export(Socket $socket, int $process_id): string|false\",\n        \"Exports the WSAPROTOCOL_INFO Structure\"\n     ],\n     \"socket_wsaprotocol_info_import\": [\n        \"socket_wsaprotocol_info_import(string $info_id): Socket|false\",\n        \"Imports a Socket from another Process\"\n     ],\n     \"socket_wsaprotocol_info_release\": [\n        \"socket_wsaprotocol_info_release(string $info_id): bool\",\n        \"Releases an exported WSAPROTOCOL_INFO Structure\"\n     ],\n     \"spl_object_id\": [\n        \"spl_object_id(object $object): int\",\n        \"\"\n     ],\n     \"sqlsrv_begin_transaction\": [\n        \"sqlsrv_begin_transaction(resource $conn): bool\",\n        \"Begins a database transaction\"\n     ],\n     \"sqlsrv_cancel\": [\n        \"sqlsrv_cancel(resource $stmt): bool\",\n        \"Cancels a statement\"\n     ],\n     \"sqlsrv_client_info\": [\n        \"sqlsrv_client_info(resource $conn): array\",\n        \"Returns information about the client and specified connection\"\n     ],\n     \"sqlsrv_close\": [\n        \"sqlsrv_close(resource $conn): bool\",\n        \"Closes an open connection and releases resourses associated with the connection\"\n     ],\n     \"sqlsrv_commit\": [\n        \"sqlsrv_commit(resource $conn): bool\",\n        \"Commits a transaction that was begun with sqlsrv_begin_transaction()\"\n     ],\n     \"sqlsrv_configure\": [\n        \"sqlsrv_configure(string $setting, mixed $value): bool\",\n        \"Changes the driver error handling and logging configurations\"\n     ],\n     \"sqlsrv_connect\": [\n        \"sqlsrv_connect(string $serverName, array $connectionInfo = ?): resource\",\n        \"Opens a connection to a Microsoft SQL Server database\"\n     ],\n     \"sqlsrv_errors\": [\n        \"sqlsrv_errors(int $errorsOrWarnings = ?): mixed\",\n        \"Returns error and warning information about the last SQLSRV operation performed\"\n     ],\n     \"sqlsrv_execute\": [\n        \"sqlsrv_execute(resource $stmt): bool\",\n        \"Executes a statement prepared with sqlsrv_prepare()\"\n     ],\n     \"sqlsrv_fetch_array\": [\n        \"sqlsrv_fetch_array(resource $stmt, int $fetchType = ?, int $row = ?, int $offset = ?): array\",\n        \"Returns a row as an array\"\n     ],\n     \"sqlsrv_fetch_object\": [\n        \"sqlsrv_fetch_object(resource $stmt, string $className = ?, array $ctorParams = ?, int $row = ?, int $offset = ?): mixed\",\n        \"Retrieves the next row of data in a result set as an object\"\n     ],\n     \"sqlsrv_fetch\": [\n        \"sqlsrv_fetch(resource $stmt, int $row = ?, int $offset = ?): mixed\",\n        \"Makes the next row in a result set available for reading\"\n     ],\n     \"sqlsrv_field_metadata\": [\n        \"sqlsrv_field_metadata(resource $stmt): mixed\",\n        \"\"\n     ],\n     \"sqlsrv_free_stmt\": [\n        \"sqlsrv_free_stmt(resource $stmt): bool\",\n        \"Frees all resources for the specified statement\"\n     ],\n     \"sqlsrv_get_config\": [\n        \"sqlsrv_get_config(string $setting): mixed\",\n        \"Returns the value of the specified configuration setting\"\n     ],\n     \"sqlsrv_get_field\": [\n        \"sqlsrv_get_field(resource $stmt, int $fieldIndex, int $getAsType = ?): mixed\",\n        \"Gets field data from the currently selected row\"\n     ],\n     \"sqlsrv_has_rows\": [\n        \"sqlsrv_has_rows(resource $stmt): bool\",\n        \"Indicates whether the specified statement has rows\"\n     ],\n     \"sqlsrv_next_result\": [\n        \"sqlsrv_next_result(resource $stmt): mixed\",\n        \"Makes the next result of the specified statement active\"\n     ],\n     \"sqlsrv_num_fields\": [\n        \"sqlsrv_num_fields(resource $stmt): mixed\",\n        \"Retrieves the number of fields (columns) on a statement\"\n     ],\n     \"sqlsrv_num_rows\": [\n        \"sqlsrv_num_rows(resource $stmt): mixed\",\n        \"Retrieves the number of rows in a result set\"\n     ],\n     \"sqlsrv_prepare\": [\n        \"sqlsrv_prepare(resource $conn, string $sql, array $params = ?, array $options = ?): mixed\",\n        \"Prepares a query for execution\"\n     ],\n     \"sqlsrv_query\": [\n        \"sqlsrv_query(resource $conn, string $sql, array $params = ?, array $options = ?): mixed\",\n        \"Prepares and executes a query\"\n     ],\n     \"sqlsrv_rollback\": [\n        \"sqlsrv_rollback(resource $conn): bool\",\n        \"\"\n     ],\n     \"sqlsrv_rows_affected\": [\n        \"sqlsrv_rows_affected(resource $stmt): int|false\",\n        \"\"\n     ],\n     \"sqlsrv_send_stream_data\": [\n        \"sqlsrv_send_stream_data(resource $stmt): bool\",\n        \"Sends data from parameter streams to the server\"\n     ],\n     \"sqlsrv_server_info\": [\n        \"sqlsrv_server_info(resource $conn): array\",\n        \"Returns information about the server\"\n     ],\n     \"str_contains\": [\n        \"str_contains(string $haystack, string $needle): bool\",\n        \"Determine if a string contains a given substring\"\n     ],\n     \"str_ends_with\": [\n        \"str_ends_with(string $haystack, string $needle): bool\",\n        \"Checks if a string ends with a given substring\"\n     ],\n     \"str_starts_with\": [\n        \"str_starts_with(string $haystack, string $needle): bool\",\n        \"Checks if a string starts with a given substring\"\n     ],\n     \"stream_isatty\": [\n        \"stream_isatty(resource $stream): bool\",\n        \"Check if a stream is a TTY\"\n     ],\n     \"stream_notification_callback\": [\n        \"stream_notification_callback(int $notification_code, int $severity, string $message, int $message_code, int $bytes_transferred, int $bytes_max): void\",\n        \"A callback function for the notification context parameter\"\n     ],\n     \"stream_register_wrapper\": [\n        \"stream_register_wrapper()\",\n        \"Alias of stream_wrapper_register()\"\n     ],\n     \"stream_set_chunk_size\": [\n        \"stream_set_chunk_size(resource $stream, int $size): int\",\n        \"Set the stream chunk size\"\n     ],\n     \"stream_set_read_buffer\": [\n        \"stream_set_read_buffer(resource $stream, int $size): int\",\n        \"Set read file buffering on the given stream\"\n     ],\n     \"tcpwrap_check\": [\n        \"tcpwrap_check(string $daemon, string $address, string $user = ?, bool $nodns = false): bool\",\n        \"Performs a tcpwrap check\"\n     ],\n     \"trait_exists\": [\n        \"trait_exists(string $trait, bool $autoload = true): bool\",\n        \"Checks if the trait exists\"\n     ],\n     \"use_soap_error_handler\": [\n        \"use_soap_error_handler(bool $enable = true): bool\",\n        \"Set whether to use the SOAP error handler\"\n     ],\n     \"user_error\": [\n        \"user_error()\",\n        \"Alias of trigger_error()\"\n     ],\n     \"yaml_emit_file\": [\n        \"yaml_emit_file(string $filename, mixed $data, int $encoding = YAML_ANY_ENCODING, int $linebreak = YAML_ANY_BREAK, array $callbacks = null): bool\",\n        \"Send the YAML representation of a value to a file\"\n     ],\n     \"yaml_emit\": [\n        \"yaml_emit(mixed $data, int $encoding = YAML_ANY_ENCODING, int $linebreak = YAML_ANY_BREAK, array $callbacks = null): string\",\n        \"Returns the YAML representation of a value\"\n     ],\n     \"yaml_parse_file\": [\n        \"yaml_parse_file(string $filename, int $pos = 0, int &$ndocs = ?, array $callbacks = null): mixed\",\n        \"Parse a YAML stream from a file\"\n     ],\n     \"yaml_parse_url\": [\n        \"yaml_parse_url(string $url, int $pos = 0, int &$ndocs = ?, array $callbacks = null): mixed\",\n        \"Parse a Yaml stream from a URL\"\n     ],\n     \"yaml_parse\": [\n        \"yaml_parse(string $input, int $pos = 0, int &$ndocs = ?, array $callbacks = null): mixed\",\n        \"Parse a YAML stream\"\n     ],\n     \"zlib_decode\": [\n        \"zlib_decode(string $data, int $max_length = 0): string|false\",\n        \"Uncompress any raw/gzip/zlib encoded data\"\n     ],\n     \"zlib_encode\": [\n        \"zlib_encode(string $data, int $encoding, int $level = -1): string|false\",\n        \"Compress data with the specified encoding\"\n     ]\n};\n\nvar variableMap = {\n    \"$_COOKIE\": {\n        type: \"array\"\n    },\n    \"$_ENV\": {\n        type: \"array\"\n    },\n    \"$_FILES\": {\n        type: \"array\"\n    },\n    \"$_GET\": {\n        type: \"array\"\n    },\n    \"$_POST\": {\n        type: \"array\"\n    },\n    \"$_REQUEST\": {\n        type: \"array\"\n    },\n    \"$_SERVER\": {\n        type: \"array\",\n        value: {\n            \"DOCUMENT_ROOT\":  1,\n            \"GATEWAY_INTERFACE\":  1,\n            \"HTTP_ACCEPT\":  1,\n            \"HTTP_ACCEPT_CHARSET\":  1,\n            \"HTTP_ACCEPT_ENCODING\":  1 ,\n            \"HTTP_ACCEPT_LANGUAGE\":  1,\n            \"HTTP_CONNECTION\":  1,\n            \"HTTP_HOST\":  1,\n            \"HTTP_REFERER\":  1,\n            \"HTTP_USER_AGENT\":  1,\n            \"PATH_TRANSLATED\":  1,\n            \"PHP_SELF\":  1,\n            \"QUERY_STRING\":  1,\n            \"REMOTE_ADDR\":  1,\n            \"REMOTE_PORT\":  1,\n            \"REQUEST_METHOD\":  1,\n            \"REQUEST_URI\":  1,\n            \"SCRIPT_FILENAME\":  1,\n            \"SCRIPT_NAME\":  1,\n            \"SERVER_ADMIN\":  1,\n            \"SERVER_NAME\":  1,\n            \"SERVER_PORT\":  1,\n            \"SERVER_PROTOCOL\":  1,\n            \"SERVER_SIGNATURE\":  1,\n            \"SERVER_SOFTWARE\":  1,\n            \"argv\":  1,\n            \"argc\":  1\n        }\n    },\n    \"$_SESSION\": {\n        type: \"array\"\n    },\n    \"$GLOBALS\": {\n        type: \"array\"\n    },\n    '$argv': {\n        type: \"array\"\n    },\n    '$argc': {\n        type: \"int\"\n    }\n};\n\nfunction is(token, type) {\n    return token.type.lastIndexOf(type) > -1;\n}\n\nvar PhpCompletions = function() {\n\n};\n\n(function() {\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        var token = session.getTokenAt(pos.row, pos.column);\n\n        if (!token)\n            return [];\n        \n        if (token.type==='support.php_tag' && token.value==='<?')\n            return this.getTagCompletions(state, session, pos, prefix);\n\n        // php function\n        if (token.type==='identifier') {\n            if (token.index > 0) {\n                var prevToken = session.getTokenAt(pos.row, token.start);\n                if (prevToken.type==='support.php_tag') {\n                    return this.getTagCompletions(state, session, pos, prefix);\n                }\n            }\n            return this.getFunctionCompletions(state, session, pos, prefix);\n        }\n\n        // php variable\n        if (is(token, \"variable\"))\n            return this.getVariableCompletions(state, session, pos, prefix);\n\n        // php array key\n        var line = session.getLine(pos.row).substr(0, pos.column);\n        if (token.type==='string' && /(\\$[\\w]*)\\[[\"']([^'\"]*)$/i.test(line))\n            return this.getArrayKeyCompletions(state, session, pos, prefix);\n\n        return [];\n    };\n    \n    this.getTagCompletions = function(state, session, pos, prefix) {\n        return [{\n            caption: 'php',\n            value: 'php',\n            meta: \"php tag\",\n            score: 1000000\n        }, {\n            caption: '=',\n            value: '=',\n            meta: \"php tag\",\n            score: 1000000\n        }];\n    };\n\n    this.getFunctionCompletions = function(state, session, pos, prefix) {\n        var functions = Object.keys(functionMap);\n        return functions.map(function(func){\n            return {\n                caption: func,\n                snippet: func + '($0)',\n                meta: \"php function\",\n                score: 1000000,\n                docHTML: functionMap[func][1]\n            };\n        });\n    };\n\n    this.getVariableCompletions = function(state, session, pos, prefix) {\n        var variables = Object.keys(variableMap);\n        return variables.map(function(variable){\n            return {\n                caption: variable,\n                value: variable,\n                meta: \"php variable\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getArrayKeyCompletions = function(state, session, pos, prefix) {\n        var line = session.getLine(pos.row).substr(0, pos.column);\n        var variable = line.match(/(\\$[\\w]*)\\[[\"']([^'\"]*)$/i)[1];\n\n        if (!variableMap[variable]) {\n            return [];\n        }\n\n        var keys = [];\n        if (variableMap[variable].type==='array' && variableMap[variable].value)\n            keys = Object.keys(variableMap[variable].value);\n\n        return keys.map(function(key) {\n            return {\n                caption: key,\n                value: key,\n                meta: \"php array key\",\n                score: 1000000\n            };\n        });\n    };\n\n}).call(PhpCompletions.prototype);\n\nexports.PhpCompletions = PhpCompletions;\n"
  },
  {
    "path": "src/mode/php_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar PhpLangHighlightRules = function() {\n    var docComment = DocCommentHighlightRules;\n    // http://php.net/quickref.php\n    var builtinFunctions = lang.arrayToMap(\n'abs|acos|acosh|addcslashes|addslashes|aggregate|aggregate_info|aggregate_methods|aggregate_methods_by_list|aggregate_methods_by_regexp|\\\naggregate_properties|aggregate_properties_by_list|aggregate_properties_by_regexp|aggregation_info|amqpconnection|amqpexchange|amqpqueue|\\\napache_child_terminate|apache_get_modules|apache_get_version|apache_getenv|apache_lookup_uri|apache_note|apache_request_headers|\\\napache_reset_timeout|apache_response_headers|apache_setenv|apc_add|apc_bin_dump|apc_bin_dumpfile|apc_bin_load|apc_bin_loadfile|\\\napc_cache_info|apc_cas|apc_clear_cache|apc_compile_file|apc_dec|apc_define_constants|apc_delete|apc_delete_file|apc_exists|apc_fetch|\\\napc_inc|apc_load_constants|apc_sma_info|apc_store|apciterator|apd_breakpoint|apd_callstack|apd_clunk|apd_continue|apd_croak|\\\napd_dump_function_table|apd_dump_persistent_resources|apd_dump_regular_resources|apd_echo|apd_get_active_symbols|apd_set_pprof_trace|\\\napd_set_session|apd_set_session_trace|apd_set_session_trace_socket|appenditerator|array|array_change_key_case|array_chunk|array_column|array_combine|\\\narray_count_values|array_diff|array_diff_assoc|array_diff_key|array_diff_uassoc|array_diff_ukey|array_fill|array_fill_keys|array_filter|\\\narray_flip|array_intersect|array_intersect_assoc|array_intersect_key|array_intersect_uassoc|array_intersect_ukey|array_key_exists|\\\narray_keys|array_map|array_merge|array_merge_recursive|array_multisort|array_pad|array_pop|array_product|array_push|array_rand|\\\narray_reduce|array_replace|array_replace_recursive|array_reverse|array_search|array_shift|array_slice|array_splice|array_sum|array_udiff|\\\narray_udiff_assoc|array_udiff_uassoc|array_uintersect|array_uintersect_assoc|array_uintersect_uassoc|array_unique|array_unshift|\\\narray_values|array_walk|array_walk_recursive|arrayaccess|arrayiterator|arrayobject|arsort|asin|asinh|asort|assert|assert_options|atan|\\\natan2|atanh|audioproperties|badfunctioncallexception|badmethodcallexception|base64_decode|base64_encode|base_convert|basename|\\\nbbcode_add_element|bbcode_add_smiley|bbcode_create|bbcode_destroy|bbcode_parse|bbcode_set_arg_parser|bbcode_set_flags|bcadd|bccomp|bcdiv|\\\nbcmod|bcmul|bcompiler_load|bcompiler_load_exe|bcompiler_parse_class|bcompiler_read|bcompiler_write_class|bcompiler_write_constant|\\\nbcompiler_write_exe_footer|bcompiler_write_file|bcompiler_write_footer|bcompiler_write_function|bcompiler_write_functions_from_file|\\\nbcompiler_write_header|bcompiler_write_included_filename|bcpow|bcpowmod|bcscale|bcsqrt|bcsub|bin2hex|bind_textdomain_codeset|bindec|\\\nbindtextdomain|bson_decode|bson_encode|bumpValue|bzclose|bzcompress|bzdecompress|bzerrno|bzerror|bzerrstr|bzflush|bzopen|bzread|bzwrite|\\\ncachingiterator|cairo|cairo_create|cairo_font_face_get_type|cairo_font_face_status|cairo_font_options_create|cairo_font_options_equal|\\\ncairo_font_options_get_antialias|cairo_font_options_get_hint_metrics|cairo_font_options_get_hint_style|\\\ncairo_font_options_get_subpixel_order|cairo_font_options_hash|cairo_font_options_merge|cairo_font_options_set_antialias|\\\ncairo_font_options_set_hint_metrics|cairo_font_options_set_hint_style|cairo_font_options_set_subpixel_order|cairo_font_options_status|\\\ncairo_format_stride_for_width|cairo_image_surface_create|cairo_image_surface_create_for_data|cairo_image_surface_create_from_png|\\\ncairo_image_surface_get_data|cairo_image_surface_get_format|cairo_image_surface_get_height|cairo_image_surface_get_stride|\\\ncairo_image_surface_get_width|cairo_matrix_create_scale|cairo_matrix_create_translate|cairo_matrix_invert|cairo_matrix_multiply|\\\ncairo_matrix_rotate|cairo_matrix_transform_distance|cairo_matrix_transform_point|cairo_matrix_translate|cairo_pattern_add_color_stop_rgb|\\\ncairo_pattern_add_color_stop_rgba|cairo_pattern_create_for_surface|cairo_pattern_create_linear|cairo_pattern_create_radial|\\\ncairo_pattern_create_rgb|cairo_pattern_create_rgba|cairo_pattern_get_color_stop_count|cairo_pattern_get_color_stop_rgba|\\\ncairo_pattern_get_extend|cairo_pattern_get_filter|cairo_pattern_get_linear_points|cairo_pattern_get_matrix|\\\ncairo_pattern_get_radial_circles|cairo_pattern_get_rgba|cairo_pattern_get_surface|cairo_pattern_get_type|cairo_pattern_set_extend|\\\ncairo_pattern_set_filter|cairo_pattern_set_matrix|cairo_pattern_status|cairo_pdf_surface_create|cairo_pdf_surface_set_size|\\\ncairo_ps_get_levels|cairo_ps_level_to_string|cairo_ps_surface_create|cairo_ps_surface_dsc_begin_page_setup|\\\ncairo_ps_surface_dsc_begin_setup|cairo_ps_surface_dsc_comment|cairo_ps_surface_get_eps|cairo_ps_surface_restrict_to_level|\\\ncairo_ps_surface_set_eps|cairo_ps_surface_set_size|cairo_scaled_font_create|cairo_scaled_font_extents|cairo_scaled_font_get_ctm|\\\ncairo_scaled_font_get_font_face|cairo_scaled_font_get_font_matrix|cairo_scaled_font_get_font_options|cairo_scaled_font_get_scale_matrix|\\\ncairo_scaled_font_get_type|cairo_scaled_font_glyph_extents|cairo_scaled_font_status|cairo_scaled_font_text_extents|\\\ncairo_surface_copy_page|cairo_surface_create_similar|cairo_surface_finish|cairo_surface_flush|cairo_surface_get_content|\\\ncairo_surface_get_device_offset|cairo_surface_get_font_options|cairo_surface_get_type|cairo_surface_mark_dirty|\\\ncairo_surface_mark_dirty_rectangle|cairo_surface_set_device_offset|cairo_surface_set_fallback_resolution|cairo_surface_show_page|\\\ncairo_surface_status|cairo_surface_write_to_png|cairo_svg_surface_create|cairo_svg_surface_restrict_to_version|\\\ncairo_svg_version_to_string|cairoantialias|cairocontent|cairocontext|cairoexception|cairoextend|cairofillrule|cairofilter|cairofontface|\\\ncairofontoptions|cairofontslant|cairofonttype|cairofontweight|cairoformat|cairogradientpattern|cairohintmetrics|cairohintstyle|\\\ncairoimagesurface|cairolineargradient|cairolinecap|cairolinejoin|cairomatrix|cairooperator|cairopath|cairopattern|cairopatterntype|\\\ncairopdfsurface|cairopslevel|cairopssurface|cairoradialgradient|cairoscaledfont|cairosolidpattern|cairostatus|cairosubpixelorder|\\\ncairosurface|cairosurfacepattern|cairosurfacetype|cairosvgsurface|cairosvgversion|cairotoyfontface|cal_days_in_month|cal_from_jd|cal_info|\\\ncal_to_jd|calcul_hmac|calculhmac|call_user_func|call_user_func_array|call_user_method|call_user_method_array|callbackfilteriterator|ceil|\\\nchdb|chdb_create|chdir|checkdate|checkdnsrr|chgrp|chmod|chop|chown|chr|chroot|chunk_split|class_alias|class_exists|class_implements|\\\nclass_parents|class_uses|classkit_import|classkit_method_add|classkit_method_copy|classkit_method_redefine|classkit_method_remove|\\\nclasskit_method_rename|clearstatcache|clone|closedir|closelog|collator|com|com_addref|com_create_guid|com_event_sink|com_get|\\\ncom_get_active_object|com_invoke|com_isenum|com_load|com_load_typelib|com_message_pump|com_print_typeinfo|com_propget|com_propput|\\\ncom_propset|com_release|com_set|compact|connection_aborted|connection_status|connection_timeout|constant|construct|construct|construct|\\\nconvert_cyr_string|convert_uudecode|convert_uuencode|copy|cos|cosh|count|count_chars|countable|counter_bump|counter_bump_value|\\\ncounter_create|counter_get|counter_get_meta|counter_get_named|counter_get_value|counter_reset|counter_reset_value|crack_check|\\\ncrack_closedict|crack_getlastmessage|crack_opendict|crc32|create_function|crypt|ctype_alnum|ctype_alpha|ctype_cntrl|ctype_digit|\\\nctype_graph|ctype_lower|ctype_print|ctype_punct|ctype_space|ctype_upper|ctype_xdigit|cubrid_affected_rows|cubrid_bind|\\\ncubrid_client_encoding|cubrid_close|cubrid_close_prepare|cubrid_close_request|cubrid_col_get|cubrid_col_size|cubrid_column_names|\\\ncubrid_column_types|cubrid_commit|cubrid_connect|cubrid_connect_with_url|cubrid_current_oid|cubrid_data_seek|cubrid_db_name|\\\ncubrid_disconnect|cubrid_drop|cubrid_errno|cubrid_error|cubrid_error_code|cubrid_error_code_facility|cubrid_error_msg|cubrid_execute|\\\ncubrid_fetch|cubrid_fetch_array|cubrid_fetch_assoc|cubrid_fetch_field|cubrid_fetch_lengths|cubrid_fetch_object|cubrid_fetch_row|\\\ncubrid_field_flags|cubrid_field_len|cubrid_field_name|cubrid_field_seek|cubrid_field_table|cubrid_field_type|cubrid_free_result|\\\ncubrid_get|cubrid_get_autocommit|cubrid_get_charset|cubrid_get_class_name|cubrid_get_client_info|cubrid_get_db_parameter|\\\ncubrid_get_server_info|cubrid_insert_id|cubrid_is_instance|cubrid_list_dbs|cubrid_load_from_glo|cubrid_lob_close|cubrid_lob_export|\\\ncubrid_lob_get|cubrid_lob_send|cubrid_lob_size|cubrid_lock_read|cubrid_lock_write|cubrid_move_cursor|cubrid_new_glo|cubrid_next_result|\\\ncubrid_num_cols|cubrid_num_fields|cubrid_num_rows|cubrid_ping|cubrid_prepare|cubrid_put|cubrid_query|cubrid_real_escape_string|\\\ncubrid_result|cubrid_rollback|cubrid_save_to_glo|cubrid_schema|cubrid_send_glo|cubrid_seq_drop|cubrid_seq_insert|cubrid_seq_put|\\\ncubrid_set_add|cubrid_set_autocommit|cubrid_set_db_parameter|cubrid_set_drop|cubrid_unbuffered_query|cubrid_version|curl_close|\\\ncurl_copy_handle|curl_errno|curl_error|curl_exec|curl_getinfo|curl_init|curl_multi_add_handle|curl_multi_close|curl_multi_exec|\\\ncurl_multi_getcontent|curl_multi_info_read|curl_multi_init|curl_multi_remove_handle|curl_multi_select|curl_setopt|curl_setopt_array|\\\ncurl_version|current|cyrus_authenticate|cyrus_bind|cyrus_close|cyrus_connect|cyrus_query|cyrus_unbind|date|date_add|date_create|\\\ndate_create_from_format|date_date_set|date_default_timezone_get|date_default_timezone_set|date_diff|date_format|date_get_last_errors|\\\ndate_interval_create_from_date_string|date_interval_format|date_isodate_set|date_modify|date_offset_get|date_parse|date_parse_from_format|\\\ndate_sub|date_sun_info|date_sunrise|date_sunset|date_time_set|date_timestamp_get|date_timestamp_set|date_timezone_get|date_timezone_set|\\\ndateinterval|dateperiod|datetime|datetimezone|db2_autocommit|db2_bind_param|db2_client_info|db2_close|db2_column_privileges|db2_columns|\\\ndb2_commit|db2_conn_error|db2_conn_errormsg|db2_connect|db2_cursor_type|db2_escape_string|db2_exec|db2_execute|db2_fetch_array|\\\ndb2_fetch_assoc|db2_fetch_both|db2_fetch_object|db2_fetch_row|db2_field_display_size|db2_field_name|db2_field_num|db2_field_precision|\\\ndb2_field_scale|db2_field_type|db2_field_width|db2_foreign_keys|db2_free_result|db2_free_stmt|db2_get_option|db2_last_insert_id|\\\ndb2_lob_read|db2_next_result|db2_num_fields|db2_num_rows|db2_pclose|db2_pconnect|db2_prepare|db2_primary_keys|db2_procedure_columns|\\\ndb2_procedures|db2_result|db2_rollback|db2_server_info|db2_set_option|db2_special_columns|db2_statistics|db2_stmt_error|db2_stmt_errormsg|\\\ndb2_table_privileges|db2_tables|dba_close|dba_delete|dba_exists|dba_fetch|dba_firstkey|dba_handlers|dba_insert|dba_key_split|dba_list|\\\ndba_nextkey|dba_open|dba_optimize|dba_popen|dba_replace|dba_sync|dbase_add_record|dbase_close|dbase_create|dbase_delete_record|\\\ndbase_get_header_info|dbase_get_record|dbase_get_record_with_names|dbase_numfields|dbase_numrecords|dbase_open|dbase_pack|\\\ndbase_replace_record|dbplus_add|dbplus_aql|dbplus_chdir|dbplus_close|dbplus_curr|dbplus_errcode|dbplus_errno|dbplus_find|dbplus_first|\\\ndbplus_flush|dbplus_freealllocks|dbplus_freelock|dbplus_freerlocks|dbplus_getlock|dbplus_getunique|dbplus_info|dbplus_last|dbplus_lockrel|\\\ndbplus_next|dbplus_open|dbplus_prev|dbplus_rchperm|dbplus_rcreate|dbplus_rcrtexact|dbplus_rcrtlike|dbplus_resolve|dbplus_restorepos|\\\ndbplus_rkeys|dbplus_ropen|dbplus_rquery|dbplus_rrename|dbplus_rsecindex|dbplus_runlink|dbplus_rzap|dbplus_savepos|dbplus_setindex|\\\ndbplus_setindexbynumber|dbplus_sql|dbplus_tcl|dbplus_tremove|dbplus_undo|dbplus_undoprepare|dbplus_unlockrel|dbplus_unselect|\\\ndbplus_update|dbplus_xlockrel|dbplus_xunlockrel|dbx_close|dbx_compare|dbx_connect|dbx_error|dbx_escape_string|dbx_fetch_row|dbx_query|\\\ndbx_sort|dcgettext|dcngettext|deaggregate|debug_backtrace|debug_print_backtrace|debug_zval_dump|decbin|dechex|decoct|define|\\\ndefine_syslog_variables|defined|deg2rad|delete|dgettext|die|dio_close|dio_fcntl|dio_open|dio_read|dio_seek|dio_stat|dio_tcsetattr|\\\ndio_truncate|dio_write|dir|directoryiterator|dirname|disk_free_space|disk_total_space|diskfreespace|dl|dngettext|dns_check_record|\\\ndns_get_mx|dns_get_record|dom_import_simplexml|domainexception|domattr|domattribute_name|domattribute_set_value|domattribute_specified|\\\ndomattribute_value|domcharacterdata|domcomment|domdocument|domdocument_add_root|domdocument_create_attribute|\\\ndomdocument_create_cdata_section|domdocument_create_comment|domdocument_create_element|domdocument_create_element_ns|\\\ndomdocument_create_entity_reference|domdocument_create_processing_instruction|domdocument_create_text_node|domdocument_doctype|\\\ndomdocument_document_element|domdocument_dump_file|domdocument_dump_mem|domdocument_get_element_by_id|domdocument_get_elements_by_tagname|\\\ndomdocument_html_dump_mem|domdocument_xinclude|domdocumentfragment|domdocumenttype|domdocumenttype_entities|\\\ndomdocumenttype_internal_subset|domdocumenttype_name|domdocumenttype_notations|domdocumenttype_public_id|domdocumenttype_system_id|\\\ndomelement|domelement_get_attribute|domelement_get_attribute_node|domelement_get_elements_by_tagname|domelement_has_attribute|\\\ndomelement_remove_attribute|domelement_set_attribute|domelement_set_attribute_node|domelement_tagname|domentity|domentityreference|\\\ndomexception|domimplementation|domnamednodemap|domnode|domnode_add_namespace|domnode_append_child|domnode_append_sibling|\\\ndomnode_attributes|domnode_child_nodes|domnode_clone_node|domnode_dump_node|domnode_first_child|domnode_get_content|\\\ndomnode_has_attributes|domnode_has_child_nodes|domnode_insert_before|domnode_is_blank_node|domnode_last_child|domnode_next_sibling|\\\ndomnode_node_name|domnode_node_type|domnode_node_value|domnode_owner_document|domnode_parent_node|domnode_prefix|domnode_previous_sibling|\\\ndomnode_remove_child|domnode_replace_child|domnode_replace_node|domnode_set_content|domnode_set_name|domnode_set_namespace|\\\ndomnode_unlink_node|domnodelist|domnotation|domprocessinginstruction|domprocessinginstruction_data|domprocessinginstruction_target|\\\ndomtext|domxml_new_doc|domxml_open_file|domxml_open_mem|domxml_version|domxml_xmltree|domxml_xslt_stylesheet|domxml_xslt_stylesheet_doc|\\\ndomxml_xslt_stylesheet_file|domxml_xslt_version|domxpath|domxsltstylesheet_process|domxsltstylesheet_result_dump_file|\\\ndomxsltstylesheet_result_dump_mem|dotnet|dotnet_load|doubleval|each|easter_date|easter_days|echo|empty|emptyiterator|\\\nenchant_broker_describe|enchant_broker_dict_exists|enchant_broker_free|enchant_broker_free_dict|enchant_broker_get_error|\\\nenchant_broker_init|enchant_broker_list_dicts|enchant_broker_request_dict|enchant_broker_request_pwl_dict|enchant_broker_set_ordering|\\\nenchant_dict_add_to_personal|enchant_dict_add_to_session|enchant_dict_check|enchant_dict_describe|enchant_dict_get_error|\\\nenchant_dict_is_in_session|enchant_dict_quick_check|enchant_dict_store_replacement|enchant_dict_suggest|end|ereg|ereg_replace|eregi|\\\neregi_replace|error_get_last|error_log|error_reporting|errorexception|escapeshellarg|escapeshellcmd|eval|event_add|event_base_free|\\\nevent_base_loop|event_base_loopbreak|event_base_loopexit|event_base_new|event_base_priority_init|event_base_set|event_buffer_base_set|\\\nevent_buffer_disable|event_buffer_enable|event_buffer_fd_set|event_buffer_free|event_buffer_new|event_buffer_priority_set|\\\nevent_buffer_read|event_buffer_set_callback|event_buffer_timeout_set|event_buffer_watermark_set|event_buffer_write|event_del|event_free|\\\nevent_new|event_set|exception|exec|exif_imagetype|exif_read_data|exif_tagname|exif_thumbnail|exit|exp|expect_expectl|expect_popen|explode|\\\nexpm1|export|export|extension_loaded|extract|ezmlm_hash|fam_cancel_monitor|fam_close|fam_monitor_collection|fam_monitor_directory|\\\nfam_monitor_file|fam_next_event|fam_open|fam_pending|fam_resume_monitor|fam_suspend_monitor|fbsql_affected_rows|fbsql_autocommit|\\\nfbsql_blob_size|fbsql_change_user|fbsql_clob_size|fbsql_close|fbsql_commit|fbsql_connect|fbsql_create_blob|fbsql_create_clob|\\\nfbsql_create_db|fbsql_data_seek|fbsql_database|fbsql_database_password|fbsql_db_query|fbsql_db_status|fbsql_drop_db|fbsql_errno|\\\nfbsql_error|fbsql_fetch_array|fbsql_fetch_assoc|fbsql_fetch_field|fbsql_fetch_lengths|fbsql_fetch_object|fbsql_fetch_row|\\\nfbsql_field_flags|fbsql_field_len|fbsql_field_name|fbsql_field_seek|fbsql_field_table|fbsql_field_type|fbsql_free_result|\\\nfbsql_get_autostart_info|fbsql_hostname|fbsql_insert_id|fbsql_list_dbs|fbsql_list_fields|fbsql_list_tables|fbsql_next_result|\\\nfbsql_num_fields|fbsql_num_rows|fbsql_password|fbsql_pconnect|fbsql_query|fbsql_read_blob|fbsql_read_clob|fbsql_result|fbsql_rollback|\\\nfbsql_rows_fetched|fbsql_select_db|fbsql_set_characterset|fbsql_set_lob_mode|fbsql_set_password|fbsql_set_transaction|fbsql_start_db|\\\nfbsql_stop_db|fbsql_table_name|fbsql_tablename|fbsql_username|fbsql_warnings|fclose|fdf_add_doc_javascript|fdf_add_template|fdf_close|\\\nfdf_create|fdf_enum_values|fdf_errno|fdf_error|fdf_get_ap|fdf_get_attachment|fdf_get_encoding|fdf_get_file|fdf_get_flags|fdf_get_opt|\\\nfdf_get_status|fdf_get_value|fdf_get_version|fdf_header|fdf_next_field_name|fdf_open|fdf_open_string|fdf_remove_item|fdf_save|\\\nfdf_save_string|fdf_set_ap|fdf_set_encoding|fdf_set_file|fdf_set_flags|fdf_set_javascript_action|fdf_set_on_import_javascript|fdf_set_opt|\\\nfdf_set_status|fdf_set_submit_form_action|fdf_set_target_frame|fdf_set_value|fdf_set_version|feof|fflush|fgetc|fgetcsv|fgets|fgetss|file|\\\nfile_exists|file_get_contents|file_put_contents|fileatime|filectime|filegroup|fileinode|filemtime|fileowner|fileperms|filepro|\\\nfilepro_fieldcount|filepro_fieldname|filepro_fieldtype|filepro_fieldwidth|filepro_retrieve|filepro_rowcount|filesize|filesystemiterator|\\\nfiletype|filter_has_var|filter_id|filter_input|filter_input_array|filter_list|filter_var|filter_var_array|filteriterator|finfo_buffer|\\\nfinfo_close|finfo_file|finfo_open|finfo_set_flags|floatval|flock|floor|flush|fmod|fnmatch|fopen|forward_static_call|\\\nforward_static_call_array|fpassthru|fprintf|fputcsv|fputs|fread|frenchtojd|fribidi_log2vis|fscanf|fseek|fsockopen|fstat|ftell|ftok|\\\nftp_alloc|ftp_cdup|ftp_chdir|ftp_chmod|ftp_close|ftp_connect|ftp_delete|ftp_exec|ftp_fget|ftp_fput|ftp_get|ftp_get_option|ftp_login|\\\nftp_mdtm|ftp_mkdir|ftp_nb_continue|ftp_nb_fget|ftp_nb_fput|ftp_nb_get|ftp_nb_put|ftp_nlist|ftp_pasv|ftp_put|ftp_pwd|ftp_quit|ftp_raw|\\\nftp_rawlist|ftp_rename|ftp_rmdir|ftp_set_option|ftp_site|ftp_size|ftp_ssl_connect|ftp_systype|ftruncate|func_get_arg|func_get_args|\\\nfunc_num_args|function_exists|fwrite|gc_collect_cycles|gc_disable|gc_enable|gc_enabled|gd_info|gearmanclient|gearmanjob|gearmantask|\\\ngearmanworker|geoip_continent_code_by_name|geoip_country_code3_by_name|geoip_country_code_by_name|geoip_country_name_by_name|\\\ngeoip_database_info|geoip_db_avail|geoip_db_filename|geoip_db_get_all_info|geoip_id_by_name|geoip_isp_by_name|geoip_org_by_name|\\\ngeoip_record_by_name|geoip_region_by_name|geoip_region_name_by_code|geoip_time_zone_by_country_and_region|getMeta|getNamed|getValue|\\\nget_browser|get_called_class|get_cfg_var|get_class|get_class_methods|get_class_vars|get_current_user|get_declared_classes|\\\nget_declared_interfaces|get_declared_traits|get_defined_constants|get_defined_functions|get_defined_vars|get_extension_funcs|get_headers|\\\nget_html_translation_table|get_include_path|get_included_files|get_loaded_extensions|get_magic_quotes_gpc|get_magic_quotes_runtime|\\\nget_meta_tags|get_object_vars|get_parent_class|get_required_files|get_resource_type|getallheaders|getconstant|getconstants|getconstructor|\\\ngetcwd|getdate|getdefaultproperties|getdoccomment|getendline|getenv|getextension|getextensionname|getfilename|gethostbyaddr|gethostbyname|\\\ngethostbynamel|gethostname|getimagesize|getinterfacenames|getinterfaces|getlastmod|getmethod|getmethods|getmodifiers|getmxrr|getmygid|\\\ngetmyinode|getmypid|getmyuid|getname|getnamespacename|getopt|getparentclass|getproperties|getproperty|getprotobyname|getprotobynumber|\\\ngetrandmax|getrusage|getservbyname|getservbyport|getshortname|getstartline|getstaticproperties|getstaticpropertyvalue|gettext|\\\ngettimeofday|gettype|glob|globiterator|gmagick|gmagickdraw|gmagickpixel|gmdate|gmmktime|gmp_abs|gmp_add|gmp_and|gmp_clrbit|gmp_cmp|\\\ngmp_com|gmp_div|gmp_div_q|gmp_div_qr|gmp_div_r|gmp_divexact|gmp_fact|gmp_gcd|gmp_gcdext|gmp_hamdist|gmp_init|gmp_intval|gmp_invert|\\\ngmp_jacobi|gmp_legendre|gmp_mod|gmp_mul|gmp_neg|gmp_nextprime|gmp_or|gmp_perfect_square|gmp_popcount|gmp_pow|gmp_powm|gmp_prob_prime|\\\ngmp_random|gmp_scan0|gmp_scan1|gmp_setbit|gmp_sign|gmp_sqrt|gmp_sqrtrem|gmp_strval|gmp_sub|gmp_testbit|gmp_xor|gmstrftime|\\\ngnupg_adddecryptkey|gnupg_addencryptkey|gnupg_addsignkey|gnupg_cleardecryptkeys|gnupg_clearencryptkeys|gnupg_clearsignkeys|gnupg_decrypt|\\\ngnupg_decryptverify|gnupg_encrypt|gnupg_encryptsign|gnupg_export|gnupg_geterror|gnupg_getprotocol|gnupg_import|gnupg_init|gnupg_keyinfo|\\\ngnupg_setarmor|gnupg_seterrormode|gnupg_setsignmode|gnupg_sign|gnupg_verify|gopher_parsedir|grapheme_extract|grapheme_stripos|\\\ngrapheme_stristr|grapheme_strlen|grapheme_strpos|grapheme_strripos|grapheme_strrpos|grapheme_strstr|grapheme_substr|gregoriantojd|\\\ngupnp_context_get_host_ip|gupnp_context_get_port|gupnp_context_get_subscription_timeout|gupnp_context_host_path|gupnp_context_new|\\\ngupnp_context_set_subscription_timeout|gupnp_context_timeout_add|gupnp_context_unhost_path|gupnp_control_point_browse_start|\\\ngupnp_control_point_browse_stop|gupnp_control_point_callback_set|gupnp_control_point_new|gupnp_device_action_callback_set|\\\ngupnp_device_info_get|gupnp_device_info_get_service|gupnp_root_device_get_available|gupnp_root_device_get_relative_location|\\\ngupnp_root_device_new|gupnp_root_device_set_available|gupnp_root_device_start|gupnp_root_device_stop|gupnp_service_action_get|\\\ngupnp_service_action_return|gupnp_service_action_return_error|gupnp_service_action_set|gupnp_service_freeze_notify|gupnp_service_info_get|\\\ngupnp_service_info_get_introspection|gupnp_service_introspection_get_state_variable|gupnp_service_notify|gupnp_service_proxy_action_get|\\\ngupnp_service_proxy_action_set|gupnp_service_proxy_add_notify|gupnp_service_proxy_callback_set|gupnp_service_proxy_get_subscribed|\\\ngupnp_service_proxy_remove_notify|gupnp_service_proxy_set_subscribed|gupnp_service_thaw_notify|gzclose|gzcompress|gzdecode|gzdeflate|\\\ngzencode|gzeof|gzfile|gzgetc|gzgets|gzgetss|gzinflate|gzopen|gzpassthru|gzputs|gzread|gzrewind|gzseek|gztell|gzuncompress|gzwrite|\\\nhalt_compiler|haruannotation|haruannotation_setborderstyle|haruannotation_sethighlightmode|haruannotation_seticon|\\\nharuannotation_setopened|harudestination|harudestination_setfit|harudestination_setfitb|harudestination_setfitbh|harudestination_setfitbv|\\\nharudestination_setfith|harudestination_setfitr|harudestination_setfitv|harudestination_setxyz|harudoc|harudoc_addpage|\\\nharudoc_addpagelabel|harudoc_construct|harudoc_createoutline|harudoc_getcurrentencoder|harudoc_getcurrentpage|harudoc_getencoder|\\\nharudoc_getfont|harudoc_getinfoattr|harudoc_getpagelayout|harudoc_getpagemode|harudoc_getstreamsize|harudoc_insertpage|harudoc_loadjpeg|\\\nharudoc_loadpng|harudoc_loadraw|harudoc_loadttc|harudoc_loadttf|harudoc_loadtype1|harudoc_output|harudoc_readfromstream|\\\nharudoc_reseterror|harudoc_resetstream|harudoc_save|harudoc_savetostream|harudoc_setcompressionmode|harudoc_setcurrentencoder|\\\nharudoc_setencryptionmode|harudoc_setinfoattr|harudoc_setinfodateattr|harudoc_setopenaction|harudoc_setpagelayout|harudoc_setpagemode|\\\nharudoc_setpagesconfiguration|harudoc_setpassword|harudoc_setpermission|harudoc_usecnsencodings|harudoc_usecnsfonts|\\\nharudoc_usecntencodings|harudoc_usecntfonts|harudoc_usejpencodings|harudoc_usejpfonts|harudoc_usekrencodings|harudoc_usekrfonts|\\\nharuencoder|haruencoder_getbytetype|haruencoder_gettype|haruencoder_getunicode|haruencoder_getwritingmode|haruexception|harufont|\\\nharufont_getascent|harufont_getcapheight|harufont_getdescent|harufont_getencodingname|harufont_getfontname|harufont_gettextwidth|\\\nharufont_getunicodewidth|harufont_getxheight|harufont_measuretext|haruimage|haruimage_getbitspercomponent|haruimage_getcolorspace|\\\nharuimage_getheight|haruimage_getsize|haruimage_getwidth|haruimage_setcolormask|haruimage_setmaskimage|haruoutline|\\\nharuoutline_setdestination|haruoutline_setopened|harupage|harupage_arc|harupage_begintext|harupage_circle|harupage_closepath|\\\nharupage_concat|harupage_createdestination|harupage_createlinkannotation|harupage_createtextannotation|harupage_createurlannotation|\\\nharupage_curveto|harupage_curveto2|harupage_curveto3|harupage_drawimage|harupage_ellipse|harupage_endpath|harupage_endtext|\\\nharupage_eofill|harupage_eofillstroke|harupage_fill|harupage_fillstroke|harupage_getcharspace|harupage_getcmykfill|harupage_getcmykstroke|\\\nharupage_getcurrentfont|harupage_getcurrentfontsize|harupage_getcurrentpos|harupage_getcurrenttextpos|harupage_getdash|\\\nharupage_getfillingcolorspace|harupage_getflatness|harupage_getgmode|harupage_getgrayfill|harupage_getgraystroke|harupage_getheight|\\\nharupage_gethorizontalscaling|harupage_getlinecap|harupage_getlinejoin|harupage_getlinewidth|harupage_getmiterlimit|harupage_getrgbfill|\\\nharupage_getrgbstroke|harupage_getstrokingcolorspace|harupage_gettextleading|harupage_gettextmatrix|harupage_gettextrenderingmode|\\\nharupage_gettextrise|harupage_gettextwidth|harupage_gettransmatrix|harupage_getwidth|harupage_getwordspace|harupage_lineto|\\\nharupage_measuretext|harupage_movetextpos|harupage_moveto|harupage_movetonextline|harupage_rectangle|harupage_setcharspace|\\\nharupage_setcmykfill|harupage_setcmykstroke|harupage_setdash|harupage_setflatness|harupage_setfontandsize|harupage_setgrayfill|\\\nharupage_setgraystroke|harupage_setheight|harupage_sethorizontalscaling|harupage_setlinecap|harupage_setlinejoin|harupage_setlinewidth|\\\nharupage_setmiterlimit|harupage_setrgbfill|harupage_setrgbstroke|harupage_setrotate|harupage_setsize|harupage_setslideshow|\\\nharupage_settextleading|harupage_settextmatrix|harupage_settextrenderingmode|harupage_settextrise|harupage_setwidth|harupage_setwordspace|\\\nharupage_showtext|harupage_showtextnextline|harupage_stroke|harupage_textout|harupage_textrect|hasconstant|hash|hash_algos|hash_copy|\\\nhash_file|hash_final|hash_hmac|hash_hmac_file|hash_init|hash_update|hash_update_file|hash_update_stream|hasmethod|hasproperty|header|\\\nheader_register_callback|header_remove|headers_list|headers_sent|hebrev|hebrevc|hex2bin|hexdec|highlight_file|highlight_string|\\\nhtml_entity_decode|htmlentities|htmlspecialchars|htmlspecialchars_decode|http_build_cookie|http_build_query|http_build_str|http_build_url|\\\nhttp_cache_etag|http_cache_last_modified|http_chunked_decode|http_date|http_deflate|http_get|http_get_request_body|\\\nhttp_get_request_body_stream|http_get_request_headers|http_head|http_inflate|http_match_etag|http_match_modified|\\\nhttp_match_request_header|http_negotiate_charset|http_negotiate_content_type|http_negotiate_language|http_parse_cookie|http_parse_headers|\\\nhttp_parse_message|http_parse_params|http_persistent_handles_clean|http_persistent_handles_count|http_persistent_handles_ident|\\\nhttp_post_data|http_post_fields|http_put_data|http_put_file|http_put_stream|http_redirect|http_request|http_request_body_encode|\\\nhttp_request_method_exists|http_request_method_name|http_request_method_register|http_request_method_unregister|http_response_code|\\\nhttp_send_content_disposition|http_send_content_type|http_send_data|http_send_file|http_send_last_modified|http_send_status|\\\nhttp_send_stream|http_support|http_throttle|httpdeflatestream|httpdeflatestream_construct|httpdeflatestream_factory|\\\nhttpdeflatestream_finish|httpdeflatestream_flush|httpdeflatestream_update|httpinflatestream|httpinflatestream_construct|\\\nhttpinflatestream_factory|httpinflatestream_finish|httpinflatestream_flush|httpinflatestream_update|httpmessage|httpmessage_addheaders|\\\nhttpmessage_construct|httpmessage_detach|httpmessage_factory|httpmessage_fromenv|httpmessage_fromstring|httpmessage_getbody|\\\nhttpmessage_getheader|httpmessage_getheaders|httpmessage_gethttpversion|httpmessage_getparentmessage|httpmessage_getrequestmethod|\\\nhttpmessage_getrequesturl|httpmessage_getresponsecode|httpmessage_getresponsestatus|httpmessage_gettype|httpmessage_guesscontenttype|\\\nhttpmessage_prepend|httpmessage_reverse|httpmessage_send|httpmessage_setbody|httpmessage_setheaders|httpmessage_sethttpversion|\\\nhttpmessage_setrequestmethod|httpmessage_setrequesturl|httpmessage_setresponsecode|httpmessage_setresponsestatus|httpmessage_settype|\\\nhttpmessage_tomessagetypeobject|httpmessage_tostring|httpquerystring|httpquerystring_construct|httpquerystring_get|httpquerystring_mod|\\\nhttpquerystring_set|httpquerystring_singleton|httpquerystring_toarray|httpquerystring_tostring|httpquerystring_xlate|httprequest|\\\nhttprequest_addcookies|httprequest_addheaders|httprequest_addpostfields|httprequest_addpostfile|httprequest_addputdata|\\\nhttprequest_addquerydata|httprequest_addrawpostdata|httprequest_addssloptions|httprequest_clearhistory|httprequest_construct|\\\nhttprequest_enablecookies|httprequest_getcontenttype|httprequest_getcookies|httprequest_getheaders|httprequest_gethistory|\\\nhttprequest_getmethod|httprequest_getoptions|httprequest_getpostfields|httprequest_getpostfiles|httprequest_getputdata|\\\nhttprequest_getputfile|httprequest_getquerydata|httprequest_getrawpostdata|httprequest_getrawrequestmessage|\\\nhttprequest_getrawresponsemessage|httprequest_getrequestmessage|httprequest_getresponsebody|httprequest_getresponsecode|\\\nhttprequest_getresponsecookies|httprequest_getresponsedata|httprequest_getresponseheader|httprequest_getresponseinfo|\\\nhttprequest_getresponsemessage|httprequest_getresponsestatus|httprequest_getssloptions|httprequest_geturl|httprequest_resetcookies|\\\nhttprequest_send|httprequest_setcontenttype|httprequest_setcookies|httprequest_setheaders|httprequest_setmethod|httprequest_setoptions|\\\nhttprequest_setpostfields|httprequest_setpostfiles|httprequest_setputdata|httprequest_setputfile|httprequest_setquerydata|\\\nhttprequest_setrawpostdata|httprequest_setssloptions|httprequest_seturl|httprequestpool|httprequestpool_attach|httprequestpool_construct|\\\nhttprequestpool_destruct|httprequestpool_detach|httprequestpool_getattachedrequests|httprequestpool_getfinishedrequests|\\\nhttprequestpool_reset|httprequestpool_send|httprequestpool_socketperform|httprequestpool_socketselect|httpresponse|httpresponse_capture|\\\nhttpresponse_getbuffersize|httpresponse_getcache|httpresponse_getcachecontrol|httpresponse_getcontentdisposition|\\\nhttpresponse_getcontenttype|httpresponse_getdata|httpresponse_getetag|httpresponse_getfile|httpresponse_getgzip|httpresponse_getheader|\\\nhttpresponse_getlastmodified|httpresponse_getrequestbody|httpresponse_getrequestbodystream|httpresponse_getrequestheaders|\\\nhttpresponse_getstream|httpresponse_getthrottledelay|httpresponse_guesscontenttype|httpresponse_redirect|httpresponse_send|\\\nhttpresponse_setbuffersize|httpresponse_setcache|httpresponse_setcachecontrol|httpresponse_setcontentdisposition|\\\nhttpresponse_setcontenttype|httpresponse_setdata|httpresponse_setetag|httpresponse_setfile|httpresponse_setgzip|httpresponse_setheader|\\\nhttpresponse_setlastmodified|httpresponse_setstream|httpresponse_setthrottledelay|httpresponse_status|hw_array2objrec|hw_changeobject|\\\nhw_children|hw_childrenobj|hw_close|hw_connect|hw_connection_info|hw_cp|hw_deleteobject|hw_docbyanchor|hw_docbyanchorobj|\\\nhw_document_attributes|hw_document_bodytag|hw_document_content|hw_document_setcontent|hw_document_size|hw_dummy|hw_edittext|hw_error|\\\nhw_errormsg|hw_free_document|hw_getanchors|hw_getanchorsobj|hw_getandlock|hw_getchildcoll|hw_getchildcollobj|hw_getchilddoccoll|\\\nhw_getchilddoccollobj|hw_getobject|hw_getobjectbyquery|hw_getobjectbyquerycoll|hw_getobjectbyquerycollobj|hw_getobjectbyqueryobj|\\\nhw_getparents|hw_getparentsobj|hw_getrellink|hw_getremote|hw_getremotechildren|hw_getsrcbydestobj|hw_gettext|hw_getusername|hw_identify|\\\nhw_incollections|hw_info|hw_inscoll|hw_insdoc|hw_insertanchors|hw_insertdocument|hw_insertobject|hw_mapid|hw_modifyobject|hw_mv|\\\nhw_new_document|hw_objrec2array|hw_output_document|hw_pconnect|hw_pipedocument|hw_root|hw_setlinkroot|hw_stat|hw_unlock|hw_who|\\\nhwapi_attribute|hwapi_attribute_key|hwapi_attribute_langdepvalue|hwapi_attribute_value|hwapi_attribute_values|hwapi_checkin|\\\nhwapi_checkout|hwapi_children|hwapi_content|hwapi_content_mimetype|hwapi_content_read|hwapi_copy|hwapi_dbstat|hwapi_dcstat|\\\nhwapi_dstanchors|hwapi_dstofsrcanchor|hwapi_error_count|hwapi_error_reason|hwapi_find|hwapi_ftstat|hwapi_hgcsp|hwapi_hwstat|\\\nhwapi_identify|hwapi_info|hwapi_insert|hwapi_insertanchor|hwapi_insertcollection|hwapi_insertdocument|hwapi_link|hwapi_lock|hwapi_move|\\\nhwapi_new_content|hwapi_object|hwapi_object_assign|hwapi_object_attreditable|hwapi_object_count|hwapi_object_insert|hwapi_object_new|\\\nhwapi_object_remove|hwapi_object_title|hwapi_object_value|hwapi_objectbyanchor|hwapi_parents|hwapi_reason_description|hwapi_reason_type|\\\nhwapi_remove|hwapi_replace|hwapi_setcommittedversion|hwapi_srcanchors|hwapi_srcsofdst|hwapi_unlock|hwapi_user|hwapi_userlist|hypot|\\\nibase_add_user|ibase_affected_rows|ibase_backup|ibase_blob_add|ibase_blob_cancel|ibase_blob_close|ibase_blob_create|ibase_blob_echo|\\\nibase_blob_get|ibase_blob_import|ibase_blob_info|ibase_blob_open|ibase_close|ibase_commit|ibase_commit_ret|ibase_connect|ibase_db_info|\\\nibase_delete_user|ibase_drop_db|ibase_errcode|ibase_errmsg|ibase_execute|ibase_fetch_assoc|ibase_fetch_object|ibase_fetch_row|\\\nibase_field_info|ibase_free_event_handler|ibase_free_query|ibase_free_result|ibase_gen_id|ibase_maintain_db|ibase_modify_user|\\\nibase_name_result|ibase_num_fields|ibase_num_params|ibase_param_info|ibase_pconnect|ibase_prepare|ibase_query|ibase_restore|\\\nibase_rollback|ibase_rollback_ret|ibase_server_info|ibase_service_attach|ibase_service_detach|ibase_set_event_handler|ibase_timefmt|\\\nibase_trans|ibase_wait_event|iconv|iconv_get_encoding|iconv_mime_decode|iconv_mime_decode_headers|iconv_mime_encode|iconv_set_encoding|\\\niconv_strlen|iconv_strpos|iconv_strrpos|iconv_substr|id3_get_frame_long_name|id3_get_frame_short_name|id3_get_genre_id|id3_get_genre_list|\\\nid3_get_genre_name|id3_get_tag|id3_get_version|id3_remove_tag|id3_set_tag|id3v2attachedpictureframe|id3v2frame|id3v2tag|idate|\\\nidn_to_ascii|idn_to_unicode|idn_to_utf8|ifx_affected_rows|ifx_blobinfile_mode|ifx_byteasvarchar|ifx_close|ifx_connect|ifx_copy_blob|\\\nifx_create_blob|ifx_create_char|ifx_do|ifx_error|ifx_errormsg|ifx_fetch_row|ifx_fieldproperties|ifx_fieldtypes|ifx_free_blob|\\\nifx_free_char|ifx_free_result|ifx_get_blob|ifx_get_char|ifx_getsqlca|ifx_htmltbl_result|ifx_nullformat|ifx_num_fields|ifx_num_rows|\\\nifx_pconnect|ifx_prepare|ifx_query|ifx_textasvarchar|ifx_update_blob|ifx_update_char|ifxus_close_slob|ifxus_create_slob|ifxus_free_slob|\\\nifxus_open_slob|ifxus_read_slob|ifxus_seek_slob|ifxus_tell_slob|ifxus_write_slob|ignore_user_abort|iis_add_server|iis_get_dir_security|\\\niis_get_script_map|iis_get_server_by_comment|iis_get_server_by_path|iis_get_server_rights|iis_get_service_state|iis_remove_server|\\\niis_set_app_settings|iis_set_dir_security|iis_set_script_map|iis_set_server_rights|iis_start_server|iis_start_service|iis_stop_server|\\\niis_stop_service|image2wbmp|image_type_to_extension|image_type_to_mime_type|imagealphablending|imageantialias|imagearc|imagechar|\\\nimagecharup|imagecolorallocate|imagecolorallocatealpha|imagecolorat|imagecolorclosest|imagecolorclosestalpha|imagecolorclosesthwb|\\\nimagecolordeallocate|imagecolorexact|imagecolorexactalpha|imagecolormatch|imagecolorresolve|imagecolorresolvealpha|imagecolorset|\\\nimagecolorsforindex|imagecolorstotal|imagecolortransparent|imageconvolution|imagecopy|imagecopymerge|imagecopymergegray|\\\nimagecopyresampled|imagecopyresized|imagecreate|imagecreatefromgd|imagecreatefromgd2|imagecreatefromgd2part|imagecreatefromgif|\\\nimagecreatefromjpeg|imagecreatefrompng|imagecreatefromstring|imagecreatefromwbmp|imagecreatefromxbm|imagecreatefromxpm|\\\nimagecreatetruecolor|imagedashedline|imagedestroy|imageellipse|imagefill|imagefilledarc|imagefilledellipse|imagefilledpolygon|\\\nimagefilledrectangle|imagefilltoborder|imagefilter|imagefontheight|imagefontwidth|imageftbbox|imagefttext|imagegammacorrect|imagegd|\\\nimagegd2|imagegif|imagegrabscreen|imagegrabwindow|imageinterlace|imageistruecolor|imagejpeg|imagelayereffect|imageline|imageloadfont|\\\nimagepalettecopy|imagepng|imagepolygon|imagepsbbox|imagepsencodefont|imagepsextendfont|imagepsfreefont|imagepsloadfont|imagepsslantfont|\\\nimagepstext|imagerectangle|imagerotate|imagesavealpha|imagesetbrush|imagesetpixel|imagesetstyle|imagesetthickness|imagesettile|\\\nimagestring|imagestringup|imagesx|imagesy|imagetruecolortopalette|imagettfbbox|imagettftext|imagetypes|imagewbmp|imagexbm|imagick|\\\nimagick_adaptiveblurimage|imagick_adaptiveresizeimage|imagick_adaptivesharpenimage|imagick_adaptivethresholdimage|imagick_addimage|\\\nimagick_addnoiseimage|imagick_affinetransformimage|imagick_animateimages|imagick_annotateimage|imagick_appendimages|imagick_averageimages|\\\nimagick_blackthresholdimage|imagick_blurimage|imagick_borderimage|imagick_charcoalimage|imagick_chopimage|imagick_clear|imagick_clipimage|\\\nimagick_clippathimage|imagick_clone|imagick_clutimage|imagick_coalesceimages|imagick_colorfloodfillimage|imagick_colorizeimage|\\\nimagick_combineimages|imagick_commentimage|imagick_compareimagechannels|imagick_compareimagelayers|imagick_compareimages|\\\nimagick_compositeimage|imagick_construct|imagick_contrastimage|imagick_contraststretchimage|imagick_convolveimage|imagick_cropimage|\\\nimagick_cropthumbnailimage|imagick_current|imagick_cyclecolormapimage|imagick_decipherimage|imagick_deconstructimages|\\\nimagick_deleteimageartifact|imagick_despeckleimage|imagick_destroy|imagick_displayimage|imagick_displayimages|imagick_distortimage|\\\nimagick_drawimage|imagick_edgeimage|imagick_embossimage|imagick_encipherimage|imagick_enhanceimage|imagick_equalizeimage|\\\nimagick_evaluateimage|imagick_extentimage|imagick_flattenimages|imagick_flipimage|imagick_floodfillpaintimage|imagick_flopimage|\\\nimagick_frameimage|imagick_fximage|imagick_gammaimage|imagick_gaussianblurimage|imagick_getcolorspace|imagick_getcompression|\\\nimagick_getcompressionquality|imagick_getcopyright|imagick_getfilename|imagick_getfont|imagick_getformat|imagick_getgravity|\\\nimagick_gethomeurl|imagick_getimage|imagick_getimagealphachannel|imagick_getimageartifact|imagick_getimagebackgroundcolor|\\\nimagick_getimageblob|imagick_getimageblueprimary|imagick_getimagebordercolor|imagick_getimagechanneldepth|\\\nimagick_getimagechanneldistortion|imagick_getimagechanneldistortions|imagick_getimagechannelextrema|imagick_getimagechannelmean|\\\nimagick_getimagechannelrange|imagick_getimagechannelstatistics|imagick_getimageclipmask|imagick_getimagecolormapcolor|\\\nimagick_getimagecolors|imagick_getimagecolorspace|imagick_getimagecompose|imagick_getimagecompression|imagick_getimagecompressionquality|\\\nimagick_getimagedelay|imagick_getimagedepth|imagick_getimagedispose|imagick_getimagedistortion|imagick_getimageextrema|\\\nimagick_getimagefilename|imagick_getimageformat|imagick_getimagegamma|imagick_getimagegeometry|imagick_getimagegravity|\\\nimagick_getimagegreenprimary|imagick_getimageheight|imagick_getimagehistogram|imagick_getimageindex|imagick_getimageinterlacescheme|\\\nimagick_getimageinterpolatemethod|imagick_getimageiterations|imagick_getimagelength|imagick_getimagemagicklicense|imagick_getimagematte|\\\nimagick_getimagemattecolor|imagick_getimageorientation|imagick_getimagepage|imagick_getimagepixelcolor|imagick_getimageprofile|\\\nimagick_getimageprofiles|imagick_getimageproperties|imagick_getimageproperty|imagick_getimageredprimary|imagick_getimageregion|\\\nimagick_getimagerenderingintent|imagick_getimageresolution|imagick_getimagesblob|imagick_getimagescene|imagick_getimagesignature|\\\nimagick_getimagesize|imagick_getimagetickspersecond|imagick_getimagetotalinkdensity|imagick_getimagetype|imagick_getimageunits|\\\nimagick_getimagevirtualpixelmethod|imagick_getimagewhitepoint|imagick_getimagewidth|imagick_getinterlacescheme|imagick_getiteratorindex|\\\nimagick_getnumberimages|imagick_getoption|imagick_getpackagename|imagick_getpage|imagick_getpixeliterator|imagick_getpixelregioniterator|\\\nimagick_getpointsize|imagick_getquantumdepth|imagick_getquantumrange|imagick_getreleasedate|imagick_getresource|imagick_getresourcelimit|\\\nimagick_getsamplingfactors|imagick_getsize|imagick_getsizeoffset|imagick_getversion|imagick_hasnextimage|imagick_haspreviousimage|\\\nimagick_identifyimage|imagick_implodeimage|imagick_labelimage|imagick_levelimage|imagick_linearstretchimage|imagick_liquidrescaleimage|\\\nimagick_magnifyimage|imagick_mapimage|imagick_mattefloodfillimage|imagick_medianfilterimage|imagick_mergeimagelayers|imagick_minifyimage|\\\nimagick_modulateimage|imagick_montageimage|imagick_morphimages|imagick_mosaicimages|imagick_motionblurimage|imagick_negateimage|\\\nimagick_newimage|imagick_newpseudoimage|imagick_nextimage|imagick_normalizeimage|imagick_oilpaintimage|imagick_opaquepaintimage|\\\nimagick_optimizeimagelayers|imagick_orderedposterizeimage|imagick_paintfloodfillimage|imagick_paintopaqueimage|\\\nimagick_painttransparentimage|imagick_pingimage|imagick_pingimageblob|imagick_pingimagefile|imagick_polaroidimage|imagick_posterizeimage|\\\nimagick_previewimages|imagick_previousimage|imagick_profileimage|imagick_quantizeimage|imagick_quantizeimages|imagick_queryfontmetrics|\\\nimagick_queryfonts|imagick_queryformats|imagick_radialblurimage|imagick_raiseimage|imagick_randomthresholdimage|imagick_readimage|\\\nimagick_readimageblob|imagick_readimagefile|imagick_recolorimage|imagick_reducenoiseimage|imagick_removeimage|imagick_removeimageprofile|\\\nimagick_render|imagick_resampleimage|imagick_resetimagepage|imagick_resizeimage|imagick_rollimage|imagick_rotateimage|\\\nimagick_roundcorners|imagick_sampleimage|imagick_scaleimage|imagick_separateimagechannel|imagick_sepiatoneimage|\\\nimagick_setbackgroundcolor|imagick_setcolorspace|imagick_setcompression|imagick_setcompressionquality|imagick_setfilename|\\\nimagick_setfirstiterator|imagick_setfont|imagick_setformat|imagick_setgravity|imagick_setimage|imagick_setimagealphachannel|\\\nimagick_setimageartifact|imagick_setimagebackgroundcolor|imagick_setimagebias|imagick_setimageblueprimary|imagick_setimagebordercolor|\\\nimagick_setimagechanneldepth|imagick_setimageclipmask|imagick_setimagecolormapcolor|imagick_setimagecolorspace|imagick_setimagecompose|\\\nimagick_setimagecompression|imagick_setimagecompressionquality|imagick_setimagedelay|imagick_setimagedepth|imagick_setimagedispose|\\\nimagick_setimageextent|imagick_setimagefilename|imagick_setimageformat|imagick_setimagegamma|imagick_setimagegravity|\\\nimagick_setimagegreenprimary|imagick_setimageindex|imagick_setimageinterlacescheme|imagick_setimageinterpolatemethod|\\\nimagick_setimageiterations|imagick_setimagematte|imagick_setimagemattecolor|imagick_setimageopacity|imagick_setimageorientation|\\\nimagick_setimagepage|imagick_setimageprofile|imagick_setimageproperty|imagick_setimageredprimary|imagick_setimagerenderingintent|\\\nimagick_setimageresolution|imagick_setimagescene|imagick_setimagetickspersecond|imagick_setimagetype|imagick_setimageunits|\\\nimagick_setimagevirtualpixelmethod|imagick_setimagewhitepoint|imagick_setinterlacescheme|imagick_setiteratorindex|imagick_setlastiterator|\\\nimagick_setoption|imagick_setpage|imagick_setpointsize|imagick_setresolution|imagick_setresourcelimit|imagick_setsamplingfactors|\\\nimagick_setsize|imagick_setsizeoffset|imagick_settype|imagick_shadeimage|imagick_shadowimage|imagick_sharpenimage|imagick_shaveimage|\\\nimagick_shearimage|imagick_sigmoidalcontrastimage|imagick_sketchimage|imagick_solarizeimage|imagick_spliceimage|imagick_spreadimage|\\\nimagick_steganoimage|imagick_stereoimage|imagick_stripimage|imagick_swirlimage|imagick_textureimage|imagick_thresholdimage|\\\nimagick_thumbnailimage|imagick_tintimage|imagick_transformimage|imagick_transparentpaintimage|imagick_transposeimage|\\\nimagick_transverseimage|imagick_trimimage|imagick_uniqueimagecolors|imagick_unsharpmaskimage|imagick_valid|imagick_vignetteimage|\\\nimagick_waveimage|imagick_whitethresholdimage|imagick_writeimage|imagick_writeimagefile|imagick_writeimages|imagick_writeimagesfile|\\\nimagickdraw|imagickdraw_affine|imagickdraw_annotation|imagickdraw_arc|imagickdraw_bezier|imagickdraw_circle|imagickdraw_clear|\\\nimagickdraw_clone|imagickdraw_color|imagickdraw_comment|imagickdraw_composite|imagickdraw_construct|imagickdraw_destroy|\\\nimagickdraw_ellipse|imagickdraw_getclippath|imagickdraw_getcliprule|imagickdraw_getclipunits|imagickdraw_getfillcolor|\\\nimagickdraw_getfillopacity|imagickdraw_getfillrule|imagickdraw_getfont|imagickdraw_getfontfamily|imagickdraw_getfontsize|\\\nimagickdraw_getfontstyle|imagickdraw_getfontweight|imagickdraw_getgravity|imagickdraw_getstrokeantialias|imagickdraw_getstrokecolor|\\\nimagickdraw_getstrokedasharray|imagickdraw_getstrokedashoffset|imagickdraw_getstrokelinecap|imagickdraw_getstrokelinejoin|\\\nimagickdraw_getstrokemiterlimit|imagickdraw_getstrokeopacity|imagickdraw_getstrokewidth|imagickdraw_gettextalignment|\\\nimagickdraw_gettextantialias|imagickdraw_gettextdecoration|imagickdraw_gettextencoding|imagickdraw_gettextundercolor|\\\nimagickdraw_getvectorgraphics|imagickdraw_line|imagickdraw_matte|imagickdraw_pathclose|imagickdraw_pathcurvetoabsolute|\\\nimagickdraw_pathcurvetoquadraticbezierabsolute|imagickdraw_pathcurvetoquadraticbezierrelative|\\\nimagickdraw_pathcurvetoquadraticbeziersmoothabsolute|imagickdraw_pathcurvetoquadraticbeziersmoothrelative|imagickdraw_pathcurvetorelative|\\\nimagickdraw_pathcurvetosmoothabsolute|imagickdraw_pathcurvetosmoothrelative|imagickdraw_pathellipticarcabsolute|\\\nimagickdraw_pathellipticarcrelative|imagickdraw_pathfinish|imagickdraw_pathlinetoabsolute|imagickdraw_pathlinetohorizontalabsolute|\\\nimagickdraw_pathlinetohorizontalrelative|imagickdraw_pathlinetorelative|imagickdraw_pathlinetoverticalabsolute|\\\nimagickdraw_pathlinetoverticalrelative|imagickdraw_pathmovetoabsolute|imagickdraw_pathmovetorelative|imagickdraw_pathstart|\\\nimagickdraw_point|imagickdraw_polygon|imagickdraw_polyline|imagickdraw_pop|imagickdraw_popclippath|imagickdraw_popdefs|\\\nimagickdraw_poppattern|imagickdraw_push|imagickdraw_pushclippath|imagickdraw_pushdefs|imagickdraw_pushpattern|imagickdraw_rectangle|\\\nimagickdraw_render|imagickdraw_rotate|imagickdraw_roundrectangle|imagickdraw_scale|imagickdraw_setclippath|imagickdraw_setcliprule|\\\nimagickdraw_setclipunits|imagickdraw_setfillalpha|imagickdraw_setfillcolor|imagickdraw_setfillopacity|imagickdraw_setfillpatternurl|\\\nimagickdraw_setfillrule|imagickdraw_setfont|imagickdraw_setfontfamily|imagickdraw_setfontsize|imagickdraw_setfontstretch|\\\nimagickdraw_setfontstyle|imagickdraw_setfontweight|imagickdraw_setgravity|imagickdraw_setstrokealpha|imagickdraw_setstrokeantialias|\\\nimagickdraw_setstrokecolor|imagickdraw_setstrokedasharray|imagickdraw_setstrokedashoffset|imagickdraw_setstrokelinecap|\\\nimagickdraw_setstrokelinejoin|imagickdraw_setstrokemiterlimit|imagickdraw_setstrokeopacity|imagickdraw_setstrokepatternurl|\\\nimagickdraw_setstrokewidth|imagickdraw_settextalignment|imagickdraw_settextantialias|imagickdraw_settextdecoration|\\\nimagickdraw_settextencoding|imagickdraw_settextundercolor|imagickdraw_setvectorgraphics|imagickdraw_setviewbox|imagickdraw_skewx|\\\nimagickdraw_skewy|imagickdraw_translate|imagickpixel|imagickpixel_clear|imagickpixel_construct|imagickpixel_destroy|imagickpixel_getcolor|\\\nimagickpixel_getcolorasstring|imagickpixel_getcolorcount|imagickpixel_getcolorvalue|imagickpixel_gethsl|imagickpixel_issimilar|\\\nimagickpixel_setcolor|imagickpixel_setcolorvalue|imagickpixel_sethsl|imagickpixeliterator|imagickpixeliterator_clear|\\\nimagickpixeliterator_construct|imagickpixeliterator_destroy|imagickpixeliterator_getcurrentiteratorrow|\\\nimagickpixeliterator_getiteratorrow|imagickpixeliterator_getnextiteratorrow|imagickpixeliterator_getpreviousiteratorrow|\\\nimagickpixeliterator_newpixeliterator|imagickpixeliterator_newpixelregioniterator|imagickpixeliterator_resetiterator|\\\nimagickpixeliterator_setiteratorfirstrow|imagickpixeliterator_setiteratorlastrow|imagickpixeliterator_setiteratorrow|\\\nimagickpixeliterator_synciterator|imap_8bit|imap_alerts|imap_append|imap_base64|imap_binary|imap_body|imap_bodystruct|imap_check|\\\nimap_clearflag_full|imap_close|imap_create|imap_createmailbox|imap_delete|imap_deletemailbox|imap_errors|imap_expunge|imap_fetch_overview|\\\nimap_fetchbody|imap_fetchheader|imap_fetchmime|imap_fetchstructure|imap_fetchtext|imap_gc|imap_get_quota|imap_get_quotaroot|imap_getacl|\\\nimap_getmailboxes|imap_getsubscribed|imap_header|imap_headerinfo|imap_headers|imap_last_error|imap_list|imap_listmailbox|imap_listscan|\\\nimap_listsubscribed|imap_lsub|imap_mail|imap_mail_compose|imap_mail_copy|imap_mail_move|imap_mailboxmsginfo|imap_mime_header_decode|\\\nimap_msgno|imap_num_msg|imap_num_recent|imap_open|imap_ping|imap_qprint|imap_rename|imap_renamemailbox|imap_reopen|\\\nimap_rfc822_parse_adrlist|imap_rfc822_parse_headers|imap_rfc822_write_address|imap_savebody|imap_scan|imap_scanmailbox|imap_search|\\\nimap_set_quota|imap_setacl|imap_setflag_full|imap_sort|imap_status|imap_subscribe|imap_thread|imap_timeout|imap_uid|imap_undelete|\\\nimap_unsubscribe|imap_utf7_decode|imap_utf7_encode|imap_utf8|implementsinterface|implode|import_request_variables|in_array|include|\\\ninclude_once|inclued_get_data|inet_ntop|inet_pton|infiniteiterator|ingres_autocommit|ingres_autocommit_state|ingres_charset|ingres_close|\\\ningres_commit|ingres_connect|ingres_cursor|ingres_errno|ingres_error|ingres_errsqlstate|ingres_escape_string|ingres_execute|\\\ningres_fetch_array|ingres_fetch_assoc|ingres_fetch_object|ingres_fetch_proc_return|ingres_fetch_row|ingres_field_length|ingres_field_name|\\\ningres_field_nullable|ingres_field_precision|ingres_field_scale|ingres_field_type|ingres_free_result|ingres_next_error|ingres_num_fields|\\\ningres_num_rows|ingres_pconnect|ingres_prepare|ingres_query|ingres_result_seek|ingres_rollback|ingres_set_environment|\\\ningres_unbuffered_query|ini_alter|ini_get|ini_get_all|ini_restore|ini_set|innamespace|inotify_add_watch|inotify_init|inotify_queue_len|\\\ninotify_read|inotify_rm_watch|interface_exists|intl_error_name|intl_get_error_code|intl_get_error_message|intl_is_failure|\\\nintldateformatter|intval|invalidargumentexception|invoke|invokeargs|ip2long|iptcembed|iptcparse|is_a|is_array|is_bool|is_callable|is_dir|\\\nis_double|is_executable|is_file|is_finite|is_float|is_infinite|is_int|is_integer|is_link|is_long|is_nan|is_null|is_numeric|is_object|\\\nis_readable|is_real|is_resource|is_scalar|is_soap_fault|is_string|is_subclass_of|is_uploaded_file|is_writable|is_writeable|isabstract|\\\niscloneable|isdisabled|isfinal|isinstance|isinstantiable|isinterface|isinternal|isiterateable|isset|issubclassof|isuserdefined|iterator|\\\niterator_apply|iterator_count|iterator_to_array|iteratoraggregate|iteratoriterator|java_last_exception_clear|java_last_exception_get|\\\njddayofweek|jdmonthname|jdtofrench|jdtogregorian|jdtojewish|jdtojulian|jdtounix|jewishtojd|join|jpeg2wbmp|json_decode|json_encode|\\\njson_last_error|jsonserializable|judy|judy_type|judy_version|juliantojd|kadm5_chpass_principal|kadm5_create_principal|\\\nkadm5_delete_principal|kadm5_destroy|kadm5_flush|kadm5_get_policies|kadm5_get_principal|kadm5_get_principals|kadm5_init_with_password|\\\nkadm5_modify_principal|key|krsort|ksort|lcfirst|lcg_value|lchgrp|lchown|ldap_8859_to_t61|ldap_add|ldap_bind|ldap_close|ldap_compare|\\\nldap_connect|ldap_count_entries|ldap_delete|ldap_dn2ufn|ldap_err2str|ldap_errno|ldap_error|ldap_explode_dn|ldap_first_attribute|\\\nldap_first_entry|ldap_first_reference|ldap_free_result|ldap_get_attributes|ldap_get_dn|ldap_get_entries|ldap_get_option|ldap_get_values|\\\nldap_get_values_len|ldap_list|ldap_mod_add|ldap_mod_del|ldap_mod_replace|ldap_modify|ldap_next_attribute|ldap_next_entry|\\\nldap_next_reference|ldap_parse_reference|ldap_parse_result|ldap_read|ldap_rename|ldap_sasl_bind|ldap_search|ldap_set_option|\\\nldap_set_rebind_proc|ldap_sort|ldap_start_tls|ldap_t61_to_8859|ldap_unbind|lengthexception|levenshtein|libxml_clear_errors|\\\nlibxml_disable_entity_loader|libxml_get_errors|libxml_get_last_error|libxml_set_streams_context|libxml_use_internal_errors|libxmlerror|\\\nlimititerator|link|linkinfo|list|locale|localeconv|localtime|log|log10|log1p|logicexception|long2ip|lstat|ltrim|lzf_compress|\\\nlzf_decompress|lzf_optimized_for|m_checkstatus|m_completeauthorizations|m_connect|m_connectionerror|m_deletetrans|m_destroyconn|\\\nm_destroyengine|m_getcell|m_getcellbynum|m_getcommadelimited|m_getheader|m_initconn|m_initengine|m_iscommadelimited|m_maxconntimeout|\\\nm_monitor|m_numcolumns|m_numrows|m_parsecommadelimited|m_responsekeys|m_responseparam|m_returnstatus|m_setblocking|m_setdropfile|m_setip|\\\nm_setssl|m_setssl_cafile|m_setssl_files|m_settimeout|m_sslcert_gen_hash|m_transactionssent|m_transinqueue|m_transkeyval|m_transnew|\\\nm_transsend|m_uwait|m_validateidentifier|m_verifyconnection|m_verifysslcert|magic_quotes_runtime|mail|\\\nmailparse_determine_best_xfer_encoding|mailparse_msg_create|mailparse_msg_extract_part|mailparse_msg_extract_part_file|\\\nmailparse_msg_extract_whole_part_file|mailparse_msg_free|mailparse_msg_get_part|mailparse_msg_get_part_data|mailparse_msg_get_structure|\\\nmailparse_msg_parse|mailparse_msg_parse_file|mailparse_rfc822_parse_addresses|mailparse_stream_encode|mailparse_uudecode_all|main|max|\\\nmaxdb_affected_rows|maxdb_autocommit|maxdb_bind_param|maxdb_bind_result|maxdb_change_user|maxdb_character_set_name|maxdb_client_encoding|\\\nmaxdb_close|maxdb_close_long_data|maxdb_commit|maxdb_connect|maxdb_connect_errno|maxdb_connect_error|maxdb_data_seek|maxdb_debug|\\\nmaxdb_disable_reads_from_master|maxdb_disable_rpl_parse|maxdb_dump_debug_info|maxdb_embedded_connect|maxdb_enable_reads_from_master|\\\nmaxdb_enable_rpl_parse|maxdb_errno|maxdb_error|maxdb_escape_string|maxdb_execute|maxdb_fetch|maxdb_fetch_array|maxdb_fetch_assoc|\\\nmaxdb_fetch_field|maxdb_fetch_field_direct|maxdb_fetch_fields|maxdb_fetch_lengths|maxdb_fetch_object|maxdb_fetch_row|maxdb_field_count|\\\nmaxdb_field_seek|maxdb_field_tell|maxdb_free_result|maxdb_get_client_info|maxdb_get_client_version|maxdb_get_host_info|maxdb_get_metadata|\\\nmaxdb_get_proto_info|maxdb_get_server_info|maxdb_get_server_version|maxdb_info|maxdb_init|maxdb_insert_id|maxdb_kill|maxdb_master_query|\\\nmaxdb_more_results|maxdb_multi_query|maxdb_next_result|maxdb_num_fields|maxdb_num_rows|maxdb_options|maxdb_param_count|maxdb_ping|\\\nmaxdb_prepare|maxdb_query|maxdb_real_connect|maxdb_real_escape_string|maxdb_real_query|maxdb_report|maxdb_rollback|\\\nmaxdb_rpl_parse_enabled|maxdb_rpl_probe|maxdb_rpl_query_type|maxdb_select_db|maxdb_send_long_data|maxdb_send_query|maxdb_server_end|\\\nmaxdb_server_init|maxdb_set_opt|maxdb_sqlstate|maxdb_ssl_set|maxdb_stat|maxdb_stmt_affected_rows|maxdb_stmt_bind_param|\\\nmaxdb_stmt_bind_result|maxdb_stmt_close|maxdb_stmt_close_long_data|maxdb_stmt_data_seek|maxdb_stmt_errno|maxdb_stmt_error|\\\nmaxdb_stmt_execute|maxdb_stmt_fetch|maxdb_stmt_free_result|maxdb_stmt_init|maxdb_stmt_num_rows|maxdb_stmt_param_count|maxdb_stmt_prepare|\\\nmaxdb_stmt_reset|maxdb_stmt_result_metadata|maxdb_stmt_send_long_data|maxdb_stmt_sqlstate|maxdb_stmt_store_result|maxdb_store_result|\\\nmaxdb_thread_id|maxdb_thread_safe|maxdb_use_result|maxdb_warning_count|mb_check_encoding|mb_convert_case|mb_convert_encoding|\\\nmb_convert_kana|mb_convert_variables|mb_decode_mimeheader|mb_decode_numericentity|mb_detect_encoding|mb_detect_order|mb_encode_mimeheader|\\\nmb_encode_numericentity|mb_encoding_aliases|mb_ereg|mb_ereg_match|mb_ereg_replace|mb_ereg_search|mb_ereg_search_getpos|\\\nmb_ereg_search_getregs|mb_ereg_search_init|mb_ereg_search_pos|mb_ereg_search_regs|mb_ereg_search_setpos|mb_eregi|mb_eregi_replace|\\\nmb_get_info|mb_http_input|mb_http_output|mb_internal_encoding|mb_language|mb_list_encodings|mb_output_handler|mb_parse_str|\\\nmb_preferred_mime_name|mb_regex_encoding|mb_regex_set_options|mb_send_mail|mb_split|mb_strcut|mb_strimwidth|mb_stripos|mb_stristr|\\\nmb_strlen|mb_strpos|mb_strrchr|mb_strrichr|mb_strripos|mb_strrpos|mb_strstr|mb_strtolower|mb_strtoupper|mb_strwidth|\\\nmb_substitute_character|mb_substr|mb_substr_count|mcrypt_cbc|mcrypt_cfb|mcrypt_create_iv|mcrypt_decrypt|mcrypt_ecb|\\\nmcrypt_enc_get_algorithms_name|mcrypt_enc_get_block_size|mcrypt_enc_get_iv_size|mcrypt_enc_get_key_size|mcrypt_enc_get_modes_name|\\\nmcrypt_enc_get_supported_key_sizes|mcrypt_enc_is_block_algorithm|mcrypt_enc_is_block_algorithm_mode|mcrypt_enc_is_block_mode|\\\nmcrypt_enc_self_test|mcrypt_encrypt|mcrypt_generic|mcrypt_generic_deinit|mcrypt_generic_end|mcrypt_generic_init|mcrypt_get_block_size|\\\nmcrypt_get_cipher_name|mcrypt_get_iv_size|mcrypt_get_key_size|mcrypt_list_algorithms|mcrypt_list_modes|mcrypt_module_close|\\\nmcrypt_module_get_algo_block_size|mcrypt_module_get_algo_key_size|mcrypt_module_get_supported_key_sizes|mcrypt_module_is_block_algorithm|\\\nmcrypt_module_is_block_algorithm_mode|mcrypt_module_is_block_mode|mcrypt_module_open|mcrypt_module_self_test|mcrypt_ofb|md5|md5_file|\\\nmdecrypt_generic|memcache|memcache_debug|memcached|memory_get_peak_usage|memory_get_usage|messageformatter|metaphone|method_exists|mhash|\\\nmhash_count|mhash_get_block_size|mhash_get_hash_name|mhash_keygen_s2k|microtime|mime_content_type|min|ming_keypress|\\\nming_setcubicthreshold|ming_setscale|ming_setswfcompression|ming_useconstants|ming_useswfversion|mkdir|mktime|money_format|mongo|\\\nmongobindata|mongocode|mongocollection|mongoconnectionexception|mongocursor|mongocursorexception|mongocursortimeoutexception|mongodate|\\\nmongodb|mongodbref|mongoexception|mongogridfs|mongogridfscursor|mongogridfsexception|mongogridfsfile|mongoid|mongoint32|mongoint64|\\\nmongomaxkey|mongominkey|mongoregex|mongotimestamp|move_uploaded_file|mpegfile|mqseries_back|mqseries_begin|mqseries_close|mqseries_cmit|\\\nmqseries_conn|mqseries_connx|mqseries_disc|mqseries_get|mqseries_inq|mqseries_open|mqseries_put|mqseries_put1|mqseries_set|\\\nmqseries_strerror|msession_connect|msession_count|msession_create|msession_destroy|msession_disconnect|msession_find|msession_get|\\\nmsession_get_array|msession_get_data|msession_inc|msession_list|msession_listvar|msession_lock|msession_plugin|msession_randstr|\\\nmsession_set|msession_set_array|msession_set_data|msession_timeout|msession_uniq|msession_unlock|msg_get_queue|msg_queue_exists|\\\nmsg_receive|msg_remove_queue|msg_send|msg_set_queue|msg_stat_queue|msql|msql_affected_rows|msql_close|msql_connect|msql_create_db|\\\nmsql_createdb|msql_data_seek|msql_db_query|msql_dbname|msql_drop_db|msql_error|msql_fetch_array|msql_fetch_field|msql_fetch_object|\\\nmsql_fetch_row|msql_field_flags|msql_field_len|msql_field_name|msql_field_seek|msql_field_table|msql_field_type|msql_fieldflags|\\\nmsql_fieldlen|msql_fieldname|msql_fieldtable|msql_fieldtype|msql_free_result|msql_list_dbs|msql_list_fields|msql_list_tables|\\\nmsql_num_fields|msql_num_rows|msql_numfields|msql_numrows|msql_pconnect|msql_query|msql_regcase|msql_result|msql_select_db|msql_tablename|\\\nmssql_bind|mssql_close|mssql_connect|mssql_data_seek|mssql_execute|mssql_fetch_array|mssql_fetch_assoc|mssql_fetch_batch|\\\nmssql_fetch_field|mssql_fetch_object|mssql_fetch_row|mssql_field_length|mssql_field_name|mssql_field_seek|mssql_field_type|\\\nmssql_free_result|mssql_free_statement|mssql_get_last_message|mssql_guid_string|mssql_init|mssql_min_error_severity|\\\nmssql_min_message_severity|mssql_next_result|mssql_num_fields|mssql_num_rows|mssql_pconnect|mssql_query|mssql_result|mssql_rows_affected|\\\nmssql_select_db|mt_getrandmax|mt_rand|mt_srand|multipleiterator|mysql_affected_rows|mysql_client_encoding|mysql_close|mysql_connect|\\\nmysql_create_db|mysql_data_seek|mysql_db_name|mysql_db_query|mysql_drop_db|mysql_errno|mysql_error|mysql_escape_string|mysql_fetch_array|\\\nmysql_fetch_assoc|mysql_fetch_field|mysql_fetch_lengths|mysql_fetch_object|mysql_fetch_row|mysql_field_flags|mysql_field_len|\\\nmysql_field_name|mysql_field_seek|mysql_field_table|mysql_field_type|mysql_free_result|mysql_get_client_info|mysql_get_host_info|\\\nmysql_get_proto_info|mysql_get_server_info|mysql_info|mysql_insert_id|mysql_list_dbs|mysql_list_fields|mysql_list_processes|\\\nmysql_list_tables|mysql_num_fields|mysql_num_rows|mysql_pconnect|mysql_ping|mysql_query|mysql_real_escape_string|mysql_result|\\\nmysql_select_db|mysql_set_charset|mysql_stat|mysql_tablename|mysql_thread_id|mysql_unbuffered_query|mysqli|mysqli_affected_rows|\\\nmysqli_autocommit|mysqli_bind_param|mysqli_bind_result|mysqli_cache_stats|mysqli_change_user|mysqli_character_set_name|\\\nmysqli_client_encoding|mysqli_close|mysqli_commit|mysqli_connect|mysqli_connect_errno|mysqli_connect_error|mysqli_data_seek|\\\nmysqli_debug|mysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_driver|mysqli_dump_debug_info|mysqli_embedded_server_end|\\\nmysqli_embedded_server_start|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_errno|mysqli_error|mysqli_escape_string|\\\nmysqli_execute|mysqli_fetch|mysqli_fetch_all|mysqli_fetch_array|mysqli_fetch_assoc|mysqli_fetch_field|mysqli_fetch_field_direct|\\\nmysqli_fetch_fields|mysqli_fetch_lengths|mysqli_fetch_object|mysqli_fetch_row|mysqli_field_count|mysqli_field_seek|mysqli_field_tell|\\\nmysqli_free_result|mysqli_get_charset|mysqli_get_client_info|mysqli_get_client_stats|mysqli_get_client_version|mysqli_get_connection_stats|\\\nmysqli_get_host_info|mysqli_get_metadata|mysqli_get_proto_info|mysqli_get_server_info|mysqli_get_server_version|mysqli_get_warnings|\\\nmysqli_info|mysqli_init|mysqli_insert_id|mysqli_kill|mysqli_link_construct|mysqli_master_query|mysqli_more_results|mysqli_multi_query|\\\nmysqli_next_result|mysqli_num_fields|mysqli_num_rows|mysqli_options|mysqli_param_count|mysqli_ping|mysqli_poll|mysqli_prepare|\\\nmysqli_query|mysqli_real_connect|mysqli_real_escape_string|mysqli_real_query|mysqli_reap_async_query|mysqli_refresh|mysqli_report|\\\nmysqli_result|mysqli_rollback|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|mysqli_select_db|mysqli_send_long_data|\\\nmysqli_send_query|mysqli_set_charset|mysqli_set_local_infile_default|mysqli_set_local_infile_handler|mysqli_set_opt|mysqli_slave_query|\\\nmysqli_sqlstate|mysqli_ssl_set|mysqli_stat|mysqli_stmt|mysqli_stmt_affected_rows|mysqli_stmt_attr_get|mysqli_stmt_attr_set|\\\nmysqli_stmt_bind_param|mysqli_stmt_bind_result|mysqli_stmt_close|mysqli_stmt_data_seek|mysqli_stmt_errno|mysqli_stmt_error|\\\nmysqli_stmt_execute|mysqli_stmt_fetch|mysqli_stmt_field_count|mysqli_stmt_free_result|mysqli_stmt_get_result|mysqli_stmt_get_warnings|\\\nmysqli_stmt_init|mysqli_stmt_insert_id|mysqli_stmt_next_result|mysqli_stmt_num_rows|mysqli_stmt_param_count|mysqli_stmt_prepare|\\\nmysqli_stmt_reset|mysqli_stmt_result_metadata|mysqli_stmt_send_long_data|mysqli_stmt_sqlstate|mysqli_stmt_store_result|mysqli_store_result|\\\nmysqli_thread_id|mysqli_thread_safe|mysqli_use_result|mysqli_warning|mysqli_warning_count|mysqlnd_ms_get_stats|\\\nmysqlnd_ms_query_is_select|mysqlnd_ms_set_user_pick_server|mysqlnd_qc_change_handler|mysqlnd_qc_clear_cache|mysqlnd_qc_get_cache_info|\\\nmysqlnd_qc_get_core_stats|mysqlnd_qc_get_handler|mysqlnd_qc_get_query_trace_log|mysqlnd_qc_set_user_handlers|natcasesort|natsort|\\\nncurses_addch|ncurses_addchnstr|ncurses_addchstr|ncurses_addnstr|ncurses_addstr|ncurses_assume_default_colors|ncurses_attroff|\\\nncurses_attron|ncurses_attrset|ncurses_baudrate|ncurses_beep|ncurses_bkgd|ncurses_bkgdset|ncurses_border|ncurses_bottom_panel|\\\nncurses_can_change_color|ncurses_cbreak|ncurses_clear|ncurses_clrtobot|ncurses_clrtoeol|ncurses_color_content|ncurses_color_set|\\\nncurses_curs_set|ncurses_def_prog_mode|ncurses_def_shell_mode|ncurses_define_key|ncurses_del_panel|ncurses_delay_output|ncurses_delch|\\\nncurses_deleteln|ncurses_delwin|ncurses_doupdate|ncurses_echo|ncurses_echochar|ncurses_end|ncurses_erase|ncurses_erasechar|ncurses_filter|\\\nncurses_flash|ncurses_flushinp|ncurses_getch|ncurses_getmaxyx|ncurses_getmouse|ncurses_getyx|ncurses_halfdelay|ncurses_has_colors|\\\nncurses_has_ic|ncurses_has_il|ncurses_has_key|ncurses_hide_panel|ncurses_hline|ncurses_inch|ncurses_init|ncurses_init_color|\\\nncurses_init_pair|ncurses_insch|ncurses_insdelln|ncurses_insertln|ncurses_insstr|ncurses_instr|ncurses_isendwin|ncurses_keyok|\\\nncurses_keypad|ncurses_killchar|ncurses_longname|ncurses_meta|ncurses_mouse_trafo|ncurses_mouseinterval|ncurses_mousemask|ncurses_move|\\\nncurses_move_panel|ncurses_mvaddch|ncurses_mvaddchnstr|ncurses_mvaddchstr|ncurses_mvaddnstr|ncurses_mvaddstr|ncurses_mvcur|\\\nncurses_mvdelch|ncurses_mvgetch|ncurses_mvhline|ncurses_mvinch|ncurses_mvvline|ncurses_mvwaddstr|ncurses_napms|ncurses_new_panel|\\\nncurses_newpad|ncurses_newwin|ncurses_nl|ncurses_nocbreak|ncurses_noecho|ncurses_nonl|ncurses_noqiflush|ncurses_noraw|\\\nncurses_pair_content|ncurses_panel_above|ncurses_panel_below|ncurses_panel_window|ncurses_pnoutrefresh|ncurses_prefresh|ncurses_putp|\\\nncurses_qiflush|ncurses_raw|ncurses_refresh|ncurses_replace_panel|ncurses_reset_prog_mode|ncurses_reset_shell_mode|ncurses_resetty|\\\nncurses_savetty|ncurses_scr_dump|ncurses_scr_init|ncurses_scr_restore|ncurses_scr_set|ncurses_scrl|ncurses_show_panel|ncurses_slk_attr|\\\nncurses_slk_attroff|ncurses_slk_attron|ncurses_slk_attrset|ncurses_slk_clear|ncurses_slk_color|ncurses_slk_init|ncurses_slk_noutrefresh|\\\nncurses_slk_refresh|ncurses_slk_restore|ncurses_slk_set|ncurses_slk_touch|ncurses_standend|ncurses_standout|ncurses_start_color|\\\nncurses_termattrs|ncurses_termname|ncurses_timeout|ncurses_top_panel|ncurses_typeahead|ncurses_ungetch|ncurses_ungetmouse|\\\nncurses_update_panels|ncurses_use_default_colors|ncurses_use_env|ncurses_use_extended_names|ncurses_vidattr|ncurses_vline|ncurses_waddch|\\\nncurses_waddstr|ncurses_wattroff|ncurses_wattron|ncurses_wattrset|ncurses_wborder|ncurses_wclear|ncurses_wcolor_set|ncurses_werase|\\\nncurses_wgetch|ncurses_whline|ncurses_wmouse_trafo|ncurses_wmove|ncurses_wnoutrefresh|ncurses_wrefresh|ncurses_wstandend|\\\nncurses_wstandout|ncurses_wvline|newinstance|newinstanceargs|newt_bell|newt_button|newt_button_bar|newt_centered_window|newt_checkbox|\\\nnewt_checkbox_get_value|newt_checkbox_set_flags|newt_checkbox_set_value|newt_checkbox_tree|newt_checkbox_tree_add_item|\\\nnewt_checkbox_tree_find_item|newt_checkbox_tree_get_current|newt_checkbox_tree_get_entry_value|newt_checkbox_tree_get_multi_selection|\\\nnewt_checkbox_tree_get_selection|newt_checkbox_tree_multi|newt_checkbox_tree_set_current|newt_checkbox_tree_set_entry|\\\nnewt_checkbox_tree_set_entry_value|newt_checkbox_tree_set_width|newt_clear_key_buffer|newt_cls|newt_compact_button|\\\nnewt_component_add_callback|newt_component_takes_focus|newt_create_grid|newt_cursor_off|newt_cursor_on|newt_delay|newt_draw_form|\\\nnewt_draw_root_text|newt_entry|newt_entry_get_value|newt_entry_set|newt_entry_set_filter|newt_entry_set_flags|newt_finished|newt_form|\\\nnewt_form_add_component|newt_form_add_components|newt_form_add_hot_key|newt_form_destroy|newt_form_get_current|newt_form_run|\\\nnewt_form_set_background|newt_form_set_height|newt_form_set_size|newt_form_set_timer|newt_form_set_width|newt_form_watch_fd|\\\nnewt_get_screen_size|newt_grid_add_components_to_form|newt_grid_basic_window|newt_grid_free|newt_grid_get_size|newt_grid_h_close_stacked|\\\nnewt_grid_h_stacked|newt_grid_place|newt_grid_set_field|newt_grid_simple_window|newt_grid_v_close_stacked|newt_grid_v_stacked|\\\nnewt_grid_wrapped_window|newt_grid_wrapped_window_at|newt_init|newt_label|newt_label_set_text|newt_listbox|newt_listbox_append_entry|\\\nnewt_listbox_clear|newt_listbox_clear_selection|newt_listbox_delete_entry|newt_listbox_get_current|newt_listbox_get_selection|\\\nnewt_listbox_insert_entry|newt_listbox_item_count|newt_listbox_select_item|newt_listbox_set_current|newt_listbox_set_current_by_key|\\\nnewt_listbox_set_data|newt_listbox_set_entry|newt_listbox_set_width|newt_listitem|newt_listitem_get_data|newt_listitem_set|\\\nnewt_open_window|newt_pop_help_line|newt_pop_window|newt_push_help_line|newt_radio_get_current|newt_radiobutton|newt_redraw_help_line|\\\nnewt_reflow_text|newt_refresh|newt_resize_screen|newt_resume|newt_run_form|newt_scale|newt_scale_set|newt_scrollbar_set|\\\nnewt_set_help_callback|newt_set_suspend_callback|newt_suspend|newt_textbox|newt_textbox_get_num_lines|newt_textbox_reflowed|\\\nnewt_textbox_set_height|newt_textbox_set_text|newt_vertical_scrollbar|newt_wait_for_key|newt_win_choice|newt_win_entries|newt_win_menu|\\\nnewt_win_message|newt_win_messagev|newt_win_ternary|next|ngettext|nl2br|nl_langinfo|norewinditerator|normalizer|notes_body|notes_copy_db|\\\nnotes_create_db|notes_create_note|notes_drop_db|notes_find_note|notes_header_info|notes_list_msgs|notes_mark_read|notes_mark_unread|\\\nnotes_nav_create|notes_search|notes_unread|notes_version|nsapi_request_headers|nsapi_response_headers|nsapi_virtual|nthmac|number_format|\\\nnumberformatter|oauth|oauth_get_sbs|oauth_urlencode|oauthexception|oauthprovider|ob_clean|ob_deflatehandler|ob_end_clean|ob_end_flush|\\\nob_etaghandler|ob_flush|ob_get_clean|ob_get_contents|ob_get_flush|ob_get_length|ob_get_level|ob_get_status|ob_gzhandler|ob_iconv_handler|\\\nob_implicit_flush|ob_inflatehandler|ob_list_handlers|ob_start|ob_tidyhandler|oci_bind_array_by_name|oci_bind_by_name|oci_cancel|\\\noci_client_version|oci_close|oci_collection_append|oci_collection_assign|oci_collection_element_assign|oci_collection_element_get|\\\noci_collection_free|oci_collection_max|oci_collection_size|oci_collection_trim|oci_commit|oci_connect|oci_define_by_name|oci_error|\\\noci_execute|oci_fetch|oci_fetch_all|oci_fetch_array|oci_fetch_assoc|oci_fetch_object|oci_fetch_row|oci_field_is_null|oci_field_name|\\\noci_field_precision|oci_field_scale|oci_field_size|oci_field_type|oci_field_type_raw|oci_free_statement|oci_internal_debug|oci_lob_append|\\\noci_lob_close|oci_lob_copy|oci_lob_eof|oci_lob_erase|oci_lob_export|oci_lob_flush|oci_lob_free|oci_lob_getbuffering|oci_lob_import|\\\noci_lob_is_equal|oci_lob_load|oci_lob_read|oci_lob_rewind|oci_lob_save|oci_lob_savefile|oci_lob_seek|oci_lob_setbuffering|oci_lob_size|\\\noci_lob_tell|oci_lob_truncate|oci_lob_write|oci_lob_writetemporary|oci_lob_writetofile|oci_new_collection|oci_new_connect|oci_new_cursor|\\\noci_new_descriptor|oci_num_fields|oci_num_rows|oci_parse|oci_password_change|oci_pconnect|oci_result|oci_rollback|oci_server_version|\\\noci_set_action|oci_set_client_identifier|oci_set_client_info|oci_set_edition|oci_set_module_name|oci_set_prefetch|oci_statement_type|\\\nocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|ocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|\\\nocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|ocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|\\\nocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|ocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|\\\nociloadlob|ocilogoff|ocilogon|ocinewcollection|ocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|\\\nocirollback|ocirowcount|ocisavelob|ocisavelobfile|ociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|\\\noctdec|odbc_autocommit|odbc_binmode|odbc_close|odbc_close_all|odbc_columnprivileges|odbc_columns|odbc_commit|odbc_connect|odbc_cursor|\\\nodbc_data_source|odbc_do|odbc_error|odbc_errormsg|odbc_exec|odbc_execute|odbc_fetch_array|odbc_fetch_into|odbc_fetch_object|\\\nodbc_fetch_row|odbc_field_len|odbc_field_name|odbc_field_num|odbc_field_precision|odbc_field_scale|odbc_field_type|odbc_foreignkeys|\\\nodbc_free_result|odbc_gettypeinfo|odbc_longreadlen|odbc_next_result|odbc_num_fields|odbc_num_rows|odbc_pconnect|odbc_prepare|\\\nodbc_primarykeys|odbc_procedurecolumns|odbc_procedures|odbc_result|odbc_result_all|odbc_rollback|odbc_setoption|odbc_specialcolumns|\\\nodbc_statistics|odbc_tableprivileges|odbc_tables|openal_buffer_create|openal_buffer_data|openal_buffer_destroy|openal_buffer_get|\\\nopenal_buffer_loadwav|openal_context_create|openal_context_current|openal_context_destroy|openal_context_process|openal_context_suspend|\\\nopenal_device_close|openal_device_open|openal_listener_get|openal_listener_set|openal_source_create|openal_source_destroy|\\\nopenal_source_get|openal_source_pause|openal_source_play|openal_source_rewind|openal_source_set|openal_source_stop|openal_stream|opendir|\\\nopenlog|openssl_cipher_iv_length|openssl_csr_export|openssl_csr_export_to_file|openssl_csr_get_public_key|openssl_csr_get_subject|\\\nopenssl_csr_new|openssl_csr_sign|openssl_decrypt|openssl_dh_compute_key|openssl_digest|openssl_encrypt|openssl_error_string|\\\nopenssl_free_key|openssl_get_cipher_methods|openssl_get_md_methods|openssl_get_privatekey|openssl_get_publickey|openssl_open|\\\nopenssl_pkcs12_export|openssl_pkcs12_export_to_file|openssl_pkcs12_read|openssl_pkcs7_decrypt|openssl_pkcs7_encrypt|openssl_pkcs7_sign|\\\nopenssl_pkcs7_verify|openssl_pkey_export|openssl_pkey_export_to_file|openssl_pkey_free|openssl_pkey_get_details|openssl_pkey_get_private|\\\nopenssl_pkey_get_public|openssl_pkey_new|openssl_private_decrypt|openssl_private_encrypt|openssl_public_decrypt|openssl_public_encrypt|\\\nopenssl_random_pseudo_bytes|openssl_seal|openssl_sign|openssl_verify|openssl_x509_check_private_key|openssl_x509_checkpurpose|\\\nopenssl_x509_export|openssl_x509_export_to_file|openssl_x509_free|openssl_x509_parse|openssl_x509_read|ord|outeriterator|\\\noutofboundsexception|outofrangeexception|output_add_rewrite_var|output_reset_rewrite_vars|overflowexception|overload|override_function|\\\novrimos_close|ovrimos_commit|ovrimos_connect|ovrimos_cursor|ovrimos_exec|ovrimos_execute|ovrimos_fetch_into|ovrimos_fetch_row|\\\novrimos_field_len|ovrimos_field_name|ovrimos_field_num|ovrimos_field_type|ovrimos_free_result|ovrimos_longreadlen|ovrimos_num_fields|\\\novrimos_num_rows|ovrimos_prepare|ovrimos_result|ovrimos_result_all|ovrimos_rollback|pack|parentiterator|parse_ini_file|parse_ini_string|\\\nparse_str|parse_url|parsekit_compile_file|parsekit_compile_string|parsekit_func_arginfo|passthru|pathinfo|pclose|pcntl_alarm|pcntl_exec|\\\npcntl_fork|pcntl_getpriority|pcntl_setpriority|pcntl_signal|pcntl_signal_dispatch|pcntl_sigprocmask|pcntl_sigtimedwait|pcntl_sigwaitinfo|\\\npcntl_wait|pcntl_waitpid|pcntl_wexitstatus|pcntl_wifexited|pcntl_wifsignaled|pcntl_wifstopped|pcntl_wstopsig|pcntl_wtermsig|\\\npdf_activate_item|pdf_add_annotation|pdf_add_bookmark|pdf_add_launchlink|pdf_add_locallink|pdf_add_nameddest|pdf_add_note|pdf_add_outline|\\\npdf_add_pdflink|pdf_add_table_cell|pdf_add_textflow|pdf_add_thumbnail|pdf_add_weblink|pdf_arc|pdf_arcn|pdf_attach_file|pdf_begin_document|\\\npdf_begin_font|pdf_begin_glyph|pdf_begin_item|pdf_begin_layer|pdf_begin_page|pdf_begin_page_ext|pdf_begin_pattern|pdf_begin_template|\\\npdf_begin_template_ext|pdf_circle|pdf_clip|pdf_close|pdf_close_image|pdf_close_pdi|pdf_close_pdi_page|pdf_closepath|\\\npdf_closepath_fill_stroke|pdf_closepath_stroke|pdf_concat|pdf_continue_text|pdf_create_3dview|pdf_create_action|pdf_create_annotation|\\\npdf_create_bookmark|pdf_create_field|pdf_create_fieldgroup|pdf_create_gstate|pdf_create_pvf|pdf_create_textflow|pdf_curveto|\\\npdf_define_layer|pdf_delete|pdf_delete_pvf|pdf_delete_table|pdf_delete_textflow|pdf_encoding_set_char|pdf_end_document|pdf_end_font|\\\npdf_end_glyph|pdf_end_item|pdf_end_layer|pdf_end_page|pdf_end_page_ext|pdf_end_pattern|pdf_end_template|pdf_endpath|pdf_fill|\\\npdf_fill_imageblock|pdf_fill_pdfblock|pdf_fill_stroke|pdf_fill_textblock|pdf_findfont|pdf_fit_image|pdf_fit_pdi_page|pdf_fit_table|\\\npdf_fit_textflow|pdf_fit_textline|pdf_get_apiname|pdf_get_buffer|pdf_get_errmsg|pdf_get_errnum|pdf_get_font|pdf_get_fontname|\\\npdf_get_fontsize|pdf_get_image_height|pdf_get_image_width|pdf_get_majorversion|pdf_get_minorversion|pdf_get_parameter|\\\npdf_get_pdi_parameter|pdf_get_pdi_value|pdf_get_value|pdf_info_font|pdf_info_matchbox|pdf_info_table|pdf_info_textflow|pdf_info_textline|\\\npdf_initgraphics|pdf_lineto|pdf_load_3ddata|pdf_load_font|pdf_load_iccprofile|pdf_load_image|pdf_makespotcolor|pdf_moveto|pdf_new|\\\npdf_open_ccitt|pdf_open_file|pdf_open_gif|pdf_open_image|pdf_open_image_file|pdf_open_jpeg|pdf_open_memory_image|pdf_open_pdi|\\\npdf_open_pdi_document|pdf_open_pdi_page|pdf_open_tiff|pdf_pcos_get_number|pdf_pcos_get_stream|pdf_pcos_get_string|pdf_place_image|\\\npdf_place_pdi_page|pdf_process_pdi|pdf_rect|pdf_restore|pdf_resume_page|pdf_rotate|pdf_save|pdf_scale|pdf_set_border_color|\\\npdf_set_border_dash|pdf_set_border_style|pdf_set_char_spacing|pdf_set_duration|pdf_set_gstate|pdf_set_horiz_scaling|pdf_set_info|\\\npdf_set_info_author|pdf_set_info_creator|pdf_set_info_keywords|pdf_set_info_subject|pdf_set_info_title|pdf_set_layer_dependency|\\\npdf_set_leading|pdf_set_parameter|pdf_set_text_matrix|pdf_set_text_pos|pdf_set_text_rendering|pdf_set_text_rise|pdf_set_value|\\\npdf_set_word_spacing|pdf_setcolor|pdf_setdash|pdf_setdashpattern|pdf_setflat|pdf_setfont|pdf_setgray|pdf_setgray_fill|pdf_setgray_stroke|\\\npdf_setlinecap|pdf_setlinejoin|pdf_setlinewidth|pdf_setmatrix|pdf_setmiterlimit|pdf_setpolydash|pdf_setrgbcolor|pdf_setrgbcolor_fill|\\\npdf_setrgbcolor_stroke|pdf_shading|pdf_shading_pattern|pdf_shfill|pdf_show|pdf_show_boxed|pdf_show_xy|pdf_skew|pdf_stringwidth|pdf_stroke|\\\npdf_suspend_page|pdf_translate|pdf_utf16_to_utf8|pdf_utf32_to_utf16|pdf_utf8_to_utf16|pdo|pdo_cubrid_schema|pdo_pgsqllobcreate|\\\npdo_pgsqllobopen|pdo_pgsqllobunlink|pdo_sqlitecreateaggregate|pdo_sqlitecreatefunction|pdoexception|pdostatement|pfsockopen|\\\npg_affected_rows|pg_cancel_query|pg_client_encoding|pg_close|pg_connect|pg_connection_busy|pg_connection_reset|pg_connection_status|\\\npg_convert|pg_copy_from|pg_copy_to|pg_dbname|pg_delete|pg_end_copy|pg_escape_bytea|pg_escape_string|pg_execute|pg_fetch_all|\\\npg_fetch_all_columns|pg_fetch_array|pg_fetch_assoc|pg_fetch_object|pg_fetch_result|pg_fetch_row|pg_field_is_null|pg_field_name|\\\npg_field_num|pg_field_prtlen|pg_field_size|pg_field_table|pg_field_type|pg_field_type_oid|pg_free_result|pg_get_notify|pg_get_pid|\\\npg_get_result|pg_host|pg_insert|pg_last_error|pg_last_notice|pg_last_oid|pg_lo_close|pg_lo_create|pg_lo_export|pg_lo_import|pg_lo_open|\\\npg_lo_read|pg_lo_read_all|pg_lo_seek|pg_lo_tell|pg_lo_unlink|pg_lo_write|pg_meta_data|pg_num_fields|pg_num_rows|pg_options|\\\npg_parameter_status|pg_pconnect|pg_ping|pg_port|pg_prepare|pg_put_line|pg_query|pg_query_params|pg_result_error|pg_result_error_field|\\\npg_result_seek|pg_result_status|pg_select|pg_send_execute|pg_send_prepare|pg_send_query|pg_send_query_params|pg_set_client_encoding|\\\npg_set_error_verbosity|pg_trace|pg_transaction_status|pg_tty|pg_unescape_bytea|pg_untrace|pg_update|pg_version|php_check_syntax|\\\nphp_ini_loaded_file|php_ini_scanned_files|php_logo_guid|php_sapi_name|php_strip_whitespace|php_uname|phpcredits|phpinfo|phpversion|pi|\\\npng2wbmp|popen|pos|posix_access|posix_ctermid|posix_errno|posix_get_last_error|posix_getcwd|posix_getegid|posix_geteuid|posix_getgid|\\\nposix_getgrgid|posix_getgrnam|posix_getgroups|posix_getlogin|posix_getpgid|posix_getpgrp|posix_getpid|posix_getppid|posix_getpwnam|\\\nposix_getpwuid|posix_getrlimit|posix_getsid|posix_getuid|posix_initgroups|posix_isatty|posix_kill|posix_mkfifo|posix_mknod|posix_setegid|\\\nposix_seteuid|posix_setgid|posix_setpgid|posix_setsid|posix_setuid|posix_strerror|posix_times|posix_ttyname|posix_uname|pow|preg_filter|\\\npreg_grep|preg_last_error|preg_match|preg_match_all|preg_quote|preg_replace|preg_replace_callback|preg_split|prev|print|print_r|\\\nprinter_abort|printer_close|printer_create_brush|printer_create_dc|printer_create_font|printer_create_pen|printer_delete_brush|\\\nprinter_delete_dc|printer_delete_font|printer_delete_pen|printer_draw_bmp|printer_draw_chord|printer_draw_elipse|printer_draw_line|\\\nprinter_draw_pie|printer_draw_rectangle|printer_draw_roundrect|printer_draw_text|printer_end_doc|printer_end_page|printer_get_option|\\\nprinter_list|printer_logical_fontheight|printer_open|printer_select_brush|printer_select_font|printer_select_pen|printer_set_option|\\\nprinter_start_doc|printer_start_page|printer_write|printf|proc_close|proc_get_status|proc_nice|proc_open|proc_terminate|property_exists|\\\nps_add_bookmark|ps_add_launchlink|ps_add_locallink|ps_add_note|ps_add_pdflink|ps_add_weblink|ps_arc|ps_arcn|ps_begin_page|\\\nps_begin_pattern|ps_begin_template|ps_circle|ps_clip|ps_close|ps_close_image|ps_closepath|ps_closepath_stroke|ps_continue_text|ps_curveto|\\\nps_delete|ps_end_page|ps_end_pattern|ps_end_template|ps_fill|ps_fill_stroke|ps_findfont|ps_get_buffer|ps_get_parameter|ps_get_value|\\\nps_hyphenate|ps_include_file|ps_lineto|ps_makespotcolor|ps_moveto|ps_new|ps_open_file|ps_open_image|ps_open_image_file|\\\nps_open_memory_image|ps_place_image|ps_rect|ps_restore|ps_rotate|ps_save|ps_scale|ps_set_border_color|ps_set_border_dash|\\\nps_set_border_style|ps_set_info|ps_set_parameter|ps_set_text_pos|ps_set_value|ps_setcolor|ps_setdash|ps_setflat|ps_setfont|ps_setgray|\\\nps_setlinecap|ps_setlinejoin|ps_setlinewidth|ps_setmiterlimit|ps_setoverprintmode|ps_setpolydash|ps_shading|ps_shading_pattern|ps_shfill|\\\nps_show|ps_show2|ps_show_boxed|ps_show_xy|ps_show_xy2|ps_string_geometry|ps_stringwidth|ps_stroke|ps_symbol|ps_symbol_name|\\\nps_symbol_width|ps_translate|pspell_add_to_personal|pspell_add_to_session|pspell_check|pspell_clear_session|pspell_config_create|\\\npspell_config_data_dir|pspell_config_dict_dir|pspell_config_ignore|pspell_config_mode|pspell_config_personal|pspell_config_repl|\\\npspell_config_runtogether|pspell_config_save_repl|pspell_new|pspell_new_config|pspell_new_personal|pspell_save_wordlist|\\\npspell_store_replacement|pspell_suggest|putenv|px_close|px_create_fp|px_date2string|px_delete|px_delete_record|px_get_field|px_get_info|\\\npx_get_parameter|px_get_record|px_get_schema|px_get_value|px_insert_record|px_new|px_numfields|px_numrecords|px_open_fp|px_put_record|\\\npx_retrieve_record|px_set_blob_file|px_set_parameter|px_set_tablename|px_set_targetencoding|px_set_value|px_timestamp2string|\\\npx_update_record|qdom_error|qdom_tree|quoted_printable_decode|quoted_printable_encode|quotemeta|rad2deg|radius_acct_open|\\\nradius_add_server|radius_auth_open|radius_close|radius_config|radius_create_request|radius_cvt_addr|radius_cvt_int|radius_cvt_string|\\\nradius_demangle|radius_demangle_mppe_key|radius_get_attr|radius_get_vendor_attr|radius_put_addr|radius_put_attr|radius_put_int|\\\nradius_put_string|radius_put_vendor_addr|radius_put_vendor_attr|radius_put_vendor_int|radius_put_vendor_string|\\\nradius_request_authenticator|radius_send_request|radius_server_secret|radius_strerror|rand|range|rangeexception|rar_wrapper_cache_stats|\\\nrararchive|rarentry|rarexception|rawurldecode|rawurlencode|read_exif_data|readdir|readfile|readgzfile|readline|readline_add_history|\\\nreadline_callback_handler_install|readline_callback_handler_remove|readline_callback_read_char|readline_clear_history|\\\nreadline_completion_function|readline_info|readline_list_history|readline_on_new_line|readline_read_history|readline_redisplay|\\\nreadline_write_history|readlink|realpath|realpath_cache_get|realpath_cache_size|recode|recode_file|recode_string|recursivearrayiterator|\\\nrecursivecachingiterator|recursivecallbackfilteriterator|recursivedirectoryiterator|recursivefilteriterator|recursiveiterator|\\\nrecursiveiteratoriterator|recursiveregexiterator|recursivetreeiterator|reflection|reflectionclass|reflectionexception|reflectionextension|\\\nreflectionfunction|reflectionfunctionabstract|reflectionmethod|reflectionobject|reflectionparameter|reflectionproperty|reflector|\\\nregexiterator|register_shutdown_function|register_tick_function|rename|rename_function|require|require_once|reset|resetValue|\\\nresourcebundle|restore_error_handler|restore_exception_handler|restore_include_path|return|rewind|rewinddir|rmdir|round|rpm_close|\\\nrpm_get_tag|rpm_is_valid|rpm_open|rpm_version|rrd_create|rrd_error|rrd_fetch|rrd_first|rrd_graph|rrd_info|rrd_last|rrd_lastupdate|\\\nrrd_restore|rrd_tune|rrd_update|rrd_xport|rrdcreator|rrdgraph|rrdupdater|rsort|rtrim|runkit_class_adopt|runkit_class_emancipate|\\\nrunkit_constant_add|runkit_constant_redefine|runkit_constant_remove|runkit_function_add|runkit_function_copy|runkit_function_redefine|\\\nrunkit_function_remove|runkit_function_rename|runkit_import|runkit_lint|runkit_lint_file|runkit_method_add|runkit_method_copy|\\\nrunkit_method_redefine|runkit_method_remove|runkit_method_rename|runkit_return_value_used|runkit_sandbox_output_handler|\\\nrunkit_superglobals|runtimeexception|samconnection_commit|samconnection_connect|samconnection_constructor|samconnection_disconnect|\\\nsamconnection_errno|samconnection_error|samconnection_isconnected|samconnection_peek|samconnection_peekall|samconnection_receive|\\\nsamconnection_remove|samconnection_rollback|samconnection_send|samconnection_setDebug|samconnection_subscribe|samconnection_unsubscribe|\\\nsammessage_body|sammessage_constructor|sammessage_header|sca_createdataobject|sca_getservice|sca_localproxy_createdataobject|\\\nsca_soapproxy_createdataobject|scandir|sdo_das_changesummary_beginlogging|sdo_das_changesummary_endlogging|\\\nsdo_das_changesummary_getchangeddataobjects|sdo_das_changesummary_getchangetype|sdo_das_changesummary_getoldcontainer|\\\nsdo_das_changesummary_getoldvalues|sdo_das_changesummary_islogging|sdo_das_datafactory_addpropertytotype|sdo_das_datafactory_addtype|\\\nsdo_das_datafactory_getdatafactory|sdo_das_dataobject_getchangesummary|sdo_das_relational_applychanges|sdo_das_relational_construct|\\\nsdo_das_relational_createrootdataobject|sdo_das_relational_executepreparedquery|sdo_das_relational_executequery|\\\nsdo_das_setting_getlistindex|sdo_das_setting_getpropertyindex|sdo_das_setting_getpropertyname|sdo_das_setting_getvalue|\\\nsdo_das_setting_isset|sdo_das_xml_addtypes|sdo_das_xml_create|sdo_das_xml_createdataobject|sdo_das_xml_createdocument|\\\nsdo_das_xml_document_getrootdataobject|sdo_das_xml_document_getrootelementname|sdo_das_xml_document_getrootelementuri|\\\nsdo_das_xml_document_setencoding|sdo_das_xml_document_setxmldeclaration|sdo_das_xml_document_setxmlversion|sdo_das_xml_loadfile|\\\nsdo_das_xml_loadstring|sdo_das_xml_savefile|sdo_das_xml_savestring|sdo_datafactory_create|sdo_dataobject_clear|\\\nsdo_dataobject_createdataobject|sdo_dataobject_getcontainer|sdo_dataobject_getsequence|sdo_dataobject_gettypename|\\\nsdo_dataobject_gettypenamespaceuri|sdo_exception_getcause|sdo_list_insert|sdo_model_property_getcontainingtype|\\\nsdo_model_property_getdefault|sdo_model_property_getname|sdo_model_property_gettype|sdo_model_property_iscontainment|\\\nsdo_model_property_ismany|sdo_model_reflectiondataobject_construct|sdo_model_reflectiondataobject_export|\\\nsdo_model_reflectiondataobject_getcontainmentproperty|sdo_model_reflectiondataobject_getinstanceproperties|\\\nsdo_model_reflectiondataobject_gettype|sdo_model_type_getbasetype|sdo_model_type_getname|sdo_model_type_getnamespaceuri|\\\nsdo_model_type_getproperties|sdo_model_type_getproperty|sdo_model_type_isabstracttype|sdo_model_type_isdatatype|sdo_model_type_isinstance|\\\nsdo_model_type_isopentype|sdo_model_type_issequencedtype|sdo_sequence_getproperty|sdo_sequence_insert|sdo_sequence_move|seekableiterator|\\\nsem_acquire|sem_get|sem_release|sem_remove|serializable|serialize|session_cache_expire|session_cache_limiter|session_commit|\\\nsession_decode|session_destroy|session_encode|session_get_cookie_params|session_id|session_is_registered|session_module_name|session_name|\\\nsession_pgsql_add_error|session_pgsql_get_error|session_pgsql_get_field|session_pgsql_reset|session_pgsql_set_field|session_pgsql_status|\\\nsession_regenerate_id|session_register|session_save_path|session_set_cookie_params|session_set_save_handler|session_start|\\\nsession_unregister|session_unset|session_write_close|setCounterClass|set_error_handler|set_exception_handler|set_file_buffer|\\\nset_include_path|set_magic_quotes_runtime|set_socket_blocking|set_time_limit|setcookie|setlocale|setproctitle|setrawcookie|\\\nsetstaticpropertyvalue|setthreadtitle|settype|sha1|sha1_file|shell_exec|shm_attach|shm_detach|shm_get_var|shm_has_var|shm_put_var|\\\nshm_remove|shm_remove_var|shmop_close|shmop_delete|shmop_open|shmop_read|shmop_size|shmop_write|show_source|shuffle|signeurlpaiement|\\\nsimilar_text|simplexml_import_dom|simplexml_load_file|simplexml_load_string|simplexmlelement|simplexmliterator|sin|sinh|sizeof|sleep|snmp|\\\nsnmp2_get|snmp2_getnext|snmp2_real_walk|snmp2_set|snmp2_walk|snmp3_get|snmp3_getnext|snmp3_real_walk|snmp3_set|snmp3_walk|\\\nsnmp_get_quick_print|snmp_get_valueretrieval|snmp_read_mib|snmp_set_enum_print|snmp_set_oid_numeric_print|snmp_set_oid_output_format|\\\nsnmp_set_quick_print|snmp_set_valueretrieval|snmpget|snmpgetnext|snmprealwalk|snmpset|snmpwalk|snmpwalkoid|soapclient|soapfault|\\\nsoapheader|soapparam|soapserver|soapvar|socket_accept|socket_bind|socket_clear_error|socket_close|socket_connect|socket_create|\\\nsocket_create_listen|socket_create_pair|socket_get_option|socket_get_status|socket_getpeername|socket_getsockname|socket_last_error|\\\nsocket_listen|socket_read|socket_recv|socket_recvfrom|socket_select|socket_send|socket_sendto|socket_set_block|socket_set_blocking|\\\nsocket_set_nonblock|socket_set_option|socket_set_timeout|socket_shutdown|socket_strerror|socket_write|solr_get_version|solrclient|\\\nsolrclientexception|solrdocument|solrdocumentfield|solrexception|solrgenericresponse|solrillegalargumentexception|\\\nsolrillegaloperationexception|solrinputdocument|solrmodifiableparams|solrobject|solrparams|solrpingresponse|solrquery|solrqueryresponse|\\\nsolrresponse|solrupdateresponse|solrutils|sort|soundex|sphinxclient|spl_autoload|spl_autoload_call|spl_autoload_extensions|\\\nspl_autoload_functions|spl_autoload_register|spl_autoload_unregister|spl_classes|spl_object_hash|splbool|spldoublylinkedlist|splenum|\\\nsplfileinfo|splfileobject|splfixedarray|splfloat|splheap|splint|split|spliti|splmaxheap|splminheap|splobjectstorage|splobserver|\\\nsplpriorityqueue|splqueue|splstack|splstring|splsubject|spltempfileobject|spoofchecker|sprintf|sql_regcase|sqlite3|sqlite3result|\\\nsqlite3stmt|sqlite_array_query|sqlite_busy_timeout|sqlite_changes|sqlite_close|sqlite_column|sqlite_create_aggregate|\\\nsqlite_create_function|sqlite_current|sqlite_error_string|sqlite_escape_string|sqlite_exec|sqlite_factory|sqlite_fetch_all|\\\nsqlite_fetch_array|sqlite_fetch_column_types|sqlite_fetch_object|sqlite_fetch_single|sqlite_fetch_string|sqlite_field_name|\\\nsqlite_has_more|sqlite_has_prev|sqlite_key|sqlite_last_error|sqlite_last_insert_rowid|sqlite_libencoding|sqlite_libversion|sqlite_next|\\\nsqlite_num_fields|sqlite_num_rows|sqlite_open|sqlite_popen|sqlite_prev|sqlite_query|sqlite_rewind|sqlite_seek|sqlite_single_query|\\\nsqlite_udf_decode_binary|sqlite_udf_encode_binary|sqlite_unbuffered_query|sqlite_valid|sqrt|srand|sscanf|ssdeep_fuzzy_compare|\\\nssdeep_fuzzy_hash|ssdeep_fuzzy_hash_filename|ssh2_auth_hostbased_file|ssh2_auth_none|ssh2_auth_password|ssh2_auth_pubkey_file|\\\nssh2_connect|ssh2_exec|ssh2_fetch_stream|ssh2_fingerprint|ssh2_methods_negotiated|ssh2_publickey_add|ssh2_publickey_init|\\\nssh2_publickey_list|ssh2_publickey_remove|ssh2_scp_recv|ssh2_scp_send|ssh2_sftp|ssh2_sftp_lstat|ssh2_sftp_mkdir|ssh2_sftp_readlink|\\\nssh2_sftp_realpath|ssh2_sftp_rename|ssh2_sftp_rmdir|ssh2_sftp_stat|ssh2_sftp_symlink|ssh2_sftp_unlink|ssh2_shell|ssh2_tunnel|stat|\\\nstats_absolute_deviation|stats_cdf_beta|stats_cdf_binomial|stats_cdf_cauchy|stats_cdf_chisquare|stats_cdf_exponential|stats_cdf_f|\\\nstats_cdf_gamma|stats_cdf_laplace|stats_cdf_logistic|stats_cdf_negative_binomial|stats_cdf_noncentral_chisquare|stats_cdf_noncentral_f|\\\nstats_cdf_poisson|stats_cdf_t|stats_cdf_uniform|stats_cdf_weibull|stats_covariance|stats_den_uniform|stats_dens_beta|stats_dens_cauchy|\\\nstats_dens_chisquare|stats_dens_exponential|stats_dens_f|stats_dens_gamma|stats_dens_laplace|stats_dens_logistic|\\\nstats_dens_negative_binomial|stats_dens_normal|stats_dens_pmf_binomial|stats_dens_pmf_hypergeometric|stats_dens_pmf_poisson|stats_dens_t|\\\nstats_dens_weibull|stats_harmonic_mean|stats_kurtosis|stats_rand_gen_beta|stats_rand_gen_chisquare|stats_rand_gen_exponential|\\\nstats_rand_gen_f|stats_rand_gen_funiform|stats_rand_gen_gamma|stats_rand_gen_ibinomial|stats_rand_gen_ibinomial_negative|\\\nstats_rand_gen_int|stats_rand_gen_ipoisson|stats_rand_gen_iuniform|stats_rand_gen_noncenral_chisquare|stats_rand_gen_noncentral_f|\\\nstats_rand_gen_noncentral_t|stats_rand_gen_normal|stats_rand_gen_t|stats_rand_get_seeds|stats_rand_phrase_to_seeds|stats_rand_ranf|\\\nstats_rand_setall|stats_skew|stats_standard_deviation|stats_stat_binomial_coef|stats_stat_correlation|stats_stat_gennch|\\\nstats_stat_independent_t|stats_stat_innerproduct|stats_stat_noncentral_t|stats_stat_paired_t|stats_stat_percentile|stats_stat_powersum|\\\nstats_variance|stomp|stomp_connect_error|stomp_version|stompexception|stompframe|str_getcsv|str_ireplace|str_pad|str_repeat|str_replace|\\\nstr_rot13|str_shuffle|str_split|str_word_count|strcasecmp|strchr|strcmp|strcoll|strcspn|stream_bucket_append|stream_bucket_make_writeable|\\\nstream_bucket_new|stream_bucket_prepend|stream_context_create|stream_context_get_default|stream_context_get_options|\\\nstream_context_get_params|stream_context_set_default|stream_context_set_option|stream_context_set_params|stream_copy_to_stream|\\\nstream_encoding|stream_filter_append|stream_filter_prepend|stream_filter_register|stream_filter_remove|stream_get_contents|\\\nstream_get_filters|stream_get_line|stream_get_meta_data|stream_get_transports|stream_get_wrappers|stream_is_local|\\\nstream_notification_callback|stream_register_wrapper|stream_resolve_include_path|stream_select|stream_set_blocking|stream_set_read_buffer|\\\nstream_set_timeout|stream_set_write_buffer|stream_socket_accept|stream_socket_client|stream_socket_enable_crypto|stream_socket_get_name|\\\nstream_socket_pair|stream_socket_recvfrom|stream_socket_sendto|stream_socket_server|stream_socket_shutdown|stream_supports_lock|\\\nstream_wrapper_register|stream_wrapper_restore|stream_wrapper_unregister|streamwrapper|strftime|strip_tags|stripcslashes|stripos|\\\nstripslashes|stristr|strlen|strnatcasecmp|strnatcmp|strncasecmp|strncmp|strpbrk|strpos|strptime|strrchr|strrev|strripos|strrpos|strspn|\\\nstrstr|strtok|strtolower|strtotime|strtoupper|strtr|strval|substr|substr_compare|substr_count|substr_replace|svm|svmmodel|svn_add|\\\nsvn_auth_get_parameter|svn_auth_set_parameter|svn_blame|svn_cat|svn_checkout|svn_cleanup|svn_client_version|svn_commit|svn_delete|\\\nsvn_diff|svn_export|svn_fs_abort_txn|svn_fs_apply_text|svn_fs_begin_txn2|svn_fs_change_node_prop|svn_fs_check_path|\\\nsvn_fs_contents_changed|svn_fs_copy|svn_fs_delete|svn_fs_dir_entries|svn_fs_file_contents|svn_fs_file_length|svn_fs_is_dir|svn_fs_is_file|\\\nsvn_fs_make_dir|svn_fs_make_file|svn_fs_node_created_rev|svn_fs_node_prop|svn_fs_props_changed|svn_fs_revision_prop|svn_fs_revision_root|\\\nsvn_fs_txn_root|svn_fs_youngest_rev|svn_import|svn_log|svn_ls|svn_mkdir|svn_repos_create|svn_repos_fs|svn_repos_fs_begin_txn_for_commit|\\\nsvn_repos_fs_commit_txn|svn_repos_hotcopy|svn_repos_open|svn_repos_recover|svn_revert|svn_status|svn_update|swf_actiongeturl|\\\nswf_actiongotoframe|swf_actiongotolabel|swf_actionnextframe|swf_actionplay|swf_actionprevframe|swf_actionsettarget|swf_actionstop|\\\nswf_actiontogglequality|swf_actionwaitforframe|swf_addbuttonrecord|swf_addcolor|swf_closefile|swf_definebitmap|swf_definefont|\\\nswf_defineline|swf_definepoly|swf_definerect|swf_definetext|swf_endbutton|swf_enddoaction|swf_endshape|swf_endsymbol|swf_fontsize|\\\nswf_fontslant|swf_fonttracking|swf_getbitmapinfo|swf_getfontinfo|swf_getframe|swf_labelframe|swf_lookat|swf_modifyobject|swf_mulcolor|\\\nswf_nextid|swf_oncondition|swf_openfile|swf_ortho|swf_ortho2|swf_perspective|swf_placeobject|swf_polarview|swf_popmatrix|swf_posround|\\\nswf_pushmatrix|swf_removeobject|swf_rotate|swf_scale|swf_setfont|swf_setframe|swf_shapearc|swf_shapecurveto|swf_shapecurveto3|\\\nswf_shapefillbitmapclip|swf_shapefillbitmaptile|swf_shapefilloff|swf_shapefillsolid|swf_shapelinesolid|swf_shapelineto|swf_shapemoveto|\\\nswf_showframe|swf_startbutton|swf_startdoaction|swf_startshape|swf_startsymbol|swf_textwidth|swf_translate|swf_viewport|swfaction|\\\nswfbitmap|swfbutton|swfdisplayitem|swffill|swffont|swffontchar|swfgradient|swfmorph|swfmovie|swfprebuiltclip|swfshape|swfsound|\\\nswfsoundinstance|swfsprite|swftext|swftextfield|swfvideostream|swish_construct|swish_getmetalist|swish_getpropertylist|swish_prepare|\\\nswish_query|swishresult_getmetalist|swishresult_stem|swishresults_getparsedwords|swishresults_getremovedstopwords|swishresults_nextresult|\\\nswishresults_seekresult|swishsearch_execute|swishsearch_resetlimit|swishsearch_setlimit|swishsearch_setphrasedelimiter|\\\nswishsearch_setsort|swishsearch_setstructure|sybase_affected_rows|sybase_close|sybase_connect|sybase_data_seek|\\\nsybase_deadlock_retry_count|sybase_fetch_array|sybase_fetch_assoc|sybase_fetch_field|sybase_fetch_object|sybase_fetch_row|\\\nsybase_field_seek|sybase_free_result|sybase_get_last_message|sybase_min_client_severity|sybase_min_error_severity|\\\nsybase_min_message_severity|sybase_min_server_severity|sybase_num_fields|sybase_num_rows|sybase_pconnect|sybase_query|sybase_result|\\\nsybase_select_db|sybase_set_message_handler|sybase_unbuffered_query|symlink|sys_get_temp_dir|sys_getloadavg|syslog|system|tag|tan|tanh|\\\ntcpwrap_check|tempnam|textdomain|tidy|tidy_access_count|tidy_config_count|tidy_diagnose|tidy_error_count|tidy_get_error_buffer|\\\ntidy_get_output|tidy_load_config|tidy_reset_config|tidy_save_config|tidy_set_encoding|tidy_setopt|tidy_warning_count|tidynode|time|\\\ntime_nanosleep|time_sleep_until|timezone_abbreviations_list|timezone_identifiers_list|timezone_location_get|timezone_name_from_abbr|\\\ntimezone_name_get|timezone_offset_get|timezone_open|timezone_transitions_get|timezone_version_get|tmpfile|token_get_all|token_name|\\\ntokyotyrant|tokyotyrantquery|tokyotyranttable|tostring|tostring|touch|trait_exists|transliterator|traversable|trigger_error|trim|uasort|ucfirst|\\\nucwords|udm_add_search_limit|udm_alloc_agent|udm_alloc_agent_array|udm_api_version|udm_cat_list|udm_cat_path|udm_check_charset|\\\nudm_check_stored|udm_clear_search_limits|udm_close_stored|udm_crc32|udm_errno|udm_error|udm_find|udm_free_agent|udm_free_ispell_data|\\\nudm_free_res|udm_get_doc_count|udm_get_res_field|udm_get_res_param|udm_hash32|udm_load_ispell_data|udm_open_stored|udm_set_agent_param|\\\nuksort|umask|underflowexception|unexpectedvalueexception|uniqid|unixtojd|unlink|unpack|unregister_tick_function|unserialize|unset|\\\nurldecode|urlencode|use_soap_error_handler|user_error|usleep|usort|utf8_decode|utf8_encode|v8js|v8jsexception|var_dump|var_export|variant|\\\nvariant_abs|variant_add|variant_and|variant_cast|variant_cat|variant_cmp|variant_date_from_timestamp|variant_date_to_timestamp|\\\nvariant_div|variant_eqv|variant_fix|variant_get_type|variant_idiv|variant_imp|variant_int|variant_mod|variant_mul|variant_neg|variant_not|\\\nvariant_or|variant_pow|variant_round|variant_set|variant_set_type|variant_sub|variant_xor|version_compare|vfprintf|virtual|\\\nvpopmail_add_alias_domain|vpopmail_add_alias_domain_ex|vpopmail_add_domain|vpopmail_add_domain_ex|vpopmail_add_user|vpopmail_alias_add|\\\nvpopmail_alias_del|vpopmail_alias_del_domain|vpopmail_alias_get|vpopmail_alias_get_all|vpopmail_auth_user|vpopmail_del_domain|\\\nvpopmail_del_domain_ex|vpopmail_del_user|vpopmail_error|vpopmail_passwd|vpopmail_set_user_quota|vprintf|vsprintf|w32api_deftype|\\\nw32api_init_dtype|w32api_invoke_function|w32api_register_function|w32api_set_call_method|wddx_add_vars|wddx_deserialize|wddx_packet_end|\\\nwddx_packet_start|wddx_serialize_value|wddx_serialize_vars|win32_continue_service|win32_create_service|win32_delete_service|\\\nwin32_get_last_control_message|win32_pause_service|win32_ps_list_procs|win32_ps_stat_mem|win32_ps_stat_proc|win32_query_service_status|\\\nwin32_set_service_status|win32_start_service|win32_start_service_ctrl_dispatcher|win32_stop_service|wincache_fcache_fileinfo|\\\nwincache_fcache_meminfo|wincache_lock|wincache_ocache_fileinfo|wincache_ocache_meminfo|wincache_refresh_if_changed|\\\nwincache_rplist_fileinfo|wincache_rplist_meminfo|wincache_scache_info|wincache_scache_meminfo|wincache_ucache_add|wincache_ucache_cas|\\\nwincache_ucache_clear|wincache_ucache_dec|wincache_ucache_delete|wincache_ucache_exists|wincache_ucache_get|wincache_ucache_inc|\\\nwincache_ucache_info|wincache_ucache_meminfo|wincache_ucache_set|wincache_unlock|wordwrap|xattr_get|xattr_list|xattr_remove|xattr_set|\\\nxattr_supported|xdiff_file_bdiff|xdiff_file_bdiff_size|xdiff_file_bpatch|xdiff_file_diff|xdiff_file_diff_binary|xdiff_file_merge3|\\\nxdiff_file_patch|xdiff_file_patch_binary|xdiff_file_rabdiff|xdiff_string_bdiff|xdiff_string_bdiff_size|xdiff_string_bpatch|\\\nxdiff_string_diff|xdiff_string_diff_binary|xdiff_string_merge3|xdiff_string_patch|xdiff_string_patch_binary|xdiff_string_rabdiff|\\\nxhprof_disable|xhprof_enable|xhprof_sample_disable|xhprof_sample_enable|xml_error_string|xml_get_current_byte_index|\\\nxml_get_current_column_number|xml_get_current_line_number|xml_get_error_code|xml_parse|xml_parse_into_struct|xml_parser_create|\\\nxml_parser_create_ns|xml_parser_free|xml_parser_get_option|xml_parser_set_option|xml_set_character_data_handler|xml_set_default_handler|\\\nxml_set_element_handler|xml_set_end_namespace_decl_handler|xml_set_external_entity_ref_handler|xml_set_notation_decl_handler|\\\nxml_set_object|xml_set_processing_instruction_handler|xml_set_start_namespace_decl_handler|xml_set_unparsed_entity_decl_handler|xmlreader|\\\nxmlrpc_decode|xmlrpc_decode_request|xmlrpc_encode|xmlrpc_encode_request|xmlrpc_get_type|xmlrpc_is_fault|xmlrpc_parse_method_descriptions|\\\nxmlrpc_server_add_introspection_data|xmlrpc_server_call_method|xmlrpc_server_create|xmlrpc_server_destroy|\\\nxmlrpc_server_register_introspection_callback|xmlrpc_server_register_method|xmlrpc_set_type|xmlwriter_end_attribute|xmlwriter_end_cdata|\\\nxmlwriter_end_comment|xmlwriter_end_document|xmlwriter_end_dtd|xmlwriter_end_dtd_attlist|xmlwriter_end_dtd_element|\\\nxmlwriter_end_dtd_entity|xmlwriter_end_element|xmlwriter_end_pi|xmlwriter_flush|xmlwriter_full_end_element|xmlwriter_open_memory|\\\nxmlwriter_open_uri|xmlwriter_output_memory|xmlwriter_set_indent|xmlwriter_set_indent_string|xmlwriter_start_attribute|\\\nxmlwriter_start_attribute_ns|xmlwriter_start_cdata|xmlwriter_start_comment|xmlwriter_start_document|xmlwriter_start_dtd|\\\nxmlwriter_start_dtd_attlist|xmlwriter_start_dtd_element|xmlwriter_start_dtd_entity|xmlwriter_start_element|xmlwriter_start_element_ns|\\\nxmlwriter_start_pi|xmlwriter_text|xmlwriter_write_attribute|xmlwriter_write_attribute_ns|xmlwriter_write_cdata|xmlwriter_write_comment|\\\nxmlwriter_write_dtd|xmlwriter_write_dtd_attlist|xmlwriter_write_dtd_element|xmlwriter_write_dtd_entity|xmlwriter_write_element|\\\nxmlwriter_write_element_ns|xmlwriter_write_pi|xmlwriter_write_raw|xpath_eval|xpath_eval_expression|xpath_new_context|xpath_register_ns|\\\nxpath_register_ns_auto|xptr_eval|xptr_new_context|xslt_backend_info|xslt_backend_name|xslt_backend_version|xslt_create|xslt_errno|\\\nxslt_error|xslt_free|xslt_getopt|xslt_process|xslt_set_base|xslt_set_encoding|xslt_set_error_handler|xslt_set_log|xslt_set_object|\\\nxslt_set_sax_handler|xslt_set_sax_handlers|xslt_set_scheme_handler|xslt_set_scheme_handlers|xslt_setopt|xsltprocessor|yaml_emit|\\\nyaml_emit_file|yaml_parse|yaml_parse_file|yaml_parse_url|yaz_addinfo|yaz_ccl_conf|yaz_ccl_parse|yaz_close|yaz_connect|yaz_database|\\\nyaz_element|yaz_errno|yaz_error|yaz_es|yaz_es_result|yaz_get_option|yaz_hits|yaz_itemorder|yaz_present|yaz_range|yaz_record|yaz_scan|\\\nyaz_scan_result|yaz_schema|yaz_search|yaz_set_option|yaz_sort|yaz_syntax|yaz_wait|yp_all|yp_cat|yp_err_string|yp_errno|yp_first|\\\nyp_get_default_domain|yp_master|yp_match|yp_next|yp_order|zend_logo_guid|zend_thread_id|zend_version|zip_close|zip_entry_close|\\\nzip_entry_compressedsize|zip_entry_compressionmethod|zip_entry_filesize|zip_entry_name|zip_entry_open|zip_entry_read|zip_open|zip_read|\\\nziparchive|ziparchive_addemptydir|ziparchive_addfile|ziparchive_addfromstring|ziparchive_close|ziparchive_deleteindex|\\\nziparchive_deletename|ziparchive_extractto|ziparchive_getarchivecomment|ziparchive_getcommentindex|ziparchive_getcommentname|\\\nziparchive_getfromindex|ziparchive_getfromname|ziparchive_getnameindex|ziparchive_getstatusstring|ziparchive_getstream|\\\nziparchive_locatename|ziparchive_open|ziparchive_renameindex|ziparchive_renamename|ziparchive_setCommentName|ziparchive_setarchivecomment|\\\nziparchive_setcommentindex|ziparchive_statindex|ziparchive_statname|ziparchive_unchangeall|ziparchive_unchangearchive|\\\nziparchive_unchangeindex|ziparchive_unchangename|zlib_get_coding_type|array_is_list|fdatasync|fdiv|fsync|get_debug_type|get_resource_id|\\\njson_validate|mb_str_pad|mysqli_execute_query|preg_last_error_msg|stream_context_set_options|str_contains|str_ends_with|str_starts_with'.split('|')\n    );\n\n    // http://php.net/manual/en/reserved.keywords.php\n    var keywords = lang.arrayToMap(\n'abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|do|else|elseif|enddeclare|endfor|endforeach|\\\nendif|endswitch|endwhile|extends|final|finally|for|foreach|function|global|goto|if|implements|instanceof|insteadof|interface|namespace|new|or|private|protected|\\\npublic|static|switch|throw|trait|try|use|var|while|xor|yield'.split('|')\n    );\n\n    // http://php.net/manual/en/reserved.keywords.php\n    var languageConstructs = lang.arrayToMap(\n        ('__halt_compiler|die|echo|empty|exit|eval|include|include_once|isset|list|require|require_once|return|print|unset').split('|')\n    );\n\n    var builtinConstants = lang.arrayToMap(\n        ('true|TRUE|false|FALSE|null|NULL|__CLASS__|__DIR__|__FILE__|__LINE__|__METHOD__|__FUNCTION__|__NAMESPACE__|__TRAIT__').split('|')\n    );\n\n    var builtinVariables = lang.arrayToMap(\n'$GLOBALS|$_SERVER|$_GET|$_POST|$_FILES|$_REQUEST|$_SESSION|$_ENV|$_COOKIE|$php_errormsg|$HTTP_RAW_POST_DATA|\\\n$http_response_header|$argc|$argv'.split('|')\n    );\n\n    // Discovery done by downloading 'Many HTML files' from:  http://php.net/download-docs.php\n    // Then search for files containing 'deprecated' (case-insensitive) and look at each file that turns up.\n    var builtinFunctionsDeprecated = lang.arrayToMap(\n'key_exists|cairo_matrix_create_scale|cairo_matrix_create_translate|call_user_method|call_user_method_array|com_addref|com_get|\\\ncom_invoke|com_isenum|com_load|com_release|com_set|connection_timeout|cubrid_load_from_glo|cubrid_new_glo|cubrid_save_to_glo|\\\ncubrid_send_glo|define_syslog_variables|dl|ereg|ereg_replace|eregi|eregi_replace|hw_documentattributes|hw_documentbodytag|\\\nhw_documentsize|hw_outputdocument|imagedashedline|maxdb_bind_param|maxdb_bind_result|maxdb_client_encoding|maxdb_close_long_data|\\\nmaxdb_execute|maxdb_fetch|maxdb_get_metadata|maxdb_param_count|maxdb_send_long_data|mcrypt_ecb|mcrypt_generic_end|mime_content_type|\\\nmysql_createdb|mysql_dbname|mysql_db_query|mysql_drop_db|mysql_dropdb|mysql_escape_string|mysql_fieldflags|mysql_fieldflags|\\\nmysql_fieldname|mysql_fieldtable|mysql_fieldtype|mysql_freeresult|mysql_listdbs|mysql_list_fields|mysql_listfields|mysql_list_tables|\\\nmysql_listtables|mysql_numfields|mysql_numrows|mysql_selectdb|mysql_tablename|mysqli_bind_param|mysqli_bind_result|\\\nmysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_execute|\\\nmysqli_fetch|mysqli_get_metadata|mysqli_master_query|mysqli_param_count|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|\\\nmysqli_send_long_data|mysqli_send_query|mysqli_slave_query|ocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|\\\nocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|ocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|\\\nocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|ocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|\\\nocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|ociloadlob|ocilogoff|ocilogon|ocinewcollection|\\\nocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|ocirollback|ocirowcount|ocisavelob|ocisavelobfile|\\\nociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|PDF_add_annotation|PDF_add_bookmark|\\\nPDF_add_launchlink|PDF_add_locallink|PDF_add_note|PDF_add_outline|PDF_add_pdflink|PDF_add_weblink|PDF_attach_file|PDF_begin_page|\\\nPDF_begin_template|PDF_close_pdi|PDF_close|PDF_findfont|PDF_get_font|PDF_get_fontname|PDF_get_fontsize|PDF_get_image_height|\\\nPDF_get_image_width|PDF_get_majorversion|PDF_get_minorversion|PDF_get_pdi_parameter|PDF_get_pdi_value|PDF_open_ccitt|PDF_open_file|\\\nPDF_open_gif|PDF_open_image_file|PDF_open_image|PDF_open_jpeg|PDF_open_pdi|PDF_open_tiff|PDF_place_image|PDF_place_pdi_page|\\\nPDF_set_border_color|PDF_set_border_dash|PDF_set_border_style|PDF_set_char_spacing|PDF_set_duration|PDF_set_horiz_scaling|\\\nPDF_set_info_author|PDF_set_info_creator|PDF_set_info_keywords|PDF_set_info_subject|PDF_set_info_title|PDF_set_leading|\\\nPDF_set_text_matrix|PDF_set_text_rendering|PDF_set_text_rise|PDF_set_word_spacing|PDF_setgray_fill|PDF_setgray_stroke|PDF_setgray|\\\nPDF_setpolydash|PDF_setrgbcolor_fill|PDF_setrgbcolor_stroke|PDF_setrgbcolor|PDF_show_boxed|php_check_syntax|px_set_tablename|\\\npx_set_targetencoding|runkit_sandbox_output_handler|session_is_registered|session_register|session_unregister\\\nset_magic_quotes_runtime|magic_quotes_runtime|set_socket_blocking|socket_set_blocking|set_socket_timeout|socket_set_timeout|split|spliti|\\\nsql_regcase'.split('|')\n    );\n\n    var keywordsDeprecated = lang.arrayToMap(\n        ('cfunction|old_function').split('|')\n    );\n\n    var futureReserved = lang.arrayToMap([]);\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : /(?:#|\\/\\/)(?:[^?]|\\?[^>])*/\n            },\n            docComment.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string.regexp\",\n                regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/][gimy]*\\\\s*(?=[).,;]|$)\"\n            }, {\n                token : \"string\", // \" string start\n                regex : '\"',\n                next : \"qqstring\"\n            }, {\n                token : \"string\", // ' string start\n                regex : \"'\",\n                next : \"qstring\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : /0[xX][0-9a-fA-F]+(?:_[0-9a-fA-F]+)*\\b/\n            }, {\n                token : \"constant.numeric\", // octal\n                regex : /0[oO]?[0-7]+(_[0-7]+)*\\b/\n            }, {\n                token : \"constant.numeric\", // binary\n                regex : /0[bB][01]+(_[01]+)*\\b/\n            }, {\n                token : \"constant.numeric\", // float\n                regex : /(?:[\\d]+(?:_\\d+)*\\.?\\d*(?:_\\d+)*|\\.\\d+(?:_\\d+)*)(?:[eE][+-]?\\d+(?:_\\d+)*)?\\b/\n            }, {\n                token : \"constant.language\", // constants\n                regex : \"\\\\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|\" +\n                        \"ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|\" +\n                        \"HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|\" +\n                        \"L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|\" +\n                        \"VERSION))|__COMPILER_HALT_OFFSET__)\\\\b\"\n            }, {\n                token : [\"keyword\", \"text\", \"support.class\"],\n                regex : \"\\\\b(new)(\\\\s+)(\\\\w+)\"\n            }, {\n                token : [\"support.class\", \"keyword.operator\"],\n                regex : \"\\\\b(\\\\w+)(::)\"\n            }, {\n                token : \"constant.language\", // constants\n                regex : \"\\\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|\" +\n                        \"SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|\" +\n                        \"O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|\" +\n                        \"R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|\" +\n                        \"YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|\" +\n                        \"ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|\" +\n                        \"T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|\" +\n                        \"HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|\" +\n                        \"I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|\" +\n                        \"O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|\" +\n                        \"L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|\" +\n                        \"M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|\" +\n                        \"OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|\" +\n                        \"P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|\" +\n                        \"RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|\" +\n                        \"T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR)|STD(?:IN|OUT|ERR))\\\\b\"\n            }, {\n                token : function(value) {\n                    if (keywords.hasOwnProperty(value))\n                        return \"keyword\";\n                    else if (builtinConstants.hasOwnProperty(value))\n                        return \"constant.language\";\n                    else if (builtinVariables.hasOwnProperty(value))\n                        return \"variable.language\";\n                    else if (futureReserved.hasOwnProperty(value))\n                        return \"invalid.illegal\";\n                    else if (builtinFunctions.hasOwnProperty(value))\n                        return \"support.function\";\n                    else if (value == \"debugger\")\n                        return \"invalid.deprecated\";\n                    else\n                        if(value.match(/^(\\$[a-zA-Z_\\x7f-\\uffff][a-zA-Z0-9_\\x7f-\\uffff]*|self|parent)$/))\n                            return \"variable\";\n                        return \"identifier\";\n                },\n                regex : /[a-zA-Z_$\\x7f-\\uffff][a-zA-Z0-9_\\x7f-\\uffff]*/\n            }, {\n                onMatch : function(value, currentSate, state) {\n                    value = value.substr(3);\n                    if (value[0] == \"'\" || value[0] == '\"')\n                        value = value.slice(1, -1);\n                    state.unshift(this.next, value);\n                    return \"markup.list\";\n                },\n                regex : /<<<(?:\\w+|'\\w+'|\"\\w+\")$/,\n                next: \"heredoc\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"::|!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|!=|!==|<=|>=|=>|<<=|>>=|>>>=|<>|<|>|\\\\.=|=|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|/=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[,;]/\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"heredoc\" : [\n            {\n                onMatch : function(value, currentState, stack) {\n                    if (stack[1] != value) {\n                        this.next = \"\";\n                        return \"string\";\n                    }\n                    stack.shift();\n                    stack.shift();\n                    this.next = this.nextState;\n                    return \"markup.list\";\n                },\n                regex : \"^\\\\w+(?=;?$)\",\n                nextState: \"start\"\n            }, {\n                token: \"string\",\n                regex : \".*\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"constant.language.escape\",\n                regex : '\\\\\\\\(?:[nrtvef\\\\\\\\\"$]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})'\n            }, {\n                token : \"variable\",\n                regex : /\\$[\\w]+(?:\\[[\\w\\]+]|[=\\-]>\\w+)?/\n            }, {\n                token : \"variable\",\n                regex : /\\$\\{[^\"\\}]+\\}?/           // this is wrong but ok for now\n            },\n            {token : \"string\", regex : '\"', next : \"start\"},\n            {defaultToken : \"string\"}\n        ],\n        \"qstring\" : [\n            {token : \"constant.language.escape\", regex : /\\\\['\\\\]/},\n            {token : \"string\", regex : \"'\", next : \"start\"},\n            {defaultToken : \"string\"}\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(PhpLangHighlightRules, TextHighlightRules);\n\n\nvar PhpHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    var startRules = [\n        {\n            token : \"support.php_tag\", // php open tag\n            regex : \"<\\\\?(?:php|=)?\",\n            push  : \"php-start\"\n        }\n    ];\n\n    var endRules = [\n        {\n            token : \"support.php_tag\", // php close tag\n            regex : \"\\\\?>\",\n            next  : \"pop\"\n        }\n    ];\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], startRules);\n\n    this.embedRules(PhpLangHighlightRules, \"php-\", endRules, [\"start\"]);\n\n    this.normalizeRules();\n};\n\noop.inherits(PhpHighlightRules, HtmlHighlightRules);\n\nexports.PhpHighlightRules = PhpHighlightRules;\nexports.PhpLangHighlightRules = PhpLangHighlightRules;\n"
  },
  {
    "path": "src/mode/php_laravel_blade.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var PHPLaravelBladeHighlightRules = require(\"./php_laravel_blade_highlight_rules\").PHPLaravelBladeHighlightRules;\n    var PHPMode = require(\"./php\").Mode;\n    var JavaScriptMode = require(\"./javascript\").Mode;\n    var CssMode = require(\"./css\").Mode;\n    var HtmlMode = require(\"./html\").Mode;\n\n    var Mode = function() {\n        PHPMode.call(this);\n\n        this.HighlightRules = PHPLaravelBladeHighlightRules;\n        this.createModeDelegates({\n            \"js-\": JavaScriptMode,\n            \"css-\": CssMode,\n            \"html-\": HtmlMode\n        });\n    };\n    oop.inherits(Mode, PHPMode);\n\n    (function() {\n\n        this.$id = \"ace/mode/php_laravel_blade\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/php_laravel_blade_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar PhpHighlightRules = require(\"./php_highlight_rules\").PhpHighlightRules;\n\nvar PHPLaravelBladeHighlightRules = function() {\n    PhpHighlightRules.call(this);\n\n    var bladeRules = {\n        start: [{\n            include: \"bladeComments\"\n        }, {\n            include: \"directives\"\n        }, {\n            include: \"parenthesis\"\n        }],\n        comments: [{\n            include: \"bladeComments\"\n        }, {\n            token: \"punctuation.definition.comment.blade\",\n            regex: \"(\\\\/\\\\/(.)*)|(\\\\#(.)*)\"\n        }, {\n            token: \"punctuation.definition.comment.begin.php\",\n            regex: \"(?:\\\\/\\\\*)\",\n            push: [{\n                token: \"punctuation.definition.comment.end.php\",\n                regex: \"(?:\\\\*\\\\/)\",\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.blade\"\n            }]\n        }], \n        bladeComments: [{\n            token: \"punctuation.definition.comment.begin.blade\",\n            regex: \"(?:\\\\{\\\\{\\\\-\\\\-)\",\n            push: [{\n                token: \"punctuation.definition.comment.end.blade\",\n                regex: \"(?:\\\\-\\\\-\\\\}\\\\})\",\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.blade\"\n            }]\n        }],\n        parenthesis: [{\n            token: \"parenthesis.begin.blade\",\n            regex: \"\\\\(\",\n            push: [{\n                token: \"parenthesis.end.blade\",\n                regex: \"\\\\)\",\n                next: \"pop\"\n            }, {\n                include: \"strings\"\n            }, {\n                include: \"variables\"\n            }, {\n                include: \"lang\"\n            }, {\n                include: \"parenthesis\"\n            }, {\n                include: \"comments\"\n            }, {\n                defaultToken: \"source.blade\"\n            }]\n        }],\n        directives: [{\n                token: [\"directive.declaration.blade\", \"keyword.directives.blade\"],\n                regex: \"(@)(endunless|endisset|endempty|endauth|endguest|endcomponent|endslot|endalert|endverbatim|endsection|show|php|endphp|endpush|endprepend|endenv|endforelse|isset|empty|component|slot|alert|json|verbatim|section|auth|guest|hasSection|forelse|includeIf|includeWhen|includeFirst|each|push|stack|prepend|inject|env|elseenv|unless|yield|extends|parent|include|acfrepeater|block|can|cannot|choice|debug|elsecan|elsecannot|embed|hipchat|lang|layout|macro|macrodef|minify|partial|render|servers|set|slack|story|task|unset|wpposts|acfend|after|append|breakpoint|endafter|endcan|endcannot|endembed|endmacro|endmarkdown|endminify|endpartial|endsetup|endstory|endtask|endunless|markdown|overwrite|setup|stop|wpempty|wpend|wpquery)\"\n\n            }, {\n                token: [\"directive.declaration.blade\", \"keyword.control.blade\"],\n                regex: \"(@)(if|else|elseif|endif|foreach|endforeach|switch|case|break|default|endswitch|for|endfor|while|endwhile|continue)\"\n            }, {\n                token: [\"directive.ignore.blade\", \"injections.begin.blade\"],\n                regex: \"(@?)(\\\\{\\\\{)\",\n                push: [{\n                    token: \"injections.end.blade\",\n                    regex: \"\\\\}\\\\}\",\n                    next: \"pop\"\n                }, {\n                    include: \"strings\"\n                }, {\n                    include: \"variables\"\n                }, {\n                    include: \"comments\"\n                }, {\n                    defaultToken: \"source.blade\"\n                }]\n            }, {\n                token: \"injections.unescaped.begin.blade\",\n                regex: \"\\\\{\\\\!\\\\!\",\n                push: [{\n                    token: \"injections.unescaped.end.blade\",\n                    regex: \"\\\\!\\\\!\\\\}\",\n                    next: \"pop\"\n                }, {\n                    include: \"strings\"\n                }, {\n                    include: \"variables\"\n                }, {\n                    defaultToken: \"source.blade\"\n                }]\n            }\n\n        ],\n\n        lang: [{\n            token: \"keyword.operator.blade\",\n            regex: \"(?:!=|!|<=|>=|<|>|===|==|=|\\\\+\\\\+|\\\\;|\\\\,|%|&&|\\\\|\\\\|)|\\\\b(?:and|or|eq|neq|ne|gte|gt|ge|lte|lt|le|not|mod|as)\\\\b\"\n        }, {\n            token: \"constant.language.blade\",\n            regex: \"\\\\b(?:TRUE|FALSE|true|false)\\\\b\"\n        }],\n        strings: [{\n            token: \"punctuation.definition.string.begin.blade\",\n            regex: \"\\\"\",\n            push: [{\n                token: \"punctuation.definition.string.end.blade\",\n                regex: \"\\\"\",\n                next: \"pop\"\n            }, {\n                token: \"string.character.escape.blade\",\n                regex: \"\\\\\\\\.\"\n            }, {\n                defaultToken: \"string.quoted.single.blade\"\n            }]\n        }, {\n            token: \"punctuation.definition.string.begin.blade\",\n            regex: \"'\",\n            push: [{\n                token: \"punctuation.definition.string.end.blade\",\n                regex: \"'\",\n                next: \"pop\"\n            }, {\n                token: \"string.character.escape.blade\",\n                regex: \"\\\\\\\\.\"\n            }, {\n                defaultToken: \"string.quoted.double.blade\"\n            }]\n        }],\n        variables: [{\n            token: \"variable.blade\",\n            regex: \"\\\\$([a-zA-Z_][a-zA-Z0-9_]*)\\\\b\"\n        }, {\n            token: [\"keyword.operator.blade\", \"constant.other.property.blade\"],\n            regex: \"(->)([a-zA-Z_][a-zA-Z0-9_]*)\\\\b\"\n        }, {\n            token: [\"keyword.operator.blade\",\n                \"meta.function-call.object.blade\",\n                \"punctuation.definition.variable.blade\",\n                \"variable.blade\",\n                \"punctuation.definition.variable.blade\"\n            ],\n            regex: \"(->)([a-zA-Z_][a-zA-Z0-9_]*)(\\\\()(.*?)(\\\\))\"\n        }]\n    };\n\n    var bladeStart = bladeRules.start;\n\n    for (var rule in this.$rules) {\n        this.$rules[rule].unshift.apply(this.$rules[rule], bladeStart);\n    }\n\n    Object.keys(bladeRules).forEach(function(x) {\n        if (!this.$rules[x])\n            this.$rules[x] = bladeRules[x];\n    }, this);\n\n    this.normalizeRules();\n};\n\n\noop.inherits(PHPLaravelBladeHighlightRules, PhpHighlightRules);\n\nexports.PHPLaravelBladeHighlightRules = PHPLaravelBladeHighlightRules;\n"
  },
  {
    "path": "src/mode/php_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar Mode = require(\"./php\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    \"test: inline mode\" : function() {\n        var mode = new Mode();\n        var tokenizer = mode.getTokenizer();\n        var tokens = tokenizer.getLineTokens(\"'juhu kinners' ?> html  <? 'php'\", \"start\").tokens;\n        assert.equal(\"string\", tokens[tokens.length - 1].type);\n        assert.notEqual(\"string\", tokens[0].type);\n        assert.equal(tokens.length, 4);\n        \n        mode = new Mode({inline: true});\n        tokenizer = mode.getTokenizer();\n        tokens = tokenizer.getLineTokens(\"'juhu kinners' ?> html  <? 'php'\", \"start\").tokens;\n        assert.equal(\"string\", tokens[0].type);\n        assert.equal(\"string\", tokens[tokens.length - 1].type);\n        assert.equal(tokens.length, 9);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/pig.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PigHighlightRules = require(\"./pig_highlight_rules\").PigHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PigHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/pig\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/pig_highlight_rules.js",
    "content": "/* This file was autogenerated from Pig.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PigHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            token: \"comment.block.pig\",\n            regex: /\\/\\*/,\n            push: [{\n                token: \"comment.block.pig\",\n                regex: /\\*\\//,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.block.pig\"\n            }]\n        }, {\n            token: \"comment.line.double-dash.asciidoc\",\n            regex: /--.*$/\n        }, {\n            token: \"keyword.control.pig\",\n            regex: /\\b(?:ASSERT|LOAD|STORE|DUMP|FILTER|DISTINCT|FOREACH|GENERATE|STREAM|JOIN|COGROUP|GROUP|CROSS|ORDER|LIMIT|UNION|SPLIT|DESCRIBE|EXPLAIN|ILLUSTRATE|AS|BY|INTO|USING|LIMIT|PARALLEL|OUTER|INNER|DEFAULT|LEFT|SAMPLE|RANK|CUBE|ALL|KILL|QUIT|MAPREDUCE|ASC|DESC|THROUGH|SHIP|CACHE|DECLARE|CASE|WHEN|THEN|END|IN|PARTITION|FULL|IMPORT|IF|ONSCHEMA|INPUT|OUTPUT)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"storage.datatypes.pig\",\n            regex: /\\b(?:int|long|float|double|chararray|bytearray|boolean|datetime|biginteger|bigdecimal|tuple|bag|map)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"support.function.storage.pig\",\n            regex: /\\b(?:PigStorage|BinStorage|BinaryStorage|PigDump|HBaseStorage|JsonLoader|JsonStorage|AvroStorage|TextLoader|PigStreaming|TrevniStorage|AccumuloStorage)\\b/\n        }, {\n            token: \"support.function.udf.pig\",\n            regex: /\\b(?:DIFF|TOBAG|TOMAP|TOP|TOTUPLE|RANDOM|FLATTEN|flatten|CUBE|ROLLUP|IsEmpty|ARITY|PluckTuple|SUBTRACT|BagToString)\\b/\n        }, {\n            token: \"support.function.udf.math.pig\",\n            regex: /\\b(?:ABS|ACOS|ASIN|ATAN|CBRT|CEIL|COS|COSH|EXP|FLOOR|LOG|LOG10|ROUND|ROUND_TO|SIN|SINH|SQRT|TAN|TANH|AVG|COUNT|COUNT_STAR|MAX|MIN|SUM|COR|COV)\\b/\n        }, {\n            token: \"support.function.udf.string.pig\",\n            regex: /\\b(?:CONCAT|INDEXOF|LAST_INDEX_OF|LCFIRST|LOWER|REGEX_EXTRACT|REGEX_EXTRACT_ALL|REPLACE|SIZE|STRSPLIT|SUBSTRING|TOKENIZE|TRIM|UCFIRST|UPPER|LTRIM|RTRIM|ENDSWITH|STARTSWITH|TRIM)\\b/\n        }, {\n            token: \"support.function.udf.datetime.pig\",\n            regex: /\\b(?:AddDuration|CurrentTime|DaysBetween|GetDay|GetHour|GetMilliSecond|GetMinute|GetMonth|GetSecond|GetWeek|GetWeekYear|GetYear|HoursBetween|MilliSecondsBetween|MinutesBetween|MonthsBetween|SecondsBetween|SubtractDuration|ToDate|WeeksBetween|YearsBetween|ToMilliSeconds|ToString|ToUnixTime)\\b/\n        }, {\n            token: \"support.function.command.pig\",\n            regex: /\\b(?:cat|cd|copyFromLocal|copyToLocal|cp|ls|mkdir|mv|pwd|rm)\\b/\n        }, {\n            token: \"variable.pig\",\n            regex: /\\$[a_zA-Z0-9_]+/\n        }, {\n            token: \"constant.language.pig\",\n            regex: /\\b(?:NULL|true|false|stdin|stdout|stderr)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"constant.numeric.pig\",\n            regex: /\\b\\d+(?:\\.\\d+)?\\b/\n        }, {\n            token: \"keyword.operator.comparison.pig\",\n            regex: /!=|==|<|>|<=|>=|\\b(?:MATCHES|IS|OR|AND|NOT)\\b/,\n            caseInsensitive: true\n        }, {\n            token: \"keyword.operator.arithmetic.pig\",\n            regex: /\\+|\\-|\\*|\\/|\\%|\\?|:|::|\\.\\.|#/\n        }, {\n            token: \"string.quoted.double.pig\",\n            regex: /\"/,\n            push: [{\n                token: \"string.quoted.double.pig\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.pig\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.pig\"\n            }]\n        }, {\n            token: \"string.quoted.single.pig\",\n            regex: /'/,\n            push: [{\n                token: \"string.quoted.single.pig\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.pig\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.single.pig\"\n            }]\n        }, {\n            todo: {\n                token: [\n                    \"text\",\n                    \"keyword.parameter.pig\",\n                    \"text\",\n                    \"storage.type.parameter.pig\"\n                ],\n                regex: /^(\\s*)(set)(\\s+)(\\S+)/,\n                caseInsensitive: true,\n                push: [{\n                    token: \"text\",\n                    regex: /$/,\n                    next: \"pop\"\n                }, {\n                    include: \"$self\"\n                }]\n            }\n        }, {\n            token: [\n                \"text\",\n                \"keyword.alias.pig\",\n                \"text\",\n                \"storage.type.alias.pig\"\n            ],\n            regex: /(\\s*)(DEFINE|DECLARE|REGISTER)(\\s+)(\\S+)/,\n            caseInsensitive: true,\n            push: [{\n                token: \"text\",\n                regex: /;?$/,\n                next: \"pop\"\n            }]\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nPigHighlightRules.metaData = {\n    fileTypes: [\"pig\"],\n    name: \"Pig\",\n    scopeName: \"source.pig\"\n};\n\n\noop.inherits(PigHighlightRules, TextHighlightRules);\n\nexports.PigHighlightRules = PigHighlightRules;\n"
  },
  {
    "path": "src/mode/plain_text.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar Behaviour = require(\"./behaviour\").Behaviour;\n\nvar Mode = function() {\n    this.HighlightRules = TextHighlightRules;\n    this.$behaviour = new Behaviour();\n};\n\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    this.getNextLineIndent = function(state, line, tab) {\n        return '';\n    };\n    this.$id = \"ace/mode/plain_text\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/plain_text_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar PlainTextMode = require(\"./plain_text\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new PlainTextMode();\n    },\n\n    \"test: lines should not be indented\" : function() {\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"   abc\", \"  \"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/plsql.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PLSqlHighlightRules = require(\"./plsql_highlight_rules\").plsqlHighlightRules;\nvar FoldMode = require(\"./folding/sql\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PLSqlHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/plsql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "src/mode/plsql_highlight_rules.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/* This file was autogenerated from  (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar plsqlHighlightRules = function() {\n    var keywords = (\n        \"all|alter|and|any|array|arrow|as|asc|at|begin|between|by|case|check|clusters|cluster|colauth|columns|compress|connect|crash|create|cross|current|database|declare|default|delete|desc|distinct|drop|else|end|exception|exclusive|exists|fetch|form|for|foreign|from|goto|grant|group|having|identified|if|in|inner|indexes|index|insert|intersect|into|is|join|key|left|like|lock|minus|mode|natural|nocompress|not|nowait|null|of|on|option|or|order|overlaps|outer|primary|prior|procedure|public|qualify|range|record|references|resource|revoke|right|select|share|size|sql|start|subtype|tabauth|table|then|to|type|union|unique|update|use|values|view|views|when|where|with\"\n    );\n\n    var builtinConstants = (\n        \"true|false\"\n    );\n\n    var builtinFunctions = (\n        \"abs|acos|add_months|ascii|asciistr|asin|atan|atan2|avg|bfilename|bin_to_num|bitand|cardinality|case|cast|ceil|chartorowid|chr|coalesce|compose|concat|convert|corr|cos|cosh|count|covar_pop|covar_samp|cume_dist|current_date|current_timestamp|dbtimezone|decode|decompose|dense_rank|dump|empty_blob|empty_clob|exp|extract|first_value|floor|from_tz|greatest|group_id|hextoraw|initcap|instr|instr2|instr4|instrb|instrc|lag|last_day|last_value|lead|least|length|length2|length4|lengthb|lengthc|listagg|ln|lnnvl|localtimestamp|log|lower|lpad|ltrim|max|median|min|mod|months_between|nanvl|nchr|new_time|next_day|nth_value|nullif|numtodsinterval|numtoyminterval|nvl|nvl2|power|rank|rawtohex|regexp_count|regexp_instr|regexp_replace|regexp_substr|remainder|replace|round|row_number|rownum|rpad|rtrim|sessiontimezone|sign|sin|sinh|soundex|sqrt|stddev|substr|sum|sys_context|sysdate|systimestamp|tan|tanh|to_char|to_clob|to_date|to_dsinterval|to_lob|to_multi_byte|to_nclob|to_number|to_single_byte|to_timestamp|to_timestamp_tz|to_yminterval|translate|trim|trunc|tz_offset|uid|upper|user|userenv|var_pop|var_samp|variance|vsize\"\n    );\n\n    var dataTypes = (\n        \"char|nchar|nvarchar2|varchar2|long|raw|\" +\n        \"number|numeric|float|dec|decimal|integer|int|smallint|real|double|precision|\" +\n        \"date|timestamp|interval|year|day|\" +\n        \"bfile|blob|clob|nclob|\" +\n        \"rowid|urowid\"\n    );\n    \n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants,\n        \"storage.type\": dataTypes\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"--.*$\"\n        },  {\n            token : \"comment\",\n            start : \"/\\\\*\",\n            end : \"\\\\*/\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\".*?\"'\n        }, {\n            token : \"string\",           // ' string\n            regex : \"'.*?'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(plsqlHighlightRules, TextHighlightRules);\n\nexports.plsqlHighlightRules = plsqlHighlightRules;\n"
  },
  {
    "path": "src/mode/powershell.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PowershellHighlightRules = require(\"./powershell_highlight_rules\").PowershellHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PowershellHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode({start: \"^\\\\s*(<#)\", end: \"^[#\\\\s]>\\\\s*$\"});\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n    this.blockComment = {start: \"<#\", end: \"#>\"};\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n      \n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/powershell\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/powershell_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PowershellHighlightRules = function() {\n    var identifierRe = \"[a-zA-Z\\\\?_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\?_\\u00a1-\\uffff]*\";\n\n    // Help Reference: about_Language_Keywords\n    // https://technet.microsoft.com/en-us/library/hh847744.aspx\n    var keywords = (\n        \"begin|break|catch|class|continue|data|define|do|dynamicparam|else|elseif|end|enum|exit|filter|\" +\n        \"finally|for|foreach|from|function|if|in|inlinescript|hidden|parallel|param|\" +\n        \"process|return|static|sequence|switch|throw|trap|try|until|using|while|workflow|var\"\n    );\n\n    // Command to enumerate all module commands in Windows PowerShell:\n    // PS C:\\> Get-Module -ListAvailable | Select-Object -Unique Name -ExpandProperty Name | Sort-Object |\n    //             ForEach-Object { \"// Module $_\"; '\"' + ((Get-Command -Module $_ | Select-Object -ExpandProperty Name) -join '|') + '|\" +' } | clip\n    var builtinFunctions = (\n        // Module AppBackgroundTask\n        \"Get-AppBackgroundTask|Start-AppBackgroundTask|Unregister-AppBackgroundTask|Disable-AppBackgroundTaskDiagnosticLog|Enable-AppBackgroundTaskDiagnosticLog|Set-AppBackgroundTaskResourcePolicy|\" +\n        // Module AppLocker\n        \"Get-AppLockerFileInformation|Get-AppLockerPolicy|New-AppLockerPolicy|Set-AppLockerPolicy|Test-AppLockerPolicy|\" +\n        // Module AppvClient\n        \"Add-AppvClientConnectionGroup|Add-AppvClientPackage|Add-AppvPublishingServer|Disable-Appv|Disable-AppvClientConnectionGroup|Disable-AppvClientMode|Disable-AppvPublishingServer|Enable-Appv|Enable-AppvClientConnectionGroup|Enable-AppvClientMode|Enable-AppvPublishingServer|Get-AppvClientApplication|Get-AppvClientConfiguration|Get-AppvClientConnectionGroup|Get-AppvClientMode|Get-AppvClientPackage|Get-AppvClientPackageStatus|Get-AppvClientPackageVersion|Get-AppvClientPackageVersionHistory|Get-AppvClientPackageVersionStatus|Get-AppvClientPublishingServer|Get-AppvClientSFTFileSystem|Get-AppvClientStatus|Get-AppvPublishingServer|Get-AppvVirtualProcess|Publish-AppvClientPackage|Remove-AppvClientConnectionGroup|Remove-AppvClientPackage|Remove-AppvPublishingServer|Set-AppvClientConfiguration|Set-AppvClientMode|Set-AppvClientPackage|Set-AppvClientPublishingServer|Set-AppvVirtualProcess|Sync-AppvPublishingServer|Get-AppvStatus|Mount-AppvClientConnectionGroup|Repair-AppvClientConnectionGroup|Repair-AppvClientPackage|Send-AppvClientReport|Set-AppvPublishingServer|Start-AppvVirtualProcess|Stop-AppvClientConnectionGroup|Stop-AppvClientPackage|Unpublish-AppvClientPackage|\" +\n        // Module AppvSequencer\n        \"Expand-AppvSequencerPackage|New-AppvPackageAccelerator|New-AppvSequencerPackage|Update-AppvSequencerPackage|\" + \n        // Module Appx\n        \"Add-AppSharedPackageContainer|Add-AppxPackage|Add-AppxVolume|Dismount-AppxVolume|Get-AppSharedPackageContainer|Get-AppxDefaultVolume|Get-AppxLastError|Get-AppxLog|Get-AppxPackage|Get-AppxPackageAutoUpdateSettings|Get-AppxPackageManifest|Get-AppxVolume|Invoke-CommandInDesktopPackage|Mount-AppxVolume|Move-AppxPackage|Remove-AppSharedPackageContainer|Remove-AppxPackage|Remove-AppxPackageAutoUpdateSettings|Remove-AppxVolume|Reset-AppSharedPackageContainer|Reset-AppxPackage|Set-AppxDefaultVolume|Set-AppxPackageAutoUpdateSettings|\" +\n        // Module AssignedAccess\n        \"Clear-AssignedAccess|Get-AssignedAccess|Set-AssignedAccess|\" +\n        // Module BestPractices\n        \"Get-BpaModel|Get-BpaResult|Invoke-BpaModel|Set-BpaResult|\" +\n        // Module BitLocker\n        \"Add-BitLockerKeyProtector|Backup-BitLockerKeyProtector|BackupToAAD-BitLockerKeyProtector|Clear-BitLockerAutoUnlock|Disable-BitLocker|Disable-BitLockerAutoUnlock|Enable-BitLocker|Enable-BitLockerAutoUnlock|Get-BitLockerVolume|Lock-BitLocker|Remove-BitLockerKeyProtector|Resume-BitLocker|Suspend-BitLocker|Unlock-BitLocker|\" +\n        // Module BitsTransfer\n        \"Add-BitsFile|Complete-BitsTransfer|Get-BitsTransfer|Remove-BitsTransfer|Resume-BitsTransfer|Set-BitsTransfer|Start-BitsTransfer|Suspend-BitsTransfer|\" +\n        // Module BootEventCollector\n        \"Checkpoint-SbecActiveConfig|Clear-SbecProviderCache|Disable-SbecAutologger|Disable-SbecBcd|Enable-SbecAutologger|Enable-SbecBcd|Enable-SbecBootImage|Enable-SbecWdsBcd|Get-SbecActiveConfig|Get-SbecBackupConfig|Get-SbecDestination|Get-SbecForwarding|Get-SbecHistory|Get-SbecLocalizedMessage|Get-SbecLogSession|Get-SbecTraceProviders|New-SbecUnattendFragment|Redo-SbecActiveConfig|Restore-SbecBackupConfig|Save-SbecInstance|Save-SbecLogSession|Set-SbecActiveConfig|Set-SbecLogSession|Start-SbecInstance|Start-SbecLogSession|Start-SbecNtKernelLogSession|Start-SbecSimpleLogSession|Stop-SbecInstance|Stop-SbecLogSession|Test-SbecActiveConfig|Test-SbecConfig|Undo-SbecActiveConfig|\" +\n        // Module BranchCache\n        \"Add-BCDataCacheExtension|Clear-BCCache|Disable-BC|Disable-BCDowngrading|Disable-BCServeOnBattery|Enable-BCDistributed|Enable-BCDowngrading|Enable-BCHostedClient|Enable-BCHostedServer|Enable-BCLocal|Enable-BCServeOnBattery|Export-BCCachePackage|Export-BCSecretKey|Get-BCClientConfiguration|Get-BCContentServerConfiguration|Get-BCDataCache|Get-BCDataCacheExtension|Get-BCHashCache|Get-BCHostedCacheServerConfiguration|Get-BCNetworkConfiguration|Get-BCStatus|Import-BCCachePackage|Import-BCSecretKey|Publish-BCFileContent|Publish-BCWebContent|Remove-BCDataCacheExtension|Reset-BC|Set-BCAuthentication|Set-BCCache|Set-BCDataCacheEntryMaxAge|Set-BCMinSMBLatency|Set-BCSecretKey|\" +\n        // Module ClusterAwareUpdating\n        \"Add-CauClusterRole|Disable-CauClusterRole|Enable-CauClusterRole|Export-CauReport|Get-CauClusterRole|Get-CauPlugin|Get-CauReport|Get-CauRun|Invoke-CauRun|Invoke-CauScan|Register-CauPlugin|Remove-CauClusterRole|Save-CauDebugTrace|Set-CauClusterRole|Stop-CauRun|Test-CauSetup|Unregister-CauPlugin|\" +\n        // Module CimCmdlets\n        \"Export-BinaryMiLog|Get-CimAssociatedInstance|Get-CimClass|Get-CimInstance|Get-CimSession|Import-BinaryMiLog|Invoke-CimMethod|New-CimInstance|New-CimSession|New-CimSessionOption|Register-CimIndicationEvent|Remove-CimInstance|Remove-CimSession|Set-CimInstance|\" +\n        // Module CIPolicy\n        \"ConvertFrom-CIPolicy|\" +\n        // Module ConfigCI\n        \"Add-SignerRule|ConvertFrom-CIPolicy|Edit-CIPolicyRule|Get-CIPolicy|Get-CIPolicyIdInfo|Get-CIPolicyInfo|Get-SystemDriver|Merge-CIPolicy|New-CIPolicy|New-CIPolicyRule|Remove-CIPolicyRule|Set-CIPolicyIdInfo|Set-CIPolicySetting|Set-CIPolicyVersion|Set-HVCIOptions|Set-RuleOption|\" +\n        // Module DcbQoS\n        \"Disable-NetQosFlowControl|Enable-NetQosFlowControl|Get-NetQosDcbxSetting|Get-NetQosFlowControl|Get-NetQosTrafficClass|New-NetQosTrafficClass|Remove-NetQosTrafficClass|Set-NetQosDcbxSetting|Set-NetQosFlowControl|Set-NetQosTrafficClass|Switch-NetQosDcbxSetting|Switch-NetQosFlowControl|Switch-NetQosTrafficClass|\" +\n        // Module Deduplication\n        \"Disable-DedupVolume|Enable-DedupVolume|Expand-DedupFile|Get-DedupJob|Get-DedupMetadata|Get-DedupSchedule|Get-DedupStatus|Get-DedupVolume|Measure-DedupFileMetadata|New-DedupSchedule|Remove-DedupSchedule|Set-DedupSchedule|Set-DedupVolume|Start-DedupJob|Stop-DedupJob|Update-DedupStatus|\" +\n        // Module Defender\n        \"Add-MpPreference|Get-MpComputerStatus|Get-MpPreference|Get-MpThreat|Get-MpThreatCatalog|Get-MpThreatDetection|Remove-MpPreference|Remove-MpThreat|Set-MpPreference|Start-MpScan|Start-MpWDOScan|Update-MpSignature|\" +\n        // Module DeviceHealthAttestation\n        \"Backup-DHASConfiguration|Get-DHASActiveEncryptionCertificate|Get-DHASActiveSigningCertificate|Get-DHASCertificateChainPolicy|Get-DHASInactiveEncryptionCertificate|Get-DHASInactiveSigningCertificate|Install-DeviceHealthAttestation|Remove-DHASInactiveEncryptionCertificate|Remove-DHASInactiveSigningCertificate|Restore-DHASConfiguration|Set-DHASActiveEncryptionCertificate|Set-DHASActiveSigningCertificate|Set-DHASCertificateChainPolicy|Set-DHASSupportedAuthenticationSchema|Uninstall-DeviceHealthAttestation||\" +\n        // Module DFSN\n        \"Get-DfsnAccess|Get-DfsnFolder|Get-DfsnFolderTarget|Get-DfsnRoot|Get-DfsnRootTarget|Get-DfsnServerConfiguration|Grant-DfsnAccess|Move-DfsnFolder|New-DfsnFolder|New-DfsnFolderTarget|New-DfsnRoot|New-DfsnRootTarget|Remove-DfsnAccess|Remove-DfsnFolder|Remove-DfsnFolderTarget|Remove-DfsnRoot|Remove-DfsnRootTarget|Revoke-DfsnAccess|Set-DfsnFolder|Set-DfsnFolderTarget|Set-DfsnRoot|Set-DfsnRootTarget|Set-DfsnServerConfiguration|\" +\n        // Module DFSR\n        \"Add-DfsrConnection|Add-DfsrMember|ConvertFrom-DfsrGuid|Export-DfsrClone|Get-DfsrBacklog|Get-DfsrCloneState|Get-DfsrConnection|Get-DfsrConnectionSchedule|Get-DfsrDelegation|Get-DfsReplicatedFolder|Get-DfsReplicationGroup|Get-DfsrFileHash|Get-DfsrGroupSchedule|Get-DfsrIdRecord|Get-DfsrMember|Get-DfsrMembership|Get-DfsrPreservedFiles|Get-DfsrServiceConfiguration|Get-DfsrState|Grant-DfsrDelegation|Import-DfsrClone|New-DfsReplicatedFolder|New-DfsReplicationGroup|Remove-DfsrConnection|Remove-DfsReplicatedFolder|Remove-DfsReplicationGroup|Remove-DfsrMember|Remove-DfsrPropagationTestFile|Reset-DfsrCloneState|Restore-DfsrPreservedFiles|Revoke-DfsrDelegation|Set-DfsrConnection|Set-DfsrConnectionSchedule|Set-DfsReplicatedFolder|Set-DfsReplicationGroup|Set-DfsrGroupSchedule|Set-DfsrMember|Set-DfsrMembership|Set-DfsrServiceConfiguration|Start-DfsrPropagationTest|Suspend-DfsReplicationGroup|Sync-DfsReplicationGroup|Update-DfsrConfigurationFromAD|Write-DfsrHealthReport|Write-DfsrPropagationReport|\" +\n        // Module DhcpServer\n        \"Add-DhcpServerInDC|Add-DhcpServerSecurityGroup|Add-DhcpServerv4Class|Add-DhcpServerv4ExclusionRange|Add-DhcpServerv4Failover|Add-DhcpServerv4FailoverScope|Add-DhcpServerv4Filter|Add-DhcpServerv4Lease|Add-DhcpServerv4MulticastExclusionRange|Add-DhcpServerv4MulticastScope|Add-DhcpServerv4OptionDefinition|Add-DhcpServerv4Policy|Add-DhcpServerv4PolicyIPRange|Add-DhcpServerv4Reservation|Add-DhcpServerv4Scope|Add-DhcpServerv4Superscope|Add-DhcpServerv6Class|Add-DhcpServerv6ExclusionRange|Add-DhcpServerv6Lease|Add-DhcpServerv6OptionDefinition|Add-DhcpServerv6Reservation|Add-DhcpServerv6Scope|Backup-DhcpServer|Export-DhcpServer|Get-DhcpServerAuditLog|Get-DhcpServerDatabase|Get-DhcpServerDnsCredential|Get-DhcpServerInDC|Get-DhcpServerSetting|Get-DhcpServerv4Binding|Get-DhcpServerv4Class|Get-DhcpServerv4DnsSetting|Get-DhcpServerv4ExclusionRange|Get-DhcpServerv4Failover|Get-DhcpServerv4Filter|Get-DhcpServerv4FilterList|Get-DhcpServerv4FreeIPAddress|Get-DhcpServerv4Lease|Get-DhcpServerv4MulticastExclusionRange|Get-DhcpServerv4MulticastLease|Get-DhcpServerv4MulticastScope|Get-DhcpServerv4MulticastScopeStatistics|Get-DhcpServerv4OptionDefinition|Get-DhcpServerv4OptionValue|Get-DhcpServerv4Policy|Get-DhcpServerv4PolicyIPRange|Get-DhcpServerv4Reservation|Get-DhcpServerv4Scope|Get-DhcpServerv4ScopeStatistics|Get-DhcpServerv4Statistics|Get-DhcpServerv4Superscope|Get-DhcpServerv4SuperscopeStatistics|Get-DhcpServerv6Binding|Get-DhcpServerv6Class|Get-DhcpServerv6DnsSetting|Get-DhcpServerv6ExclusionRange|Get-DhcpServerv6FreeIPAddress|Get-DhcpServerv6Lease|Get-DhcpServerv6OptionDefinition|Get-DhcpServerv6OptionValue|Get-DhcpServerv6Reservation|Get-DhcpServerv6Scope|Get-DhcpServerv6ScopeStatistics|Get-DhcpServerv6StatelessStatistics|Get-DhcpServerv6StatelessStore|Get-DhcpServerv6Statistics|Get-DhcpServerVersion|Import-DhcpServer|Invoke-DhcpServerv4FailoverReplication|Remove-DhcpServerDnsCredential|Remove-DhcpServerInDC|Remove-DhcpServerv4Class|Remove-DhcpServerv4ExclusionRange|Remove-DhcpServerv4Failover|Remove-DhcpServerv4FailoverScope|Remove-DhcpServerv4Filter|Remove-DhcpServerv4Lease|Remove-DhcpServerv4MulticastExclusionRange|Remove-DhcpServerv4MulticastLease|Remove-DhcpServerv4MulticastScope|Remove-DhcpServerv4OptionDefinition|Remove-DhcpServerv4OptionValue|Remove-DhcpServerv4Policy|Remove-DhcpServerv4PolicyIPRange|Remove-DhcpServerv4Reservation|Remove-DhcpServerv4Scope|Remove-DhcpServerv4Superscope|Remove-DhcpServerv6Class|Remove-DhcpServerv6ExclusionRange|Remove-DhcpServerv6Lease|Remove-DhcpServerv6OptionDefinition|Remove-DhcpServerv6OptionValue|Remove-DhcpServerv6Reservation|Remove-DhcpServerv6Scope|Rename-DhcpServerv4Superscope|Repair-DhcpServerv4IPRecord|Restore-DhcpServer|Set-DhcpServerAuditLog|Set-DhcpServerDatabase|Set-DhcpServerDnsCredential|Set-DhcpServerSetting|Set-DhcpServerv4Binding|Set-DhcpServerv4Class|Set-DhcpServerv4DnsSetting|Set-DhcpServerv4Failover|Set-DhcpServerv4FilterList|Set-DhcpServerv4MulticastScope|Set-DhcpServerv4OptionDefinition|Set-DhcpServerv4OptionValue|Set-DhcpServerv4Policy|Set-DhcpServerv4Reservation|Set-DhcpServerv4Scope|Set-DhcpServerv6Binding|Set-DhcpServerv6Class|Set-DhcpServerv6DnsSetting|Set-DhcpServerv6OptionDefinition|Set-DhcpServerv6OptionValue|Set-DhcpServerv6Reservation|Set-DhcpServerv6Scope|Set-DhcpServerv6StatelessStore|\" +\n        // Module DirectAccessClientComponents\n        \"Disable-DAManualEntryPointSelection|Enable-DAManualEntryPointSelection|Get-DAClientExperienceConfiguration|Get-DAEntryPointTableItem|New-DAEntryPointTableItem|Remove-DAEntryPointTableItem|Rename-DAEntryPointTableItem|Reset-DAClientExperienceConfiguration|Reset-DAEntryPointTableItem|Set-DAClientExperienceConfiguration|Set-DAEntryPointTableItem|\" +\n        // Module Dism\n        \"Add-AppxProvisionedPackage|Add-WindowsCapability|Add-WindowsDriver|Add-WindowsImage|Add-WindowsPackage|Clear-WindowsCorruptMountPoint|Disable-WindowsOptionalFeature|Dismount-WindowsImage|Enable-WindowsOptionalFeature|Expand-WindowsCustomDataImage|Expand-WindowsImage|Export-WindowsCapabilitySource|Export-WindowsDriver|Export-WindowsImage|Get-AppxProvisionedPackage|Get-NonRemovableAppsPolicy|Get-WIMBootEntry|Get-WindowsCapability|Get-WindowsDriver|Get-WindowsEdition|Get-WindowsImage|Get-WindowsImageContent|Get-WindowsOptionalFeature|Get-WindowsPackage|Get-WindowsReservedStorageState|Mount-WindowsImage|New-WindowsCustomImage|New-WindowsImage|Optimize-AppXProvisionedPackages|Optimize-WindowsImage|Remove-AppxProvisionedPackage|Remove-WindowsCapability|Remove-WindowsDriver|Remove-WindowsImage|Remove-WindowsPackage|Repair-WindowsImage|Save-WindowsImage|Set-AppXProvisionedDataFile|Set-NonRemovableAppsPolicy|Set-WindowsEdition|Set-WindowsProductKey|Set-WindowsReservedStorageState|Split-WindowsImage|Start-OSUninstall|Update-WIMBootEntry|Use-WindowsUnattend|\" +\n        // Module DnsClient\n        \"Add-DnsClientDohServerAddress|Add-DnsClientNrptRule|Clear-DnsClientCache|Get-DnsClient|Get-DnsClientCache|Get-DnsClientDohServerAddress|Get-DnsClientGlobalSetting|Get-DnsClientNrptGlobal|Get-DnsClientNrptPolicy|Get-DnsClientNrptRule|Get-DnsClientServerAddress|Register-DnsClient|Remove-DnsClientDohServerAddress|Remove-DnsClientNrptRule|Resolve-DnsName|Set-DnsClient|Set-DnsClientDohServerAddress|Set-DnsClientGlobalSetting|Set-DnsClientNrptGlobal|Set-DnsClientNrptRule|Set-DnsClientServerAddress|\" +\n        // Module DnsServer\n        \"Add-DnsServerClientSubnet|Add-DnsServerConditionalForwarderZone|Add-DnsServerDirectoryPartition|Add-DnsServerForwarder|Add-DnsServerPrimaryZone|Add-DnsServerQueryResolutionPolicy|Add-DnsServerRecursionScope|Add-DnsServerResourceRecord|Add-DnsServerResourceRecordA|Add-DnsServerResourceRecordAAAA|Add-DnsServerResourceRecordCName|Add-DnsServerResourceRecordDnsKey|Add-DnsServerResourceRecordDS|Add-DnsServerResourceRecordMX|Add-DnsServerResourceRecordPtr|Add-DnsServerResponseRateLimitingExceptionlist|Add-DnsServerRootHint|Add-DnsServerSecondaryZone|Add-DnsServerSigningKey|Add-DnsServerStubZone|Add-DnsServerTrustAnchor|Add-DnsServerVirtualizationInstance|Add-DnsServerZoneDelegation|Add-DnsServerZoneScope|Add-DnsServerZoneTransferPolicy|Clear-DnsServerCache|Clear-DnsServerStatistics|ConvertTo-DnsServerPrimaryZone|ConvertTo-DnsServerSecondaryZone|Disable-DnsServerPolicy|Disable-DnsServerSigningKeyRollover|Enable-DnsServerPolicy|Enable-DnsServerSigningKeyRollover|Export-DnsServerDnsSecPublicKey|Export-DnsServerZone|Get-DnsServer|Get-DnsServerCache|Get-DnsServerClientSubnet|Get-DnsServerDiagnostics|Get-DnsServerDirectoryPartition|Get-DnsServerDnsSecZoneSetting|Get-DnsServerDsSetting|Get-DnsServerEDns|Get-DnsServerForwarder|Get-DnsServerGlobalNameZone|Get-DnsServerGlobalQueryBlockList|Get-DnsServerQueryResolutionPolicy|Get-DnsServerRecursion|Get-DnsServerRecursionScope|Get-DnsServerResourceRecord|Get-DnsServerResponseRateLimiting|Get-DnsServerResponseRateLimitingExceptionlist|Get-DnsServerRootHint|Get-DnsServerScavenging|Get-DnsServerSetting|Get-DnsServerSigningKey|Get-DnsServerStatistics|Get-DnsServerTrustAnchor|Get-DnsServerTrustPoint|Get-DnsServerVirtualizationInstance|Get-DnsServerZone|Get-DnsServerZoneAging|Get-DnsServerZoneDelegation|Get-DnsServerZoneScope|Get-DnsServerZoneTransferPolicy|Import-DnsServerResourceRecordDS|Import-DnsServerRootHint|Import-DnsServerTrustAnchor|Invoke-DnsServerSigningKeyRollover|Invoke-DnsServerZoneSign|Invoke-DnsServerZoneUnsign|Register-DnsServerDirectoryPartition|Remove-DnsServerClientSubnet|Remove-DnsServerDirectoryPartition|Remove-DnsServerForwarder|Remove-DnsServerQueryResolutionPolicy|Remove-DnsServerRecursionScope|Remove-DnsServerResourceRecord|Remove-DnsServerResponseRateLimitingExceptionlist|Remove-DnsServerRootHint|Remove-DnsServerSigningKey|Remove-DnsServerTrustAnchor|Remove-DnsServerVirtualizationInstance|Remove-DnsServerZone|Remove-DnsServerZoneDelegation|Remove-DnsServerZoneScope|Remove-DnsServerZoneTransferPolicy|Reset-DnsServerZoneKeyMasterRole|Restore-DnsServerPrimaryZone|Restore-DnsServerSecondaryZone|Resume-DnsServerZone|Set-DnsServer|Set-DnsServerCache|Set-DnsServerClientSubnet|Set-DnsServerConditionalForwarderZone|Set-DnsServerDiagnostics|Set-DnsServerDnsSecZoneSetting|Set-DnsServerDsSetting|Set-DnsServerEDns|Set-DnsServerForwarder|Set-DnsServerGlobalNameZone|Set-DnsServerGlobalQueryBlockList|Set-DnsServerPrimaryZone|Set-DnsServerQueryResolutionPolicy|Set-DnsServerRecursion|Set-DnsServerRecursionScope|Set-DnsServerResourceRecord|Set-DnsServerResourceRecordAging|Set-DnsServerResponseRateLimiting|Set-DnsServerResponseRateLimitingExceptionlist|Set-DnsServerRootHint|Set-DnsServerScavenging|Set-DnsServerSecondaryZone|Set-DnsServerSetting|Set-DnsServerSigningKey|Set-DnsServerStubZone|Set-DnsServerVirtualizationInstance|Set-DnsServerZoneAging|Set-DnsServerZoneDelegation|Set-DnsServerZoneTransferPolicy|Show-DnsServerCache|Show-DnsServerKeyStorageProvider|Start-DnsServerScavenging|Start-DnsServerZoneTransfer|Step-DnsServerSigningKeyRollover|Suspend-DnsServerZone|Sync-DnsServerZone|Test-DnsServer|Test-DnsServerDnsSecZoneSetting|Unregister-DnsServerDirectoryPartition|Update-DnsServerTrustPoint|\" +\n        // Module EventTracingManagement\n        \"Add-EtwTraceProvider|Get-AutologgerConfig|Get-EtwTraceProvider|Get-EtwTraceSession|New-AutologgerConfig|New-EtwTraceSession|Remove-AutologgerConfig|Remove-EtwTraceProvider|Save-EtwTraceSession|Send-EtwTraceSession|Set-EtwTraceProvider|Start-EtwTraceSession|Stop-EtwTraceSession|Update-AutologgerConfig|Update-EtwTraceSession|\" +\n        // Module FailoverClusters\n        \"Add-ClusterCheckpoint|Add-ClusterDisk|Add-ClusterFileServerRole|Add-ClusterGenericApplicationRole|Add-ClusterGenericScriptRole|Add-ClusterGenericServiceRole|Add-ClusterGroup|Add-ClusterGroupSetDependency|Add-ClusterGroupToSet|Add-ClusteriSCSITargetServerRole|Add-ClusterNode|Add-ClusterResource|Add-ClusterResourceDependency|Add-ClusterResourceType|Add-ClusterScaleOutFileServerRole|Add-ClusterSharedVolume|Add-ClusterVirtualMachineRole|Add-ClusterVMMonitoredItem|Block-ClusterAccess|Clear-ClusterDiskReservation|Clear-ClusterNode|Disable-ClusterStorageSpacesDirect|Enable-ClusterStorageSpacesDirect|Get-Cluster|Get-ClusterAccess|Get-ClusterAvailableDisk|Get-ClusterCheckpoint|Get-ClusterDiagnosticInfo|Get-ClusterFaultDomain|Get-ClusterFaultDomainXML|Get-ClusterGroup|Get-ClusterGroupSet|Get-ClusterGroupSetDependency|Get-ClusterLog|Get-ClusterNetwork|Get-ClusterNetworkInterface|Get-ClusterNode|Get-ClusterOwnerNode|Get-ClusterParameter|Get-ClusterQuorum|Get-ClusterResource|Get-ClusterResourceDependency|Get-ClusterResourceDependencyReport|Get-ClusterResourceType|Get-ClusterSharedVolume|Get-ClusterSharedVolumeState|Get-ClusterStorageSpacesDirect|Get-ClusterVMMonitoredItem|Grant-ClusterAccess|Move-ClusterGroup|Move-ClusterResource|Move-ClusterSharedVolume|Move-ClusterVirtualMachineRole|New-Cluster|New-ClusterFaultDomain|New-ClusterGroupSet|New-ClusterNameAccount|Remove-Cluster|Remove-ClusterAccess|Remove-ClusterCheckpoint|Remove-ClusterFaultDomain|Remove-ClusterGroup|Remove-ClusterGroupFromSet|Remove-ClusterGroupSet|Remove-ClusterGroupSetDependency|Remove-ClusterNode|Remove-ClusterResource|Remove-ClusterResourceDependency|Remove-ClusterResourceType|Remove-ClusterSharedVolume|Remove-ClusterVMMonitoredItem|Repair-ClusterStorageSpacesDirect|Reset-ClusterVMMonitoredState|Resume-ClusterNode|Resume-ClusterResource|Set-ClusterFaultDomain|Set-ClusterFaultDomainXML|Set-ClusterGroupSet|Set-ClusterLog|Set-ClusterOwnerNode|Set-ClusterParameter|Set-ClusterQuorum|Set-ClusterResourceDependency|Set-ClusterStorageSpacesDirect|Set-ClusterStorageSpacesDirectDisk|Start-Cluster|Start-ClusterGroup|Start-ClusterNode|Start-ClusterResource|Stop-Cluster|Stop-ClusterGroup|Stop-ClusterNode|Stop-ClusterResource|Suspend-ClusterNode|Suspend-ClusterResource|Test-Cluster|Test-ClusterResourceFailure|Update-ClusterFunctionalLevel|Update-ClusterIPResource|Update-ClusterNetworkNameResource|Update-ClusterVirtualMachineConfiguration|\" +\n        // Module FileServerResourceManager\n        \"Get-FsrmAdrSetting|Get-FsrmAutoQuota|Get-FsrmClassification|Get-FsrmClassificationPropertyDefinition|Get-FsrmClassificationRule|Get-FsrmEffectiveNamespace|Get-FsrmFileGroup|Get-FsrmFileManagementJob|Get-FsrmFileScreen|Get-FsrmFileScreenException|Get-FsrmFileScreenTemplate|Get-FsrmMacro|Get-FsrmMgmtProperty|Get-FsrmQuota|Get-FsrmQuotaTemplate|Get-FsrmRmsTemplate|Get-FsrmSetting|Get-FsrmStorageReport|New-FsrmAction|New-FsrmAutoQuota|New-FsrmClassificationPropertyDefinition|New-FsrmClassificationPropertyValue|New-FsrmClassificationRule|New-FsrmFileGroup|New-FsrmFileManagementJob|New-FsrmFileScreen|New-FsrmFileScreenException|New-FsrmFileScreenTemplate|New-FsrmFmjAction|New-FsrmFmjCondition|New-FsrmFMJNotification|New-FsrmFmjNotificationAction|New-FsrmQuota|New-FsrmQuotaTemplate|New-FsrmQuotaThreshold|New-FsrmScheduledTask|New-FsrmStorageReport|Remove-FsrmAutoQuota|Remove-FsrmClassificationPropertyDefinition|Remove-FsrmClassificationRule|Remove-FsrmFileGroup|Remove-FsrmFileManagementJob|Remove-FsrmFileScreen|Remove-FsrmFileScreenException|Remove-FsrmFileScreenTemplate|Remove-FsrmMgmtProperty|Remove-FsrmQuota|Remove-FsrmQuotaTemplate|Remove-FsrmStorageReport|Reset-FsrmFileScreen|Reset-FsrmQuota|Send-FsrmTestEmail|Set-FsrmAdrSetting|Set-FsrmAutoQuota|Set-FsrmClassification|Set-FsrmClassificationPropertyDefinition|Set-FsrmClassificationRule|Set-FsrmFileGroup|Set-FsrmFileManagementJob|Set-FsrmFileScreen|Set-FsrmFileScreenException|Set-FsrmFileScreenTemplate|Set-FsrmMgmtProperty|Set-FsrmQuota|Set-FsrmQuotaTemplate|Set-FsrmSetting|Set-FsrmStorageReport|Start-FsrmClassification|Start-FsrmFileManagementJob|Start-FsrmStorageReport|Stop-FsrmClassification|Stop-FsrmFileManagementJob|Stop-FsrmStorageReport|Update-FsrmAutoQuota|Update-FsrmClassificationPropertyDefinition|Update-FsrmQuota|Wait-FsrmClassification|Wait-FsrmFileManagementJob|Wait-FsrmStorageReport|\" +\n        // Module GroupPolicy\n        \"Backup-GPO|Copy-GPO|Get-GPInheritance|Get-GPO|Get-GPOReport|Get-GPPermission|Get-GPPrefRegistryValue|Get-GPRegistryValue|Get-GPResultantSetOfPolicy|Get-GPStarterGPO|Import-GPO|Invoke-GPUpdate|New-GPLink|New-GPO|New-GPStarterGPO|Remove-GPLink|Remove-GPO|Remove-GPPrefRegistryValue|Remove-GPRegistryValue|Rename-GPO|Restore-GPO|Set-GPInheritance|Set-GPLink|Set-GPPermission|Set-GPPrefRegistryValue|Set-GPRegistryValue|\" +\n        // Module HardwareCertification\n        \"Export-HwCertTestCollectionToXml|Import-HwCertTestCollectionFromXml|Merge-HwCertTestCollectionFromPackage|Merge-HwCertTestCollectionFromXml|New-HwCertProjectDefinitionFile|New-HwCertTestCollection|New-HwCertTestCollectionExcelReport|\" +\n        // Module HgsAttestation\n        \"Add-HgsAttestationCIPolicy|Add-HgsAttestationDumpPolicy|Add-HgsAttestationHostGroup|Add-HgsAttestationTpmHost|Add-HgsAttestationTpmPolicy|Disable-HgsAttestationPolicy|Enable-HgsAttestationPolicy|Get-HgsAttestationHostGroup|Get-HgsAttestationPolicy|Get-HgsAttestationSignerCertificate|Get-HgsAttestationTpmHost|Remove-HgsAttestationHostGroup|Remove-HgsAttestationPolicy|Remove-HgsAttestationTpmHost|\" +\n        // Module HgsClient\n        \"ConvertTo-HgsKeyProtector|Export-HgsGuardian|Get-HgsAttestationBaselinePolicy|Get-HgsClientConfiguration|Get-HgsGuardian|Grant-HgsKeyProtectorAccess|Import-HgsGuardian|New-HgsGuardian|New-HgsKeyProtector|Remove-HgsGuardian|Revoke-HgsKeyProtectorAccess|Set-HgsClientConfiguration|Test-HgsClientConfiguration|\" +\n        // Module HgsDiagnostics\n        \"Get-HgsTrace|Get-HgsTraceFileData|New-HgsTraceTarget|Test-HgsTraceTarget|\" +\n        // Module HgsKeyProtection\n        \"Add-HgsKeyProtectionAttestationSignerCertificate|Add-HgsKeyProtectionCertificate|Export-HgsKeyProtectionState|Get-HgsKeyProtectionAttestationSignerCertificate|Get-HgsKeyProtectionCertificate|Get-HgsKeyProtectionConfiguration|Import-HgsKeyProtectionState|Remove-HgsKeyProtectionAttestationSignerCertificate|Remove-HgsKeyProtectionCertificate|Set-HgsKeyProtectionAttestationSignerCertificatePolicy|Set-HgsKeyProtectionCertificate|Set-HgsKeyProtectionConfiguration|\" +\n        // Module HgsServer\n        \"Clear-HgsServer|Export-HgsServerState|Get-HgsServer|Import-HgsServerState|Initialize-HgsServer|Install-HgsServer|Set-HgsServer|Test-HgsServer|Uninstall-HgsServer|\" +\n        // Module HNVDiagnostics\n        \"Debug-SlbDatapath|Debug-VirtualMachineQueueOperation|Disable-MuxEchoResponder|Enable-MuxEchoResponder|Get-CustomerRoute|Get-NetworkControllerVipResource|Get-PACAMapping|Get-ProviderAddress|Get-VipHostMapping|Get-VMNetworkAdapterPortId|Get-VMSwitchExternalPortId|Test-DipHostReachability|Test-EncapOverheadSettings|Test-LogicalNetworkConnection|Test-LogicalNetworkSupportsJumboPacket|Test-VipReachability|Test-VirtualNetworkConnection|\" +\n        // Module HostComputeService\n        \"Get-ComputeProcess|Stop-ComputeProcess|\" +\n        // Module Hyper-V\n        \"Add-VMDvdDrive|Add-VMFibreChannelHba|Add-VMGpuPartitionAdapter|Add-VMGroupMember|Add-VMHardDiskDrive|Add-VMMigrationNetwork|Add-VMNetworkAdapter|Add-VMNetworkAdapterAcl|Add-VMNetworkAdapterExtendedAcl|Add-VmNetworkAdapterRoutingDomainMapping|Add-VMRemoteFx3dVideoAdapter|Add-VMScsiController|Add-VMStoragePath|Add-VMSwitch|Add-VMSwitchExtensionPortFeature|Add-VMSwitchExtensionSwitchFeature|Add-VMSwitchTeamMember|Checkpoint-VM|Compare-VM|Complete-VMFailover|Connect-VMNetworkAdapter|Connect-VMSan|Convert-VHD|Copy-VMFile|Debug-VM|Disable-VMConsoleSupport|Disable-VMEventing|Disable-VMIntegrationService|Disable-VMMigration|Disable-VMRemoteFXPhysicalVideoAdapter|Disable-VMResourceMetering|Disable-VMSwitchExtension|Disable-VMTPM|Disconnect-VMNetworkAdapter|Disconnect-VMSan|Dismount-VHD|Enable-VMConsoleSupport|Enable-VMEventing|Enable-VMIntegrationService|Enable-VMMigration|Enable-VMRemoteFXPhysicalVideoAdapter|Enable-VMReplication|Enable-VMResourceMetering|Enable-VMSwitchExtension|Enable-VMTPM|Export-VM|Export-VMSnapshot|Get-VHD|Get-VHDSet|Get-VHDSnapshot|Get-VM|Get-VMBios|Get-VMComPort|Get-VMConnectAccess|Get-VMDvdDrive|Get-VMFibreChannelHba|Get-VMFirmware|Get-VMFloppyDiskDrive|Get-VMGpuPartitionAdapter|Get-VMGroup|Get-VMHardDiskDrive|Get-VMHost|Get-VMHostCluster|Get-VMHostNumaNode|Get-VMHostNumaNodeStatus|Get-VMHostPartitionableGpu|Get-VMHostSupportedVersion|Get-VMIdeController|Get-VMIntegrationService|Get-VMKeyProtector|Get-VMMemory|Get-VMMigrationNetwork|Get-VMNetworkAdapter|Get-VMNetworkAdapterAcl|Get-VMNetworkAdapterExtendedAcl|Get-VMNetworkAdapterFailoverConfiguration|Get-VmNetworkAdapterIsolation|Get-VMNetworkAdapterRoutingDomainMapping|Get-VMNetworkAdapterTeamMapping|Get-VMNetworkAdapterVlan|Get-VMProcessor|Get-VMRemoteFx3dVideoAdapter|Get-VMRemoteFXPhysicalVideoAdapter|Get-VMReplication|Get-VMReplicationAuthorizationEntry|Get-VMReplicationServer|Get-VMResourcePool|Get-VMSan|Get-VMScsiController|Get-VMSecurity|Get-VMSnapshot|Get-VMStoragePath|Get-VMSwitch|Get-VMSwitchExtension|Get-VMSwitchExtensionPortData|Get-VMSwitchExtensionPortFeature|Get-VMSwitchExtensionSwitchData|Get-VMSwitchExtensionSwitchFeature|Get-VMSwitchTeam|Get-VMSystemSwitchExtension|Get-VMSystemSwitchExtensionPortFeature|Get-VMSystemSwitchExtensionSwitchFeature|Get-VMVideo|Grant-VMConnectAccess|Import-VM|Import-VMInitialReplication|Measure-VM|Measure-VMReplication|Measure-VMResourcePool|Merge-VHD|Mount-VHD|Move-VM|Move-VMStorage|New-VFD|New-VHD|New-VM|New-VMGroup|||New-VMReplicationAuthorizationEntry|New-VMResourcePool|New-VMSan|New-VMSwitch|Optimize-VHD|Optimize-VHDSet|Remove-VHDSnapshot|Remove-VM|Remove-VMDvdDrive|Remove-VMFibreChannelHba|Remove-VMGpuPartitionAdapter|Remove-VMGroup|Remove-VMGroupMember|Remove-VMHardDiskDrive|Remove-VMMigrationNetwork|Remove-VMNetworkAdapter|Remove-VMNetworkAdapterAcl|Remove-VMNetworkAdapterExtendedAcl|Remove-VMNetworkAdapterRoutingDomainMapping|Remove-VMNetworkAdapterTeamMapping|Remove-VMRemoteFx3dVideoAdapter|Remove-VMReplication|Remove-VMReplicationAuthorizationEntry|Remove-VMResourcePool|Remove-VMSan|Remove-VMSavedState|Remove-VMScsiController|Remove-VMSnapshot|Remove-VMStoragePath|Remove-VMSwitch|Remove-VMSwitchExtensionPortFeature|Remove-VMSwitchExtensionSwitchFeature|Remove-VMSwitchTeamMember|Rename-VM|Rename-VMGroup|Rename-VMNetworkAdapter|Rename-VMResourcePool|Rename-VMSan|Rename-VMSnapshot|Rename-VMSwitch|Repair-VM|Reset-VMReplicationStatistics|Reset-VMResourceMetering|Resize-VHD|Restart-VM|Restore-VMSnapshot|Resume-VM|Resume-VMReplication|Revoke-VMConnectAccess|Save-VM|Set-VHD|Set-VM|Set-VMBios|Set-VMComPort|Set-VMDvdDrive|Set-VMFibreChannelHba|Set-VMFirmware|Set-VMFloppyDiskDrive|Set-VMGpuPartitionAdapter|Set-VMHardDiskDrive|Set-VMHost|Set-VMHostCluster|Set-VMHostPartitionableGpu|Set-VMKeyProtector|Set-VMMemory|Set-VMMigrationNetwork|Set-VMNetworkAdapter|Set-VMNetworkAdapterFailoverConfiguration|Set-VmNetworkAdapterIsolation|Set-VmNetworkAdapterRoutingDomainMapping|Set-VMNetworkAdapterTeamMapping|Set-VMNetworkAdapterVlan|Set-VMProcessor|Set-VMRemoteFx3dVideoAdapter|Set-VMReplication|Set-VMReplicationAuthorizationEntry|Set-VMReplicationServer|Set-VMResourcePool|Set-VMSan|Set-VMSecurity|Set-VMSecurityPolicy|Set-VMSwitch|Set-VMSwitchExtensionPortFeature|Set-VMSwitchExtensionSwitchFeature|Set-VMSwitchTeam|Set-VMVideo|Start-VM|Start-VMFailover|Start-VMInitialReplication|Start-VMTrace|Stop-VM|Stop-VMFailover|Stop-VMInitialReplication|Stop-VMReplication|Stop-VMTrace|Suspend-VM|Suspend-VMReplication|Test-VHD|Test-VMNetworkAdapter|Test-VMReplicationConnection|Update-VMVersion|\" +\n        // Module IISAdministration\n        \"Clear-IISCentralCertProvider|Clear-IISConfigCollection|Disable-IISCentralCertProvider|Disable-IISSharedConfig|Enable-IISCentralCertProvider|Enable-IISSharedConfig|Export-IISConfiguration|Get-IISAppPool|Get-IISCentralCertProvider|Get-IISConfigAttributeValue|Get-IISConfigCollection|Get-IISConfigCollectionElement|Get-IISConfigElement|Get-IISConfigSection|Get-IISServerManager|Get-IISSharedConfig|Get-IISSite|Get-IISSiteBinding|New-IISConfigCollectionElement|New-IISSite|New-IISSiteBinding|Remove-IISConfigAttribute|Remove-IISConfigCollectionElement|Remove-IISConfigElement|Remove-IISSite|Remove-IISSiteBinding|Reset-IISServerManager|Set-IISCentralCertProvider|Set-IISCentralCertProviderCredential|Set-IISConfigAttributeValue|Start-IISCommitDelay|Start-IISSite|Stop-IISCommitDelay|Stop-IISSite|\" +\n        // Module International\n        \"Copy-UserInternationalSettingsToSystem|Get-WinAcceptLanguageFromLanguageListOptOut|Get-WinCultureFromLanguageListOptOut|Get-WinDefaultInputMethodOverride|Get-WinHomeLocation|Get-WinLanguageBarOption|Get-WinSystemLocale|Get-WinUILanguageOverride|Get-WinUserLanguageList|New-WinUserLanguageList|Set-Culture|Set-WinAcceptLanguageFromLanguageListOptOut|Set-WinCultureFromLanguageListOptOut|Set-WinDefaultInputMethodOverride|Set-WinHomeLocation|Set-WinLanguageBarOption|Set-WinSystemLocale|Set-WinUILanguageOverride|Set-WinUserLanguageList|\" +\n        // Module IpamServer\n        \"Add-IpamAddress|Add-IpamAddressSpace|Add-IpamBlock|Add-IpamCustomField|Add-IpamCustomFieldAssociation|Add-IpamCustomValue|Add-IpamDiscoveryDomain|\" +\n        // Module iSCSI\n        \"Connect-IscsiTarget|Disconnect-IscsiTarget|Get-IscsiConnection|Get-IscsiSession|Get-IscsiTarget|Get-IscsiTargetPortal|New-IscsiTargetPortal|Register-IscsiSession|Remove-IscsiTargetPortal|Set-IscsiChapSecret|Unregister-IscsiSession|Update-IscsiTarget|Update-IscsiTargetPortal|\" +\n        // Module IscsiTarget\n        \"Add-IscsiVirtualDiskTargetMapping|Checkpoint-IscsiVirtualDisk|Convert-IscsiVirtualDisk|Dismount-IscsiVirtualDiskSnapshot|Export-IscsiTargetServerConfiguration|Export-IscsiVirtualDiskSnapshot|Get-IscsiServerTarget|Get-IscsiTargetServerSetting|Get-IscsiVirtualDisk|Get-IscsiVirtualDiskSnapshot|Import-IscsiTargetServerConfiguration|Import-IscsiVirtualDisk|Mount-IscsiVirtualDiskSnapshot|New-IscsiServerTarget|New-IscsiVirtualDisk|Remove-IscsiServerTarget|Remove-IscsiVirtualDisk|Remove-IscsiVirtualDiskSnapshot|Remove-IscsiVirtualDiskTargetMapping|Resize-IscsiVirtualDisk|Restore-IscsiVirtualDisk|Set-IscsiServerTarget|Set-IscsiTargetServerSetting|Set-IscsiVirtualDisk|Set-IscsiVirtualDiskSnapshot|Stop-IscsiVirtualDiskOperation|\" +\n        // Module ISE\n        \"Get-IseSnippet|Import-IseSnippet|New-IseSnippet|\" +\n        // Module Kds\n        \"Add-KdsRootKey|Clear-KdsCache|Get-KdsConfiguration|Get-KdsRootKey|Set-KdsConfiguration|Test-KdsRootKey|\" +\n        // Module LanguagePackManagement\n        \"Get-InstalledLanguage|Get-SystemPreferredUILanguage|Install-Language|Set-SystemPreferredUILanguage|Uninstall-Language|\" +\n        // Module LAPS\n        \"Find-LapsADExtendedRights|Get-LapsAADPassword|Get-LapsADPassword|Get-LapsDiagnostics|Invoke-LapsPolicyProcessing|Reset-LapsPassword|Set-LapsADAuditing|Set-LapsADComputerSelfPermission|Set-LapsADPasswordExpirationTime|Set-LapsADReadPasswordPermission|Set-LapsADResetPasswordPermission|Update-LapsADSchema|\" +\n        // Module Microsoft.DiagnosticDataViewer\n        \"Disable-DiagnosticDataViewing|Enable-DiagnosticDataViewing|Get-DiagnosticData|Get-DiagnosticDataTypes|Get-DiagnosticDataViewingSetting|Get-DiagnosticStoreCapacity|Set-DiagnosticStoreCapacity|\" +\n        // Module Microsoft.PowerShell.Archive\n        \"Compress-Archive|Expand-Archive|\" +\n        // Module Microsoft.PowerShell.Diagnostics\n        \"Export-Counter|Get-Counter|Get-WinEvent|Import-Counter|New-WinEvent|\" +\n        // Module Microsoft.PowerShell.Host\n        \"Start-Transcript|Stop-Transcript|\" +\n        // Module Microsoft.PowerShell.Management\n        \"Add-Computer|Add-Content|Checkpoint-Computer|Clear-Content|Clear-EventLog|Clear-Item|Clear-ItemProperty|Clear-RecycleBin|Complete-Transaction|Convert-Path|Copy-Item|Copy-ItemProperty|Debug-Process|Disable-ComputerRestore|Enable-ComputerRestore|Get-ChildItem|Get-Clipboard|Get-ComputerRestorePoint|Get-Content|Get-ControlPanelItem|Get-EventLog|Get-HotFix|Get-Item|Get-ItemProperty|Get-ItemPropertyValue|Get-Location|Get-Process|Get-PSDrive|Get-PSProvider|Get-Service|Get-Transaction|Get-WmiObject|Invoke-Item|Invoke-WmiMethod|Join-Path|Limit-EventLog|Move-Item|Move-ItemProperty|New-EventLog|New-Item|New-ItemProperty|New-PSDrive|New-Service|New-WebServiceProxy|Pop-Location|Push-Location|Register-WmiEvent|Remove-Computer|Remove-EventLog|Remove-Item|Remove-ItemProperty|Remove-PSDrive|Remove-WmiObject|Rename-Computer|Rename-Item|Rename-ItemProperty|Reset-ComputerMachinePassword|Resolve-Path|Restart-Computer|Restart-Service|Restore-Computer|Resume-Service|Set-Clipboard|Set-Content|Set-Item|Set-ItemProperty|Set-Location|Set-Service|Set-WmiInstance|Show-ControlPanelItem|Show-EventLog|Split-Path|Start-Process|Start-Service|Start-Transaction|Stop-Computer|Stop-Process|Stop-Service|Suspend-Service|Test-ComputerSecureChannel|Test-Connection|Test-Path|Undo-Transaction|Use-Transaction|Wait-Process|Write-EventLog|\" +\n        // Module Microsoft.PowerShell.ODataUtils\n        \"Export-ODataEndpointProxy|\" +\n        // Module Microsoft.PowerShell.Security\n        \"ConvertFrom-SecureString|ConvertTo-SecureString|Get-Acl|Get-AuthenticodeSignature|Get-CmsMessage|Get-Credential|Get-ExecutionPolicy|Get-PfxCertificate|Protect-CmsMessage|Set-Acl|Set-AuthenticodeSignature|Set-ExecutionPolicy|Unprotect-CmsMessage|\" +\n        // Module Microsoft.PowerShell.Utility\n        \"ConvertFrom-SddlString|Format-Hex|Get-FileHash|Import-PowerShellDataFile|New-Guid|New-TemporaryFile|Add-Member|Add-Type|Clear-Variable|Compare-Object|ConvertFrom-Csv|ConvertFrom-Json|ConvertFrom-String|ConvertFrom-StringData|Convert-String|ConvertTo-Csv|ConvertTo-Html|ConvertTo-Json|ConvertTo-Xml|Debug-Runspace|Disable-PSBreakpoint|Disable-RunspaceDebug|Enable-PSBreakpoint|Enable-RunspaceDebug|Export-Alias|Export-Clixml|Export-Csv|Export-FormatData|Export-PSSession|Format-Custom|Format-List|Format-Table|Format-Wide|Get-Alias|Get-Culture|Get-Date|Get-Event|Get-EventSubscriber|Get-FormatData|Get-Host|Get-Member|Get-PSBreakpoint|Get-PSCallStack|Get-Random|Get-Runspace|Get-RunspaceDebug|Get-TraceSource|Get-TypeData|Get-UICulture|Get-Unique|Get-Variable|Group-Object|Import-Alias|Import-Clixml|Import-Csv|Import-LocalizedData|Import-PSSession|Invoke-Expression|Invoke-RestMethod|Invoke-WebRequest|Measure-Command|Measure-Object|New-Alias|New-Event|New-Object|New-TimeSpan|New-Variable|Out-File|Out-GridView|Out-Printer|Out-String|Read-Host|Register-EngineEvent|Register-ObjectEvent|Remove-Event|Remove-PSBreakpoint|Remove-TypeData|Remove-Variable|Select-Object|Select-String|Select-Xml|Send-MailMessage|Set-Alias|Set-Date|Set-PSBreakpoint|Set-TraceSource|Set-Variable|Show-Command|Sort-Object|Start-Sleep|Tee-Object|Trace-Command|Unblock-File|Unregister-Event|Update-FormatData|Update-List|Update-TypeData|Wait-Debugger|Wait-Event|Write-Debug|Write-Error|Write-Host|Write-Information|Write-Output|Write-Progress|Write-Verbose|Write-Warning|\" +\n        // Module Microsoft.WSMan.Management\n        \"Connect-WSMan|Disable-WSManCredSSP|Disconnect-WSMan|Enable-WSManCredSSP|Get-WSManCredSSP|Get-WSManInstance|Invoke-WSManAction|New-WSManInstance|New-WSManSessionOption|Remove-WSManInstance|Set-WSManInstance|Set-WSManQuickConfig|Test-WSMan|\" +\n        // Module MMAgent\n        \"Debug-MMAppPrelaunch|Disable-MMAgent|Enable-MMAgent|Get-MMAgent|Set-MMAgent|\" +\n        // Module MPIO\n        \"Clear-MSDSMSupportedHW|Disable-MSDSMAutomaticClaim|Enable-MSDSMAutomaticClaim|Get-MPIOAvailableHW|Get-MPIOSetting|Get-MSDSMAutomaticClaimSettings|Get-MSDSMGlobalDefaultLoadBalancePolicy|Get-MSDSMSupportedHW|New-MSDSMSupportedHW|Remove-MSDSMSupportedHW|Set-MPIOSetting|Set-MSDSMGlobalDefaultLoadBalancePolicy|Update-MPIOClaimedHW|\" +\n        // Module MsDtc\n        \"Add-DtcClusterTMMapping|Complete-DtcDiagnosticTransaction|Get-Dtc|Get-DtcAdvancedHostSetting|Get-DtcAdvancedSetting|Get-DtcClusterDefault|Get-DtcClusterTMMapping|Get-DtcDefault|Get-DtcLog|Get-DtcNetworkSetting|Get-DtcTransaction|Get-DtcTransactionsStatistics|Get-DtcTransactionsTraceSession|Get-DtcTransactionsTraceSetting|Install-Dtc|Join-DtcDiagnosticResourceManager|New-DtcDiagnosticTransaction|Receive-DtcDiagnosticTransaction|Remove-DtcClusterTMMapping|Reset-DtcLog|Send-DtcDiagnosticTransaction|Set-DtcAdvancedHostSetting|Set-DtcAdvancedSetting|Set-DtcClusterDefault|Set-DtcClusterTMMapping|Set-DtcDefault|Set-DtcLog|Set-DtcNetworkSetting|Set-DtcTransaction|Set-DtcTransactionsTraceSession|Set-DtcTransactionsTraceSetting|Start-Dtc|Start-DtcDiagnosticResourceManager|Start-DtcTransactionsTraceSession|Stop-Dtc|Stop-DtcDiagnosticResourceManager|Stop-DtcTransactionsTraceSession|Test-Dtc|Undo-DtcDiagnosticTransaction|Uninstall-Dtc|Write-DtcTransactionsTraceSession|\" +\n        // Module MSMQ\n        \"Clear-MSMQOutgoingQueue|Clear-MSMQQueue|Enable-MSMQCertificate|Get-MSMQCertificate|Get-MSMQOutgoingQueue|Get-MsmqQueue|Get-MsmqQueueACL|Get-MsmqQueueManager|Get-MsmqQueueManagerACL|Move-MsmqMessage|New-MsmqMessage|New-MsmqQueue|Receive-MsmqQueue|Remove-MsmqCertificate|Remove-MsmqQueue|Resume-MsmqOutgoingQueue|Send-MsmqQueue|Set-MsmqQueue|Set-MsmqQueueACL|Set-MsmqQueueManager|Set-MsmqQueueManagerACL|Suspend-MsmqOutgoingQueue|\" +\n        // Module MultiPoint\n        \"Add-WmsSystem|Clear-WmsStation|Close-WmsApp|Close-WmsSession|Disable-WmsDiskProtection|Disable-WmsScheduledUpdate|Disable-WmsWebLimiting|Disconnect-WmsSession|Enable-WmsDiskProtection|Enable-WmsScheduledUpdate|Enable-WmsWebLimiting|Get-WmsAlert|Get-WmsApp|Get-WmsDiskProtection|Get-WmsScheduledUpdate|Get-WmsSession|Get-WmsStation|Get-WmsSystem|Get-WmsUser|Get-WmsVersion|Get-WmsWebLimiting|Hide-WmsIdentifier|Join-WmsStation|Lock-WmsSession|Lock-WmsUsbStorage|New-WmsUser|Open-WmsApp|Publish-WmsDesktop|Remove-WmsSystem|Remove-WmsUser|Restart-WmsSystem|Resume-WmsDiskProtection|Search-WmsSystem|Set-WmsScheduledUpdate|Set-WmsStation|Set-WmsSystem|Set-WmsUser|Set-WmsWebLimiting|Show-WmsDesktop|Show-WmsIdentifier|Split-WmsStation|Stop-WmsSystem|Suspend-WmsDiskProtection|Unlock-WmsSession|Unlock-WmsUsbStorage|Unpublish-WmsDesktop|Update-WmsStation|\" +\n        // Module MultipointVdi\n        \"Disable-WmsVirtualDesktopRole|Enable-WmsVirtualDesktopRole|Get-WmsVirtualDesktop|Import-WmsVirtualDesktop|New-WmsVirtualDesktop|New-WmsVirtualDesktopTemplate|Open-WmsVirtualDesktop|\" +\n        // Module NanoServerImageGenerator\n        \"Edit-NanoServerImage|Get-NanoServerPackage|New-NanoServerImage|\" +\n        // Module NetAdapter\n        \"Disable-NetAdapter|Disable-NetAdapterBinding|Disable-NetAdapterChecksumOffload|Disable-NetAdapterEncapsulatedPacketTaskOffload|Disable-NetAdapterIPsecOffload|Disable-NetAdapterLso|Disable-NetAdapterPowerManagement|Disable-NetAdapterQos|Disable-NetAdapterRdma|Disable-NetAdapterRsc|Disable-NetAdapterRss|Disable-NetAdapterSriov|Disable-NetAdapterUso|Disable-NetAdapterVmq|Enable-NetAdapter|Enable-NetAdapterBinding|Enable-NetAdapterChecksumOffload|Enable-NetAdapterEncapsulatedPacketTaskOffload|Enable-NetAdapterIPsecOffload|Enable-NetAdapterLso|Enable-NetAdapterPowerManagement|Enable-NetAdapterQos|Enable-NetAdapterRdma|Enable-NetAdapterRsc|Enable-NetAdapterRss|Enable-NetAdapterSriov|Enable-NetAdapterUso|Enable-NetAdapterVmq|Get-NetAdapter|Get-NetAdapterAdvancedProperty|Get-NetAdapterBinding|Get-NetAdapterChecksumOffload|Get-NetAdapterDataPathConfiguration|Get-NetAdapterEncapsulatedPacketTaskOffload|Get-NetAdapterHardwareInfo|Get-NetAdapterIPsecOffload|Get-NetAdapterLso|Get-NetAdapterPowerManagement|Get-NetAdapterQos|Get-NetAdapterRdma|Get-NetAdapterRsc|Get-NetAdapterRss|Get-NetAdapterSriov|Get-NetAdapterSriovVf|Get-NetAdapterStatistics|Get-NetAdapterUso|Get-NetAdapterVmq|Get-NetAdapterVmqQueue|Get-NetAdapterVPort|New-NetAdapterAdvancedProperty|Remove-NetAdapterAdvancedProperty|Rename-NetAdapter|Reset-NetAdapterAdvancedProperty|Restart-NetAdapter|Set-NetAdapter|Set-NetAdapterAdvancedProperty|Set-NetAdapterBinding|Set-NetAdapterChecksumOffload|Set-NetAdapterDataPathConfiguration|Set-NetAdapterEncapsulatedPacketTaskOffload|Set-NetAdapterIPsecOffload|Set-NetAdapterLso|Set-NetAdapterPowerManagement|Set-NetAdapterQos|Set-NetAdapterRdma|Set-NetAdapterRsc|Set-NetAdapterRss|Set-NetAdapterSriov|Set-NetAdapterUso|Set-NetAdapterVmq|\" +\n        // Module NetConnection\n        \"Get-NetConnectionProfile|Set-NetConnectionProfile|\" +\n        // Module NetEventPacketCapture\n        \"Add-NetEventNetworkAdapter|Add-NetEventPacketCaptureProvider|Add-NetEventProvider|Add-NetEventVFPProvider|Add-NetEventVmNetworkAdapter|Add-NetEventVmSwitch|Add-NetEventVmSwitchProvider|Add-NetEventWFPCaptureProvider|Get-NetEventNetworkAdapter|Get-NetEventPacketCaptureProvider|Get-NetEventProvider|Get-NetEventSession|Get-NetEventVFPProvider|Get-NetEventVmNetworkAdapter|Get-NetEventVmSwitch|Get-NetEventVmSwitchProvider|Get-NetEventWFPCaptureProvider|New-NetEventSession|Remove-NetEventNetworkAdapter|Remove-NetEventPacketCaptureProvider|Remove-NetEventProvider|Remove-NetEventSession|Remove-NetEventVFPProvider|Remove-NetEventVmNetworkAdapter|Remove-NetEventVmSwitch|Remove-NetEventVmSwitchProvider|Remove-NetEventWFPCaptureProvider|Set-NetEventPacketCaptureProvider|Set-NetEventProvider|Set-NetEventSession|Set-NetEventVFPProvider|Set-NetEventVmSwitchProvider|Set-NetEventWFPCaptureProvider|Start-NetEventSession|Stop-NetEventSession|\" +\n        // Module NetLbfo\n        \"Add-NetLbfoTeamMember|Add-NetLbfoTeamNic|Get-NetLbfoTeam|Get-NetLbfoTeamMember|Get-NetLbfoTeamNic|New-NetLbfoTeam|Remove-NetLbfoTeam|Remove-NetLbfoTeamMember|Remove-NetLbfoTeamNic|Rename-NetLbfoTeam|Set-NetLbfoTeam|Set-NetLbfoTeamMember|Set-NetLbfoTeamNic|\" +\n        // Module NetLldpAgent\n        \"Disable-NetLldpAgent|Enable-NetLldpAgent|Get-NetLldpAgent|\" +\n        // Module NetNat\n        \"Add-NetNatExternalAddress|Add-NetNatStaticMapping|Get-NetNat|Get-NetNatExternalAddress|Get-NetNatGlobal|Get-NetNatSession|Get-NetNatStaticMapping|New-NetNat|Remove-NetNat|Remove-NetNatExternalAddress|Remove-NetNatStaticMapping|Set-NetNat|Set-NetNatGlobal|\" +\n        // Module NetQos\n        \"Get-NetQosPolicy|New-NetQosPolicy|Remove-NetQosPolicy|Set-NetQosPolicy|\" +\n        // Module NetSecurity\n        \"Copy-NetFirewallRule|Copy-NetIPsecMainModeCryptoSet|Copy-NetIPsecMainModeRule|Copy-NetIPsecPhase1AuthSet|Copy-NetIPsecPhase2AuthSet|Copy-NetIPsecQuickModeCryptoSet|Copy-NetIPsecRule|Disable-NetFirewallRule|Disable-NetIPsecMainModeRule|Disable-NetIPsecRule|Enable-NetFirewallRule|Enable-NetIPsecMainModeRule|Enable-NetIPsecRule|Find-NetIPsecRule|Get-DAPolicyChange|Get-NetFirewallAddressFilter|Get-NetFirewallApplicationFilter|Get-NetFirewallDynamicKeywordAddress|Get-NetFirewallInterfaceFilter|Get-NetFirewallInterfaceTypeFilter|Get-NetFirewallPortFilter|Get-NetFirewallProfile|Get-NetFirewallRule|Get-NetFirewallSecurityFilter|Get-NetFirewallServiceFilter|Get-NetFirewallSetting|Get-NetIPsecDospSetting|Get-NetIPsecMainModeCryptoSet|Get-NetIPsecMainModeRule|Get-NetIPsecMainModeSA|Get-NetIPsecPhase1AuthSet|Get-NetIPsecPhase2AuthSet|Get-NetIPsecQuickModeCryptoSet|Get-NetIPsecQuickModeSA|Get-NetIPsecRule|New-NetFirewallDynamicKeywordAddress|New-NetFirewallRule|New-NetIPsecAuthProposal|New-NetIPsecDospSetting|New-NetIPsecMainModeCryptoProposal|New-NetIPsecMainModeCryptoSet|New-NetIPsecMainModeRule|New-NetIPsecPhase1AuthSet|New-NetIPsecPhase2AuthSet|New-NetIPsecQuickModeCryptoProposal|New-NetIPsecQuickModeCryptoSet|New-NetIPsecRule|Open-NetGPO|Remove-NetFirewallDynamicKeywordAddress|Remove-NetFirewallRule|Remove-NetIPsecDospSetting|Remove-NetIPsecMainModeCryptoSet|Remove-NetIPsecMainModeRule|Remove-NetIPsecMainModeSA|Remove-NetIPsecPhase1AuthSet|Remove-NetIPsecPhase2AuthSet|Remove-NetIPsecQuickModeCryptoSet|Remove-NetIPsecQuickModeSA|Remove-NetIPsecRule|Rename-NetFirewallRule|Rename-NetIPsecMainModeCryptoSet|Rename-NetIPsecMainModeRule|Rename-NetIPsecPhase1AuthSet|Rename-NetIPsecPhase2AuthSet|Rename-NetIPsecQuickModeCryptoSet|Rename-NetIPsecRule|Save-NetGPO|Set-NetFirewallAddressFilter|Set-NetFirewallApplicationFilter|Set-NetFirewallInterfaceFilter|Set-NetFirewallInterfaceTypeFilter|Set-NetFirewallPortFilter|Set-NetFirewallProfile|Set-NetFirewallRule|Set-NetFirewallSecurityFilter|Set-NetFirewallServiceFilter|Set-NetFirewallSetting|Set-NetIPsecDospSetting|Set-NetIPsecMainModeCryptoSet|Set-NetIPsecMainModeRule|Set-NetIPsecPhase1AuthSet|Set-NetIPsecPhase2AuthSet|Set-NetIPsecQuickModeCryptoSet|Set-NetIPsecRule|Show-NetFirewallRule|Show-NetIPsecRule|Sync-NetIPsecRule|Update-NetFirewallDynamicKeywordAddress|Update-NetIPsecRule|\" +\n        // Module NetSwitchTeam\n        \"Add-NetSwitchTeamMember|Get-NetSwitchTeam|Get-NetSwitchTeamMember|New-NetSwitchTeam|Remove-NetSwitchTeam|Remove-NetSwitchTeamMember|Rename-NetSwitchTeam|\" +\n        // Module NetTCPIP\n        \"Find-NetRoute|Get-NetCompartment|Get-NetIPAddress|Get-NetIPConfiguration|Get-NetIPInterface|Get-NetIPv4Protocol|Get-NetIPv6Protocol|Get-NetNeighbor|Get-NetOffloadGlobalSetting|Get-NetPrefixPolicy|Get-NetRoute|Get-NetTCPConnection|Get-NetTCPSetting|Get-NetTransportFilter|Get-NetUDPEndpoint|Get-NetUDPSetting|New-NetIPAddress|New-NetNeighbor|New-NetRoute|New-NetTransportFilter|Remove-NetIPAddress|Remove-NetNeighbor|Remove-NetRoute|Remove-NetTransportFilter|Set-NetIPAddress|Set-NetIPInterface|Set-NetIPv4Protocol|Set-NetIPv6Protocol|Set-NetNeighbor|Set-NetOffloadGlobalSetting|Set-NetRoute|Set-NetTCPSetting|Set-NetUDPSetting|Test-NetConnection|\" +\n        // Module NetWNV\n        \"Get-NetVirtualizationCustomerRoute|Get-NetVirtualizationGlobal|Get-NetVirtualizationLookupRecord|Get-NetVirtualizationProviderAddress|Get-NetVirtualizationProviderRoute|New-NetVirtualizationCustomerRoute|New-NetVirtualizationLookupRecord|New-NetVirtualizationProviderAddress|New-NetVirtualizationProviderRoute|Remove-NetVirtualizationCustomerRoute|Remove-NetVirtualizationLookupRecord|Remove-NetVirtualizationProviderAddress|Remove-NetVirtualizationProviderRoute|Select-NetVirtualizationNextHop|Set-NetVirtualizationCustomerRoute|Set-NetVirtualizationGlobal|Set-NetVirtualizationLookupRecord|Set-NetVirtualizationProviderAddress|Set-NetVirtualizationProviderRoute|\" +\n        // Module NetworkConnectivityStatus\n        \"Get-DAConnectionStatus|Get-NCSIPolicyConfiguration|Reset-NCSIPolicyConfiguration|Set-NCSIPolicyConfiguration|\" +\n        // Module NetworkController\n        \"Add-NetworkControllerNode|Clear-NetworkControllerNodeContent|Disable-NetworkControllerNode|Enable-NetworkControllerNode|Get-NetworkController|Get-NetworkControllerAccessControlList|Get-NetworkControllerAccessControlListRule|Get-NetworkControllerAuditingSettingsConfiguration|Get-NetworkControllerBackup|Get-NetworkControllerCluster|Get-NetworkControllerConnectivityCheck|Get-NetworkControllerConnectivityCheckResult|Get-NetworkControllerCredential|Get-NetworkControllerDiagnostic|Get-NetworkControllerDiscovery|Get-NetworkControllerFabricRoute|Get-NetworkControllerGateway|Get-NetworkControllerGatewayPool|Get-NetworkControllerIDnsServerConfiguration|Get-NetworkControllerInternalResourceInstances|Get-NetworkControllerIpPool|Get-NetworkControllerIpReservation|Get-NetworkControllerLoadBalancer|Get-NetworkControllerLoadBalancerBackendAddressPool|Get-NetworkControllerLoadBalancerConfiguration|Get-NetworkControllerLoadBalancerFrontendIpConfiguration|Get-NetworkControllerLoadBalancerInboundNatRule|Get-NetworkControllerLoadBalancerMux|Get-NetworkControllerLoadBalancerOutboundNatRule|Get-NetworkControllerLoadBalancerProbe|Get-NetworkControllerLoadBalancingRule|Get-NetworkControllerLogicalNetwork|Get-NetworkControllerLogicalSubnet|Get-NetworkControllerMacPool|Get-NetworkControllerNetworkInterface|Get-NetworkControllerNetworkInterfaceIpConfiguration|Get-NetworkControllerNode|Get-NetworkControllerPublicIpAddress|Get-NetworkControllerRestore|Get-NetworkControllerRoute|Get-NetworkControllerRouteTable|Get-NetworkControllerServer|Get-NetworkControllerServerInterface|Get-NetworkControllerServiceInsertion|Get-NetworkControllerState|Get-NetworkControllerStatistics|Get-NetworkControllerSubnetEgressReset|Get-NetworkControllerVirtualGateway|Get-NetworkControllerVirtualGatewayBgpPeer|Get-NetworkControllerVirtualGatewayBgpRouter|Get-NetworkControllerVirtualGatewayNetworkConnection|Get-NetworkControllerVirtualGatewayPolicyMap|Get-NetworkControllerVirtualNetwork|Get-NetworkControllerVirtualNetworkConfiguration|Get-NetworkControllerVirtualNetworkPeering|Get-NetworkControllerVirtualServer|Get-NetworkControllerVirtualSubnet|Get-NetworkControllerVirtualSwitchConfiguration|Install-NetworkController|Install-NetworkControllerCluster|Invoke-NetworkControllerConnectivityCheck|Invoke-NetworkControllerState|Invoke-NetworkControllerSubnetEgressReset|New-NetworkControllerAccessControlList|New-NetworkControllerAccessControlListRule|New-NetworkControllerBackup|New-NetworkControllerCredential|New-NetworkControllerFabricRoute|New-NetworkControllerGateway|New-NetworkControllerGatewayPool|New-NetworkControllerIDnsServerConfiguration|New-NetworkControllerIpPool|New-NetworkControllerIpReservation|New-NetworkControllerLoadBalancer|New-NetworkControllerLoadBalancerBackendAddressPool|New-NetworkControllerLoadBalancerConfiguration|New-NetworkControllerLoadBalancerFrontendIpConfiguration|New-NetworkControllerLoadBalancerInboundNatRule|New-NetworkControllerLoadBalancerMux|New-NetworkControllerLoadBalancerOutboundNatRule|New-NetworkControllerLoadBalancerProbe|New-NetworkControllerLoadBalancingRule|New-NetworkControllerLogicalNetwork|New-NetworkControllerLogicalSubnet|New-NetworkControllerMacPool|New-NetworkControllerNetworkInterface|New-NetworkControllerNetworkInterfaceIpConfiguration|New-NetworkControllerNodeObject|New-NetworkControllerPublicIpAddress|New-NetworkControllerRestore|New-NetworkControllerRoute|New-NetworkControllerRouteTable|New-NetworkControllerServer|New-NetworkControllerServerInterface|New-NetworkControllerServiceInsertion|New-NetworkControllerVirtualGateway|New-NetworkControllerVirtualGatewayBgpPeer|New-NetworkControllerVirtualGatewayBgpRouter|New-NetworkControllerVirtualGatewayNetworkConnection|New-NetworkControllerVirtualGatewayPolicyMap|New-NetworkControllerVirtualNetwork|New-NetworkControllerVirtualNetworkPeering|New-NetworkControllerVirtualServer|New-NetworkControllerVirtualSubnet|Remove-NetworkControllerAccessControlList|Remove-NetworkControllerAccessControlListRule|Remove-NetworkControllerBackup|Remove-NetworkControllerCredential|Remove-NetworkControllerFabricRoute|Remove-NetworkControllerGateway|Remove-NetworkControllerGatewayPool|Remove-NetworkControllerIpPool|Remove-NetworkControllerIpReservation|Remove-NetworkControllerLoadBalancer|Remove-NetworkControllerLoadBalancerBackendAddressPool|Remove-NetworkControllerLoadBalancerConfiguration|Remove-NetworkControllerLoadBalancerFrontendIpConfiguration|Remove-NetworkControllerLoadBalancerInboundNatRule|Remove-NetworkControllerLoadBalancerMux|Remove-NetworkControllerLoadBalancerOutboundNatRule|Remove-NetworkControllerLoadBalancerProbe|Remove-NetworkControllerLoadBalancingRule|Remove-NetworkControllerLogicalNetwork|Remove-NetworkControllerLogicalSubnet|Remove-NetworkControllerMacPool|Remove-NetworkControllerNetworkInterface|Remove-NetworkControllerNetworkInterfaceIpConfiguration|Remove-NetworkControllerNode|Remove-NetworkControllerPublicIpAddress|Remove-NetworkControllerRestore|Remove-NetworkControllerRoute|Remove-NetworkControllerRouteTable|Remove-NetworkControllerServer|Remove-NetworkControllerServerInterface|Remove-NetworkControllerServiceInsertion|Remove-NetworkControllerVirtualGateway|Remove-NetworkControllerVirtualGatewayBgpPeer|Remove-NetworkControllerVirtualGatewayBgpRouter|Remove-NetworkControllerVirtualGatewayNetworkConnection|Remove-NetworkControllerVirtualGatewayPolicyMap|Remove-NetworkControllerVirtualNetwork|Remove-NetworkControllerVirtualNetworkPeering|Remove-NetworkControllerVirtualServer|Remove-NetworkControllerVirtualSubnet|Repair-NetworkControllerCluster|Set-NetworkController|Set-NetworkControllerAuditingSettingsConfiguration|Set-NetworkControllerCluster|Set-NetworkControllerDiagnostic|Set-NetworkControllerNode|Set-NetworkControllerVirtualNetworkConfiguration|Set-NetworkControllerVirtualSwitchConfiguration|Uninstall-NetworkController|Uninstall-NetworkControllerCluster|Update-NetworkController|\" +\n        // Module NetworkControllerDiagnostics\n        \"Debug-NetworkController|Debug-NetworkControllerConfigurationState|Debug-ServiceFabricNodeStatus|Get-NetworkControllerDeploymentInfo|Get-NetworkControllerManagedDevices|Get-NetworkControllerReplica|\" +\n        // Module NetworkLoadBalancingClusters\n        \"Add-NlbClusterNode|Add-NlbClusterNodeDip|Add-NlbClusterPortRule|Add-NlbClusterVip|Disable-NlbClusterPortRule|Enable-NlbClusterPortRule|Get-NlbCluster|Get-NlbClusterDriverInfo|Get-NlbClusterNode|Get-NlbClusterNodeDip|Get-NlbClusterNodeNetworkInterface|Get-NlbClusterPortRule|Get-NlbClusterVip|New-NlbCluster|New-NlbClusterIpv6Address|Remove-NlbCluster|Remove-NlbClusterNode|Remove-NlbClusterNodeDip|Remove-NlbClusterPortRule|Remove-NlbClusterVip|Resume-NlbCluster|Resume-NlbClusterNode|Set-NlbCluster|Set-NlbClusterNode|Set-NlbClusterNodeDip|Set-NlbClusterPortRule|Set-NlbClusterPortRuleNodeHandlingPriority|Set-NlbClusterPortRuleNodeWeight|Set-NlbClusterVip|Start-NlbCluster|Start-NlbClusterNode|Stop-NlbCluster|Stop-NlbClusterNode|Suspend-NlbCluster|Suspend-NlbClusterNode|\" +\n        // Module NetworkSwitchManager\n        \"Disable-NetworkSwitchEthernetPort|Disable-NetworkSwitchFeature|Disable-NetworkSwitchVlan|Enable-NetworkSwitchEthernetPort|Enable-NetworkSwitchFeature|Enable-NetworkSwitchVlan|Get-NetworkSwitchEthernetPort|Get-NetworkSwitchFeature|Get-NetworkSwitchGlobalData|Get-NetworkSwitchVlan|New-NetworkSwitchVlan|Remove-NetworkSwitchEthernetPortIPAddress|Remove-NetworkSwitchVlan|Restore-NetworkSwitchConfiguration|Save-NetworkSwitchConfiguration|Set-NetworkSwitchEthernetPortIPAddress|Set-NetworkSwitchPortMode|Set-NetworkSwitchPortProperty|Set-NetworkSwitchVlanProperty|\" +\n        // Module NetworkTransition\n        \"Add-NetIPHttpsCertBinding|Disable-NetDnsTransitionConfiguration|Disable-NetIPHttpsProfile|Disable-NetNatTransitionConfiguration|Enable-NetDnsTransitionConfiguration|Enable-NetIPHttpsProfile|Enable-NetNatTransitionConfiguration|Get-Net6to4Configuration|Get-NetDnsTransitionConfiguration|Get-NetDnsTransitionMonitoring|Get-NetIPHttpsConfiguration|Get-NetIPHttpsState|Get-NetIsatapConfiguration|Get-NetNatTransitionConfiguration|Get-NetNatTransitionMonitoring|Get-NetTeredoConfiguration|Get-NetTeredoState|New-NetIPHttpsConfiguration|New-NetNatTransitionConfiguration|Remove-NetIPHttpsCertBinding|Remove-NetIPHttpsConfiguration|Remove-NetNatTransitionConfiguration|Rename-NetIPHttpsConfiguration|Reset-Net6to4Configuration|Reset-NetDnsTransitionConfiguration|Reset-NetIPHttpsConfiguration|Reset-NetIsatapConfiguration|Reset-NetTeredoConfiguration|Set-Net6to4Configuration|Set-NetDnsTransitionConfiguration|Set-NetIPHttpsConfiguration|Set-NetIsatapConfiguration|Set-NetNatTransitionConfiguration|Set-NetTeredoConfiguration|\" +\n        // Module NFS\n        \"Disconnect-NfsSession|Get-NfsClientConfiguration|Get-NfsClientgroup|Get-NfsClientLock|Get-NfsMappedIdentity|Get-NfsMappingStore|Get-NfsMountedClient|Get-NfsNetgroup|Get-NfsNetgroupStore|Get-NfsOpenFile|Get-NfsServerConfiguration|Get-NfsSession|Get-NfsShare|Get-NfsSharePermission|Get-NfsStatistics|Grant-NfsSharePermission|Install-NfsMappingStore|New-NfsClientgroup|New-NfsMappedIdentity|New-NfsNetgroup|New-NfsShare|Remove-NfsClientgroup|Remove-NfsMappedIdentity|Remove-NfsNetgroup|Remove-NfsShare|Rename-NfsClientgroup|Reset-NfsStatistics|Resolve-NfsMappedIdentity|Revoke-NfsClientLock|Revoke-NfsMountedClient|Revoke-NfsOpenFile|Revoke-NfsSharePermission|Set-NfsClientConfiguration|Set-NfsClientgroup|Set-NfsMappedIdentity|Set-NfsMappingStore|Set-NfsNetgroup|Set-NfsNetgroupStore|Set-NfsServerConfiguration|Set-NfsShare|Test-NfsMappedIdentity|Test-NfsMappingStore|\" +\n        // Module NPS\n        \"Export-NpsConfiguration|Get-NpsRadiusClient|Get-NpsSharedSecretTemplate|Import-NpsConfiguration|New-NpsRadiusClient|Remove-NpsRadiusClient|Set-NpsRadiusClient|\" +\n        // Module PackageManagement\n        \"Find-Package|Find-PackageProvider|Get-Package|Get-PackageProvider|Get-PackageSource|Import-PackageProvider|Install-Package|Install-PackageProvider|Register-PackageSource|Save-Package|Set-PackageSource|Uninstall-Package|Unregister-PackageSource|\" +\n        // Module PcsvDevice\n        \"Clear-PcsvDeviceLog|Get-PcsvDevice|Get-PcsvDeviceLog|Restart-PcsvDevice|Set-PcsvDeviceBootConfiguration|Set-PcsvDeviceNetworkConfiguration|Set-PcsvDeviceUserPassword|Start-PcsvDevice|Stop-PcsvDevice|\" +\n        // Module PersistentMemory\n        \"Get-PmemDedicatedMemory|Get-PmemDisk|Get-PmemPhysicalDevice|Get-PmemUnusedRegion|Initialize-PmemPhysicalDevice|New-PmemDedicatedMemory|New-PmemDisk|Remove-PmemDedicatedMemory|Remove-PmemDisk|\" +\n        // Module Pester\n        \"AfterAll|AfterEach|Assert-MockCalled|Assert-VerifiableMocks|BeforeAll|BeforeEach|Context|Describe|Get-MockDynamicParameters|Get-TestDriveItem|In|InModuleScope|Invoke-Mock|Invoke-Pester|It|Mock|New-Fixture|Set-DynamicParameterVariables|Setup|Should|\" +\n        // Module PKI\n        \"Add-CertificateEnrollmentPolicyServer|Export-Certificate|Export-PfxCertificate|Get-Certificate|Get-CertificateAutoEnrollmentPolicy|Get-CertificateEnrollmentPolicyServer|Get-CertificateNotificationTask|Get-PfxData|Import-Certificate|Import-PfxCertificate|New-CertificateNotificationTask|New-SelfSignedCertificate|Remove-CertificateEnrollmentPolicyServer|Remove-CertificateNotificationTask|Set-CertificateAutoEnrollmentPolicy|Switch-Certificate|Test-Certificate|\" +\n        // Module PlatformIdentifier\n        \"Get-PlatformIdentifier|\" +\n        // Module PnpDevice\n        \"Disable-PnpDevice|Enable-PnpDevice|Get-PnpDevice|Get-PnpDeviceProperty|\" +\n        // Module PowerShellGet\n        \"Find-DscResource|Find-Module|Find-Script|Get-InstalledModule|Get-InstalledScript|Get-PSRepository|Install-Module|Install-Script|New-ScriptFileInfo|Publish-Module|Publish-Script|Register-PSRepository|Save-Module|Save-Script|Set-PSRepository|Test-ScriptFileInfo|Uninstall-Module|Uninstall-Script|Unregister-PSRepository|Update-Module|Update-ModuleManifest|Update-Script|Update-ScriptFileInfo|\" +\n        // Module PrintManagement\n        \"Add-Printer|Add-PrinterDriver|Add-PrinterPort|Get-PrintConfiguration|Get-Printer|Get-PrinterDriver|Get-PrinterPort|Get-PrinterProperty|Get-PrintJob|Read-PrinterNfcTag|Remove-Printer|Remove-PrinterDriver|Remove-PrinterPort|Remove-PrintJob|Rename-Printer|Restart-PrintJob|Resume-PrintJob|Set-PrintConfiguration|Set-Printer|Set-PrinterProperty|Suspend-PrintJob|Write-PrinterNfcTag|\" +\n        // Module ProcessMitigations\n        \"ConvertTo-ProcessMitigationPolicy|Get-ProcessMitigation|Set-ProcessMitigation|\" +\n        // Module Provisioning\n        \"Export-ProvisioningPackage|Export-Trace|Get-ProvisioningPackage|Get-TrustedProvisioningCertificate|Install-ProvisioningPackage|Install-TrustedProvisioningCertificate|Uninstall-ProvisioningPackage|Uninstall-TrustedProvisioningCertificate|\" +\n        // Module PSDesiredStateConfiguration\n        \"Configuration|Disable-DscDebug|Enable-DscDebug|Get-DscConfiguration|Get-DscConfigurationStatus|Get-DscLocalConfigurationManager|Get-DscResource|New-DscChecksum|Remove-DscConfigurationDocument|Restore-DscConfiguration|Stop-DscConfiguration|Invoke-DscResource|Publish-DscConfiguration|Set-DscLocalConfigurationManager|Start-DscConfiguration|Test-DscConfiguration|Update-DscConfiguration|\" +\n        // Module PSDiagnostics\n        \"Disable-PSTrace|Disable-PSWSManCombinedTrace|Disable-WSManTrace|Enable-PSTrace|Enable-PSWSManCombinedTrace|Enable-WSManTrace|Get-LogProperties|Set-LogProperties|Start-Trace|Stop-Trace|\" +\n        // Module PSReadline\n        \"PSConsoleHostReadline|Get-PSReadlineKeyHandler|Get-PSReadlineOption|Remove-PSReadlineKeyHandler|Set-PSReadlineKeyHandler|Set-PSReadlineOption|\" +\n        // Module PSScheduledJob\n        \"Add-JobTrigger|Disable-JobTrigger|Disable-ScheduledJob|Enable-JobTrigger|Enable-ScheduledJob|Get-JobTrigger|Get-ScheduledJob|Get-ScheduledJobOption|New-JobTrigger|New-ScheduledJobOption|Register-ScheduledJob|Remove-JobTrigger|Set-JobTrigger|Set-ScheduledJob|Set-ScheduledJobOption|Unregister-ScheduledJob|\" +\n        // Module PSWorkflow\n        \"New-PSWorkflowSession|New-PSWorkflowExecutionOption|\" +\n        // Module PSWorkflowUtility\n        \"Invoke-AsWorkflow|\" +\n        // Module RDMgmt\n        \"Add-RDServer|Add-RDSessionHost|Add-RDVirtualDesktopToCollection|Disable-RDVirtualDesktopADMachineAccountReuse|Disconnect-RDUser|Enable-RDVirtualDesktopADMachineAccountReuse|Export-RDPersonalSessionDesktopAssignment|Export-RDPersonalVirtualDesktopAssignment|Get-RDAvailableApp|Get-RDCertificate|Get-RDConnectionBrokerHighAvailability|Get-RDDeploymentGatewayConfiguration|Get-RDFileTypeAssociation|Get-RDLicenseConfiguration|Get-RDPersonalSessionDesktopAssignment|Get-RDPersonalVirtualDesktopAssignment|Get-RDPersonalVirtualDesktopPatchSchedule|Get-RDRemoteApp|Get-RDRemoteDesktop|Get-RDServer|Get-RDSessionCollection|Get-RDSessionCollectionConfiguration|Get-RDSessionHost|Get-RDUserSession|Get-RDVirtualDesktop|Get-RDVirtualDesktopCollection|Get-RDVirtualDesktopCollectionConfiguration|Get-RDVirtualDesktopCollectionJobStatus|Get-RDVirtualDesktopConcurrency|Get-RDVirtualDesktopIdleCount|Get-RDVirtualDesktopTemplateExportPath|Get-RDWorkspace|Grant-RDOUAccess|Import-RDPersonalSessionDesktopAssignment|Import-RDPersonalVirtualDesktopAssignment|Invoke-RDUserLogoff|Move-RDVirtualDesktop|New-RDCertificate|New-RDPersonalVirtualDesktopPatchSchedule|New-RDRemoteApp|New-RDSessionCollection|New-RDSessionDeployment|New-RDVirtualDesktopCollection|New-RDVirtualDesktopDeployment|Remove-RDDatabaseConnectionString|Remove-RDPersonalSessionDesktopAssignment|Remove-RDPersonalVirtualDesktopAssignment|Remove-RDPersonalVirtualDesktopPatchSchedule|Remove-RDRemoteApp|Remove-RDServer|Remove-RDSessionCollection|Remove-RDSessionHost|Remove-RDVirtualDesktopCollection|Remove-RDVirtualDesktopFromCollection|Send-RDUserMessage|Set-RDActiveManagementServer|Set-RDCertificate|Set-RDClientAccessName|Set-RDConnectionBrokerHighAvailability|Set-RDDatabaseConnectionString|Set-RDDeploymentGatewayConfiguration|Set-RDFileTypeAssociation|Set-RDLicenseConfiguration|Set-RDPersonalSessionDesktopAssignment|Set-RDPersonalVirtualDesktopAssignment|Set-RDPersonalVirtualDesktopPatchSchedule|Set-RDRemoteApp|Set-RDRemoteDesktop|Set-RDSessionCollectionConfiguration|Set-RDSessionHost|Set-RDVirtualDesktopCollectionConfiguration|Set-RDVirtualDesktopConcurrency|Set-RDVirtualDesktopIdleCount|Set-RDVirtualDesktopTemplateExportPath|Set-RDWorkspace|Stop-RDVirtualDesktopCollectionJob|Test-RDOUAccess|Test-RDVirtualDesktopADMachineAccountReuse|Update-RDVirtualDesktopCollection|\" +\n        // Module RemoteAccess\n        \"Add-BgpCustomRoute|Add-BgpPeer|Add-BgpRouteAggregate|Add-BgpRouter|Add-BgpRoutingPolicy|Add-BgpRoutingPolicyForPeer|Add-DAAppServer|Add-DAClient|Add-DAClientDnsConfiguration|Add-DAEntryPoint|Add-DAMgmtServer|Add-RemoteAccessIpFilter|Add-RemoteAccessLoadBalancerNode|Add-RemoteAccessRadius|Add-VpnIPAddressRange|Add-VpnS2SInterface|Add-VpnSstpProxyRule|Clear-BgpRouteFlapDampening|Clear-RemoteAccessInboxAccountingStore|Clear-VpnS2SInterfaceStatistics|Connect-VpnS2SInterface|Disable-BgpRouteFlapDampening|Disable-DAMultiSite|Disable-DAOtpAuthentication|Disable-RemoteAccessRoutingDomain|Disconnect-VpnS2SInterface|Disconnect-VpnUser|Enable-BgpRouteFlapDampening|Enable-DAMultiSite|Enable-DAOtpAuthentication|Enable-RemoteAccessRoutingDomain|Get-BgpCustomRoute|Get-BgpPeer|Get-BgpRouteAggregate|Get-BgpRouteFlapDampening|Get-BgpRouteInformation|Get-BgpRouter|Get-BgpRoutingPolicy|Get-BgpStatistics|Get-DAAppServer|Get-DAClient|Get-DAClientDnsConfiguration|Get-DAEntryPoint|Get-DAEntryPointDC|Get-DAMgmtServer|Get-DAMultiSite|Get-DANetworkLocationServer|Get-DAOtpAuthentication|Get-DAServer|Get-RemoteAccess|Get-RemoteAccessAccounting|Get-RemoteAccessConfiguration|Get-RemoteAccessConnectionStatistics|Get-RemoteAccessConnectionStatisticsSummary|Get-RemoteAccessHealth|Get-RemoteAccessIpFilter|Get-RemoteAccessLoadBalancer|Get-RemoteAccessRadius|Get-RemoteAccessRoutingDomain|Get-RemoteAccessUserActivity|Get-RoutingProtocolPreference|Get-VpnAuthProtocol|Get-VpnS2SInterface|Get-VpnS2SInterfaceStatistics|Get-VpnServerConfiguration|Get-VpnSstpProxyRule|Install-RemoteAccess|New-VpnSstpProxyRule|New-VpnTrafficSelector|Remove-BgpCustomRoute|Remove-BgpPeer|Remove-BgpRouteAggregate|Remove-BgpRouter|Remove-BgpRoutingPolicy|Remove-BgpRoutingPolicyForPeer|Remove-DAAppServer|Remove-DAClient|Remove-DAClientDnsConfiguration|Remove-DAEntryPoint|Remove-DAMgmtServer|Remove-RemoteAccessIpFilter|Remove-RemoteAccessLoadBalancerNode|Remove-RemoteAccessRadius|Remove-VpnIPAddressRange|Remove-VpnS2SInterface|Remove-VpnSstpProxyRule|Set-BgpPeer|Set-BgpRouteAggregate|Set-BgpRouteFlapDampening|Set-BgpRouter|Set-BgpRoutingPolicy|Set-BgpRoutingPolicyForPeer|Set-DAAppServerConnection|Set-DAClient|Set-DAClientDnsConfiguration|Set-DAEntryPoint|Set-DAEntryPointDC|Set-DAMultiSite|Set-DANetworkLocationServer|Set-DAOtpAuthentication|Set-DAServer|Set-RemoteAccess|Set-RemoteAccessAccounting|Set-RemoteAccessConfiguration|Set-RemoteAccessInboxAccountingStore|Set-RemoteAccessIpFilter|Set-RemoteAccessLoadBalancer|Set-RemoteAccessRadius|Set-RemoteAccessRoutingDomain|Set-RoutingProtocolPreference|Set-VpnAuthProtocol|Set-VpnAuthType|Set-VpnIPAddressAssignment|Set-VpnS2SInterface|Set-VpnServerConfiguration|Set-VpnSstpProxyRule|Start-BgpPeer|Stop-BgpPeer|Uninstall-RemoteAccess|Update-DAMgmtServer|\" +\n        // Module RemoteDesktopServices\n        \"Convert-License|\" +\n        // Module ScheduledTasks\n        \"Disable-ScheduledTask|Enable-ScheduledTask|Export-ScheduledTask|Get-ClusteredScheduledTask|Get-ScheduledTask|Get-ScheduledTaskInfo|New-ScheduledTask|New-ScheduledTaskAction|New-ScheduledTaskPrincipal|New-ScheduledTaskSettingsSet|New-ScheduledTaskTrigger|Register-ClusteredScheduledTask|Register-ScheduledTask|Set-ClusteredScheduledTask|Set-ScheduledTask|Start-ScheduledTask|Stop-ScheduledTask|Unregister-ClusteredScheduledTask|Unregister-ScheduledTask|\" +\n        // Module SecureBoot\n        \"Confirm-SecureBootUEFI|Format-SecureBootUEFI|Get-SecureBootPolicy|Get-SecureBootUEFI|Set-SecureBootUEFI|\" +\n        // Module ServerCore\n        \"Get-DisplayResolution|Set-DisplayResolution|\" +\n        // Module ServerManager\n        \"Disable-ServerManagerStandardUserRemoting|Enable-ServerManagerStandardUserRemoting|Get-WindowsFeature|Install-WindowsFeature|Uninstall-WindowsFeature|\" +\n        // Module ServerManagerTasks\n        \"Get-SMCounterSample|Get-SMPerformanceCollector|Get-SMServerBpaResult|Get-SMServerClusterName|Get-SMServerEvent|Get-SMServerFeature|Get-SMServerInventory|Get-SMServerService|Remove-SMServerPerformanceLog|Start-SMPerformanceCollector|Stop-SMPerformanceCollector|\" +\n        // Module ShieldedVmCmdlets\n        \"Get-KeyProtectorFromShieldingDataFile|Get-ShieldedVMProvisioningStatus|Initialize-ShieldedVM|New-ShieldedVMSpecializationDataFile|Test-ShieldingDataApplicability|\" +\n        // Module ShieldedVMDataFile\n        \"Import-ShieldingDataFile|New-ShieldingDataFile|New-VolumeIDQualifier|Save-ShieldedVMRecoveryKey|Save-VolumeSignatureCatalog|Unprotect-ShieldedVMRecoveryKey|\" +\n        // Module ShieldedVMTemplate\n        \"Initialize-VMShieldingHelperVHD|Protect-TemplateDisk|\" +\n        // Module SmbShare\n        \"Block-SmbShareAccess|Close-SmbOpenFile|Close-SmbSession|Disable-SmbDelegation|Enable-SmbDelegation|Get-SmbBandwidthLimit|Get-SmbClientConfiguration|Get-SmbClientNetworkInterface|Get-SmbConnection|Get-SmbDelegation|Get-SmbGlobalMapping|Get-SmbMapping|Get-SmbMultichannelConnection|Get-SmbMultichannelConstraint|Get-SmbOpenFile|Get-SmbServerCertificateMapping|Get-SmbServerCertProps|Get-SmbServerConfiguration|Get-SmbServerNetworkInterface|Get-SmbSession|Get-SmbShare|Get-SmbShareAccess|Grant-SmbShareAccess|New-SmbGlobalMapping|New-SmbMapping|New-SmbMultichannelConstraint|New-SmbServerCertificateMapping|New-SmbShare|Remove-SmbBandwidthLimit|Remove-SmbComponent|Remove-SmbGlobalMapping|Remove-SmbMapping|Remove-SmbMultichannelConstraint|Remove-SmbServerCertificateMapping|Remove-SmbShare|Reset-SmbClientConfiguration|Reset-SmbServerConfiguration|Revoke-SmbShareAccess|Set-SmbBandwidthLimit|Set-SmbClientConfiguration|Set-SmbPathAcl|Set-SmbServerCertificateMapping|Set-SmbServerConfiguration|Set-SmbShare|Unblock-SmbShareAccess|Update-SmbMultichannelConnection|\" +\n        // Module SmbWitness\n        \"Move-SmbClient|Get-SmbWitnessClient|Move-SmbWitnessClient|\" +\n        // Module SMISConfig\n        \"Register-SmisProvider|Search-SmisProvider|Unregister-SmisProvider|\" +\n        // Module SoftwareInventoryLogging\n        \"Get-SilComputer|Get-SilComputerIdentity|Get-SilData|Get-SilLogging|Get-SilSoftware|Get-SilUalAccess|Get-SilWindowsUpdate|Publish-SilData|Set-SilLogging|Start-SilLogging|Stop-SilLogging|\" +\n        // Module StartLayout\n        \"Get-StartApps|Export-StartLayout|Import-StartLayout|Export-StartLayoutEdgeAssets|\" +\n        // Module Storage\n        \"Add-InitiatorIdToMaskingSet|Add-PartitionAccessPath|Add-PhysicalDisk|Add-TargetPortToMaskingSet|Add-VirtualDiskToMaskingSet|Block-FileShareAccess|Clear-Disk|Clear-FileStorageTier|Connect-VirtualDisk|Debug-FileShare|Debug-StorageSubSystem|Debug-Volume|Disable-PhysicalDiskIdentification|Disable-StorageEnclosureIdentification|Disable-StorageHighAvailability|Disable-StorageMaintenanceMode|Disconnect-VirtualDisk|Dismount-DiskImage|Enable-PhysicalDiskIdentification|Enable-StorageEnclosureIdentification|Enable-StorageHighAvailability|Enable-StorageMaintenanceMode|Format-Volume|Get-DedupProperties|Get-Disk|||||Get-DiskImage|Get-DiskStorageNodeView|Get-FileIntegrity|Get-FileShare|Get-FileShareAccessControlEntry|Get-FileStorageTier|Get-InitiatorId|Get-InitiatorPort|Get-MaskingSet|Get-OffloadDataTransferSetting|Get-Partition|Get-PartitionSupportedSize|Get-PhysicalDisk|Get-PhysicalDiskStorageNodeView|Get-PhysicalExtent|Get-PhysicalExtentAssociation|Get-ResiliencySetting|Get-StorageAdvancedProperty|Get-StorageDiagnosticInfo|Get-StorageEnclosure|Get-StorageEnclosureStorageNodeView|Get-StorageEnclosureVendorData|Get-StorageFaultDomain|Get-StorageFileServer|Get-StorageFirmwareInformation|Get-StorageHealthAction|Get-StorageHealthReport|Get-StorageHealthSetting|Get-StorageJob|Get-StorageNode|Get-StoragePool|Get-StorageProvider|Get-StorageReliabilityCounter|Get-StorageSetting|Get-StorageSubSystem|Get-StorageTier|Get-StorageTierSupportedSize|Get-SupportedClusterSizes|Get-SupportedFileSystems|Get-TargetPort|Get-TargetPortal|Get-VirtualDisk|Get-VirtualDiskSupportedSize|Get-Volume|Get-VolumeCorruptionCount|Get-VolumeScrubPolicy|Grant-FileShareAccess|Hide-VirtualDisk|Initialize-Disk|Mount-DiskImage|New-FileShare|New-MaskingSet|New-Partition|New-StorageFileServer|New-StoragePool|New-StorageSubsystemVirtualDisk|New-StorageTier|New-VirtualDisk|New-VirtualDiskClone|New-VirtualDiskSnapshot|New-Volume|Optimize-StoragePool|Optimize-Volume|Register-StorageSubsystem|Remove-FileShare|Remove-InitiatorId|Remove-InitiatorIdFromMaskingSet|Remove-MaskingSet|Remove-Partition|Remove-PartitionAccessPath|Remove-PhysicalDisk|Remove-StorageFileServer|Remove-StorageHealthSetting|Remove-StoragePool|Remove-StorageTier|Remove-TargetPortFromMaskingSet|Remove-VirtualDisk|Remove-VirtualDiskFromMaskingSet|Rename-MaskingSet|Repair-FileIntegrity|Repair-VirtualDisk|Repair-Volume|Reset-PhysicalDisk|Reset-StorageReliabilityCounter|Resize-Partition|Resize-StorageTier|Resize-VirtualDisk|Revoke-FileShareAccess|Set-Disk|Set-FileIntegrity|Set-FileShare|Set-FileStorageTier|Set-InitiatorPort|Set-Partition|Set-PhysicalDisk|Set-ResiliencySetting|Set-StorageFileServer|Set-StorageHealthSetting|Set-StoragePool|Set-StorageProvider|Set-StorageSetting|Set-StorageSubSystem|Set-StorageTier|Set-VirtualDisk|Set-Volume|Set-VolumeScrubPolicy|Show-VirtualDisk|Start-StorageDiagnosticLog|Stop-StorageDiagnosticLog|Stop-StorageJob|Unblock-FileShareAccess|Unregister-StorageSubsystem|Update-Disk|Update-HostStorageCache|Update-StorageFirmware|Update-StoragePool|Update-StorageProviderCache|Write-VolumeCache|\" +\n        // Module StorageQoS\n        \"Get-StorageQoSFlow|Get-StorageQosPolicy|Get-StorageQosPolicyStore|Get-StorageQosVolume|New-StorageQosPolicy|Remove-StorageQosPolicy|Set-StorageQosPolicy|Set-StorageQosPolicyStore|\" +\n        // Module StorageReplica\n        \"Clear-SRMetadata|Dismount-SRDestination|Export-SRConfiguration|Get-SRAccess|Get-SRDelegation|Get-SRGroup|Get-SRNetworkConstraint|Get-SRPartnership|Grant-SRAccess|Grant-SRDelegation|Mount-SRDestination|New-SRGroup|New-SRPartnership|Remove-SRGroup|Remove-SRNetworkConstraint|Remove-SRPartnership|Revoke-SRAccess|Revoke-SRDelegation|Set-SRGroup|Set-SRNetworkConstraint|Set-SRPartnership|Suspend-SRGroup|Sync-SRGroup|Test-SRTopology|\" +\n        // Module SyncShare\n        \"Disable-SyncShare|Enable-SyncShare|Get-SyncServerSetting|Get-SyncShare|Get-SyncUserStatus|New-SyncShare|Remove-SyncShare|Repair-SyncShare|Set-SyncServerSetting|Set-SyncShare|\" +\n        // Module SystemInsights\n        \"Add-InsightsCapability|Disable-InsightsCapability|Disable-InsightsCapabilitySchedule|Enable-InsightsCapability|Enable-InsightsCapabilitySchedule|Get-InsightsCapability|Get-InsightsCapabilityAction|Get-InsightsCapabilityResult|Get-InsightsCapabilitySchedule|Invoke-InsightsCapability|Remove-InsightsCapability|Remove-InsightsCapabilityAction|Set-InsightsCapabilityAction|Set-InsightsCapabilitySchedule|Update-InsightsCapability|\" +\n        // Module TLS\n        \"Disable-TlsCipherSuite|Disable-TlsEccCurve|Disable-TlsSessionTicketKey|Enable-TlsCipherSuite|Enable-TlsEccCurve|Enable-TlsSessionTicketKey|Export-TlsSessionTicketKey|Get-TlsCipherSuite|Get-TlsEccCurve|New-TlsSessionTicketKey|\" +\n        // Module TroubleshootingPack\n        \"Get-TroubleshootingPack|Invoke-TroubleshootingPack|\" +\n        // Module TrustedPlatformModule\n        \"Clear-Tpm|ConvertTo-TpmOwnerAuth|Disable-TpmAutoProvisioning|Enable-TpmAutoProvisioning|Get-Tpm|Get-TpmEndorsementKeyInfo|Get-TpmSupportedFeature|Import-TpmOwnerAuth|Initialize-Tpm|Set-TpmOwnerAuth|Unblock-Tpm|\" +\n        // Module UEV\n        \"Clear-UevAppxPackage|Clear-UevConfiguration|Disable-Uev|Disable-UevAppxPackage|Disable-UevTemplate|Enable-Uev|Enable-UevAppxPackage|Enable-UevTemplate|Export-UevConfiguration|Export-UevPackage|Get-UevAppxPackage|Get-UevConfiguration|Get-UevStatus|Get-UevTemplate|Get-UevTemplateProgram|Import-UevConfiguration|Register-UevTemplate|Repair-UevTemplateIndex|Restore-UevBackup|Restore-UevUserSetting|Set-UevConfiguration|Set-UevTemplateProfile|Test-UevTemplate|Unregister-UevTemplate|Update-UevTemplate|\" +\n        // Module UpdateServices\n        \"Add-WsusComputer|Add-WsusDynamicCategory|Approve-WsusUpdate|Deny-WsusUpdate|Get-WsusClassification|Get-WsusComputer|Get-WsusDynamicCategory|Get-WsusProduct|Get-WsusServer|Get-WsusUpdate|Invoke-WsusServerCleanup|Remove-WsusDynamicCategory|Set-WsusClassification|Set-WsusDynamicCategory|Set-WsusProduct|Set-WsusServerSynchronization|\" +\n        // Module UserAccessLogging\n        \"Disable-Ual|Enable-Ual|Get-Ual|Get-UalDailyAccess|Get-UalDailyDeviceAccess|Get-UalDailyUserAccess|Get-UalDeviceAccess|Get-UalDns|Get-UalHyperV|Get-UalOverview|Get-UalServerDevice|Get-UalServerUser|Get-UalSystemId|Get-UalUserAccess|\" +\n        // Module VAMT\n        \"Add-VamtProductKey|Export-VamtData|Find-VamtManagedMachine|Get-VamtConfirmationId|Get-VamtProduct|Get-VamtProductKey|Import-VamtData|Initialize-VamtData|Install-VamtConfirmationId|Install-VamtProductActivation|Install-VamtProductKey|Update-VamtProduct|\" +\n        // Module VpnClient\n        \"Add-VpnConnection|Add-VpnConnectionRoute|Add-VpnConnectionTriggerApplication|Add-VpnConnectionTriggerDnsConfiguration|Add-VpnConnectionTriggerTrustedNetwork|Get-VpnConnection|Get-VpnConnectionTrigger|New-EapConfiguration|New-VpnServerAddress|Remove-VpnConnection|Remove-VpnConnectionRoute|Remove-VpnConnectionTriggerApplication|Remove-VpnConnectionTriggerDnsConfiguration|Remove-VpnConnectionTriggerTrustedNetwork|Set-VpnConnection|Set-VpnConnectionIPsecConfiguration|Set-VpnConnectionProxy|Set-VpnConnectionTriggerDnsConfiguration|Set-VpnConnectionTriggerTrustedNetwork|\" +\n        // Module WDS\n        \"Add-WdsDriverPackage|Approve-WdsClient|Copy-WdsInstallImage|Deny-WdsClient|Disable-WdsBootImage|Disable-WdsDriverPackage|Disable-WdsInstallImage|Disconnect-WdsMulticastClient|Enable-WdsBootImage|Enable-WdsDriverPackage|Enable-WdsInstallImage|Export-WdsBootImage|Export-WdsInstallImage|Get-WdsBootImage|Get-WdsClient|Get-WdsDriverPackage|Get-WdsInstallImage|Get-WdsInstallImageGroup|Get-WdsMulticastClient|Import-WdsBootImage|Import-WdsDriverPackage|Import-WdsInstallImage|New-WdsClient|New-WdsInstallImageGroup|Remove-WdsBootImage|Remove-WdsClient|Remove-WdsDriverPackage|Remove-WdsInstallImage|Remove-WdsInstallImageGroup|Set-WdsBootImage|Set-WdsClient|Set-WdsInstallImage|Set-WdsInstallImageGroup|\" +\n        // Module WebAdministration\n        \"Add-WebConfiguration|Add-WebConfigurationLock|Add-WebConfigurationProperty|Backup-WebConfiguration|Clear-WebCentralCertProvider|Clear-WebConfiguration|Clear-WebRequestTracingSetting|Clear-WebRequestTracingSettings|ConvertTo-WebApplication|Disable-WebCentralCertProvider|Disable-WebGlobalModule|Disable-WebRequestTracing|Enable-WebCentralCertProvider|Enable-WebGlobalModule|Enable-WebRequestTracing|Get-WebAppDomain|Get-WebApplication|Get-WebAppPoolState|Get-WebBinding|Get-WebCentralCertProvider|Get-WebConfigFile|Get-WebConfiguration|Get-WebConfigurationBackup|Get-WebConfigurationLocation|Get-WebConfigurationLock|Get-WebConfigurationProperty|Get-WebFilePath|Get-WebGlobalModule|Get-WebHandler|Get-WebItemState|Get-WebManagedModule|Get-WebRequest|Get-Website|Get-WebsiteState|Get-WebURL|Get-WebVirtualDirectory|New-WebApplication|New-WebAppPool|New-WebBinding|New-WebFtpSite|New-WebGlobalModule|New-WebHandler|New-WebManagedModule|New-Website|New-WebVirtualDirectory|Remove-WebApplication|Remove-WebAppPool|Remove-WebBinding|Remove-WebConfigurationBackup|Remove-WebConfigurationLocation|Remove-WebConfigurationLock|Remove-WebConfigurationProperty|Remove-WebGlobalModule|Remove-WebHandler|Remove-WebManagedModule|Remove-Website|Remove-WebVirtualDirectory|Rename-WebConfigurationLocation|Restart-WebAppPool|Restart-WebItem|Restore-WebConfiguration|Select-WebConfiguration|Set-WebBinding|Set-WebCentralCertProvider|Set-WebCentralCertProviderCredential|Set-WebConfiguration|Set-WebConfigurationProperty|Set-WebGlobalModule|Set-WebHandler|Set-WebManagedModule|Start-WebAppPool|Start-WebCommitDelay|Start-WebItem|Start-Website|Stop-WebAppPool|Stop-WebCommitDelay|Stop-WebItem|Stop-Website|\" +\n        // Module WebApplicationProxy\n        \"Add-WebApplicationProxyApplication|Get-WebApplicationProxyApplication|Get-WebApplicationProxyAvailableADFSRelyingParty|Get-WebApplicationProxyConfiguration|Get-WebApplicationProxyHealth|Get-WebApplicationProxySslCertificate|Install-WebApplicationProxy|Remove-WebApplicationProxyApplication|Set-WebApplicationProxyApplication|Set-WebApplicationProxyConfiguration|Set-WebApplicationProxySslCertificate|Update-WebApplicationProxyDeviceRegistration|\" +\n        // Module WHEA\n        \"Get-WheaMemoryPolicy|Set-WheaMemoryPolicy|\" +\n        // Module WindowsDeveloperLicense\n        \"Get-WindowsDeveloperLicense|Show-WindowsDeveloperLicenseRegistration|Unregister-WindowsDeveloperLicense|\" +\n        // Module WindowsDiagnosticData\n        \"Clear-WindowsDiagnosticData|\" +\n        // Module WindowsErrorReporting\n        \"Disable-WindowsErrorReporting|Enable-WindowsErrorReporting|Get-WindowsErrorReporting|\" +\n        // Module WindowsSearch\n        \"Get-WindowsSearchSetting|Set-WindowsSearchSetting|\" +\n        // Module WindowsServerBackup\n        \"Add-WBBackupTarget|Add-WBBareMetalRecovery|Add-WBFileSpec|Add-WBSystemState|Add-WBVirtualMachine|Add-WBVolume|Backup-ACL|Get-WBBackupSet|Get-WBBackupTarget|Get-WBBackupVolumeBrowsePath|Get-WBBareMetalRecovery|Get-WBDisk|Get-WBFileSpec|Get-WBJob|Get-WBPerformanceConfiguration|Get-WBPolicy|Get-WBSchedule|Get-WBSummary|Get-WBSystemState|Get-WBVirtualMachine|Get-WBVolume|Get-WBVssBackupOption|New-WBBackupTarget|New-WBFileSpec|New-WBPolicy|Remove-WBBackupSet|Remove-WBBackupTarget|Remove-WBBareMetalRecovery|Remove-WBCatalog|Remove-WBFileSpec|Remove-WBPolicy|Remove-WBSystemState|Remove-WBVirtualMachine|Remove-WBVolume|Restore-ACL|Restore-WBCatalog|Resume-WBBackup|Resume-WBVolumeRecovery|Set-WBPerformanceConfiguration|Set-WBPolicy|Set-WBSchedule|Set-WBVssBackupOption|Start-WBApplicationRecovery|Start-WBBackup|Start-WBFileRecovery|Start-WBHyperVRecovery|Start-WBSystemStateRecovery|Start-WBVolumeRecovery|Stop-WBJob|\" +\n        // Module WindowsUpdate\n        \"Get-WindowsUpdateLog\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords\n    }, \"identifier\");\n\n    // Help Reference: about_Operators\n    // https://technet.microsoft.com/en-us/library/hh847732.aspx\n    var binaryOperatorsRe = (\n        // Comparison Operators\n        \"eq|ne|gt|lt|le|ge|like|notlike|match|notmatch|contains|notcontains|in|notin|band|bor|bxor|bnot|\" + \n        \"ceq|cne|cgt|clt|cle|cge|clike|cnotlike|cmatch|cnotmatch|ccontains|cnotcontains|cin|cnotin|\" + \n        \"ieq|ine|igt|ilt|ile|ige|ilike|inotlike|imatch|inotmatch|icontains|inotcontains|iin|inotin|\" +\n        // Logical Operators\n        \"and|or|xor|not|\" +\n        // String Operators\n        \"split|join|replace|f|\" +\n        \"csplit|creplace|\" +\n        \"isplit|ireplace|\" +\n        // Type Operators\n        \"is|isnot|as|\" +\n        // Shift Operators\n        \"shl|shr\"\n    );\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"#.*$\"\n            }, {\n                token : \"comment.start\",\n                regex : \"<#\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // multi line\n                regex : /@'$/,\n                push: [\n                    {\n                        token: \"string\",\n                        regex: /^'@/,\n                        next: \"pop\"\n                    },\n                    {\n                        defaultToken: \"string\"\n                    }\n                ]\n            }, {\n                token : \"string\", // multi line\n                regex : /@\"$/,\n                push: [\n                    {\n                        token: \"string\",\n                        regex: /^\"@/,\n                        next: \"pop\"\n                    },\n                    {include: \"expressions\"},\n                    {include: \"expandable-strings\"},\n                    {\n                        defaultToken: \"string\"\n                    }\n                ]\n            },\n            {include: \"strings\"},\n            {include: \"variables\"},\n            {include: \"statements\"},\n            {include: \"expressions\"},\n            {\n                token : \"lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"rparen\",\n                regex : \"[\\\\])}]\"\n            },\n            {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment.end\",\n                regex : \"#>\",\n                next : \"start\"\n            }, {\n                token : \"doc.comment.tag\",\n                regex : \"^\\\\.\\\\w+\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"expandable-strings\" : [\n            {\n                token: \"constant.language.escape\",\n                regex: /`./\n            },\n            {include: \"variables\"}\n        ],\n        \"variables\": [\n            {\n                token : \"variable.instance\",\n                regex : \"[$]\"+identifierRe+\"\\\\b\"\n            },\n            {\n                token : \"variable.braced\",\n                regex: /\\$\\{/,\n                push: [\n                    {\n                        token: \"variable.braced\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    },\n                    {\n                        token: \"constant.language.escape\",\n                        regex: /`./\n                    },\n                    {defaultToken: \"variable.braced\"}\n                    ]\n            }\n        ],\n        \"statements\" : [\n            {\n                token : \"punctuation\",\n                regex: \";\"\n            },\n            {\n                token : \"keyword.operator\",\n                regex : \"\\\\-(?:\" + binaryOperatorsRe + \")\"\n            }, {\n                // Arithmetic, Assignment, Redirection, Call, Not & Pipeline Operators\n                token : \"keyword.operator\",\n                regex : \"&|\\\\+|\\\\-|\\\\*|\\\\/|\\\\%|\\\\=|\\\\>|\\\\&|\\\\!|\\\\|\"\n            },\n            {include: \"constants\"},\n            {\n                token : keywordMapper,\n                // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$\\\\-]*\\\\b\"\n            }\n        ],\n        \"constants\": [\n            {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"[$](?:[Tt]rue|[Ff]alse)\\\\b\"\n            }, {\n                token : \"constant.language\",\n                regex : \"[$][Nn]ull\\\\b\"\n            }\n        ],\n        \"strings\": [\n            {\n                token : \"string\", // single line\n                regex : \"['][^']*[']\"\n            },\n            {\n                token : \"string\", // single line\n                regex : /\"/,\n                push: [\n                    {\n                        token: \"string\",\n                        regex: /\"|$/,\n                        next: \"pop\"\n                    },\n                    {include: \"expressions\"},\n                    {include: \"expandable-strings\"},\n                    {\n                        defaultToken: \"string\"\n                    }\n                ]\n            }\n        ],\n        \"expressions\": [\n            {\n                token: \"keyword.operator\",\n                regex: /[$@]\\(/,\n                push: [\n                    {\n                        token: \"keyword.operator\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    },\n                    {include: \"parens-block\"},\n                    {include: \"expressions\"},\n                    {include: \"strings\"},\n                    {include: \"variables\"},\n                    {include: \"statements\"}\n                ]\n            },\n            {//hash literal expressions\n                token: \"keyword.operator\",\n                regex: /@\\{/,\n                push: [\n                    {\n                        token: \"keyword.operator\",\n                        regex: /\\}/,\n                        next: \"pop\"\n                    },\n                    {include: \"parens-block\"},\n                    {include: \"strings\"},\n                    {include: \"variables\"},\n                    {include: \"statements\"}\n                ]\n            }\n        ],\n        \"parens-block\": [\n            {\n                token: \"paren.lparen\",\n                regex: /\\(/,\n                push: [\n                    {\n                        token: \"paren.rparen\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    },\n                    {include: \"parens-block\"},\n                    {include: \"strings\"},\n                    {include: \"variables\"},\n                    {include: \"statements\"}\n                ]\n            }\n        ]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(PowershellHighlightRules, TextHighlightRules);\n\nexports.PowershellHighlightRules = PowershellHighlightRules;\n"
  },
  {
    "path": "src/mode/praat.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PraatHighlightRules = require(\"./praat_highlight_rules\").PraatHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PraatHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/praat\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/praat_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PraatHighlightRules = function() {\n\n    var keywords = (\n        \"if|then|else|elsif|elif|endif|fi|\" +\n        \"endfor|endproc|\" + // related keywords specified below\n        \"while|endwhile|\" +\n        \"repeat|until|\" +\n        \"select|plus|minus|\" +\n        \"assert|asserterror\"\n    );\n\n    var predefinedVariables = (\n        \"macintosh|windows|unix|\" +\n        \"praatVersion|praatVersion\\\\$\" +\n        \"pi|undefined|\" +\n        \"newline\\\\$|tab\\\\$|\" +\n        \"shellDirectory\\\\$|homeDirectory\\\\$|preferencesDirectory\\\\$|\" +\n        \"temporaryDirectory\\\\$|defaultDirectory\\\\$\"\n    );\n\n    // What is \"endSendPraat\"? Function? Directive?\n    var directives = (\n        \"clearinfo|endSendPraat\"\n    );\n\n    var functions = (\n//      Info functions\n        \"writeInfo|writeInfoLine|appendInfo|appendInfoLine|info\\\\$|\" +\n        \"writeFile|writeFileLine|appendFile|appendFileLine|\" +\n//      Math functions\n        \"abs|round|floor|ceiling|min|max|imin|imax|\" +\n        \"sqrt|sin|cos|tan|arcsin|arccos|arctan|arctan2|sinc|sincpi|\" +\n        \"exp|ln|lnBeta|lnGamma|log10|log2|\" +\n        \"sinh|cosh|tanh|arcsinh|arccosh|arctanh|\" +\n        \"sigmoid|invSigmoid|erf|erfc|\" +\n        \"random(?:Uniform|Integer|Gauss|Poisson|Binomial)|\" +\n        \"gaussP|gaussQ|invGaussQ|incompleteGammaP|incompleteBeta|\" +\n        \"chiSquareP|chiSquareQ|invChiSquareQ|studentP|studentQ|invStudentQ|\" +\n        \"fisherP|fisherQ|invFisherQ|\" +\n        \"binomialP|binomialQ|invBinomialP|invBinomialQ|\" +\n        \"hertzToBark|barkToHerz|\" +\n        \"hertzToMel|melToHertz|\" +\n        \"hertzToSemitones|semitonesToHerz|\" +\n        \"erb|hertzToErb|erbToHertz|\" +\n        \"phonToDifferenceLimens|differenceLimensToPhon|\" +\n        \"soundPressureToPhon|\" +\n        \"beta|beta2|besselI|besselK|\" +\n        \"numberOfColumns|numberOfRows|\" +\n//      String functions\n        \"selected|selected\\\\$|numberOfSelected|variableExists|\"+\n        \"index|rindex|startsWith|endsWith|\"+\n        \"index_regex|rindex_regex|replace_regex\\\\$|\"+\n        \"length|extractWord\\\\$|extractLine\\\\$|extractNumber|\" +\n        \"left\\\\$|right\\\\$|mid\\\\$|replace\\\\$|\" +\n        \"date\\\\$|fixed\\\\$|percent\\\\$|\" +\n//      Array functions\n        \"zero#|linear#|randomUniform#|randomInteger#|randomGauss#|\" +\n//      Pause functions\n        \"beginPause|endPause|\" +\n//      Demo functions\n        \"demoShow|demoWindowTitle|demoInput|demoWaitForInput|\" +\n        \"demoClicked|demoClickedIn|demoX|demoY|\" +\n        \"demoKeyPressed|demoKey\\\\$|\" +\n        \"demoExtraControlKeyPressed|demoShiftKeyPressed|\"+\n        \"demoCommandKeyPressed|demoOptionKeyPressed|\" +\n//      File functions\n        \"environment\\\\$|chooseReadFile\\\\$|\" +\n        \"chooseDirectory\\\\$|createDirectory|fileReadable|deleteFile|\" +\n        \"selectObject|removeObject|plusObject|minusObject|\" +\n        \"runScript|exitScript|\" +\n//      sendpraat functions\n        \"beginSendPraat|endSendPraat|\" +\n//      Other\n        \"objectsAreIdentical\"\n    );\n\n    var objectTypes = (\n        \"Activation|AffineTransform|AmplitudeTier|Art|Artword|Autosegment|\"  +\n        \"BarkFilter|CCA|Categories|Cepstrum|Cepstrumc|ChebyshevSeries|\"      +\n        \"ClassificationTable|Cochleagram|Collection|Configuration|\"          +\n        \"Confusion|ContingencyTable|Corpus|Correlation|Covariance|\"          +\n        \"CrossCorrelationTable|CrossCorrelationTables|DTW|Diagonalizer|\"     +\n        \"Discriminant|Dissimilarity|Distance|Distributions|DurationTier|\"    +\n        \"EEG|ERP|ERPTier|Eigen|Excitation|Excitations|ExperimentMFC|FFNet|\"  +\n        \"FeatureWeights|Formant|FormantFilter|FormantGrid|FormantPoint|\"     +\n        \"FormantTier|GaussianMixture|HMM|HMM_Observation|\"                   +\n        \"HMM_ObservationSequence|HMM_State|HMM_StateSequence|Harmonicity|\"   +\n        \"ISpline|Index|Intensity|IntensityTier|IntervalTier|KNN|KlattGrid|\"  +\n        \"KlattTable|LFCC|LPC|Label|LegendreSeries|LinearRegression|\"         +\n        \"LogisticRegression|LongSound|Ltas|MFCC|MSpline|ManPages|\"           +\n        \"Manipulation|Matrix|MelFilter|MixingMatrix|Movie|Network|\"          +\n        \"OTGrammar|OTHistory|OTMulti|PCA|PairDistribution|ParamCurve|\"       +\n        \"Pattern|Permutation|Pitch|PitchTier|PointProcess|Polygon|\"          +\n        \"Polynomial|Procrustes|RealPoint|RealTier|ResultsMFC|Roots|SPINET|\"  +\n        \"SSCP|SVD|Salience|ScalarProduct|Similarity|SimpleString|\"           +\n        \"SortedSetOfString|Sound|Speaker|Spectrogram|Spectrum|SpectrumTier|\" +\n        \"SpeechSynthesizer|SpellingChecker|Strings|StringsIndex|Table|\"      +\n        \"TableOfReal|TextGrid|TextInterval|TextPoint|TextTier|Tier|\"         +\n        \"Transition|VocalTract|Weight|WordList\"\n    );\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n            // Interpolated strings\n                token : \"string.interpolated\",\n                regex : /'((?:\\.?[a-z][a-zA-Z0-9_.]*)(?:\\$|#|:[0-9]+)?)'/\n            }, {\n            // stopwatch\n                token : [\"text\", \"text\", \"keyword.operator\", \"text\", \"keyword\"],\n                regex : /(^\\s*)(?:(\\.?[a-z][a-zA-Z0-9_.]*\\$?\\s+)(=)(\\s+))?(stopwatch)/\n            }, {\n            // Directives which introduce unquoted strings\n                token : [\"text\", \"keyword\", \"text\", \"string\"],\n                regex : /(^\\s*)(print(?:line|tab)?|echo|exit|pause|send(?:praat|socket)|include|execute|system(?:_nocheck)?)(\\s+)(.*)/\n            }, {\n            // Directives with no arguments\n                token : [\"text\", \"keyword\"],\n                regex : \"(^\\\\s*)(\" + directives + \")$\"\n            }, {\n            // Operators\n                token : [\"text\", \"keyword.operator\", \"text\"],\n                regex : /(\\s+)((?:\\+|-|\\/|\\*|<|>)=?|==?|!=|%|\\^|\\||and|or|not)(\\s+)/\n            }, {\n            // Commands\n                token : [\"text\", \"text\", \"keyword.operator\", \"text\", \"keyword\", \"text\", \"keyword\"],\n                regex : /(^\\s*)(?:(\\.?[a-z][a-zA-Z0-9_.]*\\$?\\s+)(=)(\\s+))?(?:((?:no)?warn|(?:unix_)?nocheck|noprogress)(\\s+))?((?:[A-Z][^.:\"]+)(?:$|(?:\\.{3}|:)))/\n            }, {\n            // Editor mode\n                token : [\"text\", \"keyword\", \"text\", \"keyword\"],\n                regex : /(^\\s*)((?:no(?:warn|check))?)(\\s*)(\\b(?:editor(?::?)|endeditor)\\b)/\n            }, {\n            // Demo commands\n                token : [\"text\", \"keyword\", \"text\", \"keyword\"],\n                regex : /(^\\s*)(?:(demo)?(\\s+))((?:[A-Z][^.:\"]+)(?:$|(?:\\.{3}|:)))/\n            }, {\n            // Font-sizing commands\n                token : [\"text\", \"keyword\", \"text\", \"keyword\"],\n                regex : /^(\\s*)(?:(demo)(\\s+))?(10|12|14|16|24)$/\n            }, {\n            // do-style command calls\n                token : [\"text\", \"support.function\", \"text\"],\n                regex : /(\\s*)(do\\$?)(\\s*:\\s*|\\s*\\(\\s*)/\n            }, {\n            // Object types\n                token : \"entity.name.type\",\n                regex : \"(\" + objectTypes + \")\"\n            }, {\n            // Predefined variables\n                token : \"variable.language\",\n                regex : \"(\" + predefinedVariables + \")\"\n            }, {\n            // Functions\n                token : [\"support.function\", \"text\"],\n                regex : \"((?:\" + functions + \")\\\\$?)(\\\\s*(?::|\\\\())\"\n            }, {\n            // For-loop declarations\n                token : \"keyword\",\n                regex : /(\\bfor\\b)/,\n                next : \"for\"\n            }, {\n            // Generic keywords\n                token : \"keyword\",\n                regex : \"(\\\\b(?:\" + keywords + \")\\\\b)\"\n            }, {\n            // Generic strings\n                token : \"string\",\n                regex : /\"[^\"]*\"/\n            }, {\n            // Multiline quoted strings\n                token : \"string\",\n                regex : /\"[^\"]*$/,\n                next : \"brokenstring\"\n            }, {\n            // Form declarations\n                token : [\"text\", \"keyword\", \"text\", \"entity.name.section\"],\n                regex : /(^\\s*)(\\bform\\b)(\\s+)(.*)/,\n                next : \"form\"\n            }, {\n            // Numeric constants\n                token : \"constant.numeric\",\n                regex : /\\b[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/\n            }, {\n            // Procedure declarations\n                token : [\"keyword\", \"text\", \"entity.name.function\"],\n                regex : /(procedure)(\\s+)([^:\\s]+)/\n            }, {\n            // New-style procedure calls\n                token : [\"entity.name.function\", \"text\"],\n                regex : /(@\\S+)(:|\\s*\\()/\n            }, {\n            // Old-style procedure calls\n                token : [\"text\", \"keyword\", \"text\", \"entity.name.function\"],\n                regex : /(^\\s*)(call)(\\s+)(\\S+)/\n            }, {\n            // Comments\n                token : \"comment\",\n                regex : /(^\\s*#|;).*$/\n            }, {\n                token : \"text\",\n                regex : /\\s+/\n            }\n        ],\n        \"form\" : [\n            {\n                token : [\"keyword\", \"text\", \"constant.numeric\"],\n                regex : /((?:optionmenu|choice)\\s+)(\\S+:\\s+)([0-9]+)/\n            }, {\n                token : [\"keyword\", \"constant.numeric\"],\n                regex : /((?:option|button)\\s+)([+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b)/\n            }, {\n                token : [\"keyword\", \"string\"],\n                regex : /((?:option|button)\\s+)(.*)/\n            }, {\n                token : [\"keyword\", \"text\", \"string\"],\n                regex : /((?:sentence|text)\\s+)(\\S+\\s*)(.*)/\n            }, {\n                token : [\"keyword\", \"text\", \"string\", \"invalid.illegal\"],\n                regex : /(word\\s+)(\\S+\\s*)(\\S+)?(\\s.*)?/\n            }, {\n                token : [\"keyword\", \"text\", \"constant.language\"],\n                regex : /(boolean\\s+)(\\S+\\s*)(0|1|\"?(?:yes|no)\"?)/\n            }, {\n                token : [\"keyword\", \"text\", \"constant.numeric\"],\n                regex : /((?:real|natural|positive|integer)\\s+)(\\S+\\s*)([+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b)/\n            }, {\n                token : [\"keyword\", \"string\"],\n                regex : /(comment\\s+)(.*)/\n            }, {\n                token : \"keyword\",\n                regex : 'endform',\n                next : \"start\"\n            }\n        ],\n        \"for\" : [\n            {\n                token : [\"keyword\", \"text\", \"constant.numeric\", \"text\"],\n                regex : /(from|to)(\\s+)([+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?)(\\s*)/\n            }, {\n                token : [\"keyword\", \"text\"],\n                regex : /(from|to)(\\s+\\S+\\s*)/\n            }, {\n                token : \"text\",\n                regex : /$/,\n                next : \"start\"\n            }\n        ],\n        \"brokenstring\" : [\n            {\n                token : [\"text\", \"string\"],\n                regex : /(\\s*\\.{3})([^\"]*)/\n            }, {\n                token : \"string\",\n                regex : /\"/,\n                next : \"start\"\n            }\n        ]\n    };\n};\n\noop.inherits(PraatHighlightRules, TextHighlightRules);\n\nexports.PraatHighlightRules = PraatHighlightRules;\n"
  },
  {
    "path": "src/mode/prisma.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PrismaHighlightRules = require(\"./prisma_highlight_rules\").PrismaHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PrismaHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    // this.blockComment = {start: \"\"/*\"\", end: \"\"*/\"\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/prisma\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/prisma_highlight_rules.js",
    "content": "/* This file was autogenerated from ../convert.json (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PrismaHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            include: \"#triple_comment\"\n        }, {\n            include: \"#double_comment\"\n        }, {\n            include: \"#model_block_definition\"\n        }, {\n            include: \"#config_block_definition\"\n        }, {\n            include: \"#enum_block_definition\"\n        }, {\n            include: \"#type_definition\"\n        }],\n        \"#model_block_definition\": [{\n            token: [\n                \"source.prisma.embedded.source\",\n                \"storage.type.model.prisma\",\n                \"source.prisma.embedded.source\",\n                \"entity.name.type.model.prisma\",\n                \"source.prisma.embedded.source\",\n                \"punctuation.definition.tag.prisma\"\n            ],\n            regex: /^(\\s*)(model|type)(\\s+)([A-Za-z][\\w]*)(\\s+)({)/,\n            push: [{\n                token: \"punctuation.definition.tag.prisma\",\n                regex: /\\s*\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#triple_comment\"\n            }, {\n                include: \"#double_comment\"\n            }, {\n                include: \"#field_definition\"\n            }, {\n                defaultToken: \"source.prisma.embedded.source\"\n            }]\n        }],\n        \"#enum_block_definition\": [{\n            token: [\n                \"source.prisma.embedded.source\",\n                \"storage.type.enum.prisma\",\n                \"source.prisma.embedded.source\",\n                \"entity.name.type.enum.prisma\",\n                \"source.prisma.embedded.source\",\n                \"punctuation.definition.tag.prisma\"\n            ],\n            regex: /^(\\s*)(enum)(\\s+)([A-Za-z][\\w]*)(\\s+)({)/,\n            push: [{\n                token: \"punctuation.definition.tag.prisma\",\n                regex: /\\s*\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#triple_comment\"\n            }, {\n                include: \"#double_comment\"\n            }, {\n                include: \"#enum_value_definition\"\n            }, {\n                defaultToken: \"source.prisma.embedded.source\"\n            }]\n        }],\n        \"#config_block_definition\": [{\n            token: [\n                \"source.prisma.embedded.source\",\n                \"storage.type.config.prisma\",\n                \"source.prisma.embedded.source\",\n                \"entity.name.type.config.prisma\",\n                \"source.prisma.embedded.source\",\n                \"punctuation.definition.tag.prisma\"\n            ],\n            regex: /^(\\s*)(generator|datasource)(\\s+)([A-Za-z][\\w]*)(\\s+)({)/,\n            push: [{\n                token: \"source.prisma.embedded.source\",\n                regex: /\\s*\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#triple_comment\"\n            }, {\n                include: \"#double_comment\"\n            }, {\n                include: \"#assignment\"\n            }, {\n                defaultToken: \"source.prisma.embedded.source\"\n            }]\n        }],\n        \"#assignment\": [{\n            token: [\n                \"text\",\n                \"variable.other.assignment.prisma\",\n                \"text\",\n                \"keyword.operator.terraform\",\n                \"text\"\n            ],\n            regex: /^(\\s*)(\\w+)(\\s*)(=)(\\s*)/,\n            push: [{\n                token: \"text\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                include: \"#double_comment_inline\"\n            }]\n        }],\n        \"#field_definition\": [{\n            token: [\n                \"text\",\n                \"variable.other.assignment.prisma\",\n                \"invalid.illegal.colon.prisma\",\n                \"text\",\n                \"support.type.primitive.prisma\",\n                \"keyword.operator.list_type.prisma\",\n                \"keyword.operator.optional_type.prisma\",\n                \"invalid.illegal.required_type.prisma\"\n            ],\n            regex: /^(\\s*)(\\w+)((?:\\s*:)?)(\\s+)(\\w+)((?:\\[\\])?)((?:\\?)?)((?:\\!)?)/\n        }, {\n            include: \"#attribute_with_arguments\"\n        }, {\n            include: \"#attribute\"\n        }],\n        \"#type_definition\": [{\n            token: [\n                \"text\",\n                \"storage.type.type.prisma\",\n                \"text\",\n                \"entity.name.type.type.prisma\",\n                \"text\",\n                \"support.type.primitive.prisma\"\n            ],\n            regex: /^(\\s*)(type)(\\s+)(\\w+)(\\s*=\\s*)(\\w+)/\n        }, {\n            include: \"#attribute_with_arguments\"\n        }, {\n            include: \"#attribute\"\n        }],\n        \"#enum_value_definition\": [{\n            token: [\n                \"text\",\n                \"variable.other.assignment.prisma\",\n                \"text\"\n            ],\n            regex: /^(\\s*)(\\w+)(\\s*$)/\n        }, {\n            include: \"#attribute_with_arguments\"\n        }, {\n            include: \"#attribute\"\n        }],\n        \"#attribute_with_arguments\": [{\n            token: [\n                \"entity.name.function.attribute.prisma\",\n                \"punctuation.definition.tag.prisma\"\n            ],\n            regex: /(@@?[\\w\\.]+)(\\()/,\n            push: [{\n                token: \"punctuation.definition.tag.prisma\",\n                regex: /\\)/,\n                next: \"pop\"\n            }, {\n                include: \"#named_argument\"\n            }, {\n                include: \"#value\"\n            }, {\n                defaultToken: \"source.prisma.attribute.with_arguments\"\n            }]\n        }],\n        \"#attribute\": [{\n            token: \"entity.name.function.attribute.prisma\",\n            regex: /@@?[\\w\\.]+/\n        }],\n        \"#array\": [{\n            token: \"source.prisma.array\",\n            regex: /\\[/,\n            push: [{\n                token: \"source.prisma.array\",\n                regex: /\\]/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                defaultToken: \"source.prisma.array\"\n            }]\n        }],\n        \"#value\": [{\n            include: \"#array\"\n        }, {\n            include: \"#functional\"\n        }, {\n            include: \"#literal\"\n        }],\n        \"#functional\": [{\n            token: [\n                \"support.function.functional.prisma\",\n                \"punctuation.definition.tag.prisma\"\n            ],\n            regex: /(\\w+)(\\()/,\n            push: [{\n                token: \"punctuation.definition.tag.prisma\",\n                regex: /\\)/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                defaultToken: \"source.prisma.functional\"\n            }]\n        }],\n        \"#literal\": [{\n            include: \"#boolean\"\n        }, {\n            include: \"#number\"\n        }, {\n            include: \"#double_quoted_string\"\n        }, {\n            include: \"#identifier\"\n        }],\n        \"#identifier\": [{\n            token: \"support.constant.constant.prisma\",\n            regex: /\\b(?:\\w)+\\b/\n        }],\n        \"#map_key\": [{\n            token: [\n                \"variable.parameter.key.prisma\",\n                \"text\",\n                \"punctuation.definition.separator.key-value.prisma\",\n                \"text\"\n            ],\n            regex: /(\\w+)(\\s*)(:)(\\s*)/\n        }],\n        \"#named_argument\": [{\n            include: \"#map_key\"\n        }, {\n            include: \"#value\"\n        }],\n        \"#triple_comment\": [{\n            token: \"comment.prisma\",\n            regex: /\\/\\/\\//,\n            push: [{\n                token: \"comment.prisma\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.prisma\"\n            }]\n        }],\n        \"#double_comment\": [{\n            token: \"comment.prisma\",\n            regex: /\\/\\//,\n            push: [{\n                token: \"comment.prisma\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.prisma\"\n            }]\n        }],\n        \"#double_comment_inline\": [{\n            token: \"comment.prisma\",\n            regex: /\\/\\/[^$]*/\n        }],\n        \"#boolean\": [{\n            token: \"constant.language.boolean.prisma\",\n            regex: /\\b(?:true|false)\\b/\n        }],\n        \"#number\": [{\n            token: \"constant.numeric.prisma\",\n            regex: /(?:0(?:x|X)[0-9a-fA-F]*|(?:\\+|-)?\\b(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:[LlFfUuDdg]|UL|ul)?\\b/\n        }],\n        \"#double_quoted_string\": [{\n            token: \"string.quoted.double.start.prisma\",\n            regex: /\"/,\n            push: [{\n                token: \"string.quoted.double.end.prisma\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                include: \"#string_interpolation\"\n            }, {\n                token: \"string.quoted.double.prisma\",\n                regex: /[\\w\\-\\/\\._\\\\%@:\\?=]+/\n            }, {\n                defaultToken: \"unnamed\"\n            }]\n        }],\n        \"#string_interpolation\": [{\n            token: \"keyword.control.interpolation.start.prisma\",\n            regex: /\\$\\{/,\n            push: [{\n                token: \"keyword.control.interpolation.end.prisma\",\n                regex: /\\s*\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                defaultToken: \"source.tag.embedded.source.prisma\"\n            }]\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nPrismaHighlightRules.metaData = {\n    name: \"Prisma\",\n    scopeName: \"source.prisma\"\n};\n\n\noop.inherits(PrismaHighlightRules, TextHighlightRules);\n\nexports.PrismaHighlightRules = PrismaHighlightRules;\n"
  },
  {
    "path": "src/mode/prolog.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PrologHighlightRules = require(\"./prolog_highlight_rules\").PrologHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = PrologHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"%\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/prolog\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/prolog_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/stephenroller/prolog-tmbundle/master/Syntaxes/Prolog.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PrologHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { include: '#comment' },\n         { include: '#basic_fact' },\n         { include: '#rule' },\n         { include: '#directive' },\n         { include: '#fact' } ],\n      '#atom': \n       [ { token: 'constant.other.atom.prolog',\n           regex: '\\\\b[a-z][a-zA-Z0-9_]*\\\\b' },\n         { token: 'constant.numeric.prolog',\n           regex: '-?\\\\d+(?:\\\\.\\\\d+)?' },\n         { include: '#string' } ],\n      '#basic_elem': \n       [ { include: '#comment' },\n         { include: '#statement' },\n         { include: '#constants' },\n         { include: '#operators' },\n         { include: '#builtins' },\n         { include: '#list' },\n         { include: '#atom' },\n         { include: '#variable' } ],\n      '#basic_fact': \n       [ { token: \n            [ 'entity.name.function.fact.basic.prolog',\n              'punctuation.end.fact.basic.prolog' ],\n           regex: '([a-z]\\\\w*)(\\\\.)' } ],\n      '#builtins': \n       [ { token: 'support.function.builtin.prolog',\n           regex: '\\\\b(?:abolish|abort|ancestors|arg|ascii|assert[az]|atom(?:ic)?|body|char|close|conc|concat|consult|define|definition|dynamic|dump|fail|file|free|free_proc|functor|getc|goal|halt|head|head|integer|length|listing|match_args|member|next_clause|nl|nonvar|nth|number|cvars|nvars|offset|op|print?|prompt|putc|quoted|ratom|read|redefine|rename|retract(?:all)?|see|seeing|seen|skip|spy|statistics|system|tab|tell|telling|term|time|told|univ|unlink_clause|unspy_predicate|var|write)\\\\b' } ],\n      '#comment': \n       [ { token: \n            [ 'punctuation.definition.comment.prolog',\n              'comment.line.percentage.prolog' ],\n           regex: '(%)(.*$)' },\n         { token: 'punctuation.definition.comment.prolog',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.prolog',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.prolog' } ] } ],\n      '#constants': \n       [ { token: 'constant.language.prolog',\n           regex: '\\\\b(?:true|false|yes|no)\\\\b' } ],\n      '#directive': \n       [ { token: 'keyword.operator.directive.prolog',\n           regex: ':-',\n           push: \n            [ { token: 'meta.directive.prolog', regex: '\\\\.', next: 'pop' },\n              { include: '#comment' },\n              { include: '#statement' },\n              { defaultToken: 'meta.directive.prolog' } ] } ],\n      '#expr': \n       [ { include: '#comments' },\n         { token: 'meta.expression.prolog',\n           regex: '\\\\(',\n           push: \n            [ { token: 'meta.expression.prolog', regex: '\\\\)', next: 'pop' },\n              { include: '#expr' },\n              { defaultToken: 'meta.expression.prolog' } ] },\n         { token: 'keyword.control.cutoff.prolog', regex: '!' },\n         { token: 'punctuation.control.and.prolog', regex: ',' },\n         { token: 'punctuation.control.or.prolog', regex: ';' },\n         { include: '#basic_elem' } ],\n      '#fact': \n       [ { token: \n            [ 'entity.name.function.fact.prolog',\n              'punctuation.begin.fact.parameters.prolog' ],\n           regex: '([a-z]\\\\w*)(\\\\()(?!.*:-)',\n           push: \n            [ { token: \n                 [ 'punctuation.end.fact.parameters.prolog',\n                   'punctuation.end.fact.prolog' ],\n                regex: '(\\\\))(\\\\.?)',\n                next: 'pop' },\n              { include: '#parameter' },\n              { defaultToken: 'meta.fact.prolog' } ] } ],\n      '#list': \n       [ { token: 'punctuation.begin.list.prolog',\n           regex: '\\\\[(?=.*\\\\])',\n           push: \n            [ { token: 'punctuation.end.list.prolog',\n                regex: '\\\\]',\n                next: 'pop' },\n              { include: '#comment' },\n              { token: 'punctuation.separator.list.prolog', regex: ',' },\n              { token: 'punctuation.concat.list.prolog',\n                regex: '\\\\|',\n                push: \n                 [ { token: 'meta.list.concat.prolog',\n                     regex: '(?=\\\\s*\\\\])',\n                     next: 'pop' },\n                   { include: '#basic_elem' },\n                   { defaultToken: 'meta.list.concat.prolog' } ] },\n              { include: '#basic_elem' },\n              { defaultToken: 'meta.list.prolog' } ] } ],\n      '#operators': \n       [ { token: 'keyword.operator.prolog',\n           regex: '\\\\\\\\\\\\+|\\\\bnot\\\\b|\\\\bis\\\\b|->|[><]|[><\\\\\\\\:=]?=|(?:=\\\\\\\\|\\\\\\\\=)=' } ],\n      '#parameter': \n       [ { token: 'variable.language.anonymous.prolog',\n           regex: '\\\\b_\\\\b' },\n         { token: 'variable.parameter.prolog',\n           regex: '\\\\b[A-Z_]\\\\w*\\\\b' },\n         { token: 'punctuation.separator.parameters.prolog', regex: ',' },\n         { include: '#basic_elem' },\n         { token: 'text', regex: '[^\\\\s]' } ],\n      '#rule': \n       [ { token: 'meta.rule.prolog',\n           regex: '(?=[a-z]\\\\w*.*:-)',\n           push: \n            [ { token: 'punctuation.rule.end.prolog',\n                regex: '\\\\.',\n                next: 'pop' },\n              { token: 'meta.rule.signature.prolog',\n                regex: '(?=[a-z]\\\\w*.*:-)',\n                push: \n                 [ { token: 'meta.rule.signature.prolog',\n                     regex: '(?=:-)',\n                     next: 'pop' },\n                   { token: 'entity.name.function.rule.prolog',\n                     regex: '[a-z]\\\\w*(?=\\\\(|\\\\s*:-)' },\n                   { token: 'punctuation.rule.parameters.begin.prolog',\n                     regex: '\\\\(',\n                     push: \n                      [ { token: 'punctuation.rule.parameters.end.prolog',\n                          regex: '\\\\)',\n                          next: 'pop' },\n                        { include: '#parameter' },\n                        { defaultToken: 'meta.rule.parameters.prolog' } ] },\n                   { defaultToken: 'meta.rule.signature.prolog' } ] },\n              { token: 'keyword.operator.definition.prolog',\n                regex: ':-',\n                push: \n                 [ { token: 'meta.rule.definition.prolog',\n                     regex: '(?=\\\\.)',\n                     next: 'pop' },\n                   { include: '#comment' },\n                   { include: '#expr' },\n                   { defaultToken: 'meta.rule.definition.prolog' } ] },\n              { defaultToken: 'meta.rule.prolog' } ] } ],\n      '#statement': \n       [ { token: 'meta.statement.prolog',\n           regex: '(?=[a-z]\\\\w*\\\\()',\n           push: \n            [ { token: 'punctuation.end.statement.parameters.prolog',\n                regex: '\\\\)',\n                next: 'pop' },\n              { include: '#builtins' },\n              { include: '#atom' },\n              { token: 'punctuation.begin.statement.parameters.prolog',\n                regex: '\\\\(',\n                push: \n                 [ { token: 'meta.statement.parameters.prolog',\n                     regex: '(?=\\\\))',\n                     next: 'pop' },\n                   { token: 'punctuation.separator.statement.prolog', regex: ',' },\n                   { include: '#basic_elem' },\n                   { defaultToken: 'meta.statement.parameters.prolog' } ] },\n              { defaultToken: 'meta.statement.prolog' } ] } ],\n      '#string': \n       [ { token: 'punctuation.definition.string.begin.prolog',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.prolog',\n                regex: '\\'',\n                next: 'pop' },\n              { token: 'constant.character.escape.prolog', regex: '\\\\\\\\.' },\n              { token: 'constant.character.escape.quote.prolog',\n                regex: '\\'\\'' },\n              { defaultToken: 'string.quoted.single.prolog' } ] } ],\n      '#variable': \n       [ { token: 'variable.language.anonymous.prolog',\n           regex: '\\\\b_\\\\b' },\n         { token: 'variable.other.prolog',\n           regex: '\\\\b[A-Z_][a-zA-Z0-9_]*\\\\b' } ] };\n    \n    this.normalizeRules();\n};\n\nPrologHighlightRules.metaData = { fileTypes: [ 'plg', 'prolog' ],\n      foldingStartMarker: '(%\\\\s*region \\\\w*)|([a-z]\\\\w*.*:- ?)',\n      foldingStopMarker: '(%\\\\s*end(\\\\s*region)?)|(?=\\\\.)',\n      keyEquivalent: '^~P',\n      name: 'Prolog',\n      scopeName: 'source.prolog' };\n\n\noop.inherits(PrologHighlightRules, TextHighlightRules);\n\nexports.PrologHighlightRules = PrologHighlightRules;\n"
  },
  {
    "path": "src/mode/properties.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PropertiesHighlightRules = require(\"./properties_highlight_rules\").PropertiesHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = PropertiesHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$id = \"ace/mode/properties\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/properties_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PropertiesHighlightRules = function() {\n\n    var escapeRe = /\\\\u[0-9a-fA-F]{4}|\\\\/;\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : /[!#].*$/\n            }, {\n                // Empty value\n                token : \"keyword\",\n                regex : /[=:]$/\n            }, {\n                token : \"keyword\",\n                regex : /[=:]/,\n                next  : \"value\"\n            }, {\n                token : \"constant.language.escape\",\n                regex : escapeRe\n            }, {\n                defaultToken: \"variable\"\n            }\n        ],\n        \"value\" : [\n            {\n                // Multi-line string\n                regex : /\\\\$/,\n                token : \"string\",\n                next : \"value\"\n            }, {\n                regex : /$/,\n                token : \"string\",\n                next : \"start\"\n            }, {\n                token : \"constant.language.escape\",\n                regex : escapeRe\n            }, {\n                defaultToken: \"string\"\n            }\n        ]\n    };\n\n};\n\noop.inherits(PropertiesHighlightRules, TextHighlightRules);\n\nexports.PropertiesHighlightRules = PropertiesHighlightRules;\n"
  },
  {
    "path": "src/mode/protobuf.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar CMode = require(\"./c_cpp\").Mode;\nvar ProtobufHighlightRules = require(\"./protobuf_highlight_rules\").ProtobufHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    CMode.call(this);\n    this.foldingRules = new CStyleFoldMode();\n    this.HighlightRules = ProtobufHighlightRules;\n};\noop.inherits(Mode, CMode);\n\n(function() {\n    // Extra logic goes here.\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/protobuf\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/protobuf_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var ProtobufHighlightRules = function() {\n\n        var builtinTypes = \"double|float|int32|int64|uint32|uint64|sint32|\" +\n                           \"sint64|fixed32|fixed64|sfixed32|sfixed64|bool|\" +\n                           \"string|bytes\";\n        var keywordDeclaration = \"message|required|optional|repeated|package|\" +\n                                 \"import|option|enum\";\n\n        var keywordMapper = this.createKeywordMapper({\n            \"keyword.declaration.protobuf\": keywordDeclaration,\n            \"support.type\": builtinTypes\n        }, \"identifier\");\n\n        this.$rules = {\n            \"start\": [{\n                    token: \"comment\",\n                    regex: /\\/\\/.*$/\n                }, {\n                    token: \"comment\",\n                    regex: /\\/\\*/,\n                    next: \"comment\"\n                }, {\n                    token: \"constant\",\n                    regex: \"<[^>]+>\"\n                }, {\n                    regex: \"=\",\n                    token: \"keyword.operator.assignment.protobuf\"\n                }, {\n                    token : \"string\", // single line\n                    regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n                }, {\n                    token : \"string\", // single line\n                    regex : '[\\'](?:(?:\\\\\\\\.)|(?:[^\\'\\\\\\\\]))*?[\\']'\n                }, {\n                    token: \"constant.numeric\", // hex\n                    regex: \"0[xX][0-9a-fA-F]+\\\\b\"\n                }, {\n                    token: \"constant.numeric\", // float\n                    regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n                }, {\n                    token: keywordMapper,\n                    regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                }],\n            \"comment\": [{\n                    token : \"comment\", // closing comment\n                    regex : \"\\\\*\\\\/\",\n                    next : \"start\"\n                }, {\n                    defaultToken : \"comment\"\n                }]\n        };\n\n        this.normalizeRules();\n    };\n\n    oop.inherits(ProtobufHighlightRules, TextHighlightRules);\n\n    exports.ProtobufHighlightRules = ProtobufHighlightRules;\n"
  },
  {
    "path": "src/mode/prql.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./prql_highlight_rules\").PrqlHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    // Extra logic goes here.\n    this.$id = \"ace/mode/prql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/prql_highlight_rules.js",
    "content": "// https://prql-lang.org/\n// https://github.com/PRQL/prql\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PrqlHighlightRules = function() {\n    var builtinFunctions = \"min|max|sum|average|stddev|every|any|concat_array|count|\" +\n    \"lag|lead|first|last|rank|rank_dense|row_number|\" +\n    \"round|as|in|\" +\n    \"tuple_every|tuple_map|tuple_zip|_eq|_is_null|\" +\n    \"from_text|\" +\n    \"lower|upper|\" +\n    \"read_parquet|read_csv\";\n\n    var builtinTypes = [\n        \"bool\",\n        \"int\",\n        \"int8\",\n        \"int16\",\n        \"int32\",\n        \"int64\",\n        \"int128\",\n        \"float\",\n        \"text\",\n        \"timestamp\",\n        \"set\"].join(\"|\");\n\n    var keywordMapper = this.createKeywordMapper({\n       \"constant.language\": \"null\",\n       \"constant.language.boolean\": \"true|false\",\n       \"keyword\": \"let|into|case|prql|type|module|internal\",\n       \"storage.type\": \"let|func\",\n       \"support.function\": builtinFunctions,\n       \"support.type\": builtinTypes,\n       \"variable.language\": \"date|math\"\n    }, \"identifier\");\n    \n    var escapeRe = /\\\\(\\d+|['\"\\\\&bfnrt]|u\\{[0-9a-fA-F]{1,6}\\}|x[0-9a-fA-F]{2})/;\n    var identifierRe = /[A-Za-z_][a-z_A-Z0-9]/.source;\n    var numRe = /(?:\\d\\d*(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+\\b)?/.source;\n    var bidi = \"[\\\\u202A\\\\u202B\\\\u202D\\\\u202E\\\\u2066\\\\u2067\\\\u2068\\\\u202C\\\\u2069]\";\n\n    this.$rules = {\n        start: [\n        {\n            token: \"string.start\",\n            regex: 's?\"',\n            next: \"string\"\n        }, {\n            token: \"string.start\",\n            regex: 'f\"',\n            next: \"fstring\"\n        }, {\n            token: \"string.start\",\n            regex: 'r\"',\n            next: \"rstring\"\n        }, {\n            token: \"string.single\",\n            start: \"'\",\n            end: \"'\"\n        }, {\n            token: \"string.character\",\n            regex: \"'(?:\" + escapeRe.source + \"|.)'?\"\n        }, {\n            token: \"constant.language\",\n            regex: \"^\" + identifierRe + \"*\"\n        }, {\n            token : [\"constant.numeric\", \"keyword\"],\n            regex : \"(\" + numRe + \")(years|months|weeks|days|hours|minutes|seconds|milliseconds|microseconds)\"\n        }, {\n            token: \"constant.numeric\", // hexadecimal, octal and binary\n            regex: /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\\b/\n        }, {\n            token: \"constant.numeric\", // decimal integers and floats\n            regex: numRe\n        }, {\n            token: \"comment.block.documentation\",\n            regex: \"#!.*\"\n        }, {\n            token: \"comment.line.number-sign\",\n            regex: \"#.*\"\n        }, {\n            token: \"keyword.operator\",\n            regex: /\\|\\s*/,\n            next: \"pipe\"\n        }, {\n            token: \"keyword.operator\",\n            regex: /->|=>|==|!=|>=|<=|~=|&&|\\|\\||\\?\\?|\\/\\/|@/\n        }, {\n            token: \"invalid.illegal\",\n            regex: bidi\n        }, {\n            token: \"punctuation.operator\",\n            regex: /[,`]/\n        }, {\n            token: keywordMapper,\n            regex: \"[\\\\w\\\\xff-\\\\u218e\\\\u2455-\\\\uffff]+\\\\b\"\n        }, {\n            token: \"paren.lparen\",\n            regex: /[\\[({]/\n        }, {\n            token: \"paren.rparen\",\n            regex: /[\\])}]/\n        } ],\n        pipe: [{\n            token: \"constant.language\",\n            regex: identifierRe + \"*\",\n            next: \"pop\"\n        },{\n            token: \"error\",\n            regex: \"\",\n            next: \"pop\"\n        }],\n        string: [{\n            token: \"constant.character.escape\",\n            regex: escapeRe\n        }, {\n            token: \"text\",\n            regex: /\\\\(\\s|$)/,\n            next: \"stringGap\"\n        }, {\n            token: \"string.end\",\n            regex: '\"',\n            next: \"start\"\n        }, {\n            token: \"invalid.illegal\",\n            regex: bidi\n        }, {\n            defaultToken: \"string.double\"\n        }],\n        stringGap: [{\n            token: \"text\",\n            regex: /\\\\/,\n            next: \"string\"\n        }, {\n            token: \"error\",\n            regex: \"\",\n            next: \"start\"\n        }],\n        fstring: [{\n            token: \"constant.character.escape\",\n            regex: escapeRe\n        }, {\n            token: \"string.end\",\n            regex: '\"',\n            next: \"start\"\n        }, {\n            token: \"invalid.illegal\",\n            regex: bidi\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fstringParenRules\"\n        }, {\n            token: \"invalid.illegal\",\n            regex: bidi\n        }, {\n            defaultToken: \"string\"\n        }],\n        fstringParenRules: [{\n            token: \"constant.language\",\n            regex: \"^\" + identifierRe + \"*\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"}\",\n            next: \"pop\"\n        }],\n        rstring: [{\n            token: \"string.end\",\n            regex: '\"',\n            next: \"start\"\n        }, {\n            token: \"invalid.illegal\",\n            regex: bidi\n        }, {\n            defaultToken: \"string\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(PrqlHighlightRules, TextHighlightRules);\n\nexports.PrqlHighlightRules = PrqlHighlightRules;\n"
  },
  {
    "path": "src/mode/puppet.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PuppetHighlightRules = require(\"./puppet_highlight_rules\").PuppetHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function () {\n    TextMode.call(this);\n    this.HighlightRules = PuppetHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\n\noop.inherits(Mode, TextMode);\n\n\n(function () {\n    this.lineCommentStart = \"#\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.$id = \"ace/mode/puppet\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/puppet_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar PuppetHighlightRules = function () {\n    this.$rules = {\n        \"start\": [\n            {\n                token: ['keyword.type.puppet', 'constant.class.puppet', 'keyword.inherits.puppet', 'constant.class.puppet'],\n                regex: \"^\\\\s*(class)(\\\\s+(?:[-_A-Za-z0-9\\\".]+::)*[-_A-Za-z0-9\\\".]+\\\\s*)(?:(inherits\\\\s*)(\\\\s+(?:[-_A-Za-z0-9\\\".]+::)*[-_A-Za-z0-9\\\".]+\\\\s*))?\"\n            },\n            {\n                token: ['storage.function.puppet', 'name.function.puppet', 'punctuation.lpar'],\n                regex: \"(^\\\\s*define)(\\\\s+[a-zA-Z0-9_:]+\\\\s*)(\\\\()\",\n                push:\n                    [{\n                        token: 'punctuation.rpar.puppet',\n                        regex: \"\\\\)\",\n                        next: 'pop'\n                    },\n                        {include: \"constants\"},\n                        {include: \"variable\"},\n                        {include: \"strings\"},\n                        {include: \"operators\"},\n                        {defaultToken: 'string'}]\n            },\n            {\n                token: [\"language.support.class\", \"keyword.operator\"],\n                regex: \"\\\\b([a-zA-Z_]+)(\\\\s+=>)\"\n            },\n            {\n                token: [\"exported.resource.puppet\", \"keyword.name.resource.puppet\", \"paren.lparen\"],\n                regex: \"(\\\\@\\\\@)?(\\\\s*[a-zA-Z_]*)(\\\\s*\\\\{)\"\n            },\n            {\n                token: \"qualified.variable.puppet\",\n                regex: \"(\\\\$([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*::[a-z0-9_][a-zA-Z0-9_]*)\"\n            },\n\n            {\n                token: \"singleline.comment.puppet\",\n                regex: '#(.)*$'\n            },\n            {\n                token: \"multiline.comment.begin.puppet\",\n                regex: '^\\\\s*\\\\/\\\\*',\n                push: \"blockComment\"\n            },\n            {\n                token: \"keyword.control.puppet\",\n                regex: \"\\\\b(case|if|unless|else|elsif|in|default:|and|or)\\\\s+(?!::)\"\n            },\n            {\n                token: \"keyword.control.puppet\",\n                regex: \"\\\\b(import|default|inherits|include|require|contain|node|application|consumes|environment|site|function|produces)\\\\b\"\n            },\n            {\n                token: \"support.function.puppet\",\n                regex: \"\\\\b(lest|str2bool|escape|gsub|Timestamp|Timespan|with|alert|crit|debug|notice|sprintf|split|step|strftime|slice|shellquote|type|sha1|defined|scanf|reverse_each|regsubst|return|emerg|reduce|err|failed|fail|versioncmp|file|generate|then|info|realize|search|tag|tagged|template|epp|warning|hiera_include|each|assert_type|binary_file|create_resources|dig|digest|filter|lookup|find_file|fqdn_rand|hiera_array|hiera_hash|inline_epp|inline_template|map|match|md5|new|next)\\\\b\"\n            },\n            {\n                token: \"constant.types.puppet\",\n                regex: \"\\\\b(String|File|Package|Service|Class|Integer|Array|Catalogentry|Variant|Boolean|Undef|Number|Hash|Float|Numeric|NotUndef|Callable|Optional|Any|Regexp|Sensitive|Sensitive.new|Type|Resource|Default|Enum|Scalar|Collection|Data|Pattern|Tuple|Struct)\\\\b\"\n            },\n\n            {\n                token: \"paren.lparen\",\n                regex: \"[[({]\"\n            },\n            {\n                token: \"paren.rparen\",\n                regex: \"[\\\\])}]\"\n            },\n            {include: \"variable\"},\n            {include: \"constants\"},\n            {include: \"strings\"},\n            {include: \"operators\"},\n            {\n                token: \"regexp.begin.string.puppet\",\n                regex: \"\\\\s*(\\\\/(\\\\S)+)\\\\/\"\n            }\n        ],\n        blockComment: [{\n            regex: \"\\\\*\\\\/\",\n            token: \"multiline.comment.end.puppet\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }],\n        \"constants\": [\n            {\n                token: \"constant.language.puppet\",\n                regex: \"\\\\b(false|true|running|stopped|installed|purged|latest|file|directory|held|undef|present|absent|link|mounted|unmounted)\\\\b\"\n            }\n        ],\n        \"variable\": [\n            {\n                token: \"variable.puppet\",\n                regex: \"(\\\\$[a-z0-9_\\{][a-zA-Z0-9_]*)\"\n            }\n        ],\n        \"strings\": [\n            {\n                token: \"punctuation.quote.puppet\",\n                regex: \"'\",\n                push:\n                    [{\n                        token: 'punctuation.quote.puppet',\n                        regex: \"'\",\n                        next: 'pop'\n                    },\n                        {include: \"escaped_chars\"},\n                        {defaultToken: 'string'}]\n            },\n            {\n                token: \"punctuation.quote.puppet\",\n                regex: '\"',\n                push:\n                    [{\n                        token: 'punctuation.quote.puppet',\n                        regex: '\"',\n                        next: 'pop'\n                    },\n                        {include: \"escaped_chars\"},\n                        {include: \"variable\"},\n                        {defaultToken: 'string'}]\n            }\n        ],\n        \"escaped_chars\": [\n            {\n                token: \"constant.escaped_char.puppet\",\n                regex: \"\\\\\\\\.\"\n            }\n        ],\n        \"operators\": [\n            {\n                token: \"keyword.operator\",\n                regex: \"\\\\+\\\\.|\\\\-\\\\.|\\\\*\\\\.|\\\\/\\\\.|#|;;|\\\\+|\\\\-|\\\\*|\\\\*\\\\*\\\\/|\\\\/\\\\/|%|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|<-|=|::|,\"\n            }\n        ]\n    };\n    this.normalizeRules();\n};\n\n\noop.inherits(PuppetHighlightRules, TextHighlightRules);\n\nexports.PuppetHighlightRules = PuppetHighlightRules;\n"
  },
  {
    "path": "src/mode/python.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar PythonHighlightRules = require(\"./python_highlight_rules\").PythonHighlightRules;\nvar PythonFoldMode = require(\"./folding/pythonic\").FoldMode;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = PythonHighlightRules;\n    this.foldingRules = new PythonFoldMode(\"\\\\:\");\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n    this.$pairQuotesAfter = {\n        \"'\": /[ruf]/i,\n        '\"': /[ruf]/i\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    var outdents = {\n        \"pass\": 1,\n        \"return\": 1,\n        \"raise\": 1,\n        \"break\": 1,\n        \"continue\": 1\n    };\n    \n    this.checkOutdent = function(state, line, input) {\n        if (input !== \"\\r\\n\" && input !== \"\\r\" && input !== \"\\n\")\n            return false;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n        \n        if (!tokens)\n            return false;\n        \n        // ignore trailing comments\n        do {\n            var last = tokens.pop();\n        } while (last && (last.type == \"comment\" || (last.type == \"text\" && last.value.match(/^\\s+$/))));\n        \n        if (!last)\n            return false;\n        \n        return (last.type == \"keyword\" && outdents[last.value]);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        // outdenting in python is slightly different because it always applies\n        // to the next line and only of a new line is inserted\n        \n        row += 1;\n        var indent = this.$getIndent(doc.getLine(row));\n        var tab = doc.getTabString();\n        if (indent.slice(-tab.length) == tab)\n            doc.remove(new Range(row, indent.length-tab.length, row, indent.length));\n    };\n\n    this.$id = \"ace/mode/python\";\n    this.snippetFileId = \"ace/snippets/python\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/python_highlight_rules.js",
    "content": "/*\n * TODO: python delimiters\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar PythonHighlightRules = function() {\n\n    var keywords = (\n        \"and|as|assert|break|class|continue|def|del|elif|else|except|exec|\" +\n        \"finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|\" +\n        \"raise|return|try|while|with|yield|async|await|nonlocal\"\n    );\n\n    var builtinConstants = (\n        \"True|False|None|NotImplemented|Ellipsis|__debug__\"\n    );\n\n    var builtinFunctions = (\n        \"abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|\" +\n        \"eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|\" +\n        \"binfile|bin|iter|property|tuple|bool|filter|len|range|type|bytearray|\" +\n        \"float|list|raw_input|unichr|callable|format|locals|reduce|unicode|\" +\n        \"chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|\" +\n        \"cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|\" +\n        \"__import__|complex|hash|min|apply|delattr|help|next|setattr|set|\" +\n        \"buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern|\" +\n        \"ascii|breakpoint|bytes\"\n    );\n\n    //var futureReserved = \"\";\n    var keywordMapper = this.createKeywordMapper({\n        \"invalid.deprecated\": \"debugger\",\n        \"support.function\": builtinFunctions,\n        \"variable.language\": \"self|cls\",\n        \"constant.language\": builtinConstants,\n        \"keyword\": keywords\n    }, \"identifier\");\n\n    var strPre = \"[uU]?\";\n    var strRawPre = \"[rR]\";\n    var strFormatPre = \"[fF]\";\n    var strRawFormatPre = \"(?:[rR][fF]|[fF][rR])\";\n    var decimalInteger = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    var octInteger = \"(?:0[oO]?[0-7]+)\";\n    var hexInteger = \"(?:0[xX][\\\\dA-Fa-f]+)\";\n    var binInteger = \"(?:0[bB][01]+)\";\n    var integer = \"(?:\" + decimalInteger + \"|\" + octInteger + \"|\" + hexInteger + \"|\" + binInteger + \")\";\n\n    var exponent = \"(?:[eE][+-]?\\\\d+)\";\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var exponentFloat = \"(?:(?:\" + pointFloat + \"|\" + intPart + \")\" + exponent + \")\";\n    var floatNumber = \"(?:\" + exponentFloat + \"|\" + pointFloat + \")\";\n\n    var stringEscape = \"\\\\\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\\\\\abfnrtv'\\\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"#.*$\"\n        }, {\n            token : \"string\",           // multi line \"\"\" string start\n            regex : strPre + '\"{3}',\n            next : \"qqstring3\"\n        }, {\n            token : \"string\",           // \" string\n            regex : strPre + '\"(?=.)',\n            next : \"qqstring\"\n        }, {\n            token : \"string\",           // multi line ''' string start\n            regex : strPre + \"'{3}\",\n            next : \"qstring3\"\n        }, {\n            token : \"string\",           // ' string\n            regex : strPre + \"'(?=.)\",\n            next : \"qstring\"\n        }, {\n            token: \"string\",\n            regex: strRawPre + '\"{3}',\n            next: \"rawqqstring3\"\n        }, {\n            token: \"string\", \n            regex: strRawPre + '\"(?=.)',\n            next: \"rawqqstring\"\n        }, {\n            token: \"string\",\n            regex: strRawPre + \"'{3}\",\n            next: \"rawqstring3\"\n        }, {\n            token: \"string\",\n            regex: strRawPre + \"'(?=.)\",\n            next: \"rawqstring\"\n        }, {\n            token: \"string\",\n            regex: strFormatPre + '\"{3}',\n            next: \"fqqstring3\"\n        }, {\n            token: \"string\",\n            regex: strFormatPre + '\"(?=.)',\n            next: \"fqqstring\"\n        }, {\n            token: \"string\",\n            regex: strFormatPre + \"'{3}\",\n            next: \"fqstring3\"\n        }, {\n            token: \"string\",\n            regex: strFormatPre + \"'(?=.)\",\n            next: \"fqstring\"\n        },{\n            token: \"string\",\n            regex: strRawFormatPre + '\"{3}',\n            next: \"rfqqstring3\"\n        }, {\n            token: \"string\",\n            regex: strRawFormatPre + '\"(?=.)',\n            next: \"rfqqstring\"\n        }, {\n            token: \"string\",\n            regex: strRawFormatPre + \"'{3}\",\n            next: \"rfqstring3\"\n        }, {\n            token: \"string\",\n            regex: strRawFormatPre + \"'(?=.)\",\n            next: \"rfqstring\"\n        }, {\n            token: \"keyword.operator\",\n            regex: \"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|%|@|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token: \"punctuation\",\n            regex: \",|:|;|\\\\->|\\\\+=|\\\\-=|\\\\*=|\\\\/=|\\\\/\\\\/=|%=|@=|&=|\\\\|=|^=|>>=|<<=|\\\\*\\\\*=\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"[\\\\[\\\\(\\\\{]\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"[\\\\]\\\\)\\\\}]\"\n        }, {\n            token: [\"keyword\", \"text\", \"entity.name.function\"],\n            regex: \"(def|class)(\\\\s+)([\\\\u00BF-\\\\u1FFF\\\\u2C00-\\\\uD7FF\\\\w]+)\"\n         }, {\n            token: \"text\",\n            regex: \"\\\\s+\"\n        }, {\n            include: \"constants\"\n        }],\n        \"qqstring3\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\", // multi line \"\"\" string end\n            regex: '\"{3}',\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"qstring3\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",  // multi line ''' string end\n            regex: \"'{3}\",\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"qqstring\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"qqstring\"\n        }, {\n            token: \"string\",\n            regex: '\"|$',\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"qstring\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"qstring\"\n        }, {\n            token: \"string\",\n            regex: \"'|$\",\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rawqqstring3\": [{\n            token: \"string\", // multi line \"\"\" string end\n            regex: '\"{3}',\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rawqstring3\": [{\n            token: \"string\",  // multi line ''' string end\n            regex: \"'{3}\",\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rawqqstring\": [{\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"rawqqstring\"\n        }, {\n            token: \"string\",\n            regex: '\"|$',\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rawqstring\": [{\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"rawqstring\"\n        }, {\n            token: \"string\",\n            regex: \"'|$\",\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"fqqstring3\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\", // multi line \"\"\" string end\n            regex: '\"{3}',\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"fqstring3\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",  // multi line ''' string end\n            regex: \"'{3}\",\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"fqqstring\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"fqqstring\"\n        }, {\n            token: \"string\",\n            regex: '\"|$',\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"fqstring\": [{\n            token: \"constant.language.escape\",\n            regex: stringEscape\n        }, {\n            token: \"string\",\n            regex: \"'|$\",\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rfqqstring3\": [{\n            token: \"string\", // multi line \"\"\" string end\n            regex: '\"{3}',\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rfqstring3\": [{\n            token: \"string\",  // multi line ''' string end\n            regex: \"'{3}\",\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rfqqstring\": [{\n            token: \"string\",\n            regex: \"\\\\\\\\$\",\n            next: \"rfqqstring\"\n        }, {\n            token: \"string\",\n            regex: '\"|$',\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rfqstring\": [{\n            token: \"string\",\n            regex: \"'|$\",\n            next: \"start\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"fqstringParRules\": [{//TODO: nested {}\n            token: \"paren.lparen\",\n            regex: \"[\\\\[\\\\(]\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"[\\\\]\\\\)]\"\n        }, {\n            token: \"string\",\n            regex: \"\\\\s+\"\n        }, {\n            token: \"string\",\n            regex: \"'[^']*'\"\n        }, {\n            token: \"string\",\n            regex: '\"[^\"]*\"'\n        }, {\n            token: \"function.support\",\n            regex: \"(!s|!r|!a)\"\n        }, {\n            include: \"constants\"\n        },{\n            token: 'paren.rparen',\n            regex: \"}\",\n            next: 'pop'\n        },{\n            token: 'paren.lparen',\n            regex: \"{\",\n            push: \"fqstringParRules\"\n        }],\n        \"constants\": [{\n            token: \"constant.numeric\", // imaginary\n            regex: \"(?:\" + floatNumber + \"|\\\\d+)[jJ]\\\\b\"\n        }, {\n            token: \"constant.numeric\", // float\n            regex: floatNumber\n        }, {\n            token: \"constant.numeric\", // long integer\n            regex: integer + \"[lL]\\\\b\"\n        }, {\n            token: \"constant.numeric\", // integer\n            regex: integer + \"\\\\b\"\n        }, {\n            token: [\"punctuation\", \"function.support\"],// method\n            regex: \"(\\\\.)([a-zA-Z_]+)\\\\b\"\n        }, {\n            token: keywordMapper,\n            regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(PythonHighlightRules, TextHighlightRules);\n\nexports.PythonHighlightRules = PythonHighlightRules;\n"
  },
  {
    "path": "src/mode/python_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar Mode = require(\"./python\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {    \n        this.mode = new Mode();\n    },\n\n    \"test: getTokenizer() (smoke test)\" : function() {\n        var tokenizer = this.mode.getTokenizer();\n\n        assert.ok(tokenizer instanceof Tokenizer);\n\n        var tokens = tokenizer.getLineTokens(\"'juhu'\", \"start\").tokens;\n        assert.equal(\"string\", tokens[0].type);\n    },\n\n    \"test: auto outdent after 'pass', 'return' and 'raise'\" : function() {\n        assert.ok(this.mode.checkOutdent(\"start\", \"        pass\", \"\\n\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        pass  \", \"\\n\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        return\", \"\\n\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        raise\", \"\\n\"));\n        assert.equal(this.mode.checkOutdent(\"start\", \"        raise\", \" \"), false);\n        assert.ok(this.mode.checkOutdent(\"start\", \"        pass # comment\", \"\\n\"));\n        assert.equal(this.mode.checkOutdent(\"start\", \"'juhu'\", \"\\n\"), false);\n    },\n    \n    \"test: auto outdent\" : function() {\n        var session = new EditSession([\"    if True:\", \"        pass\", \"        \"]);\n        this.mode.autoOutdent(\"start\", session, 1);\n        assert.equal(\"    \", session.getLine(2));\n    }\n\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/qml.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextMode = require(\"./text\").Mode;\n    var QmlHighlightRules = require(\"./qml_highlight_rules\").QmlHighlightRules;\n    var FoldMode = require(\"./folding/cstyle\").FoldMode;\n\n    var Mode = function() {\n        this.HighlightRules = QmlHighlightRules;\n        this.foldingRules = new FoldMode();\n        this.$behaviour = this.$defaultBehaviour;\n    };\n    oop.inherits(Mode, TextMode);\n\n    (function() {\n        this.lineCommentStart = \"//\";\n        this.blockComment = {start: \"/*\", end: \"*/\"};\n        this.$quotes = { '\"': '\"', \"'\": \"'\" };\n        this.$id = \"ace/mode/qml\";\n    }).call(Mode.prototype);\n\n    exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/qml_highlight_rules.js",
    "content": "\"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var QmlHighlightRules = function() {\n        // see: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects\n        var keywordMapper = this.createKeywordMapper({\n            \"variable.language\":\n                \"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|\"  + // Constructors\n                \"Namespace|QName|XML|XMLList|\"                                             + // E4X\n                \"ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|\"   +\n                \"Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|\"                    +\n                \"Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|\"   + // Errors\n                \"SyntaxError|TypeError|URIError|\"                                          +\n                \"decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|\" + // Non-constructor functions\n                \"isNaN|parseFloat|parseInt|\"                                               +\n                \"JSON|Math|\"                                                               + // Other\n                \"this|arguments|prototype|window|document\"                                 , // Pseudo\n            \"keyword\":\n                \"const|yield|import|get|set|async|await|\" +\n                \"break|case|catch|continue|default|delete|do|else|finally|for|function|\" +\n                \"if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|\" +\n                // invalid or reserved\n                \"__parent__|__count__|escape|unescape|with|__proto__|\" +\n                \"class|enum|extends|super|export|implements|private|public|interface|package|protected|static|\" +\n                // qml\n                \"readonly|string|int|bool|date|color|url|real|double|var|variant|\" +\n                \"height|width|anchors|parent|\" +\n                \"Abstract3DSeries|AbstractActionInput|AbstractAnimation|AbstractAxis|AbstractAxis3D|AbstractAxisInput|\" +\n                \"AbstractBarSeries|AbstractButton|AbstractClipAnimator|AbstractClipBlendNode|AbstractDataProxy|AbstractGraph3D|\" +\n                \"AbstractInputHandler3D|AbstractPhysicalDevice|AbstractRayCaster|AbstractSeries|AbstractSkeleton|AbstractTextureImage|\" +\n                \"Accelerometer|AccelerometerReading|Accessible|Action|ActionGroup|ActionInput|\" +\n                \"AdditiveClipBlend|Address|Affector|Age|AlphaCoverage|AlphaTest|\" +\n                \"Altimeter|AltimeterReading|AmbientLightReading|AmbientLightSensor|AmbientTemperatureReading|AmbientTemperatureSensor|\" +\n                \"AnalogAxisInput|AnchorAnimation|AnchorChanges|AngleDirection|AnimatedImage|AnimatedSprite|\" +\n                \"Animation|AnimationController|AnimationGroup|Animator|ApplicationWindow|ApplicationWindowStyle|\" +\n                \"AreaSeries|Armature|AttenuationModelInverse|AttenuationModelLinear|Attractor|Attribute|\" +\n                \"Audio|AudioCategory|AudioEngine|AudioListener|AudioSample|AuthenticationDialogRequest|\" +\n                \"Axis|AxisAccumulator|AxisSetting|BackspaceKey|Bar3DSeries|BarCategoryAxis|\" +\n                \"BarDataProxy|BarSeries|BarSet|Bars3D|BaseKey|Behavior|\" +\n                \"Binding|Blend|BlendEquation|BlendEquationArguments|BlendedClipAnimator|BlitFramebuffer|\" +\n                \"BluetoothDiscoveryModel|BluetoothService|BluetoothSocket|BorderImage|BorderImageMesh|BoxPlotSeries|\" +\n                \"BoxSet|BrightnessContrast|Buffer|BusyIndicator|BusyIndicatorStyle|Button|\" +\n                \"ButtonAxisInput|ButtonGroup|ButtonStyle|Calendar|CalendarStyle|Camera|\" +\n                \"Camera3D|CameraCapabilities|CameraCapture|CameraExposure|CameraFlash|CameraFocus|\" +\n                \"CameraImageProcessing|CameraLens|CameraRecorder|CameraSelector|CandlestickSeries|CandlestickSet|\" +\n                \"Canvas|Canvas3D|Canvas3DAbstractObject|Canvas3DActiveInfo|Canvas3DBuffer|Canvas3DContextAttributes|\" +\n                \"Canvas3DFrameBuffer|Canvas3DProgram|Canvas3DRenderBuffer|Canvas3DShader|Canvas3DShaderPrecisionFormat|Canvas3DTexture|\" +\n                \"Canvas3DTextureProvider|Canvas3DUniformLocation|CanvasGradient|CanvasImageData|CanvasPixelArray|Category|\" +\n                \"CategoryAxis|CategoryAxis3D|CategoryModel|CategoryRange|ChangeLanguageKey|ChartView|\" +\n                \"CheckBox|CheckBoxStyle|CheckDelegate|CircularGauge|CircularGaugeStyle|ClearBuffers|\" +\n                \"ClipAnimator|ClipPlane|CloseEvent|ColorAnimation|ColorDialog|ColorDialogRequest|\" +\n                \"ColorGradient|ColorGradientStop|ColorMask|ColorOverlay|Colorize|Column|\" +\n                \"ColumnLayout|ComboBox|ComboBoxStyle|Compass|CompassReading|Component|Component3D|\" +\n                \"ComputeCommand|ConeGeometry|ConeMesh|ConicalGradient|Connections|ContactDetail|\" +\n                \"ContactDetails|Container|Context2D|Context3D|ContextMenuRequest|Control|\" +\n                \"CoordinateAnimation|CuboidGeometry|CuboidMesh|CullFace|CumulativeDirection|\" +\n                \"Custom3DItem|Custom3DLabel|Custom3DVolume|CustomParticle|CylinderGeometry|CylinderMesh|\" +\n                \"Date|DateTimeAxis|DelayButton|DelayButtonStyle|DelegateChoice|DelegateChooser|DelegateModel|\" +\n                \"DelegateModelGroup|DepthTest|Desaturate|Dial|DialStyle|Dialog|DialogButtonBox|DiffuseMapMaterial|\" +\n                \"DiffuseSpecularMapMaterial|DiffuseSpecularMaterial|Direction|DirectionalBlur|DirectionalLight|DispatchCompute|\" +\n                \"Displace|DistanceReading|DistanceSensor|Dithering|DoubleValidator|Drag|DragEvent|DragHandler|Drawer|DropArea|\" +\n                \"DropShadow|DwmFeatures|DynamicParameter|EditorialModel|Effect|EllipseShape|Emitter|EnterKey|EnterKeyAction|\" +\n                \"Entity|EntityLoader|EnvironmentLight|EventConnection|EventPoint|EventTouchPoint|ExclusiveGroup|ExtendedAttributes|\" +\n                \"ExtrudedTextGeometry|ExtrudedTextMesh|FastBlur|FileDialog|FileDialogRequest|FillerKey|FilterKey|FinalState|\" +\n                \"FirstPersonCameraController|Flickable|Flipable|Flow|FocusScope|FolderListModel|FontDialog|FontLoader|\" +\n                \"FontMetrics|FormValidationMessageRequest|ForwardRenderer|Frame|FrameAction|FrameGraphNode|Friction|\" +\n                \"FrontFace|FrustumCulling|FullScreenRequest|GLStateDumpExt|GammaAdjust|Gauge|GaugeStyle|GaussianBlur|\" +\n                \"GeocodeModel|Geometry|GeometryRenderer|GestureEvent|Glow|GoochMaterial|Gradient|GradientStop|GraphicsApiFilter|\" +\n                \"GraphicsInfo|Gravity|Grid|GridLayout|GridMesh|GridView|GroupBox|GroupGoal|Gyroscope|GyroscopeReading|HBarModelMapper|\" +\n                \"HBoxPlotModelMapper|HCandlestickModelMapper|HPieModelMapper|HXYModelMapper|HandlerPoint|HandwritingInputPanel|\" +\n                \"HandwritingModeKey|HeightMapSurfaceDataProxy|HideKeyboardKey|HistoryState|HolsterReading|HolsterSensor|HorizontalBarSeries|\" +\n                \"|HorizontalPercentBarSeries|HorizontalStackedBarSeries|HoverHandler|HueSaturation|HumidityReading|HumiditySensor|\" +\n                \"IRProximityReading|IRProximitySensor|Icon|Image|ImageModel|ImageParticle|InnerShadow|InputChord|InputContext|InputEngine|\" +\n                \"InputHandler3D|InputMethod|InputModeKey|InputPanel|InputSequence|InputSettings|Instantiator|IntValidator|InvokedServices|\" +\n                \"Item|ItemDelegate|ItemGrabResult|ItemModelBarDataProxy|ItemModelScatterDataProxy|ItemModelSurfaceDataProxy|ItemParticle|\" +\n                \"ItemSelectionModel|IviApplication|IviSurface|JavaScriptDialogRequest|Joint|JumpList|JumpListCategory|JumpListDestination|\" +\n                \"JumpListLink|JumpListSeparator|Key|KeyEvent|KeyIcon|KeyNavigation|KeyPanel|KeyboardColumn|KeyboardDevice|KeyboardHandler|\" +\n                \"KeyboardLayout|KeyboardLayoutLoader|KeyboardRow|KeyboardStyle|KeyframeAnimation|Keys|Label|Layer|LayerFilter|Layout|\" +\n                \"LayoutMirroring|Legend|LerpBlend|LevelAdjust|LevelOfDetail|LevelOfDetailBoundingSphere|LevelOfDetailLoader|\" +\n                \"LevelOfDetailSwitch|LidReading|LidSensor|Light|Light3D|LightReading|LightSensor|LineSeries|LineShape|LineWidth|\" +\n                \"LinearGradient|ListElement|ListModel|ListView|Loader|Locale|Location|LogValueAxis|LogValueAxis3DFormatter|LoggingCategory|\" +\n                \"LogicalDevice|Magnetometer|MagnetometerReading|Map|MapCircle|MapCircleObject|MapCopyrightNotice|MapGestureArea|MapIconObject|\" +\n                \"MapItemGroup|MapItemView|MapObjectView|MapParameter|MapPinchEvent|MapPolygon|MapPolygonObject|MapPolyline|MapPolylineObject|\" +\n                \"MapQuickItem|MapRectangle|MapRoute|MapRouteObject|MapType|Margins|MaskShape|MaskedBlur|Material|Matrix4x4|MediaPlayer|\" +\n                \"MemoryBarrier|Menu|MenuBar|MenuBarItem|MenuBarStyle|MenuItem|MenuSeparator|MenuStyle|Mesh|MessageDialog|ModeKey|MorphTarget|\" +\n                \"MorphingAnimation|MouseArea|MouseDevice|MouseEvent|MouseHandler|MultiPointHandler|MultiPointTouchArea|MultiSampleAntiAliasing|\" +\n                \"Navigator|NdefFilter|NdefMimeRecord|NdefRecord|NdefTextRecord|NdefUriRecord|NearField|NoDepthMask|NoDraw|Node|NodeInstantiator|\" +\n                \"NormalDiffuseMapAlphaMaterial|NormalDiffuseMapMaterial|NormalDiffuseSpecularMapMaterial|Number|NumberAnimation|NumberKey|Object3D|\" +\n                \"ObjectModel|ObjectPicker|OpacityAnimator|OpacityMask|OpenGLInfo|OrbitCameraController|OrientationReading|OrientationSensor|Overlay|\" +\n                \"Package|Page|PageIndicator|Pane|ParallelAnimation|Parameter|ParentAnimation|ParentChange|Particle|ParticleGroup|ParticlePainter|\" +\n                \"ParticleSystem|Path|PathAngleArc|PathAnimation|PathArc|PathAttribute|PathCubic|PathCurve|PathElement|PathInterpolator|PathLine|\" +\n                \"PathMove|PathPercent|PathQuad|PathSvg|PathView|PauseAnimation|PerVertexColorMaterial|PercentBarSeries|PhongAlphaMaterial|\" +\n                \"PhongMaterial|PickEvent|PickLineEvent|PickPointEvent|PickTriangleEvent|PickingSettings|Picture|PieMenu|PieMenuStyle|PieSeries|\" +\n                \"PieSlice|PinchArea|PinchEvent|PinchHandler|Place|PlaceAttribute|PlaceSearchModel|PlaceSearchSuggestionModel|PlaneGeometry|\" +\n                \"PlaneMesh|PlayVariation|Playlist|PlaylistItem|Plugin|PluginParameter|PointDirection|PointHandler|PointLight|PointSize|\" +\n                \"PointerDevice|PointerDeviceHandler|PointerEvent|PointerHandler|PolarChartView|PolygonOffset|Popup|Position|PositionSource|\" +\n                \"Positioner|PressureReading|PressureSensor|Product|ProgressBar|ProgressBarStyle|PropertyAction|PropertyAnimation|PropertyChanges|\" +\n                \"ProximityFilter|ProximityReading|ProximitySensor|QAbstractState|QAbstractTransition|QSignalTransition|\" +\n                \"QVirtualKeyboardSelectionListModel|Qt|QtMultimedia|QtObject|QtPositioning|QuaternionAnimation|QuotaRequest|RadialBlur|\" +\n                \"RadialGradient|Radio|RadioButton|RadioButtonStyle|RadioData|RadioDelegate|RangeSlider|Ratings|RayCaster|Rectangle|\" +\n                \"RectangleShape|RectangularGlow|RecursiveBlur|RegExpValidator|RegisterProtocolHandlerRequest|RenderCapture|\" +\n                \"RenderCaptureReply|RenderPass|RenderPassFilter|RenderSettings|RenderState|RenderStateSet|RenderSurfaceSelector|\" +\n                \"RenderTarget|RenderTargetOutput|RenderTargetSelector|Repeater|ReviewModel|Rotation|RotationAnimation|RotationAnimator|\" +\n                \"RotationReading|RotationSensor|RoundButton|Route|RouteLeg|RouteManeuver|RouteModel|RouteQuery|RouteSegment|Row|\" +\n                \"RowLayout|Scale|ScaleAnimator|Scatter3D|Scatter3DSeries|ScatterDataProxy|ScatterSeries|Scene2D|Scene3D|SceneLoader|\" +\n                \"ScissorTest|Screen|ScreenRayCaster|ScriptAction|ScrollBar|ScrollIndicator|ScrollView|ScrollViewStyle|ScxmlStateMachine|\" +\n                \"SeamlessCubemap|SelectionListItem|Sensor|SensorGesture|SensorGlobal|SensorReading|SequentialAnimation|Settings|\" +\n                \"SettingsStore|ShaderEffect|ShaderEffectSource|ShaderProgram|ShaderProgramBuilder|Shape|ShellSurface|ShellSurfaceItem|\" +\n                \"ShiftHandler|ShiftKey|Shortcut|SignalSpy|SignalTransition|SinglePointHandler|Skeleton|SkeletonLoader|Slider|SliderStyle|\" +\n                \"SmoothedAnimation|SortPolicy|Sound|SoundEffect|SoundInstance|SpaceKey|SphereGeometry|SphereMesh|SpinBox|SpinBoxStyle|\" +\n                \"SplineSeries|SplitView|SpotLight|SpringAnimation|Sprite|SpriteGoal|SpriteSequence|Stack|StackLayout|StackView|\" +\n                \"StackViewDelegate|StackedBarSeries|State|StateChangeScript|StateGroup|StateMachine|StateMachineLoader|StatusBar|\" +\n                \"StatusBarStyle|StatusIndicator|StatusIndicatorStyle|StencilMask|StencilOperation|StencilOperationArguments|StencilTest|\" +\n                \"StencilTestArguments|Store|String|Supplier|Surface3D|Surface3DSeries|SurfaceDataProxy|SwipeDelegate|SwipeView|Switch|\" +\n                \"SwitchDelegate|SwitchStyle|SymbolModeKey|SystemPalette|Tab|TabBar|TabButton|TabView|TabViewStyle|TableView|TableViewColumn|\" +\n                \"TableViewStyle|TapHandler|TapReading|TapSensor|TargetDirection|TaskbarButton|Technique|TechniqueFilter|TestCase|Text|TextArea|\" +\n                \"TextAreaStyle|TextEdit|TextField|TextFieldStyle|TextInput|TextMetrics|TextureImage|TextureImageFactory|Theme3D|ThemeColor|\" +\n                \"ThresholdMask|ThumbnailToolBar|ThumbnailToolButton|TiltReading|TiltSensor|TimeoutTransition|Timer|ToggleButton|\" +\n                \"ToggleButtonStyle|ToolBar|ToolBarStyle|ToolButton|ToolSeparator|ToolTip|Torch|TorusGeometry|TorusMesh|TouchEventSequence|\" +\n                \"TouchInputHandler3D|TouchPoint|Trace|TraceCanvas|TraceInputArea|TraceInputKey|TraceInputKeyPanel|TrailEmitter|Transaction|\" +\n                \"Transform|Transition|Translate|TreeView|TreeViewStyle|Tumbler|TumblerColumn|TumblerStyle|Turbulence|UniformAnimator|User|\" +\n                \"VBarModelMapper|VBoxPlotModelMapper|VCandlestickModelMapper|VPieModelMapper|VXYModelMapper|ValueAxis|ValueAxis3D|\" +\n                \"ValueAxis3DFormatter|Vector3dAnimation|VertexBlendAnimation|Video|VideoOutput|ViewTransition|Viewport|\" +\n                \"VirtualKeyboardSettings|Wander|WavefrontMesh|WaylandClient|WaylandCompositor|WaylandHardwareLayer|\" +\n                \"WaylandOutput|WaylandQuickItem|WaylandSeat|WaylandSurface|WaylandView|Waypoint|\" +\n                \"WebChannel|WebEngine|WebEngineAction|WebEngineCertificateError|WebEngineDownloadItem|WebEngineHistory|\" +\n                \"WebEngineHistoryListModel|WebEngineLoadRequest|WebEngineNavigationRequest|WebEngineNewViewRequest|WebEngineProfile|WebEngineScript|\" +\n                \"WebEngineSettings|WebEngineView|WebSocket|WebSocketServer|WebView|WebViewLoadRequest|\" +\n                \"WheelEvent|Window|WlShell|WlShellSurface|WorkerScript|XAnimator|\" +\n                \"XYPoint|XYSeries|XdgDecorationManagerV1|XdgPopup|XdgPopupV5|XdgPopupV6|\" +\n                \"XdgShell|XdgShellV5|XdgShellV6|XdgSurface|XdgSurfaceV5|XdgSurfaceV6|\" +\n                \"XdgToplevel|XdgToplevelV6|XmlListModel|XmlRole|YAnimator|ZoomBlur\",\n            \"storage.type\":\n                \"const|let|var|function|\" + // js\n                \"property|\", // qml\n            \"constant.language\":\n                \"null|Infinity|NaN|undefined\",\n            \"support.function\":\n                \"print|console\\\\.log\",\n            \"constant.language.boolean\": \"true|false\"\n        }, \"identifier\");\n\n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n        this.$rules = {\n            \"start\" : [\n                {\n                    token : \"string\", // single line\n                    regex : '\"',\n                    next  : \"string\"\n                }, {\n                    token : \"constant.numeric\", // hex\n                    regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n                }, {\n                    token : \"constant.numeric\", // float\n                    regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n                }, {\n                    token : \"constant.language.boolean\",\n                    regex : \"(?:true|false)\\\\b\"\n                }, {\n                    token : \"text\",\n                    regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n                }, {\n                    token : \"comment\",\n                    regex : \"\\\\/\\\\/.*$\"\n                }, {\n                    token : \"comment.start\",\n                    regex : \"\\\\/\\\\*\",\n                    next  : \"comment\"\n                }, {\n                    token : \"paren.lparen\",\n                    regex : \"[[({]\"\n                }, {\n                    token : \"paren.rparen\",\n                    regex : \"[\\\\])}]\"\n                }, {\n                    token : \"text\",\n                    regex : \"\\\\s+\"\n                }, {\n                    token : keywordMapper,\n                    regex : \"\\\\b\\\\w+\\\\b\"\n                }\n            ],\n            \"string\" : [\n                {\n                    token : \"constant.language.escape\",\n                    regex : /\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[\"\\\\\\/bfnrt])/\n                }, {\n                    token : \"string\",\n                    regex : '\"|$',\n                    next  : \"start\"\n                }, {\n                    defaultToken : \"string\"\n                }\n            ],\n            \"comment\" : [\n                {\n                    token : \"comment.end\",\n                    regex : \"\\\\*\\\\/\",\n                    next  : \"start\"\n                }, {\n                    defaultToken: \"comment\"\n                }\n            ]\n        };\n\n    };\n\n    oop.inherits(QmlHighlightRules, TextHighlightRules);\n\n    exports.QmlHighlightRules = QmlHighlightRules;\n"
  },
  {
    "path": "src/mode/r.js",
    "content": "/*\n * r.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n   \"use strict\";\n\n   var unicode = require(\"../unicode\");\n   var Range = require(\"../range\").Range;\n   var oop = require(\"../lib/oop\");\n   var TextMode = require(\"./text\").Mode;\n   var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n   var RHighlightRules = require(\"./r_highlight_rules\").RHighlightRules;\n   var MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\n   var Mode = function(){\n      this.HighlightRules = RHighlightRules;\n      this.$outdent = new MatchingBraceOutdent();\n      this.$behaviour = this.$defaultBehaviour;\n   };\n   oop.inherits(Mode, TextMode);\n\n   (function() {\n      this.lineCommentStart = \"#\";\n      // todo import codeModel from RStudio\n      this.tokenRe = new RegExp(\"^[\" + unicode.wordChars + \"._]+\", \"g\");\n\n      this.nonTokenRe = new RegExp(\"^(?:[^\" + unicode.wordChars + \"._]|\\s])+\", \"g\");\n\n      /*this.$complements = {\n               \"(\": \")\",\n               \"[\": \"]\",\n               '\"': '\"',\n               \"'\": \"'\",\n               \"{\": \"}\"\n            };\n      this.$reOpen = /^[([\"'{]$/;\n      this.$reClose = /^[)\\]\"'}]$/;\n\n      this.getNextLineIndent = function(state, line, tab, tabSize, row)\n      {\n         return this.codeModel.getNextLineIndent(row, line, state, tab, tabSize);\n      };\n\n      this.allowAutoInsert = this.smartAllowAutoInsert;\n\n      this.checkOutdent = function(state, line, input) {\n         if (! /^\\s+$/.test(line))\n            return false;\n\n         return /^\\s*[\\{\\}\\)]/.test(input);\n      };\n\n      this.getIndentForOpenBrace = function(openBracePos)\n      {\n         return this.codeModel.getIndentForOpenBrace(openBracePos);\n      };\n\n      this.autoOutdent = function(state, doc, row) {\n         if (row == 0)\n            return 0;\n\n         var line = doc.getLine(row);\n\n         var match = line.match(/^(\\s*[\\}\\)])/);\n         if (match)\n         {\n            var column = match[1].length;\n            var openBracePos = doc.findMatchingBracket({row: row, column: column});\n\n            if (!openBracePos || openBracePos.row == row) return 0;\n\n            var indent = this.codeModel.getIndentForOpenBrace(openBracePos);\n            doc.replace(new Range(row, 0, row, column-1), indent);\n         }\n\n         match = line.match(/^(\\s*\\{)/);\n         if (match)\n         {\n            var column = match[1].length;\n            var indent = this.codeModel.getBraceIndent(row-1);\n            doc.replace(new Range(row, 0, row, column-1), indent);\n         }\n      };\n\n      this.$getIndent = function(line) {\n         var match = line.match(/^(\\s+)/);\n         if (match) {\n            return match[1];\n         }\n\n         return \"\";\n      };\n\n      this.transformAction = function(state, action, editor, session, text) {\n         if (action === 'insertion' && text === \"\\n\") {\n\n            // If newline in a doxygen comment, continue the comment\n            var pos = editor.getSelectionRange().start;\n            var match = /^((\\s*#+')\\s*)/.exec(session.doc.getLine(pos.row));\n            if (match && editor.getSelectionRange().start.column >= match[2].length) {\n               return {text: \"\\n\" + match[1]};\n            }\n         }\n         return false;\n      };*/\n       this.$id = \"ace/mode/r\";\n       this.snippetFileId = \"ace/snippets/r\";\n   }).call(Mode.prototype);\n   exports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/r_highlight_rules.js",
    "content": "/*\n * r_highlight_rules.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\n   var oop = require(\"../lib/oop\");\n   var lang = require(\"../lib/lang\");\n   var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n   var TexHighlightRules = require(\"./tex_highlight_rules\").TexHighlightRules;\n\n   var RHighlightRules = function()\n   {\n\n      var keywords = lang.arrayToMap(\n            (\"function|if|in|break|next|repeat|else|for|return|switch|while|try|tryCatch|stop|warning|require|library|attach|detach|source|setMethod|setGeneric|setGroupGeneric|setClass\")\n                  .split(\"|\")\n            );\n\n      var buildinConstants = lang.arrayToMap(\n            (\"NULL|NA|TRUE|FALSE|T|F|Inf|NaN|NA_integer_|NA_real_|NA_character_|\" +\n             \"NA_complex_\").split(\"|\")\n            );\n\n      // regexp must not have capturing parentheses. Use (?:) instead.\n      // regexps are ordered -> the first match is used\n\n      this.$rules = {\n         \"start\" : [\n            {\n               // Roxygen\n               token : \"comment.sectionhead\",\n               regex : \"#+(?!').*(?:----|====|####)\\\\s*$\"\n            },\n            {\n               // Roxygen\n               token : \"comment\",\n               regex : \"#+'\",\n               next : \"rd-start\"\n            },\n            {\n               token : \"comment\",\n               regex : \"#.*$\"\n            },\n            {\n               token : \"string\", // multi line string start\n               regex : '[\"]',\n               next : \"qqstring\"\n            },\n            {\n               token : \"string\", // multi line string start\n               regex : \"[']\",\n               next : \"qstring\"\n            },\n            {\n               token : \"constant.numeric\", // hex\n               regex : \"0[xX][0-9a-fA-F]+[Li]?\\\\b\"\n            },\n            {\n               token : \"constant.numeric\", // explicit integer\n               regex : \"\\\\d+L\\\\b\"\n            },\n            {\n               token : \"constant.numeric\", // number\n               regex : \"\\\\d+(?:\\\\.\\\\d*)?(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\"\n            },\n            {\n               token : \"constant.numeric\", // number with leading decimal\n               regex : \"\\\\.\\\\d+(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\"\n            },\n            {\n               token : \"constant.language.boolean\",\n               regex : \"(?:TRUE|FALSE|T|F)\\\\b\"\n            },\n            {\n               token : \"identifier\",\n               regex : \"`.*?`\"\n            },\n            {\n               onMatch : function(value) {\n                  if (keywords[value])\n                     return \"keyword\";\n                  else if (buildinConstants[value])\n                     return \"constant.language\";\n                  else if (value == '...' || value.match(/^\\.\\.\\d+$/))\n                     return \"variable.language\";\n                  else\n                     return \"identifier\";\n               },\n               regex : \"[a-zA-Z.][a-zA-Z0-9._]*\\\\b\"\n            },\n            {\n               token : \"keyword.operator\",\n               regex : \"%%|>=|<=|==|!=|\\\\->|<\\\\-|\\\\|\\\\||&&|=|\\\\+|\\\\-|\\\\*|/|\\\\^|>|<|!|&|\\\\||~|\\\\$|:\"\n            },\n            {\n               token : \"keyword.operator\", // infix operators\n               regex : \"%.*?%\"\n            },\n            {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n               regex : \"[[({]\"\n            },\n            {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n               regex : \"[\\\\])}]\"\n            },\n            {\n               token : \"text\",\n               regex : \"\\\\s+\"\n            }\n         ],\n         \"qqstring\" : [\n            {\n               token : \"string\",\n               regex : '(?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?\"',\n               next : \"start\"\n            },\n            {\n               token : \"string\",\n               regex : '.+'\n            }\n         ],\n         \"qstring\" : [\n            {\n               token : \"string\",\n               regex : \"(?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?'\",\n               next : \"start\"\n            },\n            {\n               token : \"string\",\n               regex : '.+'\n            }\n         ]\n      };\n\n      var rdRules = new TexHighlightRules(\"comment\").getRules();\n\n      // Make all embedded TeX virtual-comment so they don't interfere with\n      // auto-indent.\n      for (var i = 0; i < rdRules[\"start\"].length; i++) {\n         rdRules[\"start\"][i].token += \".virtual-comment\";\n      }\n\n      this.addRules(rdRules, \"rd-\");\n      this.$rules[\"rd-start\"].unshift({\n          token: \"text\",\n          regex: \"^\",\n          next: \"start\"\n      });\n      this.$rules[\"rd-start\"].unshift({\n         token : \"keyword\",\n         regex : \"@(?!@)[^ ]*\"\n      });\n      this.$rules[\"rd-start\"].unshift({\n         token : \"comment\",\n         regex : \"@@\"\n      });\n      this.$rules[\"rd-start\"].push({\n         token : \"comment\",\n         regex : \"[^%\\\\\\\\[({\\\\])}]+\"\n      });\n   };\n\n   oop.inherits(RHighlightRules, TextHighlightRules);\n\n   exports.RHighlightRules = RHighlightRules;\n"
  },
  {
    "path": "src/mode/raku.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RakuHighlightRules = require(\"./raku_highlight_rules\").RakuHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = RakuHighlightRules;\n\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new CStyleFoldMode({start: \"^=(begin)\\\\b\", end: \"^=(end)\\\\b\"});\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n    this.blockComment = [\n        {start: \"=begin\", end: \"=end\", lineStartOnly: true},\n        {start: \"=item\", end: \"=end\", lineStartOnly: true}\n    ];\n\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/raku\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/raku_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar RakuHighlightRules = function() {\n\n    var keywords = (\n        \"my|our|class|role|grammar|is|does|sub|method|submethod|try|\" +\n        \"default|when|if|elsif|else|unless|with|orwith|without|for|given|proceed|\" +\n        \"succeed|loop|while|until|repeat|module|use|need|import|require|unit|\" +\n        \"constant|enum|multi|return|has|token|rule|make|made|proto|state|augment|\" +\n        \"but|anon|supersede|let|subset|gather|returns|return-rw|temp|\" +\n        \"BEGIN|CHECK|INIT|END|CLOSE|ENTER|LEAVE|KEEP|UNDO|PRE|POST|FIRST|NEXT|LAST|CATCH|CONTROL|QUIT|DOC\"\n    );\n\n    var types = (\n        \"Any|Array|Associative|AST|atomicint|Attribute|Backtrace|Backtrace::Frame|\" +\n        \"Bag|Baggy|BagHash|Blob|Block|Bool|Buf|Callable|CallFrame|Cancellation|\" +\n        \"Capture|Channel|Code|compiler|Complex|ComplexStr|Cool|CurrentThreadScheduler|\" +\n        \"Cursor|Date|Dateish|DateTime|Distro|Duration|Encoding|Exception|Failure|\"+\n        \"FatRat|Grammar|Hash|HyperWhatever|Instant|Int|IntStr|IO|IO::ArgFiles|\"+\n        \"IO::CatHandle|IO::Handle|IO::Notification|IO::Path|IO::Path::Cygwin|\"+\n        \"IO::Path::QNX|IO::Path::Unix|IO::Path::Win32|IO::Pipe|IO::Socket|\"+\n        \"IO::Socket::Async|IO::Socket::INET|IO::Spec|IO::Spec::Cygwin|IO::Spec::QNX|\"+\n        \"IO::Spec::Unix|IO::Spec::Win32|IO::Special|Iterable|Iterator|Junction|Kernel|\"+\n        \"Label|List|Lock|Lock::Async|Macro|Map|Match|Metamodel::AttributeContainer|\"+\n        \"Metamodel::C3MRO|Metamodel::ClassHOW|Metamodel::EnumHOW|Metamodel::Finalization|\"+\n        \"Metamodel::MethodContainer|Metamodel::MROBasedMethodDispatch|Metamodel::MultipleInheritance|\"+\n        \"Metamodel::Naming|Metamodel::Primitives|Metamodel::PrivateMethodContainer|\"+\n        \"Metamodel::RoleContainer|Metamodel::Trusting|Method|Mix|MixHash|Mixy|Mu|\"+\n        \"NFC|NFD|NFKC|NFKD|Nil|Num|Numeric|NumStr|ObjAt|Order|Pair|Parameter|Perl|\"+\n        \"Pod::Block|Pod::Block::Code|Pod::Block::Comment|Pod::Block::Declarator|\"+\n        \"Pod::Block::Named|Pod::Block::Para|Pod::Block::Table|Pod::Heading|Pod::Item|\"+\n        \"Positional|PositionalBindFailover|Proc|Proc::Async|Promise|Proxy|PseudoStash|\"+\n        \"Raku|QuantHash|Range|Rat|Rational|RatStr|Real|Regex|Routine|Scalar|Scheduler|\"+\n        \"Semaphore|Seq|Set|SetHash|Setty|Signature|Slip|Stash|Str|StrDistance|Stringy|\"+\n        \"Sub|Submethod|Supplier|Supplier::Preserving|Supply|Systemic|Tap|Telemetry|\"+\n        \"Telemetry::Instrument::Thread|Telemetry::Instrument::Usage|Telemetry::Period|\"+\n        \"Telemetry::Sampler|Thread|ThreadPoolScheduler|UInt|Uni|utf8|Variable|Version|\"+\n        \"VM|Whatever|WhateverCode|WrapHandle|int|uint|num|str|\"+\n        \"int8|int16|int32|int64|uint8|uint16|uint32|uint64|long|longlong|num32|num64|size_t|bool|CArray|Pointer|\"+\n\t\t\"Backtrace|Backtrace::Frame|Exception|Failure|X::AdHoc|X::Anon::Augment|X::Anon::Multi|\"+\n\t\t\"X::Assignment::RO|X::Attribute::NoPackage|X::Attribute::Package|X::Attribute::Undeclared|\"+\n\t\t\"X::Augment::NoSuchType|X::Bind|X::Bind::NativeType|X::Bind::Slice|X::Caller::NotDynamic|\"+\n\t\t\"X::Channel::ReceiveOnClosed|X::Channel::SendOnClosed|X::Comp|X::Composition::NotComposable|\"+\n\t\t\"X::Constructor::Positional|X::ControlFlow|X::ControlFlow::Return|X::DateTime::TimezoneClash|\"+\n\t\t\"X::Declaration::Scope|X::Declaration::Scope::Multi|X::Does::TypeObject|X::Eval::NoSuchLang|\"+\n\t\t\"X::Export::NameClash|X::IO|X::IO::Chdir|X::IO::Chmod|X::IO::Copy|X::IO::Cwd|X::IO::Dir|\"+\n\t\t\"X::IO::DoesNotExist|X::IO::Link|X::IO::Mkdir|X::IO::Move|X::IO::Rename|X::IO::Rmdir|X::IO::Symlink|\"+\n\t\t\"X::IO::Unlink|X::Inheritance::NotComposed|X::Inheritance::Unsupported|X::Method::InvalidQualifier|\"+\n\t\t\"X::Method::NotFound|X::Method::Private::Permission|X::Method::Private::Unqualified|\"+\n\t\t\"X::Mixin::NotComposable|X::NYI|X::NoDispatcher|X::Numeric::Real|X::OS|X::Obsolete|X::OutOfRange|\"+\n\t\t\"X::Package::Stubbed|X::Parameter::Default|X::Parameter::MultipleTypeConstraints|\"+\n\t\t\"X::Parameter::Placeholder|X::Parameter::Twigil|X::Parameter::WrongOrder|X::Phaser::Multiple|\"+\n\t\t\"X::Phaser::PrePost|X::Placeholder::Block|X::Placeholder::Mainline|X::Pod|X::Proc::Async|\"+\n\t\t\"X::Proc::Async::AlreadyStarted|X::Proc::Async::CharsOrBytes|X::Proc::Async::MustBeStarted|\"+\n\t\t\"X::Proc::Async::OpenForWriting|X::Proc::Async::TapBeforeSpawn|X::Proc::Unsuccessful|\"+\n\t\t\"X::Promise::CauseOnlyValidOnBroken|X::Promise::Vowed|X::Redeclaration|X::Role::Initialization|\"+\n\t\t\"X::Seq::Consumed|X::Sequence::Deduction|X::Signature::NameClash|X::Signature::Placeholder|\"+\n\t\t\"X::Str::Numeric|X::StubCode|X::Syntax|X::Syntax::Augment::WithoutMonkeyTyping|\"+\n\t\t\"X::Syntax::Comment::Embedded|X::Syntax::Confused|X::Syntax::InfixInTermPosition|\"+\n\t\t\"X::Syntax::Malformed|X::Syntax::Missing|X::Syntax::NegatedPair|X::Syntax::NoSelf|\"+\n\t\t\"X::Syntax::Number::RadixOutOfRange|X::Syntax::P5|X::Syntax::Regex::Adverb|\"+\n\t\t\"X::Syntax::Regex::SolitaryQuantifier|X::Syntax::Reserved|X::Syntax::Self::WithoutObject|\"+\n\t\t\"X::Syntax::Signature::InvocantMarker|X::Syntax::Term::MissingInitializer|X::Syntax::UnlessElse|\"+\n\t\t\"X::Syntax::Variable::Match|X::Syntax::Variable::Numeric|X::Syntax::Variable::Twigil|X::Temporal|\"+\n\t\t\"X::Temporal::InvalidFormat|X::TypeCheck|X::TypeCheck::Assignment|X::TypeCheck::Binding|\"+\n\t\t\"X::TypeCheck::Return|X::TypeCheck::Splice|X::Undeclared\"\n\t\t);\n\n    var builtinFunctions = (\n        \"abs|abs2rel|absolute|accept|ACCEPTS|accessed|acos|acosec|acosech|acosh|\"+\n        \"acotan|acotanh|acquire|act|action|actions|add|add_attribute|add_enum_value|\"+\n        \"add_fallback|add_method|add_parent|add_private_method|add_role|add_trustee|\"+\n        \"adverb|after|all|allocate|allof|allowed|alternative-names|annotations|antipair|\"+\n        \"antipairs|any|anyof|app_lifetime|append|arch|archname|args|arity|asec|asech|\"+\n        \"asin|asinh|ASSIGN-KEY|ASSIGN-POS|assuming|ast|at|atan|atan2|atanh|AT-KEY|\"+\n        \"atomic-assign|atomic-dec-fetch|atomic-fetch|atomic-fetch-add|atomic-fetch-dec|\"+\n        \"atomic-fetch-inc|atomic-fetch-sub|atomic-inc-fetch|AT-POS|attributes|auth|await|\"+\n        \"backtrace|Bag|BagHash|base|basename|base-repeating|batch|BIND-KEY|BIND-POS|\"+\n        \"bind-stderr|bind-stdin|bind-stdout|bind-udp|bits|bless|block|bool-only|\"+\n        \"bounds|break|Bridge|broken|BUILD|build-date|bytes|cache|callframe|calling-package|\"+\n        \"CALL-ME|callsame|callwith|can|cancel|candidates|cando|canonpath|caps|caption|\"+\n        \"Capture|cas|catdir|categorize|categorize-list|catfile|catpath|cause|ceiling|\"+\n        \"cglobal|changed|Channel|chars|chdir|child|child-name|child-typename|chmod|chomp|\"+\n        \"chop|chr|chrs|chunks|cis|classify|classify-list|cleanup|clone|close|closed|\"+\n        \"close-stdin|code|codes|collate|column|comb|combinations|command|comment|\"+\n        \"compiler|Complex|compose|compose_type|composer|condition|config|configure_destroy|\"+\n        \"configure_type_checking|conj|connect|constraints|construct|contains|contents|copy|\"+\n        \"cos|cosec|cosech|cosh|cotan|cotanh|count|count-only|cpu-cores|cpu-usage|CREATE|\"+\n        \"create_type|cross|cue|curdir|curupdir|d|Date|DateTime|day|daycount|day-of-month|\"+\n        \"day-of-week|day-of-year|days-in-month|declaration|decode|decoder|deepmap|\"+\n        \"defined|DEFINITE|delayed|DELETE-KEY|DELETE-POS|denominator|desc|DESTROY|destroyers|\"+\n        \"devnull|did-you-mean|die|dir|dirname|dir-sep|DISTROnames|do|done|duckmap|dynamic|\"+\n        \"e|eager|earlier|elems|emit|enclosing|encode|encoder|encoding|end|ends-with|enum_from_value|\"+\n        \"enum_value_list|enum_values|enums|eof|EVAL|EVALFILE|exception|excludes-max|excludes-min|\"+\n        \"EXISTS-KEY|EXISTS-POS|exit|exitcode|exp|expected|explicitly-manage|expmod|extension|f|\"+\n        \"fail|fc|feature|file|filename|find_method|find_method_qualified|finish|first|flat|flatmap|\"+\n        \"flip|floor|flush|fmt|format|formatter|freeze|from|from-list|from-loop|from-posix|full|\"+\n        \"full-barrier|get|get_value|getc|gist|got|grab|grabpairs|grep|handle|handled|handles|\"+\n        \"hardware|has_accessor|head|headers|hh-mm-ss|hidden|hides|hour|how|hyper|id|illegal|\"+\n        \"im|in|indent|index|indices|indir|infinite|infix|install_method_cache|\"+\n        \"Instant|instead|int-bounds|interval|in-timezone|invalid-str|invert|invocant|IO|\"+\n        \"IO::Notification.watch-path|is_trusted|is_type|isa|is-absolute|is-hidden|is-initial-thread|\"+\n        \"is-int|is-lazy|is-leap-year|isNaN|is-prime|is-relative|is-routine|is-setting|is-win|item|\"+\n        \"iterator|join|keep|kept|KERNELnames|key|keyof|keys|kill|kv|kxxv|l|lang|last|lastcall|later|\"+\n        \"lazy|lc|leading|level|line|lines|link|listen|live|local|lock|log|log10|lookup|lsb|\"+\n        \"MAIN|match|max|maxpairs|merge|message|method_table|methods|migrate|min|minmax|\"+\n        \"minpairs|minute|misplaced|Mix|MixHash|mkdir|mode|modified|month|move|mro|msb|multiness|\"+\n        \"name|named|named_names|narrow|nativecast|native-descriptor|nativesizeof|new|new_type|\"+\n        \"new-from-daycount|new-from-pairs|next|nextcallee|next-handle|nextsame|nextwith|NFC|NFD|\"+\n        \"NFKC|NFKD|nl-in|nl-out|nodemap|none|norm|not|note|now|nude|numerator|Numeric|of|\"+\n        \"offset|offset-in-hours|offset-in-minutes|old|on-close|one|on-switch|open|opened|\"+\n        \"operation|optional|ord|ords|orig|os-error|osname|out-buffer|pack|package|package-kind|\"+\n        \"package-name|packages|pair|pairs|pairup|parameter|params|parent|parent-name|parents|parse|\"+\n        \"parse-base|parsefile|parse-names|parts|path|path-sep|payload|peer-host|peer-port|periods|\"+\n        \"perl|permutations|phaser|pick|pickpairs|pid|placeholder|plus|polar|poll|polymod|pop|pos|\"+\n        \"positional|posix|postfix|postmatch|precomp-ext|precomp-target|pred|prefix|prematch|prepend|\"+\n        \"print|printf|print-nl|print-to|private|private_method_table|proc|produce|Promise|prompt|\"+\n        \"protect|pull-one|push|push-all|push-at-least|push-exactly|push-until-lazy|put|\"+\n        \"qualifier-type|quit|r|race|radix|raku|rand|range|raw|re|read|readchars|readonly|\"+\n        \"ready|Real|reallocate|reals|reason|rebless|receive|recv|redispatcher|redo|reduce|\"+\n        \"rel2abs|relative|release|rename|repeated|replacement|report|reserved|resolve|\"+\n        \"restore|result|resume|rethrow|reverse|right|rindex|rmdir|roles_to_compose|\"+\n        \"rolish|roll|rootdir|roots|rotate|rotor|round|roundrobin|routine-type|run|rwx|s|\"+\n        \"samecase|samemark|samewith|say|schedule-on|scheduler|scope|sec|sech|second|seek|\"+\n        \"self|send|Set|set_hidden|set_name|set_package|set_rw|set_value|SetHash|\"+\n        \"set-instruments|setup_finalization|shape|share|shell|shift|sibling|sigil|\"+\n        \"sign|signal|signals|signature|sin|sinh|sink|sink-all|skip|skip-at-least|\"+\n        \"skip-at-least-pull-one|skip-one|sleep|sleep-timer|sleep-until|Slip|slurp|\"+\n        \"slurp-rest|slurpy|snap|snapper|so|socket-host|socket-port|sort|source|\"+\n        \"source-package|spawn|SPEC|splice|split|splitdir|splitpath|sprintf|spurt|\"+\n        \"sqrt|squish|srand|stable|start|started|starts-with|status|stderr|stdout|\"+\n        \"sub_signature|subbuf|subbuf-rw|subname|subparse|subst|subst-mutate|\"+\n        \"substr|substr-eq|substr-rw|succ|sum|Supply|symlink|t|tail|take|take-rw|\"+\n        \"tan|tanh|tap|target|target-name|tc|tclc|tell|then|throttle|throw|timezone|\"+\n        \"tmpdir|to|today|toggle|to-posix|total|trailing|trans|tree|trim|trim-leading|\"+\n        \"trim-trailing|truncate|truncated-to|trusts|try_acquire|trying|twigil|type|\"+\n        \"type_captures|typename|uc|udp|uncaught_handler|unimatch|uniname|uninames|\"+\n        \"uniparse|uniprop|uniprops|unique|unival|univals|unlink|unlock|unpack|unpolar|\"+\n        \"unshift|unwrap|updir|USAGE|utc|val|value|values|VAR|variable|verbose-config|\"+\n        \"version|VMnames|volume|vow|w|wait|warn|watch|watch-path|week|weekday-of-month|\"+\n        \"week-number|week-year|WHAT|WHERE|WHEREFORE|WHICH|WHO|whole-second|WHY|\"+\n        \"wordcase|words|workaround|wrap|write|write-to|yada|year|yield|yyyy-mm-dd|\"+\n        \"z|zip|zip-latest|\"+\n        \"plan|done-testing|bail-out|todo|skip|skip-rest|diag|subtest|pass|flunk|ok|\"+\n        \"nok|cmp-ok|is-deeply|isnt|is-approx|like|unlike|use-ok|isa-ok|does-ok|\"+\n        \"can-ok|dies-ok|lives-ok|eval-dies-ok|eval-lives-ok|throws-like|fails-like|\"+\n\t\t\"rw|required|native|repr|export|symbol\"\n\t);\n\tvar constants_ascii = (\"pi|Inf|tau|time\");\n\t\n\tvar ops_txt = (\"eq|ne|gt|lt|le|ge|div|gcd|lcm|leg|cmp|ff|fff|\"+\n\t\t\"x|before|after|Z|X|and|or|andthen|notandthen|orelse|xor\"\n\t);\n\n\tvar keywordMapper = this.createKeywordMapper({\n\t\t\"keyword\": keywords,\n\t\t\"storage.type\" : types,\n\t\t\"constant.language\": constants_ascii,\n\t\t\"support.function\": builtinFunctions,\n\t\t\"keyword.operator\": ops_txt\n\t}, \"identifier\");\n\n\t// regexp must not have capturing parentheses. Use (?:) instead.\n\t// regexps are ordered -> the first match is used\n\t\n\tvar moduleName = \"[a-zA-Z_][a-zA-Z_0-9:-]*\\\\b\";\n\t\n\t// Common rules used in the start block and in qqstrings and in qq-heredocs for interpolation\n\t\n\t// Numbers - Hexadecimal\n\tvar hex = {\ttoken : \"constant.numeric\", regex : \"0x[0-9a-fA-F]+\\\\b\" };\n\t// Numbers - Num & Rat\n\tvar num_rat = { token : \"constant.numeric\", regex : \"[+-.]?\\\\d[\\\\d_]*(?:(?:\\\\.\\\\d[\\\\d_]*)?(?:[eE][+-]?\\\\d[\\\\d_]*)?)?i?\\\\b\" };\n\t// Booleans\n\tvar booleans = { token : \"constant.language.boolean\", regex : \"(?:True|False)\\\\b\" };\n\t// Versions\n\tvar versions = { token : \"constant.other\", regex : \"v[0-9](?:\\\\.[a-zA-Z0-9*])*\\\\b\" };\n\t// Keywords\n\tvar lang_keywords = { token : keywordMapper, regex : \"[a-zA-Z][\\\\:a-zA-Z0-9_-]*\\\\b\" };\n\t// Variables - also matches $_ and $1 $2 (regex match) etc.\n\tvar variables = { token : \"variable.language\", regex : \"[$@%&][?*!.]?[a-zA-Z0-9_-]+\\\\b\" };\n\t// Special variables - matches $ $/ $! and @$/\n\tvar vars_special = { token: \"variable.language\", regex : \"\\\\$[/|!]?|@\\\\$/\" };\n\t// Operators characters\n\tvar ops_char = { token : \"keyword.operator\", regex : \"=|<|>|\\\\+|\\\\*|-|/|~|%|\\\\?|!|\\\\^|\\\\.|\\\\:|\\\\,|\"+\n\t\"»|«|\\\\||\\\\&|⚛|∘\" };\n\t// Unicode Constants\n\tvar constants_unicode = { token : \"constant.language\", regex : \"𝑒|π|τ|∞\" };\n\t// qstrings\n\tvar qstrings = { token : \"string.quoted.single\", regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\" };\n\t// Word Quoting\n\tvar word_quoting = { token : \"string.quoted.single\", regex : \"[<](?:[a-zA-Z0-9 ])*[>]\"};\n\t//Regexp\n\tvar regexp = {\n\t\t\t\ttoken : \"string.regexp\",\n\t\t\t\tregex : \"[m|rx]?[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\" };\n\t\n\t\n\tthis.$rules = {\n\t\t\"start\" : [\n\t\t\t{\n\t\t\t\ttoken : \"comment.block\", // Embedded Comments - Parentheses\n\t\t\t\tregex : \"#[`|=]\\\\(.*\\\\)\"\n\t\t\t}, {\n\t\t\t\ttoken : \"comment.block\", // Embedded Comments - Brackets\n\t\t\t\tregex : \"#[`|=]\\\\[.*\\\\]\"\n\t\t\t}, {\n\t\t\t\ttoken : \"comment.doc\", // Multiline Comments\n\t\t\t\tregex : \"^=(?:begin)\\\\b\",\n\t\t\t\tnext : \"block_comment\"\n\t\t\t}, {\n\t\t\t\ttoken : \"string.unquoted\", // q Heredocs\n\t\t\t\tregex : \"q[x|w]?\\\\:to/END/;\",\n\t\t\t\tnext : \"qheredoc\"\n\t\t\t}, {\n\t\t\t\ttoken : \"string.unquoted\", // qq Heredocs\n\t\t\t\tregex : \"qq[x|w]?\\\\:to/END/;\",\n\t\t\t\tnext : \"qqheredoc\"\n\t\t\t},\n\t\t\tregexp,\n\t\t\tqstrings\n\t\t\t, {\n\t\t\t\ttoken : \"string.quoted.double\", // Double Quoted String\n\t\t\t\tregex : '\"',\n\t\t\t\tnext : \"qqstring\"\n\t\t\t},\n\t\t\tword_quoting\n\t\t\t, {\n\t\t\t\ttoken: [\"keyword\", \"text\", \"variable.module\"], // use - Module Names, Pragmas, etc.\n\t\t\t\tregex: \"(use)(\\\\s+)((?:\"+moduleName+\"\\\\.?)*)\"\n\t\t\t},\n\t\t\thex,\n\t\t\tnum_rat,\n\t\t\tbooleans,\n\t\t\tversions,\n\t\t\tlang_keywords,\n\t\t\tvariables,\n\t\t\tvars_special,\n\t\t\tops_char,\n\t\t\tconstants_unicode\n\t\t\t, {\n\t\t\t\ttoken : \"comment\", // Sigle Line Comments\n\t\t\t\tregex : \"#.*$\"\n\t\t\t}, {\n\t\t\t\ttoken : \"lparen\",\n\t\t\t\tregex : \"[[({]\"\n\t\t\t}, {\n\t\t\t\ttoken : \"rparen\",\n\t\t\t\tregex : \"[\\\\])}]\"\n\t\t\t}, {\n\t\t\t\ttoken : \"text\",\n\t\t\t\tregex : \"\\\\s+\"\n\t\t\t}\n\t\t],\n\t\t\"qqstring\" : [\n\t\t\t{\n\t\t\t\ttoken : \"constant.language.escape\",\n\t\t\t\tregex : '\\\\\\\\(?:[nrtef\\\\\\\\\"$]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})'\n\t\t\t}, \n\t\t\tvariables,\n\t\t\tvars_special\n\t\t\t, {\n\t\t\t\ttoken : \"lparen\",\n\t\t\t\tregex : \"{\",\n\t\t\t\tnext : \"qqinterpolation\"\n\t\t\t}, {\n\t\t\t\ttoken : \"string.quoted.double\", \n\t\t\t\tregex : '\"', \n\t\t\t\tnext : \"start\"\n\t\t\t}, {\n\t\t\t\tdefaultToken : \"string.quoted.double\"\n\t\t\t}\n\t\t],\n\t\t\"qqinterpolation\" : [\n\t\t\thex,\n\t\t\tnum_rat,\n\t\t\tbooleans,\n\t\t\tversions,\n\t\t\tlang_keywords,\n\t\t\tvariables,\n\t\t\tvars_special,\n\t\t\tops_char,\n\t\t\tconstants_unicode,\n\t\t\tqstrings,\n\t\t\tregexp,\n\t\t\t\n\t\t\t{\n\t\t\t\ttoken: \"rparen\",\n\t\t\t\tregex: \"}\",\n\t\t\t\tnext : \"qqstring\"\n\t\t\t}\n\t\t],\n\t\t\"block_comment\": [\n\t\t\t{\n\t\t\t\ttoken: \"comment.doc\",\n\t\t\t\tregex: \"^=end +[a-zA-Z_0-9]*\",\n\t\t\t\tnext: \"start\"\n\t\t\t},\n\t\t\t{\n\t\t\t\tdefaultToken: \"comment.doc\"\n\t\t\t}\n\t\t],\n\t\t\"qheredoc\": [\n\t\t\t{\n\t\t\t\ttoken: \"string.unquoted\",\n\t\t\t\tregex: \"END$\",\n\t\t\t\tnext: \"start\"\n\t\t\t}, {\n\t\t\t\tdefaultToken: \"string.unquoted\"\n\t\t\t}\n\t\t],\n\t\t\"qqheredoc\": [\n\t\t\tvariables,\n\t\t\tvars_special,\n\t\t\t{\n\t\t\t\ttoken : \"lparen\",\n\t\t\t\tregex : \"{\",\n\t\t\t\tnext : \"qqheredocinterpolation\"\n\t\t\t}, {\n\t\t\t\ttoken: \"string.unquoted\",\n\t\t\t\tregex: \"END$\",\n\t\t\t\tnext: \"start\"\n\t\t\t}, {\n\t\t\t\tdefaultToken: \"string.unquoted\"\n\t\t\t}\n\t\t],\n\t\t\"qqheredocinterpolation\" : [\n\t\t\thex,\n\t\t\tnum_rat,\n\t\t\tbooleans,\n\t\t\tversions,\n\t\t\tlang_keywords,\n\t\t\tvariables,\n\t\t\tvars_special,\n\t\t\tops_char,\n\t\t\tconstants_unicode,\n\t\t\tqstrings,\n\t\t\tregexp,\n\t\t\t{\n\t\t\t\ttoken: \"rparen\",\n\t\t\t\tregex: \"}\",\n\t\t\t\tnext : \"qqheredoc\"\n\t\t\t}\n\t\t]\n\t};\n};\n\noop.inherits(RakuHighlightRules, TextHighlightRules);\n\nexports.RakuHighlightRules = RakuHighlightRules;\n"
  },
  {
    "path": "src/mode/razor.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar RazorHighlightRules = require(\"./razor_highlight_rules\").RazorHighlightRules;\nvar RazorCompletions = require(\"./razor_completions\").RazorCompletions;\nvar HtmlCompletions = require(\"./html_completions\").HtmlCompletions;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.$highlightRules = new RazorHighlightRules();\n    this.$completer = new RazorCompletions();\n    this.$htmlCompleter = new HtmlCompletions();\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.getCompletions = function(state, session, pos, prefix) {\n        var razorToken = this.$completer.getCompletions(state, session, pos, prefix);\n        var htmlToken = this.$htmlCompleter.getCompletions(state, session, pos, prefix);\n        return razorToken.concat(htmlToken);\n    };\n    \n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/razor\";\n    this.snippetFileId = \"ace/snippets/razor\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/razor_completions.js",
    "content": "\"use strict\";\n\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\n\nvar keywords = [\n    \"abstract\", \"as\", \"base\", \"bool\",\n    \"break\", \"byte\", \"case\", \"catch\",\n    \"char\", \"checked\", \"class\", \"const\",\n    \"continue\", \"decimal\", \"default\", \"delegate\",\n    \"do\", \"double\",\"else\",\"enum\",\n    \"event\", \"explicit\", \"extern\", \"false\",\n    \"finally\", \"fixed\", \"float\", \"for\",\n    \"foreach\", \"goto\", \"if\", \"implicit\",\n    \"in\", \"int\", \"interface\", \"internal\",\n    \"is\", \"lock\", \"long\", \"namespace\",\n    \"new\", \"null\", \"object\", \"operator\",\n    \"out\", \"override\", \"params\", \"private\",\n    \"protected\", \"public\", \"readonly\", \"ref\",\n    \"return\", \"sbyte\", \"sealed\", \"short\",\n    \"sizeof\", \"stackalloc\", \"static\", \"string\",\n    \"struct\", \"switch\", \"this\", \"throw\",\n    \"true\", \"try\", \"typeof\", \"uint\",\n    \"ulong\", \"unchecked\", \"unsafe\", \"ushort\",\n    \"using\", \"var\", \"virtual\", \"void\",\n    \"volatile\", \"while\"];\n\nvar shortHands  = [\n    \"Html\", \"Model\", \"Url\", \"Layout\"\n];\n    \nvar RazorCompletions = function() {\n\n};\n\n(function() {\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        \n        if(state.lastIndexOf(\"razor-short-start\") == -1 && state.lastIndexOf(\"razor-block-start\") == -1)\n            return [];\n        \n        var token = session.getTokenAt(pos.row, pos.column);\n        if (!token)\n            return [];\n        \n        if(state.lastIndexOf(\"razor-short-start\") != -1) {\n            return this.getShortStartCompletions(state, session, pos, prefix);\n        }\n        \n        if(state.lastIndexOf(\"razor-block-start\") != -1) {\n            return this.getKeywordCompletions(state, session, pos, prefix);\n        }\n\n        \n    };\n    \n    this.getShortStartCompletions = function(state, session, pos, prefix) {\n        return shortHands.map(function(element){\n            return {\n                value: element,\n                meta: \"keyword\",\n                score: 1000000\n            };\n        });\n    };\n\n    this.getKeywordCompletions = function(state, session, pos, prefix) {\n        return shortHands.concat(keywords).map(function(element){\n            return {\n                value: element,\n                meta: \"keyword\",\n                score: 1000000\n            };\n        });\n    };\n\n}).call(RazorCompletions.prototype);\n\nexports.RazorCompletions = RazorCompletions;\n"
  },
  {
    "path": "src/mode/razor_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar CSharpHighlightRules = require(\"./csharp_highlight_rules\").CSharpHighlightRules;\n\nvar blockPrefix = 'razor-block-';\nvar RazorLangHighlightRules = function() {\n    CSharpHighlightRules.call(this);\n\n    var processPotentialCallback = function(value, stackItem) {\n        if (typeof stackItem === \"function\")\n            return stackItem(value);\n\n        return stackItem;\n    };\n\n    var inBraces = 'in-braces';\n    this.$rules.start.unshift({\n        regex: '[\\\\[({]',\n        onMatch: function(value, state, stack) {\n            var prefix = /razor-[^\\-]+-/.exec(state)[0];\n\n            stack.unshift(value);\n            stack.unshift(prefix + inBraces);\n            this.next = prefix + inBraces;\n            return 'paren.lparen';\n        }\n    }, {\n        start: \"@\\\\*\",\n        end: \"\\\\*@\",\n        token: \"comment\"\n    });\n\n    var parentCloseMap = {\n        '{': '}',\n        '[': ']',\n        '(': ')'\n    };\n\n    this.$rules[inBraces] = lang.deepCopy(this.$rules.start);\n    this.$rules[inBraces].unshift({\n        regex: '[\\\\])}]',\n        onMatch: function(value, state, stack) {\n            var open = stack[1];\n            if (parentCloseMap[open] !== value)\n                return 'invalid.illegal';\n\n            stack.shift(); // exit in-braces block\n            stack.shift(); // exit brace marker\n            this.next = processPotentialCallback(value, stack[0]) || 'start';\n            return 'paren.rparen';\n        }\n    });\n};\n\noop.inherits(RazorLangHighlightRules, CSharpHighlightRules);\n\nvar RazorHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    // 'Blocks': @{}, @(), @functions{}\n\n    var blockStartRule = {\n        regex: '@[({]|@functions{|@code ?{',\n        onMatch: function(value, state, stack) {\n            stack.unshift(value);\n            stack.unshift('razor-block-start');\n            this.next = 'razor-block-start';\n            return 'punctuation.block.razor';\n        }\n    };\n\n    var blockEndMap = {\n        '@{': '}',\n        '@(': ')',\n        '@functions{':'}',\n        '@code {':'}',\n        '@code{':'}'\n    };\n\n    var blockEndRule = {\n        regex: '[})]',\n        onMatch: function(value, state, stack) {\n            var blockStart = stack[1];\n            if (blockEndMap[blockStart] !== value)\n                return 'invalid.illegal';\n\n            stack.shift(); // exit razor block\n            stack.shift(); // remove block type marker\n            this.next = stack.shift() || 'start';\n            return 'punctuation.block.razor';\n        }\n    };\n\n    // Short: @Abc.Cde(Xyz).Ef\n\n    var shortStartRule = {\n        regex: \"@(?![{(])\",\n        onMatch: function(value, state, stack) {\n            stack.unshift(\"razor-short-start\");\n            this.next = \"razor-short-start\";\n            return 'punctuation.short.razor';\n        }\n    };\n\n    var shortEndRule = {\n        token: \"\",\n        regex: \"(?=[^A-Za-z_\\\\.()\\\\[\\\\]])\",\n        next: 'pop'\n    };\n\n    // Control flow: @if, etc\n\n    var ifStartRule = {\n        regex: \"@(?=if)\",\n        onMatch: function(value, state, stack) {\n            stack.unshift(function(value) {\n                if (value !== '}')\n                    return 'start';\n\n                return stack.shift() || 'start';\n            });\n            this.next = 'razor-block-start';\n            return 'punctuation.control.razor';\n        }\n    };\n\n    // Combined:\n\n    var razorStartRules = [\n        {\n            start: \"@\\\\*\",\n            end: \"\\\\*@\",\n            token: \"comment\"\n        },\n        {\n            token: [\"meta.directive.razor\", \"text\", \"identifier\"],\n            regex: \"^(\\\\s*@(?:model|inject|inherits|implements|attribute|layout|namespace|rendermode|using))(\\\\s+)(.+)$\"\n        },\n        {\n            token: [\"meta.directive.razor\", \"text\", \"string\"],\n            regex: \"^(\\\\s*@page)(\\\\s+)(.*)$\"\n        },\n        blockStartRule,\n        //ifStartRule,\n        shortStartRule\n    ];\n\n    for (var key in this.$rules)\n        this.$rules[key].unshift.apply(this.$rules[key], razorStartRules);\n\n    this.embedRules(RazorLangHighlightRules, \"razor-block-\", [blockEndRule], [\"start\"]);\n    this.embedRules(RazorLangHighlightRules, \"razor-short-\", [shortEndRule], [\"start\"]);\n\n    this.normalizeRules();\n};\n\noop.inherits(RazorHighlightRules, HtmlHighlightRules);\n\nexports.RazorHighlightRules = RazorHighlightRules;\nexports.RazorLangHighlightRules = RazorLangHighlightRules;\n"
  },
  {
    "path": "src/mode/rdoc.js",
    "content": "/*\n * rdoc.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RDocHighlightRules = require(\"./rdoc_highlight_rules\").RDocHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function(suppressHighlighting) {\n\tthis.HighlightRules = RDocHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n    this.$id = \"ace/mode/rdoc\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/rdoc_highlight_rules.js",
    "content": "/*\n * rdoc_highlight_rules.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar LaTeXHighlightRules = require(\"./latex_highlight_rules\");\n\nvar RDocHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"%.*$\"\n            }, {\n                token : \"text\", // non-command\n                regex : \"\\\\\\\\[$&%#\\\\{\\\\}]\"\n            }, {\n                token : \"keyword\", // command\n                regex : \"\\\\\\\\(?:name|alias|method|S3method|S4method|item|code|preformatted|kbd|pkg|var|env|option|command|author|email|url|source|cite|acronym|href|code|preformatted|link|eqn|deqn|keyword|usage|examples|dontrun|dontshow|figure|if|ifelse|Sexpr|RdOpts|inputencoding|usepackage)\\\\b\",\n               next : \"nospell\"\n            }, {\n                token : \"keyword\", // command\n                regex : \"\\\\\\\\(?:[a-zA-Z0-9]+|[^a-zA-Z0-9])\"\n            }, {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n                regex : \"[[({]\"\n            }, {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        // This mode is necessary to prevent spell checking, but to keep the\n        // same syntax highlighting behavior. \n        \"nospell\" : [\n           {\n               token : \"comment\",\n               regex : \"%.*$\",\n               next : \"start\"\n           }, {\n               token : \"nospell.text\", // non-command\n               regex : \"\\\\\\\\[$&%#\\\\{\\\\}]\"\n           }, {\n               token : \"keyword\", // command\n               regex : \"\\\\\\\\(?:name|alias|method|S3method|S4method|item|code|preformatted|kbd|pkg|var|env|option|command|author|email|url|source|cite|acronym|href|code|preformatted|link|eqn|deqn|keyword|usage|examples|dontrun|dontshow|figure|if|ifelse|Sexpr|RdOpts|inputencoding|usepackage)\\\\b\"\n           }, {\n               token : \"keyword\", // command\n               regex : \"\\\\\\\\(?:[a-zA-Z0-9]+|[^a-zA-Z0-9])\",\n               next : \"start\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"[[({]\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"[\\\\])]\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"}\",\n               next : \"start\"\n           }, {\n               token : \"nospell.text\",\n               regex : \"\\\\s+\"\n           }, {\n               token : \"nospell.text\",\n               regex : \"\\\\w+\"\n           }\n        ]\n    };\n};\n\noop.inherits(RDocHighlightRules, TextHighlightRules);\n\nexports.RDocHighlightRules = RDocHighlightRules;\n"
  },
  {
    "path": "src/mode/red.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RedHighlightRules = require(\"./red_highlight_rules\").RedHighlightRules;\nvar RedFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = RedHighlightRules;\n    this.foldingRules = new RedFoldMode();\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \";\";\n    this.blockComment = { start: \"comment {\", end: \"}\" };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\[\\(]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState == \"start\") {\n                return \"\";\n            }\n            var match = line.match(/^\\s*(\\/?)\\*/);\n            if (match) {\n                if (match[1]) {\n                    indent += \" \";\n                }\n                indent += \"* \";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/red\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/red_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar RedHighlightRules = function() {\n\n    //var keywordMapper = this.createKeywordMapper({\n    //}, \"text\", true, \" \");\n\n    var compoundKeywords = \"\";        \n\n    this.$rules = {\n        \"start\" : [\n            {token : \"keyword.operator\", \n                regex: /\\s([\\-+%/=<>*]|(?:\\*\\*\\|\\/\\/|==|>>>?|<>|<<|=>|<=|=\\?))(\\s|(?=:))/},\n            {token : \"string.email\", regex : /\\w[-\\w._]*\\@\\w[-\\w._]*/},\n            {token : \"value.time\", regex : /\\b\\d+:\\d+(:\\d+)?/},\n            {token : \"string.url\", regex : /\\w[-\\w_]*\\:(\\/\\/)?\\w[-\\w._]*(:\\d+)?/},\n            {token : \"value.date\", regex : /(\\b\\d{1,4}[-/]\\d{1,2}[-/]\\d{1,2}|\\d{1,2}[-/]\\d{1,2}[-/]\\d{1,4})\\b/},\n            {token : \"value.tuple\", regex : /\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(\\.\\d{1,3}){0,9}/},\n            {token : \"value.pair\", regex: /[+-]?\\d+x[-+]?\\d+/},\n            {token : \"value.binary\", regex : /\\b2#{([01]{8})+}/},\n            {token : \"value.binary\", regex : /\\b64#{([\\w/=+])+}/},\n            {token : \"value.binary\", regex : /(16)?#{([\\dabcdefABCDEF][\\dabcdefABCDEF])*}/},\n            {token : \"value.issue\", regex : /#\\w[-\\w'*.]*/},\n            {token : \"value.numeric\", regex: /[+-]?\\d['\\d]*(?:\\.\\d+)?e[-+]?\\d{1,3}\\%?(?!\\w)/},\n            {token : \"invalid.illegal\", regex: /[+-]?\\d['\\d]*(?:\\.\\d+)?\\%?[a-zA-Z]/},\n            {token : \"value.numeric\", regex: /[+-]?\\d['\\d]*(?:\\.\\d+)?\\%?(?![a-zA-Z])/},\n            {token : \"value.character\", regex : /#\"(\\^[-@/_~^\"HKLM\\[]|.)\"/},\n            {token : \"string.file\", regex : /%[-\\w\\.\\/]+/},\n            {token : \"string.tag\", regex : /</, next : \"tag\"},\n            {token : \"string\", regex : /\"/, next  : \"string\"},\n            {token : \"string.other\", regex : \"{\", next  : \"string.other\"},\n            {token : \"comment\", regex : \"comment [{]\", next : \"comment\"},\n            {token : \"comment\",  regex : /;.+$/},\n            //{token : \"invalid\", regex: \"\\\\.{2,}\"},\n            {token : \"paren.map-start\", regex : \"#\\\\(\"},\n            {token : \"paren.block-start\", regex : \"[\\\\[]\"},\n            {token : \"paren.block-end\", regex : \"[\\\\]]\"},\n            {token : \"paren.parens-start\", regex : \"[(]\"},\n            {token : \"paren.parens-end\", regex : \"\\\\)\"},\n            //{token : \"keyword\", regex : compoundKeywords}, \n            {token : \"keyword\", regex : \"/local|/external\"},\n            {token : \"keyword.preprocessor\", regex : \"#(if|either|\" +\n                \"switch|case|include|do|macrolocal|reset|process|trace)\"},\n            {token : \"constant.datatype!\", regex : \n                \"(?:datatype|unset|none|logic|block|paren|string|\" +\n                \"file|url|char|integer|float|word|set-word|lit-word|\" +\n                \"get-word|refinement|issue|native|action|op|function|\" +\n                \"path|lit-path|set-path|get-path|routine|bitset|point|\" + \n                \"object|typeset|error|vector|hash|pair|percent|tuple|\" +\n                \"map|binary|time|tag|email|handle|date|image|event|\" +\n                \"series|any-type|number|any-object|scalar|\" +\n                \"any-string|any-word|any-function|any-block|any-list|\" +\n                \"any-path|immediate|all-word|internal|external|default)!(?![-!?\\\\w~])\"},\n            {token : \"keyword.function\", regex : \n                \"\\\\b(?:collect|quote|on-parse-event|math|last|source|expand|\" +\n                \"show|context|object|input|quit|dir|make-dir|cause-error|\" +\n                \"error\\\\?|none\\\\?|block\\\\?|any-list\\\\?|word\\\\?|char\\\\?|\" +\n                \"any-string\\\\?|series\\\\?|binary\\\\?|attempt|url\\\\?|\" +\n                \"string\\\\?|suffix\\\\?|file\\\\?|object\\\\?|body-of|first|\" +\n                \"second|third|mod|clean-path|dir\\\\?|to-red-file|\" +\n                \"normalize-dir|list-dir|pad|empty\\\\?|dirize|offset\\\\?|\" +\n                \"what-dir|expand-directives|load|split-path|change-dir|\" +\n                \"to-file|path-thru|save|load-thru|View|float\\\\?|to-float|\" +\n                \"charset|\\\\?|probe|set-word\\\\?|q|words-of|replace|repend|\" +\n                \"react|function\\\\?|spec-of|unset\\\\?|halt|op\\\\?|\" +\n                \"any-function\\\\?|to-paren|tag\\\\?|routine|class-of|\" +\n                \"size-text|draw|handle\\\\?|link-tabs-to-parent|\" +\n                \"link-sub-to-parent|on-face-deep-change*|\" +\n                \"update-font-faces|do-actor|do-safe|do-events|pair\\\\?|\" +\n                \"foreach-face|hex-to-rgb|issue\\\\?|alter|path\\\\?|\" +\n                \"typeset\\\\?|datatype\\\\?|set-flag|layout|extract|image\\\\?|\" +\n                \"get-word\\\\?|to-logic|to-set-word|to-block|center-face|\" +\n                \"dump-face|request-font|request-file|request-dir|rejoin|\" +\n                \"ellipsize-at|any-block\\\\?|any-object\\\\?|map\\\\?|keys-of|\" +\n                \"a-an|also|parse-func-spec|help-string|what|routine\\\\?|\" +\n                \"action\\\\?|native\\\\?|refinement\\\\?|common-substr|\" +\n                \"red-complete-file|red-complete-path|unview|comment|\\\\?\\\\?|\" +\n                \"fourth|fifth|values-of|bitset\\\\?|email\\\\?|get-path\\\\?|\" +\n                \"hash\\\\?|integer\\\\?|lit-path\\\\?|lit-word\\\\?|logic\\\\?|\" +\n                \"paren\\\\?|percent\\\\?|set-path\\\\?|time\\\\?|tuple\\\\?|date\\\\?|\" +\n                \"vector\\\\?|any-path\\\\?|any-word\\\\?|number\\\\?|immediate\\\\?|\" +\n                \"scalar\\\\?|all-word\\\\?|to-bitset|to-binary|to-char|to-email|\" +\n                \"to-get-path|to-get-word|to-hash|to-integer|to-issue|\" +\n                \"to-lit-path|to-lit-word|to-map|to-none|to-pair|to-path|\" +\n                \"to-percent|to-refinement|to-set-path|to-string|to-tag|\" +\n                \"to-time|to-typeset|to-tuple|to-unset|to-url|to-word|\" +\n                \"to-image|to-date|parse-trace|modulo|eval-set-path|\" +\n                \"extract-boot-args|flip-exe-flag|split|do-file|\" +\n                \"exists-thru\\\\?|read-thru|do-thru|cos|sin|tan|acos|asin|\" +\n                \"atan|atan2|sqrt|clear-reactions|dump-reactions|react\\\\?|\" +\n                \"within\\\\?|overlap\\\\?|distance\\\\?|face\\\\?|metrics\\\\?|\" +\n                \"get-scroller|insert-event-func|remove-event-func|\" +\n                \"set-focus|help|fetch-help|about|ls|ll|pwd|cd|\" +\n                \"red-complete-input|matrix)(?![-!?\\\\w~])\"},\n            {token : \"keyword.action\", regex : \n                \"\\\\b(?:to|remove|copy|insert|change|clear|move|poke|put|\" +\n                \"random|reverse|sort|swap|take|trim|add|subtract|\" +\n                \"divide|multiply|make|reflect|form|mold|modify|\" +\n                \"absolute|negate|power|remainder|round|even\\\\?|odd\\\\?|\" +\n                \"and~|complement|or~|xor~|append|at|back|find|skip|\" +\n                \"tail|head|head\\\\?|index\\\\?|length\\\\?|next|pick|\" +\n                \"select|tail\\\\?|delete|read|write)(?![-_!?\\\\w~])\"\n            },\n            {token : \"keyword.native\", regex : \n                \"\\\\b(?:not|any|set|uppercase|lowercase|checksum|\" +\n                \"try|catch|browse|throw|all|as|\" +\n                \"remove-each|func|function|does|has|do|reduce|\" +\n                \"compose|get|print|prin|equal\\\\?|not-equal\\\\?|\" +\n                \"strict-equal\\\\?|lesser\\\\?|greater\\\\?|lesser-or-equal\\\\?|\" +\n                \"greater-or-equal\\\\?|same\\\\?|type\\\\?|stats|bind|in|parse|\" +\n                \"union|unique|intersect|difference|exclude|\" +\n                \"complement\\\\?|dehex|negative\\\\?|positive\\\\?|max|min|\" +\n                \"shift|to-hex|sine|cosine|tangent|arcsine|arccosine|\" +\n                \"arctangent|arctangent2|NaN\\\\?|zero\\\\?|log-2|log-10|log-e|\" +\n                \"exp|square-root|construct|value\\\\?|as-pair|\" +\n                \"extend|debase|enbase|to-local-file|\" +\n                \"wait|unset|new-line|new-line\\\\?|context\\\\?|set-env|\" +\n                \"get-env|list-env|now|sign\\\\?|call|size\\\\?)(?![-!?\\\\w~])\"\n            },\n            {token : \"keyword\", regex : \n                \"\\\\b(?:Red(?=\\\\s+\\\\[)|object|context|make|self|keep)(?![-!?\\\\w~])\"\n            },\n            {token: \"variable.language\", regex : \"this\"},\n            {token: \"keyword.control\", regex : \n                \"(?:while|if|return|case|unless|either|until|loop|repeat|\" +\n                \"forever|foreach|forall|switch|break|continue|exit)(?![-!?\\\\w~])\"},\n            {token: \"constant.language\", regex : \n                \"\\\\b(?:true|false|on|off|yes|none|no)(?![-!?\\\\w~])\"},\n            {token: \"constant.numeric\", regex : /\\bpi(?![^-_])/},\n            {token: \"constant.character\", regex : \"\\\\b(space|tab|newline|cr|lf)(?![-!?\\\\w~])\"},\n            {token: \"keyword.operator\", regex : \"\\s(or|and|xor|is)\\s\"},\n            //{token : keywordMapper, regex : \"\\\\b\\\\w[-\\\\w'*.]*\\\\b\"},\n            {token : \"variable.get-path\", regex : /:\\w[-\\w'*.?!]*(\\/\\w[-\\w'*.?!]*)(\\/\\w[-\\w'*.?!]*)*/},\n            {token : \"variable.set-path\", regex : /\\w[-\\w'*.?!]*(\\/\\w[-\\w'*.?!]*)(\\/\\w[-\\w'*.?!]*)*:/},\n            {token : \"variable.lit-path\", regex : /'\\w[-\\w'*.?!]*(\\/\\w[-\\w'*.?!]*)(\\/\\w[-\\w'*.?!]*)*/},\n            {token : \"variable.path\", regex : /\\w[-\\w'*.?!]*(\\/\\w[-\\w'*.?!]*)(\\/\\w[-\\w'*.?!]*)*/},\n            {token : \"variable.refinement\", regex : /\\/\\w[-\\w'*.?!]*/}, \n            {token : \"keyword.view.style\", regex : \n                \"\\\\b(?:window|base|button|text|field|area|check|\" +\n                \"radio|progress|slider|camera|text-list|\" +\n                \"drop-list|drop-down|panel|group-box|\" +\n                \"tab-panel|h1|h2|h3|h4|h5|box|image|init)(?![-!?\\\\w~])\"},\n            {token : \"keyword.view.event\", regex : \n                \"\\\\b(?:detect|on-detect|time|on-time|drawing|on-drawing|\" +\n                \"scroll|on-scroll|down|on-down|up|on-up|mid-down|\" +\n                \"on-mid-down|mid-up|on-mid-up|alt-down|on-alt-down|\" +\n                \"alt-up|on-alt-up|aux-down|on-aux-down|aux-up|\" +\n                \"on-aux-up|wheel|on-wheel|drag-start|on-drag-start|\" +\n                \"drag|on-drag|drop|on-drop|click|on-click|dbl-click|\" +\n                \"on-dbl-click|over|on-over|key|on-key|key-down|\" +\n                \"on-key-down|key-up|on-key-up|ime|on-ime|focus|\" +\n                \"on-focus|unfocus|on-unfocus|select|on-select|\" +\n                \"change|on-change|enter|on-enter|menu|on-menu|close|\" +\n                \"on-close|move|on-move|resize|on-resize|moving|\" +\n                \"on-moving|resizing|on-resizing|zoom|on-zoom|pan|\" +\n                \"on-pan|rotate|on-rotate|two-tap|on-two-tap|\" +\n                \"press-tap|on-press-tap|create|on-create|created|on-created)(?![-!?\\\\w~])\"},\n            {token : \"keyword.view.option\", regex : \n                \"\\\\b(?:all-over|center|color|default|disabled|down|\" +\n                \"flags|focus|font|font-color|font-name|\" +\n                \"font-size|hidden|hint|left|loose|name|\" +\n                \"no-border|now|rate|react|select|size|space)(?![-!?\\\\w~])\"},\n            {token : \"constant.other.colour\", regex : \"\\\\b(?:Red|white|transparent|\" +\n                \"black|gray|aqua|beige|blue|brick|brown|coal|coffee|\" +\n                \"crimson|cyan|forest|gold|green|ivory|khaki|leaf|linen|\" +\n                \"magenta|maroon|mint|navy|oldrab|olive|orange|papaya|\" +\n                \"pewter|pink|purple|reblue|rebolor|sienna|silver|sky|\" +\n                \"snow|tanned|teal|violet|water|wheat|yello|yellow|glass)(?![-!?\\\\w~])\"},\n            {token : \"variable.get-word\", regex : /\\:\\w[-\\w'*.?!]*/}, \n            {token : \"variable.set-word\", regex : /\\w[-\\w'*.?!]*\\:/}, \n            {token : \"variable.lit-word\", regex : /'\\w[-\\w'*.?!]*/},\n            {token : \"variable.word\", regex : /\\b\\w+[-\\w'*.!?]*/},\n            {caseInsensitive: true}\n        ],\n        \"string\" : [\n            //{token : \"constant.language.escape\",   regex : \"^\"},\n            {token : \"string\", regex : /\"/, next : \"start\"},\n            {defaultToken : \"string\"}\n        ],\n        \"string.other\" : [\n            //{token : \"constant.language.escape\",   regex : \"^\"},\n            {token : \"string.other\", regex : /}/, next : \"start\"},\n            {defaultToken : \"string.other\"}\n        ],\n        \"tag\" : [\n            {token : \"string.tag\", regex : />/, next : \"start\"},\n            {defaultToken : \"string.tag\"}\n        ],\n        \"comment\" : [\n            //{token : \"constant.language.escape\",   regex : \"^\"},\n            {token : \"comment\", regex : /}/, next : \"start\"},\n            {defaultToken : \"comment\"}\n        ]\n    };\n};\noop.inherits(RedHighlightRules, TextHighlightRules);\n\nexports.RedHighlightRules = RedHighlightRules;\n"
  },
  {
    "path": "src/mode/redshift.js",
    "content": "var oop = require(\"../lib/oop\");\nvar TextMode = require(\"../mode/text\").Mode;\nvar RedshiftHighlightRules = require(\"./redshift_highlight_rules\").RedshiftHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = RedshiftHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) { \n        if (state == \"start\" || state == \"keyword.statementEnd\") {\n            return \"\";\n        } else {\n            return this.$getIndent(line); // Keep whatever indent the previous line has\n        }\n    };\n\n    this.$id = \"ace/mode/redshift\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/redshift_highlight_rules.js",
    "content": "var oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n// Syntax highlighting for json.\nvar JsonHighlightRules = require(\"./json_highlight_rules\").JsonHighlightRules;\n\nvar RedshiftHighlightRules = function() {\n\n    // Keywords, functions, operators last updated for pg 9.3.\n    var keywords = (\n        \"aes128|aes256|all|allowoverwrite|analyse|analyze|and|any|array|as|asc|authorization|backup|\" + \n        \"between|binary|blanksasnull|both|bytedict|bzip2|case|cast|check|collate|column|constraint|create|credentials|\" + \n        \"cross|current_date|current_time|current_timestamp|current_user|current_user_id|default|deferrable|deflate|defrag|delta|\" + \n        \"delta32k|desc|disable|distinct|do|else|emptyasnull|enable|encode|encrypt|encryption|end|except|explicit|false|for|foreign|\" + \n        \"freeze|from|full|globaldict256|globaldict64k|grant|group|gzip|having|identity|ignore|ilike|in|initially|inner|intersect|into|is|\" + \n        \"isnull|join|leading|left|like|limit|localtime|localtimestamp|lun|luns|lzo|lzop|minus|mostly13|mostly32|mostly8|natural|new|not|notnull|\" + \n        \"null|nulls|off|offline|offset|old|on|only|open|or|order|outer|overlaps|parallel|partition|percent|permissions|placing|primary|raw|readratio|\" +\n        \"recover|references|rejectlog|resort|restore|right|select|session_user|similar|some|sysdate|system|table|tag|tdes|text255|text32k|then|timestamp|\" + \n        \"to|top|trailing|true|truncatecolumns|union|unique|user|using|verbose|wallet|when|where|with|without\"\n    );\n\n\n    var builtinFunctions = (\n        \"current_schema|current_schemas|has_database_privilege|has_schema_privilege|has_table_privilege|age|current_time|current_timestamp|localtime|\" + \n        \"isfinite|now|ascii|get_bit|get_byte|octet_length|set_bit|set_byte|to_ascii|avg|count|listagg|max|min|stddev_samp|stddev_pop|sum|var_samp|var_pop|\" + \n        \"bit_and|bit_or|bool_and|bool_or|avg|count|cume_dist|dense_rank|first_value|last_value|lag|lead|listagg|max|median|min|nth_value|ntile|percent_rank|\" + \n        \"percentile_cont|percentile_disc|rank|ratio_to_report|row_number|case|coalesce|decode|greatest|least|nvl|nvl2|nullif|add_months|age|convert_timezone|\" +\n        \"current_date|timeofday|current_time|current_timestamp|date_cmp|date_cmp_timestamp|date_part_year|dateadd|datediff|date_part|date_trunc|extract|getdate|\" +\n        \"interval_cmp|isfinite|last_day|localtime|localtimestamp|months_between|next_day|now|sysdate|timestamp_cmp|timestamp_cmp_date|trunc|abs|acos|asin|atan|\" +\n        \"atan2|cbrt|ceiling|ceil|checksum|cos|cot|degrees|dexp|dlog1|dlog10|exp|floor|ln|log|mod|pi|power|radians|random|round|sin|sign|sqrt|tan|trunc|ascii|\" +\n        \"bpcharcmp|btrim|bttext_pattern_cmp|char_length|character_length|charindex|chr|concat|crc32|func_sha1|get_bit|get_byte|initcap|left|right|len|length|\" +\n        \"lower|lpad|rpad|ltrim|md5|octet_length|position|quote_ident|quote_literal|regexp_count|regexp_instr|regexp_replace|regexp_substr|repeat|replace|replicate|\" +\n        \"reverse|rtrim|set_bit|set_byte|split_part|strpos|strtol|substring|textlen|to_ascii|to_hex|translate|trim|upper|json_array_length|json_extract_array_element_text|\" +\n        \"json_extract_path_text|cast|convert|to_char|to_date|to_number|current_database|current_schema|current_schemas|current_user|current_user_id|has_database_privilege|\" +\n        \"has_schema_privilege|has_table_privilege|pg_backend_pid|pg_last_copy_count|pg_last_copy_id|pg_last_query_id|pg_last_unload_count|session_user|slice_num|user|version\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords\n    }, \"identifier\", true);\n\n\n    var sqlRules = [{\n            token : \"string\", // single line string -- assume dollar strings if multi-line for now\n            regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n        }, {\n            token : \"variable.language\", // pg identifier\n            regex : '\".*?\"'\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_][a-zA-Z0-9_$]*\\\\b\" // TODO - Unicode in identifiers\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|!!|!~|!~\\\\*|!~~|!~~\\\\*|#|##|#<|#<=|#<>|#=|#>|#>=|%|\\\\&|\\\\&\\\\&|\\\\&<|\\\\&<\\\\||\\\\&>|\\\\*|\\\\+|\" +\n                    \"\\\\-|/|<|<#>|<\\\\->|<<|<<=|<<\\\\||<=|<>|<\\\\?>|<@|<\\\\^|=|>|>=|>>|>>=|>\\\\^|\\\\?#|\\\\?\\\\-|\\\\?\\\\-\\\\||\" +\n                    \"\\\\?\\\\||\\\\?\\\\|\\\\||@|@\\\\-@|@>|@@|@@@|\\\\^|\\\\||\\\\|\\\\&>|\\\\|/|\\\\|>>|\\\\|\\\\||\\\\|\\\\|/|~|~\\\\*|~<=~|~<~|\" +\n                    \"~=|~>=~|~>~|~~|~~\\\\*\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }\n    ];\n\n\n    this.$rules = {\n        \"start\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            },{\n                token : \"keyword.statementBegin\",\n                regex : \"^[a-zA-Z]+\", // Could enumerate starting keywords but this allows things to work when new statements are added.\n                next : \"statement\"\n            },{\n                token : \"support.buildin\", // psql directive\n                regex : \"^\\\\\\\\[\\\\S]+.*$\"\n            }\n        ],\n\n        \"statement\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            }, {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"commentStatement\"\n            }, {\n                token : \"statementEnd\",\n                regex : \";\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$json\\\\$\",\n                next : \"json-start\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$[\\\\w_0-9]*\\\\$$\", // dollar quote at the end of a line\n                next : \"dollarSql\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarStatementString\"\n            }\n        ].concat(sqlRules),\n\n        \"dollarSql\" : [{\n                token : \"comment\",\n                regex : \"--.*$\"\n            }, {\n                token : \"comment\", // multi-line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"commentDollarSql\"\n            }, {\n                token : \"string\", // end quoting with dollar at the start of a line\n                regex : \"^\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"statement\"\n            }, {\n                token : \"string\",\n                regex : \"\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarSqlString\"\n            }\n        ].concat(sqlRules),\n\n        \"comment\" : [{\n                token : \"comment\", // closing comment\n                regex : \".*?\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                token : \"comment\", // comment spanning whole line\n                regex : \".+\"\n            }\n        ],\n\n        \"commentStatement\" : [{\n                token : \"comment\", // closing comment\n                regex : \".*?\\\\*\\\\/\",\n                next : \"statement\"\n            }, {\n                token : \"comment\", // comment spanning whole line\n                regex : \".+\"\n            }\n        ],\n\n        \"commentDollarSql\" : [{\n                token : \"comment\", // closing comment\n                regex : \".*?\\\\*\\\\/\",\n                next : \"dollarSql\"\n            }, {\n                token : \"comment\", // comment spanning whole line\n                regex : \".+\"\n            }\n        ],\n\n        \"dollarStatementString\" : [{\n                token : \"string\", // closing dollarstring\n                regex : \".*?\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"statement\"\n            }, {\n                token : \"string\", // dollarstring spanning whole line\n                regex : \".+\"\n            }\n        ],\n\n        \"dollarSqlString\" : [{\n                token : \"string\", // closing dollarstring\n                regex : \".*?\\\\$[\\\\w_0-9]*\\\\$\",\n                next : \"dollarSql\"\n            }, {\n                token : \"string\", // dollarstring spanning whole line\n                regex : \".+\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\", [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.embedRules(JsonHighlightRules, \"json-\", [{token : \"string\", regex : \"\\\\$json\\\\$\", next : \"statement\"}]);\n};\n\noop.inherits(RedshiftHighlightRules, TextHighlightRules);\n\nexports.RedshiftHighlightRules = RedshiftHighlightRules;\n"
  },
  {
    "path": "src/mode/rhtml.js",
    "content": "/*\n * rhtml.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\n\nvar RHtmlHighlightRules = require(\"./rhtml_highlight_rules\").RHtmlHighlightRules;\n/* Make life easier, don't do these right now \nvar SweaveBackgroundHighlighter = require(\"mode/sweave_background_highlighter\").SweaveBackgroundHighlighter;\nvar RCodeModel = require(\"mode/r_code_model\").RCodeModel;\n*/\n\nvar Mode = function(doc, session) {\n   HtmlMode.call(this);\n   this.$session = session;\n   this.HighlightRules = RHtmlHighlightRules;\n\n   /* Or these.\n   this.codeModel = new RCodeModel(doc, this.$tokenizer, /^r-/,\n                                   /^<!--\\s*begin.rcode\\s*(.*)/);\n   this.foldingRules = this.codeModel;\n   this.$sweaveBackgroundHighlighter = new SweaveBackgroundHighlighter(\n         session,\n         /^<!--\\s*begin.rcode\\s*(?:.*)/,\n         /^\\s*end.rcode\\s*-->/,\n         true); */\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n   this.insertChunkInfo = {\n      value: \"<!--begin.rcode\\n\\nend.rcode-->\\n\",\n      position: {row: 0, column: 15}\n   };\n    \n   this.getLanguageMode = function(position)\n   {\n      return this.$session.getState(position.row).match(/^r-/) ? 'R' : 'HTML';\n   };\n\n   /* this.getNextLineIndent = function(state, line, tab, tabSize, row)\n   {\n      return this.codeModel.getNextLineIndent(row, line, state, tab, tabSize);\n   }; */\n\n    this.$id = \"ace/mode/rhtml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/rhtml_highlight_rules.js",
    "content": "/*\n * rhtml_highlight_rules.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar RHighlightRules = require(\"./r_highlight_rules\").RHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar RHtmlHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    this.$rules[\"start\"].unshift({\n        token: \"support.function.codebegin\",\n        regex: \"^<\" + \"!--\\\\s*begin.rcode\\\\s*(?:.*)\",\n        next: \"r-start\"\n    });\n\n    this.embedRules(RHighlightRules, \"r-\", [{\n        token: \"support.function.codeend\",\n        regex: \"^\\\\s*end.rcode\\\\s*-->\",\n        next: \"start\"\n    }], [\"start\"]);\n\n    this.normalizeRules();\n};\noop.inherits(RHtmlHighlightRules, TextHighlightRules);\n\nexports.RHtmlHighlightRules = RHtmlHighlightRules;\n"
  },
  {
    "path": "src/mode/robot.js",
    "content": "\"use strict\";\n  \nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RobotHighlightRules = require(\"./robot_highlight_rules\").RobotHighlightRules;\nvar FoldMode = require(\"./folding/pythonic\").FoldMode;\n\nvar Mode = function() {\n  this.HighlightRules = RobotHighlightRules;\n  this.foldingRules = new FoldMode();\n  this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n  this.lineCommentStart = \"#\";\n  this.$id = \"ace/mode/robot\";\n  this.snippetFileId = \"ace/snippets/robot\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/robot_highlight_rules.js",
    "content": "'use strict';\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar RobotHighlightRules = function() {\n    var builtinConstantsRegex = new RegExp(\n        /\\$\\{CURDIR\\}|\\$\\{TEMPDIR\\}|\\$\\{EXECDIR\\}|\\$\\{\\/\\}|\\$\\{\\:\\}|\\$\\{\\\\n\\}|\\$\\{true\\}|\\$\\{false\\}|\\$\\{none\\}|\\$\\{null\\}|\\$\\{space(?:\\s*\\*\\s+[0-9]+)?\\}|\\$\\{empty\\}|&\\{empty\\}|@\\{empty\\}|\\$\\{TEST NAME\\}|@\\{TEST[\\s_]TAGS\\}|\\$\\{TEST[\\s_]DOCUMENTATION\\}|\\$\\{TEST[\\s_]STATUS\\}|\\$\\{TEST[\\s_]MESSAGE\\}|\\$\\{PREV[\\s_]TEST[\\s_]NAME\\}|\\$\\{PREV[\\s_]TEST[\\s_]STATUS\\}|\\$\\{PREV[\\s_]TEST[\\s_]MESSAGE\\}|\\$\\{SUITE[\\s_]NAME\\}|\\$\\{SUITE[\\s_]SOURCE\\}|\\$\\{SUITE[\\s_]DOCUMENTATION\\}|&\\{SUITE[\\s_]METADATA\\}|\\$\\{SUITE[\\s_]STATUS\\}|\\$\\{SUITE[\\s_]MESSAGE\\}|\\$\\{KEYWORD[\\s_]STATUS\\}|\\$\\{KEYWORD[\\s_]MESSAGE\\}|\\$\\{LOG[\\s_]LEVEL\\}|\\$\\{OUTPUT[\\s_]FILE\\}|\\$\\{LOG[\\s_]FILE\\}|\\$\\{REPORT[\\s_]FILE\\}|\\$\\{DEBUG[\\s_]FILE\\}|\\$\\{OUTPUT[\\s_]DIR\\}/\n    );\n\n    this.$rules = {\n        \"start\" : [ {\n            token: \"string.robot.header\",\n            regex: /^\\*{3}\\s+(?:settings?|metadata|(?:user )?keywords?|test ?cases?|tasks?|variables?)/,\n            caseInsensitive: true,\n            push: [{\n                token: \"string.robot.header\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.robot.header\"\n            }],\n            comment: \"start of a table\"\n        }, {\n            token: \"comment.robot\",\n            regex: /(?:^|\\s{2,}|\\t|\\|\\s{1,})(?=[^\\\\])#/,\n            push: [{\n                token: \"comment.robot\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment.robot\"\n            }]\n        }, {\n            token: \"comment\",\n            regex: /^\\s*\\[?Documentation\\]?/,\n            caseInsensitive: true,\n            push: [{\n                token: \"comment\",\n                regex: /^(?!\\s*\\.\\.\\.)/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"comment\"\n            }]\n        }, {\n            token: \"storage.type.method.robot\",\n            regex: /\\[(?:Arguments|Setup|Teardown|Precondition|Postcondition|Template|Return|Timeout)\\]/,\n            caseInsensitive: true,\n            comment: \"testcase settings\"\n        }, {\n            token: \"storage.type.method.robot\",\n            regex: /\\[Tags\\]/,\n            caseInsensitive: true,\n            push: [{\n                token: \"storage.type.method.robot\",\n                regex: /^(?!\\s*\\.\\.\\.)/,\n                next: \"pop\"\n            }, {\n                token: \"comment\",\n                regex: /^\\s*\\.\\.\\./\n            }, {\n                defaultToken: \"storage.type.method.robot\"\n            }],\n            comment: \"test tags\"\n        }, {\n            token: \"constant.language\",\n            regex: builtinConstantsRegex,\n            caseInsensitive: true\n        }, {\n            token: \"entity.name.variable.wrapper\",\n            regex: /[$@&%]\\{\\{?/,\n            push: [{\n                token: \"entity.name.variable.wrapper\",\n                regex: /\\}\\}?(\\s?=)?/,\n                next: \"pop\"\n            }, {\n                include: \"$self\"\n            }, {\n                token: \"entity.name.variable\",\n                regex: /./\n            }, {\n                defaultToken: \"entity.name.variable\"\n            }]\n        }, {\n            token: \"keyword.control.robot\",\n            regex: /^[^\\s\\t*$|]+|(?=^\\|)\\s+[^\\s\\t*$|]+/,\n            push: [{\n                token: \"keyword.control.robot\",\n                regex: /(?=\\s{2})|\\t|$|\\s+(?=\\|)/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"keyword.control.robot\"\n            }]\n        }, {\n            token: \"constant.numeric.robot\",\n            regex: /\\b[0-9]+(?:\\.[0-9]+)?\\b/\n        }, {\n            token: \"keyword\",\n            regex: /\\s{2,}(for|in range|in|end|else if|if|else|with name)(\\s{2,}|$)/,\n            caseInsensitive: true\n        }, {\n            token: \"storage.type.function\",\n            regex: /^(?:\\s{2,}\\s+)[^ \\t*$@&%[.|]+/,\n            push: [{\n                token: \"storage.type.function\",\n                regex: /(?=\\s{2})|\\t|$|\\s+(?=\\|)/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"storage.type.function\"\n            }]\n        }]\n    };\n    this.normalizeRules();\n};\n\nRobotHighlightRules.metadata = {\n  fileTypes: ['robot'],\n  name: 'Robot',\n  scopeName: 'source.robot'\n};\n\noop.inherits(RobotHighlightRules, TextHighlightRules);\n\nexports.RobotHighlightRules = RobotHighlightRules;\n"
  },
  {
    "path": "src/mode/rst.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RSTHighlightRules = require(\"./rst_highlight_rules\").RSTHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = RSTHighlightRules;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n\n    this.$id = \"ace/mode/rst\";\n    this.snippetFileId = \"ace/snippets/rst\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/rst_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar RSTHighlightRules = function() {\n\n  var tokens = {\n    title: \"markup.heading\",\n    list: \"markup.heading\",\n    table: \"constant\",\n    directive: \"keyword.operator\",\n    entity: \"string\",\n    link: \"markup.underline.list\",\n    bold: \"markup.bold\",\n    italic: \"markup.italic\",\n    literal: \"support.function\",\n    comment: \"comment\"\n  };\n\n  var startStringPrefix = \"(^|\\\\s|[\\\"'(<\\\\[{\\\\-/:])\";\n  var endStringSuffix = \"(?:$|(?=\\\\s|[\\\\\\\\.,;!?\\\\-/:\\\"')>\\\\]}]))\";\n\n  this.$rules = {\n    \"start\": [\n      /* NB: Only the underline of the heading is highlighted.\n       * ACE tokenizer does not allow backtracking, the underlined text of the\n       * heading cannot be highlighted. */\n      {\n        token : tokens.title,\n        regex : \"(^)([\\\\=\\\\-`:\\\\.'\\\"~\\\\^_\\\\*\\\\+#])(\\\\2{2,}\\\\s*$)\"\n      },\n      /* Generic directive syntax (e.g. .. code-block:: c)\n       * All of the directive body is highlighted as a code block. */\n      {\n        token : [\"text\", tokens.directive, tokens.literal],\n        regex : \"(^\\\\s*\\\\.\\\\. )([^: ]+::)(.*$)\",\n        next  : \"codeblock\"\n      },\n      {\n        token : tokens.directive,\n        regex : \"::$\",\n        next  : \"codeblock\"\n      },\n      /* Link/anchor definitions */\n      {\n        token : [tokens.entity, tokens.link],\n        regex : \"(^\\\\.\\\\. _[^:]+:)(.*$)\"\n      },\n      {\n        token : [tokens.entity, tokens.link],\n        regex : \"(^__ )(https?://.*$)\"\n      },\n      /* Footnote definition */\n      {\n        token : tokens.entity,\n        regex : \"^\\\\.\\\\. \\\\[[^\\\\]]+\\\\] \"\n      },\n      /* Comment block start */\n      {\n        token : tokens.comment,\n        regex : \"^\\\\.\\\\. .*$\",\n        next  : \"comment\"\n      },\n      /* List items */\n      {\n        token : tokens.list,\n        regex : \"^\\\\s*[\\\\*\\\\+-] \"\n      },\n      {\n        token : tokens.list,\n        regex : \"^\\\\s*(?:[A-Za-z]|[0-9]+|[ivxlcdmIVXLCDM]+)\\\\. \"\n      },\n      {\n        token : tokens.list,\n        regex : \"^\\\\s*\\\\(?(?:[A-Za-z]|[0-9]+|[ivxlcdmIVXLCDM]+)\\\\) \"\n      },\n      /* \"Simple\" tables */\n      {\n        token : tokens.table,\n        regex : \"^={2,}(?: +={2,})+$\"\n      },\n      /* \"Grid\" tables */\n      {\n        token : tokens.table,\n        regex : \"^\\\\+-{2,}(?:\\\\+-{2,})+\\\\+$\"\n      },\n      {\n        token : tokens.table,\n        regex : \"^\\\\+={2,}(?:\\\\+={2,})+\\\\+$\"\n      },\n      /* Inline markup */\n      {\n        token : [\"text\", tokens.literal],\n        regex : startStringPrefix + \"(``)(?=\\\\S)\",\n        next  : \"code\"\n      },\n      {\n        token : [\"text\", tokens.bold],\n        regex : startStringPrefix + \"(\\\\*\\\\*)(?=\\\\S)\",\n        next  : \"bold\"\n      },\n      {\n        token : [\"text\", tokens.italic],\n        regex : startStringPrefix + \"(\\\\*)(?=\\\\S)\",\n        next  : \"italic\"\n      },\n      /* Substitution reference */\n      {\n        token : tokens.entity,\n        regex : \"\\\\|[\\\\w\\\\-]+?\\\\|\"\n      },\n      /* Link/footnote references */\n      {\n        token : tokens.entity,\n        regex : \":[\\\\w-:]+:`\\\\S\",\n        next  : \"entity\"\n      },\n      {\n        token : [\"text\", tokens.entity],\n        regex : startStringPrefix + \"(_`)(?=\\\\S)\",\n        next  : \"entity\"\n      },\n      {\n        token : tokens.entity,\n        regex : \"_[A-Za-z0-9\\\\-]+?\"\n      },\n      {\n        token : [\"text\", tokens.link],\n        regex : startStringPrefix + \"(`)(?=\\\\S)\",\n        next  : \"link\"\n      },\n      {\n        token : tokens.link,\n        regex : \"[A-Za-z0-9\\\\-]+?__?\"\n      },\n      {\n        token : tokens.link,\n        regex : \"\\\\[[^\\\\]]+?\\\\]_\"\n      },\n      {\n        token : tokens.link,\n        regex : \"https?://\\\\S+\"\n      },\n      /* \"Grid\" tables column separator\n       * This is at the end to make it lower priority over all other rules. */\n      {\n        token : tokens.table,\n        regex : \"\\\\|\"\n      }\n    ],\n\n    /* This state is used for all directive bodies and literal blocks.\n     * The parser returns to the \"start\" state when reaching the first\n     * non-empty line that does not start with at least one space. */\n    \"codeblock\": [\n      {\n        token : tokens.literal,\n        regex : \"^ +.+$\",\n        next : \"codeblock\"\n      },\n      {\n        token : tokens.literal,\n        regex : '^$',\n        next: \"codeblock\"\n      },\n      {\n        token : \"empty\",\n        regex : \"\",\n        next : \"start\"\n      }\n    ],\n\n    /* Inline code\n     * The parser returns to the \"start\" state when reaching \"``\" */\n    \"code\": [\n      {\n        token : tokens.literal,\n        regex : \"\\\\S``\" + endStringSuffix,\n        next  : \"start\"\n      },\n      {\n        defaultToken: tokens.literal\n      }\n    ],\n\n    /* Bold (strong) text\n     * The parser returns to the \"start\" state when reaching \"**\" */\n    \"bold\": [\n      {\n        token : tokens.bold,\n        regex : \"\\\\S\\\\*\\\\*\" + endStringSuffix,\n        next  : \"start\"\n      },\n      {\n        defaultToken: tokens.bold\n      }\n    ],\n\n    /* Italic (emphasis) text\n     * The parser returns to the \"start\" state when reaching \"*\" */\n    \"italic\": [\n      {\n        token : tokens.italic,\n        regex : \"\\\\S\\\\*\" + endStringSuffix,\n        next  : \"start\"\n      },\n      {\n        defaultToken: tokens.italic\n      }\n    ],\n\n    /* Explicit role/class text or link anchor definition\n     * The parser returns to the \"start\" state when reaching \"`\" */\n    \"entity\": [\n      {\n        token : tokens.entity,\n        regex : \"\\\\S`\" + endStringSuffix,\n        next  : \"start\"\n      },\n      {\n        defaultToken: tokens.entity\n      }\n    ],\n\n    /* Link reference\n     * The parser returns to the \"start\" state when reaching \"`_\" or \"`__\" */\n    \"link\": [\n      {\n        token : tokens.link,\n        regex : \"\\\\S`__?\" + endStringSuffix,\n        next  : \"start\"\n      },\n      {\n        defaultToken: tokens.link\n      }\n    ],\n\n    /* Comment block.\n     * The parser returns to the \"start\" state when reaching the first\n     * non-empty line that does not start with at least one space. */\n    \"comment\": [\n      {\n        token : tokens.comment,\n        regex : \"^ +.+$\",\n        next : \"comment\"\n      },\n      {\n        token : tokens.comment,\n        regex : '^$',\n        next: \"comment\"\n      },\n      {\n        token : \"empty\",\n        regex : \"\",\n        next : \"start\"\n      }\n    ]\n  };\n};\noop.inherits(RSTHighlightRules, TextHighlightRules);\n\nexports.RSTHighlightRules = RSTHighlightRules;\n"
  },
  {
    "path": "src/mode/ruby.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RubyHighlightRules = require(\"./ruby_highlight_rules\").RubyHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar Range = require(\"../range\").Range;\nvar FoldMode = require(\"./folding/ruby\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = RubyHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new FoldMode();\n    this.indentKeywords = this.foldingRules.indentKeywords;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n\n    this.lineCommentStart = \"#\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length - 1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            var startingClassOrMethod = line.match(/^\\s*(class|def|module)\\s.*$/);\n            var startingDoBlock = line.match(/.*do(\\s*|\\s+\\|.*\\|\\s*)$/);\n            var startingConditional = line.match(/^\\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\\s*/);\n            if (match || startingClassOrMethod || startingDoBlock || startingConditional) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return /^\\s+(end|else|rescue|ensure)$/.test(line + input) || this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, session, row) {\n        var line = session.getLine(row);\n        if (/}/.test(line))\n            return this.$outdent.autoOutdent(session, row);\n        var indent = this.$getIndent(line);\n        var prevLine = session.getLine(row - 1);\n        var prevIndent = this.$getIndent(prevLine);\n        var tab = session.getTabString();\n        if (prevIndent.length <= indent.length) {\n            if (indent.slice(-tab.length) == tab)\n                session.remove(new Range(row, indent.length - tab.length, row, indent.length));\n        }\n    };\n\n    this.getMatching = function(session, row, column) {\n        if (row == undefined) {\n            var pos = session.selection.lead;\n            column = pos.column;\n            row = pos.row;\n        }\n\n        var startToken = session.getTokenAt(row, column);\n        if (startToken && startToken.value in this.indentKeywords)\n            return this.foldingRules.rubyBlock(session, row, column, true);\n    };\n\n    this.$id = \"ace/mode/ruby\";\n    this.snippetFileId = \"ace/snippets/ruby\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/ruby_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n// exports is for Haml\nvar constantOtherSymbol = exports.constantOtherSymbol = {\n    token : \"constant.other.symbol.ruby\", // symbol\n    regex : \"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?\"\n};\n\nexports.qString = {\n    token : \"string\", // single line\n    regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n};\n\nexports.qqString = {\n    token : \"string\", // single line\n    regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n};\n\nexports.tString = {\n    token : \"string\", // backtick string\n    regex : \"[`](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[`]\"\n};\n\nvar constantNumericHex = exports.constantNumericHex = {\n    token : \"constant.numeric\", // hex\n    regex : \"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\\\b\"\n};\n\nvar constantNumericBinary = exports.constantNumericBinary = {\n    token: \"constant.numeric\",\n    regex: /\\b(0[bB][01](?:[01]|_(?=[01]))*)\\b/\n};\n\nvar constantNumericDecimal = exports.constantNumericDecimal = {\n    token: \"constant.numeric\",\n    regex: /\\b(0[dD](?:[1-9](?:[\\d]|_(?=[\\d]))*|0))\\b/\n};\n\nvar constantNumericOctal = exports.constantNumericOctal = {\n    token: \"constant.numeric\",\n    regex: /\\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\\b/\n};\n\nvar constantNumericRational = exports.constantNumericRational = {\n    token: \"constant.numeric\", //rational + complex\n    regex: /\\b([\\d]+(?:[./][\\d]+)?ri?)\\b/\n};\n\nvar constantNumericComplex = exports.constantNumericComplex = {\n    token: \"constant.numeric\", //simple complex numbers\n    regex: /\\b([\\d]i)\\b/\n};\n\nvar constantNumericFloat = exports.constantNumericFloat = {\n    token : \"constant.numeric\", // float + complex\n    regex : \"[+-]?\\\\d(?:\\\\d|_(?=\\\\d))*(?:(?:\\\\.\\\\d(?:\\\\d|_(?=\\\\d))*)?(?:[eE][+-]?\\\\d+)?)?i?\\\\b\"\n};\n\nvar instanceVariable = exports.instanceVariable = {\n    token : \"variable.instance\", // instance variable\n    regex : \"@{1,2}[a-zA-Z_\\\\d]+\"\n};\n\nvar RubyHighlightRules = function() {\n\n    var builtinFunctions = (\n        \"abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|\" +\n        \"assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|\" +\n        \"assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|\" +\n        \"assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|\" +\n        \"assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|\" +\n        \"assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|\" +\n        \"attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|\" +\n        \"caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|\" +\n        \"exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|\" +\n        \"gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|\" +\n        \"link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|\" +\n        \"p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|\" +\n        \"raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|\" +\n        \"set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|\" +\n        \"throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|\" +\n        \"render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|\" +\n        \"content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|\" +\n        \"fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|\" +\n        \"time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|\" +\n        \"select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|\" +\n        \"file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|\" +\n        \"protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|\" +\n        \"send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|\" +\n        \"validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|\" +\n        \"validates_inclusion_of|validates_numericality_of|validates_with|validates_each|\" +\n        \"authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|\" +\n        \"filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|\" +\n        \"translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|\" +\n        \"cache|expire_fragment|expire_cache_for|observe|cache_sweeper|\" +\n        \"has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|\" +\n        \"private_class_method|remove_method|undef_method\"\n    );\n\n    var keywords = (\n        \"alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|\" +\n        \"__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|\" +\n        \"redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend\"\n    );\n\n    var buildinConstants = (\n        \"true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|\" +\n        \"RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION\"\n    );\n\n    var builtinVariables = (\n        \"$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|\" +\n        \"$!|root_url|flash|session|cookies|params|request|response|logger|self\"\n    );\n\n    var keywordMapper = this.$keywords = this.createKeywordMapper({\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants,\n        \"variable.language\": builtinVariables,\n        \"support.function\": builtinFunctions,\n        \"invalid.deprecated\": \"debugger\" // TODO is this a remnant from js mode?\n    }, \"identifier\");\n\n    var escapedChars = \"\\\\\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\\\"\\\\\\\\]|c(?:\\\\\\\\M-)?.|M-(?:\\\\\\\\C-|\\\\\\\\c)?.|C-(?:\\\\\\\\M-)?.|[0-7]{3}|x[\\\\da-fA-F]{2}|u[\\\\da-fA-F]{4}|u{[\\\\da-fA-F]{1,6}(?:\\\\s[\\\\da-fA-F]{1,6})*})\";\n\n    var closeParen = {\n        \"(\": \")\",\n        \"[\": \"]\",\n        \"{\": \"}\",\n        \"<\": \">\",\n        \"^\": \"^\",\n        \"|\": \"|\",\n        \"%\": \"%\"\n    };\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"comment\",\n                regex: \"#.*$\"\n            }, {\n                token: \"comment.multiline\", // multi line comment\n                regex: \"^=begin(?=$|\\\\s.*$)\",\n                next: \"comment\"\n            }, {\n                token: \"string.regexp\",\n                regex: /[/](?=.*\\/)/,\n                next: \"regex\"\n            },\n\n            [{\n                token: [\"constant.other.symbol.ruby\", \"string.start\"],\n                regex: /(:)?(\")/,\n                push: [{\n                    token: \"constant.language.escape\",\n                    regex: escapedChars\n                }, {\n                    token: \"paren.start\",\n                    regex: /#{/,\n                    push: \"start\"\n                }, {\n                    token: \"string.end\",\n                    regex: /\"/,\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            }, {\n                token: \"string.start\",\n                regex: /`/,\n                push: [{\n                    token: \"constant.language.escape\",\n                    regex: escapedChars\n                }, {\n                    token: \"paren.start\",\n                    regex: /#{/,\n                    push: \"start\"\n                }, {\n                    token: \"string.end\",\n                    regex: /`/,\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            }, {\n                token: [\"constant.other.symbol.ruby\", \"string.start\"],\n                regex: /(:)?(')/,\n                push: [{\n                    token: \"constant.language.escape\",\n                    regex: /\\\\['\\\\]/\n                }, {\n                    token: \"string.end\",\n                    regex: /'/,\n                    next: \"pop\"\n                }, {\n                    defaultToken: \"string\"\n                }]\n            }, {\n                token: \"string.start\",//doesn't see any differences between strings and array of strings in highlighting\n                regex: /%[qwx]([(\\[<{^|%])/, onMatch: function (val, state, stack) {\n                    if (stack.length)\n                        stack = [];\n                    var paren = val[val.length - 1];\n                    stack.unshift(paren, state);\n                    this.next = \"qStateWithoutInterpolation\";\n                    return this.token;\n                }\n            }, {\n                token: \"string.start\", //doesn't see any differences between strings and array of strings in highlighting\n                regex: /%[QWX]?([(\\[<{^|%])/, onMatch: function (val, state, stack) {\n                    if (stack.length)\n                        stack = [];\n                    var paren = val[val.length - 1];\n                    stack.unshift(paren, state);\n                    this.next = \"qStateWithInterpolation\";\n                    return this.token;\n                }\n            }, {\n                token: \"constant.other.symbol.ruby\", //doesn't see any differences between symbols and array of symbols in highlighting\n                regex: /%[si]([(\\[<{^|%])/, onMatch: function (val, state, stack) {\n                    if (stack.length)\n                        stack = [];\n                    var paren = val[val.length - 1];\n                    stack.unshift(paren, state);\n                    this.next = \"sStateWithoutInterpolation\";\n                    return this.token;\n                }\n            }, {\n                token: \"constant.other.symbol.ruby\", //doesn't see any differences between symbols and array of symbols in highlighting\n                regex: /%[SI]([(\\[<{^|%])/, onMatch: function (val, state, stack) {\n                    if (stack.length)\n                        stack = [];\n                    var paren = val[val.length - 1];\n                    stack.unshift(paren, state);\n                    this.next = \"sStateWithInterpolation\";\n                    return this.token;\n                }\n            }, {\n                token: \"string.regexp\",\n                regex: /%[r]([(\\[<{^|%])/, onMatch: function (val, state, stack) {\n                    if (stack.length)\n                        stack = [];\n                    var paren = val[val.length - 1];\n                    stack.unshift(paren, state);\n                    this.next = \"rState\";\n                    return this.token;\n                }\n            }],\n\n            {\n                token: \"punctuation\", // namespaces aren't symbols\n                regex: \"::\"\n            },\n            instanceVariable,\n            {\n                token: \"variable.global\", // global variable\n                regex: \"[$][a-zA-Z_\\\\d]+\"\n            }, {\n                token: \"support.class\", // class name\n                regex: \"[A-Z][a-zA-Z_\\\\d]*\"\n            }, {\n                token: [\"punctuation.operator\", \"support.function\"],\n                regex: /(\\.)([a-zA-Z_\\d]+)(?=\\()/\n            }, {\n                token: [\"punctuation.operator\", \"identifier\"],\n                regex: /(\\.)([a-zA-Z_][a-zA-Z_\\d]*)/\n            }, {\n                token: \"string.character\",\n                regex: \"\\\\B\\\\?(?:\" + escapedChars + \"|\\\\S)\"\n            }, {\n                token: \"punctuation.operator\",\n                regex: /\\?(?=.+:)/\n            },\n\n            constantNumericRational,\n            constantNumericComplex,\n            constantOtherSymbol,\n            constantNumericHex,\n            constantNumericFloat,\n            constantNumericBinary,\n            constantNumericDecimal,\n            constantNumericOctal,\n            {\n                token: \"constant.language.boolean\",\n                regex: \"(?:true|false)\\\\b\"\n            }, {\n                token: keywordMapper,\n                regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token: \"punctuation.separator.key-value\",\n                regex: \"=>\"\n            }, {\n                stateName: \"heredoc\",\n                onMatch: function (value, currentState, stack) {\n                    var next = (value[2] == '-' || value[2] == '~') ? \"indentedHeredoc\" : \"heredoc\";\n                    var tokens = value.split(this.splitRegex);\n                    stack.push(next, tokens[3]);\n                    return [\n                        {type: \"constant\", value: tokens[1]},\n                        {type: \"string\", value: tokens[2]},\n                        {type: \"support.class\", value: tokens[3]},\n                        {type: \"string\", value: tokens[4]}\n                    ];\n                },\n                regex: \"(<<[-~]?)(['\\\"`]?)([\\\\w]+)(['\\\"`]?)\",\n                rules: {\n                    heredoc: [{\n                        onMatch: function(value, currentState, stack) {\n                            if (value === stack[1]) {\n                                stack.shift();\n                                stack.shift();\n                                this.next = stack[0] || \"start\";\n                                return \"support.class\";\n                            }\n                            this.next = \"\";\n                            return \"string\";\n                        },\n                        regex: \".*$\",\n                        next: \"start\"\n                    }],\n                    indentedHeredoc: [{\n                        token: \"string\",\n                        regex: \"^ +\"\n                    }, {\n                        onMatch: function(value, currentState, stack) {\n                            if (value === stack[1]) {\n                                stack.shift();\n                                stack.shift();\n                                this.next = stack[0] || \"start\";\n                                return \"support.class\";\n                            }\n                            this.next = \"\";\n                            return \"string\";\n                        },\n                        regex: \".*$\",\n                        next: \"start\"\n                    }]\n                }\n            }, {\n                regex: \"$\",\n                token: \"empty\",\n                next: function(currentState, stack) {\n                    if (stack[0] === \"heredoc\" || stack[0] === \"indentedHeredoc\")\n                        return stack[0];\n                    return currentState;\n                }\n            },  {\n                token: \"keyword.operator\",\n                regex: \"!|\\\\$|%|&|\\\\*|/|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\||\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token: \"paren.lparen\",\n                regex: \"[[({]\"\n            }, {\n                token: \"paren.rparen\",\n                regex: \"[\\\\])}]\",\n                onMatch: function(value, currentState, stack) {\n                    this.next = '';\n                    if (value == \"}\" && stack.length > 1 && stack[1] != \"start\") {\n                        stack.shift();\n                        this.next = stack.shift();\n                    }\n                    return this.token;\n                }\n            }, {\n                token: \"text\",\n                regex: \"\\\\s+\"\n            }, {\n                token: \"punctuation.operator\",\n                regex: /[?:,;.]/\n            }\n        ],\n        \"comment\": [\n            {\n                token: \"comment.multiline\", // closing comment\n                regex: \"^=end(?=$|\\\\s.*$)\",\n                next: \"start\"\n            }, {\n                token: \"comment\", // comment spanning whole line\n                regex: \".+\"\n            }\n        ],\n        \"qStateWithInterpolation\": [{\n            token: \"string.start\",// excluded nested |^% due to difficulty in realization\n            regex: /[(\\[<{]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === stack[0]) {\n                    stack.unshift(val, state);\n                    return this.token;\n                }\n                return \"string\";\n            }\n        }, {\n            token: \"constant.language.escape\",\n            regex: escapedChars\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\\\./\n        }, {\n            token: \"paren.start\",\n            regex: /#{/,\n            push: \"start\"\n        }, {\n            token: \"string.end\",\n            regex: /[)\\]>}^|%]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === closeParen[stack[0]]) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    return this.token;\n                }\n                this.next = '';\n                return \"string\";\n            }\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"qStateWithoutInterpolation\": [{\n            token: \"string.start\",// excluded nested |^% due to difficulty in realization\n            regex: /[(\\[<{]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === stack[0]) {\n                    stack.unshift(val, state);\n                    return this.token;\n                }\n                return \"string\";\n            }\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\\\['\\\\]/\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\\\./\n        }, {\n            token: \"string.end\",\n            regex: /[)\\]>}^|%]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === closeParen[stack[0]]) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    return this.token;\n                }\n                this.next = '';\n                return \"string\";\n            }\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"sStateWithoutInterpolation\": [{\n            token: \"constant.other.symbol.ruby\",// excluded nested |^% due to difficulty in realization\n            regex: /[(\\[<{]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === stack[0]) {\n                    stack.unshift(val, state);\n                    return this.token;\n                }\n                return \"constant.other.symbol.ruby\";\n            }\n        }, {\n            token: \"constant.other.symbol.ruby\",\n            regex: /[)\\]>}^|%]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === closeParen[stack[0]]) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    return this.token;\n                }\n                this.next = '';\n                return \"constant.other.symbol.ruby\";\n            }\n        }, {\n            defaultToken: \"constant.other.symbol.ruby\"\n        }],\n        \"sStateWithInterpolation\": [{\n            token: \"constant.other.symbol.ruby\",// excluded nested |^% due to difficulty in realization\n            regex: /[(\\[<{]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === stack[0]) {\n                    stack.unshift(val, state);\n                    return this.token;\n                }\n                return \"constant.other.symbol.ruby\";\n            }\n        }, {\n            token: \"constant.language.escape\",\n            regex: escapedChars\n        }, {\n            token: \"constant.language.escape\",\n            regex: /\\\\./\n        }, {\n            token: \"paren.start\",\n            regex: /#{/,\n            push: \"start\"\n        }, {\n            token: \"constant.other.symbol.ruby\",\n            regex: /[)\\]>}^|%]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === closeParen[stack[0]]) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    return this.token;\n                }\n                this.next = '';\n                return \"constant.other.symbol.ruby\";\n            }\n        }, {\n            defaultToken: \"constant.other.symbol.ruby\"\n        }],\n        \"rState\": [{\n            token: \"string.regexp\",// excluded nested |^% due to difficulty in realization\n            regex: /[(\\[<{]/, onMatch: function (val, state, stack) {\n                if (stack.length && val === stack[0]) {\n                    stack.unshift(val, state);\n                    return this.token;\n                }\n                return \"constant.language.escape\";\n            }\n        }, {\n            token: \"paren.start\",\n            regex: /#{/,\n            push: \"start\"\n        }, {\n            token: \"string.regexp\",\n            regex: /\\//\n        }, {\n            token: \"string.regexp\",\n            regex: /[)\\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) {\n                if (stack.length && val[0] === closeParen[stack[0]]) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    return this.token;\n                }\n                this.next = '';\n                return \"constant.language.escape\";\n            }\n        },\n            {include: \"regex\"},\n            {\n                defaultToken: \"string.regexp\"\n            }],\n        \"regex\": [\n            {// character classes\n                token: \"regexp.keyword\",\n                regex: /\\\\[wWdDhHsS]/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\\\[AGbBzZ]/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\\\g<[a-zA-Z0-9]*>/\n            }, {\n                token: [\"constant.language.escape\", \"regexp.keyword\", \"constant.language.escape\"],\n                regex: /(\\\\p{\\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/\n            }, {\n                token: [\"constant.language.escape\", \"invalid\", \"constant.language.escape\"],\n                regex: /(\\\\p{\\^?)([^/]*)(})/\n            }, {// escapes\n                token: \"regexp.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {// flag\n                token: \"string.regexp\",\n                regex: /[/][imxouesn]*/,\n                next: \"start\"\n            }, {// invalid operators\n                token: \"invalid\",\n                regex: /\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/\n            }, {// operators\n                token: \"constant.language.escape\",\n                regex: /\\(\\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/\n            }, {\n                token: \"constant.language.delimiter\",\n                regex: /\\|/\n            }, {\n                token: \"regexp.keyword\",\n                regex: /\\[\\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\\]\\]/\n            }, {\n                token: \"constant.language.escape\",\n                regex: /\\[\\^?/,\n                push: \"regex_character_class\"\n            }, {\n                defaultToken: \"string.regexp\"\n            }\n        ],\n        \"regex_character_class\": [\n            {\n                // character classes\n                token: \"regexp.keyword\",\n                regex: /\\\\[wWdDhHsS]/\n            }, {\n                token: \"regexp.charclass.keyword.operator\",\n                regex: \"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: /&?&?\\[\\^?/,\n                push: \"regex_character_class\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"]\",\n                next: \"pop\"\n            }, {\n                token: \"constant.language.escape\",\n                regex: \"-\"\n            }, {\n                defaultToken: \"string.regexp.characterclass\"\n            }\n        ]\n    };\n\n    this.normalizeRules();\n};\n\noop.inherits(RubyHighlightRules, TextHighlightRules);\n\nexports.RubyHighlightRules = RubyHighlightRules;\n"
  },
  {
    "path": "src/mode/ruby_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Mode = require(\"./ruby\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp: function() {\n        this.mode = new Mode();\n    },\n\n    \"test getNextLineIndent\": function() {\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"class Foo\", \"  \"), \"  \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  def thing(wut)\", \"  \"), \"    \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  fork do\", \"  \"), \"    \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  fork do |wut| \", \"  \"), \"    \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  something = :ruby\", \"  \"), \"  \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  if something == 3\", \"  \"), \"    \");\n        assert.equal(this.mode.getNextLineIndent(\"start\", \"  else\", \"  \"), \"    \");\n    },\n\n    \"test: checkOutdent\": function() {\n        assert.ok(this.mode.checkOutdent(\"start\", \"        en\", \"d\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        els\", \"e\"));\n        assert.ok(this.mode.checkOutdent(\"start\", \"        \", \"}\"));\n        assert.equal(this.mode.checkOutdent(\"start\", \"  end\", \"\\n\"), false);\n        assert.equal(this.mode.checkOutdent(\"start\", \"foo = ba\", \"r\"), false);\n    },\n\n    \"test: auto outdent\": function() {\n        var session = new EditSession([\n            \"class Phil\",\n            \"  Foo = 'bar'\",\n            \"  def to_json(*a)\",\n            \"    {\",\n            \"      'json_class'   => self.class.name, # = 'Range'\",\n            \"      'data'         => [ first, last, exclude_end? ]\",\n            \"      }\",\n            \"  end\"]);\n        this.mode.autoOutdent(\"start\", session, 6);\n        assert.equal(\"    }\", session.getLine(6));\n        this.mode.autoOutdent(\"start\", session, 7);\n        assert.equal(\"  end\", session.getLine(7));\n    },\n\n    \"test: different delimiters in percent strings\": function() {\n        var tokenizer = this.mode.getTokenizer();\n        var tokens = tokenizer.getLineTokens(\"%q<t(es)t>\", \"start\").tokens;\n        assert.equal(\"string\", tokens[1].type);\n        assert.equal(\"t(es)t\", tokens[1].value);\n\n        tokens = tokenizer.getLineTokens(\"%q<t(es)t]#comment\", \"start\").tokens;\n        assert.equal(\"string\", tokens[tokens.length - 1].type);\n        assert.equal(\"t(es)t]#comment\", tokens[tokens.length - 1].value);\n\n        tokens = tokenizer.getLineTokens(\"%%test 1\\\\%%%\", \"start\").tokens;\n        assert.equal(\"string\", tokens[1].type);\n        assert.equal(\"test 1\", tokens[1].value);\n        assert.equal(\"constant.language.escape\", tokens[2].type);\n        assert.equal(\"string.end\", tokens[3].type);\n        assert.notEqual(\"string\", tokens[4].type);\n\n        tokens = tokenizer.getLineTokens(\"%s|test|\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[0].type);\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n\n        tokens = tokenizer.getLineTokens(\"%S{test}\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[0].type);\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n    },\n\n    \"test: nested and unescaped pairs of delimiters\": function() {\n        var tokenizer = this.mode.getTokenizer();\n\n        var tokens = tokenizer.getLineTokens(\"%(t(es)t)(\", \"start\").tokens;\n        assert.equal(\"string.end\", tokens[tokens.length - 2].type);\n        assert.equal(\"paren.lparen\", tokens[tokens.length - 1].type);\n\n        tokens = tokenizer.getLineTokens(\"%q(t(es)t(\", \"start\").tokens;\n        assert.notEqual(\"paren.lparen\", tokens[tokens.length - 1].type);\n\n        tokens = tokenizer.getLineTokens(\"%{tes{t} \\\\{test\\\\}}t\", \"start\").tokens;\n        assert.notEqual(\"string\", tokens[tokens.length - 1].type);\n        assert.equal(\"string.end\", tokens[tokens.length - 2].type);\n        assert.equal(\"constant.language.escape\", tokens[tokens.length - 3].type);\n\n        tokens = tokenizer.getLineTokens(\"%s[te[s]|t][\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 2].type);\n        assert.notEqual(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n\n        tokens = tokenizer.getLineTokens(\"%s[te[s]|t[\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n        assert.equal(1, tokens.length);\n\n        tokens = tokenizer.getLineTokens(\"%S[te[s]|t][\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 2].type);\n        assert.notEqual(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n\n        tokens = tokenizer.getLineTokens(\"%S[te[s]|t[\", \"start\").tokens;\n        assert.equal(\"constant.other.symbol.ruby\", tokens[tokens.length - 1].type);\n        assert.equal(1, tokens.length);\n    },\n\n    \"test: percent Regexp strings\": function() {\n        var tokenizer = this.mode.getTokenizer();\n        //percent regexp strings supports interpolation\n        var tokens = tokenizer.getLineTokens(\"%r(#{ \\\"interpolated\\\" } regexp)\", \"start\").tokens;\n        assert.equal(\"string.regexp\", tokens[0].type);\n        assert.equal(\"paren.start\", tokens[1].type);\n        assert.equal(\"paren.rparen\", tokens[tokens.length - 2].type);\n        assert.equal(\"string.regexp\", tokens[tokens.length - 1].type);\n        //bad code style, but we should support this one\n        tokens = tokenizer.getLineTokens(\"%r((a|b)*)#comment\", \"start\").tokens;\n        assert.equal(\"string.regexp\", tokens[0].type);\n        assert.notEqual(\"string.regexp\", tokens[tokens.length - 1].type);\n    },\n\n    \"test: uppercase letter in percent strings should allow interpolation and escaped characters\": function() {\n        var tokenizer = this.mode.getTokenizer();\n        var tokens = tokenizer.getLineTokens(\"%Q(interpolated string #{1 + 1})\", \"start\").tokens;\n        assert.equal(\"string.end\", tokens[tokens.length - 1].type);\n        assert.equal(\"string.start\", tokens[0].type);\n        assert.equal(\"paren.start\", tokens[2].type);\n        assert.notEqual(\"string\", tokens[3].type);\n        assert.equal(\"1\", tokens[3].value);\n\n        tokens = tokenizer.getLineTokens(\"%q(interpolated string #{1 + 1})\", \"start\").tokens;\n        assert.equal(\"string.end\", tokens[tokens.length - 1].type);\n        assert.equal(\"string.start\", tokens[0].type);\n        assert.equal(\"string\", tokens[1].type);\n        assert.equal(\"interpolated string #{1 + 1}\", tokens[1].value);\n    },\n\n    \"test: different Heredoc tests\": function() {\n        var tokenizer = this.mode.getTokenizer();\n        var firstLine = tokenizer.getLineTokens(\"herDocs = [<<'FOO', <<BAR, <<-BAZ, <<~`EXEC`] #comment\", \"start\");\n        assert.equal(8, firstLine.state.length);\n        var nextLine = tokenizer.getLineTokens(\"  FOO #{literal}\", firstLine.state);//this line shouldn't close FOO heredoc due to indentation\n        assert.equal(\"string\", nextLine.tokens[0].type);\n        assert.equal(8, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"FOO\", nextLine.state);\n        assert.equal(\"support.class\", nextLine.tokens[0].type);\n        assert.equal(6, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"  BAR\", nextLine.state);//not closing BAR heredoc due to indentation\n        assert.equal(\"string\", nextLine.tokens[0].type);\n        assert.equal(6, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"BAR\", nextLine.state);\n        assert.equal(\"support.class\", nextLine.tokens[0].type);\n        assert.equal(4, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"  BAZ indented\", nextLine.state);\n        assert.equal(\"string\", nextLine.tokens[0].type);\n        assert.equal(4, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"    BAZ\", nextLine.state);\n        assert.equal(\"support.class\", nextLine.tokens[1].type);\n        assert.equal(2, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"        echo hi\", nextLine.state);\n        assert.equal(\"string\", nextLine.tokens[0].type);\n        assert.equal(2, nextLine.state.length);\n        nextLine = tokenizer.getLineTokens(\"    EXEC\", nextLine.state);\n        assert.equal(\"support.class\", nextLine.tokens[1].type);\n        assert.equal(\"start\", nextLine.state);\n    }\n\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/rust.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar RustHighlightRules = require(\"./rust_highlight_rules\").RustHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = RustHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\", nestable: true};\n    this.$quotes = { '\"': '\"' };\n    this.$id = \"ace/mode/rust\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/rust_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/dbp/sublime-rust/master/Rust.tmLanguage (uuid: ) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n\nvar stringEscape = /\\\\(?:[nrt0'\"\\\\]|x[\\da-fA-F]{2}|u\\{[\\da-fA-F]{6}\\})/.source;\nvar wordPattern = /[a-zA-Z_\\xa1-\\uffff][a-zA-Z0-9_\\xa1-\\uffff]*/.source;\nvar RustHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.source.rust\": \"abstract|alignof|as|async|await|become|box|break|catch|continue|const|crate|\"\n            + \"default|do|dyn|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|\"\n            + \"override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|\"\n            + \"unsafe|unsized|use|virtual|where|while|yield|try\",\n        \"storage.type.source.rust\": \"Self|isize|usize|char|bool|u8|u16|u32|u64|u128|f16|f32|f64|i8|i16|i32|i64|\"\n            + \"i128|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|\"\n            + \"c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|\"\n            + \"uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t\",\n        \"constant.language.source.rust\": \"true|false|Some|None|Ok|Err|FALSE|TRUE\",\n        \"support.constant.source.rust\": \"EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|\"\n            + \"_IONBF|_IOLBF|\"\n            + \"BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|\"\n            + \"S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|\"\n            + \"F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO\",\n        \"constant.language\": \"macro_rules|mac_variant\"\n    }, \"identifier\");\n\n    this.$rules = {\n        start: [\n            {\n                token: 'variable.other.source.rust', // `(?![\\\\\\'])` to keep a lifetime name highlighting from continuing one character\n                // past the name. The end `\\'` will block this from matching for a character like\n                // `'a'` (it should have character highlighting, not variable highlighting).\n                regex: '\\'' + wordPattern + '(?![\\\\\\'])'\n            }, {\n                token: 'string.quoted.single.source.rust',\n                regex: \"'(?:[^'\\\\\\\\]|\" + stringEscape + \")'\"\n            }, {\n                token: 'identifier',\n                regex: \"r#\" + wordPattern + \"\\\\b\"\n            }, {\n                stateName: \"bracketedComment\",\n                onMatch: function (value, currentState, stack) {\n                    var stringStart = value.replace(/^\\w+/, \"\");\n                    stack.unshift(this.next, stringStart.length, currentState);\n                    return \"string.quoted.raw.source.rust\";\n                },\n                regex: /(b|c)?r#*\"/,\n                next: [\n                    {\n                        onMatch: function (value, currentState, stack) {\n                            var token = \"string.quoted.raw.source.rust\";\n                            if (value.length >= stack[1]) {\n                                if (value.length > stack[1]) token = \"invalid\";\n                                stack.shift();\n                                stack.shift();\n                                this.next = stack.shift();\n                            }\n                            else {\n                                this.next = \"\";\n                            }\n                            return token;\n                        },\n                        regex: /\"#*/,\n                        next: \"start\"\n                    }, {\n                        defaultToken: \"string.quoted.raw.source.rust\"\n                    }\n                ]\n            }, {\n                token: 'string.quoted.double.source.rust',\n                regex: '\"',\n                push: [\n                    {\n                        token: 'string.quoted.double.source.rust',\n                        regex: '\"',\n                        next: 'pop'\n                    }, {\n                        token: 'constant.character.escape.source.rust',\n                        regex: stringEscape\n                    }, {defaultToken: 'string.quoted.double.source.rust'}\n                ]\n            }, {\n                token: ['keyword.source.rust', 'text', 'entity.name.function.source.rust', 'punctuation'],\n                regex: '\\\\b(fn)(\\\\s+)((?:r#)?' + wordPattern + ')(<)(?!<)',\n                push: \"generics\"\n            }, {\n                token: ['keyword.source.rust', 'text', 'entity.name.function.source.rust'],\n                regex: '\\\\b(fn)(\\\\s+)((?:r#)?' + wordPattern + ')'\n            }, {\n                token: ['support.constant', \"punctuation\"],\n                regex: \"(\" + wordPattern + '::)(<)(?!<)',\n                push: \"generics\"\n            }, {\n                token: 'support.constant',\n                regex: wordPattern + '::'\n            }, {\n                token: 'variable.language.source.rust',\n                regex: '\\\\bself\\\\b'\n            }, DocCommentHighlightRules.getStartRule(\"doc-start\"), {\n                token: 'comment.line.doc.source.rust',\n                regex: '///.*$'\n            }, {\n                token: 'comment.line.doc.source.rust',\n                regex: '//!.*$'\n            }, {\n                token: 'comment.line.double-dash.source.rust',\n                regex: '//.*$'\n            }, {\n                token: 'comment.start.block.source.rust',\n                regex: '/\\\\*',\n                stateName: 'comment',\n                push: [\n                    {\n                        token: 'comment.start.block.source.rust',\n                        regex: '/\\\\*',\n                        push: 'comment'\n                    }, {\n                        token: 'comment.end.block.source.rust',\n                        regex: '\\\\*/',\n                        next: 'pop'\n                    }, {defaultToken: 'comment.block.source.rust'}\n                ]\n            }, {\n                token: [\"keyword.source.rust\", \"identifier\", \"punctuaction\"],\n                regex: \"(?:(impl)|(\" + wordPattern + \"))(<)(?!<)\",\n                stateName: 'generics',\n                push: [\n                    {\n                        token: 'keyword.operator',\n                        regex: /<<|=/\n                    }, {\n                        token: \"punctuaction\",\n                        regex: \"<(?!<)\",\n                        push: \"generics\"\n                    }, {\n                        token: 'variable.other.source.rust', // `(?![\\\\\\'])` to keep a lifetime name highlighting from continuing one character\n                        // past the name. The end `\\'` will block this from matching for a character like\n                        // `'a'` (it should have character highlighting, not variable highlighting).\n                        regex: '\\'' + wordPattern + '(?![\\\\\\'])'\n                    }, {\n                        token: \"storage.type.source.rust\",\n                        regex: \"\\\\b(u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize|char|bool)\\\\b\"\n                    }, {\n                        token: \"keyword\",\n                        regex: \"\\\\b(?:const|dyn)\\\\b\"\n                    }, {\n                        token: \"punctuation\",\n                        regex: \">\",\n                        next: \"pop\"\n                    }, \n                    {include: \"punctuation\"},\n                    {include: \"operators\"},\n                    {include: \"constants\"},\n                    {\n                        token: \"identifier\",\n                        regex: \"\\\\b\"+wordPattern+\"\\\\b\"\n                    }\n                ]\n            }, {\n                token: keywordMapper,\n                regex: wordPattern\n            }, {\n                token: 'meta.preprocessor.source.rust',\n                regex: '\\\\b\\\\w\\\\(\\\\w\\\\)*!|#\\\\[[\\\\w=\\\\(\\\\)_]+\\\\]\\\\b'\n            }, \n            {include: \"punctuation\"},\n            {include: \"operators\"},\n            {include: \"constants\"}\n        ],\n        punctuation: [\n            {\n                token: \"paren.lparen\",\n                regex: /[\\[({]/\n            }, {\n                token: \"paren.rparen\",\n                regex: /[\\])}]/\n            }, {\n                token: \"punctuation.operator\",\n                regex: /[?:,;.]/\n            }\n        ],\n        operators: [\n            {\n                token: 'keyword.operator', // `[*/](?![*/])=?` is separated because `//` and `/* */` become comments and must be\n                // guarded against. This states either `*` or `/` may be matched as long as the match\n                // it isn't followed by either of the two. An `=` may be on the end.\n                regex: /\\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/\n            }\n        ],\n        constants: [\n            {\n                token: 'constant.numeric.source.rust',\n                regex: /\\b(?:0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*(?!\\.))(?:[iu](?:size|8|16|32|64|128))?\\b/\n            }, {\n                token: 'constant.numeric.source.rust',\n                regex: /\\b(?:[0-9][0-9_]*)(?:\\.[0-9][0-9_]*)?(?:[Ee][+-][0-9][0-9_]*)?(?:f32|f64)?\\b/\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.normalizeRules();\n};\n\nRustHighlightRules.metaData = { fileTypes: [ 'rs', 'rc' ],\n      foldingStartMarker: '^.*\\\\bfn\\\\s*(\\\\w+\\\\s*)?\\\\([^\\\\)]*\\\\)(\\\\s*\\\\{[^\\\\}]*)?\\\\s*$',\n      foldingStopMarker: '^\\\\s*\\\\}',\n      name: 'Rust',\n      scopeName: 'source.rust' };\n\n\noop.inherits(RustHighlightRules, TextHighlightRules);\n\nexports.RustHighlightRules = RustHighlightRules;\n"
  },
  {
    "path": "src/mode/sac.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SaCHighlightRules = require(\"./sac_highlight_rules\").sacHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n  this.HighlightRules = SaCHighlightRules;\n  this.foldingRules = new FoldMode();\n  this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n  this.lineCommentStart = \"//\";\n  this.blockComment = {start: \"/*\", end: \"*/\"};\n  this.$id = \"ace/mode/sac\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sac_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar sacHighlightRules = function() {\n\n    var keywordControls = (\n        \"break|continue|do|else|for|if|\" +\n        \"return|with|while|use|class|all|void\"\n    );\n\n    var storageType = (\n        \"bool|char|complex|double|float|\" +\n        \"byte|int|short|long|longlong|\" +\n        \"ubyte|uint|ushort|ulong|ulonglong|\" +\n        \"struct|typedef\"\n    );\n\n    var storageModifiers = (\n        \"inline|external|specialize\"\n    );\n\n    var keywordOperators = (\n        \"step|width\"\n    );\n\n    var builtinConstants = (\n        \"true|false\"\n    );\n\n    var keywordMapper = this.$keywords = this.createKeywordMapper({\n        \"keyword.control\" : keywordControls,\n        \"storage.type\" : storageType,\n        \"storage.modifier\" : storageModifiers,\n        \"keyword.operator\" : keywordOperators,\n        \"constant.language\": builtinConstants\n    }, \"identifier\");\n\n    var identifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\\\\b\";\n    var escapeRe = /\\\\(?:['\"?\\\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\\d]{2}|u[a-fA-F\\d]{4}U[a-fA-F\\d]{8}|.)/.source;\n    var formatRe = \"%\"\n          + /(\\d+\\$)?/.source // field (argument #)\n          + /[#0\\- +']*/.source // flags\n          + /[,;:_]?/.source // separator character (AltiVec)\n          + /((-?\\d+)|\\*(-?\\d+\\$)?)?/.source // minimum field width\n          + /(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?/.source // precision\n          + /(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?/.source // length modifier\n          + /(\\[[^\"\\]]+\\]|[diouxXDOUeEfFgGaACcSspn%])/.source; // conversion type\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"//$\",\n                next : \"start\"\n            }, {\n                token : \"comment\",\n                regex : \"//\",\n                next : \"singleLineComment\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // character\n                regex : \"'(?:\" + escapeRe + \"|.)?'\"\n            }, {\n                token : \"string.start\",\n                regex : '\"',\n                stateName: \"qqstring\",\n                next: [\n                    { token: \"string\", regex: /\\\\\\s*$/, next: \"qqstring\" },\n                    { token: \"constant.language.escape\", regex: escapeRe },\n                    { token: \"constant.language.escape\", regex: formatRe },\n                    { token: \"string.end\", regex: '\"|$', next: \"start\" },\n                    { defaultToken: \"string\"}\n                ]\n            }, {\n                token : \"string.start\",\n                regex : 'R\"\\\\(',\n                stateName: \"rawString\",\n                next: [\n                    { token: \"string.end\", regex: '\\\\)\"', next: \"start\" },\n                    { defaultToken: \"string\"}\n                ]\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"\n            }, {\n                token : \"keyword\", // pre-compiler directives\n                regex : \"#\\\\s*(?:include|import|pragma|line|define|undef)\\\\b\",\n                next  : \"directive\"\n            }, {\n                token : \"keyword\", // special case pre-compiler directive\n                regex : \"#\\\\s*(?:endif|if|ifdef|else|elif|ifndef)\\\\b\"\n            }, {\n                token : \"support.function\",\n                regex : \"fold|foldfix|genarray|modarray|propagate\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\"\n            }, {\n                token : \"keyword.operator\",\n                regex : /--|\\+\\+|<<=|>>=|>>>=|<>|&&|\\|\\||\\?:|[*%\\/+\\-&\\^|~!<>=]=?/\n            }, {\n              token : \"punctuation.operator\",\n              regex : \"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"singleLineComment\" : [\n            {\n                token : \"comment\",\n                regex : /\\\\$/,\n                next : \"singleLineComment\"\n            }, {\n                token : \"comment\",\n                regex : /$/,\n                next : \"start\"\n            }, {\n                defaultToken: \"comment\"\n            }\n        ],\n        \"directive\" : [\n            {\n                token : \"constant.other.multiline\",\n                regex : /\\\\/\n            },\n            {\n                token : \"constant.other.multiline\",\n                regex : /.*\\\\/\n            },\n            {\n                token : \"constant.other\",\n                regex : \"\\\\s*<.+?>\",\n                next : \"start\"\n            },\n            {\n                token : \"constant.other\", // single line\n                regex : '\\\\s*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]',\n                next : \"start\"\n            },\n            {\n                token : \"constant.other\", // single line\n                regex : \"\\\\s*['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\",\n                next : \"start\"\n            },\n            // \"\\\" implies multiline, while \"/\" implies comment\n            {\n                token : \"constant.other\",\n                regex : /[^\\\\\\/]+/,\n                next : \"start\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    this.normalizeRules();\n};\n\noop.inherits(sacHighlightRules, TextHighlightRules);\n\nexports.sacHighlightRules = sacHighlightRules;\n"
  },
  {
    "path": "src/mode/sass.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SassHighlightRules = require(\"./sass_highlight_rules\").SassHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SassHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {   \n    this.lineCommentStart = \"//\";\n    this.$id = \"ace/mode/sass\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sass_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar ScssHighlightRules = require(\"./scss_highlight_rules\").ScssHighlightRules;\n\nvar SassHighlightRules = function() {\n    ScssHighlightRules.call(this);\n    var start = this.$rules.start;\n    if (start[1].token == \"comment\") {\n        start.splice(1, 1, {\n            onMatch: function(value, currentState, stack) {\n                stack.unshift(this.next, -1, value.length - 2, currentState);\n                return \"comment\";\n            },\n            regex: /^\\s*\\/\\*/,\n            next: \"comment\"\n        }, {\n            token: \"error.invalid\",\n            regex: \"/\\\\*|[{;}]\"\n        }, {\n            token: \"support.type\",\n            regex: /^\\s*:[\\w\\-]+\\s/\n        });\n        \n        this.$rules.comment = [\n            {regex: /^\\s*/, onMatch: function(value, currentState, stack) {\n                if (stack[1] === -1)\n                    stack[1] = Math.max(stack[2], value.length - 1);\n                if (value.length <= stack[1]) {\n                    /*shift3x*/stack.shift();stack.shift();stack.shift();\n                    this.next = stack.shift();\n                    return \"text\";\n                } else {\n                    this.next = \"\";\n                    return \"comment\";\n                }\n            }, next: \"start\"},\n            {defaultToken: \"comment\"}\n        ];\n    }\n};\n\noop.inherits(SassHighlightRules, ScssHighlightRules);\n\nexports.SassHighlightRules = SassHighlightRules;\n"
  },
  {
    "path": "src/mode/scad.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar scadHighlightRules = require(\"./scad_highlight_rules\").scadHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = scadHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState == \"start\") {\n                return \"\";\n            }\n            var match = line.match(/^\\s*(\\/?)\\*/);\n            if (match) {\n                if (match[1]) {\n                    indent += \" \";\n                }\n                indent += \"* \";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/scad\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/scad_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar scadHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": \"module|if|else|for\",\n        \"constant.language\": \"NULL\"\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // multi line string start\n                regex : '[\"].*\\\\\\\\$',\n                next : \"qqstring\"\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"string\", // multi line string start\n                regex : \"['].*\\\\\\\\$\",\n                next : \"qstring\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n              token : \"constant\", // <CONSTANT>\n              regex : \"<[a-zA-Z0-9.]+>\"\n            }, {\n              token : \"keyword\", // pre-compiler directivs\n              regex : \"(?:use|include)\"\n            }, {\n                token : keywordMapper,\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|new|delete|typeof|void)\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"string\",\n                regex : '(?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?\"',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"string\",\n                regex : \"(?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?'\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ]\n    };\n    \n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(scadHighlightRules, TextHighlightRules);\n\nexports.scadHighlightRules = scadHighlightRules;\n"
  },
  {
    "path": "src/mode/scala.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar ScalaHighlightRules = require(\"./scala_highlight_rules\").ScalaHighlightRules;\n\nvar Mode = function() {\n    JavaScriptMode.call(this);\n    this.HighlightRules = ScalaHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, JavaScriptMode);\n\n(function() {\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/scala\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/scala_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ScalaHighlightRules = function() {\n\n    var keywords = (\n            \"case|default|do|else|for|if|match|while|throw|return|try|trye|catch|finally|yield|\" +\n            \"abstract|class|def|extends|final|forSome|implicit|implicits|import|lazy|new|object|null|\" +\n            \"override|package|private|protected|sealed|super|this|trait|type|val|var|with|\" +\n            \"assert|assume|require|print|println|printf|readLine|readBoolean|readByte|readShort|\" + // package scala\n            \"readChar|readInt|readLong|readFloat|readDouble\" // package scala\n    );\n\n    var buildinConstants = (\"true|false\");\n\n    var langClasses = (\n        \"AbstractMethodError|AssertionError|ClassCircularityError|\"+\n        \"ClassFormatError|Deprecated|EnumConstantNotPresentException|\"+\n        \"ExceptionInInitializerError|IllegalAccessError|\"+\n        \"IllegalThreadStateException|InstantiationError|InternalError|\"+\n\n        \"NegativeArraySizeException|NoSuchFieldError|Override|Process|\"+\n        \"ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|\"+\n        \"SuppressWarnings|TypeNotPresentException|UnknownError|\"+\n        \"UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|\"+\n        \"InstantiationException|IndexOutOfBoundsException|\"+\n        \"ArrayIndexOutOfBoundsException|CloneNotSupportedException|\"+\n        \"NoSuchFieldException|IllegalArgumentException|NumberFormatException|\"+\n        \"SecurityException|Void|InheritableThreadLocal|IllegalStateException|\"+\n        \"InterruptedException|NoSuchMethodException|IllegalAccessException|\"+\n        \"UnsupportedOperationException|Enum|StrictMath|Package|Compiler|\"+\n        \"Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|\"+\n        \"NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|\"+\n        \"NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|\"+\n        \"Character|Boolean|StackTraceElement|Appendable|StringBuffer|\"+\n        \"Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|\"+\n        \"StackOverflowError|OutOfMemoryError|VirtualMachineError|\"+\n        \"ArrayStoreException|ClassCastException|LinkageError|\"+\n        \"NoClassDefFoundError|ClassNotFoundException|RuntimeException|\"+\n        \"Exception|ThreadDeath|Error|Throwable|System|ClassLoader|\"+\n        \"Cloneable|Class|CharSequence|Comparable|String|Object|\" +\n        \"Unit|Any|AnyVal|AnyRef|Null|ScalaObject|Singleton|Seq|Iterable|List|\" +\n        \"Option|Array|Char|Byte|Int|Long|Nothing|\" +\n\n        \"App|Application|BufferedIterator|BigDecimal|BigInt|Console|Either|\" +\n        \"Enumeration|Equiv|Fractional|Function|IndexedSeq|Integral|Iterator|\" +\n        \"Map|Numeric|Nil|NotNull|Ordered|Ordering|PartialFunction|PartialOrdering|\" +\n        \"Product|Proxy|Range|Responder|Seq|Serializable|Set|Specializable|Stream|\" +\n        \"StringContext|Symbol|Traversable|TraversableOnce|Tuple|Vector|Pair|Triple\"\n\n\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"this\",\n        \"keyword\": keywords,\n        \"support.function\": langClasses,\n        \"constant.language\": buildinConstants\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string.regexp\",\n                regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n            }, {\n                token : \"string\",\n                regex : '\"\"\"',\n                next : \"tstring\"\n            }, {\n                token : \"string\",\n                regex : '\"(?=.)', // \" strings can't span multiple lines\n                next : \"string\"\n            }, {\n                token : \"symbol.constant\", // single line\n                regex : \"'[\\\\w\\\\d_]+\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : keywordMapper,\n                // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"string\" : [\n            {\n                token : \"escape\",\n                regex : '\\\\\\\\\"'\n            }, {\n                token : \"string\",\n                regex : '\"',\n                next : \"start\"\n            }, {\n                token : \"string.invalid\",\n                regex : '[^\"\\\\\\\\]*$',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '[^\"\\\\\\\\]+'\n            }\n        ],\n        \"tstring\" : [\n            {\n                token : \"string\",\n                regex : '\"{3,5}',\n                next : \"start\"\n            }, {\n                defaultToken : \"string\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(ScalaHighlightRules, TextHighlightRules);\n\nexports.ScalaHighlightRules = ScalaHighlightRules;\n"
  },
  {
    "path": "src/mode/scheme.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SchemeHighlightRules = require(\"./scheme_highlight_rules\").SchemeHighlightRules;\nvar MatchingParensOutdent = require(\"./matching_parens_outdent\").MatchingParensOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = SchemeHighlightRules;\n\tthis.$outdent = new MatchingParensOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n       \n    this.lineCommentStart = \";\";\n    this.minorIndentFunctions = [\"define\", \"lambda\", \"define-macro\", \"define-syntax\", \"syntax-rules\", \"define-record-type\", \"define-structure\"];\n\n    this.$toIndent = function(str) {\n        return str.split('').map(function(ch) {\n            if (/\\s/.exec(ch)) {\n                return ch;\n            } else {\n                return ' ';\n            }\n        }).join('');\n    };\n\n    this.$calculateIndent = function(line, tab) {\n        var baseIndent = this.$getIndent(line);\n        var delta = 0;\n        var isParen, ch;\n        // Walk back from end of line, find matching braces\n        for (var i = line.length - 1; i >= 0; i--) {\n            ch = line[i];\n            if (ch === '(') {\n                delta--;\n                isParen = true;\n            } else if (ch === '(' || ch === '[' || ch === '{') {\n                delta--;\n                isParen = false;\n            } else if (ch === ')' || ch === ']' || ch === '}') {\n                delta++;\n            }\n            if (delta < 0) {\n                break;\n            }\n        }\n        if (delta < 0 && isParen) {\n            // Were more brackets opened than closed and was a ( left open?\n            i += 1;\n            var iBefore = i;\n            var fn = '';\n            while (true) {\n                ch = line[i];\n                if (ch === ' ' || ch === '\\t') {\n                    if(this.minorIndentFunctions.indexOf(fn) !== -1) {\n                        return this.$toIndent(line.substring(0, iBefore - 1) + tab);\n                    } else {\n                        return this.$toIndent(line.substring(0, i + 1));\n                    }\n                } else if (ch === undefined) {\n                    return this.$toIndent(line.substring(0, iBefore - 1) + tab);\n                }\n                fn += line[i];\n                i++;\n            }\n        } else if(delta < 0 && !isParen) {\n            // Were more brackets openend than closed and was it not a (?\n            return this.$toIndent(line.substring(0, i+1));\n        } else if(delta > 0) {\n            // Mere more brackets closed than opened? Outdent.\n            baseIndent = baseIndent.substring(0, baseIndent.length - tab.length);\n            return baseIndent;\n        } else {\n            // Were they nicely matched? Just indent like line before.\n            return baseIndent;\n        }\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$calculateIndent(line, tab);\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    this.$id = \"ace/mode/scheme\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/scheme_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SchemeHighlightRules = function() {\n    var keywordControl = \"case|do|let|loop|if|else|when\";\n    var keywordOperator = \"eq?|eqv?|equal?|and|or|not|null?\";\n    var constantLanguage = \"#t|#f\";\n    var supportFunctions = \"cons|car|cdr|cond|lambda|lambda*|syntax-rules|format|set!|quote|eval|append|list|list?|member?|load\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control\": keywordControl,\n        \"keyword.operator\": keywordOperator,\n        \"constant.language\": constantLanguage,\n        \"support.function\": supportFunctions\n    }, \"identifier\", true);\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = \n        {\n    \"start\": [\n        {\n            token : \"comment\",\n            regex : \";.*$\"\n        },\n        {\n            \"token\": [\"storage.type.function-type.scheme\", \"text\", \"entity.name.function.scheme\"],\n            \"regex\": \"(?:\\\\b(?:(define|define-syntax|define-macro))\\\\b)(\\\\s+)((?:\\\\w|\\\\-|\\\\!|\\\\?)*)\"\n        },\n        {\n            \"token\": \"punctuation.definition.constant.character.scheme\",\n            \"regex\": \"#:\\\\S+\"\n        },\n        {\n            \"token\": [\"punctuation.definition.variable.scheme\", \"variable.other.global.scheme\", \"punctuation.definition.variable.scheme\"],\n            \"regex\": \"(\\\\*)(\\\\S*)(\\\\*)\"\n        },\n        {\n            \"token\" : \"constant.numeric\", // hex\n            \"regex\" : \"#[xXoObB][0-9a-fA-F]+\"\n        }, \n        {\n            \"token\" : \"constant.numeric\", // float\n            \"regex\" : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\"\n        },\n        {\n                \"token\" : keywordMapper,\n                \"regex\" : \"[a-zA-Z_#][a-zA-Z0-9_\\\\-\\\\?\\\\!\\\\*]*\"\n        },\n        {\n            \"token\" : \"string\",\n            \"regex\" : '\"(?=.)',\n            \"next\"  : \"qqstring\"\n        }\n    ],\n    \"qqstring\": [\n        {\n            \"token\": \"constant.character.escape.scheme\",\n            \"regex\": \"\\\\\\\\.\"\n        },\n        {\n            \"token\" : \"string\",\n            \"regex\" : '[^\"\\\\\\\\]+',\n            \"merge\" : true\n        }, {\n            \"token\" : \"string\",\n            \"regex\" : \"\\\\\\\\$\",\n            \"next\"  : \"qqstring\",\n            \"merge\" : true\n        }, {\n            \"token\" : \"string\",\n            \"regex\" : '\"|$',\n            \"next\"  : \"start\",\n            \"merge\" : true\n        }\n    ]\n};\n\n};\n\noop.inherits(SchemeHighlightRules, TextHighlightRules);\n\nexports.SchemeHighlightRules = SchemeHighlightRules;\n"
  },
  {
    "path": "src/mode/scrypt.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar scryptHighlightRules = require(\"./scrypt_highlight_rules\").scryptHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function () {\n    this.HighlightRules = scryptHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function () {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {\n        start: \"/*\",\n        end: \"*/\"\n    };\n    this.$quotes = {\n        '\"': '\"',\n        \"'\": \"'\"\n    };\n\n    this.createWorker = function (session) {\n\n        return null;\n    };\n\n\n    this.$id = \"ace/mode/scrypt\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/scrypt_highlight_rules.js",
    "content": "/* This file was autogenerated from ./tmthemes/tmscrypt.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n    \"use strict\";\n\n    var oop = require(\"../lib/oop\");\n    var DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\n    var TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n    var scryptHighlightRules = function () {\n\n        var keywords = (\n            \"contract|library|loop|new|private|\" +\n            \"public|if|else|struct|type|\" +\n            \"require|static|const|import|exit|return|asm\"\n        );\n\n        var buildinConstants = (\"true|false\");\n\n\n        var langClasses = (\n            \"function|auto|constructor|bytes|int|bool|SigHashPreimage|PrivKey|PubKey|Sig|Ripemd160|Sha1|Sha256|\" +\n            \"SigHashType|SigHashPreimage|OpCodeType\"\n        );\n\n        var keywordMapper = this.createKeywordMapper({\n            \"variable.language\": \"this\",\n            \"keyword\": keywords,\n            \"constant.language\": buildinConstants,\n            \"support.function\": langClasses\n        }, \"identifier\");\n\n        // regexp must not have capturing parentheses. Use (?:) instead.\n        // regexps are ordered -> the first match is used\n\n        this.$rules = {\n            \"start\": [\n                {\n                    token: \"comment\",\n                    regex: \"\\\\/\\\\/.*$\"\n                },\n                DocCommentHighlightRules.getStartRule(\"doc-start\"),\n                {\n                    token: \"comment\", // multi line comment\n                    regex: \"\\\\/\\\\*\",\n                    next: \"comment\"\n                }, {\n                    token: \"string\", // single line\n                    regex: '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n                }, {\n                    token: \"string\", // single line\n                    regex: \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n                }, {\n                    token: \"constant.numeric\", // hex\n                    regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\\b/\n                }, {\n                    token: \"constant.numeric\", // float\n                    regex: /[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?[LlSsDdFfYy]?\\b/\n                }, {\n                    token: \"constant.language.boolean\",\n                    regex: \"(?:true|false)\\\\b\"\n                },\n                {\n                    token: [\"support.function.math.scrypt\", \"text\", \"text\"],\n                    regex: /\\b(abs|min|max|within|ripemd160|sha1|sha256|hash160|hash256|checkSig|checkMultiSig|num2bin|pack|unpack|len|reverseBytes|repeat)(\\s*)(\\()/\n                }, {\n                    token: [\n                        \"entity.name.type.scrypt\",\n                        \"text\",\n                        \"text\",\n                        \"text\",\n                        \"variable.object.property.scrypt\"\n                    ],\n                    regex: /\\b(SigHash)(\\s*)(\\.)(\\s*)(ANYONECANPAY|ALL|FORKID|NONE|SINGLE)\\b/\n                },\n                {\n                    token: [\n                        \"entity.name.type.scrypt\",\n                        \"text\",\n                        \"text\",\n                        \"text\",\n                        \"variable.object.property.scrypt\"\n                    ],\n                    regex: /\\b(OpCode)(\\s*)(\\.)(\\s*)(OP_PUSHDATA1|OP_PUSHDATA2|OP_PUSHDATA4|OP_0|OP_FALSE|OP_1NEGATE|OP_1|OP_TRUE|OP_2|OP_3|OP_4|OP_5|OP_6|OP_7|OP_8|OP_9|OP_10|OP_11|OP_12|OP_13|OP_14|OP_15|OP_16|OP_1ADD|OP_1SUB|OP_NEGATE|OP_ABS|OP_NOT|OP_0NOTEQUAL|OP_ADD|OP_SUB|OP_MUL|OP_DIV|OP_MOD|OP_LSHIFT|OP_RSHIFT|OP_BOOLAND|OP_BOOLOR|OP_NUMEQUAL|OP_NUMEQUALVERIFY|OP_NUMNOTEQUAL|OP_LESSTHAN|OP_GREATERTHAN|OP_LESSTHANOREQUAL|OP_GREATERTHANOREQUAL|OP_MIN|OP_MAX|OP_WITHIN|OP_CAT|OP_SPLIT|OP_BIN2NUM|OP_NUM2BIN|OP_SIZE|OP_NOP|OP_IF|OP_NOTIF|OP_ELSE|OP_ENDIF|OP_VERIFY|OP_RETURN|OP_TOALTSTACK|OP_FROMALTSTACK|OP_IFDUP|OP_DEPTH|OP_DROP|OP_DUP|OP_NIP|OP_OVER|OP_PICK|OP_ROLL|OP_ROT|OP_SWAP|OP_TUCK|OP_2DROP|OP_2DUP|OP_3DUP|OP_2OVER|OP_2ROT|OP_2SWAP|OP_RIPEMD160|OP_SHA1|OP_SHA256|OP_HASH160|OP_HASH256|OP_CODESEPARATOR|OP_CHECKSIG|OP_CHECKSIGVERIFY|OP_CHECKMULTISIG|OP_CHECKMULTISIGVERIFY|OP_INVERT|OP_AND|OP_OR|OP_XOR|OP_EQUAL|OP_EQUALVERIFY)\\b/\n                }, {\n                    token: \"entity.name.type.scrypt\",\n                    regex: /\\b(?:P2PKH|P2PK|Tx|HashPuzzleRipemd160|HashPuzzleSha1|HashPuzzleSha256|HashPuzzleHash160|OpCode|SigHash)\\b/\n                }, {\n                    token: [\n                        \"punctuation.separator.period.scrypt\",\n                        'text',\n                        \"entity.name.function.scrypt\",\n                        \"text\",\n                        \"punctuation.definition.parameters.begin.bracket.round.scrypt\"\n                    ],\n                    regex: /(\\.)([^\\S$\\r]*)([\\w][\\w\\d]*)(\\s*)(\\()/, \n                    push: [{\n                        token: \"punctuation.definition.parameters.end.bracket.round.scrypt\",\n                        regex: /\\)/,\n                        next: \"pop\"\n                    }, {\n                        defaultToken: \"start\"\n                    }]\n                }, {\n                    token: keywordMapper,\n                    regex: \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n                }, {\n                    token: \"keyword.operator\",\n                    regex: \"!|\\\\$|%|&|\\\\||\\\\^|\\\\*|\\\\/|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|==|=|!=|<=|>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?|\\\\:|\\\\*=|\\\\/=|%=|\\\\+=|\\\\-=|&=|\\\\|=|\\\\^=\"\n                }, {\n                    token: \"lparen\",\n                    regex: \"[[({]\"\n                }, {\n                    token: \"rparen\",\n                    regex: \"[\\\\])}]\"\n                }, {\n                    token: \"text\",\n                    regex: \"\\\\s+\"\n                }\n            ],\n            \"comment\": [\n                {\n                    token: \"comment\", // closing comment\n                    regex: \"\\\\*\\\\/\",\n                    next: \"start\"\n                }, {\n                    defaultToken: \"comment\"\n                }\n            ]\n        };\n\n\n        this.embedRules(DocCommentHighlightRules, \"doc-\",\n            [DocCommentHighlightRules.getEndRule(\"start\")]);\n        this.normalizeRules();\n    };\n\n    oop.inherits(scryptHighlightRules, TextHighlightRules);\n\n    exports.scryptHighlightRules = scryptHighlightRules;\n"
  },
  {
    "path": "src/mode/scss.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ScssHighlightRules = require(\"./scss_highlight_rules\").ScssHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CssBehaviour = require(\"./behaviour/css\").CssBehaviour;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar CssCompletions = require(\"./css_completions\").CssCompletions;\n\n\nvar Mode = function() {\n    this.HighlightRules = ScssHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = new CssBehaviour();\n    this.$completer = new CssCompletions();\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n   \n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        // ignore braces in comments\n        var tokens = this.getTokenizer().getLineTokens(line, state).tokens;\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        var match = line.match(/^.*\\{\\s*$/);\n        if (match) {\n            indent += tab;\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    this.getCompletions = function(state, session, pos, prefix) {\n        return this.$completer.getCompletions(state, session, pos, prefix);\n    };\n\n\n    this.$id = \"ace/mode/scss\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/scss_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CssHighlightRules = require(\"./css_highlight_rules\");\n\nvar ScssHighlightRules = function() {\n    \n    var properties = lang.arrayToMap(CssHighlightRules.supportType.split(\"|\"));\n\n    var functions = lang.arrayToMap(\n        (\"hsl|hsla|rgb|rgba|url|attr|counter|counters|abs|adjust_color|adjust_hue|\" +\n         \"alpha|join|blue|ceil|change_color|comparable|complement|darken|desaturate|\" + \n         \"floor|grayscale|green|hue|if|invert|join|length|lighten|lightness|mix|\" + \n         \"nth|opacify|opacity|percentage|quote|red|round|saturate|saturation|\" +\n         \"scale_color|transparentize|type_of|unit|unitless|unquote\").split(\"|\")\n    );\n\n    var constants = lang.arrayToMap(CssHighlightRules.supportConstant.split(\"|\"));\n\n    var colors = lang.arrayToMap(CssHighlightRules.supportConstantColor.split(\"|\"));\n    \n    var keywords = lang.arrayToMap(\n        (\"@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare\").split(\"|\")\n    );\n    \n    var tags = lang.arrayToMap(\n        (\"a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|\" + \n         \"big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|\" + \n         \"command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|\" + \n         \"figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|\" + \n         \"header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|\" + \n         \"link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|\" + \n         \"option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|\" + \n         \"small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|\" + \n         \"textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp\").split(\"|\")\n    );\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var numRe = \"\\\\-?(?:(?:[0-9]+)|(?:[0-9]*\\\\.[0-9]+))\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // multi line string start\n                regex : '[\"].*\\\\\\\\$',\n                next : \"qqstring\"\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"string\", // multi line string start\n                regex : \"['].*\\\\\\\\$\",\n                next : \"qstring\"\n            }, {\n                token : \"constant.numeric\",\n                regex : numRe + \"(?:ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)\"\n            }, {\n                token : \"constant.numeric\", // hex6 color\n                regex : \"#[a-f0-9]{6}\"\n            }, {\n                token : \"constant.numeric\", // hex3 color\n                regex : \"#[a-f0-9]{3}\"\n            }, {\n                token : \"constant.numeric\",\n                regex : numRe\n            }, {\n                token : [\"support.function\", \"string\", \"support.function\"],\n                regex : \"(url\\\\()(.*)(\\\\))\"\n            }, {\n                token : function(value) {\n                    if (properties.hasOwnProperty(value.toLowerCase()))\n                        return \"support.type\";\n                    if (keywords.hasOwnProperty(value))\n                        return \"keyword\";\n                    else if (constants.hasOwnProperty(value))\n                        return \"constant.language\";\n                    else if (functions.hasOwnProperty(value))\n                        return \"support.function\";\n                    else if (colors.hasOwnProperty(value.toLowerCase()))\n                        return \"support.constant.color\";\n                    else if (tags.hasOwnProperty(value.toLowerCase()))\n                        return \"variable.language\";\n                    else\n                        return \"text\";\n                },\n                regex : \"\\\\-?[@a-z_][@a-z0-9_\\\\-]*\"\n            }, {\n                token : \"variable\",\n                regex : \"[a-z_\\\\-$][a-z0-9_\\\\-$]*\\\\b\"\n            }, {\n                token: \"variable.language\",\n                regex: \"#[a-z0-9-_]+\"\n            }, {\n                token: \"variable.language\",\n                regex: \"\\\\.[a-z0-9-_]+\"\n            }, {\n                token: \"variable.language\",\n                regex: \":[a-z0-9-_]+\"\n            }, {\n                token: \"constant\",\n                regex: \"[a-z0-9-_]+\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"<|>|<=|>=|==|!=|-|%|#|\\\\+|\\\\$|\\\\+|\\\\*\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }, {\n                caseInsensitive: true\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \"\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                defaultToken : \"comment\"\n            }\n        ],\n        \"qqstring\" : [\n            {\n                token : \"string\",\n                regex : '(?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?\"',\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ],\n        \"qstring\" : [\n            {\n                token : \"string\",\n                regex : \"(?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?'\",\n                next : \"start\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ]\n    };\n};\n\noop.inherits(ScssHighlightRules, TextHighlightRules);\n\nexports.ScssHighlightRules = ScssHighlightRules;\n"
  },
  {
    "path": "src/mode/sh.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ShHighlightRules = require(\"./sh_highlight_rules\").ShHighlightRules;\nvar Range = require(\"../range\").Range;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ShHighlightRules;\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n   \n    this.lineCommentStart = \"#\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[:]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    var outdents = {\n        \"pass\": 1,\n        \"return\": 1,\n        \"raise\": 1,\n        \"break\": 1,\n        \"continue\": 1\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (input !== \"\\r\\n\" && input !== \"\\r\" && input !== \"\\n\")\n            return false;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n\n        if (!tokens)\n            return false;\n\n        // ignore trailing comments\n        do {\n            var last = tokens.pop();\n        } while (last && (last.type == \"comment\" || (last.type == \"text\" && last.value.match(/^\\s+$/))));\n\n        if (!last)\n            return false;\n\n        return (last.type == \"keyword\" && outdents[last.value]);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        // outdenting in sh is slightly different because it always applies\n        // to the next line and only of a new line is inserted\n\n        row += 1;\n        var indent = this.$getIndent(doc.getLine(row));\n        var tab = doc.getTabString();\n        if (indent.slice(-tab.length) == tab)\n            doc.remove(new Range(row, indent.length-tab.length, row, indent.length));\n    };\n\n    this.$id = \"ace/mode/sh\";\n    this.snippetFileId = \"ace/snippets/sh\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sh_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar reservedKeywords = exports.reservedKeywords = (\n        '!|{|}|case|do|done|elif|else|'+\n        'esac|fi|for|if|in|then|until|while|'+\n        '&|;|export|local|read|typeset|unset|'+\n        'elif|select|set|function|declare|readonly'\n    );\n\nvar languageConstructs = exports.languageConstructs = (\n    '[|]|alias|bg|bind|break|builtin|'+\n     'cd|command|compgen|complete|continue|'+\n     'dirs|disown|echo|enable|eval|exec|'+\n     'exit|fc|fg|getopts|hash|help|history|'+\n     'jobs|kill|let|logout|popd|printf|pushd|'+\n     'pwd|return|set|shift|shopt|source|'+\n     'suspend|test|times|trap|type|ulimit|'+\n     'umask|unalias|wait'\n);\n\nvar ShHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword\": reservedKeywords,\n        \"support.function.builtin\": languageConstructs,\n        \"invalid.deprecated\": \"debugger\"\n    }, \"identifier\");\n\n    var integer = \"(?:(?:[1-9]\\\\d*)|(?:0))\";\n    // var integer = \"(?:\" + decimalInteger + \")\";\n\n    var fraction = \"(?:\\\\.\\\\d+)\";\n    var intPart = \"(?:\\\\d+)\";\n    var pointFloat = \"(?:(?:\" + intPart + \"?\" + fraction + \")|(?:\" + intPart + \"\\\\.))\";\n    var exponentFloat = \"(?:(?:\" + pointFloat + \"|\" +  intPart + \")\" + \")\";\n    var floatNumber = \"(?:\" + exponentFloat + \"|\" + pointFloat + \")\";\n    var fileDescriptor = \"(?:&\" + intPart + \")\";\n\n    var variableName = \"[a-zA-Z_][a-zA-Z0-9_]*\";\n    var variable = \"(?:\" + variableName + \"(?==))\";\n\n    var builtinVariable = \"(?:\\\\$(?:SHLVL|\\\\$|\\\\!|\\\\?))\";\n\n    var func = \"(?:\" + variableName + \"\\\\s*\\\\(\\\\))\";\n\n    this.$rules = {\n        \"start\" : [{\n            token : \"constant\",\n            regex : /\\\\./\n        }, {\n            token : [\"text\", \"comment\"],\n            regex : /(^|\\s)(#.*)$/\n        }, {\n            token : \"string.start\",\n            regex : '\"',\n            push : [{\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:[$`\"\\\\]|$)/\n            }, {\n                include : \"variables\"\n            }, {\n                token : \"keyword.operator\",\n                regex : /`/ // TODO highlight `\n            }, {\n                token : \"string.end\",\n                regex : '\"',\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            token : \"string\",\n            regex : \"\\\\$'\",\n            push : [{\n                token : \"constant.language.escape\",\n                regex : /\\\\(?:[abeEfnrtv\\\\'\"]|x[a-fA-F\\d]{1,2}|u[a-fA-F\\d]{4}([a-fA-F\\d]{4})?|c.|\\d{1,3})/\n            }, {\n                token : \"string\",\n                regex : \"'\",\n                next: \"pop\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        }, {\n            regex : \"<<<\",\n            token : \"keyword.operator\"\n        }, {\n            stateName: \"heredoc\",\n            regex : \"(<<-?)(\\\\s*)(['\\\"`]?)([\\\\w\\\\-]+)(['\\\"`]?)\",\n            onMatch : function(value, currentState, stack) {\n                var next = value[2] == '-' ? \"indentedHeredoc\" : \"heredoc\";\n                var tokens = value.split(this.splitRegex);\n                stack.push(next, tokens[4]);\n                return [\n                    {type:\"constant\", value: tokens[1]},\n                    {type:\"text\", value: tokens[2]},\n                    {type:\"string\", value: tokens[3]},\n                    {type:\"support.class\", value: tokens[4]},\n                    {type:\"string\", value: tokens[5]}\n                ];\n            },\n            rules: {\n                heredoc: [{\n                    onMatch:  function(value, currentState, stack) {\n                        if (value === stack[1]) {\n                            stack.shift();\n                            stack.shift();\n                            this.next = stack[0] || \"start\";\n                            return \"support.class\";\n                        }\n                        this.next = \"\";\n                        return \"string\";\n                    },\n                    regex: \".*$\",\n                    next: \"start\"\n                }],\n                indentedHeredoc: [{\n                    token: \"string\",\n                    regex: \"^\\t+\"\n                }, {\n                    onMatch:  function(value, currentState, stack) {\n                        if (value === stack[1]) {\n                            stack.shift();\n                            stack.shift();\n                            this.next = stack[0] || \"start\";\n                            return \"support.class\";\n                        }\n                        this.next = \"\";\n                        return \"string\";\n                    },\n                    regex: \".*$\",\n                    next: \"start\"\n                }]\n            }\n        }, {\n            regex : \"$\",\n            token : \"empty\",\n            next : function(currentState, stack) {\n                if (stack[0] === \"heredoc\" || stack[0] === \"indentedHeredoc\")\n                    return stack[0];\n                return currentState;\n            }\n        }, {\n            token : [\"keyword\", \"text\", \"text\", \"text\", \"variable\"],\n            regex : /(declare|local|readonly)(\\s+)(?:(-[fixar]+)(\\s+))?([a-zA-Z_][a-zA-Z0-9_]*\\b)/\n        }, {\n            token : \"variable.language\",\n            regex : builtinVariable\n        }, {\n            token : \"variable\",\n            regex : variable\n        }, {\n            include : \"variables\"\n        }, {\n            token : \"support.function\",\n            regex : func\n        }, {\n            token : \"support.function\",\n            regex : fileDescriptor\n        }, {\n            token : \"string\",           // ' string\n            start : \"'\", end : \"'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : floatNumber\n        }, {\n            token : \"constant.numeric\", // integer\n            regex : integer + \"\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_][a-zA-Z0-9_]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|~|<|>|<=|=>|=|!=|[%&|`]\"\n        }, {\n            token : \"punctuation.operator\",\n            regex : \";\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\[\\\\(\\\\{]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\]]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)\\\\}]\",\n            next : \"pop\"\n        }],\n        variables: [{\n            token : \"variable\",\n            regex : /(\\$)(\\w+)/\n        }, {\n            token : [\"variable\", \"paren.lparen\"],\n            regex : /(\\$)(\\()/,\n            push : \"start\"\n        }, {\n            token : [\"variable\", \"paren.lparen\", \"keyword.operator\", \"variable\", \"keyword.operator\"],\n            regex : /(\\$)(\\{)([#!]?)(\\w+|[*@#?\\-$!0_])(:[?+\\-=]?|##?|%%?|,,?\\/|\\^\\^?)?/,\n            push : \"start\"\n        }, {\n            token : \"variable\",\n            regex : /\\$[*@#?\\-$!0_]/\n        }, {\n            token : [\"variable\", \"paren.lparen\"],\n            regex : /(\\$)(\\{)/,\n            push : \"start\"\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\noop.inherits(ShHighlightRules, TextHighlightRules);\n\nexports.ShHighlightRules = ShHighlightRules;\n"
  },
  {
    "path": "src/mode/sjs.js",
    "content": "\"use strict\";\nvar oop = require(\"../lib/oop\");\nvar JSMode = require(\"./javascript\").Mode;\nvar SJSHighlightRules = require(\"./sjs_highlight_rules\").SJSHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SJSHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, JSMode);\n(function() {\n    // disable jshint\n    this.createWorker = function(session) {\n        return null;\n    };\n    this.$id = \"ace/mode/sjs\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sjs_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SJSHighlightRules = function() {\n    var parent = new JavaScriptHighlightRules({noES6: true});\n    var escapedRe = \"\\\\\\\\(?:x[0-9a-fA-F]{2}|\" + // hex\n        \"u[0-9a-fA-F]{4}|\" + // unicode\n        \"[0-2][0-7]{0,2}|\" + // oct\n        \"3[0-6][0-7]?|\" + // oct\n        \"37[0-7]?|\" + // oct\n        \"[4-7][0-7]?|\" + //oct\n        \".)\";\n\n    var contextAware = function(f) {\n        f.isContextAware = true;\n        return f;\n    };\n\n    var ctxBegin = function(opts) {\n        return {\n            token: opts.token,\n            regex: opts.regex,\n            next: contextAware(function(currentState, stack) {\n                if (stack.length === 0)\n                    stack.unshift(currentState);\n                stack.unshift(opts.next);\n                return opts.next;\n            })\n        };\n    };\n\n    var ctxEnd = function(opts) {\n        return {\n            token: opts.token,\n            regex: opts.regex,\n            next: contextAware(function(currentState, stack) {\n                stack.shift();\n                return stack[0] || \"start\";\n            })\n        };\n    };\n\n    this.$rules = parent.$rules;\n    this.$rules.no_regex = [\n        {\n            token: \"keyword\",\n            regex: \"(waitfor|or|and|collapse|spawn|retract)\\\\b\"\n        },\n        {\n            token: \"keyword.operator\",\n            regex: \"(->|=>|\\\\.\\\\.)\"\n        },\n        {\n            token: \"variable.language\",\n            regex: \"(hold|default)\\\\b\"\n        },\n        ctxBegin({\n            token: \"string\",\n            regex: \"`\",\n            next: \"bstring\"\n        }),\n        ctxBegin({\n            token: \"string\",\n            regex: '\"',\n            next: \"qqstring\"\n        }),\n        ctxBegin({\n            token: \"string\",\n            regex: '\"',\n            next: \"qqstring\"\n        }),\n        {\n            token: [\"paren.lparen\", \"text\", \"paren.rparen\"],\n            regex: \"(\\\\{)(\\\\s*)(\\\\|)\",\n            next: \"block_arguments\"\n        }\n\n    ].concat(this.$rules.no_regex);\n\n    this.$rules.block_arguments = [\n        {\n            token: \"paren.rparen\",\n            regex: \"\\\\|\",\n            next: \"no_regex\"\n        }\n    ].concat(this.$rules.function_arguments);\n\n    this.$rules.bstring = [\n        {\n            token : \"constant.language.escape\",\n            regex : escapedRe\n        },\n        {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next: \"bstring\"\n        },\n        ctxBegin({\n            token : \"paren.lparen\",\n            regex : \"\\\\$\\\\{\",\n            next: \"string_interp\"\n        }),\n        ctxBegin({\n            token : \"paren.lparen\",\n            regex : \"\\\\$\",\n            next: \"bstring_interp_single\"\n        }),\n        ctxEnd({\n            token : \"string\",\n            regex : \"`\"\n        }),\n        {\n            defaultToken: \"string\"\n        }\n    ];\n    \n    this.$rules.qqstring = [\n        {\n            token : \"constant.language.escape\",\n            regex : escapedRe\n        },\n        {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next: \"qqstring\"\n        },\n        ctxBegin({\n            token : \"paren.lparen\",\n            regex : \"#\\\\{\",\n            next: \"string_interp\"\n        }),\n        ctxEnd({\n            token : \"string\",\n            regex : '\"'\n        }),\n        {\n            defaultToken: \"string\"\n        }\n    ];\n\n    // collect all context-aware (or stateless), brace-less\n    // states. This gives us most normal highlighting\n    // for use within interpreted contexts\n    // without interfering with context nesting\n    var embeddableRules = [];\n    for (var i=0; i < this.$rules.no_regex.length; i++) {\n        var rule = this.$rules.no_regex[i];\n        var token = String(rule.token);\n        if (token.indexOf('paren') == -1 && (!rule.next || rule.next.isContextAware)) {\n            embeddableRules.push(rule);\n        }\n    }\n\n    this.$rules.string_interp = [\n        ctxEnd({\n            token: \"paren.rparen\",\n            regex: \"\\\\}\"\n        }),\n        ctxBegin({\n            token: \"paren.lparen\",\n            regex: '{',\n            next: \"string_interp\"\n        })\n    ].concat(embeddableRules);\n\n    // backtick strings can have single interpolation, which accept\n    // \\w+ followed by an optional set of function call parens\n    this.$rules.bstring_interp_single = [\n        {\n            token: [\"identifier\", \"paren.lparen\"],\n            regex: '(\\\\w+)(\\\\()',\n            next: 'bstring_interp_single_call'\n        },\n        // identifier-only match ends this interp\n        ctxEnd({\n            token : \"identifier\",\n            regex : \"\\\\w*\"\n        })\n    ];\n    \n    // the call part of a bstring_interp_single\n    // is terminated by a close paren `)`, but\n    // can have nested parens.\n    this.$rules.bstring_interp_single_call = [\n        ctxBegin({\n            token: \"paren.lparen\",\n            regex: \"\\\\(\",\n            next: \"bstring_interp_single_call\"\n        }),\n        ctxEnd({\n            token: \"paren.rparen\",\n            regex: \"\\\\)\"\n        })\n    ].concat(embeddableRules);\n};\noop.inherits(SJSHighlightRules, TextHighlightRules);\n\nexports.SJSHighlightRules = SJSHighlightRules;\n"
  },
  {
    "path": "src/mode/slim.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SlimHighlightRules = require(\"./slim_highlight_rules\").SlimHighlightRules;\n\nvar Mode = function() {\n    TextMode.call(this);\n    this.HighlightRules = SlimHighlightRules;\n    this.createModeDelegates({\n        javascript: require(\"./javascript\").Mode,\n        markdown: require(\"./markdown\").Mode,\n        coffee: require(\"./coffee\").Mode,\n        scss: require(\"./scss\").Mode,\n        sass: require(\"./sass\").Mode,\n        less: require(\"./less\").Mode,\n        ruby: require(\"./ruby\").Mode,\n        css: require(\"./css\").Mode\n    });\n};\n\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.$id = \"ace/mode/slim\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/slim_highlight_rules.js",
    "content": "\"use strict\";\n\nvar modes = require(\"../config\").$modes;\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar SlimHighlightRules = function() {\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: \"keyword\",\n                regex: /^(\\s*)(\\w+):\\s*/,\n                onMatch: function(value, state, stack, line) {\n                    var indent = /^\\s*/.exec(line)[0];\n                    var m = value.match(/^(\\s*)(\\w+):/);\n                    var language = m[2];\n                    if (!/^(javascript|ruby|coffee|markdown|css|scss|sass|less)$/.test(language))\n                        language = \"\";\n                    stack.unshift(\"language-embed\", [], [indent, language], state);\n                    return this.token;\n                },\n                stateName: \"language-embed\",\n                next: [{\n                    token: \"string\",\n                    regex: /^(\\s*)/,\n                    onMatch: function(value, state, stack, line) {\n                        var indent = stack[2][0];\n                        if (indent.length >= value.length) {\n                            stack.splice(0, 3);\n                            this.next = stack.shift();\n                            return this.token;\n                        }\n                        this.next = \"\";\n                        return [{type: \"text\", value: indent}];\n                    },\n                    next: \"\"\n                }, {\n                    token: \"string\",\n                    regex: /.+/,\n                    onMatch: function(value, state, stack, line) {\n                        var indent = stack[2][0];\n                        var language = stack[2][1];\n                        var embedState = stack[1];\n                        \n                        if (modes[language]) {\n                            var data = modes[language].getTokenizer().getLineTokens(line.slice(indent.length), embedState.slice(0));\n                            stack[1] = data.state;\n                            return data.tokens;\n                        }\n                        return this.token;\n                    }\n                }]\n            },\n            {\n                token: 'constant.begin.javascript.filter.slim',\n                regex: '^(\\\\s*)():$'\n            }, {\n                token: 'constant.begin..filter.slim',\n                regex: '^(\\\\s*)(ruby):$'\n            }, {\n                token: 'constant.begin.coffeescript.filter.slim',\n                regex: '^(\\\\s*)():$'\n            }, {\n                token: 'constant.begin..filter.slim',\n                regex: '^(\\\\s*)(markdown):$'\n            }, {\n                token: 'constant.begin.css.filter.slim',\n                regex: '^(\\\\s*)():$'\n            }, {\n                token: 'constant.begin.scss.filter.slim',\n                regex: '^(\\\\s*)():$'\n            }, {\n                token: 'constant.begin..filter.slim',\n                regex: '^(\\\\s*)(sass):$'\n            }, {\n                token: 'constant.begin..filter.slim',\n                regex: '^(\\\\s*)(less):$'\n            }, {\n                token: 'constant.begin..filter.slim',\n                regex: '^(\\\\s*)(erb):$'\n            }, {\n                token: 'keyword.html.tags.slim',\n                regex: '^(\\\\s*)((:?\\\\*(\\\\w)+)|doctype html|abbr|acronym|address|applet|area|article|aside|audio|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dialog|dfn|dir|div|dl|dt|embed|fieldset|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|link|li|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|source|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video|xmp|b|u|s|em|a)(?:([.#](\\\\w|\\\\.)+)+\\\\s?)?\\\\b'\n\n            }, {\n                token: 'keyword.slim',\n                regex: '^(\\\\s*)(?:([.#](\\\\w|\\\\.)+)+\\\\s?)'\n            }, {\n                token: \"string\",\n                regex: /^(\\s*)('|\\||\\/|(\\/!))\\s*/,\n                onMatch: function(val, state, stack, line) {\n                    var indent = /^\\s*/.exec(line)[0];\n                    if (stack.length < 1) {\n                        stack.push(this.next);\n                    }\n                    else {\n                        stack[0] = \"mlString\";\n                    }\n\n                    if (stack.length < 2) {\n                        stack.push(indent.length);\n                    }\n                    else {\n                        stack[1] = indent.length;\n                    }\n                    return this.token;\n                },\n                next: \"mlString\"\n            }, {\n                token: 'keyword.control.slim',\n                regex: '^(\\\\s*)(\\\\-|==|=)',\n                push: [{\n                    token: 'control.end.slim',\n                    regex: '$',\n                    next: \"pop\"\n                }, {\n                    include: \"rubyline\"\n                }, {\n                    include: \"misc\"\n                }]\n\n            }, {\n                token: 'paren',\n                regex: '\\\\(',\n                push: [{\n                    token: 'paren',\n                    regex: '\\\\)',\n                    next: \"pop\"\n                }, {\n                    include: \"misc\"\n                }]\n\n            }, {\n                token: 'paren',\n                regex: '\\\\[',\n                push: [{\n                    token: 'paren',\n                    regex: '\\\\]',\n                    next: \"pop\"\n                }, {\n                    include: \"misc\"\n                }]\n            }, {\n                include: \"misc\"\n            }\n        ],\n        \"mlString\": [{\n            token: \"indent\",\n            regex: /^\\s*/,\n            onMatch: function(val, state, stack) {\n                var curIndent = stack[1];\n\n                if (curIndent >= val.length) {\n                    this.next = \"start\";\n                    stack.splice(0);\n                }\n                else {\n                    this.next = \"mlString\";\n                }\n                return this.token;\n            },\n            next: \"start\"\n        }, {\n            defaultToken: \"string\"\n        }],\n        \"rubyline\": [{\n            token: \"keyword.operator.ruby.embedded.slim\",\n            regex: \"(==|=)(<>|><|<'|'<|<|>)?|-\"\n        }, {\n            token: \"list.ruby.operators.slim\",\n            regex: \"(\\\\b)(for|in|do|if|else|elsif|unless|while|yield|not|and|or)\\\\b\"\n        }, {\n            token: \"string\",\n            regex: \"['](.)*?[']\"\n        }, {\n            token: \"string\",\n            regex: \"[\\\"](.)*?[\\\"]\"\n        }],\n        \"misc\": [{\n            token: 'class.variable.slim',\n            regex: '\\\\@([a-zA-Z_][a-zA-Z0-9_]*)\\\\b'\n        }, {\n            token: \"list.meta.slim\",\n            regex: \"(\\\\b)(true|false|nil)(\\\\b)\"\n        }, {\n            token: 'keyword.operator.equals.slim',\n            regex: '='\n        }, {\n            token: \"string\",\n            regex: \"['](.)*?[']\"\n        }, {\n            token: \"string\",\n            regex: \"[\\\"](.)*?[\\\"]\"\n        }]\n    };\n    this.normalizeRules();\n};\n\n\noop.inherits(SlimHighlightRules, TextHighlightRules);\n\nexports.SlimHighlightRules = SlimHighlightRules;\n"
  },
  {
    "path": "src/mode/smarty.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar SmartyHighlightRules = require(\"./smarty_highlight_rules\").SmartyHighlightRules;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = SmartyHighlightRules;\n};\n\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    \n    this.$id = \"ace/mode/smarty\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/smarty_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.github.com/amitsnyderman/sublime-smarty/master/Syntaxes/Smarty.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar SmartyHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n    var smartyRules = { start: \n       [ { include: '#comments' },\n         { include: '#blocks' } ],\n      '#blocks': \n       [ { token: 'punctuation.section.embedded.begin.smarty',\n           regex: '\\\\{%?',\n           push: \n            [ { token: 'punctuation.section.embedded.end.smarty',\n                regex: '%?\\\\}',\n                next: 'pop' },\n              { include: '#strings' },\n              { include: '#variables' },\n              { include: '#lang' },\n              { defaultToken: 'source.smarty' } ] } ],\n      '#comments': \n       [ { token: \n            [ 'punctuation.definition.comment.smarty',\n              'comment.block.smarty' ],\n           regex: '(\\\\{%?)(\\\\*)',\n           push: \n            [ { token: 'comment.block.smarty', regex: '\\\\*%?\\\\}', next: 'pop' },\n              { defaultToken: 'comment.block.smarty' } ] } ],\n      '#lang': \n       [ { token: 'keyword.operator.smarty',\n           regex: '(?:!=|!|<=|>=|<|>|===|==|%|&&|\\\\|\\\\|)|\\\\b(?:and|or|eq|neq|ne|gte|gt|ge|lte|lt|le|not|mod)\\\\b' },\n         { token: 'constant.language.smarty',\n           regex: '\\\\b(?:TRUE|FALSE|true|false)\\\\b' },\n         { token: 'keyword.control.smarty',\n           regex: '\\\\b(?:if|else|elseif|foreach|foreachelse|section|switch|case|break|default)\\\\b' },\n         { token: 'variable.parameter.smarty', regex: '\\\\b[a-zA-Z]+=' },\n         { token: 'support.function.built-in.smarty',\n           regex: '\\\\b(?:capture|config_load|counter|cycle|debug|eval|fetch|include_php|include|insert|literal|math|strip|rdelim|ldelim|assign|constant|block|html_[a-z_]*)\\\\b' },\n         { token: 'support.function.variable-modifier.smarty',\n           regex: '\\\\|(?:capitalize|cat|count_characters|count_paragraphs|count_sentences|count_words|date_format|default|escape|indent|lower|nl2br|regex_replace|replace|spacify|string_format|strip_tags|strip|truncate|upper|wordwrap)' } ],\n      '#strings': \n       [ { token: 'punctuation.definition.string.begin.smarty',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.smarty',\n                regex: '\\'',\n                next: 'pop' },\n              { token: 'constant.character.escape.smarty', regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.single.smarty' } ] },\n         { token: 'punctuation.definition.string.begin.smarty',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.smarty',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.smarty', regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.double.smarty' } ] } ],\n      '#variables': \n       [ { token: \n            [ 'punctuation.definition.variable.smarty',\n              'variable.other.global.smarty' ],\n           regex: '\\\\b(\\\\$)(Smarty\\\\.)' },\n         { token: \n            [ 'punctuation.definition.variable.smarty',\n              'variable.other.smarty' ],\n           regex: '(\\\\$)([a-zA-Z_][a-zA-Z0-9_]*)\\\\b' },\n         { token: [ 'keyword.operator.smarty', 'variable.other.property.smarty' ],\n           regex: '(->)([a-zA-Z_][a-zA-Z0-9_]*)\\\\b' },\n         { token: \n            [ 'keyword.operator.smarty',\n              'meta.function-call.object.smarty',\n              'punctuation.definition.variable.smarty',\n              'variable.other.smarty',\n              'punctuation.definition.variable.smarty' ],\n           regex: '(->)([a-zA-Z_][a-zA-Z0-9_]*)(\\\\()(.*?)(\\\\))' } ] };\n    \n    var smartyStart = smartyRules.start;\n    \n    for (var rule in this.$rules) {\n        this.$rules[rule].unshift.apply(this.$rules[rule], smartyStart);\n    }\n    \n    Object.keys(smartyRules).forEach(function(x) {\n        if (!this.$rules[x])\n            this.$rules[x] = smartyRules[x];\n    }, this);\n    \n    this.normalizeRules();\n};\n\nSmartyHighlightRules.metaData = { fileTypes: [ 'tpl' ],\n      foldingStartMarker: '\\\\{%?',\n      foldingStopMarker: '%?\\\\}',\n      name: 'Smarty',\n      scopeName: 'text.html.smarty' };\n\n\noop.inherits(SmartyHighlightRules, HtmlHighlightRules);\n\nexports.SmartyHighlightRules = SmartyHighlightRules;\n"
  },
  {
    "path": "src/mode/smithy.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SmithyHighlightRules = require(\"./smithy_highlight_rules\").SmithyHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SmithyHighlightRules;\n\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.$quotes = {'\"': '\"'};\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    this.$id = \"ace/mode/smithy\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/smithy_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.githubusercontent.com/awslabs/smithy-vscode/master/syntaxes/smithy.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SmithyHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            include: \"#comment\"\n        }, {\n            token: [\n                \"meta.keyword.statement.smithy\",\n                \"variable.other.smithy\",\n                \"text\",\n                \"keyword.operator.smithy\"\n            ],\n            regex: /^(\\$)(\\s+.+)(\\s*)(=)/\n        }, {\n            token: [\n                \"keyword.statement.smithy\",\n                \"text\",\n                \"entity.name.type.namespace.smithy\"\n            ],\n            regex: /^(namespace)(\\s+)([A-Z-a-z0-9_\\.#$-]+)/\n        }, {\n            token: [\n                \"keyword.statement.smithy\",\n                \"text\",\n                \"keyword.statement.smithy\",\n                \"text\",\n                \"entity.name.type.smithy\"\n            ],\n            regex: /^(use)(\\s+)(shape|trait)(\\s+)([A-Z-a-z0-9_\\.#$-]+)\\b/\n        }, {\n            token: [\n                \"keyword.statement.smithy\",\n                \"variable.other.smithy\",\n                \"text\",\n                \"keyword.operator.smithy\"\n            ],\n            regex: /^(metadata)(\\s+.+)(\\s*)(=)/\n        }, {\n            token: [\n                \"keyword.statement.smithy\",\n                \"text\",\n                \"entity.name.type.smithy\"\n            ],\n            regex: /^(apply|byte|short|integer|long|float|double|bigInteger|bigDecimal|boolean|blob|string|timestamp|service|resource|trait|list|map|set|structure|union|document)(\\s+)([A-Z-a-z0-9_\\.#$-]+)\\b/\n        }, {\n            token: [\n                \"keyword.operator.smithy\",\n                \"text\",\n                \"entity.name.type.smithy\",\n                \"text\",\n                \"text\",\n                \"support.function.smithy\",\n                \"text\",\n                \"text\",\n                \"support.function.smithy\"\n            ],\n            regex: /^(operation)(\\s+)([A-Z-a-z0-9_\\.#$-]+)(\\(.*\\))(?:(\\s*)(->)(\\s*[A-Z-a-z0-9_\\.#$-]+))?(?:(\\s+)(errors))?/\n        }, {\n            include: \"#trait\"\n        }, {\n            token: [\n                \"support.type.property-name.smithy\",\n                \"punctuation.separator.dictionary.pair.smithy\"\n            ],\n            regex: /([A-Z-a-z0-9_\\.#$-]+)(:)/\n        }, {\n            include: \"#value\"\n        }, {\n            token: \"keyword.other.smithy\",\n            regex: /\\->/\n        }],\n        \"#comment\": [{\n            include: \"#doc_comment\"\n        }, {\n            include: \"#line_comment\"\n        }],\n        \"#doc_comment\": [{\n            token: \"comment.block.documentation.smithy\",\n            regex: /\\/\\/\\/.*/\n        }],\n        \"#line_comment\": [{\n            token: \"comment.line.double-slash.smithy\",\n            regex: /\\/\\/.*/\n        }],\n        \"#trait\": [{\n            token: [\n                \"punctuation.definition.annotation.smithy\",\n                \"storage.type.annotation.smithy\"\n            ],\n            regex: /(@)([0-9a-zA-Z\\.#-]+)/\n        }, {\n            token: [\n                \"punctuation.definition.annotation.smithy\",\n                \"punctuation.definition.object.end.smithy\",\n                \"meta.structure.smithy\"\n            ],\n            regex: /(@)([0-9a-zA-Z\\.#-]+)(\\()/,\n            push: [{\n                token: \"punctuation.definition.object.end.smithy\",\n                regex: /\\)/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                include: \"#object_inner\"\n            }, {\n                defaultToken: \"meta.structure.smithy\"\n            }]\n        }],\n        \"#value\": [{\n            include: \"#constant\"\n        }, {\n            include: \"#number\"\n        }, {\n            include: \"#string\"\n        }, {\n            include: \"#array\"\n        }, {\n            include: \"#object\"\n        }],\n        \"#array\": [{\n            token: \"punctuation.definition.array.begin.smithy\",\n            regex: /\\[/,\n            push: [{\n                token: \"punctuation.definition.array.end.smithy\",\n                regex: /\\]/,\n                next: \"pop\"\n            }, {\n                include: \"#comment\"\n            }, {\n                include: \"#value\"\n            }, {\n                token: \"punctuation.separator.array.smithy\",\n                regex: /,/\n            }, {\n                token: \"invalid.illegal.expected-array-separator.smithy\",\n                regex: /[^\\s\\]]/\n            }, {\n                defaultToken: \"meta.structure.array.smithy\"\n            }]\n        }],\n        \"#constant\": [{\n            token: \"constant.language.smithy\",\n            regex: /\\b(?:true|false|null)\\b/\n        }],\n        \"#number\": [{\n            token: \"constant.numeric.smithy\",\n            regex: /-?(?:0|[1-9]\\d*)(?:(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)?/\n        }],\n        \"#object\": [{\n            token: \"punctuation.definition.dictionary.begin.smithy\",\n            regex: /\\{/,\n            push: [{\n                token: \"punctuation.definition.dictionary.end.smithy\",\n                regex: /\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#trait\"\n            }, {\n                include: \"#object_inner\"\n            }, {\n                defaultToken: \"meta.structure.dictionary.smithy\"\n            }]\n        }],\n        \"#object_inner\": [{\n            include: \"#comment\"\n        }, {\n            include: \"#string_key\"\n        }, {\n            token: \"punctuation.separator.dictionary.key-value.smithy\",\n            regex: /:/,\n            push: [{\n                token: \"punctuation.separator.dictionary.pair.smithy\",\n                regex: /,|(?=\\})/,\n                next: \"pop\"\n            }, {\n                include: \"#value\"\n            }, {\n                token: \"invalid.illegal.expected-dictionary-separator.smithy\",\n                regex: /[^\\s,]/\n            }, {\n                defaultToken: \"meta.structure.dictionary.value.smithy\"\n            }]\n        }, {\n            token: \"invalid.illegal.expected-dictionary-separator.smithy\",\n            regex: /[^\\s\\}]/\n        }],\n        \"#string_key\": [{\n            include: \"#identifier_key\"\n        }, {\n            include: \"#dquote_key\"\n        }, {\n            include: \"#squote_key\"\n        }],\n        \"#identifier_key\": [{\n            token: \"support.type.property-name.smithy\",\n            regex: /[A-Z-a-z0-9_\\.#$-]+/\n        }],\n        \"#dquote_key\": [{\n            include: \"#dquote\"\n        }],\n        \"#squote_key\": [{\n            include: \"#squote\"\n        }],\n        \"#string\": [{\n            include: \"#textblock\"\n        }, {\n            include: \"#dquote\"\n        }, {\n            include: \"#squote\"\n        }, {\n            include: \"#identifier\"\n        }],\n        \"#textblock\": [{\n            token: \"punctuation.definition.string.begin.smithy\",\n            regex: /\"\"\"/,\n            push: [{\n                token: \"punctuation.definition.string.end.smithy\",\n                regex: /\"\"\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.smithy\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.smithy\"\n            }]\n        }],\n        \"#dquote\": [{\n            token: \"punctuation.definition.string.begin.smithy\",\n            regex: /\"/,\n            push: [{\n                token: \"punctuation.definition.string.end.smithy\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.smithy\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.smithy\"\n            }]\n        }],\n        \"#squote\": [{\n            token: \"punctuation.definition.string.begin.smithy\",\n            regex: /'/,\n            push: [{\n                token: \"punctuation.definition.string.end.smithy\",\n                regex: /'/,\n                next: \"pop\"\n            }, {\n                token: \"constant.character.escape.smithy\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.single.smithy\"\n            }]\n        }],\n        \"#identifier\": [{\n            token: \"storage.type.smithy\",\n            regex: /[A-Z-a-z_][A-Z-a-z0-9_\\.#$-]*/\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nSmithyHighlightRules.metaData = {\n    name: \"Smithy\",\n    fileTypes: [\"smithy\"],\n    scopeName: \"source.smithy\",\n    foldingStartMarker: \"(\\\\{|\\\\[)\\\\s*\",\n    foldingStopMarker: \"\\\\s*(\\\\}|\\\\])\"\n};\n\n\noop.inherits(SmithyHighlightRules, TextHighlightRules);\n\nexports.SmithyHighlightRules = SmithyHighlightRules;\n"
  },
  {
    "path": "src/mode/snippets.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SnippetHighlightRules = function() {\n\n    var builtins = \"SELECTION|CURRENT_WORD|SELECTED_TEXT|CURRENT_LINE|LINE_INDEX|\" +\n        \"LINE_NUMBER|SOFT_TABS|TAB_SIZE|FILENAME|FILEPATH|FULLNAME\";\n\n    this.$rules = {\n        \"start\" : [\n            {token:\"constant.language.escape\", regex: /\\\\[\\$}`\\\\]/},\n            {token:\"keyword\", regex: \"\\\\$(?:TM_)?(?:\" + builtins + \")\\\\b\"},\n            {token:\"variable\", regex: \"\\\\$\\\\w+\"},\n            {onMatch: function(value, state, stack) {\n                if (stack[1])\n                    stack[1]++;\n                else\n                    stack.unshift(state, 1);\n                return this.tokenName;\n            }, tokenName: \"markup.list\", regex: \"\\\\${\", next: \"varDecl\"},\n            {onMatch: function(value, state, stack) {\n                if (!stack[1])\n                    return \"text\";\n                stack[1]--;\n                if (!stack[1])\n                    stack.splice(0,2);\n                return this.tokenName;\n            }, tokenName: \"markup.list\", regex: \"}\"},\n            {token: \"doc.comment\", regex:/^\\${2}-{5,}$/}\n        ],\n        \"varDecl\" : [\n            {regex: /\\d+\\b/, token: \"constant.numeric\"},\n            {token:\"keyword\", regex: \"(?:TM_)?(?:\" + builtins + \")\\\\b\"},\n            {token:\"variable\", regex: \"\\\\w+\"},\n            {regex: /:/, token: \"punctuation.operator\", next: \"start\"},\n            {regex: /\\//, token: \"string.regex\", next: \"regexp\"},\n            {regex: \"\", next: \"start\"}\n        ],\n        \"regexp\" : [\n            {regex: /\\\\./, token: \"escape\"},\n            {regex: /\\[/, token: \"regex.start\", next: \"charClass\"},\n            {regex: \"/\", token: \"string.regex\", next: \"format\"},\n            //{\"default\": \"string.regex\"},\n            {\"token\": \"string.regex\", regex:\".\"}\n        ],\n        charClass : [\n            {regex: \"\\\\.\", token: \"escape\"},\n            {regex: \"\\\\]\", token: \"regex.end\", next: \"regexp\"},\n            {\"token\": \"string.regex\", regex:\".\"}\n        ],\n        \"format\" : [\n            {regex: /\\\\[ulULE]/, token: \"keyword\"},\n            {regex: /\\$\\d+/, token: \"variable\"},\n            {regex: \"/[gim]*:?\", token: \"string.regex\", next: \"start\"},\n            // {\"default\": \"string\"},\n            {\"token\": \"string\", regex:\".\"}\n        ]\n    };\n};\noop.inherits(SnippetHighlightRules, TextHighlightRules);\n\nexports.SnippetHighlightRules = SnippetHighlightRules;\n\nvar SnippetGroupHighlightRules = function() {\n    this.$rules = {\n        \"start\" : [\n            {token: \"text\", regex: \"^\\\\t\", next: \"sn-start\"},\n            {token:\"invalid\", regex: /^ \\s*/},\n            {token:\"comment\", regex: /^#.*/},\n            {token:\"constant.language.escape\", regex: \"^regex \", next: \"regex\"},\n            {token:\"constant.language.escape\", regex: \"^(trigger|endTrigger|name|snippet|guard|endGuard|tabTrigger|key)\\\\b\"}\n        ],\n        \"regex\" : [\n            {token:\"text\", regex: \"\\\\.\"},\n            {token:\"keyword\", regex: \"/\"},\n            {token:\"empty\", regex: \"$\", next: \"start\"}\n        ]\n    };\n    this.embedRules(SnippetHighlightRules, \"sn-\", [\n        {token: \"text\", regex: \"^\\\\t\", next: \"sn-start\"},\n        {onMatch: function(value, state, stack) {\n            stack.splice(stack.length);\n            return this.tokenName;\n        }, tokenName: \"text\", regex: \"^(?!\\t)\", next: \"start\"}\n    ]);\n    \n};\n\noop.inherits(SnippetGroupHighlightRules, TextHighlightRules);\n\nexports.SnippetGroupHighlightRules = SnippetGroupHighlightRules;\n\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SnippetGroupHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.$indentWithTabs = true;\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/snippets\";\n    this.snippetFileId = \"ace/snippets/snippets\";\n}).call(Mode.prototype);\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/soy_template.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar SoyTemplateHighlightRules = require(\"./soy_template_highlight_rules\").SoyTemplateHighlightRules;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = SoyTemplateHighlightRules;\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$id = \"ace/mode/soy_template\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/soy_template_highlight_rules.js",
    "content": "/* This file was autogenerated from tm bundles\\SoyTemplate\\Syntaxes\\SoyTemplate.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar SoyTemplateHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var soyRules = { start: \n       [ { include: '#template' },\n         { include: '#if' },\n         { include: '#comment-line' },\n         { include: '#comment-block' },\n         { include: '#comment-doc' },\n         { include: '#call' },\n         { include: '#css' },\n         { include: '#param' },\n         { include: '#print' },\n         { include: '#msg' },\n         { include: '#for' },\n         { include: '#foreach' },\n         { include: '#switch' },\n         { include: '#tag' },\n         { include: 'text.html.basic' } ],\n      '#call': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.call.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(?=call|delcall)',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#string-quoted-single' },\n              { include: '#string-quoted-double' },\n              { token: ['entity.name.tag.soy', 'variable.parameter.soy'],\n                regex: '(call|delcall)(\\\\s+[\\\\.\\\\w]+)'},\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy' ],\n                regex: '\\\\b(data)(\\\\s*)(=)' },\n              { defaultToken: 'meta.tag.call.soy' } ] } ],\n      '#comment-line': \n       [ { token: \n            [ 'comment.line.double-slash.soy',\n              'comment.line.double-slash.soy' ],\n           regex: '(//)(.*$)' } ],\n      '#comment-block': \n       [ { token: 'punctuation.definition.comment.begin.soy',\n           regex: '/\\\\*(?!\\\\*)',\n           push: \n            [ { token: 'punctuation.definition.comment.end.soy',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.soy' } ] } ],\n      '#comment-doc': \n       [ { token: 'punctuation.definition.comment.begin.soy',\n           regex: '/\\\\*\\\\*(?!/)',\n           push: \n            [ { token: 'punctuation.definition.comment.end.soy',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { token: [ 'support.type.soy', 'text', 'variable.parameter.soy' ],\n                regex: '(@param|@param\\\\?)(\\\\s+)(\\\\w+)' },\n              { defaultToken: 'comment.block.documentation.soy' } ] } ],\n      '#css': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.css.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(css)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { token: 'support.constant.soy',\n                regex: '\\\\b(?:LITERAL|REFERENCE|BACKEND_SPECIFIC|GOOG)\\\\b' },\n              { defaultToken: 'meta.tag.css.soy' } ] } ],\n      '#for': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.for.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(for)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { token: 'keyword.operator.soy', regex: '\\\\bin\\\\b' },\n              { token: 'support.function.soy', regex: '\\\\brange\\\\b' },\n              { include: '#variable' },\n              { include: '#number' },\n              { include: '#primitive' },\n              { defaultToken: 'meta.tag.for.soy' } ] } ],\n      '#foreach': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.foreach.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(foreach)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { token: 'keyword.operator.soy', regex: '\\\\bin\\\\b' },\n              { include: '#variable' },\n              { defaultToken: 'meta.tag.foreach.soy' } ] } ],\n      '#function': \n       [ { token: 'support.function.soy',\n           regex: '\\\\b(?:isFirst|isLast|index|hasData|length|keys|round|floor|ceiling|min|max|randomInt)\\\\b' } ],\n      '#if': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.if.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(if|elseif)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#variable' },\n              { include: '#operator' },\n              { include: '#function' },\n              { include: '#string-quoted-single' },\n              { include: '#string-quoted-double' },\n              { defaultToken: 'meta.tag.if.soy' } ] } ],\n      '#namespace': \n       [ { token: [ 'entity.name.tag.soy', 'text', 'variable.parameter.soy' ],\n           regex: '(namespace|delpackage)(\\\\s+)([\\\\w\\\\.]+)' } ],\n      '#number': [ { token: 'constant.numeric', regex: '[\\\\d]+' } ],\n      '#operator': \n       [ { token: 'keyword.operator.soy',\n           regex: '==|!=|\\\\band\\\\b|\\\\bor\\\\b|\\\\bnot\\\\b|-|\\\\+|/|\\\\?:' } ],\n      '#param': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.param.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(param)',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#variable' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy' ],\n                regex: '\\\\b([\\\\w]+)(\\\\s*)((?::)?)' },\n              { defaultToken: 'meta.tag.param.soy' } ] } ],\n      '#primitive': \n       [ { token: 'constant.language.soy',\n           regex: '\\\\b(?:null|false|true)\\\\b' } ],\n      '#msg': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.msg.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(msg)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#string-quoted-single' },\n              { include: '#string-quoted-double' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy' ],\n                regex: '\\\\b(meaning|desc)(\\\\s*)(=)' },\n              { defaultToken: 'meta.tag.msg.soy' } ] } ],\n      '#print': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.print.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(print)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#variable' },\n              { include: '#print-parameter' },\n              { include: '#number' },\n              { include: '#primitive' },\n              { include: '#attribute-lookup' },\n              { defaultToken: 'meta.tag.print.soy' } ] } ],\n      '#print-parameter': \n       [ { token: 'keyword.operator.soy', regex: '\\\\|' },\n         { token: 'variable.parameter.soy',\n           regex: 'noAutoescape|id|escapeHtml|escapeJs|insertWorkBreaks|truncate' } ],\n      '#special-character': \n       [ { token: 'support.constant.soy',\n           regex: '\\\\bsp\\\\b|\\\\bnil\\\\b|\\\\\\\\r|\\\\\\\\n|\\\\\\\\t|\\\\blb\\\\b|\\\\brb\\\\b' } ],\n      '#string-quoted-double': [ { token: 'string.quoted.double', regex: '\"[^\"]*\"' } ],\n      '#string-quoted-single': [ { token: 'string.quoted.single', regex: '\\'[^\\']*\\'' } ],\n      '#switch': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.switch.soy',\n              'entity.name.tag.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(switch|case)\\\\b',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#variable' },\n              { include: '#function' },\n              { include: '#number' },\n              { include: '#string-quoted-single' },\n              { include: '#string-quoted-double' },\n              { defaultToken: 'meta.tag.switch.soy' } ] } ],\n      '#attribute-lookup': \n       [ { token: 'punctuation.definition.attribute-lookup.begin.soy',\n           regex: '\\\\[',\n           push: \n            [ { token: 'punctuation.definition.attribute-lookup.end.soy',\n                regex: '\\\\]',\n                next: 'pop' },\n              { include: '#variable' },\n              { include: '#function' },\n              { include: '#operator' },\n              { include: '#number' },\n              { include: '#primitive' },\n              { include: '#string-quoted-single' },\n              { include: '#string-quoted-double' } ] } ],\n      '#tag': \n       [ { token: 'punctuation.definition.tag.begin.soy',\n           regex: '\\\\{',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { include: '#namespace' },\n              { include: '#variable' },\n              { include: '#special-character' },\n              { include: '#tag-simple' },\n              { include: '#function' },\n              { include: '#operator' },\n              { include: '#attribute-lookup' },\n              { include: '#number' },\n              { include: '#primitive' },\n              { include: '#print-parameter' } ] } ],\n      '#tag-simple': \n       [ { token: 'entity.name.tag.soy',\n           regex: '{{\\\\s*(?:literal|else|ifempty|default)\\\\s*(?=\\\\})'} ],\n      '#template': \n       [ { token: \n            [ 'punctuation.definition.tag.begin.soy',\n              'meta.tag.template.soy' ],\n           regex: '(\\\\{/?)(\\\\s*)(?=template|deltemplate)',\n           push: \n            [ { token: 'punctuation.definition.tag.end.soy',\n                regex: '\\\\}',\n                next: 'pop' },\n              { token: ['entity.name.tag.soy', 'text', 'entity.name.function.soy' ],\n                regex: '(template|deltemplate)(\\\\s+)([\\\\.\\\\w]+)',\n                originalRegex: '(?<=template|deltemplate)\\\\s+([\\\\.\\\\w]+)' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy',\n                   'text',\n                   'string.quoted.double.soy' ],\n                regex: '\\\\b(private)(\\\\s*)(=)(\\\\s*)(\"true\"|\"false\")' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy',\n                   'text',\n                   'string.quoted.single.soy' ],\n                regex: '\\\\b(private)(\\\\s*)(=)(\\\\s*)(\\'true\\'|\\'false\\')' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy',\n                   'text',\n                   'string.quoted.double.soy' ],\n                regex: '\\\\b(autoescape)(\\\\s*)(=)(\\\\s*)(\"true\"|\"false\"|\"contextual\")' },\n              { token: \n                 [ 'entity.other.attribute-name.soy',\n                   'text',\n                   'keyword.operator.soy',\n                   'text',\n                   'string.quoted.single.soy' ],\n                regex: '\\\\b(autoescape)(\\\\s*)(=)(\\\\s*)(\\'true\\'|\\'false\\'|\\'contextual\\')' },\n              { defaultToken: 'meta.tag.template.soy' } ] } ],\n      '#variable': [ { token: 'variable.other.soy', regex: '\\\\$[\\\\w\\\\.]+' } ] };\n    \n    \n    for (var i in soyRules) {\n        if (this.$rules[i]) {\n            this.$rules[i].unshift.apply(this.$rules[i], soyRules[i]);\n        } else {\n            this.$rules[i] = soyRules[i];\n        }\n    }\n    \n    this.normalizeRules();\n};\n\nSoyTemplateHighlightRules.metaData = { comment: 'SoyTemplate',\n      fileTypes: [ 'soy' ],\n      firstLineMatch: '\\\\{\\\\s*namespace\\\\b',\n      foldingStartMarker: '\\\\{\\\\s*template\\\\s+[^\\\\}]*\\\\}',\n      foldingStopMarker: '\\\\{\\\\s*/\\\\s*template\\\\s*\\\\}',\n      name: 'SoyTemplate',\n      scopeName: 'source.soy' };\n\n\noop.inherits(SoyTemplateHighlightRules, HtmlHighlightRules);\n\nexports.SoyTemplateHighlightRules = SoyTemplateHighlightRules;\n"
  },
  {
    "path": "src/mode/space.js",
    "content": "\"use strict\";\nvar oop = require(\"../lib/oop\");\n// defines the parent mode\nvar TextMode = require(\"./text\").Mode;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n// defines the language specific highlighters and folding rules\nvar SpaceHighlightRules = require(\"./space_highlight_rules\").SpaceHighlightRules;\nvar Mode = function() {\n    // set everything up\n    this.HighlightRules = SpaceHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n(function() {\n    \n    this.$id = \"ace/mode/space\";\n}).call(Mode.prototype);\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/space_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SpaceHighlightRules = function() {\n\n    // Todo: support multiline values that escape the newline with spaces.\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"empty_line\",\n                regex : / */,\n                next : \"key\"\n            },\n            {\n                token : \"empty_line\",\n                regex : /$/,\n                next : \"key\"\n            }\n        ],\n        \"key\" : [\n            {\n                token : \"variable\",\n                regex : /\\S+/\n            },\n            {\n                token : \"empty_line\",\n                regex : /$/,\n                next : \"start\"\n            },{\n                token : \"keyword.operator\",\n                regex : / /,\n                next  : \"value\"\n            }\n        ],\n        \"value\" : [\n            {\n                token : \"keyword.operator\",\n                regex : /$/,\n                next  : \"start\"\n            },\n            {\n                token : \"string\",\n                regex : /[^$]/\n            }\n        ]\n    };\n    \n};\n\noop.inherits(SpaceHighlightRules, TextHighlightRules);\n\nexports.SpaceHighlightRules = SpaceHighlightRules;\n"
  },
  {
    "path": "src/mode/sparql.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SPARQLHighlightRules = require(\"./sparql_highlight_rules\").SPARQLHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SPARQLHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // this.lineCommentStart = \"\"#\"\";\n    // Extra logic goes here.\n    this.$id = \"ace/mode/sparql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sparql_highlight_rules.js",
    "content": "/* This file was autogenerated from sparql.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SPARQLHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            include: \"#comments\"\n        }, {\n            include: \"#strings\"\n        }, {\n            include: \"#string-language-suffixes\"\n        }, {\n            include: \"#string-datatype-suffixes\"\n        }, {\n            include: \"#logic-operators\"\n        }, {\n            include: \"#relative-urls\"\n        }, {\n            include: \"#xml-schema-types\"\n        }, {\n            include: \"#rdf-schema-types\"\n        }, {\n            include: \"#owl-types\"\n        }, {\n            include: \"#qnames\"\n        }, {\n            include: \"#keywords\"\n        }, {\n            include: \"#built-in-functions\"\n        }, {\n            include: \"#variables\"\n        }, {\n            include: \"#boolean-literal\"\n        }, {\n            include: \"#punctuation-operators\"\n        }],\n        \"#boolean-literal\": [{\n            token: \"constant.language.boolean.sparql\",\n            regex: /true|false/\n        }],\n        \"#built-in-functions\": [{\n            token: \"support.function.sparql\",\n            regex: /[Aa][Bb][Ss]|[Aa][Vv][Gg]|[Bb][Nn][Oo][Dd][Ee]|[Bb][Oo][Uu][Nn][Dd]|[Cc][Ee][Ii][Ll]|[Cc][Oo][Aa][Ll][Ee][Ss][Cc][Ee]|[Cc][Oo][Nn][Cc][Aa][Tt]|[Cc][Oo][Nn][Tt][Aa][Ii][Nn][Ss]|[Cc][Oo][Uu][Nn][Tt]|[Dd][Aa][Tt][Aa][Tt][Yy][Pp][Ee]|[Dd][Aa][Yy]|[Ee][Nn][Cc][Oo][Dd][Ee]_[Ff][Oo][Rr]_[Uu][Rr][Ii]|[Ee][Xx][Ii][Ss][Tt][Ss]|[Ff][Ll][Oo][Oo][Rr]|[Gg][Rr][Oo][Uu][Pp]_[Cc][Oo][Nn][Cc][Aa][Tt]|[Hh][Oo][Uu][Rr][Ss]|[Ii][Ff]|[Ii][Rr][Ii]|[Ii][Ss][Bb][Ll][Aa][Nn][Kk]|[Ii][Ss][Ii][Rr][Ii]|[Ii][Ss][Ll][Ii][Tt][Ee][Rr][Aa][Ll]|[Ii][Ss][Nn][Uu][Mm][Ee][Rr][Ii][Cc]|[Ii][Ss][Uu][Rr][Ii]|[Ll][Aa][Nn][Gg]|[Ll][Aa][Nn][Gg][Mm][Aa][Tt][Cc][Hh][Ee][Ss]|[Ll][Cc][Aa][Ss][Ee]|[Mm][Aa][Xx]|[Mm][Dd]5|[Mm][Ii][Nn]|[Mm][Ii][Nn][Uu][Tt][Ee][Ss]|[Mm][Oo][Nn][Tt][Hh]|[Nn][Oo][Ww]|[Rr][Aa][Nn][Dd]|[Rr][Ee][Gg][Ee][Xx]|[Rr][Ee][Pp][Ll][Aa][Cc][Ee]|[Rr][Oo][Uu][Nn][Dd]|[Ss][Aa][Mm][Ee][Tt][Ee][Rr][Mm]|[Ss][Aa][Mm][Pp][Ll][Ee]|[Ss][Ee][Cc][Oo][Nn][Dd][Ss]|[Ss][Ee][Pp][Aa][Rr][Aa][Tt][Oo][Rr]|[Ss][Hh][Aa](?:1|256|384|512)|[Ss][Tt][Rr]|[Ss][Tt][Rr][Aa][Ff][Tt][Ee][Rr]|[Ss][Tt][Rr][Bb][Ee][Ff][Oo][Rr][Ee]|[Ss][Tt][Rr][Dd][Tt]|[Ss][Tt][Rr][Ee][Nn][Dd][Ss]|[Ss][Tt][Rr][Ll][Aa][Nn][Gg]|[Ss][Tt][Rr][Ll][Ee][Nn]|[Ss][Tt][Rr][Ss][Tt][Aa][Rr][Tt][Ss]|[Ss][Tt][Rr][Uu][Uu][Ii][Dd]|[Ss][Uu][Bb][Ss][Tt][Rr]|[Ss][Uu][Mm]|[Tt][Ii][Mm][Ee][Zz][Oo][Nn][Ee]|[Tt][Zz]|[Uu][Cc][Aa][Ss][Ee]|[Uu][Rr][Ii]|[Uu][Uu][Ii][Dd]|[Yy][Ee][Aa][Rr]/\n        }],\n        \"#comments\": [{\n            token: [\n                \"punctuation.definition.comment.sparql\",\n                \"comment.line.hash.sparql\"\n            ],\n            regex: /(#)(.*$)/\n        }],\n        \"#keywords\": [{\n            token: \"keyword.other.sparql\",\n            regex: /[Aa][Dd][Dd]|[Aa][Ll][Ll]|[Aa][Ss]|[As][Ss][Cc]|[Aa][Ss][Kk]|[Bb][Aa][Ss][Ee]|[Bb][Ii][Nn][Dd]|[Bb][Yy]|[Cc][Ll][Ee][Aa][Rr]|[Cc][Oo][Nn][Ss][Tt][Rr][Uu][Cc][Tt]|[Cc][Oo][Pp][Yy]|[Cc][Rr][Ee][Aa][Tt][Ee]|[Dd][Aa][Tt][Aa]|[Dd][Ee][Ff][Aa][Uu][Ll][Tt]|[Dd][Ee][Ll][Ee][Tt][Ee]|[Dd][Ee][Sc][Cc]|[Dd][Ee][Ss][Cc][Rr][Ii][Bb][Ee]|[Dd][Ii][Ss][Tt][Ii][Nn][Cc][Tt]|[Dd][Rr][Oo][Pp]|[Ff][Ii][Ll][Tt][Ee][Rr]|[Ff][Rr][Oo][Mm]|[Gg][Rr][Aa][Pp][Hh]|[Gg][Rr][Oo][Uu][Pp]|[Hh][Aa][Vv][Ii][Nn][Gg]|[Ii][Nn][Ss][Ee][Rr][Tt]|[Ll][Ii][Mm][Ii][Tt]|[Ll][Oo][Aa][Dd]|[Mm][Ii][Nn][Uu][Ss]|[Mm][Oo][Vv][Ee]|[Nn][Aa][Mm][Ee][Dd]|[Oo][Ff][Ff][Ss][Ee][Tt]|[Oo][Pp][Tt][Ii][Oo][Nn][Aa][Ll]|[Oo][Rr][Dd][Ee][Rr]|[Pp][Rr][Ee][Ff][Ii][Xx]|[Rr][Ee][Dd][Uu][Cc][Ee][Dd]|[Ss][Ee][Ll][Ee][Cc][Tt]|[Ss][Ee][Pp][Aa][Rr][Aa][Tt][Oo][Rr]|[Ss][Ee][Rr][Vv][Ii][Cc][Ee]|[Ss][Ii][Ll][Ee][Nn][Tt]|[Tt][Oo]|[Uu][Nn][Dd][Ee][Ff]|[Uu][Nn][Ii][Oo][Nn]|[Uu][Ss][Ii][Nn][Gg]|[Vv][Aa][Ll][Uu][Ee][Ss]|[Ww][He][Ee][Rr][Ee]|[Ww][Ii][Tt][Hh]/\n        }],\n        \"#logic-operators\": [{\n            token: \"keyword.operator.logical.sparql\",\n            regex: /\\|\\||&&|=|!=|<|>|<=|>=|(?:^|!?\\s)IN(?:!?\\s|$)|(?:^|!?\\s)NOT(?:!?\\s|$)|-|\\+|\\*|\\/|\\!/\n        }],\n        \"#owl-types\": [{\n            token: \"support.type.datatype.owl.sparql\",\n            regex: /owl:[a-zA-Z]+/\n        }],\n        \"#punctuation-operators\": [{\n            token: \"keyword.operator.punctuation.sparql\",\n            regex: /;|,|\\.|\\(|\\)|\\{|\\}|\\|/\n        }],\n        \"#qnames\": [{\n            token: \"entity.name.other.qname.sparql\",\n            regex: /(?:[a-zA-Z][-_a-zA-Z0-9]*)?:(?:[_a-zA-Z][-_a-zA-Z0-9]*)?/\n        }],\n        \"#rdf-schema-types\": [{\n            token: \"support.type.datatype.rdf.schema.sparql\",\n            regex: /rdfs?:[a-zA-Z]+|(?:^|\\s)a(?:\\s|$)/\n        }],\n        \"#relative-urls\": [{\n            token: \"string.quoted.other.relative.url.sparql\",\n            regex: /</,\n            push: [{\n                token: \"string.quoted.other.relative.url.sparql\",\n                regex: />/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.other.relative.url.sparql\"\n            }]\n        }],\n        \"#string-datatype-suffixes\": [{\n            token: \"keyword.operator.datatype.suffix.sparql\",\n            regex: /\\^\\^/\n        }],\n        \"#string-language-suffixes\": [{\n            token: [\n                \"keyword.operator.language.suffix.sparql\",\n                \"constant.language.suffix.sparql\"\n            ],\n            regex: /(?!\")(@)([a-z]+(?:\\-[a-z0-9]+)*)/\n        }],\n        \"#strings\": [{\n            token: \"string.quoted.triple.sparql\",\n            regex: /\"\"\"/,\n            push: [{\n                token: \"string.quoted.triple.sparql\",\n                regex: /\"\"\"/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.triple.sparql\"\n            }]\n        }, {\n            token: \"string.quoted.double.sparql\",\n            regex: /\"/,\n            push: [{\n                token: \"string.quoted.double.sparql\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"invalid.string.newline\",\n                regex: /$/\n            }, {\n                token: \"constant.character.escape.sparql\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.sparql\"\n            }]\n        }],\n        \"#variables\": [{\n            token: \"variable.other.sparql\",\n            regex: /(?:\\?|\\$)[-_a-zA-Z0-9]+/\n        }],\n        \"#xml-schema-types\": [{\n            token: \"support.type.datatype.schema.sparql\",\n            regex: /xsd?:[a-z][a-zA-Z]+/\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nSPARQLHighlightRules.metaData = {\n    fileTypes: [\"rq\", \"sparql\"],\n    name: \"SPARQL\",\n    scopeName: \"source.sparql\"\n};\n\n\noop.inherits(SPARQLHighlightRules, TextHighlightRules);\n\nexports.SPARQLHighlightRules = SPARQLHighlightRules;\n"
  },
  {
    "path": "src/mode/sql.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SqlHighlightRules = require(\"./sql_highlight_rules\").SqlHighlightRules;\nvar SqlFoldMode = require(\"./folding/sql\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SqlHighlightRules;\n    this.foldingRules = new SqlFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.$id = \"ace/mode/sql\";\n    this.snippetFileId = \"ace/snippets/sql\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sql_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SqlHighlightRules = function() {\n\n    var keywords = (\n        \"select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|\" +\n        \"when|then|else|end|type|left|right|join|on|outer|desc|asc|union|create|table|primary|key|if|\" +\n        \"foreign|not|references|default|null|inner|cross|natural|database|drop|grant|distinct|is|in|\" + \n        \"all|alter|any|array|at|authorization|between|both|cast|check|collate|column|commit|constraint|\"+\n        \"cube|current|current_date|current_time|current_timestamp|current_user|describe|escape|except|\" +\n        \"exists|external|extract|fetch|filter|for|full|function|global|grouping|intersect|interval|\" + \n        \"into|leading|like|local|no|of|only|out|overlaps|partition|position|range|revoke|rollback|rollup|\" +\n        \"row|rows|session_user|set|some|start|tablesample|time|to|trailing|truncate|unique|unknown|\" + \n        \"user|using|values|window|with\"\n    );\n\n    var builtinConstants = (\n        \"true|false\"\n    );\n\n    var builtinFunctions = (\n        \"avg|count|first|last|max|min|sum|ucase|lcase|mid|len|round|rank|now|format|\" + \n        \"coalesce|ifnull|isnull|nvl\"\n    );\n\n    var dataTypes = (\n        \"int|numeric|decimal|date|varchar|char|bigint|float|double|bit|binary|text|set|timestamp|\" +\n        \"money|real|number|integer|string\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants,\n        \"storage.type\": dataTypes\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"--.*$\"\n        },  {\n            token : \"comment\",\n            start : \"/\\\\*\",\n            end : \"\\\\*/\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\".*?\"'\n        }, {\n            token : \"string\",           // ' string\n            regex : \"'.*?'\"\n        }, {\n            token : \"string\",           // ` string (apache drill)\n            regex : \"`.*?`\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(SqlHighlightRules, TextHighlightRules);\n\nexports.SqlHighlightRules = SqlHighlightRules;\n"
  },
  {
    "path": "src/mode/sqlserver.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar SqlServerHighlightRules = require(\"./sqlserver_highlight_rules\").SqlHighlightRules;\nvar SqlServerFoldMode = require(\"./folding/sqlserver\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = SqlServerHighlightRules;\n    this.foldingRules = new SqlServerFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"--\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    /**\n     * Override keyword completions using list created in highlight rules\n     */\n    this.getCompletions = function(state, session, pos, prefix) {\n        return session.$mode.$highlightRules.completions;\n    };\n    \n    this.$id = \"ace/mode/sqlserver\";\n    this.snippetFileId = \"ace/snippets/sqlserver\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/sqlserver_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SqlServerHighlightRules = function() {\n    /**\n     * Transact-SQL Syntax Conventions: https://msdn.microsoft.com/en-us/library/ms177563.aspx\n     * Goal: make this imitate SSMS (SQL Server Managment Studio)\n     */\n\n    // https://msdn.microsoft.com/en-us/library/ms189773.aspx\n    var logicalOperators = \"ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|SOME\";\n    logicalOperators += \"|NULL|IS|APPLY|INNER|OUTER|LEFT|RIGHT|JOIN|CROSS\"; //SSMS colors these gray too\n    //note: manually removed LEFT and RIGHT from built in functions below to color it same way SSMS does\n    \n\n    var builtinFunctions = (\n        /* https://msdn.microsoft.com/en-us/library/ms187957.aspx */\n        \"OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms173454.aspx */\n        \"AVG|CHECKSUM_AGG|COUNT|COUNT_BIG|GROUPING|GROUPING_ID|MAX|MIN|STDEV|STDEVP|SUM|VAR|VARP|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms189798.aspx */\n        \"DENSE_RANK|NTILE|RANK|ROW_NUMBER\" +\n        /* https://msdn.microsoft.com/en-us/library/ms173823.aspx */\n        \"@@DATEFIRST|@@DBTS|@@LANGID|@@LANGUAGE|@@LOCK_TIMEOUT|@@MAX_CONNECTIONS|@@MAX_PRECISION|@@NESTLEVEL|@@OPTIONS|@@REMSERVER|@@SERVERNAME|@@SERVICENAME|@@SPID|@@TEXTSIZE|@@VERSION|\" +\n        /* https://msdn.microsoft.com/en-us/library/hh231076.aspx */\n        \"CAST|CONVERT|PARSE|TRY_CAST|TRY_CONVERT|TRY_PARSE\" +\n        /* https://msdn.microsoft.com/en-us/library/ms186285.aspx */\n        \"@@CURSOR_ROWS|@@FETCH_STATUS|CURSOR_STATUS|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms186724.aspx */\n        \"@@DATEFIRST|@@LANGUAGE|CURRENT_TIMESTAMP|DATEADD|DATEDIFF|DATEFROMPARTS|DATENAME|DATEPART|DATETIME2FROMPARTS|DATETIMEFROMPARTS|DATETIMEOFFSETFROMPARTS|DAY|EOMONTH|GETDATE|GETUTCDATE|ISDATE|MONTH|SET DATEFIRST|SET DATEFORMAT|SET LANGUAGE|SMALLDATETIMEFROMPARTS|SP_HELPLANGUAGE|SWITCHOFFSET|SYSDATETIME|SYSDATETIMEOFFSET|SYSUTCDATETIME|TIMEFROMPARTS|TODATETIMEOFFSET|YEAR|DATETRUNC|\" +\n        /* https://msdn.microsoft.com/en-us/library/hh213226.aspx */\n        \"CHOOSE|IIF|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms177516.aspx */\n        \"ABS|ACOS|ASIN|ATAN|ATN2|CEILING|COS|COT|DEGREES|EXP|FLOOR|LOG|LOG10|PI|POWER|RADIANS|RAND|ROUND|SIGN|SIN|SQRT|SQUARE|TAN|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms187812.aspx */\n        \"@@PROCID|APPLOCK_MODE|APPLOCK_TEST|APP_NAME|ASSEMBLYPROPERTY|COLUMNPROPERTY|COL_LENGTH|COL_NAME|DATABASEPROPERTYEX|DATABASE_PRINCIPAL_ID|DB_ID|DB_NAME|FILEGROUPPROPERTY|FILEGROUP_ID|FILEGROUP_NAME|FILEPROPERTY|FILE_ID|FILE_IDEX|FILE_NAME|FULLTEXTCATALOGPROPERTY|FULLTEXTSERVICEPROPERTY|INDEXKEY_PROPERTY|INDEXPROPERTY|INDEX_COL|OBJECTPROPERTY|OBJECTPROPERTYEX|OBJECT_DEFINITION|OBJECT_ID|OBJECT_NAME|OBJECT_SCHEMA_NAME|ORIGINAL_DB_NAME|PARSENAME|SCHEMA_ID|SCHEMA_NAME|SCOPE_IDENTITY|SERVERPROPERTY|STATS_DATE|TYPEPROPERTY|TYPE_ID|TYPE_NAME|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms186236.aspx */\n        \"CERTENCODED|CERTPRIVATEKEY|CURRENT_USER|DATABASE_PRINCIPAL_ID|HAS_PERMS_BY_NAME|IS_MEMBER|IS_ROLEMEMBER|IS_SRVROLEMEMBER|ORIGINAL_LOGIN|PERMISSIONS|PWDCOMPARE|PWDENCRYPT|SCHEMA_ID|SCHEMA_NAME|SESSION_USER|SUSER_ID|SUSER_NAME|SUSER_SID|SUSER_SNAME|SYS.FN_BUILTIN_PERMISSIONS|SYS.FN_GET_AUDIT_FILE|SYS.FN_MY_PERMISSIONS|SYSTEM_USER|USER_ID|USER_NAME|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms181984.aspx */\n        \"ASCII|CHAR|CHARINDEX|CONCAT|DIFFERENCE|FORMAT|LEN|LOWER|LTRIM|NCHAR|PATINDEX|QUOTENAME|REPLACE|REPLICATE|REVERSE|RTRIM|SOUNDEX|SPACE|STR|STUFF|SUBSTRING|UNICODE|UPPER|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms187786.aspx */\n        \"$PARTITION|@@ERROR|@@IDENTITY|@@PACK_RECEIVED|@@ROWCOUNT|@@TRANCOUNT|BINARY_CHECKSUM|CHECKSUM|CONNECTIONPROPERTY|CONTEXT_INFO|CURRENT_REQUEST_ID|ERROR_LINE|ERROR_MESSAGE|ERROR_NUMBER|ERROR_PROCEDURE|ERROR_SEVERITY|ERROR_STATE|FORMATMESSAGE|GETANSINULL|GET_FILESTREAM_TRANSACTION_CONTEXT|HOST_ID|HOST_NAME|ISNULL|ISNUMERIC|MIN_ACTIVE_ROWVERSION|NEWID|NEWSEQUENTIALID|ROWCOUNT_BIG|XACT_STATE|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms177520.aspx */\n        \"@@CONNECTIONS|@@CPU_BUSY|@@IDLE|@@IO_BUSY|@@PACKET_ERRORS|@@PACK_RECEIVED|@@PACK_SENT|@@TIMETICKS|@@TOTAL_ERRORS|@@TOTAL_READ|@@TOTAL_WRITE|FN_VIRTUALFILESTATS|\" +\n        /* https://msdn.microsoft.com/en-us/library/ms188353.aspx */\n        \"PATINDEX|TEXTPTR|TEXTVALID|\" +\n        /* logical */\n        \"GREATEST|LEAST|\" +\n        /* time series functions */\n        \"GENERATE_SERIES|DATE_BUCKET|\" +\n        /* JSON functions */\n        \"JSON_ARRAY|JSON_OBJECT|JSON_PATH_EXISTS|ISJSON|\" +\n        /* window functions */\n        \"FIRST_VALUE|LAST_VALUE|\" +\n        /* other */\n        \"COALESCE|NULLIF\"\n    );\n    \n\n    // https://msdn.microsoft.com/en-us/library/ms187752.aspx\n    var dataTypes = (\"BIGINT|BINARY|BIT|CHAR|CURSOR|DATE|DATETIME|DATETIME2|DATETIMEOFFSET|DECIMAL|FLOAT|HIERARCHYID|IMAGE|INTEGER|INT|MONEY|NCHAR|NTEXT|NUMERIC|NVARCHAR|REAL|SMALLDATETIME|SMALLINT|SMALLMONEY|SQL_VARIANT|TABLE|TEXT|TIME|TIMESTAMP|TINYINT|UNIQUEIDENTIFIER|VARBINARY|VARCHAR|XML\");\n    \n    \n    //https://msdn.microsoft.com/en-us/library/ms176007.aspx (these are lower case!)\n    var builtInStoredProcedures = \"sp_addextendedproc|sp_addextendedproperty|sp_addmessage|sp_addtype|sp_addumpdevice|sp_add_data_file_recover_suspect_db|sp_add_log_file_recover_suspect_db|sp_altermessage|sp_attach_db|sp_attach_single_file_db|sp_autostats|sp_bindefault|sp_bindrule|sp_bindsession|sp_certify_removable|sp_clean_db_file_free_space|sp_clean_db_free_space|sp_configure|sp_control_plan_guide|sp_createstats|sp_create_plan_guide|sp_create_plan_guide_from_handle|sp_create_removable|sp_cycle_errorlog|sp_datatype_info|sp_dbcmptlevel|sp_dbmmonitoraddmonitoring|sp_dbmmonitorchangealert|sp_dbmmonitorchangemonitoring|sp_dbmmonitordropalert|sp_dbmmonitordropmonitoring|sp_dbmmonitorhelpalert|sp_dbmmonitorhelpmonitoring|sp_dbmmonitorresults|sp_db_increased_partitions|sp_delete_backuphistory|sp_depends|sp_describe_first_result_set|sp_describe_undeclared_parameters|sp_detach_db|sp_dropdevice|sp_dropextendedproc|sp_dropextendedproperty|sp_dropmessage|sp_droptype|sp_execute|sp_executesql|sp_getapplock|sp_getbindtoken|sp_help|sp_helpconstraint|sp_helpdb|sp_helpdevice|sp_helpextendedproc|sp_helpfile|sp_helpfilegroup|sp_helpindex|sp_helplanguage|sp_helpserver|sp_helpsort|sp_helpstats|sp_helptext|sp_helptrigger|sp_indexoption|sp_invalidate_textptr|sp_lock|sp_monitor|sp_prepare|sp_prepexec|sp_prepexecrpc|sp_procoption|sp_recompile|sp_refreshview|sp_releaseapplock|sp_rename|sp_renamedb|sp_resetstatus|sp_sequence_get_range|sp_serveroption|sp_setnetname|sp_settriggerorder|sp_spaceused|sp_tableoption|sp_unbindefault|sp_unbindrule|sp_unprepare|sp_updateextendedproperty|sp_updatestats|sp_validname|sp_who|sys.sp_merge_xtp_checkpoint_files|sys.sp_xtp_bind_db_resource_pool|sys.sp_xtp_checkpoint_force_garbage_collection|sys.sp_xtp_control_proc_exec_stats|sys.sp_xtp_control_query_exec_stats|sys.sp_xtp_unbind_db_resource_pool\";\n    \n    \n    // https://msdn.microsoft.com/en-us/library/ms189822.aspx\n    var keywords = \"ABSOLUTE|ACTION|ADA|ADD|ADMIN|AFTER|AGGREGATE|ALIAS|ALL|ALLOCATE|ALTER|AND|ANY|ARE|ARRAY|AS|ASC|ASENSITIVE|ASSERTION|ASYMMETRIC|AT|ATOMIC|AUTHORIZATION|BACKUP|BEFORE|BEGIN|BETWEEN|BIT_LENGTH|BLOB|BOOLEAN|BOTH|BREADTH|BREAK|BROWSE|BULK|BY|CALL|CALLED|CARDINALITY|CASCADE|CASCADED|CASE|CATALOG|CHARACTER|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CHECKPOINT|CLASS|CLOB|CLOSE|CLUSTERED|COALESCE|COLLATE|COLLATION|COLLECT|COLUMN|COMMIT|COMPLETION|COMPUTE|CONDITION|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONSTRUCTOR|CONTAINS|CONTAINSTABLE|CONTINUE|CORR|CORRESPONDING|COVAR_POP|COVAR_SAMP|CREATE|CROSS|CUBE|CUME_DIST|CURRENT|CURRENT_CATALOG|CURRENT_DATE|CURRENT_DEFAULT_TRANSFORM_GROUP|CURRENT_PATH|CURRENT_ROLE|CURRENT_SCHEMA|CURRENT_TIME|CURRENT_TRANSFORM_GROUP_FOR_TYPE|CYCLE|DATA|DATABASE|DBCC|DEALLOCATE|DEC|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DENY|DEPTH|DEREF|DESC|DESCRIBE|DESCRIPTOR|DESTROY|DESTRUCTOR|DETERMINISTIC|DIAGNOSTICS|DICTIONARY|DISCONNECT|DISK|DISTINCT|DISTRIBUTED|DOMAIN|DOUBLE|DROP|DUMP|DYNAMIC|EACH|ELEMENT|ELSE|END|END-EXEC|EQUALS|ERRLVL|ESCAPE|EVERY|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXISTS|EXIT|EXTERNAL|EXTRACT|FETCH|FILE|FILLFACTOR|FILTER|FIRST|FOR|FOREIGN|FORTRAN|FOUND|FREE|FREETEXT|FREETEXTTABLE|FROM|FULL|FULLTEXTTABLE|FUNCTION|FUSION|GENERAL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|HAVING|HOLD|HOLDLOCK|HOST|HOUR|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IGNORE|IMMEDIATE|IN|INCLUDE|INDEX|INDICATOR|INITIALIZE|INITIALLY|INNER|INOUT|INPUT|INSENSITIVE|INSERT|INTEGER|INTERSECT|INTERSECTION|INTERVAL|INTO|IS|ISOLATION|ITERATE|JOIN|KEY|KILL|LANGUAGE|LARGE|LAST|LATERAL|LEADING|LESS|LEVEL|LIKE|LIKE_REGEX|LIMIT|LINENO|LN|LOAD|LOCAL|LOCALTIME|LOCALTIMESTAMP|LOCATOR|MAP|MATCH|MEMBER|MERGE|METHOD|MINUTE|MOD|MODIFIES|MODIFY|MODULE|MULTISET|NAMES|NATIONAL|NATURAL|NCLOB|NEW|NEXT|NO|NOCHECK|NONCLUSTERED|NONE|NORMALIZE|NOT|NULL|NULLIF|OBJECT|OCCURRENCES_REGEX|OCTET_LENGTH|OF|OFF|OFFSETS|OLD|ON|ONLY|OPEN|OPERATION|OPTION|OR|ORDER|ORDINALITY|OUT|OUTER|OUTPUT|OVER|OVERLAPS|OVERLAY|PAD|PARAMETER|PARAMETERS|PARTIAL|PARTITION|PASCAL|PATH|PERCENT|PERCENTILE_CONT|PERCENTILE_DISC|PERCENT_RANK|PIVOT|PLAN|POSITION|POSITION_REGEX|POSTFIX|PRECISION|PREFIX|PREORDER|PREPARE|PRESERVE|PRIMARY|PRINT|PRIOR|PRIVILEGES|PROC|PROCEDURE|PUBLIC|RAISERROR|RANGE|READ|READS|READTEXT|RECONFIGURE|RECURSIVE|REF|REFERENCES|REFERENCING|REGR_AVGX|REGR_AVGY|REGR_COUNT|REGR_INTERCEPT|REGR_R2|REGR_SLOPE|REGR_SXX|REGR_SXY|REGR_SYY|RELATIVE|RELEASE|REPLICATION|RESTORE|RESTRICT|RESULT|RETURN|RETURNS|REVERT|REVOKE|ROLE|ROLLBACK|ROLLUP|ROUTINE|ROW|ROWCOUNT|ROWGUIDCOL|ROWS|RULE|SAVE|SAVEPOINT|SCHEMA|SCOPE|SCROLL|SEARCH|SECOND|SECTION|SECURITYAUDIT|SELECT|SEMANTICKEYPHRASETABLE|SEMANTICSIMILARITYDETAILSTABLE|SEMANTICSIMILARITYTABLE|SENSITIVE|SEQUENCE|SESSION|SET|SETS|SETUSER|SHUTDOWN|SIMILAR|SIZE|SOME|SPECIFIC|SPECIFICTYPE|SQL|SQLCA|SQLCODE|SQLERROR|SQLEXCEPTION|SQLSTATE|SQLWARNING|START|STATE|STATEMENT|STATIC|STATISTICS|STDDEV_POP|STDDEV_SAMP|STRUCTURE|SUBMULTISET|SUBSTRING_REGEX|STRING_SPLIT|SYMMETRIC|SYSTEM|TABLESAMPLE|TEMPORARY|TERMINATE|TEXTSIZE|THAN|THEN|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TOP|TRAILING|TRAN|TRANSACTION|TRANSLATE|TRANSLATE_REGEX|TRANSLATION|TREAT|TRIGGER|TRIM|TRUNCATE|TSEQUAL|UESCAPE|UNDER|UNION|UNIQUE|UNKNOWN|UNNEST|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARIABLE|VARYING|VAR_POP|VAR_SAMP|VIEW|WAITFOR|WHEN|WHENEVER|WHERE|WHILE|WIDTH_BUCKET|WINDOW|WITH|WITHIN|WITHIN GROUP|WITHOUT|WORK|WRITE|WRITETEXT|XMLAGG|XMLATTRIBUTES|XMLBINARY|XMLCAST|XMLCOMMENT|XMLCONCAT|XMLDOCUMENT|XMLELEMENT|XMLEXISTS|XMLFOREST|XMLITERATE|XMLNAMESPACES|XMLPARSE|XMLPI|XMLQUERY|XMLSERIALIZE|XMLTABLE|XMLTEXT|XMLVALIDATE|ZONE\";\n    \n    \n    // Microsoft's keyword list is missing a lot of things that are located on various other pages\n    // https://msdn.microsoft.com/en-us/library/ms187373.aspx, https://msdn.microsoft.com/en-us/library/ms181714.aspx\n    keywords += \"|KEEPIDENTITY|KEEPDEFAULTS|IGNORE_CONSTRAINTS|IGNORE_TRIGGERS|XLOCK|FORCESCAN|FORCESEEK|HOLDLOCK|NOLOCK|NOWAIT|PAGLOCK|READCOMMITTED|READCOMMITTEDLOCK|READPAST|READUNCOMMITTED|REPEATABLEREAD|ROWLOCK|SERIALIZABLE|SNAPSHOT|SPATIAL_WINDOW_MAX_CELLS|TABLOCK|TABLOCKX|UPDLOCK|XLOCK|IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX|EXPAND|VIEWS|FAST|FORCE|KEEP|KEEPFIXED|MAXDOP|MAXRECURSION|OPTIMIZE|PARAMETERIZATION|SIMPLE|FORCED|RECOMPILE|ROBUST|PLAN|SPATIAL_WINDOW_MAX_CELLS|NOEXPAND|HINT\";\n    // https://msdn.microsoft.com/en-us/library/ms173815.aspx\n    keywords += \"|LOOP|HASH|MERGE|REMOTE\";\n    // https://msdn.microsoft.com/en-us/library/ms175976.aspx\n    keywords += \"|TRY|CATCH|THROW\";\n    // highlighted words in SSMS that I'm not even sure where they come from\n    keywords += \"|TYPE\";\n    \n    \n    //remove specific built in types from keyword list\n    keywords = keywords.split('|');\n    keywords = keywords.filter(function(value, index, self) {\n        return logicalOperators.split('|').indexOf(value) === -1 && builtinFunctions.split('|').indexOf(value) === -1 && dataTypes.split('|').indexOf(value) === -1;\n    });\n    keywords = keywords.sort().join('|');\n    \n    \n    var keywordMapper = this.createKeywordMapper({\n        \"constant.language\": logicalOperators,\n        \"storage.type\": dataTypes,\n        \"support.function\": builtinFunctions,\n        \"support.storedprocedure\": builtInStoredProcedures,\n        \"keyword\": keywords\n    }, \"identifier\", true);\n    \n    \n    //https://msdn.microsoft.com/en-us/library/ms190356.aspx\n    var setStatements = \"SET ANSI_DEFAULTS|SET ANSI_NULLS|SET ANSI_NULL_DFLT_OFF|SET ANSI_NULL_DFLT_ON|SET ANSI_PADDING|SET ANSI_WARNINGS|SET ARITHABORT|SET ARITHIGNORE|SET CONCAT_NULL_YIELDS_NULL|SET CURSOR_CLOSE_ON_COMMIT|SET DATEFIRST|SET DATEFORMAT|SET DEADLOCK_PRIORITY|SET FIPS_FLAGGER|SET FMTONLY|SET FORCEPLAN|SET IDENTITY_INSERT|SET IMPLICIT_TRANSACTIONS|SET LANGUAGE|SET LOCK_TIMEOUT|SET NOCOUNT|SET NOEXEC|SET NUMERIC_ROUNDABORT|SET OFFSETS|SET PARSEONLY|SET QUERY_GOVERNOR_COST_LIMIT|SET QUOTED_IDENTIFIER|SET REMOTE_PROC_TRANSACTIONS|SET ROWCOUNT|SET SHOWPLAN_ALL|SET SHOWPLAN_TEXT|SET SHOWPLAN_XML|SET STATISTICS IO|SET STATISTICS PROFILE|SET STATISTICS TIME|SET STATISTICS XML|SET TEXTSIZE|SET XACT_ABORT\".split('|');\n    var isolationLevels = \"READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SNAPSHOP|SERIALIZABLE\".split('|');\n    for (var i = 0; i < isolationLevels.length; i++) {\n        setStatements.push('SET TRANSACTION ISOLATION LEVEL ' + isolationLevels[i]);\n    }\n    \n    \n    this.$rules = {\n        start: [{\n            token: \"string.start\",\n            regex: \"'\",\n            next: [{\n                token: \"constant.language.escape\",\n                regex: /''/\n            }, {\n                token: \"string.end\",\n                next: \"start\",\n                regex: \"'\"\n            }, {\n                defaultToken: \"string\"\n            }]\n        },\n        DocCommentHighlightRules.getStartRule(\"doc-start\"), {\n            token: \"comment\",\n            regex: \"--.*$\"\n        }, {\n            token: \"comment\",\n            start: \"/\\\\*\",\n            end: \"\\\\*/\"\n        }, {\n            token: \"constant.numeric\", // float\n            regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token: keywordMapper,\n            regex: \"@{0,2}[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b(?!])\" //up to 2 @symbols for some built in functions\n        }, {\n            token: \"constant.class\",\n            regex: \"@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            //https://msdn.microsoft.com/en-us/library/ms174986.aspx\n            token: \"keyword.operator\",\n            regex: \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=|\\\\*\"\n        }, {\n            token: \"paren.lparen\",\n            regex: \"[\\\\(]\"\n        }, {\n            token: \"paren.rparen\",\n            regex: \"[\\\\)]\"\n        }, {\n            token: \"punctuation\",\n            regex: \",|;\"\n        }, {\n            token: \"text\",\n            regex: \"\\\\s+\"\n        }],\n        comment: [\n        DocCommentHighlightRules.getTagRule(), {\n            token: \"comment\",\n            regex: \"\\\\*\\\\/\",\n            next: \"start\"\n        }, {\n            defaultToken: \"comment\",\n            caseInsensitive: true\n        }]\n    };\n    \n    //add each set statment as regex at top of rules so that they are processed first because they require multiple words\n    //note: this makes the statements not match if they are not upper case.. which is not ideal but I don't know of an easy way to fix this\n    for (var i = 0; i < setStatements.length; i++) {\n        this.$rules.start.unshift({\n            token: \"set.statement\",\n            regex: setStatements[i]\n        });\n    }\n    \n    this.embedRules(DocCommentHighlightRules, \"doc-\", [DocCommentHighlightRules.getEndRule(\"start\")]);\n    this.normalizeRules();\n    \n    \n    //prepare custom keyword completions used by mode to override default completor\n    //this allows for custom 'meta' and proper case of completions\n    var completions = [];\n    var addCompletions = function(arr, meta) {\n        arr.forEach(function(v) {\n            completions.push({\n                name: v,\n                value: v,\n                score: 0,\n                meta: meta\n            });\n        });\n    };\n    addCompletions(builtInStoredProcedures.split('|'), 'procedure');\n    addCompletions(logicalOperators.split('|'), 'operator');\n    addCompletions(builtinFunctions.split('|'), 'function');\n    addCompletions(dataTypes.split('|'), 'type');\n    addCompletions(setStatements, 'statement');\n    addCompletions(keywords.split('|'), 'keyword');\n    \n    this.completions = completions;\n};\n\noop.inherits(SqlServerHighlightRules, TextHighlightRules);\n\nexports.SqlHighlightRules = SqlServerHighlightRules;\n"
  },
  {
    "path": "src/mode/stylus.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar StylusHighlightRules = require(\"./stylus_highlight_rules\").StylusHighlightRules;\nvar FoldMode = require(\"./folding/coffee\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = StylusHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.$id = \"ace/mode/stylus\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/stylus_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY Stylus.tmlanguage (UUID: 60519324-6A3A-4382-9E0B-546993A3869A) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CssHighlightRules = require(\"./css_highlight_rules\");\n\nvar StylusHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.type\": CssHighlightRules.supportType,\n        \"support.function\": CssHighlightRules.supportFunction,\n        \"support.constant\": CssHighlightRules.supportConstant,\n        \"support.constant.color\": CssHighlightRules.supportConstantColor,\n        \"support.constant.fonts\": CssHighlightRules.supportConstantFonts\n    }, \"text\", true);\n\n    this.$rules = {\n    start: [\n        {\n            token : \"comment\",\n            regex : /\\/\\/.*$/\n        },\n        {\n            token : \"comment\", // multi line comment\n            regex : /\\/\\*/,\n            next : \"comment\"\n        },\n        {\n            token: [\"entity.name.function.stylus\", \"text\"],\n            regex: \"^([-a-zA-Z_][-\\\\w]*)?(\\\\()\"\n        },\n        {\n            token: [\"entity.other.attribute-name.class.stylus\"],\n            regex: \"\\\\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*\"\n        },\n        {\n            token: [\"entity.language.stylus\"],\n            regex: \"^ *&\"\n        },\n        {\n            token: [\"variable.language.stylus\"],\n            regex: \"(arguments)\"\n        },\n        {\n            token: [\"keyword.stylus\"],\n            regex: \"@[-\\\\w]+\"\n        },\n        {\n            token : [\"punctuation\", \"entity.other.attribute-name.pseudo-element.css\"],\n            regex : CssHighlightRules.pseudoElements\n        }, {\n            token : [\"punctuation\", \"entity.other.attribute-name.pseudo-class.css\"],\n            regex : CssHighlightRules.pseudoClasses\n        }, \n        {\n            token: [\"entity.name.tag.stylus\"],\n            regex: \"(?:\\\\b)(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|(?:h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)(?:\\\\b)\"\n        },\n        {\n            token: \"constant.numeric\",  // hex6 color\n            regex: \"#[a-fA-F0-9]{6}\"\n        }, \n        {\n            token: \"constant.numeric\", // hex3 color\n            regex: \"#[a-fA-F0-9]{3}\"\n        }, \n        {\n            token: [\"punctuation.definition.entity.stylus\", \"entity.other.attribute-name.id.stylus\"],\n            regex: \"(#)([a-zA-Z][a-zA-Z0-9_-]*)\"\n        },\n        {\n            token: \"meta.vendor-prefix.stylus\",\n            regex: \"-webkit-|-moz\\\\-|-ms-|-o-\"\n        },\n        {\n            token: \"keyword.control.stylus\",\n            regex: \"(?:!important|for|in|return|true|false|null|if|else|unless|return)\\\\b\"\n        },\n        {\n            token: \"keyword.operator.stylus\",\n            regex: \"!|~|\\\\+|-|(?:\\\\*)?\\\\*|\\\\/|%|(?:\\\\.)\\\\.\\\\.|<|>|(?:=|:|\\\\?|\\\\+|-|\\\\*|\\\\/|%|<|>)?=|!=\"\n        },\n        {\n            token: \"keyword.operator.stylus\",\n            regex: \"(?:in|is(?:nt)?|not)\\\\b\"\n        },\n        {\n            token : \"string\",\n            regex : \"'(?=.)\",\n            next  : \"qstring\"\n        }, {\n            token : \"string\",\n            regex : '\"(?=.)',\n            next  : \"qqstring\"\n        }, \n        {\n            token : \"constant.numeric\",\n            regex : CssHighlightRules.numRe\n        }, \n        {\n            token : \"keyword\",\n            regex : \"(?:ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)\\\\b\"\n        }, \n        {\n            token : keywordMapper,\n            regex : \"\\\\-?[a-zA-Z_][a-zA-Z0-9_\\\\-]*\"\n        }\n    ],\n    \"comment\" : [\n        {\n            token : \"comment\", // closing comment\n            regex : \"\\\\*\\\\/\",\n            next : \"start\"\n        }, {\n            defaultToken : \"comment\"\n        }\n    ],\n    \"qqstring\" : [\n        {\n            token : \"string\",\n            regex : '[^\"\\\\\\\\]+'\n        }, \n        {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        }, \n        {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"start\"\n        }\n    ],\n    \"qstring\" : [\n        {\n            token : \"string\",\n            regex : \"[^'\\\\\\\\]+\"\n        }, \n        {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qstring\"\n        }, \n        {\n            token : \"string\",\n            regex : \"'|$\",\n            next  : \"start\"\n        }\n    ]\n};\n\n};\n\noop.inherits(StylusHighlightRules, TextHighlightRules);\n\nexports.StylusHighlightRules = StylusHighlightRules;\n"
  },
  {
    "path": "src/mode/svg.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar XmlMode = require(\"./xml\").Mode;\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar SvgHighlightRules = require(\"./svg_highlight_rules\").SvgHighlightRules;\nvar MixedFoldMode = require(\"./folding/mixed\").FoldMode;\nvar XmlFoldMode = require(\"./folding/xml\").FoldMode;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    XmlMode.call(this);\n    \n    this.HighlightRules = SvgHighlightRules;\n    \n    this.createModeDelegates({\n        \"js-\": JavaScriptMode\n    });\n    \n    this.foldingRules = new MixedFoldMode(new XmlFoldMode(), {\n        \"js-\": new CStyleFoldMode()\n    });\n};\n\noop.inherits(Mode, XmlMode);\n\n(function() {\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n    \n\n    this.$id = \"ace/mode/svg\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/svg_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\nvar XmlHighlightRules = require(\"./xml_highlight_rules\").XmlHighlightRules;\n\nvar SvgHighlightRules = function() {\n    XmlHighlightRules.call(this);\n\n    this.embedTagRules(JavaScriptHighlightRules, \"js-\", \"script\");\n\n    this.normalizeRules();\n};\n\noop.inherits(SvgHighlightRules, XmlHighlightRules);\n\nexports.SvgHighlightRules = SvgHighlightRules;\n"
  },
  {
    "path": "src/mode/swift.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar HighlightRules = require(\"./swift_highlight_rules\").HighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = HighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\", nestable: true};\n    \n    this.$id = \"ace/mode/swift\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/swift_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar SwiftHighlightRules = function() {\n   var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"\",\n        \"keyword\": \"__COLUMN__|__FILE__|__FUNCTION__|__LINE__\"\n            + \"|as|associativity|break|case|class|continue|default|deinit|didSet\"\n            + \"|do|dynamicType|else|enum|extension|fallthrough|for|func|get|if|import\"\n            + \"|in|infix|init|inout|is|left|let|let|mutating|new|none|nonmutating\"\n            + \"|operator|override|postfix|precedence|prefix|protocol|return|right\"\n            + \"|safe|Self|self|set|struct|subscript|switch|Type|typealias\"\n            + \"|unowned|unsafe|var|weak|where|while|willSet\"\n            + \"|convenience|dynamic|final|infix|lazy|mutating|nonmutating|optional|override|postfix\"\n            + \"|prefix|required|static|guard|defer\",\n        \"storage.type\": \"bool|double|Double\"\n            + \"|extension|float|Float|int|Int|open|internal|fileprivate|private|public|string|String\",\n        \"constant.language\":\n            \"false|Infinity|NaN|nil|no|null|null|off|on|super|this|true|undefined|yes\",\n        \"support.function\":\n            \"\"\n    }, \"identifier\");\n    \n    function string(start, options) {\n        var nestable = options.nestable || options.interpolation;\n        var interpStart = options.interpolation && options.interpolation.nextState || \"start\";\n        var mainRule = {\n            regex: start + (options.multiline ? \"\" : \"(?=.)\"),\n            token: \"string.start\"\n        };\n        var nextState = [\n            options.escape && {\n                regex: options.escape,\n                token: \"character.escape\"\n            },\n            options.interpolation && {\n                token : \"paren.quasi.start\",\n                regex : lang.escapeRegExp(options.interpolation.lead + options.interpolation.open),\n                push  : interpStart\n            },\n            options.error && {\n                regex: options.error,\n                token: \"error.invalid\"\n            }, \n            {\n                regex: start + (options.multiline ? \"\" : \"|$\"),\n                token: \"string.end\",\n                next: nestable ? \"pop\" : \"start\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ].filter(Boolean);\n        \n        if (nestable)\n            mainRule.push = nextState;\n        else\n            mainRule.next = nextState;\n        \n        if (!options.interpolation)\n            return mainRule;\n        \n        var open = options.interpolation.open;\n        var close = options.interpolation.close;\n        var counter = {\n            regex: \"[\" + lang.escapeRegExp(open + close) + \"]\",\n            onMatch: function(val, state, stack) {\n                this.next = val == open ? this.nextState : \"\";\n                if (val == open && stack.length) {\n                    stack.unshift(\"start\", state);\n                    return \"paren\";\n                }\n                if (val == close && stack.length) {\n                    stack.shift();\n                    this.next = stack.shift();\n                    if (this.next.indexOf(\"string\") != -1)\n                        return \"paren.quasi.end\";\n                }\n                return val == open ? \"paren.lparen\" : \"paren.rparen\";\n            },\n            nextState: interpStart\n        }; \n        return [counter, mainRule];\n    }\n    \n    function comments() {\n        return [{\n                token : \"comment\",\n                regex : /\\/\\//,\n                next : [\n                    DocCommentHighlightRules.getTagRule(),\n                    {token : \"comment\", regex : \"$|^\", next: \"start\"},\n                    {defaultToken : \"comment\", caseInsensitive: true}\n                ]\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment.start\",\n                regex : /\\/\\*/,\n                stateName: \"nested_comment\",\n                push : [\n                    DocCommentHighlightRules.getTagRule(),\n                    {token : \"comment.start\", regex : /\\/\\*/, push: \"nested_comment\"},\n                    {token : \"comment.end\", regex : \"\\\\*\\\\/\", next : \"pop\"},\n                    {defaultToken : \"comment\", caseInsensitive: true}\n                ]\n            }\n        ];\n    }\n    \n\n    this.$rules = {\n        start: [\n            string('\"\"\"', {\n                escape: /\\\\(?:[0\\\\tnr\"']|u{[a-fA-F1-9]{0,8}})/,\n                interpolation: {lead: \"\\\\\", open: \"(\", close: \")\"},\n                error: /\\\\./,\n                multiline: true\n            }),\n            string('\"', {\n                escape: /\\\\(?:[0\\\\tnr\"']|u{[a-fA-F1-9]{0,8}})/,\n                interpolation: {lead: \"\\\\\", open: \"(\", close: \")\"},\n                error: /\\\\./,\n                multiline: false\n            }),\n            comments(),\n            {\n                 regex: /@[a-zA-Z_$][a-zA-Z_$\\d\\u0080-\\ufffe]*/,\n                 token: \"variable.parameter\"\n            },\n            {\n                regex: /[a-zA-Z_$][a-zA-Z_$\\d\\u0080-\\ufffe]*/,\n                token: keywordMapper\n            },  \n            {\n                token : \"constant.numeric\", \n                regex : /[+-]?(?:0(?:b[01]+|o[0-7]+|x[\\da-fA-F])|\\d+(?:(?:\\.\\d*)?(?:[PpEe][+-]?\\d+)?)\\b)/\n            }, {\n                token : \"keyword.operator\",\n                regex : /--|\\+\\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?:|[!$%&*+\\-~\\/^]=?/,\n                next  : \"start\"\n            }, {\n                token : \"punctuation.operator\",\n                regex : /[?:,;.]/,\n                next  : \"start\"\n            }, {\n                token : \"paren.lparen\",\n                regex : /[\\[({]/,\n                next  : \"start\"\n            }, {\n                token : \"paren.rparen\",\n                regex : /[\\])}]/\n            } \n            \n        ]\n    };\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n    \n    this.normalizeRules();\n};\n\n\noop.inherits(SwiftHighlightRules, TextHighlightRules);\n\nexports.HighlightRules = SwiftHighlightRules;\nexports.SwiftHighlightRules = SwiftHighlightRules;\n"
  },
  {
    "path": "src/mode/tcl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar TclHighlightRules = require(\"./tcl_highlight_rules\").TclHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = TclHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new CStyleFoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"#\";\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n        \n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.$id = \"ace/mode/tcl\";\n    this.snippetFileId = \"ace/snippets/tcl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/tcl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TclHighlightRules = function() {\n\n    //TODO var builtinFunctions = \"\";\n\n    this.$rules = {\n        \"start\" : [\n           {\n                token : \"comment\",\n                regex : \"#.*\\\\\\\\$\",\n                next  : \"commentfollow\"\n            }, {\n                token : \"comment\",\n                regex : \"#.*$\"\n            }, {\n                token : \"support.function\",\n                regex : '[\\\\\\\\]$',\n                next  : \"splitlineStart\"\n            }, {\n                token : \"text\",\n                regex : /\\\\(?:[\"{}\\[\\]$\\\\])/\n            }, {\n                token : \"text\", // last value before command\n                regex : '^|[^{][;][^}]|[/\\r/]',\n                next  : \"commandItem\"\n            }, {\n                token : \"string\", // single line\n                regex : '[ ]*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // multi line \"\"\" string start\n                regex : '[ ]*[\"]',\n                next  : \"qqstring\"\n            }, {\n                token : \"variable.instance\",\n                regex : \"[$]\",\n                next  : \"variable\"\n            }, {\n                token : \"support.function\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|{\\\\*}|;|::\"\n            }, {\n                token : \"identifier\",\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[{]\",\n                next  : \"commandItem\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[(]\"\n            },  {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"commandItem\" : [\n            {\n                token : \"comment\",\n                regex : \"#.*\\\\\\\\$\",\n                next  : \"commentfollow\"\n            }, {\n                token : \"comment\",\n                regex : \"#.*$\",\n                next  : \"start\"\n            }, {\n                token : \"string\", // single line\n                regex : '[ ]*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"variable.instance\", \n                regex : \"[$]\",\n                next  : \"variable\"\n            }, {\n                token : \"support.function\",\n                regex : \"(?:[:][:])[a-zA-Z0-9_/]+(?:[:][:])\",\n                next  : \"commandItem\"\n            }, {\n                token : \"support.function\",\n                regex : \"[a-zA-Z0-9_/]+(?:[:][:])\",\n                next  : \"commandItem\"\n            }, {\n                token : \"support.function\",\n                regex : \"(?:[:][:])\",\n                next  : \"commandItem\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"support.function\",\n                regex : \"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|{\\\\*}|;|::\"\n            }, {\n                token : \"keyword\",\n                regex : \"[a-zA-Z0-9_/]+\",\n                next  : \"start\"\n            } ],\n        \"commentfollow\" : [ \n            {\n                token : \"comment\",\n                regex : \".*\\\\\\\\$\",\n                next  : \"commentfollow\"\n            }, {\n                token : \"comment\",\n                regex : '.+',\n                next  : \"start\"\n        } ],\n        \"splitlineStart\" : [ \n            {\n                token : \"text\",\n                regex : \"^.\",\n                next  : \"start\"\n            }],\n        \"variable\" : [ \n            {\n                token : \"variable.instance\", // variable tcl\n                regex : \"[a-zA-Z_\\\\d]+(?:[(][a-zA-Z_\\\\d]+[)])?\",\n                next  : \"start\"\n            }, {\n                token : \"variable.instance\", // variable tcl with braces\n                regex : \"{?[a-zA-Z_\\\\d]+}?\",\n                next  : \"start\"\n            }],  \n        \"qqstring\" : [ {\n            token : \"string\", // multi line \"\"\" string end\n            regex : '(?:[^\\\\\\\\]|\\\\\\\\.)*?[\"]',\n            next : \"start\"\n        }, {\n            token : \"string\",\n            regex : '.+'\n        } ]\n    };\n};\n\noop.inherits(TclHighlightRules, TextHighlightRules);\n\nexports.TclHighlightRules = TclHighlightRules;\n"
  },
  {
    "path": "src/mode/terraform.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TerraformHighlightRules = require(\"./terraform_highlight_rules\").TerraformHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function () {\n    TextMode.call(this);\n    this.HighlightRules = TerraformHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\n\noop.inherits(Mode, TextMode);\n\n\n(function () {\n    this.lineCommentStart = [\"#\", \"//\"];\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    \n    this.$id = \"ace/mode/terraform\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/terraform_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar TerraformHighlightRules = function () {\n\n\n    this.$rules = {\n        \"start\": [\n            {\n                token: ['storage.function.terraform'],\n                regex: '\\\\b(output|resource|data|variable|module|export)\\\\b'\n            },\n            {\n                token: \"variable.terraform\",\n                regex: \"\\\\$\\\\s\",\n                push: [\n                    {\n                        token: \"keyword.terraform\",\n                        regex: \"(-var-file|-var)\"\n                    },\n                    {\n                        token: \"variable.terraform\",\n                        regex: \"\\\\n|$\",\n                        next: \"pop\"\n                    },\n\n                    {include: \"strings\"},\n                    {include: \"variables\"},\n                    {include: \"operators\"},\n\n                    {defaultToken: \"text\"}\n                ]\n            },\n            {\n                token: \"language.support.class\",\n                regex: \"\\\\b(timeouts|provider|connection|provisioner|lifecycleprovider|atlas)\\\\b\"\n            },\n\n            {\n                token: \"singleline.comment.terraform\",\n                regex: '#.*$'\n            },\n            {\n                token: \"singleline.comment.terraform\",\n                regex: '//.*$'\n            },\n            {\n                token: \"multiline.comment.begin.terraform\",\n                regex: /\\/\\*/,\n                push: \"blockComment\"\n            },\n            {\n                token: \"storage.function.terraform\",\n                regex: \"^\\\\s*(locals|terraform)\\\\s*{\"\n            },\n            {\n                token: \"paren.lparen\",\n                regex: \"[[({]\"\n            },\n\n            {\n                token: \"paren.rparen\",\n                regex: \"[\\\\])}]\"\n            },\n            {include: \"constants\"},\n            {include: \"strings\"},\n            {include: \"operators\"},\n            {include: \"variables\"}\n        ],\n        blockComment: [{\n            regex: /\\*\\//,\n            token: \"multiline.comment.end.terraform\",\n            next: \"pop\"\n        }, {\n            defaultToken: \"comment\"\n        }],\n        \"constants\": [\n            {\n                token: \"constant.language.terraform\",\n                regex: \"\\\\b(true|false|yes|no|on|off|EOF)\\\\b\"\n            },\n            {\n                token: \"constant.numeric.terraform\",\n                regex: \"(\\\\b([0-9]+)([kKmMgG]b?)?\\\\b)|(\\\\b(0x[0-9A-Fa-f]+)([kKmMgG]b?)?\\\\b)\"\n            }\n        ],\n        \"variables\": [\n            {\n                token: [\"variable.assignment.terraform\", \"keyword.operator\"],\n                regex: \"\\\\b([a-zA-Z_]+)(\\\\s*=)\"\n            }\n        ],\n        \"interpolated_variables\": [\n            {\n                token: \"variable.terraform\",\n                regex: \"\\\\b(var|self|count|path|local)\\\\b(?:\\\\.*[a-zA-Z_-]*)?\"\n            }\n        ],\n        \"strings\": [\n            {\n                token: \"punctuation.quote.terraform\",\n                regex: \"'\",\n                push:\n                    [{\n                        token: 'punctuation.quote.terraform',\n                        regex: \"'\",\n                        next: 'pop'\n                    },\n                        {include: \"escaped_chars\"},\n                        {defaultToken: 'string'}]\n            },\n            {\n                token: \"punctuation.quote.terraform\",\n                regex: '\"',\n                push:\n                    [{\n                        token: 'punctuation.quote.terraform',\n                        regex: '\"',\n                        next: 'pop'\n                    },\n                        {include: \"interpolation\"},\n                        {include: \"escaped_chars\"},\n                        {defaultToken: 'string'}]\n            }\n        ],\n        \"escaped_chars\": [\n            {\n                token: \"constant.escaped_char.terraform\",\n                regex: \"\\\\\\\\.\"\n            }\n        ],\n        \"operators\": [\n            {\n                token: \"keyword.operator\",\n                regex: \"\\\\?|:|==|!=|>|<|>=|<=|&&|\\\\|\\\\\\||!|%|&|\\\\*|\\\\+|\\\\-|/|=\"\n            }\n        ],\n        \"interpolation\": [\n            {// TODO: double $\n                token: \"punctuation.interpolated.begin.terraform\",\n                regex: \"\\\\$?\\\\$\\\\{\",\n                push: [{\n                    token: \"punctuation.interpolated.end.terraform\",\n                    regex: \"\\\\}\",\n                    next: \"pop\"\n                },\n                    {include: \"interpolated_variables\"},\n                    {include: \"operators\"},\n                    {include: \"constants\"},\n                    {include: \"strings\"},\n                    {include: \"functions\"},\n                    {include: \"parenthesis\"},\n                    {defaultToken: \"punctuation\"}\n                ]\n            }\n        ],\n        \"functions\": [\n            {\n                token: \"keyword.function.terraform\",\n                regex: \"\\\\b(abs|basename|base64decode|base64encode|base64gzip|base64sha256|base64sha512|bcrypt|ceil|chomp|chunklist|cidrhost|cidrnetmask|cidrsubnet|coalesce|coalescelist|compact|concat|contains|dirname|distinct|element|file|floor|flatten|format|formatlist|indent|index|join|jsonencode|keys|length|list|log|lookup|lower|map|matchkeys|max|merge|min|md5|pathexpand|pow|replace|rsadecrypt|sha1|sha256|sha512|signum|slice|sort|split|substr|timestamp|timeadd|title|transpose|trimspace|upper|urlencode|uuid|values|zipmap)\\\\b\"\n            }\n        ],\n        \"parenthesis\": [\n            {\n                token: \"paren.lparen\",\n                regex: \"\\\\[\"\n            },\n            {\n                token: \"paren.rparen\",\n                regex: \"\\\\]\"\n            }\n        ]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(TerraformHighlightRules, TextHighlightRules);\n\nexports.TerraformHighlightRules = TerraformHighlightRules;\n"
  },
  {
    "path": "src/mode/tex.js",
    "content": "/*\n * tex.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar TexHighlightRules = require(\"./tex_highlight_rules\").TexHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function(suppressHighlighting) {\n    if (suppressHighlighting)\n        this.HighlightRules = TextHighlightRules;\n    else\n        this.HighlightRules = TexHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n   this.lineCommentStart = \"%\";\n   this.getNextLineIndent = function(state, line, tab) {\n      return this.$getIndent(line);\n   };\n\n   this.allowAutoInsert = function() {\n      return false;\n   };\n    this.$id = \"ace/mode/tex\";\n    this.snippetFileId = \"ace/snippets/tex\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/tex_highlight_rules.js",
    "content": "/*\n * tex_highlight_rules.js\n *\n * Copyright (C) 2009-11 by RStudio, Inc.\n *\n * The Initial Developer of the Original Code is\n * Ajax.org B.V.\n * Portions created by the Initial Developer are Copyright (C) 2010\n * the Initial Developer. All Rights Reserved.\n *\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n *\n */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TexHighlightRules = function(textClass) {\n\n    if (!textClass)\n        textClass = \"text\";\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"%.*$\"\n            }, {\n                token : textClass, // non-command\n                regex : \"\\\\\\\\[$&%#\\\\{\\\\}]\"\n            }, {\n                token : \"keyword\", // command\n                regex : \"\\\\\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\\\b\",\n               next : \"nospell\"\n            }, {\n                token : \"keyword\", // command\n                regex : \"\\\\\\\\(?:[a-zA-Z0-9]+|[^a-zA-Z0-9])\"\n            }, {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n                regex : \"[[({]\"\n            }, {\n               // Obviously these are neither keywords nor operators, but\n               // labelling them as such was the easiest way to get them\n               // to be colored distinctly from regular text\n               token : \"paren.keyword.operator\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : textClass,\n                regex : \"\\\\s+\"\n            }\n        ],\n        // This mode is necessary to prevent spell checking, but to keep the\n        // same syntax highlighting behavior. The list of commands comes from\n        // Texlipse.\n        \"nospell\" : [\n           {\n               token : \"comment\",\n               regex : \"%.*$\",\n               next : \"start\"\n           }, {\n               token : \"nospell.\" + textClass, // non-command\n               regex : \"\\\\\\\\[$&%#\\\\{\\\\}]\"\n           }, {\n               token : \"keyword\", // command\n               regex : \"\\\\\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\\\b\"\n           }, {\n               token : \"keyword\", // command\n               regex : \"\\\\\\\\(?:[a-zA-Z0-9]+|[^a-zA-Z0-9])\",\n               next : \"start\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"[[({]\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"[\\\\])]\"\n           }, {\n               token : \"paren.keyword.operator\",\n               regex : \"}\",\n               next : \"start\"\n           }, {\n               token : \"nospell.\" + textClass,\n               regex : \"\\\\s+\"\n           }, {\n               token : \"nospell.\" + textClass,\n               regex : \"\\\\w+\"\n           }\n        ]\n    };\n};\n\noop.inherits(TexHighlightRules, TextHighlightRules);\n\nexports.TexHighlightRules = TexHighlightRules;\n"
  },
  {
    "path": "src/mode/text.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../../ace-internal\").Ace.SyntaxMode} SyntaxMode\n */\n\nvar config = require(\"../config\");\n\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\n\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CstyleBehaviour = require(\"./behaviour/cstyle\").CstyleBehaviour;\nvar unicode = require(\"../unicode\");\nvar lang = require(\"../lib/lang\");\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar Range = require(\"../range\").Range;\n\nvar Mode;\nMode = function() {\n    this.HighlightRules = TextHighlightRules;\n};\n\n(function() {\n    this.$defaultBehaviour = new CstyleBehaviour();\n\n    this.tokenRe = new RegExp(\"^[\" + unicode.wordChars + \"\\\\$_]+\", \"g\");\n\n    this.nonTokenRe = new RegExp(\"^(?:[^\" + unicode.wordChars + \"\\\\$_]|\\\\s])+\", \"g\");\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.getTokenizer = function() {\n        if (!this.$tokenizer) {\n            this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig);\n            this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());\n        }\n        return this.$tokenizer;\n    };\n\n    this.lineCommentStart = \"\";\n    this.blockComment = \"\";\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.toggleCommentLines = function(state, session, startRow, endRow) {\n        var doc = session.doc;\n\n        var ignoreBlankLines = true;\n        var shouldRemove = true;\n        var minIndent = Infinity;\n        var tabSize = session.getTabSize();\n        var insertAtTabStop = false;\n\n        if (!this.lineCommentStart) {\n            if (!this.blockComment)\n                return false;\n            /**@type {any}*/\n            var lineCommentStart = this.blockComment.start;\n            var lineCommentEnd = this.blockComment.end;\n            /**@type {any}*/\n            var regexpStart = new RegExp(\"^(\\\\s*)(?:\" + lang.escapeRegExp(lineCommentStart) + \")\");\n            var regexpEnd = new RegExp(\"(?:\" + lang.escapeRegExp(lineCommentEnd) + \")\\\\s*$\");\n\n            var comment = function(line, i) {\n                if (testRemove(line, i))\n                    return;\n                if (!ignoreBlankLines || /\\S/.test(line)) {\n                    doc.insertInLine({row: i, column: line.length}, lineCommentEnd);\n                    doc.insertInLine({row: i, column: minIndent}, lineCommentStart);\n                }\n            };\n\n            var uncomment = function(line, i) {\n                var m;\n                if (m = line.match(regexpEnd))\n                    doc.removeInLine(i, line.length - m[0].length, line.length);\n                if (m = line.match(regexpStart))\n                    doc.removeInLine(i, m[1].length, m[0].length);\n            };\n\n            /**@type {any}*/\n            var testRemove = function(line, row) {\n                if (regexpStart.test(line))\n                    return true;\n                var tokens = session.getTokens(row);\n                for (var i = 0; i < tokens.length; i++) {\n                    if (tokens[i].type === \"comment\")\n                        return true;\n                }\n            };\n        } else {\n            if (Array.isArray(this.lineCommentStart)) {\n                /**@type {any}*/\n                var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join(\"|\");\n                /**@type {any}*/\n                var lineCommentStart = this.lineCommentStart[0];\n            } else {\n                var regexpStart = lang.escapeRegExp(this.lineCommentStart);\n                /**@type {any}*/\n                var lineCommentStart = this.lineCommentStart;\n            }\n            regexpStart = new RegExp(\"^(\\\\s*)(?:\" + regexpStart + \") ?\");\n\n            insertAtTabStop = session.getUseSoftTabs();\n\n            var uncomment = function(line, i) {\n                var m = line.match(regexpStart);\n                if (!m) return;\n                var start = m[1].length, end = m[0].length;\n                if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == \" \")\n                    end--;\n                doc.removeInLine(i, start, end);\n            };\n            var commentWithSpace = lineCommentStart + \" \";\n            var comment = function(line, i) {\n                if (!ignoreBlankLines || /\\S/.test(line)) {\n                    if (shouldInsertSpace(line, minIndent, minIndent))\n                        doc.insertInLine({row: i, column: minIndent}, commentWithSpace);\n                    else\n                        doc.insertInLine({row: i, column: minIndent}, lineCommentStart);\n                }\n            };\n            /**@type {any}*/\n            var testRemove = function(line, i) {\n                return regexpStart.test(line);\n            };\n\n            var shouldInsertSpace = function(line, before, after) {\n                var spaces = 0;\n                while (before-- && line.charAt(before) == \" \")\n                    spaces++;\n                if (spaces % tabSize != 0)\n                    return false;\n                var spaces = 0;\n                while (line.charAt(after++) == \" \")\n                    spaces++;\n                if (tabSize > 2)\n                    return spaces % tabSize != tabSize - 1;\n                else\n                    return spaces % tabSize == 0;\n            };\n        }\n\n        function iter(fun) {\n            for (var i = startRow; i <= endRow; i++)\n                fun(doc.getLine(i), i);\n        }\n\n\n        var minEmptyLength = Infinity;\n        iter(function(line, i) {\n            var indent = line.search(/\\S/);\n            if (indent !== -1) {\n                if (indent < minIndent)\n                    minIndent = indent;\n                if (shouldRemove && !testRemove(line, i))\n                    shouldRemove = false;\n            } else if (minEmptyLength > line.length) {\n                minEmptyLength = line.length;\n            }\n        });\n\n        if (minIndent == Infinity) {\n            minIndent = minEmptyLength;\n            ignoreBlankLines = false;\n            shouldRemove = false;\n        }\n\n        if (insertAtTabStop && minIndent % tabSize != 0)\n            minIndent = Math.floor(minIndent / tabSize) * tabSize;\n\n        iter(shouldRemove ? uncomment : comment);\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.toggleBlockComment = function(state, session, range, cursor) {\n        var comment = this.blockComment;\n        if (!comment)\n            return;\n        if (!comment.start && comment[0])\n            comment = comment[0];\n\n        var iterator = new TokenIterator(session, cursor.row, cursor.column);\n        var token = iterator.getCurrentToken();\n\n        var sel = session.selection;\n        var initialRange = session.selection.toOrientedRange();\n        var startRow, colDiff;\n\n        if (token && /comment/.test(token.type)) {\n            var startRange, endRange;\n            while (token && /comment/.test(token.type)) {\n                var i = token.value.indexOf(comment.start);\n                if (i != -1) {\n                    var row = iterator.getCurrentTokenRow();\n                    var column = iterator.getCurrentTokenColumn() + i;\n                    startRange = new Range(row, column, row, column + comment.start.length);\n                    break;\n                }\n                token = iterator.stepBackward();\n            }\n\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n            while (token && /comment/.test(token.type)) {\n                var i = token.value.indexOf(comment.end);\n                if (i != -1) {\n                    var row = iterator.getCurrentTokenRow();\n                    var column = iterator.getCurrentTokenColumn() + i;\n                    endRange = new Range(row, column, row, column + comment.end.length);\n                    break;\n                }\n                token = iterator.stepForward();\n            }\n            if (endRange)\n                session.remove(endRange);\n            if (startRange) {\n                session.remove(startRange);\n                startRow = startRange.start.row;\n                colDiff = -comment.start.length;\n            }\n        } else {\n            colDiff = comment.start.length;\n            startRow = range.start.row;\n            session.insert(range.end, comment.end);\n            session.insert(range.start, comment.start);\n        }\n        // todo: selection should have ended up in the right place automatically!\n        if (initialRange.start.row == startRow)\n            initialRange.start.column += colDiff;\n        if (initialRange.end.row == startRow)\n            initialRange.end.column += colDiff;\n        session.selection.fromOrientedRange(initialRange);\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return false;\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n    };\n\n    this.$getIndent = function(line) {\n        return line.match(/^\\s*/)[0];\n    };\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.createModeDelegates = function (mapping) {\n        this.$embeds = [];\n        this.$modes = {};\n        for (let i in mapping) {\n            if (mapping[i]) {\n                var Mode = mapping[i];\n                var id = Mode.prototype.$id;\n                var mode = config.$modes[id];\n                if (!mode)\n                    config.$modes[id] = mode = new Mode();\n                if (!config.$modes[i])\n                    config.$modes[i] = mode;\n                this.$embeds.push(i);\n                this.$modes[i] = mode;\n            }\n        }\n\n        var delegations = [\"toggleBlockComment\", \"toggleCommentLines\", \"getNextLineIndent\",\n            \"checkOutdent\", \"autoOutdent\", \"transformAction\", \"getCompletions\"];\n\n        for (let i = 0; i < delegations.length; i++) {\n            (function(scope) {\n              var functionName = delegations[i];\n              var defaultHandler = scope[functionName];\n              scope[delegations[i]] =\n                  /** @this {import(\"../../ace-internal\").Ace.SyntaxMode} */\n                  function () {\n                      return this.$delegator(functionName, arguments, defaultHandler);\n                  };\n            }(this));\n        }\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.$delegator = function(method, args, defaultHandler) {\n        var state = args[0] || \"start\";\n        if (typeof state != \"string\") {\n            if (Array.isArray(state[2])) {\n                var language = state[2][state[2].length - 1];\n                var mode = this.$modes[language];\n                if (mode)\n                    return mode[method].apply(mode, [state[1]].concat([].slice.call(args, 1)));\n            }\n            state = state[0] || \"start\";\n        }\n\n        for (var i = 0; i < this.$embeds.length; i++) {\n            if (!this.$modes[this.$embeds[i]]) continue;\n\n            var split = state.split(this.$embeds[i]);\n            if (!split[0] && split[1]) {\n                args[0] = split[1];\n                var mode = this.$modes[this.$embeds[i]];\n                return mode[method].apply(mode, args);\n            }\n        }\n        var ret = defaultHandler.apply(this, args);\n        return defaultHandler ? ret : undefined;\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.transformAction = function(state, action, editor, session, param) {\n        if (this.$behaviour) {\n            var behaviours = this.$behaviour.getBehaviours();\n            for (var key in behaviours) {\n                if (behaviours[key][action]) {\n                    var ret = behaviours[key][action].apply(this, arguments);\n                    if (ret) {\n                        return ret;\n                    }\n                }\n            }\n        }\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.getKeywords = function(append) {\n        // this is for autocompletion to pick up regexp'ed keywords\n        if (!this.completionKeywords) {\n            var rules = this.$tokenizer[\"rules\"];\n            var completionKeywords = [];\n            for (var rule in rules) {\n                var ruleItr = rules[rule];\n                for (var r = 0, l = ruleItr.length; r < l; r++) {\n                    if (typeof ruleItr[r].token === \"string\") {\n                        if (/keyword|support|storage/.test(ruleItr[r].token))\n                            completionKeywords.push(ruleItr[r].regex);\n                    }\n                    else if (typeof ruleItr[r].token === \"object\") {\n                        for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {\n                            if (/keyword|support|storage/.test(ruleItr[r].token[a])) {\n                                // drop surrounding parens\n                                var rule = ruleItr[r].regex.match(/\\(.+?\\)/g)[a];\n                                completionKeywords.push(rule.substr(1, rule.length - 2));\n                            }\n                        }\n                    }\n                }\n            }\n            this.completionKeywords = completionKeywords;\n        }\n        // this is for highlighting embed rules, like HAML/Ruby or Obj-C/C\n        if (!append)\n            return this.$keywordList;\n        return completionKeywords.concat(this.$keywordList || []);\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.$createKeywordList = function() {\n        if (!this.$highlightRules)\n            this.getTokenizer();\n        return this.$keywordList = this.$highlightRules.$keywordList || [];\n    };\n\n    /**\n     * @this {SyntaxMode}\n     */\n    this.getCompletions = function(state, session, pos, prefix) {\n        var keywords = this.$keywordList || this.$createKeywordList();\n        return keywords.map(function(word) {\n            return {\n                name: word,\n                value: word,\n                score: 0,\n                meta: \"keyword\"\n            };\n        });\n    };\n\n    this.$id = \"ace/mode/text\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/text_highlight_rules.js",
    "content": "\"use strict\";\n\nconst deepCopy = require(\"../lib/deep_copy\").deepCopy;\n\n/**@type {(new() => Partial<import(\"../../ace-internal\").Ace.HighlightRules>) & {prototype: import(\"../../ace-internal\").Ace.HighlightRules}}*/\nvar TextHighlightRules;\nTextHighlightRules = function() {\n\n    // regexp must not have capturing parentheses\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [{\n            token : \"empty_line\",\n            regex : '^$'\n        }, {\n            defaultToken : \"text\"\n        }]\n    };\n};\n\n(function() {\n\n    /**\n     * @param {import(\"../../ace-internal\").Ace.HighlightRulesMap} rules\n     * @param {string} [prefix]\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.addRules = function(rules, prefix) {\n        if (!prefix) {\n            for (var key in rules)\n                this.$rules[key] = rules[key];\n            return;\n        }\n        for (var key in rules) {\n            var state = rules[key];\n            for (var i = 0; i < state.length; i++) {\n                var rule = state[i];\n                if (rule.next || rule.onMatch) {\n                    if (typeof rule.next == \"string\") {\n                        if (rule.next.indexOf(prefix) !== 0)\n                            rule.next = prefix + rule.next;\n                    }\n                    if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)\n                        rule.nextState = prefix + rule.nextState;\n                }\n            }\n            this.$rules[prefix + key] = state;\n        }\n    };\n\n    /**\n     * @returns {import(\"../../ace-internal\").Ace.HighlightRulesMap}\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.getRules = function() {\n        return this.$rules;\n    };\n\n    /**\n     * @param HighlightRules\n     * @param prefix\n     * @param escapeRules\n     * @param states\n     * @param append\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {\n        var embedRules = typeof HighlightRules == \"function\"\n            ? new HighlightRules().getRules()\n            : HighlightRules;\n        if (states) {\n            for (var i = 0; i < states.length; i++)\n                states[i] = prefix + states[i];\n        } else {\n            states = [];\n            for (var key in embedRules)\n                states.push(prefix + key);\n        }\n\n        this.addRules(embedRules, prefix);\n\n        if (escapeRules) {\n            var addRules = Array.prototype[append ? \"push\" : \"unshift\"];\n            for (var i = 0; i < states.length; i++)\n                addRules.apply(this.$rules[states[i]], deepCopy(escapeRules));\n        }\n\n        if (!this.$embeds)\n            this.$embeds = [];\n        this.$embeds.push(prefix);\n    };\n\n    /**\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.getEmbeds = function() {\n        return this.$embeds;\n    };\n\n    var pushState = function(currentState, stack) {\n        if (currentState != \"start\" || stack.length)\n            stack.unshift(this.nextState, currentState);\n        return this.nextState;\n    };\n    var popState = function(currentState, stack) {\n        // if (stack[0] === currentState)\n        stack.shift();\n        return stack.shift() || \"start\";\n    };\n\n    /**\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.normalizeRules = function() {\n        var id = 0;\n        var rules = this.$rules;\n        function processState(key) {\n            var state = rules[key];\n            state[\"processed\"] = true;\n            for (var i = 0; i < state.length; i++) {\n                var rule = state[i];\n                var toInsert = null;\n                if (Array.isArray(rule)) {\n                    toInsert = rule;\n                    // @ts-ignore\n                    rule = {};\n                }\n                if (!rule.regex && rule.start) {\n                    rule.regex = rule.start;\n                    if (!rule.next)\n                        rule.next = [];\n                    rule.next.push({\n                        defaultToken: rule.token\n                    }, {\n                        token: rule.token + \".end\",\n                        regex: rule.end || rule.start,\n                        next: \"pop\"\n                    });\n                    rule.token = rule.token + \".start\";\n                    rule.push = true;\n                }\n                var next = rule.next || rule.push;\n                if (next && Array.isArray(next)) {\n                    var stateName = rule.stateName;\n                    if (!stateName)  {\n                        stateName = rule.token;\n                        if (typeof stateName != \"string\")\n                            stateName = stateName[0] || \"\";\n                        if (rules[stateName])\n                            stateName += id++;\n                    }\n                    rules[stateName] = next;\n                    rule.next = stateName;\n                    processState(stateName);\n                } else if (next == \"pop\") {\n                    rule.next = popState;\n                }\n\n                if (rule.push) {\n                    rule.nextState = rule.next || rule.push;\n                    rule.next = pushState;\n                    delete rule.push;\n                }\n\n                if (rule.rules) {\n                    for (var r in rule.rules) {\n                        if (rules[r]) {\n                            if (rules[r].push)\n                                rules[r].push.apply(rules[r], rule.rules[r]);\n                        } else {\n                            rules[r] = rule.rules[r];\n                        }\n                    }\n                }\n                var includeName = typeof rule == \"string\" ? rule : rule.include;\n                if (includeName) {\n                    if (includeName === \"$self\")\n                        includeName = \"start\";\n                    if (Array.isArray(includeName))\n                        toInsert = includeName.map(function(x) { return rules[x]; });\n                    else\n                        toInsert = rules[includeName];\n                }\n\n                if (toInsert) {\n                    /**\n                     * @type{any[]}\n                     */\n                    // @ts-ignore\n                    var args = [i, 1].concat(toInsert);\n                    if (rule.noEscape)\n                        args = args.filter(function(x) {return !x.next;});\n                    state.splice.apply(state, args);\n                    // skip included rules since they are already processed\n                    //i += args.length - 3;\n                    i--;\n                }\n                \n                if (rule.keywordMap) {\n                    rule.token = this.createKeywordMapper(\n                        rule.keywordMap, rule.defaultToken || \"text\", rule.caseInsensitive\n                    );\n                    delete rule.defaultToken;\n                }\n            }\n        }\n        Object.keys(rules).forEach(processState, this);\n    };\n\n    this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {\n        var keywords = Object.create(null);\n        this.$keywordList = [];\n        Object.keys(map).forEach(function(className) {\n            var a = map[className];\n            var list = a.split(splitChar || \"|\");\n            for (var i = list.length; i--; ) {\n                var word = list[i];\n                this.$keywordList.push(word);\n                if (ignoreCase)\n                    word = word.toLowerCase(); \n                keywords[word] = className;\n            }\n        }, this);\n        map = null;\n        return ignoreCase\n            ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }\n            : function(value) {return keywords[value] || defaultToken; };\n    };\n\n    /**\n     * @this {import(\"../../ace-internal\").Ace.HighlightRules}\n     */\n    this.getKeywords = function() {\n        return this.$keywords;\n    };\n\n}).call(TextHighlightRules.prototype);\n\nexports.TextHighlightRules = TextHighlightRules;\n"
  },
  {
    "path": "src/mode/text_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar TextMode = require(\"./text\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new TextMode();\n    },\n\n    \"test: toggle comment lines should not do anything\" : function() {\n        var session = new EditSession([\"  abc\", \"cde\", \"fg\"]);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"  abc\", \"cde\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n\n    \"test: lines should be indented\" : function() {\n        assert.equal(\"   \", this.mode.getNextLineIndent(\"start\", \"   abc\", \"  \"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/textile.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TextileHighlightRules = require(\"./textile_highlight_rules\").TextileHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = TextileHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.type = \"text\";\n    this.getNextLineIndent = function(state, line, tab) {\n        if (state == \"intag\")\n            return tab;\n        \n        return \"\";\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    \n    this.$id = \"ace/mode/textile\";\n    this.snippetFileId = \"ace/snippets/textile\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/textile_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TextileHighlightRules = function() {\n    this.$rules = {\n        \"start\" : [\n            {\n                token : function(value) {\n                    if (value.charAt(0) == \"h\")\n                        return \"markup.heading.\" + value.charAt(1);\n                    else\n                        return \"markup.heading\";\n                },\n                regex : \"h1|h2|h3|h4|h5|h6|bq|p|bc|pre\",\n                next  : \"blocktag\"\n            },\n            {\n                token : \"keyword\",\n                regex : \"[\\\\*]+|[#]+\"\n            },\n            {\n                token : \"text\",\n                regex : \".+\"\n            }\n        ],\n        \"blocktag\" : [\n            {\n                token : \"keyword\",\n                regex : \"\\\\. \",\n                next  : \"start\"\n            },\n            {\n                token : \"keyword\",\n                regex : \"\\\\(\",\n                next  : \"blocktagproperties\"\n            }\n        ],\n        \"blocktagproperties\" : [\n            {\n                token : \"keyword\",\n                regex : \"\\\\)\",\n                next  : \"blocktag\"\n            },\n            {\n                token : \"string\",\n                regex : \"[a-zA-Z0-9\\\\-_]+\"\n            },\n            {\n                token : \"keyword\",\n                regex : \"#\"\n            }\n        ]\n    };\n};\n\noop.inherits(TextileHighlightRules, TextHighlightRules);\n\nexports.TextileHighlightRules = TextileHighlightRules;\n"
  },
  {
    "path": "src/mode/toml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TomlHighlightRules = require(\"./toml_highlight_rules\").TomlHighlightRules;\nvar FoldMode = require(\"./folding/ini\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = TomlHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    this.$id = \"ace/mode/toml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/toml_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TomlHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"constant.language.boolean\": \"true|false\"\n    }, \"identifier\");\n\n    var identifierRe = \"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\\\\b\";\n\n    this.$rules = {\n    \"start\": [\n        {\n            token: \"comment.toml\",\n            regex: /#.*$/\n        },\n        {\n            token : \"string\",\n            regex : '\"(?=.)',\n            next  : \"qqstring\"\n        },\n        {\n            token: [\"variable.keygroup.toml\"],\n            regex: \"(?:^\\\\s*)(\\\\[\\\\[([^\\\\]]+)\\\\]\\\\])\"\n        },\n        {\n            token: [\"variable.keygroup.toml\"],\n            regex: \"(?:^\\\\s*)(\\\\[([^\\\\]]+)\\\\])\"\n        },\n        {\n            token : keywordMapper,\n            regex : identifierRe\n        },\n        {\n           token : \"support.date.toml\",\n           regex: \"\\\\d{4}-\\\\d{2}-\\\\d{2}(T)\\\\d{2}:\\\\d{2}:\\\\d{2}(Z)\"\n        },\n        {\n           token: \"constant.numeric.toml\",\n           regex: \"-?\\\\d+(\\\\.?\\\\d+)?\"\n        }\n    ],\n    \"qqstring\" : [\n        {\n            token : \"string\",\n            regex : \"\\\\\\\\$\",\n            next  : \"qqstring\"\n        },\n        {\n            token : \"constant.language.escape\",\n            regex : '\\\\\\\\[0tnr\"\\\\\\\\]'\n        },\n        {\n            token : \"string\",\n            regex : '\"|$',\n            next  : \"start\"\n        },\n        {\n            defaultToken: \"string\"\n        }\n    ]\n    };\n\n};\n\noop.inherits(TomlHighlightRules, TextHighlightRules);\n\nexports.TomlHighlightRules = TomlHighlightRules;\n"
  },
  {
    "path": "src/mode/tsv.js",
    "content": "\"use strict\";\n\nvar CSVMode = require(\"./csv\").Mode;\nvar TsvHighlightRules = require(\"./tsv_highlight_rules\").TsvHighlightRules;\n\nvar Mode = function(options) {\n    var mode = new CSVMode({\n        splitter: \"\\t\",\n        quote: '\"'\n    });\n    mode.HighlightRules = TsvHighlightRules;\n    mode.$id = \"ace/mode/tsv\";\n    return mode;\n};\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/tsv_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\n\nvar TsvHighlightRules = function() {\n    TextHighlightRules.call(this);\n};\n\noop.inherits(TsvHighlightRules, TextHighlightRules);\n\nexports.TsvHighlightRules = TsvHighlightRules;\n"
  },
  {
    "path": "src/mode/tsx.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nconst JavaScriptBehaviour = require(\"./behaviour/javascript\").JavaScriptBehaviour;\nconst JavaScriptFoldMode = require(\"./folding/javascript\").FoldMode;\nvar tsMode = require(\"./typescript\").Mode;\n\nvar Mode = function() {\n    tsMode.call(this);\n    this.$highlightRuleConfig = {jsx: true};\n    this.foldingRules = new JavaScriptFoldMode();\n    this.$behaviour = new JavaScriptBehaviour();\n};\noop.inherits(Mode, tsMode);\n\n(function() {\n    this.$id = \"ace/mode/tsx\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/tsx_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TypeScriptHighlightRules = require(\"./typescript_highlight_rules\").TypeScriptHighlightRules;\n\nvar TsxHighlightRules = function () {\n    TypeScriptHighlightRules.call(this, {\n      jsx: true\n    });\n};\noop.inherits(TsxHighlightRules, TypeScriptHighlightRules);\n\nexports.TsxHighlightRules = TsxHighlightRules;"
  },
  {
    "path": "src/mode/turtle.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar TurtleHighlightRules = require(\"./turtle_highlight_rules\").TurtleHighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = TurtleHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // this.lineCommentStart = \"\"#\"\";\n    // Extra logic goes here.\n    this.$id = \"ace/mode/turtle\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/turtle_highlight_rules.js",
    "content": "/* This file was autogenerated from turtle.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TurtleHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        start: [{\n            include: \"#comments\"\n        }, {\n            include: \"#strings\"\n        }, {\n            include: \"#base-prefix-declarations\"\n        }, {\n            include: \"#string-language-suffixes\"\n        }, {\n            include: \"#string-datatype-suffixes\"\n        }, {\n            include: \"#relative-urls\"\n        }, {\n            include: \"#xml-schema-types\"\n        }, {\n            include: \"#rdf-schema-types\"\n        }, {\n            include: \"#owl-types\"\n        }, {\n            include: \"#qnames\"\n        }, {\n            include: \"#punctuation-operators\"\n        }],\n        \"#base-prefix-declarations\": [{\n            token: \"keyword.other.prefix.turtle\",\n            regex: /@(?:base|prefix)/\n        }],\n        \"#comments\": [{\n            token: [\n                \"punctuation.definition.comment.turtle\",\n                \"comment.line.hash.turtle\"\n            ],\n            regex: /(#)(.*$)/\n        }],\n        \"#owl-types\": [{\n            token: \"support.type.datatype.owl.turtle\",\n            regex: /owl:[a-zA-Z]+/\n        }],\n        \"#punctuation-operators\": [{\n            token: \"keyword.operator.punctuation.turtle\",\n            regex: /;|,|\\.|\\(|\\)|\\[|\\]/\n        }],\n        \"#qnames\": [{\n            token: \"entity.name.other.qname.turtle\",\n            regex: /(?:[a-zA-Z][-_a-zA-Z0-9]*)?:(?:[_a-zA-Z][-_a-zA-Z0-9]*)?/\n        }],\n        \"#rdf-schema-types\": [{\n            token: \"support.type.datatype.rdf.schema.turtle\",\n            regex: /rdfs?:[a-zA-Z]+|(?:^|\\s)a(?:\\s|$)/\n        }],\n        \"#relative-urls\": [{\n            token: \"string.quoted.other.relative.url.turtle\",\n            regex: /</,\n            push: [{\n                token: \"string.quoted.other.relative.url.turtle\",\n                regex: />/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.other.relative.url.turtle\"\n            }]\n        }],\n        \"#string-datatype-suffixes\": [{\n            token: \"keyword.operator.datatype.suffix.turtle\",\n            regex: /\\^\\^/\n        }],\n        \"#string-language-suffixes\": [{\n            token: [\n                \"keyword.operator.language.suffix.turtle\",\n                \"constant.language.suffix.turtle\"\n            ],\n            regex: /(?!\")(@)([a-z]+(?:\\-[a-z0-9]+)*)/\n        }],\n        \"#strings\": [{\n            token: \"string.quoted.triple.turtle\",\n            regex: /\"\"\"/,\n            push: [{\n                token: \"string.quoted.triple.turtle\",\n                regex: /\"\"\"/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.triple.turtle\"\n            }]\n        }, {\n            token: \"string.quoted.double.turtle\",\n            regex: /\"/,\n            push: [{\n                token: \"string.quoted.double.turtle\",\n                regex: /\"/,\n                next: \"pop\"\n            }, {\n                token: \"invalid.string.newline\",\n                regex: /$/\n            }, {\n                token: \"constant.character.escape.turtle\",\n                regex: /\\\\./\n            }, {\n                defaultToken: \"string.quoted.double.turtle\"\n            }]\n        }],\n        \"#xml-schema-types\": [{\n            token: \"support.type.datatype.xml.schema.turtle\",\n            regex: /xsd?:[a-z][a-zA-Z]+/\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nTurtleHighlightRules.metaData = {\n    fileTypes: [\"ttl\", \"nt\"],\n    name: \"Turtle\",\n    scopeName: \"source.turtle\"\n};\n\n\noop.inherits(TurtleHighlightRules, TextHighlightRules);\n\nexports.TurtleHighlightRules = TurtleHighlightRules;\n"
  },
  {
    "path": "src/mode/twig.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar TwigHighlightRules = require(\"./twig_highlight_rules\").TwigHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = TwigHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.blockComment = {start: \"{#\", end: \"#}\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n    this.$id = \"ace/mode/twig\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/twig_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar TwigHighlightRules = function() {\n    // inherit from html\n    HtmlHighlightRules.call(this);\n\n    var tags = \"autoescape|block|do|embed|extends|filter|flush|for|from|if|import|include|macro|sandbox|set|spaceless|use|verbatim\";\n    tags = tags + \"|end\" + tags.replace(/\\|/g, \"|end\");\n    var filters = \"abs|batch|capitalize|convert_encoding|date|date_modify|default|e|escape|first|format|join|json_encode|keys|last|length|lower|merge|nl2br|number_format|raw|replace|reverse|slice|sort|split|striptags|title|trim|upper|url_encode\";\n    var functions = \"attribute|constant|cycle|date|dump|parent|random|range|template_from_string\";\n    var tests = \"constant|divisibleby|sameas|defined|empty|even|iterable|odd\";\n    var constants = \"null|none|true|false\";\n    var operators = \"b-and|b-xor|b-or|in|is|and|or|not\";\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control.twig\": tags,\n        \"support.function.twig\": [filters, functions, tests].join(\"|\"),\n        \"keyword.operator.twig\":  operators,\n        \"constant.language.twig\": constants\n    }, \"identifier\");\n\n    // add twig start tags to the HTML start tags\n    for (var rule in this.$rules) {\n        this.$rules[rule].unshift({\n            token : \"variable.other.readwrite.local.twig\",\n            regex : \"\\\\{\\\\{-?\",\n            push : \"twig-start\"\n        }, {\n            token : \"meta.tag.twig\",\n            regex : \"\\\\{%-?\",\n            push : \"twig-start\"\n        }, {\n            token : \"comment.block.twig\",\n            regex : \"\\\\{#-?\",\n            push : \"twig-comment\"\n        });\n    }\n\n    // add twig closing comment to HTML comments\n    this.$rules[\"twig-comment\"] = [{\n        token : \"comment.block.twig\",\n        regex : \".*-?#\\\\}\",\n        next : \"pop\"\n    }];\n\n    this.$rules[\"twig-start\"] = [{\n        token : \"variable.other.readwrite.local.twig\",\n        regex : \"-?\\\\}\\\\}\",\n        next : \"pop\"\n    }, {\n        token : \"meta.tag.twig\",\n        regex : \"-?%\\\\}\",\n        next : \"pop\"\n    }, {\n        token : \"string\",\n        regex : \"'\",\n        next  : \"twig-qstring\"\n    }, {\n        token : \"string\",\n        regex : '\"',\n        next  : \"twig-qqstring\"\n    }, {\n        token : \"constant.numeric\", // hex\n        regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n    }, {\n        token : \"constant.numeric\", // float\n        regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n    }, {\n        token : \"constant.language.boolean\",\n        regex : \"(?:true|false)\\\\b\"\n    }, {\n        token : keywordMapper,\n        regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n    }, {\n        token : \"keyword.operator.assignment\",\n        regex : \"=|~\"\n    }, {\n        token : \"keyword.operator.comparison\",\n        regex : \"==|!=|<|>|>=|<=|===\"\n    }, {\n        token : \"keyword.operator.arithmetic\",\n        regex : \"\\\\+|-|/|%|//|\\\\*|\\\\*\\\\*\"\n    }, {\n        token : \"keyword.operator.other\",\n        regex : \"\\\\.\\\\.|\\\\|\"\n    }, {\n        token : \"punctuation.operator\",\n        regex : /\\?|:|,|;|\\./\n    }, {\n        token : \"paren.lparen\",\n        regex : /[\\[\\({]/\n    }, {\n        token : \"paren.rparen\",\n        regex : /[\\])}]/\n    }, {\n        token : \"text\",\n        regex : \"\\\\s+\"\n    } ];\n\n    this.$rules[\"twig-qqstring\"] = [{\n            token : \"constant.language.escape\",\n            regex : /\\\\[\\\\\"$#ntr]|#{[^\"}]*}/\n        }, {\n            token : \"string\",\n            regex : '\"',\n            next  : \"twig-start\"\n        }, {\n            defaultToken : \"string\"\n        }\n    ];\n\n    this.$rules[\"twig-qstring\"] = [{\n            token : \"constant.language.escape\",\n            regex : /\\\\[\\\\'ntr]}/\n        }, {\n            token : \"string\",\n            regex : \"'\",\n            next  : \"twig-start\"\n        }, {\n            defaultToken : \"string\"\n        }\n    ];\n\n    this.normalizeRules();\n};\n\noop.inherits(TwigHighlightRules, TextHighlightRules);\n\nexports.TwigHighlightRules = TwigHighlightRules;\n"
  },
  {
    "path": "src/mode/typescript.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar jsMode = require(\"./javascript\").Mode;\nvar TypeScriptHighlightRules = require(\"./typescript_highlight_rules\").TypeScriptHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = TypeScriptHighlightRules;\n    \n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, jsMode);\n\n(function() {\n    this.createWorker = function(session) {\n        return null;\n    };\n    this.$id = \"ace/mode/typescript\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/typescript_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: 21e323af-f665-4161-96e7-5087d262557e) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptHighlightRules = require(\"./javascript_highlight_rules\").JavaScriptHighlightRules;\n\nvar TypeScriptHighlightRules = function (options) {\n\n    var tsRules = [\n        // Match stuff like: function name: return type)\n        {\n            token: [\"storage.type\", \"text\", \"entity.name.function.ts\"],\n            regex: \"(function)(\\\\s+)([a-zA-Z0-9\\$_\\u00a1-\\uffff][a-zA-Z0-9\\d\\$_\\u00a1-\\uffff]*)\"\n        },\n        {\n            token: \"keyword\",\n            regex: \"(?:\\\\b(constructor|declare|interface|as|AS|public|private|extends|export|super|readonly|module|namespace|abstract|implements)\\\\b)\"\n        },\n        {\n            token: [\"keyword\", \"storage.type.variable.ts\"],\n            regex: \"(class|type)(\\\\s+[a-zA-Z0-9_?.$][\\\\w?.$]*)\"\n         },\n        {\n            token: \"keyword\",\n            regex: \"\\\\b(?:super|export|import|keyof|infer)\\\\b\"\n        }, \n        {\n            token: [\"storage.type.variable.ts\"],\n            regex: \"(?:\\\\b(this\\\\.|string\\\\b|bool\\\\b|boolean\\\\b|number\\\\b|true\\\\b|false\\\\b|undefined\\\\b|any\\\\b|null\\\\b|(?:unique )?symbol\\\\b|object\\\\b|never\\\\b|enum\\\\b))\"\n        }\n    ];\n\n    var JSRules = new JavaScriptHighlightRules({jsx: (options && options.jsx) == true}).getRules();\n    \n    JSRules.no_regex = tsRules.concat(JSRules.no_regex);\n    this.$rules = JSRules;\n};\n\noop.inherits(TypeScriptHighlightRules, JavaScriptHighlightRules);\n\nexports.TypeScriptHighlightRules = TypeScriptHighlightRules;\n"
  },
  {
    "path": "src/mode/vala.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ValaHighlightRules = require(\"./vala_highlight_rules\").ValaHighlightRules;\nvar CStyleFoldMode = require(\"./folding/cstyle\").FoldMode;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\n\nvar Mode = function() {\n    this.HighlightRules = ValaHighlightRules;\n    \n    this.$outdent = new MatchingBraceOutdent();\n    this.$behaviour = this.$defaultBehaviour;\n    this.foldingRules = new CStyleFoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n        var endState = tokenizedLine.state;\n\n        if (tokens.length && tokens[tokens.length-1].type == \"comment\") {\n            return indent;\n        }\n\n        if (state == \"start\" || state == \"no_regex\") {\n            var match = line.match(/^.*(?:\\bcase\\b.*:|[\\{\\(\\[])\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        } else if (state == \"doc-start\") {\n            if (endState == \"start\" || endState == \"no_regex\") {\n                return \"\";\n            }\n            var match = line.match(/^\\s*(\\/?)\\*/);\n            if (match) {\n                if (match[1]) {\n                    indent += \" \";\n                }\n                indent += \"* \";\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    // Extra logic goes here.\n    this.$id = \"ace/mode/vala\";\n    this.snippetFileId = \"ace/snippets/vala\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/vala_highlight_rules.js",
    "content": "/* This file was autogenerated from https://raw.githubusercontent.com/technosophos/Vala-TMBundle/master/Syntaxes/Vala.tmLanguage (uuid: ) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ValaHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = { start: \n       [ { token: \n            [ 'meta.using.vala',\n              'keyword.other.using.vala',\n              'meta.using.vala',\n              'storage.modifier.using.vala',\n              'meta.using.vala',\n              'punctuation.terminator.vala' ],\n           regex: '^(\\\\s*)(using)\\\\b(?:(\\\\s*)([^ ;$]+)(\\\\s*)((?:;)?))?' },\n         { include: '#code' } ],\n      '#all-types': \n       [ { include: '#primitive-arrays' },\n         { include: '#primitive-types' },\n         { include: '#object-types' } ],\n      '#annotations': \n       [ { token: \n            [ 'storage.type.annotation.vala',\n              'punctuation.definition.annotation-arguments.begin.vala' ],\n           regex: '(@[^ (]+)(\\\\()',\n           push: \n            [ { token: 'punctuation.definition.annotation-arguments.end.vala',\n                regex: '\\\\)',\n                next: 'pop' },\n              { token: \n                 [ 'constant.other.key.vala',\n                   'text',\n                   'keyword.operator.assignment.vala' ],\n                regex: '(\\\\w*)(\\\\s*)(=)' },\n              { include: '#code' },\n              { token: 'punctuation.seperator.property.vala', regex: ',' },\n              { defaultToken: 'meta.declaration.annotation.vala' } ] },\n         { token: 'storage.type.annotation.vala', regex: '@\\\\w*' } ],\n      '#anonymous-classes-and-new': \n       [ { token: 'keyword.control.new.vala',\n           regex: '\\\\bnew\\\\b',\n           push_disabled: \n            [ { token: 'text',\n                regex: '(?<=\\\\)|\\\\])(?!\\\\s*{)|(?<=})|(?=;)',\n                TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n                originalRegex: '(?<=\\\\)|\\\\])(?!\\\\s*{)|(?<=})|(?=;)',\n                next: 'pop' },\n              { token: [ 'storage.type.vala', 'text' ],\n                regex: '(\\\\w+)(\\\\s*)(?=\\\\[)',\n                push: \n                 [ { token: 'text', regex: '}|(?=;|\\\\))', next: 'pop' },\n                   { token: 'text',\n                     regex: '\\\\[',\n                     push: \n                      [ { token: 'text', regex: '\\\\]', next: 'pop' },\n                        { include: '#code' } ] },\n                   { token: 'text',\n                     regex: '{',\n                     push: \n                      [ { token: 'text', regex: '(?=})', next: 'pop' },\n                        { include: '#code' } ] } ] },\n              { token: 'text',\n                regex: '(?=\\\\w.*\\\\()',\n                push: \n                 [ { token: 'text',\n                     regex: '(?<=\\\\))',\n                     TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n                     originalRegex: '(?<=\\\\))',\n                     next: 'pop' },\n                   { include: '#object-types' },\n                   { token: 'text',\n                     regex: '\\\\(',\n                     push: \n                      [ { token: 'text', regex: '\\\\)', next: 'pop' },\n                        { include: '#code' } ] } ] },\n              { token: 'meta.inner-class.vala',\n                regex: '{',\n                push: \n                 [ { token: 'meta.inner-class.vala', regex: '}', next: 'pop' },\n                   { include: '#class-body' },\n                   { defaultToken: 'meta.inner-class.vala' } ] } ] } ],\n      '#assertions': \n       [ { token: \n            [ 'keyword.control.assert.vala',\n              'meta.declaration.assertion.vala' ],\n           regex: '\\\\b(assert|requires|ensures)(\\\\s)',\n           push: \n            [ { token: 'meta.declaration.assertion.vala',\n                regex: '$',\n                next: 'pop' },\n              { token: 'keyword.operator.assert.expression-seperator.vala',\n                regex: ':' },\n              { include: '#code' },\n              { defaultToken: 'meta.declaration.assertion.vala' } ] } ],\n      '#class': \n       [ { token: 'meta.class.vala',\n           regex: '(?=\\\\w?[\\\\w\\\\s]*(?:class|(?:@)?interface|enum|struct|namespace)\\\\s+\\\\w+)',\n           push: \n            [ { token: 'paren.vala',\n                regex: '}',\n                next: 'pop' },\n              { include: '#storage-modifiers' },\n              { include: '#comments' },\n              { token: \n                 [ 'storage.modifier.vala',\n                   'meta.class.identifier.vala',\n                   'entity.name.type.class.vala' ],\n                regex: '(class|(?:@)?interface|enum|struct|namespace)(\\\\s+)([\\\\w\\\\.]+)' },\n              { token: 'storage.modifier.extends.vala',\n                regex: ':',\n                push: \n                 [ { token: 'meta.definition.class.inherited.classes.vala',\n                     regex: '(?={|,)',\n                     next: 'pop' },\n                   { include: '#object-types-inherited' },\n                   { include: '#comments' },\n                   { defaultToken: 'meta.definition.class.inherited.classes.vala' } ] },\n              { token: \n                 [ 'storage.modifier.implements.vala',\n                   'meta.definition.class.implemented.interfaces.vala' ],\n                regex: '(,)(\\\\s)',\n                push: \n                 [ { token: 'meta.definition.class.implemented.interfaces.vala',\n                     regex: '(?=\\\\{)',\n                     next: 'pop' },\n                   { include: '#object-types-inherited' },\n                   { include: '#comments' },\n                   { defaultToken: 'meta.definition.class.implemented.interfaces.vala' } ] },\n              { token: 'paren.vala',\n                regex: '{',\n                push: \n                 [ { token: 'paren.vala', regex: '(?=})', next: 'pop' },\n                   { include: '#class-body' },\n                   { defaultToken: 'meta.class.body.vala' } ] },\n              { defaultToken: 'meta.class.vala' } ],\n           comment: 'attempting to put namespace in here.' } ],\n      '#class-body': \n       [ { include: '#comments' },\n         { include: '#class' },\n         { include: '#enums' },\n         { include: '#methods' },\n         { include: '#annotations' },\n         { include: '#storage-modifiers' },\n         { include: '#code' } ],\n      '#code': \n       [ { include: '#comments' },\n         { include: '#class' },\n         { token: 'text',\n           regex: '{',\n           push: \n            [ { token: 'text', regex: '}', next: 'pop' },\n              { include: '#code' } ] },\n         { include: '#assertions' },\n         { include: '#parens' },\n         { include: '#constants-and-special-vars' },\n         { include: '#anonymous-classes-and-new' },\n         { include: '#keywords' },\n         { include: '#storage-modifiers' },\n         { include: '#strings' },\n         { include: '#all-types' } ],\n      '#comments': \n       [ { token: 'punctuation.definition.comment.vala',\n           regex: '/\\\\*\\\\*/' },\n         { include: 'text.html.javadoc' },\n         { include: '#comments-inline' } ],\n      '#comments-inline': \n       [ { token: 'punctuation.definition.comment.vala',\n           regex: '/\\\\*',\n           push: \n            [ { token: 'punctuation.definition.comment.vala',\n                regex: '\\\\*/',\n                next: 'pop' },\n              { defaultToken: 'comment.block.vala' } ] },\n         { token: \n            [ 'text',\n              'punctuation.definition.comment.vala',\n              'comment.line.double-slash.vala' ],\n           regex: '(\\\\s*)(//)(.*$)' } ],\n      '#constants-and-special-vars': \n       [ { token: 'constant.language.vala',\n           regex: '\\\\b(?:true|false|null)\\\\b' },\n         { token: 'variable.language.vala',\n           regex: '\\\\b(?:this|base)\\\\b' },\n         { token: 'constant.numeric.vala',\n           regex: '\\\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\\\.?[0-9]*|\\\\.[0-9]+)(?:(?:e|E)(?:\\\\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\\\\b' },\n         { token: [ 'keyword.operator.dereference.vala', 'constant.other.vala' ],\n           regex: '((?:\\\\.)?)\\\\b([A-Z][A-Z0-9_]+)(?!<|\\\\.class|\\\\s*\\\\w+\\\\s*=)\\\\b' } ],\n      '#enums': \n       [ { token: 'text',\n           regex: '^(?=\\\\s*[A-Z0-9_]+\\\\s*(?:{|\\\\(|,))',\n           push: \n            [ { token: 'text', regex: '(?=;|})', next: 'pop' },\n              { token: 'constant.other.enum.vala',\n                regex: '\\\\w+',\n                push: \n                 [ { token: 'meta.enum.vala', regex: '(?=,|;|})', next: 'pop' },\n                   { include: '#parens' },\n                   { token: 'text',\n                     regex: '{',\n                     push: \n                      [ { token: 'text', regex: '}', next: 'pop' },\n                        { include: '#class-body' } ] },\n                   { defaultToken: 'meta.enum.vala' } ] } ] } ],\n      '#keywords': \n       [ { token: 'keyword.control.catch-exception.vala',\n           regex: '\\\\b(?:try|catch|finally|throw)\\\\b' },\n         { token: 'keyword.control.vala', regex: '\\\\?|:|\\\\?\\\\?' },\n         { token: 'keyword.control.vala',\n           regex: '\\\\b(?:return|break|case|continue|default|do|while|for|foreach|switch|if|else|in|yield|get|set|value)\\\\b' },\n         { token: 'keyword.operator.vala',\n           regex: '\\\\b(?:typeof|is|as)\\\\b' },\n         { token: 'keyword.operator.comparison.vala',\n           regex: '==|!=|<=|>=|<>|<|>' },\n         { token: 'keyword.operator.assignment.vala', regex: '=' },\n         { token: 'keyword.operator.increment-decrement.vala',\n           regex: '\\\\-\\\\-|\\\\+\\\\+' },\n         { token: 'keyword.operator.arithmetic.vala',\n           regex: '\\\\-|\\\\+|\\\\*|\\\\/|%' },\n         { token: 'keyword.operator.logical.vala', regex: '!|&&|\\\\|\\\\|' },\n         { token: 'keyword.operator.dereference.vala',\n           regex: '\\\\.(?=\\\\S)',\n           originalRegex: '(?<=\\\\S)\\\\.(?=\\\\S)' },\n         { token: 'punctuation.terminator.vala', regex: ';' },\n         { token: 'keyword.operator.ownership', regex: 'owned|unowned' } ],\n      '#methods': \n       [ { token: 'meta.method.vala',\n           regex: '(?!new)(?=\\\\w.*\\\\s+)(?=[^=]+\\\\()',\n           push: \n            [ { token: 'paren.vala', regex: '}|(?=;)', next: 'pop' },\n              { include: '#storage-modifiers' },\n              { token: [ 'entity.name.function.vala', 'meta.method.identifier.vala' ],\n                regex: '([\\\\~\\\\w\\\\.]+)(\\\\s*\\\\()',\n                push: \n                 [ { token: 'meta.method.identifier.vala',\n                     regex: '\\\\)',\n                     next: 'pop' },\n                   { include: '#parameters' },\n                   { defaultToken: 'meta.method.identifier.vala' } ] },\n              { token: 'meta.method.return-type.vala',\n                regex: '(?=\\\\w.*\\\\s+\\\\w+\\\\s*\\\\()',\n                push: \n                 [ { token: 'meta.method.return-type.vala',\n                     regex: '(?=\\\\w+\\\\s*\\\\()',\n                     next: 'pop' },\n                   { include: '#all-types' },\n                   { defaultToken: 'meta.method.return-type.vala' } ] },\n              { include: '#throws' },\n              { token: 'paren.vala',\n                regex: '{',\n                push: \n                 [ { token: 'paren.vala', regex: '(?=})', next: 'pop' },\n                   { include: '#code' },\n                   { defaultToken: 'meta.method.body.vala' } ] },\n              { defaultToken: 'meta.method.vala' } ] } ],\n      '#namespace': \n       [ { token: 'text',\n           regex: '^(?=\\\\s*[A-Z0-9_]+\\\\s*(?:{|\\\\(|,))',\n           push: \n            [ { token: 'text', regex: '(?=;|})', next: 'pop' },\n              { token: 'constant.other.namespace.vala',\n                regex: '\\\\w+',\n                push: \n                 [ { token: 'meta.namespace.vala', regex: '(?=,|;|})', next: 'pop' },\n                   { include: '#parens' },\n                   { token: 'text',\n                     regex: '{',\n                     push: \n                      [ { token: 'text', regex: '}', next: 'pop' },\n                        { include: '#code' } ] },\n                   { defaultToken: 'meta.namespace.vala' } ] } ],\n           comment: 'This is not quite right. See the class grammar right now' } ],\n      '#object-types': \n       [ { token: 'storage.type.generic.vala',\n           regex: '\\\\b(?:[a-z]\\\\w*\\\\.)*[A-Z]+\\\\w*<',\n           push: \n            [ { token: 'storage.type.generic.vala',\n                regex: '>|[^\\\\w\\\\s,\\\\?<\\\\[()\\\\]]',\n                TODO: 'FIXME: regexp doesn\\'t have js equivalent',\n                originalRegex: '>|[^\\\\w\\\\s,\\\\?<\\\\[(?:[,]+)\\\\]]',\n                next: 'pop' },\n              { include: '#object-types' },\n              { token: 'storage.type.generic.vala',\n                regex: '<',\n                push: \n                 [ { token: 'storage.type.generic.vala',\n                     regex: '>|[^\\\\w\\\\s,\\\\[\\\\]<]',\n                     next: 'pop' },\n                   { defaultToken: 'storage.type.generic.vala' } ],\n                comment: 'This is just to support <>\\'s with no actual type prefix' },\n              { defaultToken: 'storage.type.generic.vala' } ] },\n         { token: 'storage.type.object.array.vala',\n           regex: '\\\\b(?:[a-z]\\\\w*\\\\.)*[A-Z]+\\\\w*(?=\\\\[)',\n           push: \n            [ { token: 'storage.type.object.array.vala',\n                regex: '(?=[^\\\\]\\\\s])',\n                next: 'pop' },\n              { token: 'text',\n                regex: '\\\\[',\n                push: \n                 [ { token: 'text', regex: '\\\\]', next: 'pop' },\n                   { include: '#code' } ] },\n              { defaultToken: 'storage.type.object.array.vala' } ] },\n         { token: \n            [ 'storage.type.vala',\n              'keyword.operator.dereference.vala',\n              'storage.type.vala' ],\n           regex: '\\\\b(?:([a-z]\\\\w*)(\\\\.))*([A-Z]+\\\\w*\\\\b)' } ],\n      '#object-types-inherited': \n       [ { token: 'entity.other.inherited-class.vala',\n           regex: '\\\\b(?:[a-z]\\\\w*\\\\.)*[A-Z]+\\\\w*<',\n           push: \n            [ { token: 'entity.other.inherited-class.vala',\n                regex: '>|[^\\\\w\\\\s,<]',\n                next: 'pop' },\n              { include: '#object-types' },\n              { token: 'storage.type.generic.vala',\n                regex: '<',\n                push: \n                 [ { token: 'storage.type.generic.vala',\n                     regex: '>|[^\\\\w\\\\s,<]',\n                     next: 'pop' },\n                   { defaultToken: 'storage.type.generic.vala' } ],\n                comment: 'This is just to support <>\\'s with no actual type prefix' },\n              { defaultToken: 'entity.other.inherited-class.vala' } ] },\n         { token: \n            [ 'entity.other.inherited-class.vala',\n              'keyword.operator.dereference.vala',\n              'entity.other.inherited-class.vala' ],\n           regex: '\\\\b(?:([a-z]\\\\w*)(\\\\.))*([A-Z]+\\\\w*)' } ],\n      '#parameters': \n       [ { token: 'storage.modifier.vala', regex: 'final' },\n         { include: '#primitive-arrays' },\n         { include: '#primitive-types' },\n         { include: '#object-types' },\n         { token: 'variable.parameter.vala', regex: '\\\\w+' } ],\n      '#parens': \n       [ { token: 'text',\n           regex: '\\\\(',\n           push: \n            [ { token: 'text', regex: '\\\\)', next: 'pop' },\n              { include: '#code' } ] } ],\n      '#primitive-arrays': \n       [ { token: 'storage.type.primitive.array.vala',\n           regex: '\\\\b(?:bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|int8|int16|int32|int64|uint8|uint16|uint32|uint64)(?:\\\\[\\\\])*\\\\b' } ],\n      '#primitive-types': \n       [ { token: 'storage.type.primitive.vala',\n           regex: '\\\\b(?:var|bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\\\b',\n           comment: 'var is not really a primitive, but acts like one in most cases' } ],\n      '#storage-modifiers': \n       [ { token: 'storage.modifier.vala',\n           regex: '\\\\b(?:public|private|protected|internal|static|final|sealed|virtual|override|abstract|readonly|volatile|dynamic|async|unsafe|out|ref|weak|owned|unowned|const)\\\\b',\n           comment: 'Not sure about unsafe and readonly' } ],\n      '#strings': \n       [ { token: 'punctuation.definition.string.begin.vala',\n           regex: '@\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.vala',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.vala',\n                regex: '\\\\\\\\.|%[\\\\w\\\\.\\\\-]+|\\\\$(?:\\\\w+|\\\\([\\\\w\\\\s\\\\+\\\\-\\\\*\\\\/]+\\\\))' },\n              { defaultToken: 'string.quoted.interpolated.vala' } ] },\n         { token: 'punctuation.definition.string.begin.vala',\n           regex: '\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.vala',\n                regex: '\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.vala', regex: '\\\\\\\\.' },\n              { token: 'constant.character.escape.vala',\n                regex: '%[\\\\w\\\\.\\\\-]+' },\n              { defaultToken: 'string.quoted.double.vala' } ] },\n         { token: 'punctuation.definition.string.begin.vala',\n           regex: '\\'',\n           push: \n            [ { token: 'punctuation.definition.string.end.vala',\n                regex: '\\'',\n                next: 'pop' },\n              { token: 'constant.character.escape.vala', regex: '\\\\\\\\.' },\n              { defaultToken: 'string.quoted.single.vala' } ] },\n         { token: 'punctuation.definition.string.begin.vala',\n           regex: '\"\"\"',\n           push: \n            [ { token: 'punctuation.definition.string.end.vala',\n                regex: '\"\"\"',\n                next: 'pop' },\n              { token: 'constant.character.escape.vala',\n                regex: '%[\\\\w\\\\.\\\\-]+' },\n              { defaultToken: 'string.quoted.triple.vala' } ] } ],\n      '#throws': \n       [ { token: 'storage.modifier.vala',\n           regex: 'throws',\n           push: \n            [ { token: 'meta.throwables.vala', regex: '(?={|;)', next: 'pop' },\n              { include: '#object-types' },\n              { defaultToken: 'meta.throwables.vala' } ] } ],\n      '#values': \n       [ { include: '#strings' },\n         { include: '#object-types' },\n         { include: '#constants-and-special-vars' } ] };\n    \n    this.normalizeRules();\n};\n\nValaHighlightRules.metaData = { \n    comment: 'Based heavily on the Java bundle\\'s language syntax. TODO:\\n* Closures\\n* Delegates\\n* Properties: Better support for properties.\\n* Annotations\\n* Error domains\\n* Named arguments\\n* Array slicing, negative indexes, multidimensional\\n* construct blocks\\n* lock blocks?\\n* regex literals\\n* DocBlock syntax highlighting. (Currently importing javadoc)\\n* Folding rule for comments.\\n',\n      fileTypes: [ 'vala' ],\n      foldingStartMarker: '(\\\\{\\\\s*(//.*)?$|^\\\\s*// \\\\{\\\\{\\\\{)',\n      foldingStopMarker: '^\\\\s*(\\\\}|// \\\\}\\\\}\\\\}$)',\n      name: 'Vala',\n      scopeName: 'source.vala' };\n\n\noop.inherits(ValaHighlightRules, TextHighlightRules);\n\nexports.ValaHighlightRules = ValaHighlightRules;\n"
  },
  {
    "path": "src/mode/vbscript.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar VBScriptHighlightRules = require(\"./vbscript_highlight_rules\").VBScriptHighlightRules;\nvar FoldMode = require(\"./folding/vbscript\").FoldMode;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = VBScriptHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n    this.indentKeywords = this.foldingRules.indentKeywords;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = [\"'\", \"REM\"];\n\n    var outdentKeywords = [\n        \"else\",\n        \"elseif\",\n        \"end\",\n        \"loop\",\n        \"next\",\n        \"wend\"\n    ];\n\n    function isSecondOfDoubleKeyword(tokens, i) {\n        var val = tokens[i].value.toLowerCase();\n        var prevToken = i >= 2 ? tokens[i - 2] : null;\n        if (!prevToken) return false;\n        var prevVal = prevToken.value.toLowerCase();\n\n        // Do While / Do Until / Loop While / Loop Until\n        if ((val === \"while\" || val === \"until\") && (prevVal === \"do\" || prevVal === \"loop\")) {\n            return true;\n        }\n        // Exit For / Exit Do / Exit Sub / Exit Function / Exit Property\n        if (prevVal === \"exit\" && (val === \"for\" || val === \"do\" || val === \"sub\" || val === \"function\" || val\n            === \"property\")) {\n            return true;\n        }\n        return false;\n    }\n\n    function getNetIndentLevel(tokens, line, indentKeywords) {\n        var level = 0;\n        // Support single-line blocks by decrementing the indent level if\n        // an ending token is found\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            if (token.type == \"keyword.control.asp\" || token.type == \"storage.type.function.asp\") {\n                var val = token.value.toLowerCase();\n                if (val in indentKeywords) {\n                    if (isSecondOfDoubleKeyword(tokens, i)) {\n                        continue;\n                    }\n                    switch (val) {\n                        case \"property\":\n                        case \"sub\":\n                        case \"function\":\n                        case \"select\":\n                        case \"do\":\n                        case \"for\":\n                        case \"class\":\n                        case \"while\":\n                        case \"with\":\n                        case \"if\":\n                            var checkToken = new RegExp(\"^\\\\s* end\\\\s+\" + val, \"i\");\n                            var singleLineCondition = /^\\s*If\\s+.*\\s+Then(?!')\\s+(?!')\\S/i.test(line);\n                            if (!singleLineCondition && !checkToken.test(line))\n                                level += indentKeywords[val];\n                            break;\n                        default:\n                            level += indentKeywords[val];\n                            break;\n                    }\n                }\n            }\n        }\n        // Limit the level to +/- 1 since usually users only indent one level\n        // at a time regardless of the logical nesting level\n        if (level < 0) {\n            return -1;\n        } else if (level > 0) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n        var level = 0;\n\n        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);\n        var tokens = tokenizedLine.tokens;\n\n        if (state == \"start\") {\n            level = getNetIndentLevel(tokens, line, this.indentKeywords);\n        }\n        if (level > 0) {\n            return indent + tab;\n        } else if (level < 0 && indent.substr(indent.length - tab.length) == tab) {\n            // Don't do a next-line outdent if we're going to do a real outdent of this line\n            if (!this.checkOutdent(state, line, \"\\n\")) {\n                return indent.substr(0, indent.length - tab.length);\n            }\n        }\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        if (input != \"\\n\" && input != \"\\r\" && input != \"\\r\\n\")\n            return false;\n\n        var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens;\n\n        if (!tokens || !tokens.length)\n            return false;\n        var val = tokens[0].value.toLowerCase();\n        return ((tokens[0].type == \"keyword.control.asp\" || tokens[0].type == \"storage.type.function.asp\") && outdentKeywords.indexOf(val) != -1);\n    };\n\n    this.getMatching = function(session, row, column, tokenRange) {\n        if (row == undefined) {\n            var pos = session.selection.lead;\n            column = pos.column;\n            row = pos.row;\n        }\n        if (tokenRange == undefined)\n            tokenRange = true;\n\n        var startToken = session.getTokenAt(row, column);\n        if (startToken) {\n            var val = startToken.value.toLowerCase();\n            if (/^\\s+$/.test(val)) {\n                column = column + val.length;\n                startToken = session.getTokenAt(row, column);\n                if (!startToken) {\n                    return;\n                }\n                val = startToken.value.toLowerCase();\n            }\n            if (val in this.indentKeywords)\n                return this.foldingRules.vbsBlock(session, row, column, tokenRange);\n        }\n    };\n\n    this.autoOutdent = function(state, session, row) {\n        var line = session.getLine(row);\n        var column = line.match(/^\\s*/)[0].length;\n        if (!column || !row) return;\n\n        var startRange = this.getMatching(session, row, column + 1, false);\n        if (!startRange || startRange.start.row == row)\n            return;\n        var indent = this.$getIndent(session.getLine(startRange.start.row));\n        if (indent.length != column) {\n            session.replace(new Range(row, 0, row, column), indent);\n            session.outdentRows(new Range(row + 1, 0, row + 1, 0));\n        }\n    };\n\n    this.$id = \"ace/mode/vbscript\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/vbscript_highlight_rules.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: 7F9C9343-D48E-4E7D-BFE8-F680714DCD3E) */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar VBScriptHighlightRules = function() {\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.control.asp\":  \"If|Then|Else|ElseIf|End|While|Wend|For|To|Each|Case|Select|Return\"\n            + \"|Continue|Do|Until|Loop|Next|With|Exit|Function|Property|Type|Enum|Sub|IIf|Class\",\n        \"storage.type.asp\": \"Dim|Call|Const|Redim|Set|Let|Get|New|Randomize|Option|Explicit|Preserve|Erase|Execute|ExecuteGlobal\",\n        \"storage.modifier.asp\": \"Private|Public|Default\",\n        \"keyword.operator.asp\": \"Mod|And|Not|Or|Xor|As|Eqv|Imp|Is\",\n        \"constant.language.asp\": \"Empty|False|Nothing|Null|True\",\n        \"variable.language.vb.asp\": \"Me\",\n        \"support.class.vb.asp\": \"RegExp\",\n        \"support.class.asp\": \"Application|ObjectContext|Request|Response|Server|Session\",\n        \"support.class.collection.asp\": \"Contents|StaticObjects|ClientCertificate|Cookies|Form|QueryString|ServerVariables\",\n        \"support.constant.asp\": \"TotalBytes|Buffer|CacheControl|Charset|ContentType|Expires|ExpiresAbsolute\"\n            + \"|IsClientConnected|PICS|Status|ScriptTimeout|CodePage|LCID|SessionID|Timeout\",\n        \"support.function.asp\": \"Lock|Unlock|SetAbort|SetComplete|BinaryRead|AddHeader|AppendToLog\"\n            + \"|BinaryWrite|Clear|Flush|Redirect|Write|CreateObject|HTMLEncode|MapPath|URLEncode|Abandon|Convert|Regex\",\n        \"support.function.event.asp\": \"Application_OnEnd|Application_OnStart\"\n            + \"|OnTransactionAbort|OnTransactionCommit|Session_OnEnd|Session_OnStart\",\n        \"support.function.vb.asp\": \"Array|Add|Asc|Atn|CBool|CByte|CCur|CDate|CDbl|Chr|CInt|CLng\"\n            + \"|Conversions|Cos|CreateObject|CSng|CStr|Date|DateAdd|DateDiff|DatePart|DateSerial\"\n            + \"|DateValue|Day|Derived|Math|Escape|Eval|Exists|Exp|Filter|FormatCurrency\"\n            + \"|FormatDateTime|FormatNumber|FormatPercent|GetLocale|GetObject|GetRef|Hex\"\n            + \"|Hour|InputBox|InStr|InStrRev|Int|Fix|IsArray|IsDate|IsEmpty|IsNull|IsNumeric\"\n            + \"|IsObject|Item|Items|Join|Keys|LBound|LCase|Left|Len|LoadPicture|Log|LTrim|RTrim\"\n            + \"|Trim|Maths|Mid|Minute|Month|MonthName|MsgBox|Now|Oct|Remove|RemoveAll|Replace\"\n            + \"|RGB|Right|Rnd|Round|ScriptEngine|ScriptEngineBuildVersion|ScriptEngineMajorVersion\"\n            + \"|ScriptEngineMinorVersion|Second|SetLocale|Sgn|Sin|Space|Split|Sqr|StrComp|String|StrReverse\"\n            + \"|Tan|Time|Timer|TimeSerial|TimeValue|TypeName|UBound|UCase|Unescape|VarType|Weekday|WeekdayName|Year\"\n            + \"|AscB|AscW|ChrB|ChrW|InStrB|LeftB|LenB|MidB|RightB|Abs|GetUILanguage\",\n        \"support.type.vb.asp\": \"vbTrue|vbFalse|vbCr|vbCrLf|vbFormFeed|vbLf|vbNewLine|vbNullChar|vbNullString\"\n            + \"|vbTab|vbVerticalTab|vbBinaryCompare|vbTextCompare|vbSunday|vbMonday|vbTuesday|vbWednesday\"\n            + \"|vbThursday|vbFriday|vbSaturday|vbUseSystemDayOfWeek|vbFirstJan1|vbFirstFourDays|vbFirstFullWeek\"\n            + \"|vbGeneralDate|vbLongDate|vbShortDate|vbLongTime|vbShortTime|vbObjectError|vbEmpty|vbNull|vbInteger\"\n            + \"|vbLong|vbSingle|vbDouble|vbCurrency|vbDate|vbString|vbObject|vbError|vbBoolean|vbVariant\"\n            + \"|vbDataObject|vbDecimal|vbByte|vbArray|vbOKOnly|vbOKCancel|vbAbortRetryIgnore|vbYesNoCancel|vbYesNo\"\n            + \"|vbRetryCancel|vbCritical|vbQuestion|vbExclamation|vbInformation|vbDefaultButton1|vbDefaultButton2\"\n            + \"|vbDefaultButton3|vbDefaultButton4|vbApplicationModal|vbSystemModal|vbOK|vbCancel|vbAbort|vbRetry|vbIgnore|vbYes|vbNo\"\n            + \"|vbUseDefault\"\n    }, \"identifier\", true);\n\n    this.$rules = {\n    \"start\": [\n        {\n            token: [\n                \"meta.ending-space\"\n            ],\n            regex: \"$\"\n        },\n        {\n            token: [null],\n            regex: \"^(?=\\\\t)\",\n            next: \"state_3\"\n        },\n        {\n            token: [null],\n            regex: \"^(?= )\",\n            next: \"state_4\"\n        },\n        {\n            token: [\n                \"text\",\n                \"storage.type.function.asp\",\n                \"text\",\n                \"entity.name.function.asp\",\n                \"text\",\n                \"punctuation.definition.parameters.asp\",\n                \"variable.parameter.function.asp\",\n                \"punctuation.definition.parameters.asp\"\n            ],\n            regex: \"^(\\\\s*)(Function|Sub)(\\\\s+)([a-zA-Z_]\\\\w*)(\\\\s*)(\\\\()([^)]*)(\\\\))\"\n        },\n        {\n            token: \"punctuation.definition.comment.asp\",\n            regex: \"'|REM(?=\\\\s|$)\",\n            next: \"comment\",\n            caseInsensitive: true\n        },\n        {\n            token: \"storage.type.asp\",\n            regex: \"On\\\\s+Error\\\\s+(?:Resume\\\\s+Next|GoTo)\\\\b\",\n            caseInsensitive: true\n        },\n        {\n            token: \"punctuation.definition.string.begin.asp\",\n            regex: '\"',\n            next: \"string\"\n        },\n        {\n            token: [\n                \"punctuation.definition.variable.asp\"\n            ],\n            regex: \"(\\\\$)[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?\\\\b\\\\s*\"\n        },\n//        {\n//            token: [\n//                \"support.type.vb.asp\"\n//            ],\n//            regex: \"(?:(?<=as )(\\\\b[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?\\\\b))\", // ERROR: This contains a lookbehind, which JS does not support :(\"\n//        },\n        {\n            token: \"constant.numeric.asp\",\n            regex: \"-?\\\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:(?:[0-9]+\\\\.?[0-9]*)|(?:\\\\.[0-9]+))(?:(?:e|E)(?:\\\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\\\b\"\n        },\n        {\n            regex: \"\\\\w+\",\n            token: keywordMapper\n        },\n        {\n            token: [\"entity.name.function.asp\"],\n            regex: \"(?:(\\\\b[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?\\\\b)(?=\\\\(\\\\)?))\"\n        },\n//        {\n//            token: [\n//                \"variable.other.asp\"\n//            ],\n//            regex: \"(?:((?<=(\\\\+|=|-|\\\\&|\\\\\\\\|/|<|>|\\\\(|,))\\\\s*\\\\b([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?)\\\\b(?!(\\\\(|\\\\.))|\\\\b([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?)\\\\b(?=\\\\s*(\\\\+|=|-|\\\\&|\\\\\\\\|/|<|>|\\\\(|\\\\)))))\", // ERROR: This contains a lookbehind, which JS does not support :(\"\n//        },\n        {\n            token: [\"keyword.operator.asp\"],\n            regex: \"\\\\-|\\\\+|\\\\*|\\\\/|\\\\>|\\\\<|\\\\=|\\\\&|\\\\\\\\|\\\\^\"\n        }\n    ],\n    \"state_3\": [\n        {\n            token: [\n                \"meta.odd-tab.tabs\",\n                \"meta.even-tab.tabs\"\n            ],\n            regex: \"(\\\\t)(\\\\t)?\"\n        },\n        {\n            token: \"meta.leading-space\",\n            regex: \"(?=[^\\\\t])\",\n            next: \"start\"\n        },\n        {\n            token: \"meta.leading-space\",\n            regex: \".\",\n            next: \"state_3\"\n        }\n    ],\n    \"state_4\": [\n        {\n            token: [\"meta.odd-tab.spaces\", \"meta.even-tab.spaces\"],\n            regex: \"(  )(  )?\"\n        },\n        {\n            token: \"meta.leading-space\",\n            regex: \"(?=[^ ])\",\n            next: \"start\"\n        },\n        {\n            defaultToken: \"meta.leading-space\"\n        }\n    ],\n    \"comment\": [\n        {\n            token: \"comment.line.apostrophe.asp\",\n            regex: \"$\",\n            next: \"start\"\n        },\n        {\n            defaultToken: \"comment.line.apostrophe.asp\"\n        }\n    ],\n    \"string\": [\n        {\n            token: \"constant.character.escape.apostrophe.asp\",\n            regex: '\"\"'\n        },\n        {\n            token: \"string.quoted.double.asp\",\n            regex: '\"',\n            next: \"start\"\n        },\n        {\n            defaultToken: \"string.quoted.double.asp\"\n        }\n    ]\n};\n\n};\n\noop.inherits(VBScriptHighlightRules, TextHighlightRules);\n\nexports.VBScriptHighlightRules = VBScriptHighlightRules;\n"
  },
  {
    "path": "src/mode/vbscript_test.js",
    "content": "    \"use strict\";\n\n    var EditSession = require(\"../edit_session\").EditSession;\n    var VBScriptMode = require(\"./vbscript\").Mode;\n    var assert = require(\"../test/assertions\");\n\n    module.exports = {\n        setUp : function() {\n            this.mode = new VBScriptMode();\n        },\n\n        \"test: getNextLineIndent\": function() {\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"Class ClassName\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Public Default Function FunctionName(param)\", \"  \"), \"    \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  If Answer <> vbOK Then Exit Sub\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  If Condition Then\", \"  \"), \"    \");\n        },\n\n        \"test: checkOutdent\": function() {\n            assert.ok(this.mode.checkOutdent(\"start\", \"        End If\", \"\\n\"));\n            assert.ok(this.mode.checkOutdent(\"start\", \"        Loop\", \"\\n\"));\n            assert.equal(this.mode.checkOutdent(\"start\", \"  Class blabla\", \"\\n\"), false);\n            assert.equal(this.mode.checkOutdent(\"start\", \"\", \"\\r\"), false);\n        },\n\n        \"test: auto outdent\" : function() {\n            var session = new EditSession([\"Class ClassName\", \"  some code\", \"  End Class\"]);\n            session.setMode(this.mode);\n            this.mode.autoOutdent(\"start\", session, 2);\n            assert.equal(\"End Class\", session.getLine(2));\n        },\n\n        \"test: opening/ending tags matching\": function() {\n            var session = new EditSession([\n                'Sub Name(attr)',\n                '   If Condition Then ',\n                '      some code',\n                '   ElseIf condition2',\n                '      another code',\n                '   ElseIf condition3',\n                '      another code',\n                '   Else',\n                '      another code',\n                '   End If',\n                'End Sub'\n            ]);\n\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.range(ranges[0], 0, 0, 0, 3);\n            assert.range(ranges[1], 10, 0, 10, 7);\n\n            ranges = this.mode.getMatching(session, 10, 1);\n            assert.range(ranges[1], 0, 0, 0, 3);\n            assert.range(ranges[0], 10, 0, 10, 7);\n\n            ranges = this.mode.getMatching(session, 1, 4);\n            assert.range(ranges[0], 1, 3, 1, 5);\n            assert.range(ranges[1], 9, 3, 9, 9);\n\n            ranges = this.mode.getMatching(session, 9, 8);\n            assert.range(ranges[1], 1, 3, 1, 5);\n            assert.range(ranges[0], 9, 3, 9, 9);\n\n            ranges = this.mode.getMatching(session, 3, 4);\n            assert.range(ranges[0], 3, 3, 3, 9);\n            assert.range(ranges[1], 5, 3, 5, 9);\n\n            ranges = this.mode.getMatching(session, 5, 4);\n            assert.range(ranges[0], 5, 3, 5, 9);\n            assert.range(ranges[1], 7, 3, 7, 7);\n        },\n\n        \"test: single line condition couldn't have closing tag\": function() {\n            var session = new EditSession([\n                'Sub Name(attr)',\n                '   If Condition Then ',\n                '       If Condition Then Exit Sub',\n                '   End If',\n                'End Sub'\n            ]);\n\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 2, 8);\n            assert.equal(ranges, undefined);\n\n            ranges = this.mode.getMatching(session, 1, 4);\n            assert.range(ranges[0], 1, 3, 1, 5);\n            assert.range(ranges[1], 3, 3, 3, 9);\n\n            ranges = this.mode.getMatching(session, 3, 4);\n            assert.range(ranges[1], 1, 3, 1, 5);\n            assert.range(ranges[0], 3, 3, 3, 9);\n\n            ranges = this.mode.getMatching(session, 4, 1);\n            assert.range(ranges[1], 0, 0, 0, 3);\n            assert.range(ranges[0], 4, 0, 4, 7);\n        },\n\n        \"test: private and public properties/subs/functions should return matching tag\": function() {\n            var session = new EditSession([\n                'Class ClassName',\n                '   Public Property Get PropertyName',\n                '       some code',\n                '   End Property',\n                '',\n                '   Private Function FunctionName(value1, value2)',\n                '       some code',\n                '   End Function',\n                'End Class'\n            ]);\n\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 1, 11);\n            assert.range(ranges[0], 1, 10, 1, 18);\n            assert.range(ranges[1], 3, 3, 3, 15);\n\n            ranges = this.mode.getMatching(session, 3, 5);\n            assert.range(ranges[1], 1, 10, 1, 18);\n            assert.range(ranges[0], 3, 3, 3, 15);\n\n            ranges = this.mode.getMatching(session, 5, 14);\n            assert.range(ranges[0], 5, 11, 5, 19);\n            assert.range(ranges[1], 7, 3, 7, 15);\n\n            ranges = this.mode.getMatching(session, 7, 4);\n            assert.range(ranges[1], 5, 11, 5, 19);\n            assert.range(ranges[0], 7, 3, 7, 15);\n        },\n\n        \"test: wrong closing/opening tag\": function() {\n            var session = new EditSession([\n                'Class ClassName',\n                '   Public Property Get PropertyName',\n                '       some code',\n                '   End Class',\n                '',\n                '   Private Property FunctionName(value1, value2)',\n                '       some code',\n                '   End AnyWord',\n                'End Class'\n            ]);\n\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 1, 11);\n            assert.equal(ranges.length, 1);\n            assert.range(ranges[0], 3, 3, 3, 12);\n\n            ranges = this.mode.getMatching(session, 7, 4);\n            assert.equal(ranges.length, 1);\n            assert.range(ranges[0], 5, 11, 5, 19);\n\n            ranges = this.mode.getMatching(session, 0, 3);\n            assert.range(ranges[0], 0, 0, 0, 5);\n            assert.range(ranges[1], 8, 0, 8, 9);\n        },\n\n        \"test: Do While / Loop double keyword matching\": function() {\n            var session = new EditSession([\n                'Do While condition',\n                '   some code',\n                'Loop'\n            ]);\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 2, 0, 2, 4);\n\n            ranges = this.mode.getMatching(session, 0, 4);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 2, 0, 2, 4);\n\n            // Cursor on whitespace between \"Do\" and \"While\"\n            ranges = this.mode.getMatching(session, 0, 2);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 2, 0, 2, 4);\n        },\n\n        \"test: Do Until / Loop double keyword matching\": function() {\n            var session = new EditSession([\n                'Do Until condition',\n                '   some code',\n                'Loop'\n            ]);\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 2, 0, 2, 4);\n\n            ranges = this.mode.getMatching(session, 0, 4);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 2, 0, 2, 4);\n        },\n\n        \"test: Do / Loop Until double keyword matching\": function() {\n            var session = new EditSession([\n                'Do',\n                '   some code',\n                'Loop Until condition'\n            ]);\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 2);\n            assert.range(ranges[1], 2, 0, 2, 10); // \"Loop Until\"\n\n            ranges = this.mode.getMatching(session, 2, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 2, 0, 2, 10);\n            assert.range(ranges[1], 0, 0, 0, 2);\n\n            ranges = this.mode.getMatching(session, 2, 6);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 2, 0, 2, 10);\n            assert.range(ranges[1], 0, 0, 0, 2);\n        },\n\n        \"test: Exit statements should not match\": function() {\n            var session = new EditSession([\n                'Do While condition',\n                '   Exit Do',\n                '   some code',\n                'Loop',\n                'For i = 1 To 10',\n                '   Exit For',\n                'Next'\n            ]);\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 1, 4);\n            assert.equal(ranges, undefined);\n\n            // Exit Do - cursor on \"Do\" after \"Exit\"\n            ranges = this.mode.getMatching(session, 1, 8);\n            assert.equal(ranges, undefined);\n\n            // Exit For - cursor on \"Exit\"\n            ranges = this.mode.getMatching(session, 5, 4);\n            assert.equal(ranges, undefined);\n\n            // Exit For - cursor on \"For\" after \"Exit\"\n            ranges = this.mode.getMatching(session, 5, 8);\n            assert.equal(ranges, undefined);\n\n            // Do While should still match Loop correctly\n            ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 3, 0, 3, 4);\n        },\n\n        \"test: getNextLineIndent with double keywords\": function() {\n            // Do While/Until - one indent, not two\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"Do While condition\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"Do Until condition\", \"  \"), \"  \");\n\n            // Exit statements - no indent change\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Exit Do\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Exit For\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Exit Sub\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Exit Function\", \"  \"), \"  \");\n            assert.equal(this.mode.getNextLineIndent(\"start\", \"  Exit Property\", \"  \"), \"  \");\n        },\n\n        \"test: nested Do loops with double keywords\": function() {\n            var session = new EditSession([\n                'Do While outer',\n                '   Do Until inner',\n                '      some code',\n                '   Loop',\n                'Loop'\n            ]);\n            session.setMode(this.mode);\n\n            // Outer Do While -> outer Loop\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 8);\n            assert.range(ranges[1], 4, 0, 4, 4);\n\n            // Inner Do Until -> inner Loop\n            ranges = this.mode.getMatching(session, 1, 4);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 1, 3, 1, 11);\n            assert.range(ranges[1], 3, 3, 3, 7);\n        },\n\n        \"test: plain Do / Loop without While/Until\": function() {\n            var session = new EditSession([\n                'Do',\n                '   some code',\n                'Loop'\n            ]);\n            session.setMode(this.mode);\n\n            var ranges = this.mode.getMatching(session, 0, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 0, 0, 0, 2);\n            assert.range(ranges[1], 2, 0, 2, 4);\n\n            ranges = this.mode.getMatching(session, 2, 0);\n            assert.equal(ranges.length, 2);\n            assert.range(ranges[0], 2, 0, 2, 4);\n            assert.range(ranges[1], 0, 0, 0, 2);\n        }\n    };\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/velocity.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar VelocityHighlightRules = require(\"./velocity_highlight_rules\").VelocityHighlightRules;\nvar FoldMode = require(\"./folding/velocity\").FoldMode;\n\nvar Mode = function() {\n    HtmlMode.call(this);\n    this.HighlightRules = VelocityHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, HtmlMode);\n\n(function() {\n    this.lineCommentStart = \"##\";\n    this.blockComment = {start: \"#*\", end: \"*#\"};\n    this.$id = \"ace/mode/velocity\";\n    this.snippetFileId = \"ace/snippets/velocity\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/velocity_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar HtmlHighlightRules = require(\"./html_highlight_rules\").HtmlHighlightRules;\n\nvar VelocityHighlightRules = function() {\n    HtmlHighlightRules.call(this);\n\n    var builtinConstants = lang.arrayToMap(\n        ('true|false|null').split('|')\n    );\n\n    var builtinFunctions = lang.arrayToMap(\n        (\"_DateTool|_DisplayTool|_EscapeTool|_FieldTool|_MathTool|_NumberTool|_SerializerTool|_SortTool|_StringTool|_XPathTool\").split('|')\n    );\n\n    var builtinVariables = lang.arrayToMap(\n        ('$contentRoot|$foreach').split('|')\n    );\n\n    var keywords = lang.arrayToMap(\n        (\"#set|#macro|#include|#parse|\" +\n        \"#if|#elseif|#else|#foreach|\" +\n        \"#break|#end|#stop\"\n        ).split('|')\n    );\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules.start.push(\n        {\n            token : \"comment\",\n            regex : \"##.*$\"\n        },{\n            token : \"comment.block\", // multi line comment\n            regex : \"#\\\\*\",\n            next : \"vm_comment\"\n        }, {\n            token : \"string.regexp\",\n            regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n        }, {\n            token : \"string\", // single line\n            regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n        }, {\n            token : \"string\", // single line\n            regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n        }, {\n            token : \"constant.numeric\", // hex\n            regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : \"constant.language.boolean\",\n            regex : \"(?:true|false)\\\\b\"\n        }, {\n            token : function(value) {\n                if (keywords.hasOwnProperty(value))\n                    return \"keyword\";\n                else if (builtinConstants.hasOwnProperty(value))\n                    return \"constant.language\";\n                else if (builtinVariables.hasOwnProperty(value))\n                    return \"variable.language\";\n                else if (builtinFunctions.hasOwnProperty(value) || builtinFunctions.hasOwnProperty(value.substring(1)))\n                    return \"support.function\";\n                else if (value == \"debugger\")\n                    return \"invalid.deprecated\";\n                else\n                    if(value.match(/^(\\$[a-zA-Z_][a-zA-Z0-9_]*)$/))\n                        return \"variable\";\n                    return \"identifier\";\n            },\n            // TODO: Unicode escape sequences\n            // TODO: Unicode identifiers\n            regex : \"[a-zA-Z$#][a-zA-Z0-9_]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|&|\\\\*|\\\\-|\\\\+|=|!=|<=|>=|<|>|&&|\\\\|\\\\|\"\n        }, {\n            token : \"lparen\",\n            regex : \"[[({]\"\n        }, {\n            token : \"rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }\n    );\n\n    this.$rules[\"vm_comment\"] = [\n        {\n            token : \"comment\", // closing comment\n            regex : \"\\\\*#|-->\",\n            next : \"start\"\n        }, {\n            defaultToken: \"comment\"\n        }\n    ];\n\n    this.$rules[\"vm_start\"] = [\n        {\n            token: \"variable\",\n            regex: \"}\",\n            next: \"pop\"\n        }, {\n            token : \"string.regexp\",\n            regex : \"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"\n        }, {\n            token : \"string\", // single line\n            regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n        }, {\n            token : \"string\", // single line\n            regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n        }, {\n            token : \"constant.numeric\", // hex\n            regex : \"0[xX][0-9a-fA-F]+\\\\b\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : \"constant.language.boolean\",\n            regex : \"(?:true|false)\\\\b\"\n        }, {\n            token : function(value) {\n                if (keywords.hasOwnProperty(value))\n                    return \"keyword\";\n                else if (builtinConstants.hasOwnProperty(value))\n                    return \"constant.language\";\n                else if (builtinVariables.hasOwnProperty(value))\n                    return \"variable.language\";\n                else if (builtinFunctions.hasOwnProperty(value) || builtinFunctions.hasOwnProperty(value.substring(1)))\n                    return \"support.function\";\n                else if (value == \"debugger\")\n                    return \"invalid.deprecated\";\n                else\n                    if(value.match(/^(\\$[a-zA-Z_$][a-zA-Z0-9_]*)$/))\n                        return \"variable\";\n                    return \"identifier\";\n            },\n            // TODO: Unicode escape sequences\n            // TODO: Unicode identifiers\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"!|&|\\\\*|\\\\-|\\\\+|=|!=|<=|>=|<|>|&&|\\\\|\\\\|\"\n        }, {\n            token : \"lparen\",\n            regex : \"[[({]\"\n        }, {\n            token : \"rparen\",\n            regex : \"[\\\\])}]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        }\n    ];\n\n    for (var i in this.$rules) {\n        this.$rules[i].unshift({\n            token: \"variable\",\n            regex: \"\\\\${\",\n            push: \"vm_start\"\n        });\n    }\n\n    this.normalizeRules();\n};\n\noop.inherits(VelocityHighlightRules, TextHighlightRules);\n\nexports.VelocityHighlightRules = VelocityHighlightRules;\n"
  },
  {
    "path": "src/mode/verilog.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar VerilogHighlightRules = require(\"./verilog_highlight_rules\").VerilogHighlightRules;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = VerilogHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"//\";\n    this.blockComment = {start: \"/*\", end: \"*/\"};\n    this.$quotes = { '\"': '\"' };\n\n\n    this.$id = \"ace/mode/verilog\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/verilog_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar VerilogHighlightRules = function() {\nvar keywords = \"always|and|assign|automatic|begin|buf|bufif0|bufif1|case|casex|casez|cell|cmos|config|\" +\n    \"deassign|default|defparam|design|disable|edge|else|end|endcase|endconfig|endfunction|endgenerate|endmodule|\" +\n    \"endprimitive|endspecify|endtable|endtask|event|for|force|forever|fork|function|generate|genvar|highz0|\" +\n    \"highz1|if|ifnone|incdir|include|initial|inout|input|instance|integer|join|large|liblist|library|localparam|\" +\n    \"macromodule|medium|module|nand|negedge|nmos|nor|noshowcancelled|not|notif0|notif1|or|output|parameter|pmos|\" +\n    \"posedge|primitive|pull0|pull1|pulldown|pullup|pulsestyle_onevent|pulsestyle_ondetect|rcmos|real|realtime|\" +\n    \"reg|release|repeat|rnmos|rpmos|rtran|rtranif0|rtranif1|scalared|showcancelled|signed|small|specify|specparam|\" +\n    \"strong0|strong1|supply0|supply1|table|task|time|tran|tranif0|tranif1|tri|tri0|tri1|triand|trior|trireg|\" +\n    \"unsigned|use|vectored|wait|wand|weak0|weak1|while|wire|wor|xnor|xor\" +\n    \"begin|bufif0|bufif1|case|casex|casez|config|else|end|endcase|endconfig|endfunction|\" +\n    \"endgenerate|endmodule|endprimitive|endspecify|endtable|endtask|for|forever|function|generate|if|ifnone|\" +\n    \"macromodule|module|primitive|repeat|specify|table|task|while\";\n\n    var builtinConstants = (\n        \"true|false|null\"\n    );\n\n    var builtinFunctions = (\n        \"count|min|max|avg|sum|rank|now|coalesce|main\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"support.function\": builtinFunctions,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"//.*$\"\n        }, {\n            token : \"comment.start\",\n            regex : \"/\\\\*\",\n            next : [\n                { token : \"comment.end\", regex : \"\\\\*/\", next: \"start\" },\n                { defaultToken : \"comment\" }\n            ]\n        }, {\n            token : \"string.start\",\n            regex : '\"',\n            next : [\n                { token : \"constant.language.escape\", regex : /\\\\(?:[ntvfa\\\\\"]|[0-7]{1,3}|\\x[a-fA-F\\d]{1,2}|)/, consumeLineEnd : true },\n                { token : \"string.end\", regex : '\"|$', next: \"start\" },\n                { defaultToken : \"string\" }\n            ]\n        }, {\n            token : \"string\",\n            regex : \"'^[']'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"\\\\+|\\\\-|\\\\/|\\\\/\\\\/|%|<@>|@>|<@|&|\\\\^|~|<|>|<=|=>|==|!=|<>|=\"\n        }, {\n            token : \"paren.lparen\",\n            regex : \"[\\\\(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\)]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n    };\n    this.normalizeRules();\n};\n\noop.inherits(VerilogHighlightRules, TextHighlightRules);\n\nexports.VerilogHighlightRules = VerilogHighlightRules;\n"
  },
  {
    "path": "src/mode/vhdl.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar VHDLHighlightRules = require(\"./vhdl_highlight_rules\").VHDLHighlightRules;\n\nvar Mode = function() {\n    this.HighlightRules = VHDLHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = \"--\";\n\n    this.$id = \"ace/mode/vhdl\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/vhdl_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar VHDLHighlightRules = function() {\n\n\n    \n    var keywords = \"access|after|alias|all|architecture|assert|attribute|\"+\n                   \"begin|block|body|buffer|bus|case|component|configuration|\"+\n                   \"context|disconnect|downto|else|elsif|end|entity|exit|\"+\n                   \"file|for|force|function|generate|generic|group|guarded|\"+\n                   \"if|impure|in|inertial|inout|is|label|library|linkage|\"+\n                   \"literal|loop|map|new|next|of|on|or|open|others|out|\"+\n                   \"package|parameter|port|postponed|procedure|process|\"+\n                   \"protected|pure|range|record|register|reject|release|\"+\n                   \"report|return|select|severity|shared|signal|subtype|then|\"+\n                   \"to|transport|type|unaffected|units|until|use|variable|\"+\n                   \"wait|when|while|with\";\n    \n    var storageType = \"bit|bit_vector|boolean|character|integer|line|natural|\"+\n                      \"positive|real|register|signed|std_logic|\"+\n                      \"std_logic_vector|string||text|time|unsigned\";\n    \n    var storageModifiers = \"array|constant\";\n    \n    var keywordOperators = \"abs|and|mod|nand|nor|not|rem|rol|ror|sla|sll|sra\"+\n                           \"srl|xnor|xor\";\n    \n    var builtinConstants = (\n        \"true|false|null\"\n    );\n\n\n    var keywordMapper = this.createKeywordMapper({\n        \"keyword.operator\": keywordOperators,\n        \"keyword\": keywords,\n        \"constant.language\": builtinConstants,\n        \"storage.modifier\": storageModifiers,\n        \"storage.type\": storageType\n    }, \"identifier\", true);\n\n    this.$rules = {\n        \"start\" : [ {\n            token : \"comment\",\n            regex : \"--.*$\"\n        }, {\n            token : \"string\",           // \" string\n            regex : '\".*?\"'\n        }, {\n            token : \"string\",           // ' string\n            regex : \"'.*?'\"\n        }, {\n            token : \"constant.numeric\", // float\n            regex : \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"\n        }, {\n            token : \"keyword\", // pre-compiler directives\n            regex : \"\\\\s*(?:library|package|use)\\\\b\"\n        }, {\n            token : keywordMapper,\n            regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n        }, {\n            token : \"keyword.operator\",\n            regex : \"&|\\\\*|\\\\+|\\\\-|\\\\/|<|=|>|\\\\||=>|\\\\*\\\\*|:=|\\\\/=|>=|<=|<>\" \n        }, {\n              token : \"punctuation.operator\",\n              regex : \"\\\\'|\\\\:|\\\\,|\\\\;|\\\\.\"\n        },{\n            token : \"paren.lparen\",\n            regex : \"[[(]\"\n        }, {\n            token : \"paren.rparen\",\n            regex : \"[\\\\])]\"\n        }, {\n            token : \"text\",\n            regex : \"\\\\s+\"\n        } ]\n\n       \n    };\n};\n\noop.inherits(VHDLHighlightRules, TextHighlightRules);\n\nexports.VHDLHighlightRules = VHDLHighlightRules;\n"
  },
  {
    "path": "src/mode/visualforce.js",
    "content": "/* caption: Visualforce; extensions: component,page,vfp */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlMode = require(\"./html\").Mode;\nvar VisualforceHighlightRules = require(\"./visualforce_highlight_rules\").VisualforceHighlightRules;\nvar XmlBehaviour = require(\"./behaviour/xml\").XmlBehaviour;\nvar HtmlFoldMode = require(\"./folding/html\").FoldMode;\n\nfunction VisualforceMode() {\n    HtmlMode.call(this);\n\n    this.HighlightRules = VisualforceHighlightRules;\n    this.foldingRules = new HtmlFoldMode();\n    this.$behaviour = new XmlBehaviour();\n}\n\noop.inherits(VisualforceMode, HtmlMode);\n\nVisualforceMode.prototype.emmetConfig = {\n    profile: \"xhtml\"\n};\n\nexports.Mode = VisualforceMode;\n"
  },
  {
    "path": "src/mode/visualforce_highlight_rules.js",
    "content": "/* global define */\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar HtmlHighlightRules = require(\"../mode/html_highlight_rules\").HtmlHighlightRules;\n\nfunction string(options) {\n    return {\n        token: options.token + \".start\",\n        regex: options.start,\n        push: [{\n            token : \"constant.language.escape\",\n            regex : options.escape\n        }, {\n            token: options.token + \".end\",\n            regex: options.start,\n            next: \"pop\"\n        }, {\n            defaultToken: options.token\n        }]\n    };\n}\nvar VisualforceHighlightRules = function() {\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\":\n            \"$Action|$Api|$Component|$ComponentLabel|$CurrentPage|$FieldSet|$Label|$Label|\" +\n            \"$ObjectType|$Organization|$Page|$Permission|$Profile|$Resource|$SControl|\" +\n            \"$Setup|$Site|$System.OriginDateTime|$User|$UserRole|\" +\n            \"Site|UITheme|UIThemeDisplayed\",\n        \"keyword\":\n            \"\",\n        \"storage.type\":\n            \"\",\n        \"constant.language\":\n            \"true|false|null|TRUE|FALSE|NULL\",\n        \"support.function\":\n            \"DATE|DATEVALUE|DATETIMEVALUE|DAY|MONTH|NOW|TODAY|YEAR|BLANKVALUE|ISBLANK|\" +\n            \"NULLVALUE|PRIORVALUE|AND|CASE|IF|ISCHANGED|ISNEW|ISNUMBER|NOT|OR|ABS|\" +\n            \"CEILING|EXP|FLOOR|LN|LOG|MAX|MIN|MOD|ROUND|SQRT|BEGINS|BR|CASESAFEID|\" +\n            \"CONTAINS|FIND|GETSESSIONID|HTMLENCODE|ISPICKVAL|JSENCODE|JSINHTMLENCODE|\" +\n            \"LEFT|LEN|LOWER|LPAD|MID|RIGHT|RPAD|SUBSTITUTE|TEXT|TRIM|UPPER|URLENCODE|VALUE|\" +\n            \"GETRECORDIDS|INCLUDE|LINKTO|REGEX|REQUIRESCRIPT|URLFOR|VLOOKUP|HTMLENCODE|JSENCODE|\" +\n            \"JSINHTMLENCODE|URLENCODE\"\n    }, \"identifier\");\n\n    HtmlHighlightRules.call(this);\n    var hbs = {\n        token : \"keyword.start\",\n        regex : \"{!\",\n        push : \"Visualforce\"\n    };\n    for (var key in this.$rules) {\n        this.$rules[key].unshift(hbs);\n    }\n    this.$rules.Visualforce = [\n        string({\n            start: '\"',\n            escape: /\\\\[btnfr\"'\\\\]/,\n            token: \"string\",\n            multiline: true\n        }),\n        string({\n            start: \"'\",\n            escape: /\\\\[btnfr\"'\\\\]/,\n            token: \"string\",\n            multiline: true\n        }),\n        {\n            token: \"comment.start\",\n            regex : \"\\\\/\\\\*\",\n            push: [\n                {token : \"comment.end\", regex : \"\\\\*\\\\/|(?=})\", next : \"pop\"},\n                {defaultToken : \"comment\", caseInsensitive: true}\n            ]\n        }, {\n            token : \"keyword.end\",\n            regex : \"}\",\n            next : \"pop\"\n        }, {\n            token : keywordMapper,\n            regex : /[a-zA-Z$_\\u00a1-\\uffff][a-zA-Z\\d$_\\u00a1-\\uffff]*\\b/\n        }, {\n            token : \"keyword.operator\",\n            regex : /==|<>|!=|<=|>=|&&|\\|\\||[+\\-*/^()=<>&]/\n        }, {\n            token : \"punctuation.operator\",\n            regex : /[?:,;.]/\n        }, {\n            token : \"paren.lparen\",\n            regex : /[\\[({]/\n        }, {\n            token : \"paren.rparen\",\n            regex : /[\\])}]/\n        }\n    ];\n\n    this.normalizeRules();\n};\n\noop.inherits(VisualforceHighlightRules, HtmlHighlightRules);\n\nexports.VisualforceHighlightRules = VisualforceHighlightRules;\n"
  },
  {
    "path": "src/mode/vue.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nconst {FoldMode: HtmlFoldMode} = require(\"./folding/html\");\nconst lang = require(\"../lib/lang\");\nconst {XmlBehaviour} = require(\"./behaviour/xml\");\nconst {HtmlCompletions} = require(\"./html_completions\");\nvar HTMLMode = require(\"./html\").Mode;\nvar VueHighlightRules = require(\"./vue_highlight_rules\").VueHighlightRules;\n\nvar voidElements = [\n    \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"menuitem\", \"param\", \"source\",\n    \"track\", \"wbr\"\n];\nvar optionalEndTags = [\"li\", \"dt\", \"dd\", \"p\", \"rt\", \"rp\", \"optgroup\", \"option\", \"colgroup\", \"td\", \"th\"];\nvar Mode = function () {\n    this.HighlightRules = VueHighlightRules;\n    this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags));\n    this.$behaviour = new XmlBehaviour();\n    this.$completer = new HtmlCompletions();\n};\noop.inherits(Mode, HTMLMode);\n\n(function () {\n    this.blockComment = {\n        start: \"<!--\",\n        end: \"-->\"\n    };\n    this.voidElements = lang.arrayToMap(voidElements);\n\n    this.getCompletions = function (state, session, pos, prefix) {\n        return this.$completer.getCompletions(state, session, pos, prefix);\n    };\n\n    this.$id = \"ace/mode/vue\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/vue_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar {CssHighlightRules} = require(\"./css_highlight_rules\");\nvar {TypeScriptHighlightRules} = require(\"./typescript_highlight_rules\");\nvar {CoffeeHighlightRules} = require(\"./coffee_highlight_rules\");\nvar {HtmlHighlightRules} = require(\"./html_highlight_rules\");\nvar {JavaScriptHighlightRules} = require(\"./javascript_highlight_rules\");\nvar {StylusHighlightRules} = require(\"./stylus_highlight_rules\");\nvar {SassHighlightRules} = require(\"./sass_highlight_rules\");\nvar {ScssHighlightRules} = require(\"./scss_highlight_rules\");\nvar {LessHighlightRules} = require(\"./less_highlight_rules\");\nvar {Tokenizer} = require(\"../tokenizer\");\nvar {SlimHighlightRules} = require(\"./slim_highlight_rules\");\nvar {JadeHighlightRules} = require(\"./jade_highlight_rules\");\n\nvar JavaScriptMode = require(\"./javascript\").Mode;\n\nvar VueHighlightRules = function (options) {\n\n    /**\n     * @param {{new(): Ace.HighlightRules}|Ace.HighlightRulesMap} HighlightRules\n     * @param {string} tag\n     * @param {string} value\n     * @param {string} [attribute]\n     */\n    this.embedLangRules = function (HighlightRules, tag, value, attribute) {\n        var condition = attribute ? \"(?=[^>]*\" + attribute + \"\\\\s*=\\\\s*['\\\"]\" + value + \"['\\\"]))\" : \"(?=\\\\s|>|$))\";\n        this.$rules.start.unshift({\n            token: [\"meta.tag.punctuation.tag-open.xml\", \"meta.tag.\" + tag + \".tag-name.xml\"],\n            regex: \"(<)(\" + tag + condition,\n            next: [\n                {\n                    token: \"meta.tag.punctuation.tag-close.\" + tag + \".xml\",\n                    regex: \"/?>\",\n                    next: value + \"-start\"\n                }, {include: \"attributes\"}\n            ]\n        });\n\n        this.$rules[tag + \"-end\"] = [\n            {include: \"attributes\"}, {\n                token: \"meta.tag.punctuation.tag-close.xml\",\n                regex: \"/?>\",\n                next: \"start\",\n                onMatch: function (value, currentState, stack) {\n                    stack.splice(0);\n                    return this.token;\n                }\n            }\n        ];\n\n        this.embedRules(HighlightRules, value + \"-\", [\n            {\n                token: [\"meta.tag.punctuation.end-tag-open.xml\", \"meta.tag.\" + tag + \".tag-name.xml\"],\n                regex: \"(</)(\" + tag + \"(?=\\\\s|>|$))\",\n                next: tag + \"-end\"\n            }, {\n                token: \"string.cdata.xml\",\n                regex: \"<\\\\!\\\\[CDATA\\\\[\"\n            }, {\n                token: \"string.cdata.xml\",\n                regex: \"\\\\]\\\\]>\"\n            }\n        ]);\n    };\n\n    var vueRules = [\n        {\n            include: \"vue-interpolations\"\n        }\n    ];\n\n    var VueRules = new HtmlHighlightRules().getRules();\n    VueRules.start = vueRules.concat(VueRules.start);\n    VueRules[\"vue-interpolations\"] = [\n        {\n            token: \"punctuation\",\n            regex: /\\{\\{\\{?/,\n            next: \"js-interpolation-start\"\n        }\n    ];\n\n    var self = this;\n    VueRules.tag_stuff.unshift({//vue-directives \n        token: \"string\",\n        regex: /(?:\\b(v-)|(:|@))(\\[?[a-zA-Z\\-.]+\\]?)(?:(\\:\\[?[a-zA-Z\\-]+\\]?))?((?:\\.[a-zA-Z\\-]+)*)(\\s*)(=)(\\s*)([\"'])/,\n        onMatch: function (value, currentState, stack) {\n            var quote = value[value.length - 1];\n            stack.unshift(quote, currentState);\n\n            var values = new RegExp(this.regex).exec(value);\n            if (!values) return \"text\";\n            var tokens = [];\n            var types = [\n                \"entity.other.attribute-name.xml\", \"punctuation.separator.key-value.xml\",\n                \"entity.other.attribute-name.xml\", \"entity.other.attribute-name.xml\", \"entity.other.attribute-name.xml\",\n                \"text\", \"punctuation.separator.key-value.xml\", \"text\", \"string\"\n            ];\n            for (var i = 0, l = types.length; i < l; i++) {\n                if (values[i + 1]) tokens[tokens.length] = {\n                    type: types[i],\n                    value: values[i + 1]\n                };\n            }\n            return tokens;\n        },\n        next: [\n            {\n                token: \"string\",\n                regex: /$/,\n                next: \"tag_stuff\"\n            }, {\n                token: \"string\",\n                regex: /.*/,\n                onMatch: function (value, currentState, stack, line) {\n                    var quote = stack[0];\n                    var parts = value.split(quote);\n                    let text = parts[0];\n                    this.next = \"\";\n                    if (parts.length > 1) {\n                        stack.shift();\n                        var nextState = stack.shift();\n                        var currentData = new Tokenizer(self.$rules).getLineTokens(\n                            parts.slice(1).join(quote), nextState);\n                        currentData.tokens.unshift({\n                            type: \"string\",\n                            value: quote\n                        });\n                        this.next = Array.isArray(currentData.state) ? currentData.state[currentData.state.length - 1]\n                            : currentData.state;\n                    }\n                    var data = new JavaScriptMode().getTokenizer().getLineTokens(text, \"start\");\n                    var tokens = data.tokens;\n                    if (currentData) {\n                        tokens.push(...currentData.tokens);\n                    }\n                    return tokens;\n                }\n            }\n        ]\n    }, {\n        token: \"string\",\n        regex: '\"',\n        next: [\n            {\n                token: \"string\",\n                regex: '\"|$',\n                next: \"tag_stuff\"\n            }, {\n                include: \"vue-interpolations\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ]\n    }, {\n        token: \"string\",\n        regex: \"'\",\n        next: [\n            {\n                token: \"string\",\n                regex: \"'|$\",\n                next: \"tag_stuff\"\n            }, {\n                include: \"vue-interpolations\"\n            }, {\n                defaultToken: \"string\"\n            }\n        ]\n    });\n    this.$rules = VueRules;\n\n    this.embedRules(JavaScriptHighlightRules, \"js-interpolation-\", [\n        {\n            token: \"punctuation\",\n            regex: /\\}\\}\\}?/,\n            next: \"start\"\n        }\n    ]);\n\n    this.embedLangRules(CssHighlightRules, \"style\", \"css\");\n    this.embedLangRules(StylusHighlightRules, \"style\", \"stylus\", \"lang\");\n    //TODO: postcss is missing: this.embedLangRules(StylusHighlightRules, \"style\", \"lang\", \"postcss\");\n    this.embedLangRules(SassHighlightRules, \"style\", \"sass\", \"lang\");\n    this.embedLangRules(ScssHighlightRules, \"style\", \"scss\", \"lang\");\n    this.embedLangRules(LessHighlightRules, \"style\", \"less\", \"lang\");\n    this.embedLangRules(TypeScriptHighlightRules, \"script\", \"ts\", \"lang\");\n    this.embedLangRules(CoffeeHighlightRules, \"script\", \"coffee\", \"lang\");\n    //TODO: this.embedLangRules(CoffeeHighlightRules, \"script\", \"livescript\", \"lang\");\n    this.embedLangRules(SlimHighlightRules, \"template\", \"slm\", \"lang\");\n    this.embedLangRules(JadeHighlightRules, \"template\", \"jade\", \"lang\");\n    //TODO: this.embedLangRules(Pug, \"template\", \"pug\", \"lang\");\n    this.embedLangRules(StylusHighlightRules, \"template\", \"stylus\", \"lang\");\n    \n    this.normalizeRules();\n};\n\noop.inherits(VueHighlightRules, HtmlHighlightRules);\n\nexports.VueHighlightRules = VueHighlightRules;\n"
  },
  {
    "path": "src/mode/wollok.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar JavaScriptMode = require(\"./javascript\").Mode;\nvar WollokHighlightRules = require(\"./wollok_highlight_rules\").WollokHighlightRules;\n\nvar Mode = function() {\n    JavaScriptMode.call(this);\n    this.HighlightRules = WollokHighlightRules;\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, JavaScriptMode);\n\n(function() {\n    \n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.$id = \"ace/mode/wollok\";\n    this.snippetFileId = \"ace/snippets/wollok\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/wollok_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar DocCommentHighlightRules = require(\"./doc_comment_highlight_rules\").DocCommentHighlightRules;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar WollokHighlightRules = function() {\n\n    // taken from http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html\n    var keywords = (\n    \"test|describe|package|inherits|false|import|else|or|class|and|not|native|override|program|self|try|const|var|catch|object|super|throw|if|null|return|true|new|constructor|method|mixin\"\n    );\n\n    var buildinConstants = (\"null|assert|console\");\n\n    var langClasses = (\n        \"Object|Pair|String|Boolean|Number|Integer|Double|Collection|Set|List|Exception|Range\" +\n        \"|StackTraceElement\"\n    );\n\n    var keywordMapper = this.createKeywordMapper({\n        \"variable.language\": \"self\",\n        \"keyword\": keywords,\n        \"constant.language\": buildinConstants,\n        \"support.function\": langClasses\n    }, \"identifier\");\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"\\\\/\\\\/.*$\"\n            },\n            DocCommentHighlightRules.getStartRule(\"doc-start\"),\n            {\n                token : \"comment\", // multi line comment\n                regex : \"\\\\/\\\\*\",\n                next : \"comment\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // single line\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"constant.numeric\", // hex\n                regex : /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\\b/\n            }, {\n                token : \"constant.numeric\", // float\n                regex : /[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?[LlSsDdFfYy]?\\b/\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"(?:true|false)\\\\b\"\n            }, {\n                token : keywordMapper,\n                // TODO: Unicode escape sequences\n                // TODO: Unicode identifiers\n                regex : \"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"===|&&|\\\\*=|\\\\.\\\\.|\\\\*\\\\*|#|!|%|\\\\*|\\\\?:|\\\\+|\\\\/|,|\\\\+=|\\\\-|\\\\.\\\\.<|!==|:|\\\\/=|\\\\?\\\\.|\\\\+\\\\+|>|=|<|>=|=>|==|\\\\]|\\\\[|\\\\-=|\\\\->|\\\\||\\\\-\\\\-|<>|!=|%=|\\\\|\"\n            }, {\n                token : \"lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : \"\\\\s+\"\n            }\n        ],\n        \"comment\" : [\n            {\n                token : \"comment\", // closing comment\n                regex : \".*?\\\\*\\\\/\",\n                next : \"start\"\n            }, {\n                token : \"comment\", // comment spanning whole line\n                regex : \".+\"\n            }\n        ]\n    };\n\n    this.embedRules(DocCommentHighlightRules, \"doc-\",\n        [ DocCommentHighlightRules.getEndRule(\"start\") ]);\n};\n\noop.inherits(WollokHighlightRules, TextHighlightRules);\n\nexports.WollokHighlightRules = WollokHighlightRules;\n"
  },
  {
    "path": "src/mode/xml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar TextMode = require(\"./text\").Mode;\nvar XmlHighlightRules = require(\"./xml_highlight_rules\").XmlHighlightRules;\nvar XmlBehaviour = require(\"./behaviour/xml\").XmlBehaviour;\nvar XmlFoldMode = require(\"./folding/xml\").FoldMode;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\n\nvar Mode = function() {\n   this.HighlightRules = XmlHighlightRules;\n   this.$behaviour = new XmlBehaviour();\n   this.foldingRules = new XmlFoldMode();\n};\n\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.voidElements = lang.arrayToMap([]);\n\n    this.blockComment = {start: \"<!--\", end: \"-->\"};\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/xml_worker\", \"Worker\");\n        worker.attachToDocument(session.getDocument());\n\n        worker.on(\"error\", function(e) {\n            session.setAnnotations(e.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n    \n    this.$id = \"ace/mode/xml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/xml_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar XmlHighlightRules = function(normalize) {\n    // http://www.w3.org/TR/REC-xml/#NT-NameChar\n    // NameStartChar\t   ::=   \t\":\" | [A-Z] | \"_\" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]\n    // NameChar\t   ::=   \tNameStartChar | \"-\" | \".\" | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n    var tagRegex = \"[_:a-zA-Z\\xc0-\\uffff][-_:.a-zA-Z0-9\\xc0-\\uffff]*\";\n\n    this.$rules = {\n        start : [\n            {token : \"string.cdata.xml\", regex : \"<\\\\!\\\\[CDATA\\\\[\", next : \"cdata\"},\n            {\n                token : [\"punctuation.instruction.xml\", \"keyword.instruction.xml\"],\n                regex : \"(<\\\\?)(\" + tagRegex + \")\", next : \"processing_instruction\"\n            },\n            {token : \"comment.start.xml\", regex : \"<\\\\!--\", next : \"comment\"},\n            {\n                token : [\"xml-pe.doctype.xml\", \"xml-pe.doctype.xml\"],\n                regex : \"(<\\\\!)(DOCTYPE)(?=[\\\\s])\", next : \"doctype\", caseInsensitive: true\n            },\n            {include : \"tag\"},\n            {token : \"text.end-tag-open.xml\", regex: \"</\"},\n            {token : \"text.tag-open.xml\", regex: \"<\"},\n            {include : \"reference\"},\n            {defaultToken : \"text.xml\"}\n        ],\n\n        processing_instruction : [{\n            token : \"entity.other.attribute-name.decl-attribute-name.xml\",\n            regex : tagRegex\n        }, {\n            token : \"keyword.operator.decl-attribute-equals.xml\",\n            regex : \"=\"\n        }, {\n            include: \"whitespace\"\n        }, {\n            include: \"string\"\n        }, {\n            token : \"punctuation.xml-decl.xml\",\n            regex : \"\\\\?>\",\n            next : \"start\"\n        }],\n\n        doctype : [\n            {include : \"whitespace\"},\n            {include : \"string\"},\n            {token : \"xml-pe.doctype.xml\", regex : \">\", next : \"start\"},\n            {token : \"xml-pe.xml\", regex : \"[-_a-zA-Z0-9:]+\"},\n            {token : \"punctuation.int-subset\", regex : \"\\\\[\", push : \"int_subset\"}\n        ],\n\n        int_subset : [{\n            token : \"text.xml\",\n            regex : \"\\\\s+\"\n        }, {\n            token: \"punctuation.int-subset.xml\",\n            regex: \"]\",\n            next: \"pop\"\n        }, {\n            token : [\"punctuation.markup-decl.xml\", \"keyword.markup-decl.xml\"],\n            regex : \"(<\\\\!)(\" + tagRegex + \")\",\n            push : [{\n                token : \"text\",\n                regex : \"\\\\s+\"\n            },\n            {\n                token : \"punctuation.markup-decl.xml\",\n                regex : \">\",\n                next : \"pop\"\n            },\n            {include : \"string\"}]\n        }],\n\n        cdata : [\n            {token : \"string.cdata.xml\", regex : \"\\\\]\\\\]>\", next : \"start\"},\n            {token : \"text.xml\", regex : \"\\\\s+\"},\n            {token : \"text.xml\", regex : \"(?:[^\\\\]]|\\\\](?!\\\\]>))+\"}\n        ],\n\n        comment : [\n            {token : \"comment.end.xml\", regex : \"-->\", next : \"start\"},\n            {defaultToken : \"comment.xml\"}\n        ],\n\n        reference : [{\n            token : \"constant.language.escape.reference.xml\",\n            regex : \"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"\n        }],\n\n        attr_reference : [{\n            token : \"constant.language.escape.reference.attribute-value.xml\",\n            regex : \"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"\n        }],\n\n        tag : [{\n            token : [\"meta.tag.punctuation.tag-open.xml\", \"meta.tag.punctuation.end-tag-open.xml\", \"meta.tag.tag-name.xml\"],\n            regex : \"(?:(<)|(</))((?:\" + tagRegex + \":)?\" + tagRegex + \")\",\n            next: [\n                {include : \"attributes\"},\n                {token : \"meta.tag.punctuation.tag-close.xml\", regex : \"/?>\", next : \"start\"}\n            ]\n        }],\n\n        tag_whitespace : [\n            {token : \"text.tag-whitespace.xml\", regex : \"\\\\s+\"}\n        ],\n        // for doctype and processing instructions\n        whitespace : [\n            {token : \"text.whitespace.xml\", regex : \"\\\\s+\"}\n        ],\n\n        // for doctype and processing instructions\n        string: [{\n            token : \"string.xml\",\n            regex : \"'\",\n            push : [\n                {token : \"string.xml\", regex: \"'\", next: \"pop\"},\n                {defaultToken : \"string.xml\"}\n            ]\n        }, {\n            token : \"string.xml\",\n            regex : '\"',\n            push : [\n                {token : \"string.xml\", regex: '\"', next: \"pop\"},\n                {defaultToken : \"string.xml\"}\n            ]\n        }],\n\n        attributes: [{\n            token : \"entity.other.attribute-name.xml\",\n            regex : tagRegex\n        }, {\n            token : \"keyword.operator.attribute-equals.xml\",\n            regex : \"=\"\n        }, {\n            include: \"tag_whitespace\"\n        }, {\n            include: \"attribute_value\"\n        }],\n\n        attribute_value: [{\n            token : \"string.attribute-value.xml\",\n            regex : \"'\",\n            push : [\n                {token : \"string.attribute-value.xml\", regex: \"'\", next: \"pop\"},\n                {include : \"attr_reference\"},\n                {defaultToken : \"string.attribute-value.xml\"}\n            ]\n        }, {\n            token : \"string.attribute-value.xml\",\n            regex : '\"',\n            push : [\n                {token : \"string.attribute-value.xml\", regex: '\"', next: \"pop\"},\n                {include : \"attr_reference\"},\n                {defaultToken : \"string.attribute-value.xml\"}\n            ]\n        }]\n    };\n\n    if (this.constructor === XmlHighlightRules)\n        this.normalizeRules();\n};\n\n\n(function() {\n\n    this.embedTagRules = function(HighlightRules, prefix, tag){\n        this.$rules.tag.unshift({\n            token : [\"meta.tag.punctuation.tag-open.xml\", \"meta.tag.\" + tag + \".tag-name.xml\"],\n            regex : \"(<)(\" + tag + \"(?=\\\\s|>|$))\",\n            next: [\n                {include : \"attributes\"},\n                {token : \"meta.tag.punctuation.tag-close.xml\", regex : \"/?>\", next : prefix + \"start\"}\n            ]\n        });\n\n        this.$rules[tag + \"-end\"] = [\n            {include : \"attributes\"},\n            {token : \"meta.tag.punctuation.tag-close.xml\", regex : \"/?>\",  next: \"start\",\n                onMatch : function(value, currentState, stack) {\n                    stack.splice(0);\n                    return this.token;\n            }}\n        ];\n\n        this.embedRules(HighlightRules, prefix, [{\n            token: [\"meta.tag.punctuation.end-tag-open.xml\", \"meta.tag.\" + tag + \".tag-name.xml\"],\n            regex : \"(</)(\" + tag + \"(?=\\\\s|>|$))\",\n            next: tag + \"-end\"\n        }, {\n            token: \"string.cdata.xml\",\n            regex : \"<\\\\!\\\\[CDATA\\\\[\"\n        }, {\n            token: \"string.cdata.xml\",\n            regex : \"\\\\]\\\\]>\"\n        }]);\n    };\n\n}).call(TextHighlightRules.prototype);\n\noop.inherits(XmlHighlightRules, TextHighlightRules);\n\nexports.XmlHighlightRules = XmlHighlightRules;\n"
  },
  {
    "path": "src/mode/xml_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar XmlMode = require(\"./xml\").Mode;\nvar assert = require(\"../test/assertions\");\n\nmodule.exports = {\n    setUp : function() {\n        this.mode = new XmlMode();\n    },\n\n    \"test: getTokenizer() (smoke test)\" : function() {\n        var tokenizer = this.mode.getTokenizer();\n\n        assert.ok(tokenizer instanceof Tokenizer);\n\n        var tokens = tokenizer.getLineTokens(\"<juhu>\", \"start\").tokens;\n        assert.equal(\"meta.tag.punctuation.tag-open.xml\", tokens[0].type);\n    },\n\n    \"test: toggle comment lines should not do anything\" : function() {\n        var session = new EditSession([\"    abc\", \"  cde\", \"fg\"]);\n\n        this.mode.toggleCommentLines(\"start\", session, 0, 1);\n        assert.equal([\"  <!--  abc-->\", \"  <!--cde-->\", \"fg\"].join(\"\\n\"), session.toString());\n    },\n\n    \"test: next line indent should be the same as the current line indent\" : function() {\n        assert.equal(\"     \", this.mode.getNextLineIndent(\"start\", \"     abc\"));\n        assert.equal(\"\", this.mode.getNextLineIndent(\"start\", \"abc\"));\n        assert.equal(\"\\t\", this.mode.getNextLineIndent(\"start\", \"\\tabc\"));\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mode/yaml.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar YamlHighlightRules = require(\"./yaml_highlight_rules\").YamlHighlightRules;\nvar MatchingBraceOutdent = require(\"./matching_brace_outdent\").MatchingBraceOutdent;\nvar FoldMode = require(\"./folding/yaml\").FoldMode;\nvar WorkerClient = require(\"../worker/worker_client\").WorkerClient;\n\nvar Mode = function() {\n    this.HighlightRules = YamlHighlightRules;\n    this.$outdent = new MatchingBraceOutdent();\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n\n    this.lineCommentStart = [\"#\"];\n    \n    this.getNextLineIndent = function(state, line, tab) {\n        var indent = this.$getIndent(line);\n\n        if (state == \"start\") {\n            var match = line.match(/^.*[\\{\\(\\[]\\s*$/);\n            if (match) {\n                indent += tab;\n            }\n        }\n\n        return indent;\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return this.$outdent.checkOutdent(line, input);\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n        this.$outdent.autoOutdent(doc, row);\n    };\n\n    this.createWorker = function(session) {\n        var worker = new WorkerClient([\"ace\"], \"ace/mode/yaml_worker\", \"YamlWorker\");\n        worker.attachToDocument(session.getDocument());\n\n        worker.on(\"annotate\", function(results) {\n            session.setAnnotations(results.data);\n        });\n\n        worker.on(\"terminate\", function() {\n            session.clearAnnotations();\n        });\n\n        return worker;\n    };\n\n\n    this.$id = \"ace/mode/yaml\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/yaml_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar YamlHighlightRules = function() {\n\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n    this.$rules = {\n        \"start\" : [\n            {\n                token : \"comment\",\n                regex : \"#.*$\"\n            }, {\n                token : \"list.markup\",\n                regex : /^(?:-{3}|\\.{3})\\s*(?=#|$)/\n            },  {\n                token : \"list.markup\",\n                regex : /^\\s*[\\-?](?:$|\\s)/\n            }, {\n                token: \"constant\",\n                regex: \"!![\\\\w//]+\"\n            }, {\n                token: \"constant.language\",\n                regex: \"[&\\\\*][a-zA-Z0-9-_]+\"\n            }, {\n                token: [\"meta.tag\", \"keyword\"],\n                regex: /^(\\s*\\w[^\\s:]*?)(:(?=\\s|$))/\n            },{\n                token: [\"meta.tag\", \"keyword\"],\n                regex: /(\\w[^\\s:]*?)(\\s*:(?=\\s|$))/\n            }, {\n                token : \"keyword.operator\",\n                regex : \"<<\\\\w*:\\\\w*\"\n            }, {\n                token : \"keyword.operator\",\n                regex : \"-\\\\s*(?=[{])\"\n            }, {\n                token : \"string\", // single line\n                regex : '[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'\n            }, {\n                token : \"string\", // multi line string start\n                regex : /[|>][-+\\d]*(?:$|\\s+(?:$|#))/,\n                onMatch: function(val, state, stack, line) {\n                    line = line.replace(/ #.*/, \"\");\n                    var indent = /^ *((:\\s*)?-(\\s*[^|>])?)?/.exec(line)[0]\n                        .replace(/\\S\\s*$/, \"\").length;\n                    var indentationIndicator = parseInt(/\\d+[\\s+-]*$/.exec(line));\n                    \n                    if (indentationIndicator) {\n                        indent += indentationIndicator - 1;\n                        this.next = \"mlString\";\n                    } else {\n                        this.next = \"mlStringPre\";\n                    }\n                    if (!stack.length) {\n                        stack.push(this.next);\n                        stack.push(indent);\n                    } else {\n                        stack[0] = this.next;\n                        stack[1] = indent;\n                    }\n                    return this.token;\n                },\n                next : \"mlString\"\n            }, {\n                token : \"string\", // single quoted string\n                regex : \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"\n            }, {\n                token : \"constant.numeric\", // float\n                regex : /(\\b|[+\\-\\.])[\\d_]+(?:(?:\\.[\\d_]*)?(?:[eE][+\\-]?[\\d_]+)?)(?=[^\\d-\\w]|$)$/\n            }, {\n                token : \"constant.numeric\", // other number\n                regex : /[+\\-]?\\.inf\\b|NaN\\b|0x[\\dA-Fa-f_]+|0b[10_]+/\n            }, {\n                token : \"constant.language.boolean\",\n                regex : \"\\\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\\\b\"\n            }, {\n                token : \"paren.lparen\",\n                regex : \"[[({]\"\n            }, {\n                token : \"paren.rparen\",\n                regex : \"[\\\\])}]\"\n            }, {\n                token : \"text\",\n                regex : /[^\\s,:\\[\\]\\{\\}]+/\n            }\n        ],\n        \"mlStringPre\" : [\n            {\n                token : \"indent\",\n                regex : /^ *$/\n            }, {\n                token : \"indent\",\n                regex : /^ */,\n                onMatch: function(val, state, stack) {\n                    var curIndent = stack[1];\n\n                    if (curIndent >= val.length) {\n                        this.next = \"start\";\n                        stack.shift();\n                        stack.shift();\n                    }\n                    else {\n                        stack[1] = val.length - 1;\n                        this.next = stack[0] = \"mlString\";\n                    }\n                    return this.token;\n                },\n                next : \"mlString\"\n            }, {\n                defaultToken : \"string\"\n            }\n        ],\n        \"mlString\" : [\n            {\n                token : \"indent\",\n                regex : /^ *$/\n            }, {\n                token : \"indent\",\n                regex : /^ */,\n                onMatch: function(val, state, stack) {\n                    var curIndent = stack[1];\n\n                    if (curIndent >= val.length) {\n                        this.next = \"start\";\n                        stack.splice(0);\n                    }\n                    else {\n                        this.next = \"mlString\";\n                    }\n                    return this.token;\n                },\n                next : \"mlString\"\n            }, {\n                token : \"string\",\n                regex : '.+'\n            }\n        ]};\n    this.normalizeRules();\n\n};\n\noop.inherits(YamlHighlightRules, TextHighlightRules);\n\nexports.YamlHighlightRules = YamlHighlightRules;\n"
  },
  {
    "path": "src/mode/zeek.js",
    "content": "/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ZeekHighlightRules = require(\"./zeek_highlight_rules\").ZeekHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ZeekHighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"#\";\n    // Extra logic goes here.\n    this.$id = \"ace/mode/zeek\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/zeek_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ZeekHighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = {\n        \"start\": [\n            {\n            token: \"comment.line\",\n            regex: \"#.*$\"\n            },\n            {\n            token: \"string.double\",\n            regex: /\"/,\n            next: \"string-state\"\n            },\n            {\n            token: \"string.regexp\",\n            regex: \"(/)(?=.*/)\",\n            next: \"pattern-state\"\n            },\n            {\n            token: [\"keyword.other\", \"meta.preprocessor\"],\n            regex: /(@(?:load-plugin|load-sigs|load|unload))(.*$)/\n            },\n            {\n            token: \"keyword.other\",\n            regex: /@(?:DEBUG|DIR|FILENAME|deprecated|if|ifdef|ifndef|else|endif)/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.preprocessor\",\n                \"keyword.operator\",\n                \"meta.preprocessor\"\n            ],\n            regex: /(@prefixes)(\\s*)(\\+?=)(.*$)/\n            },\n            {\n            token: \"storage.modifier.attribute\",\n            regex: /\\&\\b(?:redef|priority|log|optional|default|add_func|delete_func|expire_func|read_expire|write_expire|create_expire|synchronized|persistent|rotate_interval|rotate_size|encrypt|raw_output|mergeable|error_handler|type_column|deprecated)\\b/\n            },\n            {\n            token: \"constant.language\",\n            regex: /\\b(?:T|F)\\b/\n            },\n            {\n            token: \"constant.numeric.port\",\n            regex: /\\b\\d{1,5}\\/(?:udp|tcp|icmp|unknown)\\b/\n            },\n            {\n            token: \"constant.numeric.addr\",\n            regex: /\\b(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\b/,\n            comment: \"IPv4 address\"\n            },\n            {\n            token: \"constant.numeric.addr\",\n            regex: /\\[(?:[0-9a-fA-F]{0,4}:){2,7}(?:[0-9a-fA-F]{0,4})?(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2}))?\\]/,\n            comment: \"IPv6 address\"\n            },\n            {\n            token: \"constant.numeric.float.decimal.interval\",\n            regex: /(?:(?:\\d*\\.\\d*(?:[eE][+-]?\\d+)?|\\d*[eE][+-]?\\d+|\\d*\\.\\d*)|\\d+)\\s*(?:day|hr|min|msec|usec|sec)s?/\n            },\n            {\n            token: \"constant.numeric.float.decimal\",\n            regex: /\\d*\\.\\d*(?:[eE][+-]?\\d+)?|\\d*[eE][+-]?\\d+|\\d*\\.\\d*/\n            },\n            {\n            token: \"constant.numeric.hostname\",\n            regex: /\\b[A-Za-z0-9][A-Za-z0-9\\-]*(?:\\.[A-Za-z0-9][A-Za-z0-9\\-]*)+\\b/\n            },\n            {\n            token: \"constant.numeric.integer.hexadecimal\",\n            regex: /\\b0x[0-9a-fA-F]+\\b/\n            },\n            {\n            token: \"constant.numeric.integer.decimal\",\n            regex: /\\b\\d+\\b/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /==|!=|<=|<|>=|>/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /(&&)|(\\|\\|)|(!)/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /=|\\+=|-=/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /\\+\\+|\\+|--|-|\\*|\\/|%/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /&|\\||\\^|~/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /\\b(?:in|as|is)\\b/\n            },\n            {\n            token: \"punctuation.terminator\",\n            regex: /;/\n            },\n            {\n            token: \"punctuation.accessor\",\n            regex: /\\??\\$/\n            },\n            {\n            token: \"punctuation.accessor\",\n            regex: /::/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /\\?/\n            },\n            // Unsure how to tell if colon is used as operator vs. separator.\n            // {\n            // token: \"keyword.operator\",\n            // regex: /:/\n            // },\n            {\n            token: \"punctuation.separator\",\n            regex: /:/\n            },\n            {\n            token: \"punctuation.separator\",\n            regex: /,/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.namespace\",\n                \"entity.name.namespace\"\n            ],\n            regex: /(module)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)/\n            },\n            {\n            token: \"keyword.other\",\n            regex: /\\bexport\\b/\n            },\n            {\n            token: \"keyword.control.conditional\",\n            regex: /\\b(?:if|else)\\b/\n            },\n            {\n            token: \"keyword.control\",\n            regex: /\\b(?:for|while)\\b/\n            },\n            {\n            token: \"keyword.control\",\n            regex: /\\b(?:return|break|next|continue|fallthrough)\\b/\n            },\n            {\n            token: \"keyword.control\",\n            regex: /\\b(?:switch|default|case)\\b/\n            },\n            {\n            token: \"keyword.other\",\n            regex: /\\b(?:add|delete)\\b/\n            },\n            {\n            token: \"keyword.other\",\n            regex: /\\bprint\\b/\n            },\n            {\n            token: \"keyword.control\",\n            regex: /\\b(?:when|timeout|schedule)\\b/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.struct.record\",\n                \"entity.name.struct.record\",\n                \"meta.struct.record\",\n                \"punctuation.separator\",\n                \"meta.struct.record\",\n                \"storage.type.struct.record\"\n            ],\n            regex: /\\b(type)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\\s*)(:)(\\s*\\b)(record)\\b/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.enum\",\n                \"entity.name.enum\",\n                \"meta.enum\",\n                \"punctuation.separator\",\n                \"meta.enum\",\n                \"storage.type.enum\"\n            ],\n            regex: /\\b(type)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\\s*)(:)(\\s*\\b)(enum)\\b/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.type\",\n                \"entity.name.type\",\n                \"meta.type\",\n                \"punctuation.separator\"\n            ],\n            regex: /\\b(type)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\\s*)(:)/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.struct.record\",\n                \"storage.type.struct.record\",\n                \"meta.struct.record\",\n                \"entity.name.struct.record\"\n            ],\n            regex: /\\b(redef)(\\s+)(record)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\\b/\n            },\n            {\n            token: [\n                \"keyword.other\",\n                \"meta.enum\",\n                \"storage.type.enum\",\n                \"meta.enum\",\n                \"entity.name.enum\"\n            ],\n            regex: /\\b(redef)(\\s+)(enum)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\\b/\n            },\n            {\n            token: [\n                \"storage.type\",\n                \"text\",\n                \"entity.name.function.event\"\n            ],\n            regex: /\\b(event)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\\()/\n            },\n            {\n            token: [\n                \"storage.type\",\n                \"text\",\n                \"entity.name.function.hook\"\n            ],\n            regex: /\\b(hook)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\\()/\n            },\n            {\n            token: [\n                \"storage.type\",\n                \"text\",\n                \"entity.name.function\"\n            ],\n            regex: /\\b(function)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\\()/\n            },\n            {\n            token: \"keyword.other\",\n            regex: /\\bredef\\b/\n            },\n            {\n            token: \"storage.type\",\n            regex: /\\bany\\b/\n            },\n            {\n            token: \"storage.type\",\n            regex: /\\b(?:enum|record|set|table|vector)\\b/\n            },\n            {\n            token: [\n                \"storage.type\",\n                \"text\",\n                \"keyword.operator\",\n                \"text\",\n                \"storage.type\"\n            ],\n            regex: /\\b(opaque)(\\s+)(of)(\\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\\b/\n            },\n            {\n            token: \"keyword.operator\",\n            regex: /\\bof\\b/\n            },\n            {\n            token: \"storage.type\",\n            regex: /\\b(?:addr|bool|count|double|file|int|interval|pattern|port|string|subnet|time)\\b/\n            },\n            {\n            token: \"storage.type\",\n            regex: /\\b(?:function|hook|event)\\b/\n            },\n            {\n            token: \"storage.modifier\",\n            regex: /\\b(?:global|local|const|option)\\b/\n            },\n            {\n            token: \"entity.name.function.call\",\n            regex: /\\b[A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*(?=s*\\()/\n            },\n            {\n            token: \"punctuation.section.block.begin\",\n            regex: /\\{/\n            },\n            {\n            token: \"punctuation.section.block.end\",\n            regex: /\\}/\n            },\n            {\n            token: \"punctuation.section.brackets.begin\",\n            regex: /\\[/\n            },\n            {\n            token: \"punctuation.section.brackets.end\",\n            regex: /\\]/\n            },\n            {\n            token: \"punctuation.section.parens.begin\",\n            regex: /\\(/\n            },\n            {\n            token: \"punctuation.section.parens.end\",\n            regex: /\\)/\n            }\n\n        ], // state: start\n\n        \"string-state\": [\n            {\n            token: \"constant.character.escape\",\n            regex: /\\\\./\n            },\n            {\n            token: \"string.double\",\n            regex: /\"/,\n            next: \"start\"\n            },\n            {\n            token: \"constant.other.placeholder\",\n            regex: /%-?[0-9]*(\\.[0-9]+)?[DTdxsefg]/\n            },\n            {\n            token: \"string.double\",\n            regex: \".\"\n            }\n        ], // state: string-state\n\n        \"pattern-state\": [\n            {\n            token: \"constant.character.escape\",\n            regex: /\\\\./\n            },\n            {\n            token: \"string.regexp\",\n            regex: \"/\",\n            next: \"start\"\n            },\n            {\n            token: \"string.regexp\",\n            regex: \".\"\n            }\n        ] // state: pattern-state\n\n    };\n\n    this.normalizeRules();\n};\n\nZeekHighlightRules.metaData = {\n    fileTypes: [\"bro\", \"zeek\"],\n    name: \"Zeek\",\n    scopeName: \"source.zeek\"\n};\n\n\noop.inherits(ZeekHighlightRules, TextHighlightRules);\n\nexports.ZeekHighlightRules = ZeekHighlightRules;\n"
  },
  {
    "path": "src/mode/zig.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar ZigHighlightRules = require(\"./zig_highlight_rules\").ZigHighlightRules;\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = ZigHighlightRules;\n    this.foldingRules = new FoldMode();\n    this.$behaviour = this.$defaultBehaviour;\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    this.lineCommentStart = \"//\";\n    this.$id = \"ace/mode/zig\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n"
  },
  {
    "path": "src/mode/zig_highlight_rules.js",
    "content": "\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar ZigHighlightRules = function() {\n    this.$rules = {\n        start: [{\n            include: \"#dummy_main\"\n        }],\n        \"#block\": [{\n            token: [\n                \"storage.type.zig\",\n                \"text\",\n                \"punctuation.section.braces.begin.zig\"\n            ],\n            regex: /((?:[a-zA-Z_][\\w.]*|@\\\".+\\\")?)(\\s*)(\\{)/,\n            push: [{\n                token: \"punctuation.section.braces.end.zig\",\n                regex: /\\}/,\n                next: \"pop\"\n            }, {\n                include: \"#dummy_main\"\n            }]\n        }],\n        \"#character_escapes\": [{\n            token: \"constant.character.escape.newline.zig\",\n            regex: /\\\\n/\n        }, {\n            token: \"constant.character.escape.carrigereturn.zig\",\n            regex: /\\\\r/\n        }, {\n            token: \"constant.character.escape.tabulator.zig\",\n            regex: /\\\\t/\n        }, {\n            token: \"constant.character.escape.backslash.zig\",\n            regex: /\\\\\\\\/\n        }, {\n            token: \"constant.character.escape.single-quote.zig\",\n            regex: /\\\\'/\n        }, {\n            token: \"constant.character.escape.double-quote.zig\",\n            regex: /\\\\\\\"/\n        }, {\n            token: \"constant.character.escape.hexidecimal.zig\",\n            regex: /\\\\x[a-fA-F\\d]{2}/\n        }, {\n            token: \"constant.character.escape.hexidecimal.zig\",\n            regex: /\\\\u\\{[a-fA-F\\d]{1,6}\\}/\n        }],\n        \"#comments\": [{\n            token: \"comment.line.documentation.zig\",\n            regex: /\\/\\/[!\\/](?=[^\\/])/,\n            push: [{\n                token: \"comment.line.documentation.zig\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                include: \"#commentContents\"\n            }, {\n                defaultToken: \"comment.line.documentation.zig\"\n            }]\n        }, {\n            token: \"comment.line.double-slash.zig\",\n            regex: /\\/\\//,\n            push: [{\n                token: \"comment.line.double-slash.zig\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                include: \"#commentContents\"\n            }, {\n                defaultToken: \"comment.line.double-slash.zig\"\n            }]\n        }],\n        \"#commentContents\": [{\n            token: \"keyword.todo.zig\",\n            regex: /\\b(?:TODO|FIXME|XXX|NOTE)\\b:?/\n        }],\n        \"#constants\": [{\n            token: \"constant.language.zig\",\n            regex: /\\b(?:null|undefined|true|false)\\b/\n        }, {\n            token: \"constant.numeric.integer.zig\",\n            regex: /\\b(?!\\.)-?[\\d_]+(?!\\.)\\b/\n        }, {\n            token: \"constant.numeric.integer.hexadecimal.zig\",\n            regex: /\\b(?!\\.)0x[a-fA-F\\d_]+(?!\\.)\\b/\n        }, {\n            token: \"constant.numeric.integer.octal.zig\",\n            regex: /\\b(?!\\.)0o[0-7_]+(?!\\.)\\b/\n        }, {\n            token: \"constant.numeric.integer.binary.zig\",\n            regex: /\\b(?!\\.)0b[01_]+(?!\\.)\\b/\n        }, {\n            token: \"constant.numeric.float.zig\",\n            regex: /(?!\\.)-?\\b[\\d_]+(?:\\.[\\d_]+)?(?:[eE][+-]?[\\d_]+)?(?!\\.)\\b/\n        }, {\n            token: \"constant.numeric.float.hexadecimal.zig\",\n            regex: /(?!\\.)-?\\b0x[a-fA-F\\d_]+(?:\\.[a-fA-F\\d_]+)?[pP]?(?:[+-]?[\\d_]+)?(?!\\.)\\b/\n        }],\n        \"#container_decl\": [{\n            token: \"entity.name.union.zig\",\n            regex: /\\b(?!\\d)(?:[a-zA-Z_]\\w*|@\\\".+\\\")?(?=\\s*=\\s*(?:extern|packed)?\\b\\s*union\\s*[(\\{])/\n        }, {\n            token: \"entity.name.struct.zig\",\n            regex: /\\b(?!\\d)(?:[a-zA-Z_]\\w*|@\\\".+\\\")?(?=\\s*=\\s*(?:extern|packed)?\\b\\s*struct\\s*[(\\{])/\n        }, {\n            token: \"entity.name.enum.zig\",\n            regex: /\\b(?!\\d)(?:[a-zA-Z_]\\w*|@\\\".+\\\")?(?=\\s*=\\s*(?:extern|packed)?\\b\\s*enum\\s*[(\\{])/\n        }, {\n            token: \"entity.name.error.zig\",\n            regex: /\\b(?!\\d)(?:[a-zA-Z_]\\w*|@\\\".+\\\")?(?=\\s*=\\s*error\\s*[(\\{])/\n        }, {\n            token: [\n                \"storage.type.error.zig\",\n                \"punctuation.accessor.zig\",\n                \"entity.name.error.zig\"\n            ],\n            regex: /\\b(error)(\\.)([a-zA-Z_]\\w*|@\\\".+\\\")/\n        }],\n        \"#dummy_main\": [{\n            include: \"#label\"\n        }, {\n            include: \"#function_type\"\n        }, {\n            include: \"#function_def\"\n        }, {\n            include: \"#punctuation\"\n        }, {\n            include: \"#storage_modifier\"\n        }, {\n            include: \"#container_decl\"\n        }, {\n            include: \"#constants\"\n        }, {\n            include: \"#comments\"\n        }, {\n            include: \"#strings\"\n        }, {\n            include: \"#storage\"\n        }, {\n            include: \"#keywords\"\n        }, {\n            include: \"#operators\"\n        }, {\n            include: \"#support\"\n        }, {\n            include: \"#field_decl\"\n        }, {\n            include: \"#block\"\n        }, {\n            include: \"#function_call\"\n        }, {\n            include: \"#enum_literal\"\n        }, {\n            include: \"#variables\"\n        }],\n        \"#enum_literal\": [{\n            token: \"constant.language.enum\",\n            regex: /(?!\\w|\\)|\\?|\\}|\\]|\\*|\\.)\\.(?:[a-zA-Z_]\\w*\\b|@\\\"[^\\\"]*\\\")(?!\\(|\\s*=[^=>])/\n        }],\n        \"#field_decl\": [{\n            token: [\n                \"variable.other.member.zig\",\n                \"text\",\n                \"punctuation.separator.zig\",\n                \"text\"\n            ],\n            regex: /([a-zA-Z_]\\w*|@\\\".+\\\")(\\s*)(:)(\\s*)/,\n            push: [{\n                token: [\n                    \"storage.type.zig\",\n                    \"text\",\n                    \"punctuation.separator.zig\",\n                    \"keyword.operator.assignment.zig\"\n                ],\n                regex: /((?:[a-zA-Z_][\\w.]*|@\\\".+\\\")?)(\\s*)(?:(,)|(=)|$)/,\n                next: \"pop\"\n            }, {\n                include: \"#dummy_main\"\n            }]\n        }],\n        \"#function_call\": [{\n            token: \"variable.function.zig\",\n            regex: /\\b(?!fn)(?:[a-zA-Z_]\\w*|@\\\".+\\\")(?=\\s*\\()/\n        }],\n        \"#keywords\": [{\n            token: \"keyword.control.zig\",\n            regex: /\\b(?:while|for|break|return|continue|asm|defer|errdefer|unreachable)\\b/\n        }, {\n            token: \"keyword.control.async.zig\",\n            regex: /\\b(?:async|await|suspend|nosuspend|resume)\\b/\n        }, {\n            token: \"keyword.control.conditional.zig\",\n            regex: /\\b(?:if|else|switch|try|catch|orelse)\\b/\n        }, {\n            token: \"keyword.control.import.zig\",\n            regex: /\\b(?!\\w)(?:@import|@cImport|@cInclude)\\b/\n        }, {\n            token: \"keyword.other.usingnamespace.zig\",\n            regex: /\\busingnamespace\\b/\n        }],\n        \"#label\": [{\n            token: [\n                \"keyword.control.zig\",\n                \"text\",\n                \"entity.name.label.zig\",\n                \"entity.name.label.zig\"\n            ],\n            regex: /\\b(break|continue)(\\s*:\\s*)([a-zA-Z_]\\w*|@\\\".+\\\")\\b|\\b(?!\\d)([a-zA-Z_]\\w*|@\\\".+\\\")\\b(?=\\s*:\\s*(?:\\{|while\\b))/\n        }],\n        \"#operators\": [{\n            token: \"keyword.operator.zig\",\n            regex: /\\b!\\b/\n        }, {\n            token: \"keyword.operator.logical.zig\",\n            regex: /==|(?:!|>|<)=?/\n        }, {\n            token: \"keyword.operator.word.zig\",\n            regex: /\\b(?:and|or)\\b/\n        }, {\n            token: \"keyword.operator.assignment.zig\",\n            regex: /(?:(?:\\+|-|\\*)\\%?|\\/|%|<<|>>|&|\\|(?=[^\\|])|\\^)?=/\n        }, {\n            token: \"keyword.operator.arithmetic.zig\",\n            regex: /(?:\\+|-|\\*)\\%?|\\/(?!\\/)|%/\n        }, {\n            token: \"keyword.operator.bitwise.zig\",\n            regex: /<<|>>|&(?=[a-zA-Z_]|@\\\")|\\|(?=[^\\|])|\\^|~/\n        }, {\n            token: \"keyword.operator.other.zig\",\n            regex: /\\+\\+|\\*\\*|->|\\.\\?|\\.\\*|&(?=[a-zA-Z_]|@\\\")|\\?|\\|\\||\\.{2,3}/\n        }],\n        \"#param_list\": [{\n            token: [\n                \"variable.parameter.zig\",\n                \"text\",\n                \"punctuation.separator.zig\",\n                \"text\"\n            ],\n            regex: /([a-zA-Z_]\\w*|@\\\".+\\\")(\\s*)(:)(\\s*)/,\n            push: [{\n                token: [\n                    \"storage.type.zig\",\n                    \"text\",\n                    \"punctuation.separator.zig\",\n                    \"punctuation.section.parens.end.zig\"\n                ],\n                regex: /((?:[a-zA-Z_][\\w.]*|@\\\".+\\\")?)(\\s*)(?:(,)|(\\)))/,\n                next: \"pop\"\n            }, {\n                include: \"#dummy_main\"\n            }, {\n                token: \"storage.type.zig\",\n                regex: /[a-zA-Z_][\\w.]*|@\\\".+\\\"/\n            }]\n        }],\n        \"#punctuation\": [{\n            token: \"punctuation.separator.zig\",\n            regex: /,/\n        }, {\n            token: \"punctuation.terminator.zig\",\n            regex: /;/\n        }, {\n            token: \"punctuation.section.parens.begin.zig\",\n            regex: /\\(/\n        }, {\n            token: \"punctuation.section.parens.end.zig\",\n            regex: /\\)/\n        }],\n        \"#storage\": [{\n            token: \"storage.type.zig\",\n            regex: /\\b(?:bool|void|noreturn|type|anyerror|anytype)\\b/\n        }, {\n            token: \"storage.type.integer.zig\",\n            regex: /\\b(?!\\.)(?:[iu]\\d+|[iu]size|comptime_int)\\b/\n        }, {\n            token: \"storage.type.float.zig\",\n            regex: /\\b(?:f16|f32|f64|f128|comptime_float)\\b/\n        }, {\n            token: \"storage.type.c_compat.zig\",\n            regex: /\\b(?:c_short|c_ushort|c_int|c_uint|c_long|c_ulong|c_longlong|c_ulonglong|c_longdouble|c_void)\\b/\n        }, {\n            token: [\n                \"storage.type.zig\",\n                \"text\",\n                \"keyword.operator.zig\",\n                \"text\",\n                \"storage.type.zig\"\n            ],\n            regex: /\\b(anyframe)\\b(\\s*)((?:->)?)(\\s*)(?:([a-zA-Z_][\\w.]*|@\\\".+\\\")\\b(?!\\s*\\())?/\n        }, {\n            token: \"storage.type.function.zig\",\n            regex: /\\bfn\\b/\n        }, {\n            token: \"storage.type.test.zig\",\n            regex: /\\btest\\b/\n        }, {\n            token: \"storage.type.struct.zig\",\n            regex: /\\bstruct\\b/\n        }, {\n            token: \"storage.type.enum.zig\",\n            regex: /\\benum\\b/\n        }, {\n            token: \"storage.type.union.zig\",\n            regex: /\\bunion\\b/\n        }, {\n            token: \"storage.type.error.zig\",\n            regex: /\\berror\\b/\n        }],\n        \"#storage_modifier\": [{\n            token: \"storage.modifier.zig\",\n            regex: /\\b(?:const|var|extern|packed|export|pub|noalias|inline|noinline|comptime|volatile|align|linksection|threadlocal|allowzero)\\b/\n        }],\n        \"#strings\": [{\n            token: \"string.quoted.single.zig\",\n            regex: /\\'/,\n            push: [{\n                token: \"string.quoted.single.zig\",\n                regex: /\\'/,\n                next: \"pop\"\n            }, {\n                include: \"#character_escapes\"\n            }, {\n                token: \"invalid.illegal.character.zig\",\n                regex: /\\\\[^\\'][^\\']*?/\n            }, {\n                defaultToken: \"string.quoted.single.zig\"\n            }]\n        }, {\n            token: \"string.quoted.double.zig\",\n            regex: /c?\\\"/,\n            push: [{\n                token: \"string.quoted.double.zig\",\n                regex: /\\\"/,\n                next: \"pop\"\n            }, {\n                include: \"#character_escapes\"\n            }, {\n                token: \"invalid.illegal.character.zig\",\n                regex: /\\\\[^\\'][^\\']*?/\n            }, {\n                defaultToken: \"string.quoted.double.zig\"\n            }]\n        }, {\n            token: \"string.quoted.other.zig\",\n            regex: /c?\\\\\\\\/,\n            push: [{\n                token: \"string.quoted.other.zig\",\n                regex: /$/,\n                next: \"pop\"\n            }, {\n                defaultToken: \"string.quoted.other.zig\"\n            }]\n        }],  \n        \"#function_type\": [{\n            token: [\n                \"storage.type.function.zig\",\n                \"text\",\n                \"punctuation.section.parens.begin.zig\"\n            ],\n            regex: /\\b(fn)(\\s*)(\\()/,\n            push: [{\n                token: [\n                    \"text\",\n                    \"storage.type.zig\",\n                    \"text\",\n                    \"keyword.operator.zig\",\n                    \"text\",\n                    \"storage.type.zig\"\n                ],\n                regex: /(\\s*)(?:([a-zA-Z_]\\w*|@\\\".+\\\"))?(\\s*)((?:!)?)(\\s*)([a-zA-Z_]\\w*|@\\\".+\\\")/,\n                next: \"pop\"\n            }, {\n                include: \"#label\"\n            }, {\n                include: \"#param_list\"\n            }, {\n                token: \"storage.type.zig\",\n                regex: /[a-zA-Z_]\\w*|@\\\".+\\\"/\n            }, {\n                include: \"#dummy_main\"\n            }, {\n                defaultToken: \"meta.function.parameters.zig\"\n            }]\n        }],\n        \"#function_def\": [{\n            token: [\n                \"text\",\n                \"entity.name.function\",\n                \"punctuation.section.parens.begin.zig\"\n            ],\n            regex: /(?=fn\\s+)(\\s+)([a-zA-Z_]\\w*|@\\\".+\\\")(\\()/,\n            push: [{\n                token: [\n                    \"text\",\n                    \"storage.type.zig\",\n                    \"keyword.operator.zig\",\n                    \"text\",\n                    \"storage.type.zig\"\n                ],\n                regex: /(\\s*)((?:[a-zA-Z_][\\w.]*|@\\\".+\\\")?)((?:!)?)(\\s*)(?:([a-zA-Z_][\\w.]*|@\\\".+\\\")?)/,\n                next: \"pop\"\n            }, {\n                include: \"#label\"\n            }, {\n                include: \"#param_list\"\n            }, {\n                token: \"storage.type.zig\",\n                regex: /[a-zA-Z_][\\w.]*|@\\\".+\\\"/\n            }, {\n                include: \"#dummy_main\"\n            }]\n        }],\n        \"#support\": [{\n            token: \"support.function.zig\",\n            regex: /\\b@(?!\\w|\\\"|[0-9])[a-zA-Z_]\\w*\\b/\n        }],\n        \"#variables\": [{\n            token: \"variable.constant.zig\",\n            regex: /\\b[_A-Z][_A-Z0-9]+\\b/\n        }, {\n            token: \"entity.name.type.zig\",\n            regex: /\\b[_a-zA-Z][_a-zA-Z0-9]*_t\\b/\n        }, {\n            token: \"entity.name.type.zig\",\n            regex: /\\b[A-Z][a-zA-Z0-9]*\\b/\n        }, {\n            token: \"variable.zig\",\n            regex: /\\b[_a-zA-Z][_a-zA-Z0-9]*\\b/\n        }]\n    };\n    \n    this.normalizeRules();\n};\n\nZigHighlightRules.metaData = {\n    fileTypes: [\"zig\"],\n    keyEquivalent: \"^~Z\",\n    name: \"Zig\",\n    scopeName: \"source.zig\"\n};\n\n\noop.inherits(ZigHighlightRules, TextHighlightRules);\n\nexports.ZigHighlightRules = ZigHighlightRules;\n"
  },
  {
    "path": "src/mouse/default_gutter_handler.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./mouse_handler\").MouseHandler} MouseHandler\n */\nvar dom = require(\"../lib/dom\");\nvar MouseEvent = require(\"./mouse_event\").MouseEvent;\nvar HoverTooltip = require(\"../tooltip\").HoverTooltip;\nvar nls = require(\"../config\").nls;\nvar Range = require(\"../range\").Range;\n\n/**\n * @param {MouseHandler} mouseHandler\n * @this {MouseHandler}\n */\nfunction GutterHandler(mouseHandler) {\n    var editor = mouseHandler.editor;\n    var gutter = editor.renderer.$gutterLayer;\n    mouseHandler.$tooltip = new GutterTooltip(editor);\n    mouseHandler.$tooltip.addToEditor(editor);\n\n    mouseHandler.$tooltip.setDataProvider(function(e, editor) {\n        var row = e.getDocumentPosition().row;\n        mouseHandler.$tooltip.showTooltip(row);\n    });\n\n    mouseHandler.editor.setDefaultHandler(\"guttermousedown\", function(e) {\n        if (!editor.isFocused() || e.getButton() != 0)\n            return;\n        var gutterRegion = gutter.getRegion(e);\n\n        if (gutterRegion == \"foldWidgets\")\n            return;\n\n        var row = e.getDocumentPosition().row;\n        var selection = editor.session.selection;\n\n        if (e.getShiftKey())\n            selection.selectTo(row, 0);\n        else {\n            if (e.domEvent.detail == 2) {\n                editor.selectAll();\n                return e.preventDefault();\n            }\n            mouseHandler.$clickSelection = editor.selection.getLineRange(row);\n        }\n        mouseHandler.setState(\"selectByLines\");\n        mouseHandler.captureMouse(e);\n        return e.preventDefault();\n    });\n}\n\nexports.GutterHandler = GutterHandler;\n\n\nclass GutterTooltip extends HoverTooltip {\n    /**\n     * @param {import(\"../editor\").Editor} editor\n     */\n    constructor(editor) {\n        super(editor.container);\n        this.id = \"gt\" + (++GutterTooltip.$uid);\n        this.editor = editor;\n        /**@type {Number | Undefined}*/\n        this.visibleTooltipRow;\n        var el = this.getElement();\n        el.setAttribute(\"role\", \"tooltip\");\n        el.setAttribute(\"id\", this.id);\n        el.style.pointerEvents = \"auto\";\n        this.idleTime = 50;\n\n        this.onDomMouseMove = this.onDomMouseMove.bind(this);\n        this.onDomMouseOut = this.onDomMouseOut.bind(this);\n\n        this.setClassName(\"ace_gutter-tooltip\");\n    }\n    \n    onDomMouseMove(domEvent) {\n        var aceEvent = new MouseEvent(domEvent, this.editor);\n        this.onMouseMove(aceEvent, this.editor);\n    }\n    \n    onDomMouseOut(domEvent) {\n        var aceEvent = new MouseEvent(domEvent, this.editor);\n        this.onMouseOut(aceEvent);\n    }\n\n    addToEditor(editor) {\n        var gutter = editor.renderer.$gutter;\n        gutter.addEventListener(\"mousemove\", this.onDomMouseMove);\n        gutter.addEventListener(\"mouseout\", this.onDomMouseOut);\n        super.addToEditor(editor);\n    }\n\n    removeFromEditor(editor) {\n        var gutter = editor.renderer.$gutter;\n        gutter.removeEventListener(\"mousemove\", this.onDomMouseMove);\n        gutter.removeEventListener(\"mouseout\", this.onDomMouseOut);\n        super.removeFromEditor(editor);\n    }\n\n    destroy() {\n        if (this.editor) {\n            this.removeFromEditor(this.editor);\n        }\n        super.destroy();\n    }\n\n    static get annotationLabels() {\n        return {\n            error: {\n                singular: nls(\"gutter-tooltip.aria-label.error.singular\", \"error\"),\n                plural: nls(\"gutter-tooltip.aria-label.error.plural\", \"errors\")\n            },\n            security: {\n                singular: nls(\"gutter-tooltip.aria-label.security.singular\", \"security finding\"),\n                plural: nls(\"gutter-tooltip.aria-label.security.plural\", \"security findings\")\n            },\n            warning: {\n                singular: nls(\"gutter-tooltip.aria-label.warning.singular\", \"warning\"),\n                plural: nls(\"gutter-tooltip.aria-label.warning.plural\", \"warnings\")\n            },\n            info: {\n                singular: nls(\"gutter-tooltip.aria-label.info.singular\", \"information message\"),\n                plural: nls(\"gutter-tooltip.aria-label.info.plural\", \"information messages\")\n            },\n            hint: {\n                singular: nls(\"gutter-tooltip.aria-label.hint.singular\", \"suggestion\"),\n                plural: nls(\"gutter-tooltip.aria-label.hint.plural\", \"suggestions\")\n            }\n        };\n    }\n\n    /**\n     * @param {number} row\n     */\n    showTooltip(row) {\n        var gutter = this.editor.renderer.$gutterLayer;\n        var annotationsInRow = gutter.$annotations[row];\n        var annotation;\n\n        if (annotationsInRow)\n            annotation = {\n                displayText: Array.from(annotationsInRow.displayText),\n                type: Array.from(annotationsInRow.type)\n            };\n        else annotation = {displayText: [], type: []};\n\n        // If the tooltip is for a row which has a closed fold, check whether there are\n        // annotations in the folded lines. If so, add a summary to the list of annotations.\n        var fold = gutter.session.getFoldLine(row);\n        if (fold && gutter.$showFoldedAnnotations) {\n            var annotationsInFold = {error: [], security: [], warning: [], info: [], hint: []};\n            var severityRank = {error: 1, security: 2, warning: 3, info: 4, hint: 5};\n            var mostSevereAnnotationTypeInFold;\n\n            for (var i = row + 1; i <= fold.end.row; i++) {\n                if (!gutter.$annotations[i]) continue;\n\n                for (var j = 0; j < gutter.$annotations[i].text.length; j++) {\n                    var annotationType = gutter.$annotations[i].type[j];\n                    annotationsInFold[annotationType].push(gutter.$annotations[i].text[j]);\n\n                    if (\n                        !mostSevereAnnotationTypeInFold ||\n                        severityRank[annotationType] < severityRank[mostSevereAnnotationTypeInFold]\n                    ) {\n                        mostSevereAnnotationTypeInFold = annotationType;\n                    }\n                }\n            }\n\n            if ([\"error\", \"security\", \"warning\"].includes(mostSevereAnnotationTypeInFold)) {\n                var summaryFoldedAnnotations = `${GutterTooltip.annotationsToSummaryString(\n                    annotationsInFold\n                )} in folded code.`;\n\n                annotation.displayText.push(summaryFoldedAnnotations);\n                annotation.type.push(mostSevereAnnotationTypeInFold + \"_fold\");\n            }\n        }\n\n        if (annotation.displayText.length === 0) return this.hide();\n\n        var annotationMessages = {error: [], security: [], warning: [], info: [], hint: []};\n        var iconClassName = gutter.$useSvgGutterIcons ? \"ace_icon_svg\" : \"ace_icon\";\n\n        // Construct the contents of the tooltip.\n        for (var i = 0; i < annotation.displayText.length; i++) {\n            var lineElement = dom.createElement(\"span\");\n\n            var iconElement = dom.createElement(\"span\");\n            iconElement.classList.add(...[`ace_${annotation.type[i]}`, iconClassName]);\n            iconElement.setAttribute(\n                \"aria-label\",\n                `${GutterTooltip.annotationLabels[annotation.type[i].replace(\"_fold\", \"\")].singular}`\n            );\n            iconElement.setAttribute(\"role\", \"img\");\n            // Set empty content to the img span to get it to show up\n            iconElement.appendChild(dom.createTextNode(\" \"));\n\n            lineElement.appendChild(iconElement);\n            lineElement.appendChild(dom.createTextNode(annotation.displayText[i]));\n            lineElement.appendChild(dom.createElement(\"br\"));\n\n            annotationMessages[annotation.type[i].replace(\"_fold\", \"\")].push(lineElement);\n        }\n\n        var tooltipElement = dom.createElement(\"span\");\n\n        // Update the tooltip content\n        annotationMessages.error.forEach((el) => tooltipElement.appendChild(el));\n        annotationMessages.security.forEach((el) => tooltipElement.appendChild(el));\n        annotationMessages.warning.forEach((el) => tooltipElement.appendChild(el));\n        annotationMessages.info.forEach((el) => tooltipElement.appendChild(el));\n        annotationMessages.hint.forEach((el) => tooltipElement.appendChild(el));\n\n        tooltipElement.setAttribute(\"aria-live\", \"polite\");\n\n        var annotationNode = this.$findLinkedAnnotationNode(row);\n        if (annotationNode) {\n            annotationNode.setAttribute(\"aria-describedby\", this.id);\n        }\n\n        var range = Range.fromPoints({row, column: 0}, {row, column: 0});\n        this.showForRange(this.editor, range, tooltipElement);\n        this.visibleTooltipRow = row;\n        this.editor._signal(\"showGutterTooltip\", this);\n    }\n\n    $setPosition(editor, _ignoredPosition, _withMarker, range) {\n        var gutterCell = this.$findCellByRow(range.start.row);\n        if (!gutterCell) return;\n        var el = gutterCell && gutterCell.element;\n        var anchorEl = el && (el.querySelector(\".ace_gutter_annotation\"));\n        if (!anchorEl) return;\n        var r = anchorEl.getBoundingClientRect();\n        if (!r) return;\n        var position = {\n            pageX: r.right,\n            pageY: r.top\n        };\n        //we don't need marker for gutter\n        return super.$setPosition(editor, position, false, range);\n    }\n\n    $shouldPlaceAbove(labelHeight, anchorTop, spaceBelow) {\n        return spaceBelow < labelHeight;\n    }\n\n    $findLinkedAnnotationNode(row) {\n        var cell = this.$findCellByRow(row);\n        if (cell) {\n            var element = cell.element;\n            if (element.childNodes.length > 2) {\n                return element.childNodes[2];\n            }\n        }\n    }\n\n    $findCellByRow(row) {\n        return this.editor.renderer.$gutterLayer.$lines.cells.find((el) => el.row === row);\n    }\n\n    hide(e) {\n        if(!this.isOpen){\n            return;\n        }\n        this.$element.removeAttribute(\"aria-live\");\n\n        if (this.visibleTooltipRow != undefined) {\n            var annotationNode = this.$findLinkedAnnotationNode(this.visibleTooltipRow);\n            if (annotationNode) {\n                annotationNode.removeAttribute(\"aria-describedby\");\n            }\n        }\n        this.visibleTooltipRow = undefined;\n        this.editor._signal(\"hideGutterTooltip\", this);\n        super.hide(e);\n    }\n\n    static annotationsToSummaryString(annotations) {\n        var summary = [];\n        var annotationTypes = [\"error\", \"security\", \"warning\", \"info\", \"hint\"];\n        for (var annotationType of annotationTypes) {\n            if (!annotations[annotationType].length) continue;\n            var label = annotations[annotationType].length === 1 ? GutterTooltip.annotationLabels[annotationType].singular : GutterTooltip.annotationLabels[annotationType].plural;\n            summary.push(`${annotations[annotationType].length} ${label}`);\n        }\n        return summary.join(\", \");\n    }\n\n    /**\n     * Check if cursor is outside gutter\n     * @param e\n     * @return {boolean}\n     */\n    isOutsideOfText(e) {\n        var editor = e.editor;\n        var rect = editor.renderer.$gutter.getBoundingClientRect();\n        return !(e.clientX >= rect.left && e.clientX <= rect.right &&\n               e.clientY >= rect.top && e.clientY <= rect.bottom);\n    }\n}\n\nGutterTooltip.$uid = 0;\n\nexports.GutterTooltip = GutterTooltip;\n"
  },
  {
    "path": "src/mouse/default_gutter_handler_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"../multi_select\");\nrequire(\"../theme/textmate\");\nvar Editor = require(\"../editor\").Editor;\nvar Mode = require(\"../mode/java\").Mode;\nvar VirtualRenderer = require(\"../virtual_renderer\").VirtualRenderer;\nvar assert = require(\"../test/assertions\");\nvar user = require(\"../test/user\");\nvar lang = require(\"../lib/lang\");\n\nvar MouseEvent = function(type, opts){\n    var e = document.createEvent(\"MouseEvents\");\n    e.initMouseEvent(/click|wheel/.test(type) ? type : \"mouse\" + type,\n        true, true, window,\n        opts.detail,\n        opts.x, opts.y, opts.x, opts.y,\n        opts.ctrl, opts.alt, opts.shift, opts.meta,\n        opts.button || 0, opts.relatedTarget);\n    return e;\n};\n\nvar editor;\n\nfunction findVisibleTooltip() {\n    const tooltips = document.body.querySelectorAll(\".ace_gutter-tooltip\");\n    for (let i = 0; i < tooltips.length; i++) {\n        if (window.getComputedStyle(tooltips[i]).display === \"block\") {\n            return tooltips[i];\n        }\n    }\n    return null;\n}\n\nmodule.exports = {\n    setUp : function() {\n        this.editor = new Editor(new VirtualRenderer());\n        this.editor.container.style.position = \"absolute\";\n        this.editor.container.style.height = \"500px\";\n        this.editor.container.style.width = \"500px\";\n        this.editor.container.style.left = \"50px\";\n        this.editor.container.style.top = \"10px\";\n        document.body.appendChild(this.editor.container);\n        editor = this.editor;\n    },\n    \"test: gutter error tooltip\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_error/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n\n        assert.ok(/error test/.test(tooltip.textContent));\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: 0, y: 0}));\n        done();\n    },\n    \"test: gutter security tooltip\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"security finding test\", type: \"security\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_security/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/security finding test/.test(tooltip.textContent));\n        done();\n    },\n    \"test: gutter warning tooltip\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"warning test\", type: \"warning\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_warning/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/warning test/.test(tooltip.textContent));\n        done();\n    },\n    \"test: gutter info tooltip\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"info test\", type: \"info\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_info/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/info test/.test(tooltip.textContent));\n        done();\n    },\n    \"test: gutter hint tooltip\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"suggestion test\", type: \"hint\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_hint/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/suggestion test/.test(tooltip.textContent));\n        done();\n    },\n    \"test: gutter svg icons\" : function() {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setOption(\"useSvgGutterIcons\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, type: \"error\", text: \"error test\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var line = lines.cells[0].element;\n        assert.ok(/ace_gutter-cell_svg-icons/.test(line.className));\n\n        var annotation = line.childNodes[2].firstChild;\n        assert.ok(/ace_icon_svg/.test(annotation.className));\n    },\n    \"test: error show up in fold\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, type: \"error\", text: \"error test\"}]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should have fold class.\n        var annotation = lines.cells[0].element.childNodes[2].firstChild;\n        assert.ok(/ace_error_fold/.test(annotation.className));\n\n        var row = lines.cells[0].row;\n        editor.$mouseHandler.$tooltip.showTooltip(row);\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error in folded/.test(tooltip.textContent));\n        done();\n    },\n    \"test: security show up in fold\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, type: \"security\", text: \"security finding test\"}]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should have fold class.\n        var annotation = lines.cells[0].element.childNodes[2].firstChild;\n        assert.ok(/ace_security_fold/.test(annotation.className));\n\n        var row = lines.cells[0].row;\n        editor.$mouseHandler.$tooltip.showTooltip(row);\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/security finding in folded/.test(tooltip.textContent));\n        done();\n    },\n    \"test: warning show up in fold\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, type: \"warning\", text: \"warning test\"}]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should have fold class.\n        var annotation = lines.cells[0].element.childNodes[2].firstChild;\n        assert.ok(/ace_warning_fold/.test(annotation.className));\n\n        var row = lines.cells[0].row;\n        editor.$mouseHandler.$tooltip.showTooltip(row);\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/warning in folded/.test(tooltip.textContent));\n        done();\n    },\n    \"test: info not show up in fold\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, type: \"info\", text: \"info test\"}]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should NOT have fold class.\n        var annotation = lines.cells[0].element.childNodes[2];\n        assert.notOk(/fold/.test(annotation.className));\n    },\n    \"test: hint not show up in fold\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 1, column: 0, type: \"hint\", text: \"suggestion test\"}]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var toggler = lines.cells[0].element.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should NOT have fold class.\n        var annotation = lines.cells[0].element.childNodes[2];\n        assert.notOk(/fold/.test(annotation.className));\n    },\n    \"test: severities are correctly ordered/ranked when folding\": function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setOption(\"showFoldedAnnotations\", true);\n        editor.setValue(value, -1);\n        // Rank is: Error > Security > Warning\n        editor.session.setAnnotations([\n            {row: 1, column: 0, type: \"warning\", text: \"warning test\"},\n            {row: 1, column: 0, type: \"security\", text: \"security finding test\"},\n            {row: 1, column: 0, type: \"error\", text: \"error test\"}\n        ]);\n        editor.renderer.$loop._flush();\n\n        // Fold the line containing the annotation.\n        var lines = editor.renderer.$gutterLayer.$lines;\n        assert.equal(lines.cells[1].element.textContent, \"2\");\n        var firstLineGutterElement = lines.cells[0].element;\n        var toggler = firstLineGutterElement.querySelector(\".ace_fold-widget\");\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(new MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        assert.ok(/ace_closed/.test(toggler.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n\n        // Annotation node should have Error fold class\n        assert.ok(/ace_error_fold/.test(firstLineGutterElement.className));\n        assert.notOk(/ace_security_fold/.test(firstLineGutterElement.className));\n        assert.notOk(/ace_warning_fold/.test(firstLineGutterElement.className));\n\n        // Annotation node should have Security fold class\n        editor.session.setAnnotations([\n            {row: 1, column: 0, type: \"security\", text: \"security finding test\"},\n            {row: 1, column: 0, type: \"warning\", text: \"warning test\"}\n        ]);\n        editor.renderer.$loop._flush();\n        assert.notOk(/ace_error_fold/.test(firstLineGutterElement.className));\n        assert.ok(/ace_security_fold/.test(firstLineGutterElement.className));\n        assert.notOk(/ace_warning_fold/.test(firstLineGutterElement.className));\n\n        // Annotation node should have Warning fold class\n        editor.session.setAnnotations([\n            {row: 1, column: 0, type: \"warning\", text: \"warning test\"}\n        ]);\n        editor.renderer.$loop._flush();\n        assert.notOk(/ace_error_fold/.test(firstLineGutterElement.className));\n        assert.notOk(/ace_security_fold/.test(firstLineGutterElement.className));\n        assert.ok(/ace_warning_fold/.test(firstLineGutterElement.className));\n    },\n    \"test: gutter tooltip should properly display special characters (\\\" ' & <)\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"special characters \\\" ' & <\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_error/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/special characters \" ' & </.test(tooltip.textContent));\n        done();\n    },\n    \"test: gutter hover tooltip should remain open when pressing ctrl key combination\" : async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var annotation = lines.cells[0].element;\n        assert.ok(/ace_error/.test(annotation.className));\n\n        var rect = annotation.getBoundingClientRect();\n        annotation.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n        tooltip.focus();\n        user.type(\"Ctrl-C\");\n        tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n        // also verify if it closes when presses another key\n        user.type(\"Escape\");\n        tooltip = document.body.querySelector(\".ace_gutter-tooltip\");\n        assert.strictEqual(tooltip.style.display, \"none\");\n        done();\n    },\n    \"test: gutter tooltip aria-describedby attribute\": async function(done) {\n        var editor = this.editor;\n        var value = \"\";\n\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.session.setAnnotations([{row: 0, column: 0, text: \"error test\", type: \"error\"}]);\n        editor.renderer.$loop._flush();\n\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var element = lines.cells[0].element;\n        var annotation = element.childNodes[2];\n        assert.ok(/ace_error/.test(element.className));\n\n        var rect = element.getBoundingClientRect();\n        element.dispatchEvent(new MouseEvent(\"move\", {x: rect.left + rect.width/2, y: rect.top + rect.height/2}));\n\n        // Wait for the tooltip to appear after its timeout.\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        var tooltip = findVisibleTooltip();\n        assert.ok(/error test/.test(tooltip.textContent));\n\n        var ariaDescribedBy = annotation.getAttribute(\"aria-describedby\");\n        assert.ok(ariaDescribedBy, \"aria-describedby should be set when tooltip is shown\");\n        assert.equal(ariaDescribedBy, tooltip.id, \"aria-describedby should match tooltip id\");\n\n        editor.container.dispatchEvent(new MouseEvent(\"wheel\", {}));\n\n        await lang.sleep(100);\n        editor.renderer.$loop._flush();\n        assert.equal(\n            annotation.getAttribute(\"aria-describedby\"), \"\",\n            \"aria-describedby should be removed when tooltip is hidden\"\n        );\n        done();\n    },\n\n    tearDown : function() {\n        this.editor.destroy();\n        document.body.removeChild(this.editor.container);\n    }\n};\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mouse/default_handlers.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./mouse_handler\").MouseHandler} MouseHandler\n * @typedef {import(\"./mouse_event\").MouseEvent} MouseEvent\n */\nvar useragent = require(\"../lib/useragent\");\n\nvar DRAG_OFFSET = 0; // pixels\nvar SCROLL_COOLDOWN_T = 550; // milliseconds\n\nclass DefaultHandlers {\n    /**\n     * @param {MouseHandler} mouseHandler\n     */\n    constructor(mouseHandler) {\n        mouseHandler.$clickSelection = null;\n\n        var editor = mouseHandler.editor;\n        editor.setDefaultHandler(\"mousedown\", this.onMouseDown.bind(mouseHandler));\n        editor.setDefaultHandler(\"dblclick\", this.onDoubleClick.bind(mouseHandler));\n        editor.setDefaultHandler(\"tripleclick\", this.onTripleClick.bind(mouseHandler));\n        editor.setDefaultHandler(\"quadclick\", this.onQuadClick.bind(mouseHandler));\n        editor.setDefaultHandler(\"mousewheel\", this.onMouseWheel.bind(mouseHandler));\n\n        var exports = [\"select\", \"startSelect\", \"selectEnd\", \"selectAllEnd\", \"selectByWordsEnd\",\n            \"selectByLinesEnd\", \"dragWait\", \"dragWaitEnd\", \"focusWait\"];\n\n        exports.forEach(function(x) {\n            mouseHandler[x] = this[x];\n        }, this);\n\n        mouseHandler[\"selectByLines\"] = this.extendSelectionBy.bind(mouseHandler, \"getLineRange\");\n        mouseHandler[\"selectByWords\"] = this.extendSelectionBy.bind(mouseHandler, \"getWordRange\");\n    }\n\n    /**\n     * @param {MouseEvent} ev\n     * @this {MouseHandler}\n     */\n    onMouseDown(ev) {\n        var inSelection = ev.inSelection();\n        var pos = ev.getDocumentPosition();\n        this.mousedownEvent = ev;\n        var editor = this.editor;\n\n        var button = ev.getButton();\n        if (button !== 0) {\n            var selectionRange = editor.getSelectionRange();\n            var selectionEmpty = selectionRange.isEmpty();\n            if (selectionEmpty || button == 1)\n                editor.selection.moveToPosition(pos);\n            // 2: contextmenu, 1: linux paste\n            if (button == 2) {\n                editor.textInput.onContextMenu(ev.domEvent);\n                if (!useragent.isMozilla)\n                    ev.preventDefault();\n            }\n            // stopping event here breaks contextmenu on ff mac\n            // not stoping breaks it on chrome mac\n            return;\n        }\n\n        this.mousedownEvent.time = Date.now();\n        // if this click caused the editor to be focused should not clear the\n        // selection\n        if (inSelection && !editor.isFocused()) {\n            editor.focus();\n            if (this.$focusTimeout && !this.$clickSelection && !editor.inMultiSelectMode) {\n                this.setState(\"focusWait\");\n                this.captureMouse(ev);\n                return;\n            }\n        }\n\n        this.captureMouse(ev);\n        this.startSelect(pos, ev.domEvent._clicks > 1);\n        return ev.preventDefault();\n    }\n\n    /**\n     * \n     * @param {import(\"../../ace-internal\").Ace.Position} [pos]\n     * @param {boolean} [waitForClickSelection]\n     * @this {MouseHandler}\n     */\n    startSelect(pos, waitForClickSelection) {\n        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);\n        var editor = this.editor;\n        if (!this.mousedownEvent) return;\n        // allow double/triple click handlers to change selection\n        if (this.mousedownEvent.getShiftKey())\n            editor.selection.selectToPosition(pos);\n        else if (!waitForClickSelection)\n            editor.selection.moveToPosition(pos);\n        if (!waitForClickSelection)\n            this.select();\n        editor.setStyle(\"ace_selecting\");\n        this.setState(\"select\");\n    }\n\n    /**\n     * @this {MouseHandler}\n     */\n    select() {\n        var anchor, editor = this.editor;\n        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n        if (this.$clickSelection) {\n            var cmp = this.$clickSelection.comparePoint(cursor);\n\n            if (cmp == -1) {\n                anchor = this.$clickSelection.end;\n            } else if (cmp == 1) {\n                anchor = this.$clickSelection.start;\n            } else {\n                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor, editor.session);\n                cursor = orientedRange.cursor;\n                anchor = orientedRange.anchor;\n            }\n            editor.selection.setSelectionAnchor(anchor.row, anchor.column);\n        }\n        editor.selection.selectToPosition(cursor);\n        editor.renderer.scrollCursorIntoView();\n    }\n\n    /**\n     * @param {string | number} unitName\n     * @this {MouseHandler}\n     */\n    extendSelectionBy(unitName) {\n        var anchor, editor = this.editor;\n        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n        var range = editor.selection[unitName](cursor.row, cursor.column);\n        if (this.$clickSelection) {\n            var cmpStart = this.$clickSelection.comparePoint(range.start);\n            var cmpEnd = this.$clickSelection.comparePoint(range.end);\n\n            if (cmpStart == -1 && cmpEnd <= 0) {\n                anchor = this.$clickSelection.end;\n                if (range.end.row != cursor.row || range.end.column != cursor.column)\n                    cursor = range.start;\n            } else if (cmpEnd == 1 && cmpStart >= 0) {\n                anchor = this.$clickSelection.start;\n                if (range.start.row != cursor.row || range.start.column != cursor.column)\n                    cursor = range.end;\n            } else if (cmpStart == -1 && cmpEnd == 1) {\n                cursor = range.end;\n                anchor = range.start;\n            } else {\n                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor, editor.session);\n                cursor = orientedRange.cursor;\n                anchor = orientedRange.anchor;\n            }\n            editor.selection.setSelectionAnchor(anchor.row, anchor.column);\n        }\n        editor.selection.selectToPosition(cursor);\n        editor.renderer.scrollCursorIntoView();\n    }\n\n    /**\n     * @this {MouseHandler}\n     */\n    selectByLinesEnd() {\n        this.$clickSelection = null;\n        this.editor.unsetStyle(\"ace_selecting\");\n    }\n\n    /**\n     * @this {MouseHandler}\n     */\n    focusWait() {\n        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n        var time = Date.now();\n\n        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimeout)\n            this.startSelect(this.mousedownEvent.getDocumentPosition());\n    }\n    \n    /**\n     * @param {MouseEvent} ev\n     * @this {MouseHandler}\n     */\n    onDoubleClick(ev) {\n        var pos = ev.getDocumentPosition();\n        var editor = this.editor;\n        var session = editor.session;\n\n        var range = session.getBracketRange(pos);\n        if (range) {\n            if (range.isEmpty()) {\n                range.start.column--;\n                range.end.column++;\n            }\n            this.setState(\"select\");\n        } else {\n            range = editor.selection.getWordRange(pos.row, pos.column);\n            this.setState(\"selectByWords\");\n        }\n        this.$clickSelection = range;\n        this.select();\n    }\n\n    /**\n     * @param {MouseEvent} ev\n     * @this {MouseHandler}\n     */\n    onTripleClick(ev) {\n        var pos = ev.getDocumentPosition();\n        var editor = this.editor;\n\n        this.setState(\"selectByLines\");\n        var range = editor.getSelectionRange();\n        if (range.isMultiLine() && range.contains(pos.row, pos.column)) {\n            this.$clickSelection = editor.selection.getLineRange(range.start.row);\n            this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;\n        } else {\n            this.$clickSelection = editor.selection.getLineRange(pos.row);\n        }\n        this.select();\n    }\n\n    /**\n     * @param {MouseEvent} ev\n     * @this {MouseHandler}\n     */\n    onQuadClick(ev) {\n        var editor = this.editor;\n\n        editor.selectAll();\n        this.$clickSelection = editor.getSelectionRange();\n        this.setState(\"selectAll\");\n    }\n\n    /**\n     * @param {MouseEvent} ev\n     * @this {MouseHandler}\n     */\n    onMouseWheel(ev) {\n        if (ev.getAccelKey())\n            return;\n\n        // shift wheel to horizontal scroll\n        if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {\n            ev.wheelX = ev.wheelY;\n            ev.wheelY = 0;\n        }\n        \n        var editor = this.editor;\n        \n        if (!this.$lastScroll)\n            this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 };\n        \n        var prevScroll = this.$lastScroll;\n        var t = ev.domEvent.timeStamp;\n        var dt = t - prevScroll.t;\n        var vx = dt ? ev.wheelX / dt : prevScroll.vx;\n        var vy = dt ? ev.wheelY / dt : prevScroll.vy;\n        \n        // touchbar keeps sending scroll events after touchend, if we do not stop these events,\n        // users can't scrol editor without scrolling the parent node\n        if (dt < SCROLL_COOLDOWN_T) {\n            vx = (vx + prevScroll.vx) / 2;\n            vy = (vy + prevScroll.vy) / 2;\n        }\n        \n        var direction = Math.abs(vx / vy);\n        \n        var canScroll = false;\n        if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0))\n            canScroll = true;\n        if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed))\n            canScroll = true;\n            \n        if (canScroll) {\n            prevScroll.allowed = t;\n        } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {\n            var isSlower = Math.abs(vx) <= 1.5 * Math.abs(prevScroll.vx)\n                && Math.abs(vy) <= 1.5 * Math.abs(prevScroll.vy);\n            if (isSlower) {\n                canScroll = true;\n                prevScroll.allowed = t;\n            }\n            else {\n                prevScroll.allowed = 0;\n            }\n        }\n        \n        prevScroll.t = t;\n        prevScroll.vx = vx;\n        prevScroll.vy = vy;\n\n        if (canScroll) {\n            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);\n            return ev.stop();\n        }\n    }\n\n}\nDefaultHandlers.prototype.selectEnd = DefaultHandlers.prototype.selectByLinesEnd;\nDefaultHandlers.prototype.selectAllEnd = DefaultHandlers.prototype.selectByLinesEnd;\nDefaultHandlers.prototype.selectByWordsEnd = DefaultHandlers.prototype.selectByLinesEnd;\n\nexports.DefaultHandlers = DefaultHandlers;\n\nfunction calcDistance(ax, ay, bx, by) {\n    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n}\n\nfunction calcRangeOrientation(range, cursor, session) {\n    if (range.start.row == range.end.row)\n        var cmp = 2 * cursor.column - range.start.column - range.end.column;\n    else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)\n        var cmp = 3 * cursor.column - 2 * session.getLine(range.start.row).length;\n    else\n        var cmp = 2 * cursor.row - range.start.row - range.end.row;\n\n    if (cmp < 0)\n        return {cursor: range.start, anchor: range.end};\n    else\n        return {cursor: range.end, anchor: range.start};\n}\n"
  },
  {
    "path": "src/mouse/dragdrop_handler.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./mouse_handler\").MouseHandler} MouseHandler\n */\nvar dom = require(\"../lib/dom\");\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\n\nvar AUTOSCROLL_DELAY = 200;\nvar SCROLL_CURSOR_DELAY = 200;\nvar SCROLL_CURSOR_HYSTERESIS = 5;\n\n/**\n * @param {MouseHandler} mouseHandler\n */\nfunction DragdropHandler(mouseHandler) {\n\n    var editor = mouseHandler.editor;\n\n    var dragImage = dom.createElement(\"div\");\n    dragImage.style.cssText = \"top:-100px;position:absolute;z-index:2147483647;opacity:0.5\";\n    dragImage.textContent = \"\\xa0\";\n\n    var exports = [\"dragWait\", \"dragWaitEnd\", \"startDrag\", \"dragReadyEnd\", \"onMouseDrag\"];\n\n    exports.forEach(function(x) {\n        mouseHandler[x] = this[x];\n    }, this);\n    // @ts-ignore\n    editor.on(\"mousedown\", this.onMouseDown.bind(mouseHandler));\n\n    var mouseTarget = editor.container;\n    var dragSelectionMarker, x, y;\n    var timerId, range;\n    var dragCursor, counter = 0;\n    var dragOperation;\n    var isInternal;\n    var autoScrollStartTime;\n    var cursorMovedTime;\n    var cursorPointOnCaretMoved;\n    /**\n     * @param e\n     * @this {MouseHandler}\n     * @return {*}\n     */\n    this.onDragStart = function(e) {\n        // webkit workaround, see this.onMouseDown\n        if (this.cancelDrag || !mouseTarget.draggable) {\n            var self = this;\n            setTimeout(function(){\n                self.startSelect();\n                self.captureMouse(e);\n            }, 0);\n            return e.preventDefault();\n        }\n        range = editor.getSelectionRange();\n\n        var dataTransfer = e.dataTransfer;\n        dataTransfer.effectAllowed = editor.getReadOnly() ? \"copy\" : \"copyMove\";\n        editor.container.appendChild(dragImage);\n\n        dataTransfer.setDragImage && dataTransfer.setDragImage(dragImage, 0, 0);\n        setTimeout(function() {\n            editor.container.removeChild(dragImage);\n        });\n        // clear Opera garbage\n        dataTransfer.clearData();\n        dataTransfer.setData(\"Text\", editor.session.getTextRange());\n\n        isInternal = true;\n        this.setState(\"drag\");\n    };\n    /**\n     * @param e\n     * @this {MouseHandler}\n     * @return {*}\n     */\n    this.onDragEnd = function(e) {\n        mouseTarget.draggable = false;\n        isInternal = false;\n        this.setState(null);\n        if (!editor.getReadOnly()) {\n            var dropEffect = e.dataTransfer.dropEffect;\n            if (!dragOperation && dropEffect == \"move\")\n                // text was dragged outside the editor\n                editor.session.remove(editor.getSelectionRange());\n            editor.$resetCursorStyle();\n        }\n        this.editor.unsetStyle(\"ace_dragging\");\n        this.editor.renderer.setCursorStyle(\"\");\n    };\n    /**\n     * @param e\n     * @this {MouseHandler}\n     * @return {*}\n     */\n    this.onDragEnter = function(e) {\n        if (editor.getReadOnly() || !canAccept(e.dataTransfer))\n            return;\n        x = e.clientX;\n        y = e.clientY;\n        if (!dragSelectionMarker)\n            addDragMarker();\n        counter++;\n        // dataTransfer object does not save dropEffect across events on IE, so we store it in dragOperation\n        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n        return event.preventDefault(e);\n    };\n    /**\n     * @param e\n     * @this {MouseHandler}\n     * @return {*}\n     */\n    this.onDragOver = function(e) {\n        if (editor.getReadOnly() || !canAccept(e.dataTransfer))\n            return;\n        x = e.clientX;\n        y = e.clientY;\n        // Opera doesn't trigger dragenter event on drag start\n        if (!dragSelectionMarker) {\n            addDragMarker();\n            counter++;\n        }\n        if (onMouseMoveTimer !== null)\n            onMouseMoveTimer = null;\n\n        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n        return event.preventDefault(e);\n    };\n\n    this.onDragLeave = function(e) {\n        counter--;\n        if (counter <= 0 && dragSelectionMarker) {\n            clearDragMarker();\n            dragOperation = null;\n            return event.preventDefault(e);\n        }\n    };\n    /**\n     * @param e\n     * @this {MouseHandler}\n     * @return {*}\n     */\n    this.onDrop = function(e) {\n        if (!dragCursor)\n            return;\n        var dataTransfer = e.dataTransfer;\n        if (isInternal) {\n            switch (dragOperation) {\n                case \"move\":\n                    if (range.contains(dragCursor.row, dragCursor.column)) {\n                        // clear selection\n                        range = {\n                            start: dragCursor,\n                            end: dragCursor\n                        };\n                    } else {\n                        // move text\n                        range = editor.moveText(range, dragCursor);\n                    }\n                    break;\n                case \"copy\":\n                    // copy text\n                    range = editor.moveText(range, dragCursor, true);\n                    break;\n            }\n        } else {\n            var dropData = dataTransfer.getData('Text');\n            range = {\n                start: dragCursor,\n                end: editor.session.insert(dragCursor, dropData)\n            };\n            editor.focus();\n            dragOperation = null;\n        }\n        clearDragMarker();\n        return event.preventDefault(e);\n    };\n\n    event.addListener(mouseTarget, \"dragstart\", this.onDragStart.bind(mouseHandler), editor);\n    event.addListener(mouseTarget, \"dragend\", this.onDragEnd.bind(mouseHandler), editor);\n    event.addListener(mouseTarget, \"dragenter\", this.onDragEnter.bind(mouseHandler), editor);\n    event.addListener(mouseTarget, \"dragover\", this.onDragOver.bind(mouseHandler), editor);\n    event.addListener(mouseTarget, \"dragleave\", this.onDragLeave.bind(mouseHandler), editor);\n    event.addListener(mouseTarget, \"drop\", this.onDrop.bind(mouseHandler), editor);\n\n    function scrollCursorIntoView(cursor, prevCursor) {\n        var now = Date.now();\n        var vMovement = !prevCursor || cursor.row != prevCursor.row;\n        var hMovement = !prevCursor || cursor.column != prevCursor.column;\n        if (!cursorMovedTime || vMovement || hMovement) {\n            editor.moveCursorToPosition(cursor);\n            cursorMovedTime = now;\n            cursorPointOnCaretMoved = {x: x, y: y};\n        } else {\n            var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);\n            if (distance > SCROLL_CURSOR_HYSTERESIS) {\n                cursorMovedTime = null;\n            } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {\n                editor.renderer.scrollCursorIntoView();\n                cursorMovedTime = null;\n            }\n        }\n    }\n\n    function autoScroll(cursor, prevCursor) {\n        var now = Date.now();\n        var lineHeight = editor.renderer.layerConfig.lineHeight;\n        var characterWidth = editor.renderer.layerConfig.characterWidth;\n        var editorRect = editor.renderer.scroller.getBoundingClientRect();\n        var offsets = {\n           x: {\n               left: x - editorRect.left,\n               right: editorRect.right - x\n           },\n           y: {\n               top: y - editorRect.top,\n               bottom: editorRect.bottom - y\n           }\n        };\n        var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);\n        var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);\n        var scrollCursor = {row: cursor.row, column: cursor.column};\n        if (nearestXOffset / characterWidth <= 2) {\n            scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);\n        }\n        if (nearestYOffset / lineHeight <= 1) {\n            scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);\n        }\n        var vScroll = cursor.row != scrollCursor.row;\n        var hScroll = cursor.column != scrollCursor.column;\n        var vMovement = !prevCursor || cursor.row != prevCursor.row;\n        if (vScroll || (hScroll && !vMovement)) {\n            if (!autoScrollStartTime)\n                autoScrollStartTime = now;\n            else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)\n                editor.renderer.scrollCursorIntoView(scrollCursor);\n        } else {\n            autoScrollStartTime = null;\n        }\n    }\n\n    function onDragInterval() {\n        var prevCursor = dragCursor;\n        dragCursor = editor.renderer.screenToTextCoordinates(x, y);\n        scrollCursorIntoView(dragCursor, prevCursor);\n        autoScroll(dragCursor, prevCursor);\n    }\n\n    function addDragMarker() {\n        range = editor.selection.toOrientedRange();\n        dragSelectionMarker = editor.session.addMarker(range, \"ace_selection\", editor.getSelectionStyle());\n        editor.clearSelection();\n        if (editor.isFocused())\n            editor.renderer.$cursorLayer.setBlinking(false);\n        clearInterval(timerId);\n        onDragInterval();\n        timerId = setInterval(onDragInterval, 20);\n        counter = 0;\n        event.addListener(document, \"mousemove\", onMouseMove);\n    }\n\n    function clearDragMarker() {\n        clearInterval(timerId);\n        editor.session.removeMarker(dragSelectionMarker);\n        dragSelectionMarker = null;\n        editor.selection.fromOrientedRange(range);\n        if (editor.isFocused() && !isInternal)\n            editor.$resetCursorStyle();\n        range = null;\n        dragCursor = null;\n        counter = 0;\n        autoScrollStartTime = null;\n        cursorMovedTime = null;\n        event.removeListener(document, \"mousemove\", onMouseMove);\n    }\n\n    // sometimes other code on the page can stop dragleave event leaving editor stuck in the drag state\n    var onMouseMoveTimer = null;\n    function onMouseMove() {\n        if (onMouseMoveTimer == null) {\n            onMouseMoveTimer = setTimeout(function() {\n                if (onMouseMoveTimer != null && dragSelectionMarker)\n                    clearDragMarker();\n            }, 20);\n        }\n    }\n\n    function canAccept(dataTransfer) {\n        var types = dataTransfer.types;\n        return !types || Array.prototype.some.call(types, function(type) {\n            return type == 'text/plain' || type == 'Text';\n        });\n    }\n\n    function getDropEffect(e) {\n        var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];\n        var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];\n\n        var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;\n\n        // IE throws error while dragging from another app\n        var effectAllowed = \"uninitialized\";\n        try {\n            effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();\n        } catch (e) {}\n        var dropEffect = \"none\";\n\n        if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"copy\";\n        else if (moveAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"move\";\n        else if (copyAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"copy\";\n\n        return dropEffect;\n    }\n}\n\n/**\n * @this {MouseHandler}\n */\n(function() {\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.dragWait = function() {\n        var interval = Date.now() - this.mousedownEvent.time;\n        if (interval > this.editor.getDragDelay())\n            this.startDrag();\n    };\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.dragWaitEnd = function() {\n        var target = this.editor.container;\n        target.draggable = false;\n        this.startSelect(this.mousedownEvent.getDocumentPosition());\n        this.selectEnd();\n    };\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.dragReadyEnd = function(e) {\n        this.editor.$resetCursorStyle();\n        this.editor.unsetStyle(\"ace_dragging\");\n        this.editor.renderer.setCursorStyle(\"\");\n        this.dragWaitEnd();\n    };\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.startDrag = function(){\n        this.cancelDrag = false;\n        var editor = this.editor;\n        var target = editor.container;\n        target.draggable = true;\n        editor.renderer.$cursorLayer.setBlinking(false);\n        editor.setStyle(\"ace_dragging\");\n        var cursorStyle = useragent.isWin ? \"default\" : \"move\";\n        editor.renderer.setCursorStyle(cursorStyle);\n        this.setState(\"dragReady\");\n    };\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.onMouseDrag = function(e) {\n        var target = this.editor.container;\n        if (useragent.isIE && this.state == \"dragReady\") {\n            // IE does not handle [draggable] attribute set after mousedown\n            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n            if (distance > 3)\n                // @ts-ignore\n                target.dragDrop();\n        }\n        if (this.state === \"dragWait\") {\n            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n            if (distance > 0) {\n                target.draggable = false;\n                this.startSelect(this.mousedownEvent.getDocumentPosition());\n            }\n        }\n    };\n\n    /**\n     * @this {MouseHandler & this}\n     */\n    this.onMouseDown = function(e) {\n        if (!this.$dragEnabled)\n            return;\n        this.mousedownEvent = e;\n        var editor = this.editor;\n\n        var inSelection = e.inSelection();\n        var button = e.getButton();\n        var clickCount = e.domEvent.detail || 1;\n        if (clickCount === 1 && button === 0 && inSelection) {\n            if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))\n                return;\n            this.mousedownEvent.time = Date.now();\n            var eventTarget = e.domEvent.target || e.domEvent.srcElement;\n            if (\"unselectable\" in eventTarget)\n                eventTarget.unselectable = \"on\";\n            if (editor.getDragDelay()) {\n                // https://code.google.com/p/chromium/issues/detail?id=286700\n                if (useragent.isWebKit) {\n                    this.cancelDrag = true;\n                    var mouseTarget = editor.container;\n                    mouseTarget.draggable = true;\n                }\n                this.setState(\"dragWait\");\n            } else {\n                this.startDrag();\n            }\n            this.captureMouse(e, this.onMouseDrag.bind(this));\n            // TODO: a better way to prevent default handler without preventing browser default action\n            e.defaultPrevented = true;\n        }\n    };\n\n}).call(DragdropHandler.prototype);\n\n\nfunction calcDistance(ax, ay, bx, by) {\n    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n}\n\nexports.DragdropHandler = DragdropHandler;\n"
  },
  {
    "path": "src/mouse/fold_handler.js",
    "content": "\"use strict\";\nvar dom = require(\"../lib/dom\");\n\nclass FoldHandler {\n    constructor(editor) {\n\n        editor.on(\"click\", function(e) {\n            var position = e.getDocumentPosition();\n            var session = editor.session;\n\n            // If the user clicked on a fold, then expand it.\n            var fold = session.getFoldAt(position.row, position.column, 1);\n            if (fold) {\n                if (e.getAccelKey())\n                    session.removeFold(fold);\n                else\n                    session.expandFold(fold);\n\n                e.stop();\n            }\n\n            var target = e.domEvent && e.domEvent.target;\n            if (target && dom.hasCssClass(target, \"ace_inline_button\")) {\n                if (dom.hasCssClass(target, \"ace_toggle_wrap\")) {\n                    session.setOption(\"wrap\", !session.getUseWrapMode());\n                    editor.renderer.scrollCursorIntoView();\n                }\n            }\n        });\n\n        editor.on(\"gutterclick\", function(e) {\n            var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\n\n            if (gutterRegion == \"foldWidgets\") {\n                var row = e.getDocumentPosition().row;\n                var session = editor.session;\n                if (session.foldWidgets && session.foldWidgets[row])\n                    editor.session.onFoldWidgetClick(row, e);\n                if (!editor.isFocused())\n                    editor.focus();\n                e.stop();\n            }\n        });\n\n        editor.on(\"gutterdblclick\", function(e) {\n            var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\n\n            if (gutterRegion == \"foldWidgets\") {\n                var row = e.getDocumentPosition().row;\n                var session = editor.session;\n                var data = session.getParentFoldRangeData(row, true);\n                var range = data.range || data.firstRange;\n\n                if (range) {\n                    row = range.start.row;\n                    var fold = session.getFoldAt(row, session.getLine(row).length, 1);\n\n                    if (fold) {\n                        session.removeFold(fold);\n                    } else {\n                        session.addFold(\"...\", range);\n                        editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});\n                    }\n                }\n                e.stop();\n            }\n        });\n    }\n}\n\nexports.FoldHandler = FoldHandler;\n"
  },
  {
    "path": "src/mouse/mouse_event.js",
    "content": "\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\n\n/*\n * Custom Ace mouse event\n */\nclass MouseEvent {\n    constructor(domEvent, editor) {\n        /** @type {number} */this.speed;\n        /** @type {number} */this.wheelX;\n        /** @type {number} */this.wheelY;\n        this.domEvent = domEvent;\n        this.editor = editor;\n\n        this.x = this.clientX = domEvent.clientX;\n        this.y = this.clientY = domEvent.clientY;\n\n        this.$pos = null;\n        this.$inSelection = null;\n\n        this.propagationStopped = false;\n        this.defaultPrevented = false;\n    }\n    \n    stopPropagation() {\n        event.stopPropagation(this.domEvent);\n        this.propagationStopped = true;\n    }\n    \n    preventDefault() {\n        event.preventDefault(this.domEvent);\n        this.defaultPrevented = true;\n    }\n    \n    stop() {\n        this.stopPropagation();\n        this.preventDefault();\n    }\n\n    /**\n     * Get the document position below the mouse cursor\n     * \n     * @return {Object} 'row' and 'column' of the document position\n     */\n    getDocumentPosition() {\n        if (this.$pos)\n            return this.$pos;\n        \n        this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);\n        return this.$pos;\n    }\n\n    /**\n     * Get the relative position within the gutter.\n     * \n     * @return {Number} 'row' within the gutter. \n     */\n    getGutterRow() {\n        var documentRow = this.getDocumentPosition().row;\n        var screenRow = this.editor.session.documentToScreenRow(documentRow, 0);\n        var screenTopRow = this.editor.session.documentToScreenRow(this.editor.renderer.$gutterLayer.$lines.get(0).row, 0);\n        return screenRow - screenTopRow;\n    }\n    \n    /**\n     * Check if the mouse cursor is inside of the text selection\n     * \n     * @return {Boolean} whether the mouse cursor is inside of the selection\n     */\n    inSelection() {\n        if (this.$inSelection !== null)\n            return this.$inSelection;\n            \n        var editor = this.editor;\n        \n\n        var selectionRange = editor.getSelectionRange();\n        if (selectionRange.isEmpty())\n            this.$inSelection = false;\n        else {\n            var pos = this.getDocumentPosition();\n            this.$inSelection = selectionRange.contains(pos.row, pos.column);\n        }\n\n        return this.$inSelection;\n    }\n    \n    /**\n     * Get the clicked mouse button\n     * \n     * @return {Number} 0 for left button, 1 for middle button, 2 for right button\n     */\n    getButton() {\n        return event.getButton(this.domEvent);\n    }\n    \n    /**\n     * @return {Boolean} whether the shift key was pressed when the event was emitted\n     */\n    getShiftKey() {\n        return this.domEvent.shiftKey;\n    }\n\n    getAccelKey() {\n        return useragent.isMac ? this.domEvent.metaKey : this.domEvent.ctrlKey;\n    }\n}\n\nexports.MouseEvent = MouseEvent;\n"
  },
  {
    "path": "src/mouse/mouse_handler.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"../editor\").Editor} Editor\n */\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar DefaultHandlers = require(\"./default_handlers\").DefaultHandlers;\nvar DefaultGutterHandler = require(\"./default_gutter_handler\").GutterHandler;\nvar MouseEvent = require(\"./mouse_event\").MouseEvent;\nvar DragdropHandler = require(\"./dragdrop_handler\").DragdropHandler;\nvar addTouchListeners = require(\"./touch_handler\").addTouchListeners;\nvar config = require(\"../config\");\n\nclass MouseHandler {\n    /**\n     * @param {Editor} editor\n     */\n    constructor(editor) {\n        /** @type {boolean} */this.$dragDelay;\n        /** @type {boolean} */this.$dragEnabled;\n        /** @type {boolean} */this.$mouseMoved;\n        /** @type {MouseEvent} */this.mouseEvent;\n        /** @type {number} */this.$focusTimeout;\n        var _self = this;\n        this.editor = editor;\n\n        new DefaultHandlers(this);\n        new DefaultGutterHandler(this);\n        new DragdropHandler(this);\n\n        var focusEditor = function(e) {\n            // because we have to call event.preventDefault() any window on ie and iframes\n            // on other browsers do not get focus, so we have to call window.focus() here\n            var windowBlurred = !document.hasFocus || !document.hasFocus()\n                || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());\n            if (windowBlurred)\n                window.focus();\n            editor.focus();\n            // Without this editor is blurred after double click\n            setTimeout(function () {\n                if (!editor.isFocused()) editor.focus();\n            });\n        };\n\n        var mouseTarget = editor.renderer.getMouseEventTarget();\n        event.addListener(mouseTarget, \"click\", this.onMouseEvent.bind(this, \"click\"), editor);\n        event.addListener(mouseTarget, \"mousemove\", this.onMouseMove.bind(this, \"mousemove\"), editor);\n        event.addMultiMouseDownListener([\n            mouseTarget,\n            editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner,\n            editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner,\n            editor.textInput && editor.textInput.getElement()\n        ].filter(Boolean), [400, 300, 250], this, \"onMouseEvent\", editor);\n        event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, \"mousewheel\"), editor);\n        addTouchListeners(editor.container, editor);\n\n        var gutterEl = editor.renderer.$gutter;\n        event.addListener(gutterEl, \"mousedown\", this.onMouseEvent.bind(this, \"guttermousedown\"), editor);\n        event.addListener(gutterEl, \"click\", this.onMouseEvent.bind(this, \"gutterclick\"), editor);\n        event.addListener(gutterEl, \"dblclick\", this.onMouseEvent.bind(this, \"gutterdblclick\"), editor);\n        event.addListener(gutterEl, \"mousemove\", this.onMouseEvent.bind(this, \"guttermousemove\"), editor);\n\n        event.addListener(mouseTarget, \"mousedown\", focusEditor, editor);\n        event.addListener(gutterEl, \"mousedown\", focusEditor, editor);\n        if (useragent.isIE && editor.renderer.scrollBarV) {\n            event.addListener(editor.renderer.scrollBarV.element, \"mousedown\", focusEditor, editor);\n            event.addListener(editor.renderer.scrollBarH.element, \"mousedown\", focusEditor, editor);\n        }\n\n        editor.on(\"mousemove\", function(e){\n            if (_self.state || _self.$dragDelay || !_self.$dragEnabled)\n                return;\n\n            var character = editor.renderer.screenToTextCoordinates(e.x, e.y);\n            var range = editor.session.selection.getRange();\n            var renderer = editor.renderer;\n\n            if (!range.isEmpty() && range.insideStart(character.row, character.column)) {\n                renderer.setCursorStyle(\"default\");\n            } else {\n                renderer.setCursorStyle(\"\");\n            }\n\n        }, //@ts-expect-error TODO: seems mistyping - should be boolean\n            editor);\n    }\n\n    onMouseEvent(name, e) {\n        if (!this.editor.session) return;\n        this.editor._emit(name, new MouseEvent(e, this.editor));\n    }\n\n    onMouseMove(name, e) {\n        // optimization, because mousemove doesn't have a default handler.\n        var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;\n        if (!listeners || !listeners.length)\n            return;\n\n        this.editor._emit(name, new MouseEvent(e, this.editor));\n    }\n\n    /**\n     * @param {any} name\n     * @param {{ wheelX: number; wheelY: number; }} e\n     */\n    onMouseWheel(name, e) {\n        var mouseEvent = new MouseEvent(e, this.editor);\n        //@ts-expect-error TODO: couldn't find this property init in the ace codebase\n        mouseEvent.speed = this.$scrollSpeed * 2;\n        mouseEvent.wheelX = e.wheelX;\n        mouseEvent.wheelY = e.wheelY;\n\n        this.editor._emit(name, mouseEvent);\n    }\n\n    setState(state) {\n        this.state = state;\n    }\n\n    /**\n     *\n     * @param {MouseEvent} ev\n     * @param [mouseMoveHandler]\n     * @return {ReturnType<typeof setTimeout> | undefined}\n     */\n    captureMouse(ev, mouseMoveHandler) {\n        this.x = ev.x;\n        this.y = ev.y;\n\n        this.isMousePressed = true;\n\n        // do not move textarea during selection\n        var editor = this.editor;\n        var renderer = this.editor.renderer;\n        renderer.$isMousePressed = true;\n\n        var self = this;\n        var continueCapture = true;\n\n        var onMouseMove = function(e) {\n            if (!e) return;\n            // if editor is loaded inside iframe, and mouseup event is outside\n            // we won't recieve it, so we cancel on first mousemove without button\n            if (useragent.isWebKit && !e.which && self.releaseMouse)\n                return self.releaseMouse();\n\n            self.x = e.clientX;\n            self.y = e.clientY;\n            mouseMoveHandler && mouseMoveHandler(e);\n            self.mouseEvent = new MouseEvent(e, self.editor);\n            self.$mouseMoved = true;\n        };\n\n        var onCaptureEnd = function(e) {\n            editor.off(\"beforeEndOperation\", onOperationEnd);\n            continueCapture = false;\n            if (editor.session) onCaptureUpdate();\n            self[self.state + \"End\"] && self[self.state + \"End\"](e);\n            self.state = \"\";\n            self.isMousePressed = renderer.$isMousePressed = false;\n            if (renderer.$keepTextAreaAtCursor)\n                renderer.$moveTextAreaToCursor();\n            self.$onCaptureMouseMove = self.releaseMouse = null;\n            e && self.onMouseEvent(\"mouseup\", e);\n            editor.endOperation();\n        };\n\n        var onCaptureUpdate = function() {\n            self[self.state] && self[self.state]();\n            self.$mouseMoved = false;\n        };\n\n        var onCaptureInterval = function() {\n            if (continueCapture) {\n                onCaptureUpdate();\n                event.nextFrame(onCaptureInterval);\n            }\n        };\n\n        if (useragent.isOldIE && ev.domEvent.type == \"dblclick\") {\n            return setTimeout(function() {onCaptureEnd(ev);});\n        }\n\n        var onOperationEnd = function(e) {\n            if (!self.releaseMouse) return;\n            // some touchpads fire mouseup event after a slight delay,\n            // which can cause problems if user presses a keyboard shortcut quickly\n            if (editor.curOp.command.name && editor.curOp.selectionChanged) {\n                self[self.state + \"End\"] && self[self.state + \"End\"]();\n                self.state = \"\";\n                self.releaseMouse();\n            }\n        };\n\n        editor.on(\"beforeEndOperation\", onOperationEnd);\n        editor.startOperation({command: {name: \"mouse\"}});\n\n        self.$onCaptureMouseMove = onMouseMove;\n        self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);\n\n        onCaptureInterval();\n    }\n    cancelContextMenu() {\n        var stop = function(e) {\n            if (e && e.domEvent && e.domEvent.type != \"contextmenu\")\n                return;\n            this.editor.off(\"nativecontextmenu\", stop);\n            if (e && e.domEvent)\n                event.stopEvent(e.domEvent);\n        }.bind(this);\n        setTimeout(stop, 10);\n        this.editor.on(\"nativecontextmenu\", stop);\n    }\n    destroy() {\n        if (this.releaseMouse) this.releaseMouse();\n        if (this.$tooltip) this.$tooltip.destroy();\n    }\n}\n\nMouseHandler.prototype.releaseMouse = null;\n\nconfig.defineOptions(MouseHandler.prototype, \"mouseHandler\", {\n    scrollSpeed: {initialValue: 2},\n    dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},\n    dragEnabled: {initialValue: true},\n    focusTimeout: {initialValue: 0},\n});\n\n\nexports.MouseHandler = MouseHandler;\n"
  },
  {
    "path": "src/mouse/mouse_handler_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"../test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"../multi_select\");\nrequire(\"../theme/textmate\");\nvar Editor = require(\"../editor\").Editor;\nvar Mode = require(\"../mode/java\").Mode;\nvar VirtualRenderer = require(\"../virtual_renderer\").VirtualRenderer;\nvar assert = require(\"../test/assertions\");\nvar lang = require(\"../lib/lang\");\nvar MouseEvent = function(type, opts){\n    var e = document.createEvent(\"MouseEvents\");\n    e.initMouseEvent(/click|wheel/.test(type) ? type : \"mouse\" + type,\n        true, true, window,\n        opts.detail,\n        opts.x, opts.y, opts.x, opts.y,\n        opts.ctrl, opts.alt, opts.shift, opts.meta,\n        opts.button || 0, opts.relatedTarget);\n    return e;\n};\nvar WheelEvent = function(opts) {\n    var e = new MouseEvent(\"wheel\", opts);\n    e.DOM_DELTA_PIXEL = 0;\n    e.DOM_DELTA_LINE = 1;\n    e.DOM_DELTA_PAGE = 2;\n    e.deltaMode = e[\"DOM_DELTA_\" + opts.mode.toUpperCase()];\n    e.deltaX = opts.x || 0;\n    e.deltaY = opts.y || 0;\n    return e;\n};\n\nfunction sendTouchEvent(type, opts, editor) {\n    var e = new window.CustomEvent(\"touch\" + type, {bubbles: true, cancelable: true});\n    Object.defineProperties(e, Object.getOwnPropertyDescriptors(opts));\n    editor.container.dispatchEvent(e);\n}\n\nfunction touchPos(row, column) {\n    var pos = editor.renderer.textToScreenCoordinates(row, column);\n    var h = editor.renderer.lineHeight / 2;\n    return {clientX: pos.pageX, clientY: pos.pageY + h};\n}\n\nvar editor;\n\nmodule.exports = {\n\n    setUp : function() {\n        this.editor = new Editor(new VirtualRenderer());\n        this.editor.session.setValue(\"Juhu kinners!\");\n        this.editor.container.style.position = \"absolute\";\n        this.editor.container.style.height = \"500px\";\n        this.editor.container.style.width = \"500px\";\n        this.editor.container.style.left = \"50px\";\n        this.editor.container.style.top = \"10px\";\n        document.body.appendChild(this.editor.container);\n        editor = this.editor;\n    },\n\n    \"test: double tap. issue #956\" : function() {\n        // mouse up fired immediately after mouse down\n        this.editor.resize(true);\n        var pos = this.editor.renderer.textToScreenCoordinates(0, 1);\n        var target = this.editor.renderer.getMouseEventTarget();\n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY}));\n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY, detail: 2}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY, detail: 2}));\n        \n        assert.equal(this.editor.getSelectedText(), \"Juhu\");\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY}));\n        assert.equal(this.editor.getSelectedText(), \"\");\n    },\n    \"test: multiselect\" : function() {\n        var target = this.editor.renderer.getMouseEventTarget();\n        this.editor.session.setValue(\"xyz\\n\\nabc efg\");\n        this.editor.resize(true);\n        \n        var pos = this.editor.renderer.textToScreenCoordinates(0, 1);\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY}));\n        \n        pos = this.editor.renderer.textToScreenCoordinates(0, 2);\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY, ctrl: true}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY}));\n        \n        var selection = \"Range: [0/2] -> [0/2],Range: [0/1] -> [0/1]\";\n        assert.equal(this.editor.selection.toJSON() + \"\", selection);\n        \n        pos = this.editor.renderer.textToScreenCoordinates(2, 2);\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY, detail: 2, ctrl: true}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY, detail: 2, ctrl: true}));\n        \n        selection = \"Range: [2/0] -> [2/3],\" + selection;\n        assert.equal(this.editor.selection.toJSON() + \"\", selection);\n        \n        var pos = this.editor.renderer.textToScreenCoordinates(0, 1);\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos.pageX, y: pos.pageY, ctrl: true}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos.pageX, y: pos.pageY, ctrl: true}));\n        selection = selection.split(\",\").slice(0, -1).join(\",\");\n        assert.equal(this.editor.selection.toJSON() + \"\", selection);\n        \n        var pos1 = this.editor.renderer.textToScreenCoordinates(0, 2);\n        var pos2 = this.editor.renderer.textToScreenCoordinates(2, 2);\n        \n        target.dispatchEvent(MouseEvent(\"down\", {x: pos1.pageX, y: pos1.pageY, alt: true}));\n        target.dispatchEvent(MouseEvent(\"move\", {x: pos2.pageX, y: pos2.pageY + 1, alt: true}));\n        target.dispatchEvent(MouseEvent(\"up\", {x: pos2.pageX, y: pos2.pageY + 1, alt: true}));\n        assert.equal(this.editor.selection.toJSON() + \"\", \"Range: [2/2] -> [2/2],Range: [1/0] -> [1/0],Range: [0/2] -> [0/2]\");\n    },\n    \"test: gutter\" : function() {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n\".repeat(50) + \"}\";\n        value = value.repeat(50);\n        editor.session.setMode(new Mode());\n        editor.setValue(value, -1);\n        editor.renderer.$loop._flush();\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var toggler = lines.cells[0].element.childNodes[1];\n        var rect = toggler.getBoundingClientRect();\n        if (!rect.left) rect.left = 100; // for mockdom\n        toggler.dispatchEvent(MouseEvent(\"down\", {x: rect.left, y: rect.top}));\n        toggler.dispatchEvent(MouseEvent(\"up\", {x: rect.left, y: rect.top}));\n        toggler.dispatchEvent(MouseEvent(\"click\", {x: rect.left, y: rect.top}));\n        editor.renderer.$loop._flush();\n        \n        assert.ok(/ace_gutter-active-line/.test(lines.cells[0].element.className));\n        assert.ok(/ace_closed/.test(toggler.className));\n        editor.execCommand(\"golinedown\");\n        editor.renderer.$loop._flush();\n        assert.notOk(/ace_gutter-active-line/.test(lines.cells[0].element.className));\n        assert.ok(/ace_gutter-active-line/.test(lines.cells[1].element.className));\n        assert.equal(lines.cells[1].element.textContent, \"51\");\n        \n        // wheel event on toggler\n        var e = WheelEvent({mode: \"pixel\", y: 100});\n        toggler.dispatchEvent(e);\n        editor.renderer.$loop._flush();\n        assert.ok(parseInt(lines.cells[0].element.textContent) > 1);\n    },\n    \"test: gutter click on wrapped line\" : function() {\n        var editor = this.editor;\n        var value = \"x {\\n\" + \"  abc\".repeat(100) + \"\\n}\";\n        value = value.repeat(10);\n        editor.setValue(value, -1);\n        editor.setOption(\"wrap\", 40);\n        editor.renderer.$loop._flush();\n        var lines = editor.renderer.$gutterLayer.$lines;\n        var toggler = lines.cells[1].element;\n        var rect = toggler.getBoundingClientRect();\n        editor.isFocused = () => true;\n        editor.focus();\n        \n        assert.position(editor.getCursorPosition(), 0, 0);\n\n        toggler.dispatchEvent(MouseEvent(\"down\", {x: rect.left, y: rect.top + rect.height / 2}));\n        editor.renderer.$loop._flush();         \n        assert.position(editor.getCursorPosition(), 1, 0);\n\n        toggler.dispatchEvent(MouseEvent(\"up\", {x: rect.left, y: rect.top + rect.height}));\n        editor.renderer.$loop._flush();\n        assert.position(editor.getCursorPosition(), 2, 0);\n    },\n    \"test: wheel\" : function() {\n        var editor = this.editor;\n        var lines = editor.renderer.$gutterLayer.$lines;\n        editor.setValue(\"\\n\".repeat(100), -1);\n        editor.renderer.$loop._flush();\n\n        assert.ok(parseInt(lines.cells[0].element.textContent) == 1);\n        \n        var e = WheelEvent({mode: \"line\", y: 2});\n        editor.container.dispatchEvent(e);\n        editor.renderer.$loop._flush();\n        assert.ok(parseInt(lines.cells[0].element.textContent) > 1);\n        \n        e = WheelEvent({mode: \"line\", y: -2});\n        editor.container.dispatchEvent(e);\n        editor.renderer.$loop._flush();\n        assert.ok(parseInt(lines.cells[0].element.textContent) == 1);\n        \n        e = WheelEvent({mode: \"page\", y: 1});\n        editor.container.dispatchEvent(e);\n        editor.renderer.$loop._flush();\n        assert.ok(parseInt(lines.cells[0].element.textContent) > 10);\n    },\n    \n    \"test: touch\" : async function(done) {\n        var editor = this.editor;\n        var value = \"x {\" + \"\\n  abc\".repeat(10) + \"\\n}\";\n        value = value.repeat(10);\n        editor.setValue(value, -1);\n        editor.setOption(\"maxLines\", 10);\n        editor.setOption(\"enableMobileMenu\", false);\n        editor.renderer.$loop._flush();\n        window.editor = editor;\n        window.sendTouchEvent = sendTouchEvent;\n        \n        // single tap moves cursor\n        sendTouchEvent(\"start\", {touches: [touchPos(2, 1)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(2, 1)]}, editor);\n        editor.renderer.$loop._flush();\n        assert.position(editor.getCursorPosition(), 2, 1);\n        \n        // two finger tap allows to zoom\n        sendTouchEvent(\"start\", {touches: [touchPos(5, 5), touchPos(6, 6)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(5, 5)]}, editor);\n        editor.renderer.$loop._flush();\n        assert.position(editor.getCursorPosition(), 2, 1);\n        \n        // tap and drag near cursor selects\n        sendTouchEvent(\"start\", {touches: [touchPos(2, 1)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(2, 3)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(2, 4)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(2, 3)]}, editor);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.getSelectedText(), \" ab\");\n        \n        // double tap selects the word\n        sendTouchEvent(\"start\", {touches: [touchPos(3, 3)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(3, 3)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(3, 3)]}, editor);\n        sendTouchEvent(\"start\", {touches: [touchPos(3, 3)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(3, 3)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(3, 3)]}, editor);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.getSelectedText(), \"abc\");\n        \n        // there shouldn't be any mobile menu at that point\n        var menu = editor.container.querySelector(\".ace_mobile-menu\");\n        assert.ok(menu == undefined);\n        editor.setOption(\"enableMobileMenu\", true);\n        sendTouchEvent(\"end\", {touches: [touchPos(3, 3)]}, editor);\n        editor.renderer.$loop._flush();\n        \n        menu = editor.container.querySelector(\".ace_mobile-menu\");\n        assert.ok(menu != undefined);\n        \n        // mobile menu works\n        sendTouchEvent(\"start\", {touches: [touchPos(3, 3)]}, {container: menu});\n        sendTouchEvent(\"end\", {touches: [touchPos(3, 3)]}, {container: menu});\n        var button = editor.container.querySelectorAll(\".ace_mobile-button\")[1];\n        sendTouchEvent(\"start\", {touches: [touchPos(3, 3)]}, {container: button});\n        sendTouchEvent(\"end\", {touches: [touchPos(3, 3)]}, {container: button});\n        assert.equal(editor.getSelectedText(), \"\");\n        \n        // tap and drag in other places scrolls\n        sendTouchEvent(\"start\", {touches: [touchPos(8, 3)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(8, 3)]}, editor);\n\n        await lang.sleep(2);\n        sendTouchEvent(\"move\", {touches: [touchPos(1, 3)]}, editor);\n        sendTouchEvent(\"end\", {touches: [touchPos(1, 3)]}, editor);\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.getFirstFullyVisibleRow(), 7);\n\n        // editor animates scrolling\n        await lang.sleep(50);\n        assert.notOk(menu.clientHeight);\n        assert.ok(editor.renderer.getFirstFullyVisibleRow() > 7);\n        done();\n    },\n    \n    \"test: touch selection with scrollMargin\" : function() {\n        editor.renderer.setScrollMargin(50, 50, 0, 15);\n        editor.setValue(\"Juhu Kinners!\");\n        editor.renderer.$loop._flush();\n        \n        var pos = editor.renderer.textToScreenCoordinates(0, 0);\n        \n        assert.equal(pos.pageY - editor.container.getBoundingClientRect().top, 50);\n        \n        sendTouchEvent(\"start\", {touches: [touchPos(0, 0)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(0, 5)]}, editor);\n        editor.renderer.$loop._flush();\n        sendTouchEvent(\"end\", {touches: [touchPos(0, 5)]}, editor);\n        editor.renderer.$loop._flush();\n        \n        sendTouchEvent(\"start\", {touches: [touchPos(0, 12)]}, editor);\n        sendTouchEvent(\"move\", {touches: [touchPos(0, 8)]}, editor);\n        editor.renderer.$loop._flush();\n        sendTouchEvent(\"end\", {touches: [touchPos(0, 8)]}, editor);\n        \n        assert.equal(editor.getSelectedText(), \"Kin\");\n    },\n    \n    \"test: destroy while mouse is pressed\": function() {\n        assert.ok(!this.editor.$mouseHandler.releaseMouse);\n        var target = this.editor.renderer.getMouseEventTarget();\n        target.dispatchEvent(MouseEvent(\"down\", {x: 0, y: 0}));\n        assert.ok(this.editor.$mouseHandler.releaseMouse);\n        this.editor.destroy();\n        assert.ok(!this.editor.$mouseHandler.releaseMouse);\n    },\n    tearDown : function() {\n        this.editor.destroy();\n        document.body.removeChild(this.editor.container);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/mouse/multi_select_handler.js",
    "content": "var event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\n\n// mouse\nfunction isSamePoint(p1, p2) {\n    return p1.row == p2.row && p1.column == p2.column;\n}\n\nfunction onMouseDown(e) {\n    var ev = e.domEvent;\n    var alt = ev.altKey;\n    var shift = ev.shiftKey;\n    var ctrl = ev.ctrlKey;\n    var accel = e.getAccelKey();\n    var button = e.getButton();\n    \n    if (ctrl && useragent.isMac)\n        button = ev.button;\n\n    if (e.editor.inMultiSelectMode && button == 2) {\n        e.editor.textInput.onContextMenu(e.domEvent);\n        return;\n    }\n    \n    if (!ctrl && !alt && !accel) {\n        if (button === 0 && e.editor.inMultiSelectMode)\n            e.editor.exitMultiSelectMode();\n        return;\n    }\n    \n    if (button !== 0)\n        return;\n\n    var editor = e.editor;\n    var selection = editor.selection;\n    var isMultiSelect = editor.inMultiSelectMode;\n    var pos = e.getDocumentPosition();\n    var cursor = selection.getCursor();\n    var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));\n\n    var mouseX = e.x, mouseY = e.y;\n    var onMouseSelection = function(e) {\n        mouseX = e.clientX;\n        mouseY = e.clientY;\n    };\n    \n    var session = editor.session;\n    var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);\n    var screenCursor = screenAnchor;\n    \n    var selectionMode;\n    if (editor.$mouseHandler.$enableJumpToDef) {\n        if (ctrl && alt || accel && alt)\n            selectionMode = shift ? \"block\" : \"add\";\n        else if (alt && editor.$blockSelectEnabled)\n            selectionMode = \"block\";\n    } else {\n        if (accel && !alt) {\n            selectionMode = \"add\";\n            if (!isMultiSelect && shift)\n                return;\n        } else if (alt && editor.$blockSelectEnabled) {\n            selectionMode = \"block\";\n        }\n    }\n    \n    if (selectionMode && useragent.isMac && ev.ctrlKey) {\n        editor.$mouseHandler.cancelContextMenu();\n    }\n\n    if (selectionMode == \"add\") {\n        if (!isMultiSelect && inSelection)\n            return; // dragging\n\n        if (!isMultiSelect) {\n            var range = selection.toOrientedRange();\n            editor.addSelectionMarker(range);\n        }\n\n        var oldRange = selection.rangeList.rangeAtPoint(pos);\n        \n        editor.inVirtualSelectionMode = true;\n        \n        if (shift) {\n            oldRange = null;\n            range = selection.ranges[0] || range;\n            editor.removeSelectionMarker(range);\n        }\n        editor.once(\"mouseup\", function() {\n            var tmpSel = selection.toOrientedRange();\n\n            if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))\n                selection.substractPoint(tmpSel.cursor);\n            else {\n                if (shift) {\n                    selection.substractPoint(range.cursor);\n                } else if (range) {\n                    editor.removeSelectionMarker(range);\n                    selection.addRange(range);\n                }\n                selection.addRange(tmpSel);\n            }\n            editor.inVirtualSelectionMode = false;\n        });\n\n    } else if (selectionMode == \"block\") {\n        e.stop();\n        editor.inVirtualSelectionMode = true;        \n        var initialRange;\n        var rectSel = [];\n        var blockSelect = function() {\n            var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);\n            var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX);\n\n            if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))\n                return;\n            screenCursor = newCursor;\n            \n            editor.selection.moveToPosition(cursor);\n            editor.renderer.scrollCursorIntoView();\n\n            editor.removeSelectionMarkers(rectSel);\n            rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);\n            if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())\n                rectSel[0] = editor.$mouseHandler.$clickSelection.clone();\n            rectSel.forEach(editor.addSelectionMarker, editor);\n            editor.updateSelectionMarkers();\n        };\n        if (isMultiSelect && !accel) {\n            selection.toSingleRange();\n        } else if (!isMultiSelect && accel) {\n            initialRange = selection.toOrientedRange();\n            editor.addSelectionMarker(initialRange);\n        }\n        \n        if (shift)\n            screenAnchor = session.documentToScreenPosition(selection.lead);            \n        else\n            selection.moveToPosition(pos);\n        \n        screenCursor = {row: -1, column: -1};\n\n        var onMouseSelectionEnd = function(e) {\n            blockSelect();\n            clearInterval(timerId);\n            editor.removeSelectionMarkers(rectSel);\n            if (!rectSel.length)\n                rectSel = [selection.toOrientedRange()];\n            if (initialRange) {\n                editor.removeSelectionMarker(initialRange);\n                selection.toSingleRange(initialRange);\n            }\n            for (var i = 0; i < rectSel.length; i++)\n                selection.addRange(rectSel[i]);\n            editor.inVirtualSelectionMode = false;\n            editor.$mouseHandler.$clickSelection = null;\n        };\n\n        var onSelectionInterval = blockSelect;\n\n        event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);\n        var timerId = setInterval(function() {onSelectionInterval();}, 20);\n\n        return e.preventDefault();\n    }\n}\n\n\nexports.onMouseDown = onMouseDown;\n"
  },
  {
    "path": "src/mouse/touch_handler.js",
    "content": "\"use strict\";\n\nvar MouseEvent = require(\"./mouse_event\").MouseEvent;\nvar event = require(\"../lib/event\");\nvar dom = require(\"../lib/dom\");\n\nexports.addTouchListeners = function(el, editor) {\n    var mode = \"scroll\";\n    var startX;\n    var startY;\n    var touchStartT;\n    var lastT;\n    var longTouchTimer;\n    var animationTimer;\n    var animationSteps = 0;\n    var pos;\n    var clickCount = 0;\n    var vX = 0;\n    var vY = 0;\n    var pressed;\n    var contextMenu;\n    \n    function createContextMenu() {\n        var clipboard = window.navigator && window.navigator.clipboard;\n        var isOpen = false;\n        var updateMenu = function() {\n            var selected = editor.getCopyText();\n            var hasUndo = editor.session.getUndoManager().hasUndo();\n            contextMenu.replaceChild(\n                dom.buildDom(isOpen ? [\"span\",\n                    !selected && canExecuteCommand(\"selectall\") && [\"span\", { class: \"ace_mobile-button\", action: \"selectall\" }, \"Select All\"],\n                    selected && canExecuteCommand(\"copy\") && [\"span\", { class: \"ace_mobile-button\", action: \"copy\" }, \"Copy\"],\n                    selected && canExecuteCommand(\"cut\") && [\"span\", { class: \"ace_mobile-button\", action: \"cut\" }, \"Cut\"],\n                    clipboard && canExecuteCommand(\"paste\") && [\"span\", { class: \"ace_mobile-button\", action: \"paste\" }, \"Paste\"],\n                    hasUndo && canExecuteCommand(\"undo\") && [\"span\", { class: \"ace_mobile-button\", action: \"undo\" }, \"Undo\"],\n                    canExecuteCommand(\"find\") && [\"span\", { class: \"ace_mobile-button\", action: \"find\" }, \"Find\"],\n                    canExecuteCommand(\"openCommandPalette\") && [\"span\", { class: \"ace_mobile-button\", action: \"openCommandPalette\" }, \"Palette\"]\n                ] : [\"span\"]),\n                contextMenu.firstChild\n            );\n        };\n        \n        var canExecuteCommand = function (/** @type {string} */ cmd) {\n            return editor.commands.canExecute(cmd, editor);\n        };\n        \n        var handleClick = function(e) {\n            var action = e.target.getAttribute(\"action\");\n\n            if (action == \"more\" || !isOpen) {\n                isOpen = !isOpen;\n                return updateMenu();\n            }\n            if (action == \"paste\") {\n                clipboard.readText().then(function (text) {\n                    editor.execCommand(action, text);\n                });\n            }\n            else if (action) {\n                if (action == \"cut\" || action == \"copy\") {\n                    if (clipboard)\n                        clipboard.writeText(editor.getCopyText());\n                    else\n                        document.execCommand(\"copy\");\n                }\n                editor.execCommand(action);\n            }\n            contextMenu.firstChild.style.display = \"none\";\n            isOpen = false;\n            if (action != \"openCommandPalette\")\n                editor.focus();\n        };\n        contextMenu = dom.buildDom([\"div\",\n            {\n                class: \"ace_mobile-menu\",\n                onclick: handleClick\n            },\n            [\"span\"],\n            [\"span\", { class: \"ace_mobile-button\", action: \"more\" }, \"...\"]\n        ], editor.container);\n        contextMenu.addEventListener(\"touchstart\", function(e) {\n            mode = \"menu\";\n            e.stopPropagation();\n            e.preventDefault();\n            editor.textInput.focus();\n        });\n        contextMenu.addEventListener(\"touchend\", function(e) {\n            e.stopPropagation();\n            e.preventDefault();\n            handleClick(e);\n        });\n    }\n    function showContextMenu() {\n        if (!editor.getOption(\"enableMobileMenu\")) {\n            if (contextMenu) {\n                hideContextMenu();\n            }\n            return;\n        }\n        if (!contextMenu) createContextMenu();\n        var cursor = editor.selection.cursor;\n        var pagePos = editor.renderer.textToScreenCoordinates(cursor.row, cursor.column);\n        var leftOffset = editor.renderer.textToScreenCoordinates(0, 0).pageX;\n        var scrollLeft = editor.renderer.scrollLeft;\n        var rect = editor.container.getBoundingClientRect();\n        contextMenu.style.top = pagePos.pageY - rect.top - 3 + \"px\";\n        if (pagePos.pageX - rect.left < rect.width - 70) {\n            contextMenu.style.left = \"\";\n            contextMenu.style.right = \"10px\";\n        } else {\n            contextMenu.style.right = \"\";\n            contextMenu.style.left = leftOffset + scrollLeft - rect.left + \"px\";\n        }\n        contextMenu.style.display = \"\";\n        contextMenu.firstChild.style.display = \"none\";\n        editor.on(\"input\", hideContextMenu);\n    }\n    function hideContextMenu(e) {\n        if (contextMenu)\n            contextMenu.style.display = \"none\";\n        editor.off(\"input\", hideContextMenu);\n    }\n\n    function handleLongTap() {\n        longTouchTimer = null;\n        clearTimeout(longTouchTimer);\n        var range = editor.selection.getRange();\n        var inSelection = range.contains(pos.row, pos.column);\n        if (range.isEmpty() || !inSelection) {\n            editor.selection.moveToPosition(pos);\n            editor.selection.selectWord();\n        }\n        mode = \"wait\";\n        showContextMenu();\n    }\n    function switchToSelectionMode() {\n        longTouchTimer = null;\n        clearTimeout(longTouchTimer);\n        editor.selection.moveToPosition(pos);\n        var range = clickCount >= 2\n            ? editor.selection.getLineRange(pos.row)\n            : editor.session.getBracketRange(pos);\n        if (range && !range.isEmpty()) {\n            editor.selection.setRange(range);\n        } else {\n            editor.selection.selectWord();\n        }\n        mode = \"wait\";\n    }\n    event.addListener(el, \"contextmenu\", function(e) {\n        if (!pressed) return;\n        var textarea = editor.textInput.getElement();\n        textarea.focus();\n    }, editor);\n    event.addListener(el, \"touchstart\", function (e) {\n        var touches = e.touches;\n        if (longTouchTimer || touches.length > 1) {\n            clearTimeout(longTouchTimer);\n            longTouchTimer = null;\n            touchStartT = -1;\n            mode = \"zoom\";\n            return;\n        }\n        \n        pressed = editor.$mouseHandler.isMousePressed = true;\n        var h = editor.renderer.layerConfig.lineHeight;\n        var w = editor.renderer.layerConfig.lineHeight;\n        var t = e.timeStamp;\n        lastT = t;\n        var touchObj = touches[0];\n        var x = touchObj.clientX;\n        var y = touchObj.clientY;\n        // reset clickCount if the new touch is far from the old one\n        if (Math.abs(startX - x) + Math.abs(startY - y) > h)\n            touchStartT = -1;\n        \n        startX = e.clientX = x;\n        startY = e.clientY = y;\n        vX = vY = 0;\n        \n        var ev = new MouseEvent(e, editor);\n        pos = ev.getDocumentPosition();\n\n        if (t - touchStartT < 500 && touches.length == 1 && !animationSteps) {\n            clickCount++;\n            e.preventDefault();\n            e.button = 0;\n            switchToSelectionMode();\n        } else {\n            clickCount = 0;\n            var cursor = editor.selection.cursor;\n            var anchor = editor.selection.isEmpty() ? cursor : editor.selection.anchor;\n            \n            var cursorPos = editor.renderer.$cursorLayer.getPixelPosition(cursor, true);\n            var anchorPos = editor.renderer.$cursorLayer.getPixelPosition(anchor, true);\n            var rect = editor.renderer.scroller.getBoundingClientRect();\n            var offsetTop = editor.renderer.layerConfig.offset;\n            var offsetLeft = editor.renderer.scrollLeft;\n            var weightedDistance = function(x, y) {\n                x = x / w;\n                y = y / h - 0.75;\n                return x * x + y * y;\n            };\n            \n            if (e.clientX < rect.left) {\n                mode = \"zoom\";\n                return;\n            }\n            \n            var diff1 = weightedDistance(\n                e.clientX - rect.left - cursorPos.left + offsetLeft,\n                e.clientY - rect.top - cursorPos.top + offsetTop\n            );\n            var diff2 = weightedDistance(\n                e.clientX - rect.left - anchorPos.left + offsetLeft,\n                e.clientY - rect.top - anchorPos.top + offsetTop\n            );\n            if (diff1 < 3.5 && diff2 < 3.5)\n                mode = diff1 > diff2 ? \"cursor\" : \"anchor\";\n                \n            if (diff2 < 3.5)\n                mode = \"anchor\";\n            else if (diff1 < 3.5)\n                mode = \"cursor\";\n            else\n                mode = \"scroll\";\n            longTouchTimer = setTimeout(handleLongTap, 450);\n        }\n        touchStartT = t;\n    }, editor);\n\n    event.addListener(el, \"touchend\", function (e) {\n        pressed = editor.$mouseHandler.isMousePressed = false;\n        if (animationTimer) clearInterval(animationTimer);\n        if (mode == \"zoom\") {\n            mode = \"\";\n            animationSteps = 0;\n        } else if (longTouchTimer) {\n            editor.selection.moveToPosition(pos);\n            animationSteps = 0;\n            showContextMenu();\n        } else if (mode == \"scroll\") {\n            animate();\n            hideContextMenu();\n        } else {\n            showContextMenu();\n        }\n        clearTimeout(longTouchTimer);\n        longTouchTimer = null;\n    }, editor);\n    event.addListener(el, \"touchmove\", function (e) {\n        if (longTouchTimer) {\n            clearTimeout(longTouchTimer);\n            longTouchTimer = null;\n        }\n        var touches = e.touches;\n        if (touches.length > 1 || mode == \"zoom\") return;\n\n        var touchObj = touches[0];\n\n        var wheelX = startX - touchObj.clientX;\n        var wheelY = startY - touchObj.clientY;\n\n        if (mode == \"wait\") {\n            if (wheelX * wheelX + wheelY * wheelY > 4)\n                mode = \"cursor\";\n            else\n                return e.preventDefault();\n        }\n\n        startX = touchObj.clientX;\n        startY = touchObj.clientY;\n\n        e.clientX = touchObj.clientX;\n        e.clientY = touchObj.clientY;\n\n        var t = e.timeStamp;\n        var dt = t - lastT;\n        lastT = t;\n        if (mode == \"scroll\") {\n            var mouseEvent = new MouseEvent(e, editor);\n            mouseEvent.speed = 1;\n            mouseEvent.wheelX = wheelX;\n            mouseEvent.wheelY = wheelY;\n            if (10 * Math.abs(wheelX) < Math.abs(wheelY)) wheelX = 0;\n            if (10 * Math.abs(wheelY) < Math.abs(wheelX)) wheelY = 0;\n            if (dt != 0) {\n                vX = wheelX / dt;\n                vY = wheelY / dt;\n            }\n            editor._emit(\"mousewheel\", mouseEvent);\n            if (!mouseEvent.propagationStopped) {\n                vX = vY = 0;\n            }\n        }\n        else {\n            var ev = new MouseEvent(e, editor);\n            var pos = ev.getDocumentPosition();\n            if (mode == \"cursor\")\n                editor.selection.moveCursorToPosition(pos);\n            else if (mode == \"anchor\")\n                editor.selection.setSelectionAnchor(pos.row, pos.column);\n            editor.renderer.scrollCursorIntoView(pos);\n            e.preventDefault();\n        }\n    }, editor);\n\n    function animate() {\n        animationSteps += 60;\n        animationTimer = setInterval(function() {\n            if (animationSteps-- <= 0) {\n                clearInterval(animationTimer);\n                animationTimer = null;\n            }\n            if (Math.abs(vX) < 0.01) vX = 0;\n            if (Math.abs(vY) < 0.01) vY = 0;\n            if (animationSteps < 20) vX = 0.9 * vX;\n            if (animationSteps < 20) vY = 0.9 * vY;\n            var oldScrollTop = editor.session.getScrollTop();\n            editor.renderer.scrollBy(10 * vX, 10 * vY);\n            if (oldScrollTop == editor.session.getScrollTop())\n                animationSteps = 0;\n        }, 10);\n    }\n};\n"
  },
  {
    "path": "src/multi_select.js",
    "content": "/**\n * @typedef {import(\"./anchor\").Anchor} Anchor\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.ScreenCoordinates} ScreenCoordinates\n */\n\nvar RangeList = require(\"./range_list\").RangeList;\nvar Range = require(\"./range\").Range;\nvar Selection = require(\"./selection\").Selection;\nvar onMouseDown = require(\"./mouse/multi_select_handler\").onMouseDown;\nvar event = require(\"./lib/event\");\nvar lang = require(\"./lib/lang\");\nvar commands = require(\"./commands/multi_select_commands\");\nexports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);\n\n// Todo: session.find or editor.findVolatile that returns range\nvar Search = require(\"./search\").Search;\nvar search = new Search();\n\n/**\n * @param {EditSession} session\n * @param {string | RegExp} needle\n * @param {number} dir\n */\nfunction find(session, needle, dir) {\n    search.$options.wrap = true;\n    search.$options.needle = needle;\n    search.$options.backwards = dir == -1;\n    return search.find(session);\n}\n\n// extend EditSession\nvar EditSession = require(\"./edit_session\").EditSession;\n(function() {\n    /**\n     * @this {EditSession}\n     */\n    this.getSelectionMarkers = function() {\n        return this.$selectionMarkers;\n    };\n}).call(EditSession.prototype);\n\n// extend Selection\n(function() {\n    // list of ranges in reverse addition order\n    this.ranges = null;\n\n    // automatically sorted list of ranges\n    /**@type {RangeList | null} */\n    this.rangeList = null;\n\n    /**\n     * Adds a range to a selection by entering multiselect mode, if necessary.\n     * @param {Range} range The new range to add\n     * @param {Boolean} $blockChangeEvents Whether or not to block changing events\n     * @this {Selection}\n     **/\n    this.addRange = function(range, $blockChangeEvents) {\n        if (!range)\n            return;\n\n        if (!this.inMultiSelectMode && this.rangeCount === 0) {\n            var oldRange = this.toOrientedRange();\n            this.rangeList.add(oldRange);\n            this.rangeList.add(range);\n            if (this.rangeList.ranges.length != 2) {\n                this.rangeList.removeAll();\n                return $blockChangeEvents || this.fromOrientedRange(range);\n            }\n            this.rangeList.removeAll();\n            this.rangeList.add(oldRange);\n            this.$onAddRange(oldRange);\n        }\n\n        if (!range.cursor)\n            range.cursor = range.end;\n\n        var removed = this.rangeList.add(range);\n\n        this.$onAddRange(range);\n\n        if (removed.length)\n            this.$onRemoveRange(removed);\n\n        if (this.rangeCount > 1 && !this.inMultiSelectMode) {\n            this._signal(\"multiSelect\");\n            this.inMultiSelectMode = true;\n            this.session.$undoSelect = false;\n            this.rangeList.attach(this.session);\n        }\n\n        return $blockChangeEvents || this.fromOrientedRange(range);\n    };\n\n    /**\n     * @param {Range} [range]\n     * @this {Selection}\n     **/\n    this.toSingleRange = function(range) {\n        range = range || this.ranges[0];\n        var removed = this.rangeList.removeAll();\n        if (removed.length)\n            this.$onRemoveRange(removed);\n\n        range && this.fromOrientedRange(range);\n    };\n\n    /**\n     * Removes a Range containing pos (if it exists).\n     * @param {Point} pos The position to remove, as a `{row, column}` object\n     * @this {Selection}\n     **/\n    this.substractPoint = function(pos) {\n        var removed = this.rangeList.substractPoint(pos);\n        if (removed) {\n            this.$onRemoveRange(removed);\n            return removed[0];\n        }\n    };\n\n    /**\n     * Merges overlapping ranges ensuring consistency after changes\n     * @this {Selection}\n     **/\n    this.mergeOverlappingRanges = function() {\n        var removed = this.rangeList.merge();\n        if (removed.length)\n            this.$onRemoveRange(removed);\n    };\n\n    /**\n     * @param {Range} range\n     * @this {Selection}\n     */\n    this.$onAddRange = function(range) {\n        this.rangeCount = this.rangeList.ranges.length;\n        this.ranges.unshift(range);\n        this._signal(\"addRange\", {range: range});\n    };\n\n    /**\n     * @param {Range[]} removed\n     * @this {Selection}\n     */\n    this.$onRemoveRange = function(removed) {\n        this.rangeCount = this.rangeList.ranges.length;\n        if (this.rangeCount == 1 && this.inMultiSelectMode) {\n            var lastRange = this.rangeList.ranges.pop();\n            removed.push(lastRange);\n            this.rangeCount = 0;\n        }\n\n        for (var i = removed.length; i--; ) {\n            var index = this.ranges.indexOf(removed[i]);\n            this.ranges.splice(index, 1);\n        }\n\n        this._signal(\"removeRange\", {ranges: removed});\n\n        if (this.rangeCount === 0 && this.inMultiSelectMode) {\n            this.inMultiSelectMode = false;\n            this._signal(\"singleSelect\");\n            this.session.$undoSelect = true;\n            // @ts-expect-error TODO: possible bug, no args in parameters\n            this.rangeList.detach(this.session);\n        }\n\n        lastRange = lastRange || this.ranges[0];\n        if (lastRange && !lastRange.isEqual(this.getRange()))\n            this.fromOrientedRange(lastRange);\n    };\n\n    /**\n     * adds multicursor support to selection\n     * @this {Selection}\n     */\n    this.$initRangeList = function() {\n        if (this.rangeList)\n            return;\n\n        this.rangeList = new RangeList();\n        this.ranges = [];\n        this.rangeCount = 0;\n    };\n\n    /**\n     * Returns a concatenation of all the ranges.\n     * @returns {Range[]}\n     * @this {Selection}\n     **/\n    this.getAllRanges = function() {\n        return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];\n    };\n\n    /**\n     * Splits all the ranges into lines.\n     * @this {Selection}\n     **/\n    this.splitIntoLines = function () {\n        var ranges = this.ranges.length ? this.ranges : [this.getRange()];\n        var newRanges = [];\n        for (var i = 0; i < ranges.length; i++) {\n            var range = ranges[i];\n            var row = range.start.row;\n            var endRow = range.end.row;\n            if (row === endRow) {\n                newRanges.push(range.clone());\n            } else {\n                newRanges.push(new Range(row, range.start.column, row, this.session.getLine(row).length));\n                while (++row < endRow)\n                    newRanges.push(this.getLineRange(row, true));\n                newRanges.push(new Range(endRow, 0, endRow, range.end.column));\n            }\n            if (i == 0 && !this.isBackwards())\n                newRanges = newRanges.reverse();\n        }\n        this.toSingleRange();\n        for (var i = newRanges.length; i--;)\n            this.addRange(newRanges[i]);\n    };\n\n    /**\n     * @this {Selection}\n     */\n    this.joinSelections = function () {\n        var ranges = this.rangeList.ranges;\n        var lastRange = ranges[ranges.length - 1];\n        var range = Range.fromPoints(ranges[0].start, lastRange.end);\n\n        this.toSingleRange();\n        this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n    };\n\n    /**\n     * @this {Selection}\n     **/\n    this.toggleBlockSelection = function () {\n        if (this.rangeCount > 1) {\n            var ranges = this.rangeList.ranges;\n            var lastRange = ranges[ranges.length - 1];\n            var range = Range.fromPoints(ranges[0].start, lastRange.end);\n\n            this.toSingleRange();\n            this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n        } else {\n            var cursor = this.session.documentToScreenPosition(this.cursor);\n            var anchor = this.session.documentToScreenPosition(this.anchor);\n\n            var rectSel = this.rectangularRangeBlock(cursor, anchor);\n            // @ts-expect-error TODO: possible bug\n            rectSel.forEach(this.addRange, this);\n        }\n    };\n\n    /**\n     * Gets list of ranges composing rectangular block on the screen\n     *\n     * @param {ScreenCoordinates} screenCursor The cursor to use\n     * @param {ScreenCoordinates} screenAnchor The anchor to use\n     * @param {Boolean} [includeEmptyLines] If true, this includes ranges inside the block which are empty due to clipping\n     * @returns {Range[]}\n     * @this {Selection}\n     **/\n    this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {\n        var rectSel = [];\n\n        var xBackwards = screenCursor.column < screenAnchor.column;\n        if (xBackwards) {\n            var startColumn = screenCursor.column;\n            var endColumn = screenAnchor.column;\n            var startOffsetX = screenCursor.offsetX;\n            var endOffsetX = screenAnchor.offsetX;\n        } else {\n            var startColumn = screenAnchor.column;\n            var endColumn = screenCursor.column;\n            var startOffsetX = screenAnchor.offsetX;\n            var endOffsetX = screenCursor.offsetX;\n        }\n\n        var yBackwards = screenCursor.row < screenAnchor.row;\n        if (yBackwards) {\n            var startRow = screenCursor.row;\n            var endRow = screenAnchor.row;\n        } else {\n            var startRow = screenAnchor.row;\n            var endRow = screenCursor.row;\n        }\n\n        if (startColumn < 0)\n            startColumn = 0;\n        if (startRow < 0)\n            startRow = 0;\n\n        if (startRow == endRow)\n            includeEmptyLines = true;\n\n        var docEnd;\n        for (var row = startRow; row <= endRow; row++) {\n            var range = Range.fromPoints(\n                this.session.screenToDocumentPosition(row, startColumn, startOffsetX),\n                this.session.screenToDocumentPosition(row, endColumn, endOffsetX)\n            );\n            if (range.isEmpty()) {\n                if (docEnd && isSamePoint(range.end, docEnd))\n                    break;\n                docEnd = range.end;\n            }\n            range.cursor = xBackwards ? range.start : range.end;\n            rectSel.push(range);\n        }\n\n        if (yBackwards)\n            rectSel.reverse();\n\n        if (!includeEmptyLines) {\n            var end = rectSel.length - 1;\n            while (rectSel[end].isEmpty() && end > 0)\n                end--;\n            if (end > 0) {\n                var start = 0;\n                while (rectSel[start].isEmpty())\n                    start++;\n            }\n            for (var i = end; i >= start; i--) {\n                if (rectSel[i].isEmpty())\n                    rectSel.splice(i, 1);\n            }\n        }\n\n        return rectSel;\n    };\n}).call(Selection.prototype);\n\n// extend Editor\nvar Editor = require(\"./editor\").Editor;\n(function() {\n\n    /**\n     *\n     * Updates the cursor and marker layers.\n     * @method Editor.updateSelectionMarkers\n     * @this {Editor}\n     **/\n    this.updateSelectionMarkers = function() {\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    /**\n     * Adds the selection and cursor.\n     * @param {Range & {marker?}} orientedRange A range containing a cursor\n     * @returns {Range & {marker?}}\n     * @this {Editor}\n     **/\n    this.addSelectionMarker = function(orientedRange) {\n        if (!orientedRange.cursor)\n            orientedRange.cursor = orientedRange.end;\n\n        var style = this.getSelectionStyle();\n        orientedRange.marker = this.session.addMarker(orientedRange, \"ace_selection\", style);\n\n        this.session.$selectionMarkers.push(orientedRange);\n        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;\n        return orientedRange;\n    };\n\n    /**\n     * Removes the selection marker.\n     * @param {Range & {marker?}} range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].\n     * @this {Editor}\n     **/\n    this.removeSelectionMarker = function(range) {\n        if (!range.marker)\n            return;\n        this.session.removeMarker(range.marker);\n        var index = this.session.$selectionMarkers.indexOf(range);\n        if (index != -1)\n            this.session.$selectionMarkers.splice(index, 1);\n        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;\n    };\n\n    /**\n     * @param {(Range & {marker?})[]} ranges\n     * @this {Editor}\n     */\n    this.removeSelectionMarkers = function(ranges) {\n        var markerList = this.session.$selectionMarkers;\n        for (var i = ranges.length; i--; ) {\n            var range = ranges[i];\n            if (!range.marker)\n                continue;\n            this.session.removeMarker(range.marker);\n            var index = markerList.indexOf(range);\n            if (index != -1)\n                markerList.splice(index, 1);\n        }\n        this.session.selectionMarkerCount = markerList.length;\n    };\n\n    /**\n     * @param e\n     * @this {Editor}\n     */\n    this.$onAddRange = function(e) {\n        this.addSelectionMarker(e.range);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    /**\n     * @param e\n     * @this {Editor}\n     */\n    this.$onRemoveRange = function(e) {\n        this.removeSelectionMarkers(e.ranges);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    /**\n     * @param e\n     * @this {Editor}\n     */\n    this.$onMultiSelect = function(e) {\n        if (this.inMultiSelectMode)\n            return;\n        this.inMultiSelectMode = true;\n\n        this.setStyle(\"ace_multiselect\");\n        this.keyBinding.addKeyboardHandler(commands.keyboardHandler);\n        this.commands.setDefaultHandler(\"exec\", this.$onMultiSelectExec);\n\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    /**\n     * @param e\n     * @this {Editor}\n     */\n    this.$onSingleSelect = function(e) {\n        if (this.session.multiSelect.inVirtualMode)\n            return;\n        this.inMultiSelectMode = false;\n\n        this.unsetStyle(\"ace_multiselect\");\n        this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);\n\n        this.commands.removeDefaultHandler(\"exec\", this.$onMultiSelectExec);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n        this._emit(\"changeSelection\");\n    };\n\n    /**\n     * @param e\n     * @this {Editor}\n     */\n    this.$onMultiSelectExec = function(e) {\n        var command = e.command;\n        var editor = e.editor;\n        if (!editor.multiSelect)\n            return;\n        if (!command.multiSelectAction) {\n            var result = command.exec(editor, e.args || {});\n            editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());\n            editor.multiSelect.mergeOverlappingRanges();\n        } else if (command.multiSelectAction == \"forEach\") {\n            result = editor.forEachSelection(command, e.args);\n        } else if (command.multiSelectAction == \"forEachLine\") {\n            result = editor.forEachSelection(command, e.args, true);\n        } else if (command.multiSelectAction == \"single\") {\n            editor.exitMultiSelectMode();\n            result = command.exec(editor, e.args || {});\n        } else {\n            result = command.multiSelectAction(editor, e.args || {});\n        }\n        return result;\n    };\n\n    /**\n     * Executes a command for each selection range.\n     * @param {any} cmd The command to execute\n     * @param {String} [args] Any arguments for the command\n     * @param {Object|true} [options]\n     * @this {Editor}\n     **/\n    this.forEachSelection = function(cmd, args, options) {\n        if (this.inVirtualSelectionMode)\n            return;\n        var keepOrder = options && options.keepOrder;\n        var $byLines = options == true || options && options.$byLines;\n        var session = this.session;\n        var selection = this.selection;\n        var rangeList = selection.rangeList;\n        var ranges = (keepOrder ? selection : rangeList).ranges;\n        var result;\n\n        if (!ranges.length)\n            return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});\n\n        var reg = selection._eventRegistry;\n        selection._eventRegistry = {};\n        var tmpSel = new Selection(session);\n        this.inVirtualSelectionMode = true;\n        for (var i = ranges.length; i--;) {\n            if ($byLines) {\n                while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)\n                    i--;\n            }\n            tmpSel.fromOrientedRange(ranges[i]);\n            tmpSel.index = i;\n            this.selection = session.selection = tmpSel;\n            var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});\n            if (!result && cmdResult !== undefined)\n                result = cmdResult;\n            tmpSel.toOrientedRange(ranges[i]);\n        }\n        tmpSel.detach();\n\n        this.selection = session.selection = selection;\n        this.inVirtualSelectionMode = false;\n        selection._eventRegistry = reg;\n        selection.mergeOverlappingRanges();\n        if (selection.ranges[0])\n            selection.fromOrientedRange(selection.ranges[0]);\n\n        var anim = this.renderer.$scrollAnimation;\n        this.onCursorChange();\n        this.onSelectionChange();\n        if (anim && anim.from == anim.to)\n            this.renderer.animateScrolling(anim.from);\n\n        return result;\n    };\n\n    /**\n    * Removes all the selections except the last added one.\n    * @this {Editor}\n    **/\n    this.exitMultiSelectMode = function() {\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)\n            return;\n        this.multiSelect.toSingleRange();\n    };\n\n    /**\n     * @this {Editor}\n     * @return {string}\n     */\n    this.getSelectedText = function() {\n        var text = \"\";\n        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {\n            var ranges = this.multiSelect.rangeList.ranges;\n            var buf = [];\n            for (var i = 0; i < ranges.length; i++) {\n                buf.push(this.session.getTextRange(ranges[i]));\n            }\n            var nl = this.session.getDocument().getNewLineCharacter();\n            text = buf.join(nl);\n            if (text.length == (buf.length - 1) * nl.length)\n                text = \"\";\n        } else if (!this.selection.isEmpty()) {\n            text = this.session.getTextRange(this.getSelectionRange());\n        }\n        return text;\n    };\n\n    /**\n     * @param e\n     * @param {Anchor} anchor\n     * @this {Editor}\n     */\n    this.$checkMultiselectChange = function(e, anchor) {\n        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {\n            var range = this.multiSelect.ranges[0];\n            if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)\n                return;\n            var pos = anchor == this.multiSelect.anchor\n                ? range.cursor == range.start ? range.end : range.start\n                : range.cursor;\n            if (pos.row != anchor.row\n                || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column)\n                this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());\n            else\n                this.multiSelect.mergeOverlappingRanges();\n        }\n    };\n\n    /**\n     * Finds and selects all the occurrences of `needle`.\n     * @param {String} [needle] The text to find\n     * @param {Partial<import(\"../ace-internal\").Ace.SearchOptions>} [options] The search options\n     * @param {Boolean} [additive] keeps\n     *\n     * @returns {Number} The cumulative count of all found matches\n     * @this {Editor}\n     **/\n    this.findAll = function(needle, options, additive) {\n        options = options || {};\n        options.needle = needle || options.needle;\n        if (options.needle == undefined) {\n            var range = this.selection.isEmpty()\n                ? this.selection.getWordRange()\n                : this.selection.getRange();\n            options.needle = this.session.getTextRange(range);\n        }\n        this.$search.set(options);\n\n        var ranges = this.$search.findAll(this.session);\n        if (!ranges.length)\n            return 0;\n\n        var selection = this.multiSelect;\n\n        if (!additive)\n            selection.toSingleRange(ranges[0]);\n\n        for (var i = ranges.length; i--; )\n            selection.addRange(ranges[i], true);\n\n        // keep old selection as primary if possible\n        if (range && selection.rangeList.rangeAtPoint(range.start))\n            selection.addRange(range, true);\n\n        return ranges.length;\n    };\n\n    /**\n     * Adds a cursor above or below the active cursor.\n     *\n     * @param {Number} dir The direction of lines to select: -1 for up, 1 for down\n     * @param {Boolean} [skip] If `true`, removes the active selection range\n     *\n     * @this {Editor}\n     */\n    this.selectMoreLines = function(dir, skip) {\n        var range = this.selection.toOrientedRange();\n        var isBackwards = range.cursor == range.end;\n\n        var screenLead = this.session.documentToScreenPosition(range.cursor);\n        if (this.selection.$desiredColumn)\n            screenLead.column = this.selection.$desiredColumn;\n\n        var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);\n\n        if (!range.isEmpty()) {\n            var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);\n            var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);\n        } else {\n            var anchor = lead;\n        }\n\n        if (isBackwards) {\n            /**@type {Range & {desiredColumn?: number}}*/\n            var newRange = Range.fromPoints(lead, anchor);\n            newRange.cursor = newRange.start;\n        } else {\n            /**@type {Range & {desiredColumn?: number}}*/\n            var newRange = Range.fromPoints(anchor, lead);\n            newRange.cursor = newRange.end;\n        }\n\n        newRange.desiredColumn = screenLead.column;\n        if (!this.selection.inMultiSelectMode) {\n            this.selection.addRange(range);\n        } else {\n            if (skip)\n                var toRemove = range.cursor;\n        }\n\n        this.selection.addRange(newRange);\n        if (toRemove)\n            this.selection.substractPoint(toRemove);\n    };\n\n    /**\n     * Transposes the selected ranges.\n     * @param {Number} dir The direction to rotate selections\n     * @this {Editor}\n     **/\n    this.transposeSelections = function(dir) {\n        var session = this.session;\n        var sel = session.multiSelect;\n        var all = sel.ranges;\n\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            if (range.isEmpty()) {\n                let tmp = session.getWordRange(range.start.row, range.start.column);\n                range.start.row = tmp.start.row;\n                range.start.column = tmp.start.column;\n                range.end.row = tmp.end.row;\n                range.end.column = tmp.end.column;\n            }\n        }\n        sel.mergeOverlappingRanges();\n\n        var words = [];\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            words.unshift(session.getTextRange(range));\n        }\n\n        if (dir < 0)\n            words.unshift(words.pop());\n        else\n            words.push(words.shift());\n\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            var tmp = range.clone();\n            session.replace(range, words[i]);\n            range.start.row = tmp.start.row;\n            range.start.column = tmp.start.column;\n        }\n        sel.fromOrientedRange(sel.ranges[0]);\n    };\n\n    /**\n     * Finds the next occurrence of text in an active selection and adds it to the selections.\n     * @param {Number} dir The direction of lines to select: -1 for up, 1 for down\n     * @param {Boolean} [skip] If `true`, removes the active selection range\n     * @param {Boolean} [stopAtFirst]\n     * @this {Editor}\n     **/\n    this.selectMore = function(dir, skip, stopAtFirst) {\n        var session = this.session;\n        var sel = session.multiSelect;\n\n        var range = sel.toOrientedRange();\n        if (range.isEmpty()) {\n            range = session.getWordRange(range.start.row, range.start.column);\n            range.cursor = dir == -1 ? range.start : range.end;\n            this.multiSelect.addRange(range);\n            if (stopAtFirst)\n                return;\n        }\n        var needle = session.getTextRange(range);\n\n        var newRange = find(session, needle, dir);\n        if (newRange) {\n            newRange.cursor = dir == -1 ? newRange.start : newRange.end;\n            this.session.unfold(newRange);\n            this.multiSelect.addRange(newRange);\n            this.renderer.scrollCursorIntoView(null, 0.5);\n        }\n        if (skip)\n            this.multiSelect.substractPoint(range.cursor);\n    };\n\n    /**\n     * Aligns the cursors or selected text.\n     * @this {Editor}\n     **/\n    this.alignCursors = function() {\n        var session = this.session;\n        var sel = session.multiSelect;\n        var ranges = sel.ranges;\n        // filter out ranges on same row\n        var row = -1;\n        var sameRowRanges = ranges.filter(function(r) {\n            if (r.cursor.row == row)\n                return true;\n            row = r.cursor.row;\n        });\n\n        if (!ranges.length || sameRowRanges.length == ranges.length - 1) {\n            var range = this.selection.getRange();\n            var fr = range.start.row, lr = range.end.row;\n            var guessRange = fr == lr;\n            if (guessRange) {\n                var max = this.session.getLength();\n                var line;\n                do {\n                    line = this.session.getLine(lr);\n                } while (/[=:]/.test(line) && ++lr < max);\n                do {\n                    line = this.session.getLine(fr);\n                } while (/[=:]/.test(line) && --fr > 0);\n\n                if (fr < 0) fr = 0;\n                if (lr >= max) lr = max - 1;\n            }\n            var lines = this.session.removeFullLines(fr, lr);\n            lines = this.$reAlignText(lines, guessRange);\n            this.session.insert({row: fr, column: 0}, lines.join(\"\\n\") + \"\\n\");\n            if (!guessRange) {\n                range.start.column = 0;\n                range.end.column = lines[lines.length - 1].length;\n            }\n            this.selection.setRange(range);\n        } else {\n            sameRowRanges.forEach(function(r) {\n                sel.substractPoint(r.cursor);\n            });\n\n            var maxCol = 0;\n            var minSpace = Infinity;\n            var spaceOffsets = ranges.map(function(r) {\n                var p = r.cursor;\n                var line = session.getLine(p.row);\n                var spaceOffset = line.substr(p.column).search(/\\S/g);\n                if (spaceOffset == -1)\n                    spaceOffset = 0;\n\n                if (p.column > maxCol)\n                    maxCol = p.column;\n                if (spaceOffset < minSpace)\n                    minSpace = spaceOffset;\n                return spaceOffset;\n            });\n            ranges.forEach(function(r, i) {\n                var p = r.cursor;\n                var l = maxCol - p.column;\n                var d = spaceOffsets[i] - minSpace;\n                if (l > d)\n                    session.insert(p, lang.stringRepeat(\" \", l - d));\n                else\n                    session.remove(new Range(p.row, p.column, p.row, p.column - l + d));\n\n                r.start.column = r.end.column = maxCol;\n                r.start.row = r.end.row = p.row;\n                r.cursor = r.end;\n            });\n            sel.fromOrientedRange(ranges[0]);\n            this.renderer.updateCursor();\n            this.renderer.updateBackMarkers();\n        }\n    };\n\n    /**\n     * @param {string[]} lines\n     * @param {boolean} [forceLeft]\n     * @return {*}\n     * @this {Editor}\n     */\n    this.$reAlignText = function(lines, forceLeft) {\n        var isLeftAligned = true, isRightAligned = true;\n        var startW, textW, endW;\n\n        return lines.map(function(line) {\n            var m = line.match(/(\\s*)(.*?)(\\s*)([=:].*)/);\n            if (!m)\n                return [line];\n\n            if (startW == null) {\n                startW = m[1].length;\n                textW = m[2].length;\n                endW = m[3].length;\n                return m;\n            }\n\n            if (startW + textW + endW != m[1].length + m[2].length + m[3].length)\n                isRightAligned = false;\n            if (startW != m[1].length)\n                isLeftAligned = false;\n\n            if (startW > m[1].length)\n                startW = m[1].length;\n            if (textW < m[2].length)\n                textW = m[2].length;\n            if (endW > m[3].length)\n                endW = m[3].length;\n\n            return m;\n        }).map(forceLeft ? alignLeft :\n            isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);\n\n        function spaces(n) {\n            return lang.stringRepeat(\" \", n);\n        }\n\n        function alignLeft(m) {\n            return !m[2] ? m[0] : spaces(startW) + m[2]\n                + spaces(textW - m[2].length + endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n        function alignRight(m) {\n            return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]\n                + spaces(endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n        function unAlign(m) {\n            return !m[2] ? m[0] : spaces(startW) + m[2]\n                + spaces(endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n    };\n}).call(Editor.prototype);\n\n\n/** @param {Point} p1  @param {Point} p2 */\nfunction isSamePoint(p1, p2) {\n    return p1.row == p2.row && p1.column == p2.column;\n}\n\n\n/**\n * patch\n * adds multicursor support to a session\n * @this {Editor}\n * @type {(e: any) => void}\n */\nexports.onSessionChange = function(e) {\n    var session = e.session;\n    if (session && !session.multiSelect) {\n        session.$selectionMarkers = [];\n        session.selection.$initRangeList();\n        session.multiSelect = session.selection;\n    }\n    this.multiSelect = session && session.multiSelect;\n\n    var oldSession = e.oldSession;\n    if (oldSession) {\n        oldSession.multiSelect.off(\"addRange\", this.$onAddRange);\n        oldSession.multiSelect.off(\"removeRange\", this.$onRemoveRange);\n        oldSession.multiSelect.off(\"multiSelect\", this.$onMultiSelect);\n        oldSession.multiSelect.off(\"singleSelect\", this.$onSingleSelect);\n        oldSession.multiSelect.lead.off(\"change\", this.$checkMultiselectChange);\n        oldSession.multiSelect.anchor.off(\"change\", this.$checkMultiselectChange);\n    }\n\n    if (session) {\n        session.multiSelect.on(\"addRange\", this.$onAddRange);\n        session.multiSelect.on(\"removeRange\", this.$onRemoveRange);\n        session.multiSelect.on(\"multiSelect\", this.$onMultiSelect);\n        session.multiSelect.on(\"singleSelect\", this.$onSingleSelect);\n        session.multiSelect.lead.on(\"change\", this.$checkMultiselectChange);\n        session.multiSelect.anchor.on(\"change\", this.$checkMultiselectChange);\n    }\n\n    if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {\n        if (session.selection.inMultiSelectMode)\n            this.$onMultiSelect();\n        else\n            this.$onSingleSelect();\n    }\n};\n\n// MultiSelect(editor)\n// adds multiple selection support to the editor\n// (note: should be called only once for each editor instance)\n/**\n * @param {Editor} editor\n */\nfunction MultiSelect(editor) {\n    if (editor.$multiselectOnSessionChange)\n        return;\n    editor.$onAddRange = editor.$onAddRange.bind(editor);\n    editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);\n    editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);\n    editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);\n    editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);\n    editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);\n\n    editor.$multiselectOnSessionChange(editor);\n    editor.on(\"changeSession\", editor.$multiselectOnSessionChange);\n\n    editor.on(\"mousedown\", onMouseDown);\n    editor.commands.addCommands(commands.defaultCommands);\n\n    addAltCursorListeners(editor);\n}\n\n/**\n * @param {Editor} editor\n */\nfunction addAltCursorListeners(editor){\n    if (!editor.textInput) return;\n    var el = editor.textInput.getElement();\n    var altCursor = false;\n    event.addListener(el, \"keydown\", function(e) {\n        var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey);\n        if (editor.$blockSelectEnabled && altDown) {\n            if (!altCursor) {\n                editor.renderer.setMouseCursor(\"crosshair\");\n                altCursor = true;\n            }\n        } else if (altCursor) {\n            reset();\n        }\n    }, editor);\n\n    event.addListener(el, \"keyup\", reset, editor);\n    event.addListener(el, \"blur\", reset, editor);\n    function reset(e) {\n        if (altCursor) {\n            editor.renderer.setMouseCursor(\"\");\n            altCursor = false;\n            // TODO disable menu popping up\n            // e && e.preventDefault()\n        }\n    }\n}\n\nexports.MultiSelect = MultiSelect;\n\n\nrequire(\"./config\").defineOptions(Editor.prototype, \"editor\", {\n    enableMultiselect: {\n        /**\n         * @param {boolean} val\n         * @this {Editor}\n         */\n        set: function(val) {\n            MultiSelect(this);\n            if (val) {\n                this.on(\"mousedown\", onMouseDown);\n            } else {\n                this.off(\"mousedown\", onMouseDown);\n            }\n        },\n        value: true\n    },\n    enableBlockSelect: {\n        set: function(val) {\n            this.$blockSelectEnabled = val;\n        },\n        value: true\n    }\n});\n"
  },
  {
    "path": "src/multi_select_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"./multi_select\");\nvar assert = require(\"./test/assertions\");\nvar Range = require(\"./range\").Range;\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar UndoManager = require(\"./undomanager\").UndoManager;\n\nvar editor;\nvar exec = function(name, times, args) {\n    do {\n        editor.commands.exec(name, editor, args);\n    } while(times --> 1);\n};\nvar testRanges = function(str) {\n    assert.equal(editor.selection.getAllRanges() + \"\", str + \"\");\n};\nfunction getSelection(editor) {\n    var data = editor.multiSelect.toJSON();\n    if (!data.length) data = [data];\n    data = data.map(function(x) {\n        var a, c;\n        if (x.isBackwards) {\n            a = x.end;\n            c = x.start;\n        } else {\n            c = x.end;\n            a = x.start;\n        }\n        return Range.comparePoints(a, c) \n            ? [a.row, a.column, c.row, c.column]\n            : [a.row, a.column];\n    });\n    return data.length > 1 ? data : data[0];\n}\nfunction testSelection(editor, data) {\n    assert.equal(getSelection(editor) + \"\", data + \"\");\n}\nfunction setSelection(editor, data) {\n    if (typeof data[0] == \"number\")\n        data = [data];\n    editor.selection.fromJSON(data.map(function(x) {\n        var start = {row: x[0], column: x[1]};\n        var end = x.length == 2 ? start : {row: x[2], column: x[3]};\n        var isBackwards = Range.comparePoints(start, end) > 0;\n        return isBackwards ? {\n            start: end,\n            end: start,\n            isBackwards: isBackwards\n        } : {\n            start: start,\n            end: end,\n            isBackwards: isBackwards\n        };\n    }));\n}\n\nmodule.exports = {\n\n    name: \"ACE multi_select.js\",\n\n    \"test: multiselect editing\": function() {\n        var doc = new EditSession([\n            \"w1.w2\",\n            \"    wtt.w\",\n            \"    wtt.w\"\n        ]);\n        editor = new Editor(new MockRenderer(), doc);\n\n        editor.navigateFileEnd();\n        exec(\"selectMoreBefore\", 3);\n        assert.ok(editor.inMultiSelectMode);\n        assert.equal(editor.selection.getAllRanges().length, 4);\n\n        var newLine = editor.session.getDocument().getNewLineCharacter();\n        var copyText = \"wwww\".split(\"\").join(newLine);\n        assert.equal(editor.getCopyText(), copyText);\n        exec(\"insertstring\", 1, \"a\");\n        exec(\"backspace\", 2);\n        assert.equal(editor.session.getValue(), \"w1.w2\\ntt\\ntt\");\n        assert.equal(editor.selection.getAllRanges().length, 4);\n\n        exec(\"selectall\");\n        assert.ok(!editor.inMultiSelectMode);\n        //assert.equal(editor.selection.getAllRanges().length, 1);\n    },\n\n    \"test: multiselect navigation\": function() {\n        var doc = new EditSession([\n            \"w1.w2\",\n            \"    wtt.w\",\n            \"    wtt.we\"\n        ]);\n        editor = new Editor(new MockRenderer(), doc);\n\n        editor.selectMoreLines(1);\n        testRanges(\"Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]\");\n        assert.ok(editor.inMultiSelectMode);\n\n        exec(\"golinedown\");\n        exec(\"gotolineend\");\n        testRanges(\"Range: [1/9] -> [1/9],Range: [2/10] -> [2/10]\");\n        exec(\"selectwordleft\");\n\n        testRanges(\"Range: [1/8] -> [1/9],Range: [2/8] -> [2/10]\");\n        exec(\"golinedown\", 2);\n        assert.ok(!editor.inMultiSelectMode);\n    },\n\n    \"test: multiselect session change\": function() {\n        var doc = new EditSession([\n            \"w1.w2\",\n            \"    wtt.w\",\n            \"    wtt.w\"\n        ]);\n        editor = new Editor(new MockRenderer(), doc);\n\n        editor.selectMoreLines(1);\n        testRanges(\"Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]\");\n        assert.ok(editor.inMultiSelectMode);\n\n        var doc2 = new EditSession([\"w1\"]);\n        editor.setSession(doc2);\n        assert.ok(!editor.inMultiSelectMode);\n\n        editor.setSession(doc);\n        assert.ok(editor.inMultiSelectMode);\n    },\n\n    \"test: multiselect addRange\": function() {\n        var doc = new EditSession([\n            \"w1.w2\",\n            \"    wtt.w\",\n            \"    wtt.w\"\n        ]);\n        editor = new Editor(new MockRenderer(), doc);\n        var selection = editor.selection;\n\n        var range1 = new Range(0, 2, 0, 4);\n        editor.selection.fromOrientedRange(range1);\n\n        var range2 = new Range(0, 3, 0, 4);\n        selection.addRange(range2);\n        assert.ok(!editor.inMultiSelectMode);\n        assert.ok(range2.isEqual(editor.selection.getRange()));\n\n        var range3 = new Range(0, 1, 0, 1);\n        selection.addRange(range3);\n        assert.ok(editor.inMultiSelectMode);\n        testRanges([range3, range2]);\n\n        var range4 = new Range(0, 0, 4, 0);\n        selection.addRange(range4);\n        assert.ok(!editor.inMultiSelectMode);\n    },\n\n    \"test: multiselect paste\": function() {\n        editor = new Editor(new MockRenderer());\n\n        editor.setValue(\"l1\\nl2\\nl3\", -1);\n        editor.selection.selectDown();\n        editor.$handlePaste(\"\");\n        assert.equal(\"l2\\nl3\", editor.getValue());\n\n        editor.setValue(\"l1\\nl2\\nl3\", -1);\n        editor.selectMoreLines(1);\n        editor.$handlePaste(\"x\\n\");\n        assert.equal(\"x\\nl1\\nx\\nl2\\nl3\", editor.getValue());\n        editor.execCommand(\"gotolineend\");\n        editor.$handlePaste(\"\\ny\");\n        assert.equal(\"x\\nl1\\ny\\nx\\nl2\\ny\\nl3\", editor.getValue());\n        \n        editor.selectMoreLines(-1);\n        editor.$handlePaste(\"4\\n5\\n6\");\n        assert.equal(\"x\\nl1\\ny4\\nx\\nl52\\ny6\\nl3\", editor.getValue());\n\n        editor.$handlePaste(\"7\\n\\n8\");\n        assert.equal(\"x\\nl1\\ny47\\nx\\nl52\\ny68\\nl3\", editor.getValue());\n        editor.execCommand(\"selectleft\");\n        editor.execCommand(\"selectleft\");\n        editor.$handlePaste(\"t\\nz\");\n        \n        assert.equal(\"x\\nl1\\nyt\\nz\\nx\\nt\\nz2\\nyt\\nz\\nl3\", editor.getValue());\n        editor.setValue(\"l1\\nl2\\nl3\", -1);\n        editor.selectMoreLines(1);\n        editor.selectMoreLines(1);\n        editor.$handlePaste(\"a\\nb\\nc\\nd\");\n        assert.equal(\"a\\nb\\nc\\ndl1\\na\\nb\\nc\\ndl2\\na\\nb\\nc\\ndl3\", editor.getValue());\n    },\n    \n    \"test: onPaste in command with multiselect\": function() {\n        var doc = new EditSession([\"l1\", \"l2\"]);\n        editor = new Editor(new MockRenderer(), doc);\n        editor.commands.addCommand({\n            name: 'insertfoo',\n            exec: function(ed) { ed.onPaste('foo'); },\n            multiSelectAction: \"forEach\"\n        });\n        var selection = editor.selection;\n        var range1 = new Range(0,2,0,2);\n        var range2 = new Range(1,2,1,2);\n        selection.fromOrientedRange(range1);\n        selection.addRange(range2);\n        editor.execCommand('insertfoo');\n        assert.equal('l1foo\\nl2foo', editor.getValue());\n    },\n    \n    \"test multiselect move lines\": function() {\n        editor = new Editor(new MockRenderer());\n        \n        editor.setValue(\"l1\\nl2\\nl3\\nl4\", -1);\n        setSelection(editor, [[0,2],[1,2],[2,2],[3,2]]);\n        \n        exec(\"copylinesdown\");\n        assert.equal(editor.getValue(),\"l1\\nl1\\nl2\\nl2\\nl3\\nl3\\nl4\\nl4\");\n        testSelection(editor, [[1,2],[3,2],[5,2],[7,2]]);\n        exec(\"copylinesup\");\n        assert.equal(editor.getValue(),\"l1\\nl1\\nl1\\nl2\\nl2\\nl2\\nl3\\nl3\\nl3\\nl4\\nl4\\nl4\");\n        testSelection(editor, [[1,2],[4,2],[7,2],[10,2]]);\n        exec(\"removeline\");\n        assert.equal(editor.getValue(),\"l1\\nl1\\nl2\\nl2\\nl3\\nl3\\nl4\\nl4\");\n        testSelection(editor, [[1,0],[3,0],[5,0],[7,0]]);\n        \n        setSelection(editor, [[1,2],[1,1,1,0],[3,0,3,1],[5,0,5,1],[7,0,7,1]]);\n        exec(\"copylinesdown\");\n        exec(\"copylinesup\");\n        assert.equal(editor.getValue(),\"l1\\nl1\\nl1\\nl1\\nl2\\nl2\\nl2\\nl2\\nl3\\nl3\\nl3\\nl3\\nl4\\nl4\\nl4\\nl4\");\n        testSelection(editor, [[2,2],[2,1,2,0],[6,0,6,1],[10,0,10,1],[14,0,14,1]]);\n        \n        exec(\"movelinesdown\", 12);\n        assert.equal(editor.getValue(),\"l1\\nl1\\nl1\\nl2\\nl2\\nl2\\nl3\\nl3\\nl3\\nl4\\nl4\\nl4\\nl1\\nl2\\nl3\\nl4\");\n        testSelection(editor, [[12,2],[12,1,12,0],[13,0,13,1],[14,0,14,1],[15,0,15,1]]);\n        \n        exec(\"movelinesup\", 12);\n        assert.equal(editor.getValue(),\"l1\\nl2\\nl3\\nl4\\nl1\\nl1\\nl1\\nl2\\nl2\\nl2\\nl3\\nl3\\nl3\\nl4\\nl4\\nl4\");\n        testSelection(editor, [[0,2],[0,1,0,0],[1,0,1,1],[2,0,2,1],[3,0,3,1]]);\n    },\n\n    \"test multiselect fromJSON/toJSON\": function() {\n        var doc = new EditSession([\"l1\", \"l2\"]);\n        editor = new Editor(new MockRenderer(), doc);\n        var selection = editor.selection;\n        \n        var before = selection.toJSON();\n        \n        var range1 = new Range(0,2,0,2);\n        var range2 = new Range(1,2,1,2);\n        selection.fromOrientedRange(range1);\n        selection.addRange(range2);\n        \n        var after = selection.toJSON();\n        \n        selection.fromJSON(before);\n        assert.ok(!selection.isEqual(after));\n        assert.ok(selection.isEqual(before));\n        \n        selection.fromJSON(after);\n        assert.ok(!selection.isEqual(before));\n        assert.ok(selection.isEqual(after));\n    },\n    \n    \"test multiselect align\": function() {\n        var doc = new EditSession([\"l1\", \"l2\", \"l3\"]);\n        doc.setUndoManager(new UndoManager());\n        editor = new Editor(new MockRenderer(), doc);\n        var selection = editor.selection;\n        selection.addRange(new Range(1,0,1,0));\n        selection.addRange(new Range(2,2,2,2));\n        editor.execCommand(\"alignCursors\");\n        assert.equal('  l1\\n  l2\\nl3', editor.getValue());\n        doc.markUndoGroup();\n        editor.execCommand(\"undo\");\n        assert.equal('l1\\nl2\\nl3', editor.getValue());\n    },\n    \n    \"test multiselect transpose\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.setValue(\"ay caramba\");\n        var selection = editor.selection;\n        selection.fromJSON([new Range(0,3,0,10), new Range(0,0,0,2)]);\n        editor.execCommand(\"transposeletters\");\n        assert.equal('caramba ay', editor.getValue());\n        editor.execCommand(\"transposeletters\");\n        assert.ok(!editor.getSelectionRange().isEmpty());\n        assert.equal('ay caramba', editor.getValue());\n    },\n    \n    \"test select next\": function() {\n        editor = new Editor(new MockRenderer());\n        editor.setValue(\"a\\na\\na\", 1);\n        editor.execCommand(\"selectMoreBefore\");\n        editor.execCommand(\"selectMoreBefore\");\n        testSelection(editor, [[0,1,0,0],[1,1,1,0],[2,1,2,0]]);\n        assert.equal(editor.session.$highlightLineMarker.start.row, 0);\n    },\n    \n    \"test multiSelect delete\": function() {\n        editor.setValue(\"\\n\" + \"a\\nb\\nc/\\n\".repeat(4), -1);\n        exec(\"selectdown\", 4);\n        exec(\"selectleft\", 2);\n        exec(\"selectMoreAfter\", 3);\n        exec(\"del\", 1);\n        assert.equal(editor.getValue(), \"////\\n\");\n        testSelection(editor, [[0,3],[0,2],[0,1],[0,0]]);\n        exec(\"selectright\", 1);\n        exec(\"insertstring\", 1, \"a\");\n        assert.equal(editor.getValue(), \"aaaa\\n\");\n        testSelection(editor, [[0,4],[0,3],[0,2],[0,1]]);\n        \n        editor.setValue(\"w1.w2\\n\\n    0\\n1\\n2\\n3\\n4\\n5\\n6\\n    qwe\\n\\n\\n\\n\\n\\n\");\n        editor.selection.fromJSON([\n            new Range(2,4,9,7),\n            new Range(0,3,0,4),\n            new Range(0,0,0,1)\n        ]);\n\n        editor.session.remove(new Range(4,0,5,0));\n        testSelection(editor, [[2,4,8,7],[0,3,0,4],[0,0,0,1]]);\n    },\n    \n    \"test splitIntoLines\": function() {\n        var session = new EditSession([\"l1\", \"l2\", \"l3\"]);\n        var selection = session.selection;\n        editor = new Editor(new MockRenderer(), session);\n        \n        selection.moveTo(0, 0);\n        selection.selectDown();\n        selection.splitIntoLines();\n        assert.equal(editor.selection.ranges + \"\", \"Range: [1/0] -> [1/0],Range: [0/0] -> [0/2]\", 2);\n        selection.selectAll();\n        assert.equal(editor.selection.rangeCount, 0);\n        \n        selection.splitIntoLines();\n        assert.equal(editor.selection.rangeCount, 3);\n        \n        editor.execCommand(\"gotolineend\");\n        editor.execCommand(\"addLineAfter\");\n        editor.execCommand(\"insertstring\", \"x\");\n        editor.execCommand(\"selectup\");\n        editor.execCommand(\"splitSelectionIntoLines\");\n        assert.equal(editor.selection.rangeCount, 6);\n        assert.equal(editor.selection.cursor.row, 4);\n        editor.execCommand(\"toggleSplitSelectionIntoLines\");\n        assert.equal(editor.selection.getAllRanges() + \"\", \"Range: [0/1] -> [5/1]\");\n        \n        editor.setValue(\"\");\n        assert.equal(editor.selection.inMultiSelectMode, false);\n        assert.equal(editor.selection.rangeCount, 0);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/occur.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./editor\").Editor} Editor\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.SearchOptions} SearchOptions\n */\n\nvar oop = require(\"./lib/oop\");\nvar Search = require(\"./search\").Search;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar SearchHighlight = require(\"./search_highlight\").SearchHighlight;\n\n/**\n * Finds all lines matching a search term in the current [[Document\n * `Document`]] and displays them instead of the original `Document`. Keeps\n * track of the mapping between the occur doc and the original doc.\n **/\nclass Occur extends Search {\n\n    /**\n     * Enables occur mode. expects that `options.needle` is a search term.\n     * This search term is used to filter out all the lines that include it\n     * and these are then used as the content of a new [[Document\n     * `Document`]]. The current cursor position of editor will be translated\n     * so that the cursor is on the matching row/column as it was before.\n     * @param {Editor} editor\n     * @param {Object} options options.needle should be a String\n     * @return {Boolean} Whether occur activation was successful\n     *\n     **/\n    enter(editor, options) {\n        if (!options.needle) return false;\n        var pos = editor.getCursorPosition();\n        this.displayOccurContent(editor, options);\n        var translatedPos = this.originalToOccurPosition(editor.session, pos);\n        editor.moveCursorToPosition(translatedPos);\n        return true;\n    }\n\n    /**\n     * Disables occur mode. Resets the [[Sessions `EditSession`]] [[Document\n     * `Document`]] back to the original doc. If options.translatePosition is\n     * truthy also maps the [[Editors `Editor`]] cursor position accordingly.\n     * @param {Editor} editor\n     * @param {Object} options options.translatePosition\n     * @return {Boolean} Whether occur deactivation was successful\n     *\n     **/\n    exit(editor, options) {\n        var pos = options.translatePosition && editor.getCursorPosition();\n        var translatedPos = pos && this.occurToOriginalPosition(editor.session, pos);\n        this.displayOriginalContent(editor);\n        if (translatedPos)\n            editor.moveCursorToPosition(translatedPos);\n        return true;\n    }\n\n    /**\n     * @param {EditSession} sess\n     * @param {RegExp} regexp\n     */\n    highlight(sess, regexp) {\n        var hl = sess.$occurHighlight = sess.$occurHighlight || sess.addDynamicMarker(\n                new SearchHighlight(null, \"ace_occur-highlight\", \"text\"));\n        hl.setRegexp(regexp);\n        sess._emit(\"changeBackMarker\"); // force highlight layer redraw\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {Partial<SearchOptions>} options\n     */\n    displayOccurContent(editor, options) {\n        // this.setSession(session || new EditSession(\"\"))\n        this.$originalSession = editor.session;\n        var found = this.matchingLines(editor.session, options);\n        var lines = found.map(function(foundLine) { return foundLine.content; });\n        /**@type {EditSession}*/\n        var occurSession = new EditSession(lines.join('\\n'));\n        occurSession.$occur = this;\n        occurSession.$occurMatchingLines = found;\n        editor.setSession(occurSession);\n        this.$useEmacsStyleLineStart = this.$originalSession.$useEmacsStyleLineStart;\n        occurSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart;\n        this.highlight(occurSession, options.re);\n        occurSession._emit('changeBackMarker');\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    displayOriginalContent(editor) {\n        editor.setSession(this.$originalSession);\n        this.$originalSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart;\n    }\n\n    /**\n    * Translates the position from the original document to the occur lines in\n    * the document or the beginning if the doc {row: 0, column: 0} if not\n    * found.\n    * @param {EditSession} session The occur session\n    * @param {Point} pos The position in the original document\n    * @return {Point} position in occur doc\n    **/\n    originalToOccurPosition(session, pos) {\n        var lines = session.$occurMatchingLines;\n        var nullPos = {row: 0, column: 0};\n        if (!lines) return nullPos;\n        for (var i = 0; i < lines.length; i++) {\n            if (lines[i].row === pos.row)\n                return {row: i, column: pos.column};\n        }\n        return nullPos;\n    }\n\n    /**\n    * Translates the position from the occur document to the original document\n    * or `pos` if not found.\n    * @param {EditSession} session The occur session\n    * @param {Point} pos The position in the occur session document\n    * @return {Point} position\n    **/\n    occurToOriginalPosition(session, pos) {\n        var lines = session.$occurMatchingLines;\n        if (!lines || !lines[pos.row])\n            return pos;\n        return {row: lines[pos.row].row, column: pos.column};\n    }\n\n    /**\n     * @param {EditSession} session\n     * @param {Partial<SearchOptions>} options\n     */\n    matchingLines(session, options) {\n        options = oop.mixin({}, options);\n        if (!session || !options.needle) return [];\n        var search = new Search();\n        search.set(options);\n        return search.findAll(session).reduce(function(lines, range) {\n            var row = range.start.row;\n            var last = lines[lines.length-1];\n            return last && last.row === row ?\n                lines :\n                lines.concat({row: row, content: session.getLine(row)});\n        }, []);\n    }\n\n}\n\nvar dom = require('./lib/dom');\ndom.importCssString(\".ace_occur-highlight {\\n\\\n    border-radius: 4px;\\n\\\n    background-color: rgba(87, 255, 8, 0.25);\\n\\\n    position: absolute;\\n\\\n    z-index: 4;\\n\\\n    box-sizing: border-box;\\n\\\n    box-shadow: 0 0 4px rgb(91, 255, 50);\\n\\\n}\\n\\\n.ace_dark .ace_occur-highlight {\\n\\\n    background-color: rgb(80, 140, 85);\\n\\\n    box-shadow: 0 0 4px rgb(60, 120, 70);\\n\\\n}\\n\", \"incremental-occur-highlighting\", false);\n\nexports.Occur = Occur;\n"
  },
  {
    "path": "src/occur_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar Range = require(\"./range\").Range;\nvar assert = require(\"./test/assertions\");\nvar Occur = require(\"./occur\").Occur;\nvar occurStartCommand = require(\"./commands/occur_commands\").occurStartCommand;\nvar editor, occur;\n\nmodule.exports = {\n\n    name: \"ACE occur.js\",\n\n    setUp: function() {\n        var session = new EditSession('');\n        editor = new Editor(new MockRenderer(), session);\n        occur = new Occur();\n    },\n\n    \"test: find lines matching\" : function() {\n        editor.session.insert({row: 0, column: 0}, 'abc\\ndef\\nxyz\\nbcxbc');\n        var result = occur.matchingLines(editor.session, {needle: 'bc'}),\n            expected = [{row: 0, content: 'abc'}, {row: 3, content: 'bcxbc'}];\n        assert.deepEqual(result, expected);\n    },\n\n    \"test: display occurrences\" : function() {\n        var text = 'abc\\ndef\\nxyz\\nbcx\\n';\n        editor.session.insert({row: 0, column: 0}, text);\n        occur.displayOccurContent(editor, {needle: 'bc'});\n        assert.equal(editor.getValue(), 'abc\\nbcx');\n        occur.displayOriginalContent(editor);\n        assert.equal(editor.getValue(), text);\n    },\n\n    \"test: original position from occur doc\" : function() {\n        var text = 'abc\\ndef\\nxyz\\nbcx\\n';\n        editor.session.insert({row: 0, column: 0}, text);\n        occur.displayOccurContent(editor, {needle: 'bc'});\n        assert.equal(editor.getValue(), 'abc\\nbcx');\n        var pos = occur.occurToOriginalPosition(editor.session, {row: 1, column: 2});\n        assert.position(pos, 3, 2);\n    },\n\n    \"test: occur command\" : function() {\n        // setup\n        var text = 'hel\\nlo\\n\\nwo\\nrld\\n';\n        editor.session.insert({row: 0, column: 0}, text);\n        editor.commands.addCommand(occurStartCommand);\n\n        // run occur for lines including 'o'\n        editor.execCommand('occur', {needle: 'o'});\n        assert.equal(editor.getValue(), 'lo\\nwo');\n        // command install OK?\n        // assert.ok(editor.getReadOnly(), 'occur doc not marked as read only');\n        assert.ok(editor.getKeyboardHandler().isOccurHandler, 'no occur handler installed');\n        assert.ok(editor.commands.byName.occurexit, 'no exitoccur command installed');\n\n        // exit occur\n        editor.execCommand('occurexit');\n        assert.equal(editor.getValue(), text);\n\n        // editor state cleaned up?\n        // assert.ok(!editor.getReadOnly(), 'original doc is marked as read only');\n        assert.ok(!editor.getKeyboardHandler().isOccurHandler, 'occur handler installed after detach');\n        assert.ok(!editor.commands.byName.occurexit, 'exitoccur installed after exiting occur');\n    },\n\n    \"test: occur navigation\" : function() {\n        // setup\n        var text = 'hel\\nlo\\n\\nwo\\nrld\\n';\n        editor.session.insert({row: 0, column: 0}, text);\n        editor.commands.addCommand(occurStartCommand);\n        editor.moveCursorToPosition({row: 1, column: 1});\n\n        // run occur for lines including 'o'\n        editor.execCommand('occur', {needle: 'o'});\n        assert.equal(editor.getValue(), 'lo\\nwo');\n        assert.position(editor.getCursorPosition(), 0, 1, 'original -> occur pos');\n\n        // move to second line and accept\n        editor.moveCursorToPosition({row: 1, column: 1});\n        editor.execCommand('occuraccept');\n\n        assert.position(editor.getCursorPosition(), 3, 1, 'occur -> original pos');\n    },\n\n    \"test: recursive occur\" : function() {\n        // setup\n        var text = 'x\\nabc1\\nx\\nabc2\\n';\n        editor.session.insert({row: 0, column: 0}, text);\n        editor.commands.addCommand(occurStartCommand);\n\n        // orig -> occur1\n        editor.execCommand('occur', {needle: 'abc'});\n        assert.equal(editor.getValue(), 'abc1\\nabc2', \"orig -> occur1\");\n\n        // occur1 -> occur2\n        editor.execCommand('occur', {needle: '2'});\n        assert.equal(editor.getValue(), 'abc2', \"occur1 -> occur2\");\n\n        // occur2 -> occur1\n        editor.execCommand('occurexit');\n        assert.equal(editor.getValue(), 'abc1\\nabc2', \"occur2 -> occur1\");\n\n        // occur1 -> orig\n        editor.execCommand('occurexit');\n        assert.equal(editor.getValue(), text, \"occur1 -> orig\");\n    }\n\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/placeholder.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n */\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar oop = require(\"./lib/oop\");\n\nclass PlaceHolder {\n    /**\n     * @param {EditSession} session\n     * @param {Number} length\n     * @param {import(\"../ace-internal\").Ace.Point} pos\n     * @param {any[]} others\n     * @param {String} mainClass\n     * @param {String} othersClass\n     **/\n    constructor(session, length, pos, others, mainClass, othersClass) {\n        var _self = this;\n        this.length = length;\n        this.session = session;\n        this.doc = session.getDocument();\n        this.mainClass = mainClass;\n        this.othersClass = othersClass;\n        this.$onUpdate = this.onUpdate.bind(this);\n        this.doc.on(\"change\", this.$onUpdate, true);\n        this.$others = others;\n\n        this.$onCursorChange = function() {\n            setTimeout(function() {\n                _self.onCursorChange();\n            });\n        };\n\n        this.$pos = pos;\n        // Used for reset\n        var undoStack = session.getUndoManager().$undoStack || session.getUndoManager()[\"$undostack\"] || {length: -1};\n        this.$undoStackDepth = undoStack.length;\n        this.setup();\n\n        session.selection.on(\"changeCursor\", this.$onCursorChange);\n    }\n\n    /**\n     * PlaceHolder.setup()\n     *\n     * TODO\n     *\n     **/\n    setup() {\n        var _self = this;\n        var doc = this.doc;\n        var session = this.session;\n\n        this.selectionBefore = session.selection.toJSON();\n        if (session.selection.inMultiSelectMode)\n            session.selection.toSingleRange();\n\n        this.pos = doc.createAnchor(this.$pos.row, this.$pos.column);\n        var pos = this.pos;\n        pos.$insertRight = true;\n        pos.detach();\n        pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);\n        this.others = [];\n        this.$others.forEach(function(other) {\n            var anchor = doc.createAnchor(other.row, other.column);\n            anchor.$insertRight = true;\n            anchor.detach();\n            _self.others.push(anchor);\n        });\n        session.setUndoSelect(false);\n    }\n\n    /**\n     * PlaceHolder.showOtherMarkers()\n     *\n     * TODO\n     *\n     **/\n    showOtherMarkers() {\n        if (this.othersActive) return;\n        var session = this.session;\n        var _self = this;\n        this.othersActive = true;\n        this.others.forEach(function(anchor) {\n            anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);\n        });\n    }\n\n    /**\n     * PlaceHolder.hideOtherMarkers()\n     *\n     * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one.\n     *\n     **/\n    hideOtherMarkers() {\n        if (!this.othersActive) return;\n        this.othersActive = false;\n        for (var i = 0; i < this.others.length; i++) {\n            this.session.removeMarker(this.others[i].markerId);\n        }\n    }\n\n    /**\n     * PlaceHolder@onUpdate(e)\n     *\n     * Emitted when the place holder updates.\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     * @internal\n     */\n    onUpdate(delta) {\n        if (this.$updating)\n            return this.updateAnchors(delta);\n\n        var range = delta;\n        if (range.start.row !== range.end.row) return;\n        if (range.start.row !== this.pos.row) return;\n        this.$updating = true;\n        var lengthDiff = delta.action === \"insert\" ? range.end.column - range.start.column : range.start.column - range.end.column;\n        var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1;\n        var distanceFromStart = range.start.column - this.pos.column;\n\n        this.updateAnchors(delta);\n\n        if (inMainRange)\n            this.length += lengthDiff;\n\n        if (inMainRange && !this.session.$fromUndo) {\n            if (delta.action === 'insert') {\n                for (var i = this.others.length - 1; i >= 0; i--) {\n                    var otherPos = this.others[i];\n                    var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};\n                    this.doc.insertMergedLines(newPos, delta.lines);\n                }\n            } else if (delta.action === 'remove') {\n                for (var i = this.others.length - 1; i >= 0; i--) {\n                    var otherPos = this.others[i];\n                    var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};\n                    this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));\n                }\n            }\n        }\n\n        this.$updating = false;\n        this.updateMarkers();\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     */\n    updateAnchors(delta) {\n        this.pos.onChange(delta);\n        for (var i = this.others.length; i--;)\n            this.others[i].onChange(delta);\n        this.updateMarkers();\n    }\n\n    updateMarkers() {\n        if (this.$updating)\n            return;\n        var _self = this;\n        var session = this.session;\n        var updateMarker = function(pos, className) {\n            session.removeMarker(pos.markerId);\n            pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false);\n        };\n        updateMarker(this.pos, this.mainClass);\n        for (var i = this.others.length; i--;)\n            updateMarker(this.others[i], this.othersClass);\n    }\n\n\n    /**\n     * PlaceHolder@onCursorChange(e)\n     *\n     * Emitted when the cursor changes.\n     * @param {any} [event]\n     * @internal\n     */\n    onCursorChange(event) {\n        if (this.$updating || !this.session) return;\n        var pos = this.session.selection.getCursor();\n        if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {\n            this.showOtherMarkers();\n            this._emit(\"cursorEnter\", event);\n        } else {\n            this.hideOtherMarkers();\n            this._emit(\"cursorLeave\", event);\n        }\n    }\n\n    /**\n     * PlaceHolder.detach()\n     *\n     * TODO\n     *\n     **/\n    detach() {\n        this.session.removeMarker(this.pos && this.pos.markerId);\n        this.hideOtherMarkers();\n        this.doc.off(\"change\", this.$onUpdate);\n        this.session.selection.off(\"changeCursor\", this.$onCursorChange);\n        this.session.setUndoSelect(true);\n        this.session = null;\n    }\n\n    /**\n     * PlaceHolder.cancel()\n     *\n     * TODO\n     *\n     **/\n    cancel() {\n        if (this.$undoStackDepth === -1)\n            return;\n        var undoManager = this.session.getUndoManager();\n        var undosRequired = (undoManager.$undoStack || undoManager[\"$undostack\"]).length - this.$undoStackDepth;\n        for (var i = 0; i < undosRequired; i++) {\n            undoManager.undo(this.session, true);\n        }\n        if (this.selectionBefore)\n            this.session.selection.fromJSON(this.selectionBefore);\n    }\n}\n\noop.implement(PlaceHolder.prototype, EventEmitter);\n\nexports.PlaceHolder = PlaceHolder;\n"
  },
  {
    "path": "src/placeholder_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Editor = require(\"./editor\").Editor;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar assert = require(\"./test/assertions\");\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar PlaceHolder = require(\"./placeholder\").PlaceHolder;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar lang = require(\"./lib/lang\");\n\nrequire(\"./multi_select\");\n\nmodule.exports = {\n\n    \"test: simple at the end appending of text\": function () {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n\n        editor.moveCursorTo(0, 5);\n        editor.insert('b');\n        assert.equal(session.doc.getValue(), \"var ab = 10;\\nconsole.log(ab, ab);\");\n        editor.insert('cd');\n        assert.equal(session.doc.getValue(), \"var abcd = 10;\\nconsole.log(abcd, abcd);\");\n        editor.remove('left');\n        editor.remove('left');\n        editor.remove('left');\n        assert.equal(session.doc.getValue(), \"var a = 10;\\nconsole.log(a, a);\");\n    },\n\n    \"test: inserting text outside placeholder\": function () {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\\n\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n\n        editor.moveCursorTo(2, 0);\n        editor.insert('b');\n        assert.equal(session.doc.getValue(), \"var a = 10;\\nconsole.log(a, a);\\nb\");\n    },\n\n    \"test: insertion at the beginning\": async function (next) {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        var p = new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n\n        editor.moveCursorTo(0, 4);\n        editor.insert('$');\n        assert.equal(session.doc.getValue(), \"var $a = 10;\\nconsole.log($a, $a);\");\n        editor.moveCursorTo(0, 4);\n\n        // Have to put this in a setTimeout because the anchor is only fixed later.\n        await lang.sleep(20);\n        editor.insert('v');\n        assert.equal(session.doc.getValue(), \"var v$a = 10;\\nconsole.log(v$a, v$a);\");\n        next();\n    },\n\n    \"test: detaching placeholder\": function () {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        var p = new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n\n        editor.moveCursorTo(0, 5);\n        editor.insert('b');\n        assert.equal(session.doc.getValue(), \"var ab = 10;\\nconsole.log(ab, ab);\");\n        p.detach();\n        editor.insert('cd');\n        assert.equal(session.doc.getValue(), \"var abcd = 10;\\nconsole.log(ab, ab);\");\n    },\n\n    \"test: events\": function () {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\", new JavaScriptMode());\n        var editor = new Editor(new MockRenderer(), session);\n\n        var p = new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n        var entered = false;\n        var left = false;\n        p.on(\"cursorEnter\", function () {\n            entered = true;\n        });\n        p.on(\"cursorLeave\", function () {\n            left = true;\n        });\n\n        editor.moveCursorTo(0, 0);\n        editor.moveCursorTo(0, 4);\n        p.onCursorChange(); // Have to do this by hand because moveCursorTo doesn't trigger the event\n        assert.ok(entered);\n        editor.moveCursorTo(1, 0);\n        p.onCursorChange(); // Have to do this by hand because moveCursorTo doesn't trigger the event\n        assert.ok(left);\n    },\n\n    \"test: cancel\": async function (next) {\n        var session = new EditSession(\"var a = 10;\\nconsole.log(a, a);\", new JavaScriptMode());\n        session.setUndoManager(new UndoManager());\n        var editor = new Editor(new MockRenderer(), session);\n        var p = new PlaceHolder(session, 1, {row: 0, column: 4}, [{row: 1, column: 12}, {row: 1, column: 15}]);\n\n        editor.moveCursorTo(0, 5);\n        editor.insert('b');\n        editor.insert('cd');\n        editor.remove('left');\n        assert.equal(session.doc.getValue(), \"var abc = 10;\\nconsole.log(abc, abc);\");\n\n        // Wait a little for the changes to enter the undo stack\n        await lang.sleep(80);\n        p.cancel();\n        assert.equal(session.doc.getValue(), \"var a = 10;\\nconsole.log(a, a);\");\n        next();\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/range.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"../ace-internal\").Ace.IRange} IRange\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n */\n/**\n * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogous to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.\n **/\nclass Range {\n    /**\n     * Creates a new `Range` object with the given starting and ending rows and columns.\n     * @param {Number} [startRow] The starting row\n     * @param {Number} [startColumn] The starting column\n     * @param {Number} [endRow] The ending row\n     * @param {Number} [endColumn] The ending column\n     * @constructor\n     **/\n    constructor(startRow, startColumn, endRow, endColumn) {\n        /**@type {Point}*/\n        this.start = {\n            row: startRow,\n            column: startColumn\n        };\n        /**@type {Point}*/\n        this.end = {\n            row: endRow,\n            column: endColumn\n        };\n    }\n    \n    /**\n     * Returns `true` if and only if the starting row and column, and ending row and column, are equivalent to those given by `range`.\n     * @param {IRange} range A range to check against\n     * @return {Boolean}\n     **/\n    isEqual(range) {\n        return this.start.row === range.start.row &&\n            this.end.row === range.end.row &&\n            this.start.column === range.start.column &&\n            this.end.column === range.end.column;\n    }\n\n    /**\n     * Returns a string containing the range's row and column information, given like this:\n     * ```\n     *    [start.row/start.column] -> [end.row/end.column]\n     * ```\n     * @return {String}\n     **/\n    toString() {\n        return (\"Range: [\" + this.start.row + \"/\" + this.start.column +\n            \"] -> [\" + this.end.row + \"/\" + this.end.column + \"]\");\n    }\n\n    /**\n     * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:\n     * ```javascript\n     *    this.start.row <= row <= this.end.row &&\n     *    this.start.column <= column <= this.end.column\n     * ```\n     * @param {Number} row A row to check for\n     * @param {Number} column A column to check for\n     * @returns {Boolean}\n     * @related [[Range.compare]]\n     **/\n\n    contains(row, column) {\n        return this.compare(row, column) == 0;\n    }\n\n    /**\n     * Compares `this` range (A) with another range (B).\n     * @param {IRange} range A range to compare with\n     * @related [[Range.compare]]\n     * @returns {Number} This method returns one of the following numbers:\n     * * `-2`: (B) is in front of (A), and doesn't intersect with (A)\n     * * `-1`: (B) begins before (A) but ends inside of (A)\n     * * `0`: (B) is completely inside of (A)\n     * * `+1`: (B) begins inside of (A) but ends outside of (A)\n     * * `+2`: (B) is after (A) and doesn't intersect with (A)\n     * * `42`: FTW state: (B) ends in (A) but starts outside of (A)\n     **/\n    compareRange(range) {\n        var cmp,\n            end = range.end,\n            start = range.start;\n\n        cmp = this.compare(end.row, end.column);\n        if (cmp == 1) {\n            cmp = this.compare(start.row, start.column);\n            if (cmp == 1) {\n                return 2;\n            } else if (cmp == 0) {\n                return 1;\n            } else {\n                return 0;\n            }\n        } else if (cmp == -1) {\n            return -2;\n        } else {\n            cmp = this.compare(start.row, start.column);\n            if (cmp == -1) {\n                return -1;\n            } else if (cmp == 1) {\n                return 42;\n            } else {\n                return 0;\n            }\n        }\n    }\n\n    /**\n     * Compares the row and column of `p` with the starting and ending [[Point]]'s of the calling range (by calling [[Range.compare]]).\n     * @param {Point} p A point to compare with\n     * @related [[Range.compare]]\n     * @returns {Number}\n     **/\n    comparePoint(p) {\n        return this.compare(p.row, p.column);\n    }\n\n    /**\n     * Checks the start and end [[Point]]'s of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.\n     * @param {IRange} range A range to compare with\n     * @returns {Boolean}\n     * @related [[Range.comparePoint]]\n     **/\n    containsRange(range) {\n        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;\n    }\n\n    /**\n     * Returns `true` if passed in `range` intersects with the one calling this method.\n     * @param {IRange} range A range to compare with\n     * @returns {Boolean}\n     **/\n    intersects(range) {\n        var cmp = this.compareRange(range);\n        return (cmp == -1 || cmp == 0 || cmp == 1);\n    }\n\n    /**\n     * Returns `true` if the caller's ending row is the same as `row`, and if the caller's ending column is the same as `column`.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Boolean}\n     **/\n    isEnd(row, column) {\n        return this.end.row == row && this.end.column == column;\n    }\n\n    /**\n     * Returns `true` if the caller's starting row is the same as `row`, and if the caller's starting column is the same as `column`.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Boolean}\n     **/\n    isStart(row, column) {\n        return this.start.row == row && this.start.column == column;\n    }\n\n    /**\n     * Sets the starting row and column for the range.\n     * @param {Number|Point} row A row to set\n     * @param {Number} [column] A column to set\n     *\n     **/\n    setStart(row, column) {\n        if (typeof row == \"object\") {\n            this.start.column = row.column;\n            this.start.row = row.row;\n        } else {\n            this.start.row = row;\n            this.start.column = column;\n        }\n    }\n\n    /**\n     * Sets the starting row and column for the range.\n     * @param {Number|Point} row A row to set\n     * @param {Number} [column] A column to set\n     *\n     **/\n    setEnd(row, column) {\n        if (typeof row == \"object\") {\n            this.end.column = row.column;\n            this.end.row = row.row;\n        } else {\n            this.end.row = row;\n            this.end.column = column;\n        }\n    }\n\n    /**\n     * Returns `true` if the `row` and `column` are within the given range.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Boolean}\n     * @related [[Range.compare]]\n     **/\n    inside(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isEnd(row, column) || this.isStart(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Returns `true` if the `row` and `column` are within the given range's starting [[Point]].\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Boolean}\n     * @related [[Range.compare]]\n     **/\n    insideStart(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isEnd(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Returns `true` if the `row` and `column` are within the given range's ending [[Point]].\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Boolean}\n     * @related [[Range.compare]]\n     *\n     **/\n    insideEnd(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isStart(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Number} This method returns one of the following numbers:\n     * * `1` if `row` is greater than the calling range\n     * * `-1` if `row` is less then the calling range\n     * * `0` otherwise\n     *\n     * If the starting row of the calling range is equal to `row`, and:\n     * * `column` is greater than or equal to the calling range's starting column, this returns `0`\n     * * Otherwise, it returns -1\n     *\n     * If the ending row of the calling range is equal to `row`, and:\n     * * `column` is less than or equal to the calling range's ending column, this returns `0`\n     * * Otherwise, it returns 1\n     **/\n    compare(row, column) {\n        if (!this.isMultiLine()) {\n            if (row === this.start.row) {\n                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);\n            }\n        }\n\n        if (row < this.start.row)\n            return -1;\n\n        if (row > this.end.row)\n            return 1;\n\n        if (this.start.row === row)\n            return column >= this.start.column ? 0 : -1;\n\n        if (this.end.row === row)\n            return column <= this.end.column ? 0 : 1;\n\n        return 0;\n    }\n\n    /**\n     * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Number} This method returns one of the following numbers:\n     * * `-1` if calling range's starting column and calling range's starting row are equal `row` and `column`\n     * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n     **/\n    compareStart(row, column) {\n        if (this.start.row == row && this.start.column == column) {\n            return -1;\n        } else {\n            return this.compare(row, column);\n        }\n    }\n\n    /**\n     * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Number} This method returns one of the following numbers:\n     * * `1` if calling range's ending column and calling range's ending row are equal `row` and `column`.\n     * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n     */\n    compareEnd(row, column) {\n        if (this.end.row == row && this.end.column == column) {\n            return 1;\n        } else {\n            return this.compare(row, column);\n        }\n    }\n\n    /**\n     * Compares the `row` and `column` with the start and end [[Point]]'s of the calling range.\n     * @param {Number} row A row to compare with\n     * @param {Number} column A column to compare with\n     * @returns {Number} This method returns one of the following numbers:\n     * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`\n     * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`\n     * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n     **/\n    compareInside(row, column) {\n        if (this.end.row == row && this.end.column == column) {\n            return 1;\n        } else if (this.start.row == row && this.start.column == column) {\n            return -1;\n        } else {\n            return this.compare(row, column);\n        }\n    }\n\n    /**\n     * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.\n     * @param {Number} firstRow The starting row\n     * @param {Number} lastRow The ending row\n     * @returns {Range}\n    **/\n    clipRows(firstRow, lastRow) {\n        if (this.end.row > lastRow)\n            var end = {row: lastRow + 1, column: 0};\n        else if (this.end.row < firstRow)\n            var end = {row: firstRow, column: 0};\n\n        if (this.start.row > lastRow)\n            var start = {row: lastRow + 1, column: 0};\n        else if (this.start.row < firstRow)\n            var start = {row: firstRow, column: 0};\n\n        return Range.fromPoints(start || this.start, end || this.end);\n    }\n\n    /**\n     * Changes the `row` and `column` for the calling range for both the starting and ending [[Point]]'s.\n     * @param {Number} row A new row to extend to\n     * @param {Number} column A new column to extend to\n     * @returns {Range} The original range with the new row\n    **/\n    extend(row, column) {\n        var cmp = this.compare(row, column);\n\n        if (cmp == 0)\n            return this;\n        else if (cmp == -1)\n            var start = {row: row, column: column};\n        else\n            var end = {row: row, column: column};\n\n        return Range.fromPoints(start || this.start, end || this.end);\n    }\n\n    /**\n     * Returns `true` if the calling range is empty (starting [[Point]] == ending [[Point]]).\n     * @returns {Boolean}\n     **/\n    isEmpty() {\n        return (this.start.row === this.end.row && this.start.column === this.end.column);\n    }\n\n    /**\n     * Returns `true` if the range spans across multiple lines.\n     * @returns {Boolean}\n    **/\n    isMultiLine() {\n        return (this.start.row !== this.end.row);\n    }\n\n    /**\n     * Returns a duplicate of the calling range.\n     * @returns {Range}\n    **/\n    clone() {\n        return Range.fromPoints(this.start, this.end);\n    }\n\n    /**\n     * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.\n     * @returns {Range}\n    **/\n    collapseRows() {\n        if (this.end.column == 0)\n            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);\n        else\n            return new Range(this.start.row, 0, this.end.row, 0);\n    }\n\n    /**\n     * Given the current `Range`, this function converts those starting and ending [[Point]]'s into screen positions, and then returns a new `Range` object.\n     * @param {EditSession} session The `EditSession` to retrieve coordinates from\n     * @returns {Range}\n    **/\n    toScreenRange(session) {\n        var screenPosStart = session.documentToScreenPosition(this.start);\n        var screenPosEnd = session.documentToScreenPosition(this.end);\n\n        return new Range(\n            screenPosStart.row, screenPosStart.column,\n            screenPosEnd.row, screenPosEnd.column\n        );\n    }\n\n    /**\n     * Shift the calling range by `row` and `column` values.\n     * @param {Number} row\n     * @param {Number} column\n     * @experimental\n     */\n    moveBy(row, column) {\n        this.start.row += row;\n        this.start.column += column;\n        this.end.row += row;\n        this.end.column += column;\n    }\n\n}\n\n/**\n * Creates and returns a new `Range` based on the `start` [[Point]] and `end` [[Point]] of the given parameters.\n * @param {Point} start A starting point to use\n * @param {Point} end An ending point to use\n * @returns {Range}\n**/\nRange.fromPoints = function(start, end) {\n    return new Range(start.row, start.column, end.row, end.column);\n};\n\n/**\n * Compares `p1` and `p2` [[Point]]'s, useful for sorting\n * @param {Point} p1\n * @param {Point} p2\n * @returns {Number}\n */\nRange.comparePoints = function(p1, p2) {\n    return p1.row - p2.row || p1.column - p2.column;\n};\n\nexports.Range = Range;\n"
  },
  {
    "path": "src/range_list.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n */\nvar Range = require(\"./range\").Range;\nvar comparePoints = Range.comparePoints;\n\nclass RangeList {\n    \n    constructor() {\n        this.ranges = [];\n        this.$bias = 1;\n    }\n\n    /**\n     * @param {Point} pos\n     * @param {boolean} [excludeEdges]\n     * @param {number} [startIndex]\n     * @return {number}\n     */\n    pointIndex(pos, excludeEdges, startIndex) {\n        var list = this.ranges;\n\n        for (var i = startIndex || 0; i < list.length; i++) {\n            var range = list[i];\n            var cmpEnd = comparePoints(pos, range.end);\n            if (cmpEnd > 0)\n                continue;\n            var cmpStart = comparePoints(pos, range.start);\n            if (cmpEnd === 0)\n                return excludeEdges && cmpStart !== 0 ? -i-2 : i;\n            if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))\n                return i;\n\n            return -i-1;\n        }\n        return -i - 1;\n    }\n\n    /**\n     * @param {Range} range\n     */\n    add(range) {\n        var excludeEdges = !range.isEmpty();\n        var startIndex = this.pointIndex(range.start, excludeEdges);\n        if (startIndex < 0)\n            startIndex = -startIndex - 1;\n\n        var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);\n\n        if (endIndex < 0)\n            endIndex = -endIndex - 1;\n        else\n            endIndex++;\n        return this.ranges.splice(startIndex, endIndex - startIndex, range);\n    }\n\n    /**\n     * @param {Range[]} list\n     */\n    addList(list) {\n        var removed = [];\n        for (var i = list.length; i--; ) {\n            removed.push.apply(removed, this.add(list[i]));\n        }\n        return removed;\n    }\n\n    /**\n     * @param {Point} pos\n     */\n    substractPoint(pos) {\n        var i = this.pointIndex(pos);\n\n        if (i >= 0)\n            return this.ranges.splice(i, 1);\n    }\n\n    // merge overlapping ranges\n    merge() {\n        var removed = [];\n        var list = this.ranges;\n        \n        list = list.sort(function(a, b) {\n            return comparePoints(a.start, b.start);\n        });\n        \n        var next = list[0], range;\n        for (var i = 1; i < list.length; i++) {\n            range = next;\n            next = list[i];\n            var cmp = comparePoints(range.end, next.start);\n            if (cmp < 0)\n                continue;\n\n            if (cmp == 0 && !range.isEmpty() && !next.isEmpty())\n                continue;\n\n            if (comparePoints(range.end, next.end) < 0) {\n                range.end.row = next.end.row;\n                range.end.column = next.end.column;\n            }\n\n            list.splice(i, 1);\n            removed.push(next);\n            next = range;\n            i--;\n        }\n        \n        this.ranges = list;\n\n        return removed;\n    }\n\n    /**\n     * @param {number} row\n     * @param {number} column\n     */\n    contains(row, column) {\n        return this.pointIndex({row: row, column: column}) >= 0;\n    }\n\n    /**\n     * @param {Point} pos\n     */\n    containsPoint(pos) {\n        return this.pointIndex(pos) >= 0;\n    }\n\n    /**\n     * @param {Point} pos\n     */\n    rangeAtPoint(pos) {\n        var i = this.pointIndex(pos);\n        if (i >= 0)\n            return this.ranges[i];\n    }\n\n\n    /**\n     * @param {number} startRow\n     * @param {number} endRow\n     */\n    clipRows(startRow, endRow) {\n        var list = this.ranges;\n        if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)\n            return [];\n\n        var startIndex = this.pointIndex({row: startRow, column: 0});\n        if (startIndex < 0)\n            startIndex = -startIndex - 1;\n        //@ts-expect-error TODO: potential wrong argument\n        var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);\n        if (endIndex < 0)\n            endIndex = -endIndex - 1;\n\n        var clipped = [];\n        for (var i = startIndex; i < endIndex; i++) {\n            clipped.push(list[i]);\n        }\n        return clipped;\n    }\n\n    removeAll() {\n        return this.ranges.splice(0, this.ranges.length);\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    attach(session) {\n        if (this.session)\n            this.detach();\n\n        this.session = session;\n        this.onChange = this.$onChange.bind(this);\n\n        this.session.on('change', this.onChange);\n    }\n\n    detach() {\n        if (!this.session)\n            return;\n        this.session.removeListener('change', this.onChange);\n        this.session = null;\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     */\n    $onChange(delta) {\n        var start = delta.start;\n        var end = delta.end;\n        var startRow = start.row;\n        var endRow = end.row;\n        var ranges = this.ranges;\n        for (var i = 0, n = ranges.length; i < n; i++) {\n            var r = ranges[i];\n            if (r.end.row >= startRow)\n                break;\n        }\n        \n        if (delta.action == \"insert\") {\n            var lineDif = endRow - startRow;\n            var colDiff = -start.column + end.column;\n            for (; i < n; i++) {\n                var r = ranges[i];\n                if (r.start.row > startRow)\n                    break;\n    \n                if (r.start.row == startRow && r.start.column >= start.column) {\n                    if (r.start.column == start.column && this.$bias <= 0) {\n                        // do nothing\n                    } else {\n                        r.start.column += colDiff;\n                        r.start.row += lineDif;\n                    }\n                }\n                if (r.end.row == startRow && r.end.column >= start.column) {\n                    if (r.end.column == start.column && this.$bias < 0) {\n                        continue;\n                    }\n                    // special handling for the case when two ranges share an edge\n                    if (r.end.column == start.column && colDiff > 0 && i < n - 1) {\n                        if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)\n                            r.end.column -= colDiff;\n                    }\n                    r.end.column += colDiff;\n                    r.end.row += lineDif;\n                }\n            }\n        } else {\n            var lineDif = startRow - endRow;\n            var colDiff = start.column - end.column;\n            for (; i < n; i++) {\n                var r = ranges[i];\n                \n                if (r.start.row > endRow)\n                    break;\n                    \n                if (r.end.row < endRow\n                    && (\n                        startRow < r.end.row \n                        || startRow == r.end.row && start.column < r.end.column\n                    )\n                ) {\n                    r.end.row = startRow;\n                    r.end.column = start.column;\n                }\n                else if (r.end.row == endRow) {\n                    if (r.end.column <= end.column) {\n                        if (lineDif || r.end.column > start.column) {\n                            r.end.column = start.column;\n                            r.end.row = start.row;\n                        }\n                    }\n                    else {\n                        r.end.column += colDiff;\n                        r.end.row += lineDif;\n                    }\n                }\n                else if (r.end.row > endRow) {\n                    r.end.row += lineDif;\n                }\n                \n                if (r.start.row < endRow\n                    && (\n                        startRow < r.start.row \n                        || startRow == r.start.row && start.column < r.start.column\n                    )\n                ) {\n                    r.start.row = startRow;\n                    r.start.column = start.column;\n                }\n                else if (r.start.row == endRow) {\n                    if (r.start.column <= end.column) {\n                        if (lineDif || r.start.column > start.column) {\n                            r.start.column = start.column;\n                            r.start.row = start.row;\n                        }\n                    }\n                    else {\n                        r.start.column += colDiff;\n                        r.start.row += lineDif;\n                    }\n                }\n                else if (r.start.row > endRow) {\n                    r.start.row += lineDif;\n                }\n            }\n        }\n\n        if (lineDif != 0 && i < n) {\n            for (; i < n; i++) {\n                var r = ranges[i];\n                r.start.row += lineDif;\n                r.end.row += lineDif;\n            }\n        }\n    }\n\n}\n\nRangeList.prototype.comparePoints = comparePoints;\n\nexports.RangeList = RangeList;\n"
  },
  {
    "path": "src/range_list_test.js",
    "content": "\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar RangeList = require(\"./range_list\").RangeList;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar assert = require(\"./test/assertions\");\n\nfunction flatten(rangeList) {\n    var points = [];\n    rangeList.ranges.forEach(function(r) {\n        points.push(r.start.row, r.start.column, r.end.row, r.end.column);\n    });\n    return points;\n}\nfunction testRangeList(rangeList, points) {\n    assert.equal(\"\" + flatten(rangeList), \"\" + points);\n}\n\nmodule.exports = {\n\n    name: \"ACE range_list.js\",\n\n    \"test: rangeList pointIndex\": function() {\n        var rangeList = new RangeList();\n        rangeList.ranges = [\n            new Range(1,2,3,4),\n            new Range(4,2,5,4),\n            new Range(8,8,9,9)\n        ];\n\n        assert.equal(rangeList.pointIndex({row: 0, column: 1}), -1);\n        assert.equal(rangeList.pointIndex({row: 1, column: 2}), 0);\n        assert.equal(rangeList.pointIndex({row: 1, column: 3}), 0);\n        assert.equal(rangeList.pointIndex({row: 3, column: 4}), 0);\n        assert.equal(rangeList.pointIndex({row: 4, column: 1}), -2);\n        assert.equal(rangeList.pointIndex({row: 5, column: 1}), 1);\n        assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2);\n        assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4);\n    },\n    \n    \"test: rangeList pointIndex excludeEdges\": function() {\n        var rangeList = new RangeList();\n        rangeList.ranges = [\n            new Range(1,2,3,4),\n            new Range(4,2,5,4),\n            new Range(8,8,9,9),\n            new Range(10,10,10,10)\n        ];\n\n        assert.equal(rangeList.pointIndex({row: 0, column: 1}, true), -1);\n        assert.equal(rangeList.pointIndex({row: 1, column: 2}, true), -1);\n        assert.equal(rangeList.pointIndex({row: 1, column: 3}, true), 0);\n        assert.equal(rangeList.pointIndex({row: 3, column: 4}, true), -2);\n        assert.equal(rangeList.pointIndex({row: 4, column: 1}, true), -2);\n        assert.equal(rangeList.pointIndex({row: 5, column: 1}, true), 1);\n        assert.equal(rangeList.pointIndex({row: 8, column: 9}, true), 2);\n        assert.equal(rangeList.pointIndex({row: 10, column: 10}, true), 3);\n        assert.equal(rangeList.pointIndex({row: 18, column: 9}, true), -5);\n    },\n\n    \"test: rangeList add\": function() {\n        var rangeList = new RangeList();\n        rangeList.addList([\n            new Range(9,0,9,1),\n            new Range(1,2,3,4),\n            new Range(8,8,9,9),\n            new Range(4,2,5,4),\n            new Range(3,20,3,24),\n            new Range(6,6,7,7)\n        ]);\n        assert.equal(rangeList.ranges.length, 5);\n\n        rangeList.add(new Range(1,2,3,5));\n        assert.range(rangeList.ranges[0], 1,2,3,5);\n        assert.equal(rangeList.ranges.length, 5);\n\n        rangeList.add(new Range(7,7,7,7));\n        assert.range(rangeList.ranges[3], 7,7,7,7);\n        rangeList.add(new Range(7,8,7,8));\n        assert.range(rangeList.ranges[4], 7,8,7,8);\n    },\n\n    \"test: rangeList add empty\": function() {\n        var rangeList = new RangeList();\n        rangeList.addList([\n            new Range(7,10,7,10),\n            new Range(9,10,9,10),\n            new Range(8,10,8,10)\n        ]);\n        assert.equal(rangeList.ranges.length, 3);\n\n        rangeList.add(new Range(9,10,9,10));\n        testRangeList(rangeList, [7,10,7,10,8,10,8,10,9,10,9,10]);\n    },\n\n    \"test: rangeList merge\": function() {\n        var rangeList = new RangeList();\n        rangeList.addList([\n            new Range(1,2,3,4),\n            new Range(4,2,5,4),\n            new Range(6,6,7,7),\n            new Range(8,8,9,9)\n        ]);\n        var removed = [];\n\n        assert.equal(rangeList.ranges.length, 4);\n\n        rangeList.ranges[1].end.row = 7;\n        removed = rangeList.merge();\n        assert.equal(removed.length, 1);\n        assert.range(rangeList.ranges[1], 4,2,7,7);\n        assert.equal(rangeList.ranges.length, 3);\n\n        rangeList.ranges[0].end.row = 10;\n        removed = rangeList.merge();\n        assert.range(rangeList.ranges[0], 1,2,10,4);\n        assert.equal(removed.length, 2);\n        assert.equal(rangeList.ranges.length, 1);\n\n        rangeList.ranges.push(new Range(10,10,10,10));\n        rangeList.ranges.push(new Range(10,10,10,10));\n        removed = rangeList.merge();\n        assert.equal(rangeList.ranges.length, 2);\n    },\n\n    \"test: rangeList remove\": function() {\n        var rangeList = new RangeList();\n        var list = [\n            new Range(1,2,3,4),\n            new Range(4,2,5,4),\n            new Range(6,6,7,7),\n            new Range(8,8,9,9)\n        ];\n        rangeList.addList(list);\n        assert.equal(rangeList.ranges.length, 4);\n        rangeList.substractPoint({row: 1, column: 2});\n        assert.equal(rangeList.ranges.length, 3);\n        rangeList.substractPoint({row: 6, column: 7});\n        assert.equal(rangeList.ranges.length, 2);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/range_test.js",
    "content": "\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar assert = require(\"./test/assertions\");\n\nmodule.exports = {\n    \n    name: \"ACE range.js\",\n    \n    \"test: create range\": function() {\n        var range = new Range(1,2,3,4);\n\n        assert.equal(range.start.row, 1);\n        assert.equal(range.start.column, 2);\n        assert.equal(range.end.row, 3);\n        assert.equal(range.end.column, 4);\n    },\n\n    \"test: create from points\": function() {\n        var range = Range.fromPoints({row: 1, column: 2}, {row:3, column:4});\n\n        assert.equal(range.start.row, 1);\n        assert.equal(range.start.column, 2);\n        assert.equal(range.end.row, 3);\n        assert.equal(range.end.column, 4);\n    },\n\n    \"test: clip to rows\": function() {\n        assert.range(new Range(0, 20, 100, 30).clipRows(10, 30), 10, 0, 31, 0);\n        assert.range(new Range(0, 20, 30, 10).clipRows(10, 30), 10, 0, 30, 10);\n\n        var range = new Range(0, 20, 3, 10);\n        var range = range.clipRows(10, 30);\n\n        assert.ok(range.isEmpty());\n        assert.range(range, 10, 0, 10, 0);\n    },\n\n    \"test: isEmpty\": function() {\n        var range = new Range(1, 2, 1, 2);\n        assert.ok(range.isEmpty());\n\n        var range = new Range(1, 2, 1, 6);\n        assert.notOk(range.isEmpty());\n    },\n\n    \"test: is multi line\": function() {\n        var range = new Range(1, 2, 1, 6);\n        assert.notOk(range.isMultiLine());\n\n        var range = new Range(1, 2, 2, 6);\n        assert.ok(range.isMultiLine());\n    },\n\n    \"test: clone\": function() {\n        var range = new Range(1, 2, 3, 4);\n        var clone = range.clone();\n\n        assert.position(clone.start, 1, 2);\n        assert.position(clone.end, 3, 4);\n\n        clone.start.column = 20;\n        assert.position(range.start, 1, 2);\n\n        clone.end.column = 20;\n        assert.position(range.end, 3, 4);\n    },\n\n    \"test: contains for multi line ranges\": function() {\n        var range = new Range(1, 10, 5, 20);\n\n        assert.ok(range.contains(1, 10));\n        assert.ok(range.contains(2, 0));\n        assert.ok(range.contains(3, 100));\n        assert.ok(range.contains(5, 19));\n        assert.ok(range.contains(5, 20));\n\n        assert.notOk(range.contains(1, 9));\n        assert.notOk(range.contains(0, 0));\n        assert.notOk(range.contains(5, 21));\n    },\n\n    \"test: contains for single line ranges\": function() {\n        var range = new Range(1, 10, 1, 20);\n\n        assert.ok(range.contains(1, 10));\n        assert.ok(range.contains(1, 15));\n        assert.ok(range.contains(1, 20));\n\n        assert.notOk(range.contains(0, 9));\n        assert.notOk(range.contains(2, 9));\n        assert.notOk(range.contains(1, 9));\n        assert.notOk(range.contains(1, 21));\n    },\n\n    \"test: extend range\": function() {\n        var range = new Range(2, 10, 2, 30);\n\n        var range = range.extend(2, 5);\n        assert.range(range, 2, 5, 2, 30);\n\n        var range = range.extend(2, 35);\n        assert.range(range, 2, 5, 2, 35);\n\n        var range = range.extend(2, 15);\n        assert.range(range, 2, 5, 2, 35);\n\n        var range = range.extend(1, 4);\n        assert.range(range, 1, 4, 2, 35);\n\n        var range = range.extend(6, 10);\n        assert.range(range, 1, 4, 6, 10);\n    },\n\n    \"test: collapse rows\" : function() {\n        var range = new Range(0, 2, 1, 2);\n        assert.range(range.collapseRows(), 0, 0, 1, 0);\n\n        var range = new Range(2, 2, 3, 1);\n        assert.range(range.collapseRows(), 2, 0, 3, 0);\n\n        var range = new Range(2, 2, 3, 0);\n        assert.range(range.collapseRows(), 2, 0, 2, 0);\n\n        var range = new Range(2, 0, 2, 0);\n        assert.range(range.collapseRows(), 2, 0, 2, 0);\n    },\n    \n    \"test: to screen range\" : function() {\n        var session = new EditSession([\n            \"juhu\",\n            \"12\\t\\t34\",\n            \"ぁぁa\",\n            \"\\t\\t34\"\n        ]);\n        \n        var range = new Range(0, 0, 0, 3);\n        assert.range(range.toScreenRange(session), 0, 0, 0, 3);\n        \n        var range = new Range(1, 1, 1, 3);\n        assert.range(range.toScreenRange(session), 1, 1, 1, 4);\n        \n        var range = new Range(2, 1, 2, 2);\n        assert.range(range.toScreenRange(session), 2, 2, 2, 4);\n\n        var range = new Range(3, 0, 3, 4);\n        assert.range(range.toScreenRange(session), 3, 0, 3, 10);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/renderloop.js",
    "content": "\"use strict\";\n\nvar event = require(\"./lib/event\");\n\n/**\n * Batches changes (that force something to be redrawn) in the background.\n **/\nclass RenderLoop {\n    \n    constructor(onRender, win) {\n        this.onRender = onRender;\n        this.pending = false;\n        this.changes = 0;\n        this.$recursionLimit = 2;\n        this.window = win || window;\n        var _self = this;\n        this._flush = function (ts) {\n            _self.pending = false;\n            var changes = _self.changes;\n\n            if (changes) {\n                event.blockIdle(100);\n                _self.changes = 0;\n                _self.onRender(changes);\n            }\n\n            if (_self.changes) {\n                if (_self.$recursionLimit-- < 0) return;\n                _self.schedule();\n            }\n            else {\n                _self.$recursionLimit = 2;\n            }\n        };\n    }\n\n    schedule(change) {\n        this.changes = this.changes | change;\n        if (this.changes && !this.pending) {\n            event.nextFrame(this._flush);\n            this.pending = true;\n        }\n    }\n\n    clear(change) {\n        var changes = this.changes;\n        this.changes = 0;\n        return changes;\n    }\n    \n}\n\nexports.RenderLoop = RenderLoop;\n"
  },
  {
    "path": "src/scrollbar.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar event = require(\"./lib/event\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n// on ie maximal element height is smaller than what we get from 4-5K line document\n// so scrollbar doesn't work, as a workaround we do not set height higher than MAX_SCROLL_H\n// and rescale scrolltop\nvar MAX_SCROLL_H = 0x8000;\n\n/**\n * An abstract class representing a native scrollbar control.\n **/\nclass Scrollbar {\n    /**\n     * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {string} classSuffix\n     **/\n    constructor(parent, classSuffix) {\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_scrollbar ace_scrollbar\" + classSuffix;\n        this.element.tabIndex = -1;\n\n        this.inner = dom.createElement(\"div\");\n        this.inner.className = \"ace_scrollbar-inner\";\n        // on safari scrollbar is not shown for empty elements\n        this.inner.textContent = \"\\xa0\";\n        this.element.appendChild(this.inner);\n\n        parent.appendChild(this.element);\n\n        this.setVisible(false);\n        this.skipEvent = false;\n\n        // @ts-expect-error\n        event.addListener(this.element, \"scroll\", this.onScroll.bind(this));\n        event.addListener(this.element, \"mousedown\", event.preventDefault);\n    }\n\n    setVisible(isVisible) {\n        this.element.style.display = isVisible ? \"\" : \"none\";\n        this.isVisible = isVisible;\n        this.coeff = 1;\n    }\n}\noop.implement(Scrollbar.prototype, EventEmitter);\n\n/**\n * Represents a vertical scroll bar.\n **/\nclass VScrollBar extends Scrollbar {\n    /**\n     * Creates a new `VScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {Object} renderer An editor renderer\n     **/\n    constructor(parent, renderer) {\n        super(parent, '-v');\n        this.scrollTop = 0;\n        this.scrollHeight = 0;\n\n        // in OSX lion the scrollbars appear to have no width. In this case resize the\n        // element to show the scrollbar but still pretend that the scrollbar has a width\n        // of 0px\n        // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar\n        // make element a little bit wider to retain scrollbar when page is zoomed\n        renderer.$scrollbarWidth =\n            this.width = dom.scrollbarWidth(parent.ownerDocument);\n        this.inner.style.width =\n            this.element.style.width = (this.width || 15) + 5 + \"px\";\n        this.$minWidth = 0;\n    }\n\n\n    /**\n     * Emitted when the scroll bar, well, scrolls.\n     * @event scroll\n     * @internal\n     **/\n\n    onScroll() {\n        if (!this.skipEvent) {\n            this.scrollTop = this.element.scrollTop;\n            if (this.coeff != 1) {\n                var h = this.element.clientHeight / this.scrollHeight;\n                this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h);\n            }\n            this._emit(\"scroll\", {data: this.scrollTop});\n        }\n        this.skipEvent = false;\n    }\n\n    /**\n     * Returns the width of the scroll bar.\n     * @returns {Number}\n     **/\n    getWidth() {\n        return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);\n    }\n\n    /**\n     * Sets the height of the scroll bar, in pixels.\n     * @param {Number} height The new height\n     **/\n    setHeight(height) {\n        this.element.style.height = height + \"px\";\n    }\n\n    /**\n     * Sets the scroll height of the scroll bar, in pixels.\n     * @param {Number} height The new scroll height\n     **/\n    setScrollHeight(height) {\n        this.scrollHeight = height;\n        if (height > MAX_SCROLL_H) {\n            this.coeff = MAX_SCROLL_H / height;\n            height = MAX_SCROLL_H;\n        } else if (this.coeff != 1) {\n            this.coeff = 1;\n        }\n        this.inner.style.height = height + \"px\";\n    }\n\n\n    /**\n     * Sets the scroll top of the scroll bar.\n     * @param {Number} scrollTop The new scroll top\n     **/\n    setScrollTop(scrollTop) {\n        // on chrome 17+ for small zoom levels after calling this function\n        // this.element.scrollTop != scrollTop which makes page to scroll up.\n        if (this.scrollTop != scrollTop) {\n            this.skipEvent = true;\n            this.scrollTop = scrollTop;\n            this.element.scrollTop = scrollTop * this.coeff;\n        }\n    }\n\n}\n\n/**\n * Sets the inner height of the scroll bar, in pixels.\n * @param {Number} height The new inner height\n * @deprecated Use setScrollHeight instead\n **/\nVScrollBar.prototype.setInnerHeight = VScrollBar.prototype.setScrollHeight;\n\n/**\n * Represents a horisontal scroll bar.\n **/\nclass HScrollBar extends Scrollbar {\n    /**\n     * Creates a new `HScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {Object} renderer An editor renderer\n     **/\n    constructor(parent, renderer) {\n        super(parent, '-h');\n        this.scrollLeft = 0;\n\n        // in OSX lion the scrollbars appear to have no width. In this case resize the\n        // element to show the scrollbar but still pretend that the scrollbar has a width\n        // of 0px\n        // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar\n        // make element a little bit wider to retain scrollbar when page is zoomed\n        this.height = renderer.$scrollbarWidth;\n        this.inner.style.height =\n            this.element.style.height = (this.height || 15) + 5 + \"px\";\n    }\n\n    /**\n     * Emitted when the scroll bar, well, scrolls.\n     * @event scroll\n     * @internal\n     **/\n    onScroll() {\n        if (!this.skipEvent) {\n            this.scrollLeft = this.element.scrollLeft;\n            this._emit(\"scroll\", {data: this.scrollLeft});\n        }\n        this.skipEvent = false;\n    }\n\n    /**\n     * Returns the height of the scroll bar.\n     * @returns {Number}\n     **/\n    getHeight() {\n        return this.isVisible ? this.height : 0;\n    }\n\n    /**\n     * Sets the width of the scroll bar, in pixels.\n     * @param {Number} width The new width\n     **/\n    setWidth(width) {\n        this.element.style.width = width + \"px\";\n    }\n\n    /**\n     * Sets the inner width of the scroll bar, in pixels.\n     * @param {Number} width The new inner width\n     * @deprecated Use setScrollWidth instead\n     **/\n    setInnerWidth(width) {\n        this.inner.style.width = width + \"px\";\n    }\n\n    /**\n     * Sets the scroll width of the scroll bar, in pixels.\n     * @param {Number} width The new scroll width\n     **/\n    setScrollWidth(width) {\n        this.inner.style.width = width + \"px\";\n    }\n\n    /**\n     * Sets the scroll left of the scroll bar.\n     * @param {Number} scrollLeft The new scroll left\n     **/\n    setScrollLeft(scrollLeft) {\n        // on chrome 17+ for small zoom levels after calling this function\n        // this.element.scrollTop != scrollTop which makes page to scroll up.\n        if (this.scrollLeft != scrollLeft) {\n            this.skipEvent = true;\n            this.scrollLeft = this.element.scrollLeft = scrollLeft;\n        }\n    }\n\n}\n\n\nexports.ScrollBar = VScrollBar; // backward compatibility\nexports.ScrollBarV = VScrollBar; // backward compatibility\nexports.ScrollBarH = HScrollBar; // backward compatibility\n\nexports.VScrollBar = VScrollBar;\nexports.HScrollBar = HScrollBar;\n"
  },
  {
    "path": "src/scrollbar_custom.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar event = require(\"./lib/event\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n\ndom.importCssString(`.ace_editor>.ace_sb-v div, .ace_editor>.ace_sb-h div{\n  position: absolute;\n  background: rgba(128, 128, 128, 0.6);\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  border: 1px solid #bbb;\n  border-radius: 2px;\n  z-index: 8;\n}\n.ace_editor>.ace_sb-v, .ace_editor>.ace_sb-h {\n  position: absolute;\n  z-index: 6;\n  background: none;\n  overflow: hidden!important;\n}\n.ace_editor>.ace_sb-v {\n  z-index: 6;\n  right: 0;\n  top: 0;\n  width: 12px;\n}\n.ace_editor>.ace_sb-v div {\n  z-index: 8;\n  right: 0;\n  width: 100%;\n}\n.ace_editor>.ace_sb-h {\n  bottom: 0;\n  left: 0;\n  height: 12px;\n}\n.ace_editor>.ace_sb-h div {\n  bottom: 0;\n  height: 100%;\n}\n.ace_editor>.ace_sb_grabbed {\n  z-index: 8;\n  background: #000;\n}`, \"ace_scrollbar.css\", false);\n\n/**\n * An abstract class representing a native scrollbar control.\n **/\nclass ScrollBar {\n    /**\n     * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {string} classSuffix\n     **/\n    constructor(parent, classSuffix) {\n        this.element = dom.createElement(\"div\");\n        this.element.className = \"ace_sb\" + classSuffix;\n        this.inner = dom.createElement(\"div\");\n        this.inner.className = \"\";\n        this.element.appendChild(this.inner);\n        this.VScrollWidth = 12;\n        this.HScrollHeight = 12;\n\n        parent.appendChild(this.element);\n        this.setVisible(false);\n        this.skipEvent = false;\n\n        event.addMultiMouseDownListener(this.element, [500, 300, 300], this, \"onMouseDown\");\n    }\n\n    setVisible(isVisible) {\n        this.element.style.display = isVisible ? \"\" : \"none\";\n        this.isVisible = isVisible;\n        this.coeff = 1;\n    }\n}\n\noop.implement(ScrollBar.prototype, EventEmitter);\n/**\n * Represents a vertical scroll bar.\n * @class VScrollBar\n **/\n\n/**\n * Creates a new `VScrollBar`. `parent` is the owner of the scroll bar.\n * @param {Element} parent A DOM element\n * @param {Object} renderer An editor renderer\n *\n * @constructor\n **/\nclass VScrollBar extends ScrollBar {\n\n    constructor(parent, renderer) {\n        super(parent, '-v');\n        this.scrollTop = 0;\n        this.scrollHeight = 0;\n        this.parent = parent;\n        this.width = this.VScrollWidth;\n        this.renderer = renderer;\n        this.inner.style.width = this.element.style.width = (this.width || 15) + \"px\";\n        this.$minWidth = 0;\n    }\n\n    /**\n     * Emitted when the scroll thumb dragged or scrollbar canvas clicked.\n     * @internal\n     **/\n    onMouseDown(eType, e) {\n        if (eType !== \"mousedown\") return;\n\n        if (event.getButton(e) !== 0 || e.detail === 2) {\n            return;\n        }\n\n        if (e.target === this.inner) {\n            var self = this;\n            var mousePageY = e.clientY;\n\n            var onMouseMove = function (e) {\n                mousePageY = e.clientY;\n            };\n\n            var onMouseUp = function () {\n                clearInterval(timerId);\n            };\n            var startY = e.clientY;\n            var startTop = this.thumbTop;\n\n            var onScrollInterval = function () {\n                if (mousePageY === undefined) return;\n                var scrollTop = self.scrollTopFromThumbTop(startTop + mousePageY - startY);\n                if (scrollTop === self.scrollTop) return;\n                self._emit(\"scroll\", {data: scrollTop});\n            };\n\n            event.capture(this.inner, onMouseMove, onMouseUp);\n            var timerId = setInterval(onScrollInterval, 20);\n            return event.preventDefault(e);\n        }\n        var top = e.clientY - this.element.getBoundingClientRect().top - this.thumbHeight / 2;\n        this._emit(\"scroll\", {data: this.scrollTopFromThumbTop(top)});\n        return event.preventDefault(e);\n    }\n\n    getHeight() {\n        return this.height;\n    }\n\n    /**\n     * Returns new top for scroll thumb\n     * @param {Number}thumbTop\n     * @returns {Number}\n     **/\n    scrollTopFromThumbTop(thumbTop) {\n        var scrollTop = thumbTop * (this.pageHeight - this.viewHeight) / (this.slideHeight - this.thumbHeight);\n        scrollTop = scrollTop >> 0;\n        if (scrollTop < 0) {\n            scrollTop = 0;\n        }\n        else if (scrollTop > this.pageHeight - this.viewHeight) {\n            scrollTop = this.pageHeight - this.viewHeight;\n        }\n        return scrollTop;\n    }\n\n    /**\n     * Returns the width of the scroll bar.\n     * @returns {Number}\n     **/\n    getWidth() {\n        return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);\n    }\n\n    /**\n     * Sets the height of the scroll bar, in pixels.\n     * @param {Number} height The new height\n     **/\n    setHeight(height) {\n        this.height = Math.max(0, height);\n        this.slideHeight = this.height;\n        this.viewHeight = this.height;\n\n        this.setScrollHeight(this.pageHeight, true);\n    }\n\n    /**\n     * Sets the inner and scroll height of the scroll bar, in pixels.\n     * @param {Number} height The new inner height\n     *\n     * @param {boolean} force Forcely update height\n     **/\n    setScrollHeight(height, force) {\n        if (this.pageHeight === height && !force) return;\n        this.pageHeight = height;\n        this.thumbHeight = this.slideHeight * this.viewHeight / this.pageHeight;\n\n        if (this.thumbHeight > this.slideHeight) this.thumbHeight = this.slideHeight;\n        if (this.thumbHeight < 15) this.thumbHeight = 15;\n\n        this.inner.style.height = this.thumbHeight + \"px\";\n\n        if (this.scrollTop > (this.pageHeight - this.viewHeight)) {\n            this.scrollTop = (this.pageHeight - this.viewHeight);\n            if (this.scrollTop < 0) this.scrollTop = 0;\n            this._emit(\"scroll\", {data: this.scrollTop});\n        }\n    }\n\n    /**\n     * Sets the scroll top of the scroll bar.\n     * @param {Number} scrollTop The new scroll top\n     **/\n    setScrollTop(scrollTop) {\n        this.scrollTop = scrollTop;\n        if (scrollTop < 0) scrollTop = 0;\n        this.thumbTop = scrollTop * (this.slideHeight - this.thumbHeight) / (this.pageHeight - this.viewHeight);\n        this.inner.style.top = this.thumbTop + \"px\";\n    }\n}\n\nVScrollBar.prototype.setInnerHeight = VScrollBar.prototype.setScrollHeight;\n\n/**\n * Represents a horizontal scroll bar.\n **/\nclass HScrollBar extends ScrollBar {\n    /**\n     * Creates a new `HScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {Object} renderer An editor renderer\n     **/\n    constructor(parent, renderer) {\n        super(parent, '-h');\n        this.scrollLeft = 0;\n        this.scrollWidth = 0;\n        this.height = this.HScrollHeight;\n        this.inner.style.height = this.element.style.height = (this.height || 12) + \"px\";\n        this.renderer = renderer;\n    }\n\n    /**\n     * Emitted when the scroll thumb dragged or scrollbar canvas clicked.\n     * @internal\n     **/\n    onMouseDown(eType, e) {\n        if (eType !== \"mousedown\") return;\n\n        if (event.getButton(e) !== 0 || e.detail === 2) {\n            return;\n        }\n\n\n        if (e.target === this.inner) {\n            var self = this;\n            var mousePageX = e.clientX;\n\n            var onMouseMove = function (e) {\n                mousePageX = e.clientX;\n            };\n\n            var onMouseUp = function () {\n                clearInterval(timerId);\n            };\n            var startX = e.clientX;\n            var startLeft = this.thumbLeft;\n\n            var onScrollInterval = function () {\n                if (mousePageX === undefined) return;\n                var scrollLeft = self.scrollLeftFromThumbLeft(startLeft + mousePageX - startX);\n                if (scrollLeft === self.scrollLeft) return;\n                self._emit(\"scroll\", {data: scrollLeft});\n            };\n\n            event.capture(this.inner, onMouseMove, onMouseUp);\n            var timerId = setInterval(onScrollInterval, 20);\n            return event.preventDefault(e);\n        }\n\n        var left = e.clientX - this.element.getBoundingClientRect().left - this.thumbWidth / 2;\n        this._emit(\"scroll\", {data: this.scrollLeftFromThumbLeft(left)});\n        return event.preventDefault(e);\n    }\n\n    /**\n     * Returns the height of the scroll bar.\n     * @returns {Number}\n     **/\n    getHeight() {\n        return this.isVisible ? this.height : 0;\n    }\n\n    /**\n     * Returns new left for scroll thumb\n     * @param {Number} thumbLeft\n     * @returns {Number}\n     **/\n    scrollLeftFromThumbLeft(thumbLeft) {\n        var scrollLeft = thumbLeft * (this.pageWidth - this.viewWidth) / (this.slideWidth - this.thumbWidth);\n        scrollLeft = scrollLeft >> 0;\n        if (scrollLeft < 0) {\n            scrollLeft = 0;\n        }\n        else if (scrollLeft > this.pageWidth - this.viewWidth) {\n            scrollLeft = this.pageWidth - this.viewWidth;\n        }\n        return scrollLeft;\n    }\n\n    /**\n     * Sets the width of the scroll bar, in pixels.\n     * @param {Number} width The new width\n     **/\n    setWidth(width) {\n        this.width = Math.max(0, width);\n        this.element.style.width = this.width + \"px\";\n        this.slideWidth = this.width;\n        this.viewWidth = this.width;\n\n        this.setScrollWidth(this.pageWidth, true);\n    }\n\n    /**\n     * Sets the inner and scroll width of the scroll bar, in pixels.\n     * @param {Number} width The new inner width\n     * @param {boolean} force Forcely update width\n     **/\n     setScrollWidth(width, force) {\n        if (this.pageWidth === width && !force) return;\n        this.pageWidth = width;\n        this.thumbWidth = this.slideWidth * this.viewWidth / this.pageWidth;\n\n        if (this.thumbWidth > this.slideWidth) this.thumbWidth = this.slideWidth;\n        if (this.thumbWidth < 15) this.thumbWidth = 15;\n        this.inner.style.width = this.thumbWidth + \"px\";\n\n        if (this.scrollLeft > (this.pageWidth - this.viewWidth)) {\n            this.scrollLeft = (this.pageWidth - this.viewWidth);\n            if (this.scrollLeft < 0) this.scrollLeft = 0;\n            this._emit(\"scroll\", {data: this.scrollLeft});\n        }\n    }\n\n\n    /**\n     * Sets the scroll left of the scroll bar.\n     * @param {Number} scrollLeft The new scroll left\n     **/\n    setScrollLeft(scrollLeft) {\n        this.scrollLeft = scrollLeft;\n        if (scrollLeft < 0) scrollLeft = 0;\n        this.thumbLeft = scrollLeft * (this.slideWidth - this.thumbWidth) / (this.pageWidth - this.viewWidth);\n        this.inner.style.left = (this.thumbLeft) + \"px\";\n    }\n\n}\n\nHScrollBar.prototype.setInnerWidth = HScrollBar.prototype.setScrollWidth;\n\nexports.ScrollBar = VScrollBar; // backward compatibility\nexports.ScrollBarV = VScrollBar; // backward compatibility\nexports.ScrollBarH = HScrollBar; // backward compatibility\n\nexports.VScrollBar = VScrollBar;\nexports.HScrollBar = HScrollBar;\n"
  },
  {
    "path": "src/scrollbar_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"./test/assertions\");\nvar VirtualRenderer = require(\"./virtual_renderer\").VirtualRenderer;\nvar Editor = require(\"./editor\").Editor;\nvar lang = require(\"./lib/lang\");\n\nvar MouseEvent = function (type, opts) {\n    var e = document.createEvent(\"MouseEvents\");\n    e.initMouseEvent(/click|wheel/.test(type) ? type : \"mouse\" + type, true, true, window, opts.detail, opts.x, opts.y,\n        opts.x, opts.y, opts.ctrl, opts.alt, opts.shift, opts.meta, opts.button || 0, opts.relatedTarget\n    );\n    return e;\n};\nvar WheelEvent = function (opts) {\n    var e = new MouseEvent(\"wheel\", opts);\n    e.DOM_DELTA_PIXEL = 0;\n    e.DOM_DELTA_LINE = 1;\n    e.DOM_DELTA_PAGE = 2;\n    e.deltaMode = e[\"DOM_DELTA_\" + opts.mode.toUpperCase()];\n    e.deltaX = opts.x || 0;\n    e.deltaY = opts.y || 0;\n    return e;\n};\nvar editor = null;\nvar renderer = null;\nmodule.exports = {\n    name: \"ACE scrollbar_custom.js\",\n    setUp: function () {\n        if (editor) editor.destroy();\n        var el = document.createElement(\"div\");\n\n        el.style.left = \"20px\";\n        el.style.top = \"30px\";\n        el.style.width = \"300px\";\n        el.style.height = \"100px\";\n        document.body.appendChild(el);\n        renderer = new VirtualRenderer(el);\n        renderer.scrollHeight = 50;\n        renderer.layerConfig.maxHeight = 200;\n        renderer.layerConfig.lineHeight = 14;\n        editor = new Editor(renderer);\n        editor.on(\"destroy\", function () {\n            document.body.removeChild(el);\n        });\n        editor.setOptions({\n            customScrollbar: true\n        });\n        // TODO remove this when onresize doesn't recreate custom scrollbar\n        renderer.$loop._flush();\n    },\n    tearDown: function () {\n        editor && editor.destroy();\n        editor = null;\n    },\n    \"test: vertical scrolling\": function () {\n        editor.setValue(\"a\" + \"\\n\".repeat(100) + \"b\" + \"\\nxxxxxx\", -1);\n        renderer.$loop._flush();\n        renderer.scrollBarV.element.dispatchEvent(MouseEvent(\"down\", {\n            x: 0,\n            y: 80,\n            button: 0\n        }));\n        renderer.$loop._flush();\n        var thumbTop = renderer.scrollBarV.thumbTop;\n        assert.ok(thumbTop > 0);\n        editor.container.dispatchEvent(WheelEvent({\n            mode: \"line\",\n            y: 50\n        }));\n        renderer.$loop._flush();\n        assert.ok(renderer.scrollBarV.thumbTop > thumbTop);\n    },\n    \"test: dragging vertical scroll thumb\": async function (done) {\n        editor.setValue(\"a\" + \"\\n\".repeat(100) + \"b\" + \"\\nxxxxxx\", -1);\n        renderer.$loop._flush();\n\n        renderer.scrollBarV.inner.dispatchEvent(MouseEvent(\"down\", {\n            x: 5,\n            y: 10,\n            button: 0\n        }));\n        renderer.$loop._flush();\n\n        renderer.scrollBarV.inner.dispatchEvent(MouseEvent(\"move\", {\n            x: 5,\n            y: 80,\n            button: 0\n        }));\n\n        await lang.sleep(200);\n        assert.ok(renderer.scrollBarV.thumbTop > 0);\n        done();\n    },\n    \"test: horizontal scrolling\": function () {\n        assert.ok(!renderer.scrollBarH.isVisible);\n        editor.setValue(\"a\".repeat(1000), -1);\n\n        renderer.$loop._flush();\n        assert.ok(renderer.scrollBarH.isVisible);\n        renderer.scrollBarH.element.dispatchEvent(MouseEvent(\"down\", {\n            x: 80,\n            y: 0,\n            button: 0\n        }));\n        renderer.$loop._flush();\n\n        assert.ok(renderer.scrollBarH.thumbLeft > 0);\n    },\n    \"test: dragging horizontal scroll thumb\": async function (done) {\n        editor.setValue(\"a\".repeat(1000), -1);\n        renderer.$loop._flush();\n\n        renderer.scrollBarH.inner.dispatchEvent(MouseEvent(\"down\", {\n            x: 5,\n            y: 5,\n            button: 0\n        }));\n        renderer.$loop._flush();\n\n        renderer.scrollBarH.inner.dispatchEvent(MouseEvent(\"move\", {\n            x: 80,\n            y: 5,\n            button: 0\n        }));\n\n        await lang.sleep(200);\n        assert.ok(renderer.scrollBarH.thumbLeft > 0);\n        done();\n    }\n\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/search.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"../ace-internal\").Ace.SearchOptions} SearchOptions\n */\nvar lang = require(\"./lib/lang\");\nvar oop = require(\"./lib/oop\");\nvar Range = require(\"./range\").Range;\n\n/**\n * A class designed to handle all sorts of text searches within a [[Document `Document`]].\n **/\nclass Search {\n\n    constructor() {\n        /**@type {Partial<SearchOptions>}*/\n        this.$options = {};\n    }\n\n    /**\n     * Sets the search options via the `options` parameter.\n     * @param {Partial<SearchOptions>} options An object containing all the new search properties\n     * @returns {Search}\n     * @chainable\n    **/\n    set(options) {\n        oop.mixin(this.$options, options);\n        return this;\n    }\n\n    /**\n     * [Returns an object containing all the search options.]{: #Search.getOptions}\n     * @returns {Partial<SearchOptions>}\n    **/\n    getOptions() {\n        return lang.copyObject(this.$options);\n    }\n\n    /**\n     * Sets the search options via the `options` parameter.\n     * @param {Partial<SearchOptions>} options object containing all the search propertie\n     * @related Search.set\n    **/\n    setOptions(options) {\n        this.$options = options;\n    }\n\n    /**\n     * Searches for `options.needle`. If found, this method returns the [[Range `Range`]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.\n     * @param {EditSession} session The session to search with\n     * @returns {Range | null | false}\n     **/\n    find(session) {\n        var options = this.$options;\n        var iterator = this.$matchIterator(session, options);\n        if (!iterator)\n            return false;\n\n        var firstRange = null;\n        iterator.forEach(function(sr, sc, er, ec) {\n            firstRange = new Range(sr, sc, er, ec);\n            if (sc == ec && options.start && /**@type{Range}*/(options.start).start\n                && options.skipCurrent != false && firstRange.isEqual(/**@type{Range}*/(options.start))\n            ) {\n                firstRange = null;\n                return false;\n            }\n\n            return true;\n        });\n\n        return firstRange;\n    }\n\n    /**\n     * Searches for all occurrances `options.needle`. If found, this method returns an array of [[Range `Range`s]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.\n     * @param {EditSession} session The session to search with\n     * @returns {Range[]}\n    **/\n    findAll(session) {\n        var options = this.$options;\n        if (!options.needle)\n            return [];\n        this.$assembleRegExp(options);\n\n        var range = options.range;\n        var lines = range\n            ? session.getLines(range.start.row, range.end.row)\n            : session.doc.getAllLines();\n\n        var ranges = [];\n        var re = options.re;\n        if (options.$isMultiLine) {\n            var len = re.length;\n            var maxRow = lines.length - len;\n            var prevRange;\n            outer: for (var row = re.offset || 0; row <= maxRow; row++) {\n                for (var j = 0; j < len; j++)\n                    if (lines[row + j].search(re[j]) == -1)\n                        continue outer;\n\n                var startLine = lines[row];\n                var line = lines[row + len - 1];\n                var startIndex = startLine.length - startLine.match(re[0])[0].length;\n                var endIndex = line.match(re[len - 1])[0].length;\n\n                if (prevRange && prevRange.end.row === row &&\n                    prevRange.end.column > startIndex\n                ) {\n                    continue;\n                }\n                ranges.push(prevRange = new Range(\n                    row, startIndex, row + len - 1, endIndex\n                ));\n                if (len > 2)\n                    row = row + len - 2;\n            }\n        } else {\n            for (var matches, i = 0; i < lines.length; i++) {\n                if (this.$isMultilineSearch(options)) {\n                    var lng = lines.length - 1;\n                    matches = this.$multiLineForward(session, re, i, lng);\n                    if (matches) {\n                        var end_row = matches.endRow <= lng ? matches.endRow - 1 : lng;\n                        if (end_row > i)\n                            i = end_row;\n                        ranges.push(new Range(matches.startRow, matches.startCol, matches.endRow, matches.endCol));\n                    }\n                }\n                else {\n                    matches = lang.getMatchOffsets(lines[i], re);\n                    for (var j = 0; j < matches.length; j++) {\n                        var match = matches[j];\n                        ranges.push(new Range(i, match.offset, i, match.offset + match.length));\n                    }\n                }\n            }\n        }\n\n        if (range) {\n            var startColumn = range.start.column;\n            var endColumn = range.end.column;\n            var i = 0, j = ranges.length - 1;\n            while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == 0)\n                i++;\n\n            var endRow = range.end.row - range.start.row;\n            while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == endRow)\n                j--;\n\n            ranges = ranges.slice(i, j + 1);\n            for (i = 0, j = ranges.length; i < j; i++) {\n                ranges[i].start.row += range.start.row;\n                ranges[i].end.row += range.start.row;\n            }\n        }\n\n        return ranges;\n    }\n\n    parseReplaceString(replaceString) {\n        var CharCode = {\n            DollarSign: 36,\n            Ampersand: 38,\n            Digit0: 48,\n            Digit1: 49,\n            Digit9: 57,\n            Backslash: 92,\n            n: 110,\n            t: 116\n        };\n\n        var replacement = '';\n        for (var i = 0, len = replaceString.length; i < len; i++) {\n            var chCode = replaceString.charCodeAt(i);\n            if (chCode === CharCode.Backslash) {\n                // move to next char\n                i++;\n                if (i >= len) {\n                    // string ends with a \\\n                    replacement += \"\\\\\";\n                    break;\n                }\n                var nextChCode = replaceString.charCodeAt(i);\n                switch (nextChCode) {\n                    case CharCode.Backslash:\n                        // \\\\ => inserts a \"\\\"\n                        replacement += \"\\\\\";\n                        break;\n                    case CharCode.n:\n                        // \\n => inserts a LF\n                        replacement += \"\\n\";\n                        break;\n                    case CharCode.t:\n                        // \\t => inserts a TAB\n                        replacement += \"\\t\";\n                        break;\n                }\n                continue;\n            }\n\n            if (chCode === CharCode.DollarSign) {\n                // move to next char\n                i++;\n                if (i >= len) {\n                    // string ends with a $\n                    replacement += \"$\";\n                    break;\n                }\n                const nextChCode = replaceString.charCodeAt(i);\n                if (nextChCode === CharCode.DollarSign) {\n                    // $$ => inserts a \"$\"\n                    replacement += \"$$\";\n                    continue;\n                }\n                if (nextChCode === CharCode.Digit0 || nextChCode === CharCode.Ampersand) {\n                    // replace $0 to $&, making it compatible with JavaScript\n                    // $0 and $& => inserts the matched substring.\n                    replacement += \"$&\";\n                    continue;\n                }\n                if (CharCode.Digit1 <= nextChCode && nextChCode <= CharCode.Digit9) {\n                    // $n\n                    replacement += \"$\" + replaceString[i];\n                    continue;\n                }\n            }\n\n            replacement += replaceString[i];\n        }\n        return replacement || replaceString;\n    }\n\n    /**\n     * Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.\n     * @param {String} input The text to search in\n     * @param {any} replacement The replacing text\n     * + (String): If `options.regExp` is `true`, this function returns `input` with the replacement already made. Otherwise, this function just returns `replacement`.<br/>\n     * If `options.needle` was not found, this function returns `null`.\n     *\n     *\n     * @returns {String}\n    **/\n    replace(input, replacement) {\n        var options = this.$options;\n\n        var re = this.$assembleRegExp(options);\n        if (options.$isMultiLine)\n            return replacement;\n\n        if (!re)\n            return;\n\n        /**\n         * Convert all line ending variations to Unix-style = \\n\n         * Windows (\\r\\n), MacOS Classic (\\r), and Unix (\\n)\n         */\n        var mtSearch = this.$isMultilineSearch(options);\n        if (mtSearch)\n            input = input.replace(/\\r\\n|\\r|\\n/g, \"\\n\");\n\n        var match = re.exec(input);\n        if (!match || (!mtSearch && match[0].length != input.length))\n            return null;\n\n        replacement = options.regExp\n            ? this.parseReplaceString(replacement)\n            : replacement.replace(/\\$/g, \"$$$$\");\n\n        replacement = input.replace(re, replacement);\n        if (options.preserveCase) {\n            replacement = replacement.split(\"\");\n            for (var i = Math.min(input.length, input.length); i--; ) {\n                var ch = input[i];\n                if (ch && ch.toLowerCase() != ch)\n                    replacement[i] = replacement[i].toUpperCase();\n                else\n                    replacement[i] = replacement[i].toLowerCase();\n            }\n            replacement = replacement.join(\"\");\n        }\n\n        return replacement;\n    }\n\n    /**\n     *\n     * @param {Partial<SearchOptions>} options\n     * @param {boolean} [$disableFakeMultiline]\n     * @return {RegExp|boolean|*[]|*}\n     */\n    $assembleRegExp(options, $disableFakeMultiline) {\n        if (options.needle instanceof RegExp)\n            return options.re = options.needle;\n\n        var needle = options.needle;\n\n        if (!options.needle)\n            return options.re = false;\n\n        if (!options.regExp)\n            needle = lang.escapeRegExp(needle);\n\n        var modifier = options.caseSensitive ? \"gm\" : \"gmi\";\n\n        try {\n            new RegExp(needle, \"u\");\n            options.$supportsUnicodeFlag = true;\n            modifier += \"u\";\n        } catch (e) {\n            options.$supportsUnicodeFlag = false; //left for backward compatibility with previous versions for cases like /ab\\{2}/gu\n        }\n\n        if (options.wholeWord)\n            needle = addWordBoundary(needle, options);\n\n        options.$isMultiLine = !$disableFakeMultiline && /[\\n\\r]/.test(needle);\n        if (options.$isMultiLine)\n            return options.re = this.$assembleMultilineRegExp(needle, modifier);\n\n        try {\n            /**@type {RegExp|false}*/\n            var re = new RegExp(needle, modifier);\n        } catch(e) {\n            re = false;\n        }\n        return options.re = re;\n    }\n\n    /**\n     * @param {string} needle\n     * @param {string} modifier\n     */\n    $assembleMultilineRegExp(needle, modifier) {\n        var parts = needle.replace(/\\r\\n|\\r|\\n/g, \"$\\n^\").split(\"\\n\");\n        var re = [];\n        for (var i = 0; i < parts.length; i++) try {\n            re.push(new RegExp(parts[i], modifier));\n        } catch(e) {\n            return false;\n        }\n        return re;\n    }\n\n    $isMultilineSearch(options) {\n        return options.re && /\\\\r\\\\n|\\\\r|\\\\n/.test(options.re.source) && options.regExp && !options.$isMultiLine;\n    }\n\n    $multiLineForward(session, re, start, last) {\n        var line,\n            chunk = chunkEnd(session, start);\n\n        for (var row = start; row <= last;) {\n            for (var i = 0; i < chunk; i++) {\n                if (row > last)\n                    break;\n                var next = session.getLine(row++);\n                line = line == null ? next : line + \"\\n\" + next;\n            }\n\n            var match = re.exec(line);\n            re.lastIndex = 0;\n            if (match) {\n                var beforeMatch = line.slice(0, match.index).split(\"\\n\");\n                var matchedText = match[0].split(\"\\n\");\n                var startRow = start + beforeMatch.length - 1;\n                var startCol = beforeMatch[beforeMatch.length - 1].length;\n                var endRow = startRow + matchedText.length - 1;\n                var endCol = matchedText.length == 1\n                    ? startCol + matchedText[0].length\n                    : matchedText[matchedText.length - 1].length;\n\n                return {\n                    startRow: startRow,\n                    startCol: startCol,\n                    endRow: endRow,\n                    endCol: endCol\n                };\n            }\n        }\n        return null;\n    }\n\n    $multiLineBackward(session, re, endIndex, start, first) {\n        var line,\n            chunk = chunkEnd(session, start),\n            endMargin = session.getLine(start).length - endIndex;\n\n        for (var row = start; row >= first;) {\n            for (var i = 0; i < chunk && row >= first; i++) {\n                var next = session.getLine(row--);\n                line = line == null ? next : next + \"\\n\" + line;\n            }\n\n            var match = multiLineBackwardMatch(line, re, endMargin);\n            if (match) {\n                var beforeMatch = line.slice(0, match.index).split(\"\\n\");\n                var matchedText = match[0].split(\"\\n\");\n                var startRow = row + beforeMatch.length;\n                var startCol = beforeMatch[beforeMatch.length - 1].length;\n                var endRow = startRow + matchedText.length - 1;\n                var endCol = matchedText.length == 1\n                    ? startCol + matchedText[0].length\n                    : matchedText[matchedText.length - 1].length;\n\n                return {\n                    startRow: startRow,\n                    startCol: startCol,\n                    endRow: endRow,\n                    endCol: endCol\n                };\n            }\n        }\n        return null;\n    }\n\n    /**\n     * @param {EditSession} session\n     */\n    $matchIterator(session, options) {\n        var re = this.$assembleRegExp(options);\n        if (!re)\n            return false;\n\n        var mtSearch = this.$isMultilineSearch(options);\n        var mtForward = this.$multiLineForward;\n        var mtBackward = this.$multiLineBackward;\n\n        var backwards = options.backwards == true;\n        var skipCurrent = options.skipCurrent != false;\n        var supportsUnicodeFlag = re.unicode;\n\n        var range = options.range;\n        var start = options.start;\n        if (!start)\n            start = range ? range[backwards ? \"end\" : \"start\"] : session.selection.getRange();\n\n        if (start.start)\n            start = start[skipCurrent != backwards ? \"end\" : \"start\"];\n\n        var firstRow = range ? range.start.row : 0;\n        var lastRow = range ? range.end.row : session.getLength() - 1;\n\n        if (backwards) {\n            var forEach = function(callback) {\n                var row = start.row;\n                if (forEachInLine(row, start.column, callback))\n                    return;\n                for (row--; row >= firstRow; row--)\n                    if (forEachInLine(row, Number.MAX_VALUE, callback))\n                        return;\n                if (options.wrap == false)\n                    return;\n                for (row = lastRow, firstRow = start.row; row >= firstRow; row--)\n                    if (forEachInLine(row, Number.MAX_VALUE, callback))\n                        return;\n            };\n        }\n        else {\n            var forEach = function(callback) {\n                var row = start.row;\n                if (forEachInLine(row, start.column, callback))\n                    return;\n                for (row = row + 1; row <= lastRow; row++)\n                    if (forEachInLine(row, 0, callback))\n                        return;\n                if (options.wrap == false)\n                    return;\n                for (row = firstRow, lastRow = start.row; row <= lastRow; row++)\n                    if (forEachInLine(row, 0, callback))\n                        return;\n            };\n        }\n\n        if (options.$isMultiLine) {\n            var len = re.length;\n            var forEachInLine = function(row, offset, callback) {\n                var startRow = backwards ? row - len + 1 : row;\n                if (startRow < 0 || startRow + len > session.getLength()) return;\n                var line = session.getLine(startRow);\n                var startIndex = line.search(re[0]);\n                if (!backwards && startIndex < offset || startIndex === -1) return;\n                for (var i = 1; i < len; i++) {\n                    line = session.getLine(startRow + i);\n                    if (line.search(re[i]) == -1)\n                        return;\n                }\n                var endIndex = line.match(re[len - 1])[0].length;\n                if (backwards && endIndex > offset) return;\n                if (callback(startRow, startIndex, startRow + len - 1, endIndex))\n                    return true;\n            };\n        }\n        else if (backwards) {\n            var forEachInLine = function(row, endIndex, callback) {\n                if (mtSearch) {\n                    var pos = mtBackward(session, re, endIndex, row, firstRow);\n                    if (!pos)\n                        return false;\n                    if (callback(pos.startRow, pos.startCol, pos.endRow, pos.endCol))\n                        return true;\n                }\n                else {\n                    var line = session.getLine(row);\n                    var matches = [];\n                    var m, last = 0;\n                    re.lastIndex = 0;\n                    while((m = re.exec(line))) {\n                        var length = m[0].length;\n                        last = m.index;\n                        if (!length) {\n                            if (last >= line.length) break;\n                            re.lastIndex = last += lang.skipEmptyMatch(line, last, supportsUnicodeFlag);\n                        }\n                        if (m.index + length > endIndex)\n                            break;\n                        matches.push(m.index, length);\n                    }\n                    for (var i = matches.length - 1; i >= 0; i -= 2) {\n                        var column = matches[i - 1];\n                        var length = matches[i];\n                        if (callback(row, column, row, column + length))\n                            return true;\n                    }\n                }\n            };\n        }\n        else {\n            var forEachInLine = function(row, startIndex, callback) {\n                re.lastIndex = startIndex;\n                if (mtSearch) {\n                    var pos = mtForward(session, re, row, lastRow);\n                    if (pos) {\n                        var end_row = pos.endRow <= lastRow ? pos.endRow - 1 : lastRow;\n                        if (end_row > row)\n                            row = end_row;\n                    }\n                    if (!pos)\n                        return false;\n                    if (callback(pos.startRow, pos.startCol, pos.endRow, pos.endCol))\n                        return true;\n                }\n                else {\n                    var line = session.getLine(row);\n                    var last;\n                    var m;\n                    while((m = re.exec(line))) {\n                        var length = m[0].length;\n                        last = m.index;\n                        if (callback(row, last, row, last + length))\n                            return true;\n                        if (!length) {\n                            re.lastIndex = last += lang.skipEmptyMatch(line, last, supportsUnicodeFlag);\n                            if (last >= line.length) return false;\n                        }\n                    }\n                }\n            };\n        }\n        return {forEach: forEach};\n    }\n\n}\n\n/**\n *\n * @param {string} needle\n * @param {Partial<SearchOptions>} options\n * @return {string}\n */\nfunction addWordBoundary(needle, options) {\n    let supportsLookbehind = lang.supportsLookbehind();\n\n    function wordBoundary(c, firstChar = true) {\n        let wordRegExp = supportsLookbehind && options.$supportsUnicodeFlag ? new RegExp(\"[\\\\p{L}\\\\p{N}_]\",\"u\") : new RegExp(\"\\\\w\");\n\n        if (wordRegExp.test(c) || options.regExp) {\n            if (supportsLookbehind && options.$supportsUnicodeFlag) {\n                if (firstChar) return \"(?<=^|[^\\\\p{L}\\\\p{N}_])\";\n                return \"(?=[^\\\\p{L}\\\\p{N}_]|$)\";\n            }\n            return \"\\\\b\";\n        }\n        return \"\";\n    }\n\n    let needleArray = Array.from(needle);\n    let firstChar = needleArray[0];\n    let lastChar = needleArray[needleArray.length - 1];\n\n    return wordBoundary(firstChar) + needle + wordBoundary(lastChar, false);\n}\n\nfunction multiLineBackwardMatch(line, re, endMargin) {\n    var match = null;\n    var from = 0;\n    while (from <= line.length) {\n        re.lastIndex = from;\n        var newMatch = re.exec(line);\n        if (!newMatch)\n            break;\n        var end = newMatch.index + newMatch[0].length;\n        if (end > line.length - endMargin)\n            break;\n        if (!match || end > match.index + match[0].length)\n            match = newMatch;\n        from = newMatch.index + 1;\n    }\n    return match;\n}\n\nfunction chunkEnd(session, start) {\n    var base = 5000,\n        startPosition = { row: start, column: 0 },\n        startIndex = session.doc.positionToIndex(startPosition),\n        targetIndex = startIndex + base,\n        targetPosition = session.doc.indexToPosition(targetIndex),\n        targetLine = targetPosition.row;\n    return targetLine + 1;\n}\n\nexports.Search = Search;\n"
  },
  {
    "path": "src/search_highlight.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./layer/marker\").Marker} Marker\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n */\nvar lang = require(\"./lib/lang\");\nvar Range = require(\"./range\").Range;\n\nclass SearchHighlight {\n    /**\n     * @param {any} regExp\n     * @param {string} clazz\n     */\n    constructor(regExp, clazz, type = \"text\") {\n        this.setRegexp(regExp);\n        this.clazz = clazz;\n        this.type = type;\n        this.docLen = 0;\n    }\n\n    setRegexp(regExp) {\n        if (this.regExp+\"\" == regExp+\"\")\n            return;\n        this.regExp = regExp;\n        this.cache = [];\n    }\n\n    /**\n     * @param {any} html\n     * @param {Marker} markerLayer\n     * @param {EditSession} session\n     * @param {Partial<import(\"../ace-internal\").Ace.LayerConfig>} config\n     */\n    update(html, markerLayer, session, config) {\n        if (!this.regExp)\n            return;\n        var start = config.firstRow;\n        var end = config.lastRow;\n        var renderedMarkerRanges = {};\n        var _search = session.$editor && session.$editor.$search;\n        var mtSearch = _search && _search.$isMultilineSearch(session.$editor.getLastSearchOptions());\n\n        for (var i = start; i <= end; i++) {\n            var ranges = this.cache[i];\n            if (ranges == null || session.getValue().length != this.docLen) {\n                if (mtSearch) {\n                    ranges = [];\n                    var match = _search.$multiLineForward(session, this.regExp, i, end);\n                    if (match) {\n                        var end_row = match.endRow <= end ? match.endRow - 1 : end;\n                        if (end_row > i)\n                            i = end_row;\n                        ranges.push(new Range(match.startRow, match.startCol, match.endRow, match.endCol));\n                    }\n                    if (ranges.length > this.MAX_RANGES)\n                        ranges = ranges.slice(0, this.MAX_RANGES);\n                }\n                else {\n                    ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);\n                    if (ranges.length > this.MAX_RANGES)\n                        ranges = ranges.slice(0, this.MAX_RANGES);\n                    ranges = ranges.map(function(match) {\n                        return new Range(i, match.offset, i, match.offset + match.length);\n                    });\n                }\n                this.cache[i] = ranges.length ? ranges : \"\";\n            }\n\n            if (ranges.length === 0) continue;\n\n            for (var j = ranges.length; j --; ) {\n                var rangeToAddMarkerTo = ranges[j].toScreenRange(session);\n                var rangeAsString = rangeToAddMarkerTo.toString();\n                if (renderedMarkerRanges[rangeAsString]) continue;\n\n                renderedMarkerRanges[rangeAsString] = true;\n                markerLayer.drawSingleLineMarker(\n                    html, rangeToAddMarkerTo, this.clazz, config);\n            }\n        }\n        this.docLen = session.getValue().length;\n    }\n}\n\n// needed to prevent long lines from freezing the browser\nSearchHighlight.prototype.MAX_RANGES = 500;\n\nexports.SearchHighlight = SearchHighlight;\n"
  },
  {
    "path": "src/search_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar Editor = require(\"./editor\").Editor;\nvar Search = require(\"./search\").Search;\nvar assert = require(\"./test/assertions\");\nvar Range = require(\"./range\").Range;\n\nmodule.exports = {\n    \"test: configure the search object\" : function() {\n        var search = new Search();\n        search.set({\n            needle: \"juhu\"\n        });\n    },\n\n    \"test: find simple text in document\" : function() {\n        var session = new EditSession([\"juhu kinners 123\", \"456\"]);\n        var search = new Search().set({\n            needle: \"kinners\"\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 5);\n        assert.position(range.end, 0, 12);\n    },\n\n    \"test: find simple text in next line\" : function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n        var search = new Search().set({\n            needle: \"kinners\"\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 5);\n        assert.position(range.end, 1, 12);\n    },\n\n    \"test: find text starting at cursor position\" : function() {\n        var session = new EditSession([\"juhu kinners\", \"juhu kinners 123\"]);\n        session.getSelection().moveCursorTo(0, 6);\n        var search = new Search().set({\n            needle: \"kinners\"\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 5);\n        assert.position(range.end, 1, 12);\n    },\n\n    \"test: wrap search is on by default\" : function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n        session.getSelection().moveCursorTo(2, 1);\n\n        var search = new Search().set({\n            needle: \"kinners\"\n        });\n\n        assert.notEqual(search.find(session), null);\n    },\n\n    \"test: wrap search should wrap at file end\" : function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n        session.getSelection().moveCursorTo(2, 1);\n\n        var search = new Search().set({\n            needle: \"kinners\",\n            wrap: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 5);\n        assert.position(range.end, 1, 12);\n    },\n\n    \"test: wrap search should find needle even if it starts inside it\" : function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n        session.getSelection().moveCursorTo(6, 1);\n\n        var search = new Search().set({\n            needle: \"kinners\",\n            wrap: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 5);\n        assert.position(range.end, 1, 12);\n    },\n\n    \"test: wrap search with no match should return 'null'\": function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n        session.getSelection().moveCursorTo(2, 1);\n\n        var search = new Search().set({\n            needle: \"xyz\",\n            wrap: true\n        });\n\n        assert.equal(search.find(session), null);\n    },\n\n    \"test: case sensitive is by default off\": function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n\n        var search = new Search().set({\n            needle: \"JUHU\"\n        });\n\n        assert.range(search.find(session), 1, 0, 1, 4);\n    },\n\n    \"test: case sensitive search\": function() {\n        var session = new EditSession([\"abc\", \"juhu kinners 123\", \"456\"]);\n\n        var search = new Search().set({\n            needle: \"KINNERS\",\n            caseSensitive: true\n        });\n\n        var range = search.find(session);\n        assert.equal(range, null);\n    },\n\n    \"test: whole word search should not match inside of words\": function() {\n        var session = new EditSession([\"juhukinners\", \"juhu kinners 123\", \"456\"]);\n\n        var search = new Search().set({\n            needle: \"kinners\",\n            wholeWord: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 5);\n        assert.position(range.end, 1, 12);\n    },\n\n    \"test: fallback to nonUnicode mode on edge cases\": function() {\n        var session = new EditSession([\n            /* eslint-disable no-octal-escape*/\n            \"string with \\xa9 symbol\",  // test octal escape sequence\n            \"bracket ab{2}\"  // test lone quantifier brackets\n        ]);\n\n        var search = new Search().set({\n            needle: \"\\\\251\",\n            regExp: true\n        });\n        var range = search.find(session);\n        assert.position(range.start, 0, 12);\n        assert.position(range.end, 0, 13);\n\n        search.set({ needle: \"ab\\\\{2}\" });\n        range = search.find(session);\n        assert.position(range.start, 1, 8);\n        assert.position(range.end, 1, 13);\n    },\n\n    \"test: whole word search should not match inside of words with unicode\": function() {\n        var session = new EditSession([\"𝓗ello𝓦orld\", \"𝓗ello 𝓦orld 123\", \"456\"]);\n\n        var search = new Search().set({\n            needle: \"𝓗ello\",\n            wholeWord: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 0);\n        assert.position(range.end, 1, 6);\n    },\n\n    \"test: return to unicode mode when possible\": function() {\n        var session = new EditSession([\"𝓕oo\"]);\n\n        var search = new Search().set({\n            needle: \"}\",\n            regExp: true\n        });\n\n        search.find(session);\n        search.set({\n            needle: \".\"\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 0, 2);\n    },\n\n    \"test: empty match before surrogate pair\": function() {\n        var session = new EditSession([\"𝓕oo\"]);\n\n        var search = new Search().set({\n            needle: \"()\",\n            regExp: true,\n            start: new Range(0, 0, 0, 0)\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 2);\n        assert.position(range.end, 0, 2);\n    },\n\n    \"test: find backwards\": function() {\n        var session = new EditSession([\"juhu juhu juhu juhu\"]);\n        session.getSelection().moveCursorTo(0, 10);\n        var search = new Search().set({\n            needle: \"juhu\",\n            backwards: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 5);\n        assert.position(range.end, 0, 9);\n    },\n\n    \"test: find in selection\": function() {\n        var session = new EditSession([\"juhu\", \"juhu\", \"juhu\", \"juhu\"]);\n        session.getSelection().setSelectionAnchor(1, 0);\n        session.getSelection().selectTo(3, 5);\n\n        var search = new Search().set({\n            needle: \"juhu\",\n            wrap: true,\n            range: session.getSelection().getRange()\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 0);\n        assert.position(range.end, 1, 4);\n\n        search = new Search().set({\n            needle: \"juhu\",\n            wrap: true,\n            range: session.getSelection().getRange()\n        });\n\n        session.getSelection().setSelectionAnchor(0, 2);\n        session.getSelection().selectTo(3, 2);\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 0);\n        assert.position(range.end, 1, 4);\n    },\n\n    \"test: find backwards in selection\": function() {\n        var session = new EditSession([\"juhu\", \"juhu\", \"juhu\", \"juhu\"]);\n\n        session.getSelection().setSelectionAnchor(0, 2);\n        session.getSelection().selectTo(3, 2);\n\n        var search = new Search().set({\n            needle: \"juhu\",\n            wrap: true,\n            backwards: true,\n            range: session.getSelection().getRange()\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 2, 0);\n        assert.position(range.end, 2, 4);\n\n        search = new Search().set({\n            needle: \"juhu\",\n            wrap: true,\n            range: session.getSelection().getRange()\n        });\n\n        session.getSelection().setSelectionAnchor(0, 2);\n        session.getSelection().selectTo(1, 2);\n\n        var range = search.find(session);\n        assert.position(range.start, 1, 0);\n        assert.position(range.end, 1, 4);\n    },\n\n    \"test: edge case - match directly before the cursor\" : function() {\n        var session = new EditSession([\"123\", \"123\", \"juhu\"]);\n\n        var search = new Search().set({\n            needle: \"juhu\",\n            wrap: true\n        });\n\n        session.getSelection().moveCursorTo(2, 5);\n\n        var range = search.find(session);\n        assert.position(range.start, 2, 0);\n        assert.position(range.end, 2, 4);\n    },\n\n    \"test: edge case - match backwards directly after the cursor\" : function() {\n        var session = new EditSession([\"123\", \"123\", \"juhu\"]);\n\n        var search = new Search().set({\n            needle: \"juhu\",\n            wrap: true,\n            backwards: true\n        });\n\n        session.getSelection().moveCursorTo(2, 0);\n\n        var range = search.find(session);\n        assert.position(range.start, 2, 0);\n        assert.position(range.end, 2, 4);\n    },\n\n    \"test: find using a regular expression\" : function() {\n        var session = new EditSession([\"abc123 123 cd\", \"abc\"]);\n\n        var search = new Search().set({\n            needle: \"\\\\d+\",\n            regExp: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 3);\n        assert.position(range.end, 0, 6);\n    },\n\n    \"test: find using a regular expression and whole word\" : function() {\n        var session = new EditSession([\"abc123 123 cd\", \"abc\"]);\n\n        var search = new Search().set({\n            needle: \"\\\\d+\\\\b\",\n            regExp: true,\n            wholeWord: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 7);\n        assert.position(range.end, 0, 10);\n    },\n\n    \"test: use regular expressions with capture groups\": function() {\n        var session = new EditSession([\"  ab: 12px\", \"  <h1 abc\"]);\n\n        var search = new Search().set({\n            needle: \"(\\\\d+)\",\n            regExp: true\n        });\n\n        var range = search.find(session);\n        assert.position(range.start, 0, 6);\n        assert.position(range.end, 0, 8);\n    },\n\n    \"test: find all matches in selection\" : function() {\n        var session = new EditSession([\"juhu\", \"juhu\", \"juhu\", \"juhu\"]);\n\n        session.getSelection().setSelectionAnchor(0, 2);\n        session.getSelection().selectTo(3, 2);\n\n        var search = new Search().set({\n            needle: \"uh\",\n            wrap: true,\n            range: session.getSelection().getRange()\n        });\n\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 2);\n        assert.position(ranges[0].start, 1, 1);\n        assert.position(ranges[0].end, 1, 3);\n        assert.position(ranges[1].start, 2, 1);\n        assert.position(ranges[1].end, 2, 3);\n    },\n\n\n    \"test: find all multiline matches\" : function() {\n        var session = new EditSession([\"juhu\", \"juhu\", \"juhu\", \"juhu\"]);\n\n        var search = new Search().set({\n            needle: \"hu\\nju\",\n            wrap: true\n        });\n\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 3);\n        assert.position(ranges[0].start, 0, 2);\n        assert.position(ranges[0].end, 1, 2);\n        assert.position(ranges[1].start, 1, 2);\n        assert.position(ranges[1].end, 2, 2);\n    },\n\n    \"test: replace() should return the replacement if the input matches the needle\" : function() {\n        var search = new Search().set({\n            needle: \"juhu\"\n        });\n\n        assert.equal(search.replace(\"juhu\", \"kinners\"), \"kinners\");\n        assert.equal(search.replace(\"\", \"kinners\"), null);\n        assert.equal(search.replace(\" juhu\", \"kinners\"), null);\n\n        // case sensitivity\n        assert.equal(search.replace(\"Juhu\", \"kinners\"), \"kinners\");\n        search.set({caseSensitive: true});\n        assert.equal(search.replace(\"Juhu\", \"kinners\"), null);\n\n        // regexp replacement\n    },\n\n    \"test: replace with a RegExp search\" : function() {\n        var search = new Search().set({\n            needle: \"\\\\d+\",\n            regExp: true\n        });\n\n        assert.equal(search.replace(\"123\", \"kinners\"), \"kinners\");\n        assert.equal(search.replace(\"01234\", \"kinners\"), \"kinners\");\n        assert.equal(search.replace(\"\", \"kinners\"), null);\n        assert.equal(search.replace(\"a12\", \"kinners\"), null);\n        assert.equal(search.replace(\"12a\", \"kinners\"), null);\n    },\n\n    \"test: replace with RegExp match and capture groups\" : function() {\n        var search = new Search().set({\n            needle: \"ab((\\\\d)\\\\d)\",\n            regExp: true\n        });\n\n        assert.equal(search.replace(\"ab12\", \"cd$1\"), \"cd12\");\n        assert.equal(search.replace(\"ab56\", \"pr$17$2\"), \"pr5675\");\n        assert.equal(search.replace(\"ab12\", \"-$&-\"), \"-ab12-\");\n        assert.equal(search.replace(\"ab12\", \"_$0_\"), \"_ab12_\");\n\n        search.set({ needle: \"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\" });\n        assert.equal(search.replace(\"abcdefghijkl\", \"$2$9$7_$11$9$4_$8$9$4$5_$10$1$3$11_$6$12$1$7_$13\"), \"big_kid_hide_jack_flag_a3\");\n    },\n\n    \"test: replace() should correctly handle $$ in the replacement string\": function () {\n        var search = new Search().set({\n            needle: \"example\"\n        });\n\n        // Expecting $$ to be preserved in the output\n        assert.equal(search.replace(\"example\", \"$test\"), \"$test\");\n        assert.equal(search.replace(\"example\", \"$$test\"), \"$$test\");\n        assert.equal(search.replace(\"example\", \"$$$test\"), \"$$$test\");\n        assert.equal(search.replace(\"example\", \"$$$$test\"), \"$$$$test\");\n\n        search.set({\n            regExp: true,\n            needle: \"(example)\"\n        });\n\n        // Tests that $1 is replaced by the text that matches the capturing group.\n        assert.equal(search.replace(\"example\", \"$1test\"), \"exampletest\");\n\n        assert.equal(search.replace(\"example\", \"$\"), \"$\");\n        assert.equal(search.replace(\"example\", \"$$\"), \"$\");\n        assert.equal(search.replace(\"example\", \"$$$\"), \"$$\");\n        assert.equal(search.replace(\"example\", \"$$$$\"), \"$$\");\n        assert.equal(search.replace(\"example\", \"$$$$$\"), \"$$$\");\n        assert.equal(search.replace(\"example\", \"$$$$$$\"), \"$$$\");\n        assert.equal(search.replace(\"example\", \"$$$$$$$\"), \"$$$$\");\n\n        search.set({ regExp: false });\n        // Tests that without regular expression, \"$1test\" is treated as a literal string with $ escape.\n        assert.equal(search.replace(\"(example)\", \"$1test\"), \"$1test\");\n    },\n\n    \"test: replace() should correctly handle \\\\\\\\ in the replacement string\": function () {\n        var search = new Search().set({\n            needle: \"example\"\n        });\n\n        // Expecting \\\\ to be preserved in the output\n        assert.equal(search.replace(\"example\", \"\\\\test\"), \"\\\\test\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\test\"), \"\\\\\\\\test\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\test\"), \"\\\\\\\\\\\\test\");\n\n        search.set({ regExp: true });\n\n        assert.equal(search.replace(\"example\", \"\\\\\"), \"\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\"), \"\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\\"), \"\\\\\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\\\\\\"), \"\\\\\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\\\\\\\\\\"), \"\\\\\\\\\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\\\\\\\\\\\\\\"), \"\\\\\\\\\\\\\");\n        assert.equal(search.replace(\"example\", \"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), \"\\\\\\\\\\\\\\\\\");\n    },\n\n    \"test: find all using regular expresion containing $\" : function() {\n        var session = new EditSession([\"a\", \"     b\", \"c \", \"d\"]);\n\n        var search = new Search().set({\n            needle: \"[ ]+$\",\n            regExp: true,\n            wrap: true\n        });\n\n        session.getSelection().moveCursorTo(1, 2);\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 1);\n        assert.position(ranges[0].start, 2, 1);\n        assert.position(ranges[0].end, 2, 2);\n    },\n\n    \"test: find all matches in a line\" : function() {\n        var session = new EditSession(\"foo bar foo baz foobar foo\");\n\n        var search = new Search().set({\n            needle: \"foo\",\n            wrap: true,\n            wholeWord: true\n        });\n\n        session.getSelection().moveCursorTo(0, 4);\n\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 3);\n        assert.position(ranges[0].start, 0, 0);\n        assert.position(ranges[0].end, 0, 3);\n        assert.position(ranges[1].start, 0, 8);\n        assert.position(ranges[1].end, 0, 11);\n        assert.position(ranges[2].start, 0, 23);\n        assert.position(ranges[2].end, 0, 26);\n    },\n\n    \"test: find all matches in a line backwards\" : function() {\n        var session = new EditSession(\"foo bar foo baz foobar foo\");\n\n        var search = new Search().set({\n            needle: \"foo\",\n            wrap: true,\n            wholeWord: true,\n            backwards: true\n        });\n\n        session.getSelection().moveCursorTo(0, 13);\n\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 3);\n        assert.position(ranges[2].start, 0, 23);\n        assert.position(ranges[2].end, 0, 26);\n        assert.position(ranges[1].start, 0, 8);\n        assert.position(ranges[1].end, 0, 11);\n        assert.position(ranges[0].start, 0, 0);\n        assert.position(ranges[0].end, 0, 3);\n    },\n\n    \"test: find next empty range\" : function() {\n        var session = new EditSession(\"foo foobar foo\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        var options = {\n            needle: \"o*\",\n            wrap: true,\n            regExp: true,\n            backwards: false\n        };\n        var positions = [4, 5.2, 7, 8, 9, 10, 11, 12.2, 14, 0, 1.2, 3];\n\n        session.selection.moveCursorTo(0, 3);\n        for (var i = 0; i < positions.length; i++) {\n            editor.find(options);\n            var range = editor.selection.getRange();\n            var start = range.start.column;\n            var len = range.end.column - start;\n            assert.equal(start + 0.1 * len, positions[i]);\n        }\n        options.backwards = true;\n        positions = [1.2, 0, 12.2, 11, 10, 9, 8, 7, 5.2, 4, 3, 1.2, 0];\n        for (var i = 0; i < positions.length; i++) {\n            editor.find(options);\n            var range = editor.selection.getRange();\n            var start = range.start.column;\n            var len = range.end.column - start;\n            assert.equal(start + 0.1 * len, positions[i]);\n        }\n    },\n\n    \"test: repeating text\": function() {\n        var session = new EditSession(\"tttttt\\ntttttt\\ntttttt\\ntttttt\\ntttttt\\ntttttt\");\n        var editor = new Editor(new MockRenderer(), session);\n\n        var options = {\n            needle: \"^\",\n            wrap: true,\n            regExp: true,\n            backwards: false\n        };\n        function check(sl, sc, el, ec) {\n            editor.find(options);\n            var range = editor.selection.getRange();\n            assert.range(range, sl, sc, el, ec);\n        }\n\n        session.selection.moveCursorTo(1, 3);\n        check(2, 0, 2, 0);\n\n        options.needle = \"tttt\\ntttt\";\n        check(2, 2, 3, 4);\n        check(4, 2, 5, 4);\n        check(0, 2, 1, 4);\n\n        options.backwards = true;\n        check(4, 2, 5, 4);\n        check(2, 2, 3, 4);\n        check(0, 2, 1, 4);\n        check(4, 2, 5, 4);\n    },\n\n    \"test: find all matches in a range\" : function() {\n        var session = new EditSession([\n            \"\",\n            \"    var myVar1 = 1; var myVar2 = 2; var myVar3 = 3;\",\n            \"    var myVar4 = 4; var myVar5 = 5; var myVar6 = 6;\"\n        ]);\n\n        var search = new Search().set({\n            needle: \"var\",\n            backwards: true,\n            caseSensitive: true,\n            range: {start: {row: 1, column: 20}, end: {row: 2, column: 22}},\n            wholeWord: false,\n            regExp: false\n        });\n\n        var ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 3);\n        assert.position(ranges[0].start, 1, 20);\n        assert.position(ranges[0].end, 1, 23);\n        assert.position(ranges[1].start, 1, 36);\n        assert.position(ranges[1].end, 1, 39);\n        assert.position(ranges[2].start, 2, 4);\n        assert.position(ranges[2].end, 2, 7);\n    },\n\n    \"test: find all line breaks (\\\\r\\\\n, \\\\n) using regular expression\" : function() {\n        var session = new EditSession('\\nfunction foo(items, nada) {\\n    for (var i=0; i<items.length; i++) {\\n        alert(items[i] + \"juhu\\\\n\");\\n    }\\t/* Real Tab */\\n\\n\\n\\n\\n}\\n\\n\\n// test search/replace line break with regexp\\r\\n\\r\\n\\t\\t\\t\\t\\n');\n\n        var search = new Search().set({\n            needle: \"\\\\n\",\n            regExp: true,\n            wrap: true\n        });\n\n        var ranges = search.findAll(session);\n        assert.equal(ranges.length, 15);\n\n        search.set({ needle: \"\\\\n{2,}\" });\n        ranges = search.findAll(session);\n        assert.equal(ranges.length, 3);\n\n        search.set({ needle: \"\\\\n\\\\s+\" });\n        ranges = search.findAll(session);\n        assert.equal(ranges.length, 6);\n\n        search.set({ needle: \"\\\\)\\\\s\\\\{\\\\n\\\\s+\" });\n        ranges = search.findAll(session);\n        assert.equal(ranges.length, 2);\n\n        search.set({ needle: \"\\\\n+\" });\n        ranges = search.findAll(session);\n\n        assert.equal(ranges.length, 8);\n        assert.position(ranges[0].start, 0, 0);\n        assert.position(ranges[0].end, 1, 0);\n        assert.position(ranges[1].start, 1, 27);\n        assert.position(ranges[1].end, 2, 0);\n        assert.position(ranges[2].start, 2, 40);\n        assert.position(ranges[2].end, 3, 0);\n        assert.position(ranges[3].start, 3, 35);\n        assert.position(ranges[3].end, 4, 0);\n        assert.position(ranges[4].start, 4, 20);\n        assert.position(ranges[4].end, 9, 0);\n        assert.position(ranges[5].start, 9, 1);\n        assert.position(ranges[5].end, 12, 0);\n        assert.position(ranges[6].start, 12, 45);\n        assert.position(ranges[6].end, 14, 0);\n        assert.position(ranges[7].start, 14, 4);\n        assert.position(ranges[7].end, 15, 0);\n    },\n\n    \"test: find line breaks backwards using regex\" : function() {\n        var session = new EditSession('\\nfunction foo(items, nada) {\\n    for (var i=0; i<items.length; i++) {\\n        alert(items[i] + \"juhu\\\\n\");\\n    }\\t/* Real Tab */\\n\\n\\n\\n\\n}\\n\\n\\n// test search/replace line break with regexp\\r\\n\\r\\n\\t\\t\\t\\t\\n');\n        session.getSelection().moveCursorTo(2, 5);\n\n        var search = new Search().set({\n            needle: \"\\\\n\",\n            regExp: true,\n            wrap: true,\n            backwards: true\n        });\n\n        var range = search.find(session);\n\n        // Should find the first newline to the left of the cursor\n        assert.position(range.start, 1, 27);\n        assert.position(range.end, 2, 0);\n    },\n\n    \"test: replace with line breaks (\\\\n) and TAB (\\\\t) using regular expression\" : function() {\n        var search = new Search().set({\n            needle: \"with\",\n            regExp: true,\n            wrap: true\n        });\n\n        assert.equal(search.replace(\"with\", \"\\n// $0\"), \"\\n// with\");\n        assert.equal(search.replace(\"with\", \"\\t-\\t$0\"), \"\\t-\\twith\");\n\n        search.set({ needle: \"(\\\\n+)\" });\n        assert.equal(search.replace(\"\\n\", \"\"), \"\");\n        assert.equal(search.replace(\"\\n\", \"\\t\"), \"\\t\");\n        assert.equal(search.replace(\"\\n\\n\\n\", \"\\n\"), \"\\n\");\n        assert.equal(search.replace(\"\\n\\t\\n\\n\", \"\\t$1\"), \"\\t\\n\\t\\t\\n\\n\");\n        assert.equal(search.replace(\"\\r\\n /* CRLF */\", \"\\n\"), \"\\n /* CRLF */\");\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/selection.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar lang = require(\"./lib/lang\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Range = require(\"./range\").Range;\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"./anchor\").Anchor} Anchor\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n */\n\nclass Selection {\n    /**\n     * Creates a new `Selection` object.\n     * @param {EditSession} session The session to use\n     * @constructor\n     **/\n    constructor(session) {\n        /**@type {EditSession}*/\n        this.session = session;\n        /**@type {import(\"./document\").Document}*/\n        this.doc = session.getDocument();\n    \n        this.clearSelection();\n        /**@type {Anchor}*/\n        this.cursor = this.lead = this.doc.createAnchor(0, 0);\n        /**@type {Anchor}*/\n        this.anchor = this.doc.createAnchor(0, 0);\n        this.$silent = false;\n    \n        var self = this;\n        this.cursor.on(\"change\", function(e) {\n            self.$cursorChanged = true;\n            if (!self.$silent)\n                self._emit(\"changeCursor\");\n            if (!self.$isEmpty && !self.$silent)\n                self._emit(\"changeSelection\");\n            if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)\n                self.$desiredColumn = null;\n        });\n    \n        this.anchor.on(\"change\", function() {\n            self.$anchorChanged = true;\n            if (!self.$isEmpty && !self.$silent)\n                self._emit(\"changeSelection\");\n        });\n    }\n    \n    /**\n     * Returns `true` if the selection is empty.\n     * @returns {Boolean}\n     **/\n   isEmpty() {\n        return this.$isEmpty || (\n            this.anchor.row == this.lead.row &&\n            this.anchor.column == this.lead.column\n        );\n    }\n\n    /**\n     * Returns `true` if the selection is a multi-line.\n     * @returns {Boolean}\n     **/\n    isMultiLine() {\n        return !this.$isEmpty && this.anchor.row != this.cursor.row;\n    }\n\n    /**\n     * Returns an object containing the `row` and `column` current position of the cursor.\n     * @returns {Point}\n     **/\n    getCursor() {\n        return this.lead.getPosition();\n    }\n\n    /**\n     * Sets the row and column position of the anchor. This function also emits the `'changeSelection'` event.\n     * @param {Number} row The new row\n     * @param {Number} column The new column\n     *\n     **/\n    setAnchor(row, column) {\n        this.$isEmpty = false;\n        this.anchor.setPosition(row, column);\n    }\n\n\n    /**\n     * Returns an object containing the `row` and `column` of the calling selection anchor.\n     *\n     * @returns {Point}\n     * @related Anchor.getPosition\n     **/\n    getAnchor() {\n        if (this.$isEmpty)\n            return this.getSelectionLead();\n\n        return this.anchor.getPosition();\n    }\n\n\n    /**\n     * Returns an object containing the `row` and `column` of the calling selection lead.\n     * @returns {Object}\n     **/\n    getSelectionLead() {\n        return this.lead.getPosition();\n    }\n\n    /**\n     * Returns `true` if the selection is going backwards in the document.\n     * @returns {Boolean}\n     **/\n    isBackwards() {\n        var anchor = this.anchor;\n        var lead = this.lead;\n        return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));\n    }\n\n    /**\n     * [Returns the [[Range]] for the selected text.]{: #Selection.getRange}\n     * @returns {Range}\n     **/\n    getRange() {\n        var anchor = this.anchor;\n        var lead = this.lead;\n\n        if (this.$isEmpty)\n            return Range.fromPoints(lead, lead);\n\n        return this.isBackwards()\n            ? Range.fromPoints(lead, anchor)\n            : Range.fromPoints(anchor, lead);\n    }\n\n    /**\n     * [Empties the selection (by de-selecting it). This function also emits the `'changeSelection'` event.]{: #Selection.clearSelection}\n     **/\n    clearSelection() {\n        if (!this.$isEmpty) {\n            this.$isEmpty = true;\n            this._emit(\"changeSelection\");\n        }\n    }\n\n    /**\n     * Selects all the text in the document.\n     **/\n    selectAll() {\n        this.$setSelection(0, 0, Number.MAX_VALUE, Number.MAX_VALUE);\n    }\n\n    /**\n     * Sets the selection to the provided range.\n     * @param {import(\"../ace-internal\").Ace.IRange} range The range of text to select\n     * @param {Boolean} [reverse] Indicates if the range should go backwards (`true`) or not\n     **/\n    setRange(range, reverse) {\n        var start = reverse ? range.end : range.start;\n        var end = reverse ? range.start : range.end;\n        this.$setSelection(start.row, start.column, end.row, end.column);\n    }\n\n    /**\n     * @param {number} anchorRow\n     * @param {number} anchorColumn\n     * @param {number} cursorRow\n     * @param {number} cursorColumn\n     */\n    $setSelection(anchorRow, anchorColumn, cursorRow, cursorColumn) {\n        if (this.$silent)\n            return;\n        var wasEmpty = this.$isEmpty;\n        var wasMultiselect = this.inMultiSelectMode;\n        this.$silent = true;\n        this.$cursorChanged = this.$anchorChanged = false;\n        this.anchor.setPosition(anchorRow, anchorColumn);\n        this.cursor.setPosition(cursorRow, cursorColumn);\n        this.$isEmpty = !Range.comparePoints(this.anchor, this.cursor);\n        this.$silent = false;\n        if (this.$cursorChanged)\n            this._emit(\"changeCursor\");\n        if (this.$cursorChanged || this.$anchorChanged || wasEmpty != this.$isEmpty || wasMultiselect)\n            this._emit(\"changeSelection\");\n    }\n\n    $moveSelection(mover) {\n        var lead = this.lead;\n        if (this.$isEmpty)\n            this.setSelectionAnchor(lead.row, lead.column);\n\n        mover.call(this);\n    }\n\n    /**\n     * Moves the selection cursor to the indicated row and column.\n     * @param {Number} row The row to select to\n     * @param {Number} column The column to select to\n     **/\n    selectTo(row, column) {\n        this.$moveSelection(function() {\n            this.moveCursorTo(row, column);\n        });\n    }\n\n    /**\n     * Moves the selection cursor to the row and column indicated by `pos`.\n     * @param {Point} pos An object containing the row and column\n     **/\n    selectToPosition(pos) {\n        this.$moveSelection(function() {\n            this.moveCursorToPosition(pos);\n        });\n    }\n\n    /**\n     * Moves the selection cursor to the indicated row and column.\n     * @param {Number} row The row to select to\n     * @param {Number} column The column to select to\n     **/\n    moveTo(row, column) {\n        this.clearSelection();\n        this.moveCursorTo(row, column);\n    }\n\n    /**\n     * Moves the selection cursor to the row and column indicated by `pos`.\n     * @param {Object} pos An object containing the row and column\n     **/\n    moveToPosition(pos) {\n        this.clearSelection();\n        this.moveCursorToPosition(pos);\n    }\n\n\n    /**\n     * Moves the selection up one row.\n     **/\n    selectUp() {\n        this.$moveSelection(this.moveCursorUp);\n    }\n\n    /**\n     * Moves the selection down one row.\n     **/\n    selectDown() {\n        this.$moveSelection(this.moveCursorDown);\n    }\n\n    /**\n     * Moves the selection right one column.\n     **/\n    selectRight() {\n        this.$moveSelection(this.moveCursorRight);\n    }\n\n    /**\n     * Moves the selection left one column.\n     **/\n    selectLeft() {\n        this.$moveSelection(this.moveCursorLeft);\n    }\n\n    /**\n     * Moves the selection to the beginning of the current line.\n     **/\n    selectLineStart() {\n        this.$moveSelection(this.moveCursorLineStart);\n    }\n\n    /**\n     * Moves the selection to the end of the current line.\n     **/\n    selectLineEnd() {\n        this.$moveSelection(this.moveCursorLineEnd);\n    }\n\n    /**\n     * Moves the selection to the end of the file.\n     **/\n    selectFileEnd() {\n        this.$moveSelection(this.moveCursorFileEnd);\n    }\n\n    /**\n     * Moves the selection to the start of the file.\n     **/\n    selectFileStart() {\n        this.$moveSelection(this.moveCursorFileStart);\n    }\n\n    /**\n     * Moves the selection to the first word on the right.\n     **/\n    selectWordRight() {\n        this.$moveSelection(this.moveCursorWordRight);\n    }\n\n    /**\n     * Moves the selection to the first word on the left.\n     **/\n    selectWordLeft() {\n        this.$moveSelection(this.moveCursorWordLeft);\n    }\n\n    /**\n     * Moves the selection to highlight the entire word.\n     * @related EditSession.getWordRange\n     **/\n    getWordRange(row, column) {\n        if (typeof column == \"undefined\") {\n            var cursor = row || this.lead;\n            row = cursor.row;\n            column = cursor.column;\n        }\n        return this.session.getWordRange(row, column);\n    }\n\n    /**\n     * Selects an entire word boundary.\n     **/\n    selectWord() {\n        this.setSelectionRange(this.getWordRange());\n    }\n\n    /**\n     * Selects a word, including its right whitespace.\n     * @related EditSession.getAWordRange\n     **/\n    selectAWord() {\n        var cursor = this.getCursor();\n        var range = this.session.getAWordRange(cursor.row, cursor.column);\n        this.setSelectionRange(range);\n    }\n\n    getLineRange(row, excludeLastChar) {\n        var rowStart = typeof row == \"number\" ? row : this.lead.row;\n        var rowEnd;\n\n        var foldLine = this.session.getFoldLine(rowStart);\n        if (foldLine) {\n            rowStart = foldLine.start.row;\n            rowEnd = foldLine.end.row;\n        } else {\n            rowEnd = rowStart;\n        }\n        if (excludeLastChar === true)\n            return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);\n        else\n            return new Range(rowStart, 0, rowEnd + 1, 0);\n    }\n\n    /**\n     * Selects the entire line.\n     **/\n    selectLine() {\n        this.setSelectionRange(this.getLineRange());\n    }\n\n    /**\n     * Moves the cursor up one row.\n     **/\n    moveCursorUp() {\n        this.moveCursorBy(-1, 0);\n    }\n\n    /**\n     * Moves the cursor down one row.\n     **/\n    moveCursorDown() {\n        this.moveCursorBy(1, 0);\n    }\n\n    /**\n     *\n     * Returns `true` if moving the character next to the cursor in the specified direction is a soft tab.\n     * @param {Point} cursor the current cursor position\n     * @param {Number} tabSize the tab size\n     * @param {Number} direction 1 for right, -1 for left\n     */\n    wouldMoveIntoSoftTab(cursor, tabSize, direction) {\n        var start = cursor.column;\n        var end = cursor.column + tabSize;\n\n        if (direction < 0) {\n            start = cursor.column - tabSize;\n            end = cursor.column;\n        }\n        return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(\" \").length-1 == tabSize;\n    }\n\n    /**\n     * Moves the cursor left one column.\n     **/\n    moveCursorLeft() {\n        var cursor = this.lead.getPosition(),\n            fold;\n\n        if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {\n            this.moveCursorTo(fold.start.row, fold.start.column);\n        } else if (cursor.column === 0) {\n            // cursor is a line (start\n            if (cursor.row > 0) {\n                this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);\n            }\n        }\n        else {\n            var tabSize = this.session.getTabSize();\n            if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) {\n                this.moveCursorBy(0, -tabSize);\n            } else {\n                this.moveCursorBy(0, -1);\n            }\n        }\n    }\n\n    /**\n     * Moves the cursor right one column.\n     **/\n    moveCursorRight() {\n        var cursor = this.lead.getPosition(),\n            fold;\n        if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {\n            this.moveCursorTo(fold.end.row, fold.end.column);\n        }\n        else if (this.lead.column == this.doc.getLine(this.lead.row).length) {\n            if (this.lead.row < this.doc.getLength() - 1) {\n                this.moveCursorTo(this.lead.row + 1, 0);\n            }\n        }\n        else {\n            var tabSize = this.session.getTabSize();\n            /**\n             * @type {Point}\n             */\n            var cursor = this.lead;\n            if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) {\n                this.moveCursorBy(0, tabSize);\n            } else {\n                this.moveCursorBy(0, 1);\n            }\n        }\n    }\n\n    /**\n     * Moves the cursor to the start of the line.\n     **/\n    moveCursorLineStart() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var screenRow = this.session.documentToScreenRow(row, column);\n\n        // Determ the doc-position of the first character at the screen line.\n        var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);\n\n        // Determ the line\n        var beforeCursor = this.session.getDisplayLine(\n            row, null, firstColumnPosition.row,\n            firstColumnPosition.column\n        );\n\n        var leadingSpace = beforeCursor.match(/^\\s*/);\n        // TODO find better way for emacs mode to override selection behaviors\n        if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)\n            firstColumnPosition.column += leadingSpace[0].length;\n        this.moveCursorToPosition(firstColumnPosition);\n    }\n\n    /**\n     * Moves the cursor to the end of the line.\n     **/\n    moveCursorLineEnd() {\n        var lead = this.lead;\n        var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);\n        if (this.lead.column == lineEnd.column) {\n            var line = this.session.getLine(lineEnd.row);\n            if (lineEnd.column == line.length) {\n                var textEnd = line.search(/\\s+$/);\n                if (textEnd > 0)\n                    lineEnd.column = textEnd;\n            }\n        }\n\n        this.moveCursorTo(lineEnd.row, lineEnd.column);\n    }\n\n    /**\n     * Moves the cursor to the end of the file.\n     **/\n    moveCursorFileEnd() {\n        var row = this.doc.getLength() - 1;\n        var column = this.doc.getLine(row).length;\n        this.moveCursorTo(row, column);\n    }\n\n    /**\n     * Moves the cursor to the start of the file.\n     **/\n    moveCursorFileStart() {\n        this.moveCursorTo(0, 0);\n    }\n\n    /**\n     * Moves the cursor to the word on the right.\n     **/\n    moveCursorLongWordRight() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var line = this.doc.getLine(row);\n        var rightOfCursor = line.substring(column);\n\n        this.session.nonTokenRe.lastIndex = 0;\n        this.session.tokenRe.lastIndex = 0;\n\n        // skip folds\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold) {\n            this.moveCursorTo(fold.end.row, fold.end.column);\n            return;\n        }\n\n        // first skip space\n        if (this.session.nonTokenRe.exec(rightOfCursor)) {\n            column += this.session.nonTokenRe.lastIndex;\n            this.session.nonTokenRe.lastIndex = 0;\n            rightOfCursor = line.substring(column);\n        }\n\n        // if at line end proceed with next line\n        if (column >= line.length) {\n            this.moveCursorTo(row, line.length);\n            this.moveCursorRight();\n            if (row < this.doc.getLength() - 1)\n                this.moveCursorWordRight();\n            return;\n        }\n\n        // advance to the end of the next token\n        if (this.session.tokenRe.exec(rightOfCursor)) {\n            column += this.session.tokenRe.lastIndex;\n            this.session.tokenRe.lastIndex = 0;\n        }\n\n        this.moveCursorTo(row, column);\n    }\n\n    /**\n    *\n    * Moves the cursor to the word on the left.\n    **/\n    moveCursorLongWordLeft() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n\n        // skip folds\n        var fold;\n        if (fold = this.session.getFoldAt(row, column, -1)) {\n            this.moveCursorTo(fold.start.row, fold.start.column);\n            return;\n        }\n\n        var str = this.session.getFoldStringAt(row, column, -1);\n        if (str == null) {\n            str = this.doc.getLine(row).substring(0, column);\n        }\n\n        var leftOfCursor = lang.stringReverse(str);\n        this.session.nonTokenRe.lastIndex = 0;\n        this.session.tokenRe.lastIndex = 0;\n\n        // skip whitespace\n        if (this.session.nonTokenRe.exec(leftOfCursor)) {\n            column -= this.session.nonTokenRe.lastIndex;\n            leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);\n            this.session.nonTokenRe.lastIndex = 0;\n        }\n\n        // if at begin of the line proceed in line above\n        if (column <= 0) {\n            this.moveCursorTo(row, 0);\n            this.moveCursorLeft();\n            if (row > 0)\n                this.moveCursorWordLeft();\n            return;\n        }\n\n        // move to the begin of the word\n        if (this.session.tokenRe.exec(leftOfCursor)) {\n            column -= this.session.tokenRe.lastIndex;\n            this.session.tokenRe.lastIndex = 0;\n        }\n\n        this.moveCursorTo(row, column);\n    }\n\n    $shortWordEndIndex(rightOfCursor) {\n        var index = 0, ch;\n        var whitespaceRe = /\\s/;\n        var tokenRe = this.session.tokenRe;\n\n        tokenRe.lastIndex = 0;\n        if (this.session.tokenRe.exec(rightOfCursor)) {\n            index = this.session.tokenRe.lastIndex;\n        } else {\n            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))\n                index ++;\n\n            if (index < 1) {\n                tokenRe.lastIndex = 0;\n                 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {\n                    tokenRe.lastIndex = 0;\n                    index ++;\n                    if (whitespaceRe.test(ch)) {\n                        if (index > 2) {\n                            index--;\n                            break;\n                        } else {\n                            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))\n                                index ++;\n                            if (index > 2)\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n        tokenRe.lastIndex = 0;\n\n        return index;\n    }\n\n    moveCursorShortWordRight() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var line = this.doc.getLine(row);\n        var rightOfCursor = line.substring(column);\n\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold)\n            return this.moveCursorTo(fold.end.row, fold.end.column);\n\n        if (column == line.length) {\n            var l = this.doc.getLength();\n            do {\n                row++;\n                rightOfCursor = this.doc.getLine(row);\n            } while (row < l && /^\\s*$/.test(rightOfCursor));\n\n            if (!/^\\s+/.test(rightOfCursor))\n                rightOfCursor = \"\";\n            column = 0;\n        }\n\n        var index = this.$shortWordEndIndex(rightOfCursor);\n\n        this.moveCursorTo(row, column + index);\n    }\n\n    moveCursorShortWordLeft() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n\n        var fold;\n        if (fold = this.session.getFoldAt(row, column, -1))\n            return this.moveCursorTo(fold.start.row, fold.start.column);\n\n        var line = this.session.getLine(row).substring(0, column);\n        if (column === 0) {\n            do {\n                row--;\n                line = this.doc.getLine(row);\n            } while (row > 0 && /^\\s*$/.test(line));\n\n            column = line.length;\n            if (!/\\s+$/.test(line))\n                line = \"\";\n        }\n\n        var leftOfCursor = lang.stringReverse(line);\n        var index = this.$shortWordEndIndex(leftOfCursor);\n\n        return this.moveCursorTo(row, column - index);\n    }\n\n    moveCursorWordRight() {\n        if (this.session.$selectLongWords)\n            this.moveCursorLongWordRight();\n        else\n            this.moveCursorShortWordRight();\n    }\n\n    moveCursorWordLeft() {\n        if (this.session.$selectLongWords)\n            this.moveCursorLongWordLeft();\n        else\n            this.moveCursorShortWordLeft();\n    }\n\n    /**\n     * Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.\n     * @param {Number} rows The number of rows to move by\n     * @param {Number} chars The number of characters to move by\n     *\n     * @related EditSession.documentToScreenPosition\n     **/\n    moveCursorBy(rows, chars) {\n        var screenPos = this.session.documentToScreenPosition(\n            this.lead.row,\n            this.lead.column\n        );\n\n        var offsetX;\n\n        if (chars === 0) {\n            if (rows !== 0) {\n                if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) {\n                    offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column);\n                    screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]);\n                } else {\n                    offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0];\n                }\n            }\n\n            if (this.$desiredColumn)\n                screenPos.column = this.$desiredColumn;\n            else\n                this.$desiredColumn = screenPos.column;\n        }\n\n        if (rows != 0 && this.session.lineWidgets && this.session.lineWidgets[this.lead.row]) {\n            var widget = this.session.lineWidgets[this.lead.row];\n            if (rows < 0)\n                rows -= widget.rowsAbove || 0;\n            else if (rows > 0)\n                rows += widget.rowCount - (widget.rowsAbove || 0);\n        }\n\n        var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);\n\n        if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {\n\n        }\n\n        // move the cursor and update the desired column\n        this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);\n    }\n\n    /**\n     * Moves the selection to the position indicated by its `row` and `column`.\n     * @param {Point} position The position to move to\n     **/\n    moveCursorToPosition(position) {\n        this.moveCursorTo(position.row, position.column);\n    }\n\n    /**\n     * Moves the cursor to the row and column provided. [If `preventUpdateDesiredColumn` is `true`, then the cursor stays in the same column position as its original point.]{: #preventUpdateBoolDesc}\n     * @param {Number} row The row to move to\n     * @param {Number} column The column to move to\n     * @param {Boolean} [keepDesiredColumn] [If `true`, the cursor move does not respect the previous column]{: #preventUpdateBool}\n     **/\n    moveCursorTo(row, column, keepDesiredColumn) {\n        // Ensure the row/column is not inside of a fold.\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold) {\n            row = fold.start.row;\n            column = fold.start.column;\n        }\n\n        this.$keepDesiredColumnOnChange = true;\n        var line = this.session.getLine(row);\n        // do not allow putting cursor in the middle of surrogate pairs\n        if (/[\\uDC00-\\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) {\n            if (this.lead.row == row && this.lead.column == column + 1)\n                column = column - 1;\n            else\n                column = column + 1;\n        }\n        this.lead.setPosition(row, column);\n        this.$keepDesiredColumnOnChange = false;\n\n        if (!keepDesiredColumn)\n            this.$desiredColumn = null;\n    }\n\n    /**\n     * Moves the cursor to the screen position indicated by row and column. {:preventUpdateBoolDesc}\n     * @param {Number} row The row to move to\n     * @param {Number} column The column to move to\n     * @param {Boolean} keepDesiredColumn {:preventUpdateBool}\n     **/\n    moveCursorToScreen(row, column, keepDesiredColumn) {\n        var pos = this.session.screenToDocumentPosition(row, column);\n        this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);\n    }\n\n    // remove listeners from document\n    detach() {\n        this.lead.detach();\n        this.anchor.detach();\n    }\n\n    /**\n     * @param {Range & {desiredColumn?: number}} range\n     */\n    fromOrientedRange(range) {\n        this.setSelectionRange(range, range.cursor == range.start);\n        this.$desiredColumn = range.desiredColumn || this.$desiredColumn;\n    }\n\n    /**\n     * @param {Range & {desiredColumn?: number}} [range]\n     */\n    toOrientedRange(range) {\n        var r = this.getRange();\n        if (range) {\n            range.start.column = r.start.column;\n            range.start.row = r.start.row;\n            range.end.column = r.end.column;\n            range.end.row = r.end.row;\n        } else {\n            range = r;\n        }\n\n        range.cursor = this.isBackwards() ? range.start : range.end;\n        range.desiredColumn = this.$desiredColumn;\n        return range;\n    }\n\n    /**\n     * Saves the current cursor position and calls `func` that can change the cursor\n     * postion. The result is the range of the starting and eventual cursor position.\n     * Will reset the cursor position.\n     * @param {Function} func The callback that should change the cursor position\n     * @returns {Range}\n     **/\n    getRangeOfMovements(func) {\n        var start = this.getCursor();\n        try {\n            func(this);\n            var end = this.getCursor();\n            return Range.fromPoints(start, end);\n        } catch(e) {\n            return Range.fromPoints(start, start);\n        } finally {\n            this.moveCursorToPosition(start);\n        }\n    }\n\n    /**\n     * \n     * @returns {Range|Range[]}\n     */\n    toJSON() {\n        if (this.rangeCount) {\n            /**@type{Range|Range[]}*/var data = this.ranges.map(function(r) {\n                var r1 = r.clone();\n                r1.isBackwards = r.cursor == r.start;\n                return r1;\n            });\n        } else {\n            /**@type{Range|Range[]}*/var data = this.getRange();\n            data.isBackwards = this.isBackwards();\n        }\n        return data;\n    }\n\n    /**\n     * \n     * @param data\n     */\n    fromJSON(data) {\n        if (data.start == undefined) {\n            if (this.rangeList && data.length > 1) {\n                this.toSingleRange(data[0]);\n                for (var i = data.length; i--; ) {\n                    var r = Range.fromPoints(data[i].start, data[i].end);\n                    if (data[i].isBackwards)\n                        r.cursor = r.start;\n                    this.addRange(r, true);\n                }\n                return;\n            } else {\n                data = data[0];\n            }\n        }\n        if (this.rangeList)\n            this.toSingleRange(data);\n        this.setSelectionRange(data, data.isBackwards);\n    }\n\n    /**\n     * \n     * @param data\n     * @return {boolean}\n     */\n    isEqual(data) {\n        if ((data.length || this.rangeCount) && data.length != this.rangeCount)\n            return false;\n        if (!data.length || !this.ranges)\n            return this.getRange().isEqual(data);\n\n        for (var i = this.ranges.length; i--; ) {\n            if (!this.ranges[i].isEqual(data[i]))\n                return false;\n        }\n        return true;\n    }\n\n}\n\n/**\n * Left for backward compatibility\n * @deprecated\n */\nSelection.prototype.setSelectionAnchor = Selection.prototype.setAnchor;\n/**\n * Left for backward compatibility\n * @deprecated\n */\nSelection.prototype.getSelectionAnchor = Selection.prototype.getAnchor;\n\nSelection.prototype.setSelectionRange = Selection.prototype.setRange;\n\noop.implement(Selection.prototype, EventEmitter);\nexports.Selection = Selection;\n"
  },
  {
    "path": "src/selection_test.js",
    "content": "\"use strict\";\n\nvar LineWidgets = require(\"./line_widgets\").LineWidgets;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar assert = require(\"./test/assertions\");\nvar Range = require(\"./range\").Range;\n\nmodule.exports = {\n    createSession : function(rows, cols) {\n        var line = new Array(cols + 1).join(\"a\");\n        var text = new Array(rows).join(line + \"\\n\") + line;\n        return new EditSession(text);\n    },\n    \n    \"test: selectAll\" : function() {\n        var session = this.createSession(10, 10);\n        var selection = session.selection;\n        session.selection.selectAll();\n        assert.position(selection.getAnchor(), 0, 0);\n        assert.position(selection.getCursor(), 9, 10);\n        assert.position(selection.getRange().end, 9, 10);\n        assert.position(selection.getRange().start, 0, 0);\n    },\n\n    \"test: move cursor to end of file should place the cursor on last row and column\" : function() {\n        var session = this.createSession(200, 10);\n        var selection = session.getSelection();\n\n        selection.moveCursorFileEnd();\n        assert.position(selection.getCursor(), 199, 10);\n    },\n\n    \"test: moveCursor to start of file should place the cursor on the first row and column\" : function() {\n        var session = this.createSession(200, 10);\n        var selection = session.getSelection();\n\n        selection.moveCursorFileStart();\n        assert.position(selection.getCursor(), 0, 0);\n    },\n\n    \"test: move selection lead to end of file\" : function() {\n        var session = this.createSession(200, 10);\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(100, 5);\n        selection.selectFileEnd();\n\n        var range = selection.getRange();\n\n        assert.position(range.start, 100, 5);\n        assert.position(range.end, 199, 10);\n    },\n\n    \"test: move selection lead to start of file\" : function() {\n        var session = this.createSession(200, 10);\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(100, 5);\n        selection.selectFileStart();\n\n        var range = selection.getRange();\n\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 100, 5);\n    },\n\n    \"test: move cursor word right\" : function() {\n        var session = new EditSession([\n            \"ab\",\n            \" Juhu Kinners (abc, 12)\",\n            \" cde\"\n        ].join(\"\\n\"));\n        \n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorDown();\n        assert.position(selection.getCursor(), 1, 0);\n\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 1, 5);\n\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 1, 13);\n\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 1, 18);\n\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 1, 22);\n\n        // wrap line\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 2, 4);\n        \n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 2, 4);\n    },\n\n    \"test: select word right if cursor in word\" : function() {\n        var session = new EditSession(\"Juhu Kinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 2);\n        selection.moveCursorWordRight();\n\n        assert.position(selection.getCursor(), 0, 4);\n    },\n\n    \"test: moveCursor word left\" : function() {\n        var session = new EditSession([\n            \"ab\",\n            \" Juhu Kinners (abc, 12)\",\n            \" cde\"\n        ].join(\"\\n\"));\n\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorDown();\n        selection.moveCursorLineEnd();\n        assert.position(selection.getCursor(), 1, 23);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 1, 20);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 1, 15);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 1, 6);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 1, 1);\n\n        // wrap line\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 0);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 0);\n    },\n\n    \"test: moveCursor word left with umlauts\" : function() {\n        var session = new EditSession(\" Fuß Füße\");\n        session.$selectLongWords = true;\n\n        var selection = session.getSelection();\n        selection.moveCursorTo(0, 9);\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 5);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 1);\n    },\n\n    \"test: select word left if cursor in word\" : function() {\n        var session = new EditSession(\"Juhu Kinners\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 8);\n\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 5);\n    },\n\n    \"test: select word right and select\" : function() {\n        var session = new EditSession(\"Juhu Kinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 0);\n        selection.selectWordRight();\n\n        var range = selection.getRange();\n\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 0, 4);\n    },\n\n    \"test: select word left and select\" : function() {\n        var session = new EditSession(\"Juhu Kinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 3);\n        selection.selectWordLeft();\n\n        var range = selection.getRange();\n\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 0, 3);\n    },\n\n    \"test: select word with cursor in word should select the word\" : function() {\n        var session = new EditSession(\"Juhu Kinners 123\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 8);\n        selection.selectWord();\n\n        var range = selection.getRange();\n        assert.position(range.start, 0, 5);\n        assert.position(range.end, 0, 12);\n    },\n\n    \"test: select word with cursor in word including right whitespace should select the word\" : function() {\n        var session = new EditSession(\"Juhu Kinners      123\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 8);\n        selection.selectAWord();\n\n        var range = selection.getRange();\n        assert.position(range.start, 0, 5);\n        assert.position(range.end, 0, 18);\n    },\n\n    \"test: select word with cursor betwen white space and word should select the word\" : function() {\n        var session = new EditSession(\"Juhu Kinners\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 4);\n        selection.selectWord();\n\n        var range = selection.getRange();\n        assert.position(range.start, 0, 0);\n        assert.position(range.end, 0, 4);\n\n        selection.moveCursorTo(0, 5);\n        selection.selectWord();\n\n        var range = selection.getRange();\n        assert.position(range.start, 0, 5);\n        assert.position(range.end, 0, 12);\n    },\n\n    \"test: select word with cursor in white space should select white space\" : function() {\n        var session = new EditSession(\"Juhu  Kinners\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 5);\n        selection.selectWord();\n\n        var range = selection.getRange();\n        assert.position(range.start, 0, 4);\n        assert.position(range.end, 0, 6);\n    },\n\n    \"test: moving cursor should fire a 'changeCursor' event\" : function() {\n        var session = new EditSession(\"Juhu  Kinners\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 5);\n\n        var called = false;\n        selection.addEventListener(\"changeCursor\", function() {\n           called = true;\n        });\n\n        selection.moveCursorTo(0, 6);\n        assert.ok(called);\n    },\n\n    \"test: calling setCursor with the same position should not fire an event\": function() {\n        var session = new EditSession(\"Juhu  Kinners\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 5);\n\n        var called = false;\n        selection.addEventListener(\"changeCursor\", function() {\n           called = true;\n        });\n\n        selection.moveCursorTo(0, 5);\n        assert.notOk(called);\n    },\n\n    \"test: moveWordright should move past || and [\": function() {\n        var session = new EditSession(\"||foo[\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        // Move behind ||foo\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 0, 5);\n\n        // Move behind [\n        selection.moveCursorWordRight();\n        assert.position(selection.getCursor(), 0, 6);\n    },\n\n    \"test: moveWordLeft should move past || and [\": function() {\n        var session = new EditSession(\"||foo[\");\n        var selection = session.getSelection();\n        session.$selectLongWords = true;\n\n        selection.moveCursorTo(0, 6);\n\n        // Move behind [foo\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 2);\n\n        // Move behind ||\n        selection.moveCursorWordLeft();\n        assert.position(selection.getCursor(), 0, 0);\n    },\n\n    \"test: move cursor to line start should move cursor to end of the indentation first\": function() {\n        var session = new EditSession(\"12\\n    Juhu\\n12\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(1, 6);\n        selection.moveCursorLineStart();\n\n        assert.position(selection.getCursor(), 1, 4);\n    },\n\n    \"test: move cursor to line start when the cursor is at the end of the indentation should move cursor to column 0\": function() {\n        var session = new EditSession(\"12\\n    Juhu\\n12\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(1, 4);\n        selection.moveCursorLineStart();\n\n        assert.position(selection.getCursor(), 1, 0);\n    },\n\n    \"test: move cursor to line start when the cursor is at column 0 should move cursor to the end of the indentation\": function() {\n        var session = new EditSession(\"12\\n    Juhu\\n12\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(1, 0);\n        selection.moveCursorLineStart();\n\n        assert.position(selection.getCursor(), 1, 4);\n    },\n\n    // Eclipse style\n    \"test: move cursor to line start when the cursor is before the initial indentation should move cursor to the end of the indentation\": function() {\n        var session = new EditSession(\"12\\n    Juhu\\n12\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(1, 2);\n        selection.moveCursorLineStart();\n\n        assert.position(selection.getCursor(), 1, 4);\n    },\n\n    \"test go line up when in the middle of the first line should go to document start\": function() {\n        var session = new EditSession(\"juhu kinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 4);\n        selection.moveCursorUp();\n\n        assert.position(selection.getCursor(), 0, 0);\n    },\n\n    \"test: (wrap) go line up when in the middle of the first line should go to document start\": function() {\n        var session = new EditSession(\"juhu kinners\");\n        session.setWrapLimitRange(5, 5);\n        session.adjustWrapLimit(80);\n\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 4);\n        selection.moveCursorUp();\n\n        assert.position(selection.getCursor(), 0, 0);\n    },\n\n\n    \"test go line down when in the middle of the last line should go to document end\": function() {\n        var session = new EditSession(\"juhu kinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 4);\n        selection.moveCursorDown();\n\n        assert.position(selection.getCursor(), 0, 12);\n    },\n\n    \"test (wrap) go line down when in the middle of the last line should go to document end\": function() {\n        var session = new EditSession(\"juhu kinners\");\n        session.setWrapLimitRange(8, 8);\n        session.adjustWrapLimit(80);\n\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 10);\n        selection.moveCursorDown();\n\n        assert.position(selection.getCursor(), 0, 12);\n    },\n\n    \"test go line up twice and then once down when in the second should go back to the previous column\": function() {\n        var session = new EditSession(\"juhu\\nkinners\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(1, 4);\n        selection.moveCursorUp();\n        selection.moveCursorUp();\n        selection.moveCursorDown();\n\n        assert.position(selection.getCursor(), 1, 4);\n    },\n\n    \"test (keyboard navigation) when curLine is not EOL and targetLine is all whitespace new column should be current column\": function() {\n        var session = new EditSession(\"function (a) {\\n    \\n}\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(2, 0);\n        selection.moveCursorUp();\n\n        assert.position(selection.getCursor(), 1, 0);\n    },\n\n    \"test (keyboard navigation) when curLine is EOL and targetLine is shorter than current column, new column should be targetLine's EOL\": function() {\n        var session = new EditSession(\"function (a) {\\n    \\n}\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 14);\n        selection.moveCursorDown();\n\n        assert.position(selection.getCursor(), 1, 4);\n    },\n\n    \"test fromJSON/toJSON\": function() {\n        var copy = function(data) { return JSON.parse(JSON.stringify(data)); };\n        var session = new EditSession(\"function (a) {\\n    \\n}\");\n        var selection = session.getSelection();\n\n        selection.moveCursorTo(0, 14);\n        selection.moveCursorDown();\n        assert.position(selection.getCursor(), 1, 4);\n        var data = selection.toJSON();\n        selection.moveCursorDown();        \n        assert.position(selection.getCursor(), 2, 1);\n        \n        assert.ok(!selection.isEqual(data));\n        \n        var nCursor = 0;\n        var nSelection = 0;\n        selection.on(\"changeCursor\", function() { nCursor++; });\n        selection.on(\"changeSelection\", function() { nSelection++; });\n        \n        selection.fromJSON(copy(data));\n        assert.equal(nCursor, 1);\n        assert.equal(nSelection, 1);\n        assert.position(selection.getCursor(), 1, 4);\n        assert.ok(selection.isEqual(data));\n        \n        data.end.column = 10;\n        selection.fromJSON(copy(data));\n        assert.equal(nCursor, 1);\n        assert.equal(nSelection, 1);\n        data.end.column = 4;\n        assert.ok(selection.isEqual(data));\n        \n        data.start.row = 0;\n        selection.fromJSON(copy(data));\n        assert.equal(nCursor, 1);\n        assert.equal(nSelection, 2);\n        assert.ok(selection.isEqual(data));\n        \n        data.isBackwards = true;\n        selection.fromJSON(copy(data));\n        assert.equal(nCursor, 2);\n        assert.equal(nSelection, 3);\n        assert.ok(selection.isEqual(data));\n        \n        selection.moveTo(0, 0);\n        nCursor = nSelection = 0;\n        selection.selectAll();\n        assert.equal(nCursor, 1);\n        assert.equal(nSelection, 1);\n        selection.moveCursorRight();\n        selection.clearSelection();\n        nCursor = nSelection = 0;\n        selection.selectAll();\n        assert.equal(nCursor, 0);\n        assert.equal(nSelection, 1);\n    },\n\n    \"test setRange inside fold\": function() {\n        var session = new EditSession(\"-\\n-fold-\\n-\");\n        var selection = session.getSelection();\n\n        session.addFold(\".\", new Range(0, 1, 2, 0));\n        selection.setRange(new Range(1, 1, 1, 5)); \n        \n        assert.equal(session.getTextRange(), \"fold\");\n    },\n    \n    \"test navigate around line widgets\": function() {\n        var session = new EditSession([\"a\", \"b\", \"\", \"c\", \"d\"]);\n        session.widgetManager = new LineWidgets(session);\n\n        var selection = session.getSelection();\n\n        session.widgetManager.addLineWidget({\n            row: 0,\n            rowCount: 5,\n            rowsAbove: 2\n        });\n        session.widgetManager.addLineWidget({\n            row: 1,\n            rowCount: 3,\n            rowsAbove: 1\n        });\n        session.widgetManager.addLineWidget({\n            row: 3,\n            rowCount: 4\n        });\n        assert.position(session.documentToScreenPosition(3, 1), 11, 1);\n        \n        session.selection.moveCursorLineEnd();\n        session.selection.moveCursorUp();\n        assert.position(selection.cursor, 0, 0);\n        session.selection.moveCursorDown();\n        assert.position(selection.cursor, 1, 1);\n        session.selection.moveCursorDown();\n        assert.position(selection.cursor, 2, 0);\n        session.selection.moveCursorDown();\n        assert.position(selection.cursor, 3, 1);\n        session.selection.moveCursorUp();\n        assert.position(selection.cursor, 2, 0);\n        session.selection.moveCursorUp();\n        assert.position(selection.cursor, 1, 1);\n    },\n\n    \"test selectLine\": function() {\n        var session = new EditSession(\"   text  -\\n-fold-   \\n-\");\n        var selection = session.getSelection();\n\n        selection.selectLine();\n        assert.range(selection.getRange(), 0, 0, 1, 0);\n        selection.clearSelection();\n        assert.position(selection.getAnchor(), 1, 0);\n        \n        selection.moveCursorLineEnd();\n        assert.position(selection.getAnchor(), 1, 9);\n        selection.moveCursorLineEnd();\n        assert.position(selection.getAnchor(), 1, 6);\n        \n        selection.selectLineStart();\n        assert.range(selection.getRange(), 1, 0, 1, 6);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/snippets/abc.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./abc.snippets\");\nexports.scope = \"abc\";\n"
  },
  {
    "path": "src/snippets/abc.snippets.js",
    "content": "module.exports = `\nsnippet zupfnoter.print\n\t%%%%hn.print {\"startpos\": \\${1:pos_y}, \"t\":\"\\${2:title}\", \"v\":[\\${3:voices}], \"s\":[[\\${4:syncvoices}1,2]], \"f\":[\\${5:flowlines}],  \"sf\":[\\${6:subflowlines}], \"j\":[\\${7:jumplines}]}\n\nsnippet zupfnoter.note\n\t%%%%hn.note {\"pos\": [\\${1:pos_x},\\${2:pos_y}], \"text\": \"\\${3:text}\", \"style\": \"\\${4:style}\"}\n\nsnippet zupfnoter.annotation\n\t%%%%hn.annotation {\"id\": \"\\${1:id}\", \"pos\": [\\${2:pos}], \"text\": \"\\${3:text}\"}\n\nsnippet zupfnoter.lyrics\n\t%%%%hn.lyrics {\"pos\": [\\${1:x_pos},\\${2:y_pos}]}\n\nsnippet zupfnoter.legend\n\t%%%%hn.legend {\"pos\": [\\${1:x_pos},\\${2:y_pos}]}\n\n\n\nsnippet zupfnoter.target\n\t\"^:\\${1:target}\"\n\nsnippet zupfnoter.goto\n\t\"^@\\${1:target}@\\${2:distance}\"\n\nsnippet zupfnoter.annotationref\n\t\"^#\\${1:target}\"\n\nsnippet zupfnoter.annotation\n\t\"^!\\${1:text}@\\${2:x_offset},\\${3:y_offset}\"\n\n\n`;\n"
  },
  {
    "path": "src/snippets/actionscript.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./actionscript.snippets\");\nexports.scope = \"actionscript\";\n"
  },
  {
    "path": "src/snippets/actionscript.snippets.js",
    "content": "module.exports = `snippet main\n\tpackage {\n\t\timport flash.display.*;\n\t\timport flash.Events.*;\n\t\n\t\tpublic class Main extends Sprite {\n\t\t\tpublic function Main (\t) {\n\t\t\t\ttrace(\"start\");\n\t\t\t\tstage.scaleMode = StageScaleMode.NO_SCALE;\n\t\t\t\tstage.addEventListener(Event.RESIZE, resizeListener);\n\t\t\t}\n\t\n\t\t\tprivate function resizeListener (e:Event):void {\n\t\t\t\ttrace(\"The application window changed size!\");\n\t\t\t\ttrace(\"New width:  \" + stage.stageWidth);\n\t\t\t\ttrace(\"New height: \" + stage.stageHeight);\n\t\t\t}\n\t\n\t\t}\n\t\n\t}\nsnippet class\n\t\\${1:public|internal} class \\${2:name} \\${3:extends } {\n\t\tpublic function \\$2 (\t) {\n\t\t\t(\"start\");\n\t\t}\n\t}\nsnippet all\n\tpackage name {\n\n\t\t\\${1:public|internal|final} class \\${2:name} \\${3:extends } {\n\t\t\tprivate|public| static const FOO = \"abc\";\n\t\t\tprivate|public| static var BAR = \"abc\";\n\n\t\t\t// class initializer - no JIT !! one time setup\n\t\t\tif Cababilities.os == \"Linux|MacOS\" {\n\t\t\t\tFOO = \"other\";\n\t\t\t}\n\n\t\t\t// constructor:\n\t\t\tpublic function \\$2 (\t){\n\t\t\t\tsuper2();\n\t\t\t\ttrace(\"start\");\n\t\t\t}\n\t\t\tpublic function name (a, b...){\n\t\t\t\tsuper.name(..);\n\t\t\t\tlable:break\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction A(){\n\t\t// A can only be accessed within this file\n\t}\nsnippet switch\n\tswitch(\\${1}){\n\t\tcase \\${2}:\n\t\t\t\\${3}\n\t\tbreak;\n\t\tdefault:\n\t}\nsnippet case\n\t\tcase \\${1}:\n\t\t\t\\${2}\n\t\tbreak;\nsnippet package\n\tpackage \\${1:package}{\n\t\t\\${2}\n\t}\nsnippet wh\n\twhile \\${1:cond}{\n\t\t\\${2}\n\t}\nsnippet do\n\tdo {\n\t\t\\${2}\n\t} while (\\${1:cond})\nsnippet while\n\twhile \\${1:cond}{\n\t\t\\${2}\n\t}\nsnippet for enumerate names\n\tfor (\\${1:var} in \\${2:object}){\n\t\t\\${3}\n\t}\nsnippet for enumerate values\n\tfor each (\\${1:var} in \\${2:object}){\n\t\t\\${3}\n\t}\nsnippet get_set\n\tfunction get \\${1:name} {\n\t\treturn \\${2}\n\t}\n\tfunction set \\$1 (newValue) {\n\t\t\\${3}\n\t}\nsnippet interface\n\tinterface name {\n\t\tfunction method(\\${1}):\\${2:returntype};\n\t}\nsnippet try\n\ttry {\n\t\t\\${1}\n\t} catch (error:ErrorType) {\n\t\t\\${2}\n\t} finally {\n\t\t\\${3}\n\t}\n# For Loop (same as c.snippet)\nsnippet for for (..) {..}\n\tfor (\\${2:i} = 0; \\$2 < \\${1:count}; \\$2\\${3:++}) {\n\t\t\\${4:/* code */}\n\t}\n# Custom For Loop\nsnippet forr\n\tfor (\\${1:i} = \\${2:0}; \\${3:\\$1 < 10}; \\$1\\${4:++}) {\n\t\t\\${5:/* code */}\n\t}\n# If Condition\nsnippet if\n\tif (\\${1:/* condition */}) {\n\t\t\\${2:/* code */}\n\t}\nsnippet el\n\telse {\n\t\t\\${1}\n\t}\n# Ternary conditional\nsnippet t\n\t\\${1:/* condition */} ? \\${2:a} : \\${3:b}\nsnippet fun\n\tfunction \\${1:function_name}(\\${2})\\${3}\n\t{\n\t\t\\${4:/* code */}\n\t}\n# FlxSprite (usefull when using the flixel library)\nsnippet FlxSprite\n\tpackage\n\t{\n\t\timport org.flixel.*\n\n\t\tpublic class \\${1:ClassName} extends \\${2:FlxSprite}\n\t\t{\n\t\t\tpublic function \\$1(\\${3: X:Number, Y:Number}):void\n\t\t\t{\n\t\t\t\tsuper(X,Y);\n\t\t\t\t\\${4: //code...}\n\t\t\t}\n\n\t\t\toverride public function update():void\n\t\t\t{\n\t\t\t\tsuper.update();\n\t\t\t\t\\${5: //code...}\n\t\t\t}\n\t\t}\n\t}\n\n`;\n"
  },
  {
    "path": "src/snippets/c_cpp.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./c_cpp.snippets\");\nexports.scope = \"c_cpp\";\n"
  },
  {
    "path": "src/snippets/c_cpp.snippets.js",
    "content": "module.exports = `## STL Collections\n# std::array\nsnippet array\n\tstd::array<\\${1:T}, \\${2:N}> \\${3};\\${4}\n# std::vector\nsnippet vector\n\tstd::vector<\\${1:T}> \\${2};\\${3}\n# std::deque\nsnippet deque\n\tstd::deque<\\${1:T}> \\${2};\\${3}\n# std::forward_list\nsnippet flist\n\tstd::forward_list<\\${1:T}> \\${2};\\${3}\n# std::list\nsnippet list\n\tstd::list<\\${1:T}> \\${2};\\${3}\n# std::set\nsnippet set\n\tstd::set<\\${1:T}> \\${2};\\${3}\n# std::map\nsnippet map\n\tstd::map<\\${1:Key}, \\${2:T}> \\${3};\\${4}\n# std::multiset\nsnippet mset\n\tstd::multiset<\\${1:T}> \\${2};\\${3}\n# std::multimap\nsnippet mmap\n\tstd::multimap<\\${1:Key}, \\${2:T}> \\${3};\\${4}\n# std::unordered_set\nsnippet uset\n\tstd::unordered_set<\\${1:T}> \\${2};\\${3}\n# std::unordered_map\nsnippet umap\n\tstd::unordered_map<\\${1:Key}, \\${2:T}> \\${3};\\${4}\n# std::unordered_multiset\nsnippet umset\n\tstd::unordered_multiset<\\${1:T}> \\${2};\\${3}\n# std::unordered_multimap\nsnippet ummap\n\tstd::unordered_multimap<\\${1:Key}, \\${2:T}> \\${3};\\${4}\n# std::stack\nsnippet stack\n\tstd::stack<\\${1:T}> \\${2};\\${3}\n# std::queue\nsnippet queue\n\tstd::queue<\\${1:T}> \\${2};\\${3}\n# std::priority_queue\nsnippet pqueue\n\tstd::priority_queue<\\${1:T}> \\${2};\\${3}\n##\n## Access Modifiers\n# private\nsnippet pri\n\tprivate\n# protected\nsnippet pro\n\tprotected\n# public\nsnippet pub\n\tpublic\n# friend\nsnippet fr\n\tfriend\n# mutable\nsnippet mu\n\tmutable\n## \n## Class\n# class\nsnippet cl\n\tclass \\${1:\\`Filename('\\$1', 'name')\\`} \n\t{\n\tpublic:\n\t\t\\$1(\\${2});\n\t\t~\\$1();\n\n\tprivate:\n\t\t\\${3:/* data */}\n\t};\n# member function implementation\nsnippet mfun\n\t\\${4:void} \\${1:\\`Filename('\\$1', 'ClassName')\\`}::\\${2:memberFunction}(\\${3}) {\n\t\t\\${5:/* code */}\n\t}\n# namespace\nsnippet ns\n\tnamespace \\${1:\\`Filename('', 'my')\\`} {\n\t\t\\${2}\n\t} /* namespace \\$1 */\n##\n## Input/Output\n# std::cout\nsnippet cout\n\tstd::cout << \\${1} << std::endl;\\${2}\n# std::cin\nsnippet cin\n\tstd::cin >> \\${1};\\${2}\n##\n## Iteration\n# for i \nsnippet fori\n\tfor (int \\${2:i} = 0; \\$2 < \\${1:count}; \\$2\\${3:++}) {\n\t\t\\${4:/* code */}\n\t}\\${5}\n\n# foreach\nsnippet fore\n\tfor (\\${1:auto} \\${2:i} : \\${3:container}) {\n\t\t\\${4:/* code */}\n\t}\\${5}\n# iterator\nsnippet iter\n\tfor (\\${1:std::vector}<\\${2:type}>::\\${3:const_iterator} \\${4:i} = \\${5:container}.begin(); \\$4 != \\$5.end(); ++\\$4) {\n\t\t\\${6}\n\t}\\${7}\n\n# auto iterator\nsnippet itera\n\tfor (auto \\${1:i} = \\$1.begin(); \\$1 != \\$1.end(); ++\\$1) {\n\t\t\\${2:std::cout << *\\$1 << std::endl;}\n\t}\\${3}\n##\n## Lambdas\n# lamda (one line)\nsnippet ld\n\t[\\${1}](\\${2}){\\${3:/* code */}}\\${4}\n# lambda (multi-line)\nsnippet lld\n\t[\\${1}](\\${2}){\n\t\t\\${3:/* code */}\n\t}\\${4}\n`;\n"
  },
  {
    "path": "src/snippets/clojure.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./clojure.snippets\");\nexports.scope = \"clojure\";\n"
  },
  {
    "path": "src/snippets/clojure.snippets.js",
    "content": "module.exports = `snippet comm\n\t(comment\n\t  \\${1}\n\t  )\nsnippet condp\n\t(condp \\${1:pred} \\${2:expr}\n\t  \\${3})\nsnippet def\n\t(def \\${1})\nsnippet defm\n\t(defmethod \\${1:multifn} \"\\${2:doc-string}\" \\${3:dispatch-val} [\\${4:args}]\n\t  \\${5})\nsnippet defmm\n\t(defmulti \\${1:name} \"\\${2:doc-string}\" \\${3:dispatch-fn})\nsnippet defma\n\t(defmacro \\${1:name} \"\\${2:doc-string}\" \\${3:dispatch-fn})\nsnippet defn\n\t(defn \\${1:name} \"\\${2:doc-string}\" [\\${3:arg-list}]\n\t  \\${4})\nsnippet defp\n\t(defprotocol \\${1:name}\n\t  \\${2})\nsnippet defr\n\t(defrecord \\${1:name} [\\${2:fields}]\n\t  \\${3:protocol}\n\t  \\${4})\nsnippet deft\n\t(deftest \\${1:name}\n\t    (is (= \\${2:assertion})))\n\t  \\${3})\nsnippet is\n\t(is (= \\${1} \\${2}))\nsnippet defty\n\t(deftype \\${1:Name} [\\${2:fields}]\n\t  \\${3:Protocol}\n\t  \\${4})\nsnippet doseq\n\t(doseq [\\${1:elem} \\${2:coll}]\n\t  \\${3})\nsnippet fn\n\t(fn [\\${1:arg-list}] \\${2})\nsnippet if\n\t(if \\${1:test-expr}\n\t  \\${2:then-expr}\n\t  \\${3:else-expr})\nsnippet if-let \n\t(if-let [\\${1:result} \\${2:test-expr}]\n\t\t(\\${3:then-expr} \\$1)\n\t\t(\\${4:else-expr}))\nsnippet imp\n\t(:import [\\${1:package}])\n\t& {:keys [\\${1:keys}] :or {\\${2:defaults}}}\nsnippet let\n\t(let [\\${1:name} \\${2:expr}]\n\t\t\\${3})\nsnippet letfn\n\t(letfn [(\\${1:name) [\\${2:args}]\n\t          \\${3})])\nsnippet map\n\t(map \\${1:func} \\${2:coll})\nsnippet mapl\n\t(map #(\\${1:lambda}) \\${2:coll})\nsnippet met\n\t(\\${1:name} [\\${2:this} \\${3:args}]\n\t  \\${4})\nsnippet ns\n\t(ns \\${1:name}\n\t  \\${2})\nsnippet dotimes\n\t(dotimes [_ 10]\n\t  (time\n\t    (dotimes [_ \\${1:times}]\n\t      \\${2})))\nsnippet pmethod\n\t(\\${1:name} [\\${2:this} \\${3:args}])\nsnippet refer\n\t(:refer-clojure :exclude [\\${1}])\nsnippet require\n\t(:require [\\${1:namespace} :as [\\${2}]])\nsnippet use\n\t(:use [\\${1:namespace} :only [\\${2}]])\nsnippet print\n\t(println \\${1})\nsnippet reduce\n\t(reduce \\${1:(fn [p n] \\${3})} \\${2})\nsnippet when\n\t(when \\${1:test} \\${2:body})\nsnippet when-let\n\t(when-let [\\${1:result} \\${2:test}]\n\t\t\\${3:body})\n`;\n"
  },
  {
    "path": "src/snippets/coffee.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./coffee.snippets\");\nexports.scope = \"coffee\";\n"
  },
  {
    "path": "src/snippets/coffee.snippets.js",
    "content": "module.exports = `# Closure loop\nsnippet forindo\n\tfor \\${1:name} in \\${2:array}\n\t\tdo (\\$1) ->\n\t\t\t\\${3:// body}\n# Array comprehension\nsnippet fora\n\tfor \\${1:name} in \\${2:array}\n\t\t\\${3:// body...}\n# Object comprehension\nsnippet foro\n\tfor \\${1:key}, \\${2:value} of \\${3:object}\n\t\t\\${4:// body...}\n# Range comprehension (inclusive)\nsnippet forr\n\tfor \\${1:name} in [\\${2:start}..\\${3:finish}]\n\t\t\\${4:// body...}\nsnippet forrb\n\tfor \\${1:name} in [\\${2:start}..\\${3:finish}] by \\${4:step}\n\t\t\\${5:// body...}\n# Range comprehension (exclusive)\nsnippet forrex\n\tfor \\${1:name} in [\\${2:start}...\\${3:finish}]\n\t\t\\${4:// body...}\nsnippet forrexb\n\tfor \\${1:name} in [\\${2:start}...\\${3:finish}] by \\${4:step}\n\t\t\\${5:// body...}\n# Function\nsnippet fun\n\t(\\${1:args}) ->\n\t\t\\${2:// body...}\n# Function (bound)\nsnippet bfun\n\t(\\${1:args}) =>\n\t\t\\${2:// body...}\n# Class\nsnippet cla class ..\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\t\\${2}\nsnippet cla class .. constructor: ..\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\tconstructor: (\\${2:args}) ->\n\t\t\t\\${3}\n\n\t\t\\${4}\nsnippet cla class .. extends ..\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`} extends \\${2:ParentClass}\n\t\t\\${3}\nsnippet cla class .. extends .. constructor: ..\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`} extends \\${2:ParentClass}\n\t\tconstructor: (\\${3:args}) ->\n\t\t\t\\${4}\n\n\t\t\\${5}\n# If\nsnippet if\n\tif \\${1:condition}\n\t\t\\${2:// body...}\n# If __ Else\nsnippet ife\n\tif \\${1:condition}\n\t\t\\${2:// body...}\n\telse\n\t\t\\${3:// body...}\n# Else if\nsnippet elif\n\telse if \\${1:condition}\n\t\t\\${2:// body...}\n# Ternary If\nsnippet ifte\n\tif \\${1:condition} then \\${2:value} else \\${3:other}\n# Unless\nsnippet unl\n\t\\${1:action} unless \\${2:condition}\n# Switch\nsnippet swi\n\tswitch \\${1:object}\n\t\twhen \\${2:value}\n\t\t\t\\${3:// body...}\n\n# Log\nsnippet log\n\tconsole.log \\${1}\n# Try __ Catch\nsnippet try\n\ttry\n\t\t\\${1}\n\tcatch \\${2:error}\n\t\t\\${3}\n# Require\nsnippet req\n\t\\${2:\\$1} = require '\\${1:sys}'\\${3}\n# Export\nsnippet exp\n\t\\${1:root} = exports ? this\n`;\n"
  },
  {
    "path": "src/snippets/csound_document.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./csound_document.snippets\");\nexports.scope = \"csound_document\";\n"
  },
  {
    "path": "src/snippets/csound_document.snippets.js",
    "content": "module.exports = `# <CsoundSynthesizer>\nsnippet synth\n\t<CsoundSynthesizer>\n\t<CsInstruments>\n\t\\${1}\n\t</CsInstruments>\n\t<CsScore>\n\te\n\t</CsScore>\n\t</CsoundSynthesizer>\n`;\n"
  },
  {
    "path": "src/snippets/csound_orchestra.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./csound_orchestra.snippets\");\nexports.scope = \"csound_orchestra\";\n"
  },
  {
    "path": "src/snippets/csound_orchestra.snippets.js",
    "content": "module.exports = `# else\nsnippet else\n\telse\n\t\t\\${1:/* statements */}\n# elseif\nsnippet elseif\n\telseif \\${1:/* condition */} then\n\t\t\\${2:/* statements */}\n# if\nsnippet if\n\tif \\${1:/* condition */} then\n\t\t\\${2:/* statements */}\n\tendif\n# instrument block\nsnippet instr\n\tinstr \\${1:name}\n\t\t\\${2:/* statements */}\n\tendin\n# i-time while loop\nsnippet iwhile\n\ti\\${1:Index} = \\${2:0}\n\twhile i\\${1:Index} < \\${3:/* count */} do\n\t\t\\${4:/* statements */}\n\t\ti\\${1:Index} += 1\n\tod\n# k-rate while loop\nsnippet kwhile\n\tk\\${1:Index} = \\${2:0}\n\twhile k\\${1:Index} < \\${3:/* count */} do\n\t\t\\${4:/* statements */}\n\t\tk\\${1:Index} += 1\n\tod\n# opcode\nsnippet opcode\n\topcode \\${1:name}, \\${2:/* output types */ 0}, \\${3:/* input types */ 0}\n\t\t\\${4:/* statements */}\n\tendop\n# until loop\nsnippet until\n\tuntil \\${1:/* condition */} do\n\t\t\\${2:/* statements */}\n\tod\n# while loop\nsnippet while\n\twhile \\${1:/* condition */} do\n\t\t\\${2:/* statements */}\n\tod\n`;\n"
  },
  {
    "path": "src/snippets/css.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./css.snippets\");\nexports.scope = \"css\";\n"
  },
  {
    "path": "src/snippets/css.snippets.js",
    "content": "module.exports = `snippet .\n\t\\${1} {\n\t\t\\${2}\n\t}\nsnippet !\n\t !important\nsnippet bdi:m+\n\t-moz-border-image: url(\\${1}) \\${2:0} \\${3:0} \\${4:0} \\${5:0} \\${6:stretch} \\${7:stretch};\nsnippet bdi:m\n\t-moz-border-image: \\${1};\nsnippet bdrz:m\n\t-moz-border-radius: \\${1};\nsnippet bxsh:m+\n\t-moz-box-shadow: \\${1:0} \\${2:0} \\${3:0} #\\${4:000};\nsnippet bxsh:m\n\t-moz-box-shadow: \\${1};\nsnippet bdi:w+\n\t-webkit-border-image: url(\\${1}) \\${2:0} \\${3:0} \\${4:0} \\${5:0} \\${6:stretch} \\${7:stretch};\nsnippet bdi:w\n\t-webkit-border-image: \\${1};\nsnippet bdrz:w\n\t-webkit-border-radius: \\${1};\nsnippet bxsh:w+\n\t-webkit-box-shadow: \\${1:0} \\${2:0} \\${3:0} #\\${4:000};\nsnippet bxsh:w\n\t-webkit-box-shadow: \\${1};\nsnippet @f\n\t@font-face {\n\t\tfont-family: \\${1};\n\t\tsrc: url(\\${2});\n\t}\nsnippet @i\n\t@import url(\\${1});\nsnippet @m\n\t@media \\${1:print} {\n\t\t\\${2}\n\t}\nsnippet bg+\n\tbackground: #\\${1:FFF} url(\\${2}) \\${3:0} \\${4:0} \\${5:no-repeat};\nsnippet bga\n\tbackground-attachment: \\${1};\nsnippet bga:f\n\tbackground-attachment: fixed;\nsnippet bga:s\n\tbackground-attachment: scroll;\nsnippet bgbk\n\tbackground-break: \\${1};\nsnippet bgbk:bb\n\tbackground-break: bounding-box;\nsnippet bgbk:c\n\tbackground-break: continuous;\nsnippet bgbk:eb\n\tbackground-break: each-box;\nsnippet bgcp\n\tbackground-clip: \\${1};\nsnippet bgcp:bb\n\tbackground-clip: border-box;\nsnippet bgcp:cb\n\tbackground-clip: content-box;\nsnippet bgcp:nc\n\tbackground-clip: no-clip;\nsnippet bgcp:pb\n\tbackground-clip: padding-box;\nsnippet bgc\n\tbackground-color: #\\${1:FFF};\nsnippet bgc:t\n\tbackground-color: transparent;\nsnippet bgi\n\tbackground-image: url(\\${1});\nsnippet bgi:n\n\tbackground-image: none;\nsnippet bgo\n\tbackground-origin: \\${1};\nsnippet bgo:bb\n\tbackground-origin: border-box;\nsnippet bgo:cb\n\tbackground-origin: content-box;\nsnippet bgo:pb\n\tbackground-origin: padding-box;\nsnippet bgpx\n\tbackground-position-x: \\${1};\nsnippet bgpy\n\tbackground-position-y: \\${1};\nsnippet bgp\n\tbackground-position: \\${1:0} \\${2:0};\nsnippet bgr\n\tbackground-repeat: \\${1};\nsnippet bgr:n\n\tbackground-repeat: no-repeat;\nsnippet bgr:x\n\tbackground-repeat: repeat-x;\nsnippet bgr:y\n\tbackground-repeat: repeat-y;\nsnippet bgr:r\n\tbackground-repeat: repeat;\nsnippet bgz\n\tbackground-size: \\${1};\nsnippet bgz:a\n\tbackground-size: auto;\nsnippet bgz:ct\n\tbackground-size: contain;\nsnippet bgz:cv\n\tbackground-size: cover;\nsnippet bg\n\tbackground: \\${1};\nsnippet bg:ie\n\tfilter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\\${1}',sizingMethod='\\${2:crop}');\nsnippet bg:n\n\tbackground: none;\nsnippet bd+\n\tborder: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet bdb+\n\tborder-bottom: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet bdbc\n\tborder-bottom-color: #\\${1:000};\nsnippet bdbi\n\tborder-bottom-image: url(\\${1});\nsnippet bdbi:n\n\tborder-bottom-image: none;\nsnippet bdbli\n\tborder-bottom-left-image: url(\\${1});\nsnippet bdbli:c\n\tborder-bottom-left-image: continue;\nsnippet bdbli:n\n\tborder-bottom-left-image: none;\nsnippet bdblrz\n\tborder-bottom-left-radius: \\${1};\nsnippet bdbri\n\tborder-bottom-right-image: url(\\${1});\nsnippet bdbri:c\n\tborder-bottom-right-image: continue;\nsnippet bdbri:n\n\tborder-bottom-right-image: none;\nsnippet bdbrrz\n\tborder-bottom-right-radius: \\${1};\nsnippet bdbs\n\tborder-bottom-style: \\${1};\nsnippet bdbs:n\n\tborder-bottom-style: none;\nsnippet bdbw\n\tborder-bottom-width: \\${1};\nsnippet bdb\n\tborder-bottom: \\${1};\nsnippet bdb:n\n\tborder-bottom: none;\nsnippet bdbk\n\tborder-break: \\${1};\nsnippet bdbk:c\n\tborder-break: close;\nsnippet bdcl\n\tborder-collapse: \\${1};\nsnippet bdcl:c\n\tborder-collapse: collapse;\nsnippet bdcl:s\n\tborder-collapse: separate;\nsnippet bdc\n\tborder-color: #\\${1:000};\nsnippet bdci\n\tborder-corner-image: url(\\${1});\nsnippet bdci:c\n\tborder-corner-image: continue;\nsnippet bdci:n\n\tborder-corner-image: none;\nsnippet bdf\n\tborder-fit: \\${1};\nsnippet bdf:c\n\tborder-fit: clip;\nsnippet bdf:of\n\tborder-fit: overwrite;\nsnippet bdf:ow\n\tborder-fit: overwrite;\nsnippet bdf:r\n\tborder-fit: repeat;\nsnippet bdf:sc\n\tborder-fit: scale;\nsnippet bdf:sp\n\tborder-fit: space;\nsnippet bdf:st\n\tborder-fit: stretch;\nsnippet bdi\n\tborder-image: url(\\${1}) \\${2:0} \\${3:0} \\${4:0} \\${5:0} \\${6:stretch} \\${7:stretch};\nsnippet bdi:n\n\tborder-image: none;\nsnippet bdl+\n\tborder-left: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet bdlc\n\tborder-left-color: #\\${1:000};\nsnippet bdli\n\tborder-left-image: url(\\${1});\nsnippet bdli:n\n\tborder-left-image: none;\nsnippet bdls\n\tborder-left-style: \\${1};\nsnippet bdls:n\n\tborder-left-style: none;\nsnippet bdlw\n\tborder-left-width: \\${1};\nsnippet bdl\n\tborder-left: \\${1};\nsnippet bdl:n\n\tborder-left: none;\nsnippet bdlt\n\tborder-length: \\${1};\nsnippet bdlt:a\n\tborder-length: auto;\nsnippet bdrz\n\tborder-radius: \\${1};\nsnippet bdr+\n\tborder-right: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet bdrc\n\tborder-right-color: #\\${1:000};\nsnippet bdri\n\tborder-right-image: url(\\${1});\nsnippet bdri:n\n\tborder-right-image: none;\nsnippet bdrs\n\tborder-right-style: \\${1};\nsnippet bdrs:n\n\tborder-right-style: none;\nsnippet bdrw\n\tborder-right-width: \\${1};\nsnippet bdr\n\tborder-right: \\${1};\nsnippet bdr:n\n\tborder-right: none;\nsnippet bdsp\n\tborder-spacing: \\${1};\nsnippet bds\n\tborder-style: \\${1};\nsnippet bds:ds\n\tborder-style: dashed;\nsnippet bds:dtds\n\tborder-style: dot-dash;\nsnippet bds:dtdtds\n\tborder-style: dot-dot-dash;\nsnippet bds:dt\n\tborder-style: dotted;\nsnippet bds:db\n\tborder-style: double;\nsnippet bds:g\n\tborder-style: groove;\nsnippet bds:h\n\tborder-style: hidden;\nsnippet bds:i\n\tborder-style: inset;\nsnippet bds:n\n\tborder-style: none;\nsnippet bds:o\n\tborder-style: outset;\nsnippet bds:r\n\tborder-style: ridge;\nsnippet bds:s\n\tborder-style: solid;\nsnippet bds:w\n\tborder-style: wave;\nsnippet bdt+\n\tborder-top: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet bdtc\n\tborder-top-color: #\\${1:000};\nsnippet bdti\n\tborder-top-image: url(\\${1});\nsnippet bdti:n\n\tborder-top-image: none;\nsnippet bdtli\n\tborder-top-left-image: url(\\${1});\nsnippet bdtli:c\n\tborder-corner-image: continue;\nsnippet bdtli:n\n\tborder-corner-image: none;\nsnippet bdtlrz\n\tborder-top-left-radius: \\${1};\nsnippet bdtri\n\tborder-top-right-image: url(\\${1});\nsnippet bdtri:c\n\tborder-top-right-image: continue;\nsnippet bdtri:n\n\tborder-top-right-image: none;\nsnippet bdtrrz\n\tborder-top-right-radius: \\${1};\nsnippet bdts\n\tborder-top-style: \\${1};\nsnippet bdts:n\n\tborder-top-style: none;\nsnippet bdtw\n\tborder-top-width: \\${1};\nsnippet bdt\n\tborder-top: \\${1};\nsnippet bdt:n\n\tborder-top: none;\nsnippet bdw\n\tborder-width: \\${1};\nsnippet bd\n\tborder: \\${1};\nsnippet bd:n\n\tborder: none;\nsnippet b\n\tbottom: \\${1};\nsnippet b:a\n\tbottom: auto;\nsnippet bxsh+\n\tbox-shadow: \\${1:0} \\${2:0} \\${3:0} #\\${4:000};\nsnippet bxsh\n\tbox-shadow: \\${1};\nsnippet bxsh:n\n\tbox-shadow: none;\nsnippet bxz\n\tbox-sizing: \\${1};\nsnippet bxz:bb\n\tbox-sizing: border-box;\nsnippet bxz:cb\n\tbox-sizing: content-box;\nsnippet cps\n\tcaption-side: \\${1};\nsnippet cps:b\n\tcaption-side: bottom;\nsnippet cps:t\n\tcaption-side: top;\nsnippet cl\n\tclear: \\${1};\nsnippet cl:b\n\tclear: both;\nsnippet cl:l\n\tclear: left;\nsnippet cl:n\n\tclear: none;\nsnippet cl:r\n\tclear: right;\nsnippet cp\n\tclip: \\${1};\nsnippet cp:a\n\tclip: auto;\nsnippet cp:r\n\tclip: rect(\\${1:0} \\${2:0} \\${3:0} \\${4:0});\nsnippet c\n\tcolor: #\\${1:000};\nsnippet ct\n\tcontent: \\${1};\nsnippet ct:a\n\tcontent: attr(\\${1});\nsnippet ct:cq\n\tcontent: close-quote;\nsnippet ct:c\n\tcontent: counter(\\${1});\nsnippet ct:cs\n\tcontent: counters(\\${1});\nsnippet ct:ncq\n\tcontent: no-close-quote;\nsnippet ct:noq\n\tcontent: no-open-quote;\nsnippet ct:n\n\tcontent: normal;\nsnippet ct:oq\n\tcontent: open-quote;\nsnippet coi\n\tcounter-increment: \\${1};\nsnippet cor\n\tcounter-reset: \\${1};\nsnippet cur\n\tcursor: \\${1};\nsnippet cur:a\n\tcursor: auto;\nsnippet cur:c\n\tcursor: crosshair;\nsnippet cur:d\n\tcursor: default;\nsnippet cur:ha\n\tcursor: hand;\nsnippet cur:he\n\tcursor: help;\nsnippet cur:m\n\tcursor: move;\nsnippet cur:p\n\tcursor: pointer;\nsnippet cur:t\n\tcursor: text;\nsnippet d\n\tdisplay: \\${1};\nsnippet d:mib\n\tdisplay: -moz-inline-box;\nsnippet d:mis\n\tdisplay: -moz-inline-stack;\nsnippet d:b\n\tdisplay: block;\nsnippet d:cp\n\tdisplay: compact;\nsnippet d:ib\n\tdisplay: inline-block;\nsnippet d:itb\n\tdisplay: inline-table;\nsnippet d:i\n\tdisplay: inline;\nsnippet d:li\n\tdisplay: list-item;\nsnippet d:n\n\tdisplay: none;\nsnippet d:ri\n\tdisplay: run-in;\nsnippet d:tbcp\n\tdisplay: table-caption;\nsnippet d:tbc\n\tdisplay: table-cell;\nsnippet d:tbclg\n\tdisplay: table-column-group;\nsnippet d:tbcl\n\tdisplay: table-column;\nsnippet d:tbfg\n\tdisplay: table-footer-group;\nsnippet d:tbhg\n\tdisplay: table-header-group;\nsnippet d:tbrg\n\tdisplay: table-row-group;\nsnippet d:tbr\n\tdisplay: table-row;\nsnippet d:tb\n\tdisplay: table;\nsnippet ec\n\tempty-cells: \\${1};\nsnippet ec:h\n\tempty-cells: hide;\nsnippet ec:s\n\tempty-cells: show;\nsnippet exp\n\texpression()\nsnippet fl\n\tfloat: \\${1};\nsnippet fl:l\n\tfloat: left;\nsnippet fl:n\n\tfloat: none;\nsnippet fl:r\n\tfloat: right;\nsnippet f+\n\tfont: \\${1:1em} \\${2:Arial},\\${3:sans-serif};\nsnippet fef\n\tfont-effect: \\${1};\nsnippet fef:eb\n\tfont-effect: emboss;\nsnippet fef:eg\n\tfont-effect: engrave;\nsnippet fef:n\n\tfont-effect: none;\nsnippet fef:o\n\tfont-effect: outline;\nsnippet femp\n\tfont-emphasize-position: \\${1};\nsnippet femp:a\n\tfont-emphasize-position: after;\nsnippet femp:b\n\tfont-emphasize-position: before;\nsnippet fems\n\tfont-emphasize-style: \\${1};\nsnippet fems:ac\n\tfont-emphasize-style: accent;\nsnippet fems:c\n\tfont-emphasize-style: circle;\nsnippet fems:ds\n\tfont-emphasize-style: disc;\nsnippet fems:dt\n\tfont-emphasize-style: dot;\nsnippet fems:n\n\tfont-emphasize-style: none;\nsnippet fem\n\tfont-emphasize: \\${1};\nsnippet ff\n\tfont-family: \\${1};\nsnippet ff:c\n\tfont-family: \\${1:'Monotype Corsiva','Comic Sans MS'},cursive;\nsnippet ff:f\n\tfont-family: \\${1:Capitals,Impact},fantasy;\nsnippet ff:m\n\tfont-family: \\${1:Monaco,'Courier New'},monospace;\nsnippet ff:ss\n\tfont-family: \\${1:Helvetica,Arial},sans-serif;\nsnippet ff:s\n\tfont-family: \\${1:Georgia,'Times New Roman'},serif;\nsnippet fza\n\tfont-size-adjust: \\${1};\nsnippet fza:n\n\tfont-size-adjust: none;\nsnippet fz\n\tfont-size: \\${1};\nsnippet fsm\n\tfont-smooth: \\${1};\nsnippet fsm:aw\n\tfont-smooth: always;\nsnippet fsm:a\n\tfont-smooth: auto;\nsnippet fsm:n\n\tfont-smooth: never;\nsnippet fst\n\tfont-stretch: \\${1};\nsnippet fst:c\n\tfont-stretch: condensed;\nsnippet fst:e\n\tfont-stretch: expanded;\nsnippet fst:ec\n\tfont-stretch: extra-condensed;\nsnippet fst:ee\n\tfont-stretch: extra-expanded;\nsnippet fst:n\n\tfont-stretch: normal;\nsnippet fst:sc\n\tfont-stretch: semi-condensed;\nsnippet fst:se\n\tfont-stretch: semi-expanded;\nsnippet fst:uc\n\tfont-stretch: ultra-condensed;\nsnippet fst:ue\n\tfont-stretch: ultra-expanded;\nsnippet fs\n\tfont-style: \\${1};\nsnippet fs:i\n\tfont-style: italic;\nsnippet fs:n\n\tfont-style: normal;\nsnippet fs:o\n\tfont-style: oblique;\nsnippet fv\n\tfont-variant: \\${1};\nsnippet fv:n\n\tfont-variant: normal;\nsnippet fv:sc\n\tfont-variant: small-caps;\nsnippet fw\n\tfont-weight: \\${1};\nsnippet fw:b\n\tfont-weight: bold;\nsnippet fw:br\n\tfont-weight: bolder;\nsnippet fw:lr\n\tfont-weight: lighter;\nsnippet fw:n\n\tfont-weight: normal;\nsnippet f\n\tfont: \\${1};\nsnippet h\n\theight: \\${1};\nsnippet h:a\n\theight: auto;\nsnippet l\n\tleft: \\${1};\nsnippet l:a\n\tleft: auto;\nsnippet lts\n\tletter-spacing: \\${1};\nsnippet lh\n\tline-height: \\${1};\nsnippet lisi\n\tlist-style-image: url(\\${1});\nsnippet lisi:n\n\tlist-style-image: none;\nsnippet lisp\n\tlist-style-position: \\${1};\nsnippet lisp:i\n\tlist-style-position: inside;\nsnippet lisp:o\n\tlist-style-position: outside;\nsnippet list\n\tlist-style-type: \\${1};\nsnippet list:c\n\tlist-style-type: circle;\nsnippet list:dclz\n\tlist-style-type: decimal-leading-zero;\nsnippet list:dc\n\tlist-style-type: decimal;\nsnippet list:d\n\tlist-style-type: disc;\nsnippet list:lr\n\tlist-style-type: lower-roman;\nsnippet list:n\n\tlist-style-type: none;\nsnippet list:s\n\tlist-style-type: square;\nsnippet list:ur\n\tlist-style-type: upper-roman;\nsnippet lis\n\tlist-style: \\${1};\nsnippet lis:n\n\tlist-style: none;\nsnippet mb\n\tmargin-bottom: \\${1};\nsnippet mb:a\n\tmargin-bottom: auto;\nsnippet ml\n\tmargin-left: \\${1};\nsnippet ml:a\n\tmargin-left: auto;\nsnippet mr\n\tmargin-right: \\${1};\nsnippet mr:a\n\tmargin-right: auto;\nsnippet mt\n\tmargin-top: \\${1};\nsnippet mt:a\n\tmargin-top: auto;\nsnippet m\n\tmargin: \\${1};\nsnippet m:4\n\tmargin: \\${1:0} \\${2:0} \\${3:0} \\${4:0};\nsnippet m:3\n\tmargin: \\${1:0} \\${2:0} \\${3:0};\nsnippet m:2\n\tmargin: \\${1:0} \\${2:0};\nsnippet m:0\n\tmargin: 0;\nsnippet m:a\n\tmargin: auto;\nsnippet mah\n\tmax-height: \\${1};\nsnippet mah:n\n\tmax-height: none;\nsnippet maw\n\tmax-width: \\${1};\nsnippet maw:n\n\tmax-width: none;\nsnippet mih\n\tmin-height: \\${1};\nsnippet miw\n\tmin-width: \\${1};\nsnippet op\n\topacity: \\${1};\nsnippet op:ie\n\tfilter: progid:DXImageTransform.Microsoft.Alpha(Opacity=\\${1:100});\nsnippet op:ms\n\t-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=\\${1:100})';\nsnippet orp\n\torphans: \\${1};\nsnippet o+\n\toutline: \\${1:1px} \\${2:solid} #\\${3:000};\nsnippet oc\n\toutline-color: \\${1:#000};\nsnippet oc:i\n\toutline-color: invert;\nsnippet oo\n\toutline-offset: \\${1};\nsnippet os\n\toutline-style: \\${1};\nsnippet ow\n\toutline-width: \\${1};\nsnippet o\n\toutline: \\${1};\nsnippet o:n\n\toutline: none;\nsnippet ovs\n\toverflow-style: \\${1};\nsnippet ovs:a\n\toverflow-style: auto;\nsnippet ovs:mq\n\toverflow-style: marquee;\nsnippet ovs:mv\n\toverflow-style: move;\nsnippet ovs:p\n\toverflow-style: panner;\nsnippet ovs:s\n\toverflow-style: scrollbar;\nsnippet ovx\n\toverflow-x: \\${1};\nsnippet ovx:a\n\toverflow-x: auto;\nsnippet ovx:h\n\toverflow-x: hidden;\nsnippet ovx:s\n\toverflow-x: scroll;\nsnippet ovx:v\n\toverflow-x: visible;\nsnippet ovy\n\toverflow-y: \\${1};\nsnippet ovy:a\n\toverflow-y: auto;\nsnippet ovy:h\n\toverflow-y: hidden;\nsnippet ovy:s\n\toverflow-y: scroll;\nsnippet ovy:v\n\toverflow-y: visible;\nsnippet ov\n\toverflow: \\${1};\nsnippet ov:a\n\toverflow: auto;\nsnippet ov:h\n\toverflow: hidden;\nsnippet ov:s\n\toverflow: scroll;\nsnippet ov:v\n\toverflow: visible;\nsnippet pb\n\tpadding-bottom: \\${1};\nsnippet pl\n\tpadding-left: \\${1};\nsnippet pr\n\tpadding-right: \\${1};\nsnippet pt\n\tpadding-top: \\${1};\nsnippet p\n\tpadding: \\${1};\nsnippet p:4\n\tpadding: \\${1:0} \\${2:0} \\${3:0} \\${4:0};\nsnippet p:3\n\tpadding: \\${1:0} \\${2:0} \\${3:0};\nsnippet p:2\n\tpadding: \\${1:0} \\${2:0};\nsnippet p:0\n\tpadding: 0;\nsnippet pgba\n\tpage-break-after: \\${1};\nsnippet pgba:aw\n\tpage-break-after: always;\nsnippet pgba:a\n\tpage-break-after: auto;\nsnippet pgba:l\n\tpage-break-after: left;\nsnippet pgba:r\n\tpage-break-after: right;\nsnippet pgbb\n\tpage-break-before: \\${1};\nsnippet pgbb:aw\n\tpage-break-before: always;\nsnippet pgbb:a\n\tpage-break-before: auto;\nsnippet pgbb:l\n\tpage-break-before: left;\nsnippet pgbb:r\n\tpage-break-before: right;\nsnippet pgbi\n\tpage-break-inside: \\${1};\nsnippet pgbi:a\n\tpage-break-inside: auto;\nsnippet pgbi:av\n\tpage-break-inside: avoid;\nsnippet pos\n\tposition: \\${1};\nsnippet pos:a\n\tposition: absolute;\nsnippet pos:f\n\tposition: fixed;\nsnippet pos:r\n\tposition: relative;\nsnippet pos:s\n\tposition: static;\nsnippet q\n\tquotes: \\${1};\nsnippet q:en\n\tquotes: '\\\\201C' '\\\\201D' '\\\\2018' '\\\\2019';\nsnippet q:n\n\tquotes: none;\nsnippet q:ru\n\tquotes: '\\\\00AB' '\\\\00BB' '\\\\201E' '\\\\201C';\nsnippet rz\n\tresize: \\${1};\nsnippet rz:b\n\tresize: both;\nsnippet rz:h\n\tresize: horizontal;\nsnippet rz:n\n\tresize: none;\nsnippet rz:v\n\tresize: vertical;\nsnippet r\n\tright: \\${1};\nsnippet r:a\n\tright: auto;\nsnippet tbl\n\ttable-layout: \\${1};\nsnippet tbl:a\n\ttable-layout: auto;\nsnippet tbl:f\n\ttable-layout: fixed;\nsnippet tal\n\ttext-align-last: \\${1};\nsnippet tal:a\n\ttext-align-last: auto;\nsnippet tal:c\n\ttext-align-last: center;\nsnippet tal:l\n\ttext-align-last: left;\nsnippet tal:r\n\ttext-align-last: right;\nsnippet ta\n\ttext-align: \\${1};\nsnippet ta:c\n\ttext-align: center;\nsnippet ta:l\n\ttext-align: left;\nsnippet ta:r\n\ttext-align: right;\nsnippet td\n\ttext-decoration: \\${1};\nsnippet td:l\n\ttext-decoration: line-through;\nsnippet td:n\n\ttext-decoration: none;\nsnippet td:o\n\ttext-decoration: overline;\nsnippet td:u\n\ttext-decoration: underline;\nsnippet te\n\ttext-emphasis: \\${1};\nsnippet te:ac\n\ttext-emphasis: accent;\nsnippet te:a\n\ttext-emphasis: after;\nsnippet te:b\n\ttext-emphasis: before;\nsnippet te:c\n\ttext-emphasis: circle;\nsnippet te:ds\n\ttext-emphasis: disc;\nsnippet te:dt\n\ttext-emphasis: dot;\nsnippet te:n\n\ttext-emphasis: none;\nsnippet th\n\ttext-height: \\${1};\nsnippet th:a\n\ttext-height: auto;\nsnippet th:f\n\ttext-height: font-size;\nsnippet th:m\n\ttext-height: max-size;\nsnippet th:t\n\ttext-height: text-size;\nsnippet ti\n\ttext-indent: \\${1};\nsnippet ti:-\n\ttext-indent: -9999px;\nsnippet tj\n\ttext-justify: \\${1};\nsnippet tj:a\n\ttext-justify: auto;\nsnippet tj:d\n\ttext-justify: distribute;\nsnippet tj:ic\n\ttext-justify: inter-cluster;\nsnippet tj:ii\n\ttext-justify: inter-ideograph;\nsnippet tj:iw\n\ttext-justify: inter-word;\nsnippet tj:k\n\ttext-justify: kashida;\nsnippet tj:t\n\ttext-justify: tibetan;\nsnippet to+\n\ttext-outline: \\${1:0} \\${2:0} #\\${3:000};\nsnippet to\n\ttext-outline: \\${1};\nsnippet to:n\n\ttext-outline: none;\nsnippet tr\n\ttext-replace: \\${1};\nsnippet tr:n\n\ttext-replace: none;\nsnippet tsh+\n\ttext-shadow: \\${1:0} \\${2:0} \\${3:0} #\\${4:000};\nsnippet tsh\n\ttext-shadow: \\${1};\nsnippet tsh:n\n\ttext-shadow: none;\nsnippet tt\n\ttext-transform: \\${1};\nsnippet tt:c\n\ttext-transform: capitalize;\nsnippet tt:l\n\ttext-transform: lowercase;\nsnippet tt:n\n\ttext-transform: none;\nsnippet tt:u\n\ttext-transform: uppercase;\nsnippet tw\n\ttext-wrap: \\${1};\nsnippet tw:no\n\ttext-wrap: none;\nsnippet tw:n\n\ttext-wrap: normal;\nsnippet tw:s\n\ttext-wrap: suppress;\nsnippet tw:u\n\ttext-wrap: unrestricted;\nsnippet t\n\ttop: \\${1};\nsnippet t:a\n\ttop: auto;\nsnippet va\n\tvertical-align: \\${1};\nsnippet va:bl\n\tvertical-align: baseline;\nsnippet va:b\n\tvertical-align: bottom;\nsnippet va:m\n\tvertical-align: middle;\nsnippet va:sub\n\tvertical-align: sub;\nsnippet va:sup\n\tvertical-align: super;\nsnippet va:tb\n\tvertical-align: text-bottom;\nsnippet va:tt\n\tvertical-align: text-top;\nsnippet va:t\n\tvertical-align: top;\nsnippet v\n\tvisibility: \\${1};\nsnippet v:c\n\tvisibility: collapse;\nsnippet v:h\n\tvisibility: hidden;\nsnippet v:v\n\tvisibility: visible;\nsnippet whsc\n\twhite-space-collapse: \\${1};\nsnippet whsc:ba\n\twhite-space-collapse: break-all;\nsnippet whsc:bs\n\twhite-space-collapse: break-strict;\nsnippet whsc:k\n\twhite-space-collapse: keep-all;\nsnippet whsc:l\n\twhite-space-collapse: loose;\nsnippet whsc:n\n\twhite-space-collapse: normal;\nsnippet whs\n\twhite-space: \\${1};\nsnippet whs:n\n\twhite-space: normal;\nsnippet whs:nw\n\twhite-space: nowrap;\nsnippet whs:pl\n\twhite-space: pre-line;\nsnippet whs:pw\n\twhite-space: pre-wrap;\nsnippet whs:p\n\twhite-space: pre;\nsnippet wid\n\twidows: \\${1};\nsnippet w\n\twidth: \\${1};\nsnippet w:a\n\twidth: auto;\nsnippet wob\n\tword-break: \\${1};\nsnippet wob:ba\n\tword-break: break-all;\nsnippet wob:bs\n\tword-break: break-strict;\nsnippet wob:k\n\tword-break: keep-all;\nsnippet wob:l\n\tword-break: loose;\nsnippet wob:n\n\tword-break: normal;\nsnippet wos\n\tword-spacing: \\${1};\nsnippet wow\n\tword-wrap: \\${1};\nsnippet wow:no\n\tword-wrap: none;\nsnippet wow:n\n\tword-wrap: normal;\nsnippet wow:s\n\tword-wrap: suppress;\nsnippet wow:u\n\tword-wrap: unrestricted;\nsnippet z\n\tz-index: \\${1};\nsnippet z:a\n\tz-index: auto;\nsnippet zoo\n\tzoom: 1;\n`;\n"
  },
  {
    "path": "src/snippets/dart.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./dart.snippets\");\nexports.scope = \"dart\";\n"
  },
  {
    "path": "src/snippets/dart.snippets.js",
    "content": "module.exports = `snippet lib\n\tlibrary \\${1};\n\t\\${2}\nsnippet im\n\timport '\\${1}';\n\t\\${2}\nsnippet pa\n\tpart '\\${1}';\n\t\\${2}\nsnippet pao\n\tpart of \\${1};\n\t\\${2}\nsnippet main\n\tvoid main() {\n\t  \\${1:/* code */}\n\t}\nsnippet st\n\tstatic \\${1}\nsnippet fi\n\tfinal \\${1}\nsnippet re\n\treturn \\${1}\nsnippet br\n\tbreak;\nsnippet th\n\tthrow \\${1}\nsnippet cl\n\tclass \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2}\nsnippet imp\n\timplements \\${1}\nsnippet ext\n\textends \\${1}\nsnippet if\n\tif (\\${1:true}) {\n\t  \\${2}\n\t}\nsnippet ife\n\tif (\\${1:true}) {\n\t  \\${2}\n\t} else {\n\t  \\${3}\n\t}\nsnippet el\n\telse\nsnippet sw\n\tswitch (\\${1}) {\n\t  \\${2}\n\t}\nsnippet cs\n\tcase \\${1}:\n\t  \\${2}\nsnippet de\n\tdefault:\n\t  \\${1}\nsnippet for\n\tfor (var \\${2:i} = 0, len = \\${1:things}.length; \\$2 < len; \\${3:++}\\$2) {\n\t  \\${4:\\$1[\\$2]}\n\t}\nsnippet fore\n\tfor (final \\${2:item} in \\${1:itemList}) {\n\t  \\${3:/* code */}\n\t}\nsnippet wh\n\twhile (\\${1:/* condition */}) {\n\t  \\${2:/* code */}\n\t}\nsnippet dowh\n\tdo {\n\t  \\${2:/* code */}\n\t} while (\\${1:/* condition */});\nsnippet as\n\tassert(\\${1:/* condition */});\nsnippet try\n\ttry {\n\t  \\${2}\n\t} catch (\\${1:Exception e}) {\n\t}\nsnippet tryf\n\ttry {\n\t  \\${2}\n\t} catch (\\${1:Exception e}) {\n\t} finally {\n\t}\n`;\n"
  },
  {
    "path": "src/snippets/diff.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./diff.snippets\");\nexports.scope = \"diff\";\n"
  },
  {
    "path": "src/snippets/diff.snippets.js",
    "content": "module.exports = `# DEP-3 (http://dep.debian.net/deps/dep3/) style patch header\nsnippet header DEP-3 style header\n\tDescription: \\${1}\n\tOrigin: \\${2:vendor|upstream|other}, \\${3:url of the original patch}\n\tBug: \\${4:url in upstream bugtracker}\n\tForwarded: \\${5:no|not-needed|url}\n\tAuthor: \\${6:\\`g:snips_author\\`}\n\tReviewed-by: \\${7:name and email}\n\tLast-Update: \\${8:\\`strftime(\"%Y-%m-%d\")\\`}\n\tApplied-Upstream: \\${9:upstream version|url|commit}\n\n`;\n"
  },
  {
    "path": "src/snippets/django.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./django.snippets\");\nexports.scope = \"django\";\n"
  },
  {
    "path": "src/snippets/django.snippets.js",
    "content": "module.exports = `# Model Fields\n\n# Note: Optional arguments are using defaults that match what Django will use\n# as a default, e.g. with max_length fields.  Doing this as a form of self\n# documentation and to make it easy to know whether you should override the\n# default or not.\n\n# Note: Optional arguments that are booleans will use the opposite since you\n# can either not specify them, or override them, e.g. auto_now_add=False.\n\nsnippet auto\n\t\\${1:FIELDNAME} = models.AutoField(\\${2})\nsnippet bool\n\t\\${1:FIELDNAME} = models.BooleanField(\\${2:default=True})\nsnippet char\n\t\\${1:FIELDNAME} = models.CharField(max_length=\\${2}\\${3:, blank=True})\nsnippet comma\n\t\\${1:FIELDNAME} = models.CommaSeparatedIntegerField(max_length=\\${2}\\${3:, blank=True})\nsnippet date\n\t\\${1:FIELDNAME} = models.DateField(\\${2:auto_now_add=True, auto_now=True}\\${3:, blank=True, null=True})\nsnippet datetime\n\t\\${1:FIELDNAME} = models.DateTimeField(\\${2:auto_now_add=True, auto_now=True}\\${3:, blank=True, null=True})\nsnippet decimal\n\t\\${1:FIELDNAME} = models.DecimalField(max_digits=\\${2}, decimal_places=\\${3})\nsnippet email\n\t\\${1:FIELDNAME} = models.EmailField(max_length=\\${2:75}\\${3:, blank=True})\nsnippet file\n\t\\${1:FIELDNAME} = models.FileField(upload_to=\\${2:path/for/upload}\\${3:, max_length=100})\nsnippet filepath\n\t\\${1:FIELDNAME} = models.FilePathField(path=\\${2:\"/abs/path/to/dir\"}\\${3:, max_length=100}\\${4:, match=\"*.ext\"}\\${5:, recursive=True}\\${6:, blank=True, })\nsnippet float\n\t\\${1:FIELDNAME} = models.FloatField(\\${2})\nsnippet image\n\t\\${1:FIELDNAME} = models.ImageField(upload_to=\\${2:path/for/upload}\\${3:, height_field=height, width_field=width}\\${4:, max_length=100})\nsnippet int\n\t\\${1:FIELDNAME} = models.IntegerField(\\${2})\nsnippet ip\n\t\\${1:FIELDNAME} = models.IPAddressField(\\${2})\nsnippet nullbool\n\t\\${1:FIELDNAME} = models.NullBooleanField(\\${2})\nsnippet posint\n\t\\${1:FIELDNAME} = models.PositiveIntegerField(\\${2})\nsnippet possmallint\n\t\\${1:FIELDNAME} = models.PositiveSmallIntegerField(\\${2})\nsnippet slug\n\t\\${1:FIELDNAME} = models.SlugField(max_length=\\${2:50}\\${3:, blank=True})\nsnippet smallint\n\t\\${1:FIELDNAME} = models.SmallIntegerField(\\${2})\nsnippet text\n\t\\${1:FIELDNAME} = models.TextField(\\${2:blank=True})\nsnippet time\n\t\\${1:FIELDNAME} = models.TimeField(\\${2:auto_now_add=True, auto_now=True}\\${3:, blank=True, null=True})\nsnippet url\n\t\\${1:FIELDNAME} = models.URLField(\\${2:verify_exists=False}\\${3:, max_length=200}\\${4:, blank=True})\nsnippet xml\n\t\\${1:FIELDNAME} = models.XMLField(schema_path=\\${2:None}\\${3:, blank=True})\n# Relational Fields\nsnippet fk\n\t\\${1:FIELDNAME} = models.ForeignKey(\\${2:OtherModel}\\${3:, related_name=''}\\${4:, limit_choices_to=}\\${5:, to_field=''})\nsnippet m2m\n\t\\${1:FIELDNAME} = models.ManyToManyField(\\${2:OtherModel}\\${3:, related_name=''}\\${4:, limit_choices_to=}\\${5:, symmetrical=False}\\${6:, through=''}\\${7:, db_table=''})\nsnippet o2o\n\t\\${1:FIELDNAME} = models.OneToOneField(\\${2:OtherModel}\\${3:, parent_link=True}\\${4:, related_name=''}\\${5:, limit_choices_to=}\\${6:, to_field=''})\n\n# Code Skeletons\n\nsnippet form\n\tclass \\${1:FormName}(forms.Form):\n\t\t\"\"\"\\${2:docstring}\"\"\"\n\t\t\\${3}\n\nsnippet model\n\tclass \\${1:ModelName}(models.Model):\n\t\t\"\"\"\\${2:docstring}\"\"\"\n\t\t\\${3}\n\t\t\n\t\tclass Meta:\n\t\t\t\\${4}\n\t\t\n\t\tdef __unicode__(self):\n\t\t\t\\${5}\n\t\t\n\t\tdef save(self, force_insert=False, force_update=False):\n\t\t\t\\${6}\n\t\t\n\t\t@models.permalink\n\t\tdef get_absolute_url(self):\n\t\t\treturn ('\\${7:view_or_url_name}' \\${8})\n\nsnippet modeladmin\n\tclass \\${1:ModelName}Admin(admin.ModelAdmin):\n\t\t\\${2}\n\t\n\tadmin.site.register(\\$1, \\$1Admin)\n\t\nsnippet tabularinline\n\tclass \\${1:ModelName}Inline(admin.TabularInline):\n\t\tmodel = \\$1\n\nsnippet stackedinline\n\tclass \\${1:ModelName}Inline(admin.StackedInline):\n\t\tmodel = \\$1\n\nsnippet r2r\n\treturn render_to_response('\\${1:template.html}', {\n\t\t\t\\${2}\n\t\t}\\${3:, context_instance=RequestContext(request)}\n\t)\n`;\n"
  },
  {
    "path": "src/snippets/drools.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./drools.snippets\");\nexports.scope = \"drools\";\n"
  },
  {
    "path": "src/snippets/drools.snippets.js",
    "content": "module.exports = `\nsnippet rule\n\trule \"\\${1?:rule_name}\"\n\twhen\n\t\t\\${2:// when...} \n\tthen\n\t\t\\${3:// then...}\n\tend\n\nsnippet query\n\tquery \\${1?:query_name}\n\t\t\\${2:// find} \n\tend\n\t\nsnippet declare\n\tdeclare \\${1?:type_name}\n\t\t\\${2:// attributes} \n\tend\n\n`;\n"
  },
  {
    "path": "src/snippets/edifact.js",
    "content": "\"use strict\";\n    \n    exports.snippetText = require(\"./edifact.snippets\");\n    exports.scope = \"edifact\";\n"
  },
  {
    "path": "src/snippets/edifact.snippets.js",
    "content": "module.exports = `## Access Modifiers\nsnippet u\n\tUN\nsnippet un\n\tUNB\nsnippet pr\n\tprivate\n##\n## Annotations\nsnippet before\n\t@Before\n\tstatic void \\${1:intercept}(\\${2:args}) { \\${3} }\nsnippet mm\n\t@ManyToMany\n\t\\${1}\nsnippet mo\n\t@ManyToOne\n\t\\${1}\nsnippet om\n\t@OneToMany\\${1:(cascade=CascadeType.ALL)}\n\t\\${2}\nsnippet oo\n\t@OneToOne\n\t\\${1}\n##\n## Basic Java packages and import\nsnippet im\n\timport\nsnippet j.b\n\tjava.beans.\nsnippet j.i\n\tjava.io.\nsnippet j.m\n\tjava.math.\nsnippet j.n\n\tjava.net.\nsnippet j.u\n\tjava.util.\n##\n## Class\nsnippet cl\n\tclass \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2}\nsnippet in\n\tinterface \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2:extends Parent}\\${3}\nsnippet tc\n\tpublic class \\${1:\\`Filename()\\`} extends \\${2:TestCase}\n##\n## Class Enhancements\nsnippet ext\n\textends \nsnippet imp\n\timplements\n##\n## Comments\nsnippet /*\n\t/*\n\t * \\${1}\n\t */\n##\n## Constants\nsnippet co\n\tstatic public final \\${1:String} \\${2:var} = \\${3};\\${4}\nsnippet cos\n\tstatic public final String \\${1:var} = \"\\${2}\";\\${3}\n##\n## Control Statements\nsnippet case\n\tcase \\${1}:\n\t\t\\${2}\nsnippet def\n\tdefault:\n\t\t\\${2}\nsnippet el\n\telse\nsnippet elif\n\telse if (\\${1}) \\${2}\nsnippet if\n\tif (\\${1}) \\${2}\nsnippet sw\n\tswitch (\\${1}) {\n\t\t\\${2}\n\t}\n##\n## Create a Method\nsnippet m\n\t\\${1:void} \\${2:method}(\\${3}) \\${4:throws }\\${5}\n##\n## Create a Variable\nsnippet v\n\t\\${1:String} \\${2:var}\\${3: = null}\\${4};\\${5}\n##\n## Enhancements to Methods, variables, classes, etc.\nsnippet ab\n\tabstract\nsnippet fi\n\tfinal\nsnippet st\n\tstatic\nsnippet sy\n\tsynchronized\n##\n## Error Methods\nsnippet err\n\tSystem.err.print(\"\\${1:Message}\");\nsnippet errf\n\tSystem.err.printf(\"\\${1:Message}\", \\${2:exception});\nsnippet errln\n\tSystem.err.println(\"\\${1:Message}\");\n##\n## Exception Handling\nsnippet as\n\tassert \\${1:test} : \"\\${2:Failure message}\";\\${3}\nsnippet ca\n\tcatch(\\${1:Exception} \\${2:e}) \\${3}\nsnippet thr\n\tthrow\nsnippet ths\n\tthrows\nsnippet try\n\ttry {\n\t\t\\${3}\n\t} catch(\\${1:Exception} \\${2:e}) {\n\t}\nsnippet tryf\n\ttry {\n\t\t\\${3}\n\t} catch(\\${1:Exception} \\${2:e}) {\n\t} finally {\n\t}\n##\n## Find Methods\nsnippet findall\n\tList<\\${1:listName}> \\${2:items} = \\${1}.findAll();\\${3}\nsnippet findbyid\n\t\\${1:var} \\${2:item} = \\${1}.findById(\\${3});\\${4}\n##\n## Javadocs\nsnippet /**\n\t/**\n\t * \\${1}\n\t */\nsnippet @au\n\t@author \\`system(\"grep \\\\\\`id -un\\\\\\` /etc/passwd | cut -d \\\\\":\\\\\" -f5 | cut -d \\\\\",\\\\\" -f1\")\\`\nsnippet @br\n\t@brief \\${1:Description}\nsnippet @fi\n\t@file \\${1:\\`Filename()\\`}.java\nsnippet @pa\n\t@param \\${1:param}\nsnippet @re\n\t@return \\${1:param}\n##\n## Logger Methods\nsnippet debug\n\tLogger.debug(\\${1:param});\\${2}\nsnippet error\n\tLogger.error(\\${1:param});\\${2}\nsnippet info\n\tLogger.info(\\${1:param});\\${2}\nsnippet warn\n\tLogger.warn(\\${1:param});\\${2}\n##\n## Loops\nsnippet enfor\n\tfor (\\${1} : \\${2}) \\${3}\nsnippet for\n\tfor (\\${1}; \\${2}; \\${3}) \\${4}\nsnippet wh\n\twhile (\\${1}) \\${2}\n##\n## Main method\nsnippet main\n\tpublic static void main (String[] args) {\n\t\t\\${1:/* code */}\n\t}\n##\n## Print Methods\nsnippet print\n\tSystem.out.print(\"\\${1:Message}\");\nsnippet printf\n\tSystem.out.printf(\"\\${1:Message}\", \\${2:args});\nsnippet println\n\tSystem.out.println(\\${1});\n##\n## Render Methods\nsnippet ren\n\trender(\\${1:param});\\${2}\nsnippet rena\n\trenderArgs.put(\"\\${1}\", \\${2});\\${3}\nsnippet renb\n\trenderBinary(\\${1:param});\\${2}\nsnippet renj\n\trenderJSON(\\${1:param});\\${2}\nsnippet renx\n\trenderXml(\\${1:param});\\${2}\n##\n## Setter and Getter Methods\nsnippet set\n\t\\${1:public} void set\\${3:}(\\${2:String} \\${4:}){\n\t\tthis.\\$4 = \\$4;\n\t}\nsnippet get\n\t\\${1:public} \\${2:String} get\\${3:}(){\n\t\treturn this.\\${4:};\n\t}\n##\n## Terminate Methods or Loops\nsnippet re\n\treturn\nsnippet br\n\tbreak;\n##\n## Test Methods\nsnippet t\n\tpublic void test\\${1:Name}() throws Exception {\n\t\t\\${2}\n\t}\nsnippet test\n\t@Test\n\tpublic void test\\${1:Name}() throws Exception {\n\t\t\\${2}\n\t}\n##\n## Utils\nsnippet Sc\n\tScanner\n##\n## Miscellaneous\nsnippet action\n\tpublic static void \\${1:index}(\\${2:args}) { \\${3} }\nsnippet rnf\n\tnotFound(\\${1:param});\\${2}\nsnippet rnfin\n\tnotFoundIfNull(\\${1:param});\\${2}\nsnippet rr\n\tredirect(\\${1:param});\\${2}\nsnippet ru\n\tunauthorized(\\${1:param});\\${2}\nsnippet unless\n\t(unless=\\${1:param});\\${2}\n`;\n"
  },
  {
    "path": "src/snippets/erlang.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./erlang.snippets\");\nexports.scope = \"erlang\";\n"
  },
  {
    "path": "src/snippets/erlang.snippets.js",
    "content": "module.exports = `# module and export all\nsnippet mod\n\t-module(\\${1:\\`Filename('', 'my')\\`}).\n\t\n\t-compile([export_all]).\n\t\n\tstart() ->\n\t    \\${2}\n\t\n\tstop() ->\n\t    ok.\n# define directive\nsnippet def\n\t-define(\\${1:macro}, \\${2:body}).\\${3}\n# export directive\nsnippet exp\n\t-export([\\${1:function}/\\${2:arity}]).\n# include directive\nsnippet inc\n\t-include(\"\\${1:file}\").\\${2}\n# behavior directive\nsnippet beh\n\t-behaviour(\\${1:behaviour}).\\${2}\n# if expression\nsnippet if\n\tif\n\t    \\${1:guard} ->\n\t        \\${2:body}\n\tend\n# case expression\nsnippet case\n\tcase \\${1:expression} of\n\t    \\${2:pattern} ->\n\t        \\${3:body};\n\tend\n# anonymous function\nsnippet fun\n\tfun (\\${1:Parameters}) -> \\${2:body} end\\${3}\n# try...catch\nsnippet try\n\ttry\n\t    \\${1}\n\tcatch\n\t    \\${2:_:_} -> \\${3:got_some_exception}\n\tend\n# record directive\nsnippet rec\n\t-record(\\${1:record}, {\n\t    \\${2:field}=\\${3:value}}).\\${4}\n# todo comment\nsnippet todo\n\t%% TODO: \\${1}\n## Snippets below (starting with '%') are in EDoc format.\n## See http://www.erlang.org/doc/apps/edoc/chapter.html#id56887 for more details\n# doc comment\nsnippet %d\n\t%% @doc \\${1}\n# end of doc comment\nsnippet %e\n\t%% @end\n# specification comment\nsnippet %s\n\t%% @spec \\${1}\n# private function marker\nsnippet %p\n\t%% @private\n# OTP application\nsnippet application\n\t-module(\\${1:\\`Filename('', 'my')\\`}).\n\n\t-behaviour(application).\n\n\t-export([start/2, stop/1]).\n\n\tstart(_Type, _StartArgs) ->\n\t    case \\${2:root_supervisor}:start_link() of\n\t        {ok, Pid} ->\n\t            {ok, Pid};\n\t        Other ->\n\t\t          {error, Other}\n\t    end.\n\n\tstop(_State) ->\n\t    ok.\t\n# OTP supervisor\nsnippet supervisor\n\t-module(\\${1:\\`Filename('', 'my')\\`}).\n\n\t-behaviour(supervisor).\n\n\t%% API\n\t-export([start_link/0]).\n\n\t%% Supervisor callbacks\n\t-export([init/1]).\n\n\t-define(SERVER, ?MODULE).\n\n\tstart_link() ->\n\t    supervisor:start_link({local, ?SERVER}, ?MODULE, []).\n\n\tinit([]) ->\n\t    Server = {\\${2:my_server}, {\\$2, start_link, []},\n\t      permanent, 2000, worker, [\\$2]},\n\t    Children = [Server],\n\t    RestartStrategy = {one_for_one, 0, 1},\n\t    {ok, {RestartStrategy, Children}}.\n# OTP gen_server\nsnippet gen_server\n\t-module(\\${1:\\`Filename('', 'my')\\`}).\n\n\t-behaviour(gen_server).\n\n\t%% API\n\t-export([\n\t         start_link/0\n\t        ]).\n\n\t%% gen_server callbacks\n\t-export([init/1, handle_call/3, handle_cast/2, handle_info/2,\n\t         terminate/2, code_change/3]).\n\n\t-define(SERVER, ?MODULE).\n\n\t-record(state, {}).\n\n\t%%%===================================================================\n\t%%% API\n\t%%%===================================================================\n\n\tstart_link() ->\n\t    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).\n\n\t%%%===================================================================\n\t%%% gen_server callbacks\n\t%%%===================================================================\n\n\tinit([]) ->\n\t    {ok, #state{}}.\n\n\thandle_call(_Request, _From, State) ->\n\t    Reply = ok,\n\t    {reply, Reply, State}.\n\n\thandle_cast(_Msg, State) ->\n\t    {noreply, State}.\n\n\thandle_info(_Info, State) ->\n\t    {noreply, State}.\n\n\tterminate(_Reason, _State) ->\n\t    ok.\n\n\tcode_change(_OldVsn, State, _Extra) ->\n\t    {ok, State}.\n\n\t%%%===================================================================\n\t%%% Internal functions\n\t%%%===================================================================\n\n`;\n"
  },
  {
    "path": "src/snippets/fsl.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./fsl.snippets\");\nexports.scope = \"fsl\";\n"
  },
  {
    "path": "src/snippets/fsl.snippets.js",
    "content": "module.exports = `snippet header\n\tmachine_name     : \"\";\n\tmachine_author   : \"\";\n\tmachine_license  : MIT;\n\tmachine_comment  : \"\";\n\tmachine_language : en;\n\tmachine_version  : 1.0.0;\n\tfsl_version      : 1.0.0;\n\tstart_states     : [];\n`;\n"
  },
  {
    "path": "src/snippets/gobstones.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./gobstones.snippets\");\nexports.scope = \"gobstones\";\n"
  },
  {
    "path": "src/snippets/gobstones.snippets.js",
    "content": "module.exports = `# scope: gobstones\n\n# program\nsnippet program\n\tprogram {\n\t\t\\${1:// cuerpo...}\n\t}\n\n# interactive program\nsnippet interactive program\n\tinteractive program {\n\t\t\\${1:INIT} -> { \\${2:// cuerpo...} }\n\t\t\\${3:TIMEOUT(\\${4:5000}) -> { \\${5:// cuerpo...} }\n\t\t\\${6:K_ENTER} -> { \\${7:// cuerpo...} }\n\t\t_ -> {}\n\t}\n\n# procedure\nsnippet procedure\n\tprocedure \\${1:Nombre}(\\${2:parametros}) {\n\t\t\\${3:// cuerpo...}\n\t}\n\n# function\nsnippet function\n\tfunction \\${1:nombre}(\\${2:parametros}) {\n\t\treturn (\\${3:expresión..})\n\t}\n\n# return\nsnippet return\n\treturn (\\${1:expresión...})\n\n# type\nsnippet type\n\ttype \\${1:Nombre}\n\n# is variant\nsnippet is variant\n\tis variant {\n\t\tcase \\${1:NombreDelValor1} {}\n\t\tcase \\${2:NombreDelValor2} {}\n\t\tcase \\${3:NombreDelValor3} {}\n\t\tcase \\${4:NombreDelValor4} {}\n\t}\n\n# is record\nsnippet is record\n\tis record {\n\t\tfield \\${1:campo1} // \\${2:Tipo}\n\t\tfield \\${3:campo2} // \\${4:Tipo}\n\t\tfield \\${5:campo3} // \\${6:Tipo}\n\t\tfield \\${7:campo4} // \\${8:Tipo}\n\t}\n\n# type _ is variant\nsnippet type _ is variant\n\ttype \\${1:Nombre} is variant {\n\t\tcase \\${2:NombreDelValor1} {}\n\t\tcase \\${3:NombreDelValor2} {}\n\t\tcase \\${4:NombreDelValor3} {}\n\t\tcase \\${5:NombreDelValor4} {}\n\t}\n\n# type _ is record\nsnippet type _ is record\n\ttype \\${1:Nombre} is record {\n\t\tfield \\${2:campo1} // \\${3:Tipo}\n\t\tfield \\${4:campo2} // \\${5:Tipo}\n\t\tfield \\${6:campo3} // \\${7:Tipo}\n\t\tfield \\${8:campo4} // \\${9:Tipo}\n\t}\n\n# repeat\nsnippet repeat\n\trepeat \\${1:cantidad} {\n\t\t\\${2:// cuerpo...}\n\t}\n\n# foreach\nsnippet foreach\n\tforeach \\${1:índice} in \\${2:lista} {\n\t\t\\${3:// cuerpo...}\n\t}\n\n# while\nsnippet while\n\twhile (\\${1?:condición}) {\n\t\t\\${2:// cuerpo...}\n\t}\n\n# if\nsnippet if\n\tif (\\${1?:condición}) {\n\t\t\\${2:// cuerpo...}\n\t}\n\n# elseif\nsnippet elseif\n\telseif (\\${1?:condición}) {\n\t\t\\${2:// cuerpo...}\n\t}\n\n# else\nsnippet else\n\telse {\n\t\t\\${1:// cuerpo...}\n\t}\n\n# if (con else)\nsnippet if (con else)\n\tif (\\${1:condición}) {\n\t\t\\${2:// cuerpo...}\n\t} else {\n\t\t\\${3:// cuerpo....}\n\t}\n\n# if (con elseif)\nsnippet if (con elseif)\n\tif (\\${1:condición}) {\n\t\t\\${2:// cuerpo...}\n\t} elseif (\\${3:condición}) {\n\t\t\\${4:// cuerpo...}\n\t}\n\n# if (con elseif y else)\nsnippet if (con elseif y else)\n\tif (\\${1:condición}) {\n\t\t\\${2:// cuerpo...}\n\t} elseif (\\${3:condición}) {\n\t\t\\${4:// cuerpo...}\n\t} else {\n\t\t\\${5:// cuerpo....}\n\t}\n\n# if (con 3 elseif)\nsnippet if (con 3 elseif)\n\tif (\\${1:condición}) {\n\t\t\\${2:// cuerpo...}\n\t} elseif (\\${3:condición}) {\n\t\t\\${4:// cuerpo...}\n\t} elseif (\\${5:condición}) {\n\t\t\\${6:// cuerpo...}\n\t} elseif (\\${7:condición}) {\n\t\t\\${8:// cuerpo...}\n\t}\n\n# choose (2 valores)\nsnippet choose (2 valores)\n\tchoose\n\t\t\\${1:Valor1} when (\\${2:condición})\n\t\t\\${3:Valor2} otherwise\n\n# choose (2 valores y boom)\nsnippet choose (2 valores y boom)\n\tchoose\n\t\t\\${1:Valor1} when (\\${2:condición})\n\t\t\\${3:Valor2} when (\\${4:condición})\n\t\t\\${5:Valor3} when (\\${6:condición})\n\t\t\\${7:Valor4} when (\\${8:condición})\n\t\tboom(\"\\${9:No es un valor válido}\") otherwise\n\n# matching (4 valores)\nsnippet matching (4 valores)\n\tmatching (\\${1:variable}) select\n\t\t\\${2:Valor1} on \\${3:opción1}\n\t\t\\${4:Valor2} on \\${5:opción2}\n\t\t\\${6:Valor3} on \\${7:opción3}\n\t\t\\${8:Valor4} on \\${9:opción4}\n\t\tboom(\"\\${10:No es un valor válido}\") otherwise\n\n# select (4 casos)\nsnippet select (4 casos)\n\tselect\n\t\t\\${1:Valor1} on (\\${2:opción1})\n\t\t\\${3:Valor2} on (\\${4:opción2})\n\t\t\\${5:Valor3} on (\\${6:opción3})\n\t\t\\${7:Valor4} on (\\${8:opción4})\n\t\tboom(\"\\${9:No es un valor válido}\") otherwise\n\n# switch\nsnippet switch\n\tswitch (\\${1:variable}) {\n\t\t\\${2:Valor1} -> {\\${3:// cuerpo...}}\n\t\t\\${4:Valor2} -> {\\${5:// cuerpo...}}\n\t\t\\${6:Valor3} -> {\\${7:// cuerpo...}}\n\t\t\\${8:Valor4} -> {\\${9:// cuerpo...}}\n\t\t_ -> {\\${10:// cuerpo...}}\n\t}\n\n# Poner\nsnippet Poner\n\tPoner(\\${1:color})\n\n# Sacar\nsnippet Sacar\n\tSacar(\\${1:color})\n\n# Mover\nsnippet Mover\n\tMover(\\${1:dirección})\n\n# IrAlBorde\nsnippet IrAlBorde\n\tIrAlBorde(\\${1:dirección})\n\n# VaciarTablero\nsnippet VaciarTablero\n\tVaciarTablero()\n\n# BOOM\nsnippet BOOM\n\tBOOM(\"\\${1:Mensaje de error}\")\n\n# hayBolitas\nsnippet hayBolitas\n\thayBolitas(\\${1:color})\n\n# nroBolitas\nsnippet nroBolitas\n\tnroBolitas(\\${1:color})\n\n# puedeMover\nsnippet puedeMover\n\tpuedeMover(\\${1:dirección})\n\n# siguiente\nsnippet siguiente\n\tsiguiente(\\${1:color|dirección})\n\n# previo\nsnippet previo\n\tprevio(\\${1:color|dirección})\n\n# opuesto\nsnippet opuesto\n\topuesto(\\${1:dirección})\n\n# minDir\nsnippet minDir\n\tminDir()\n\n# maxDir\nsnippet maxDir\n\tmaxDir()\n\n# minColor\nsnippet minColor\n\tminDir()\n\n# maxColor\nsnippet maxColor\n\tmaxDir()\n\n# minBool\nsnippet minBool\n\tminBool()\n\n# maxBool\nsnippet maxBool\n\tmaxBool()\n\n# primero\nsnippet primero\n\tprimero(\\${1:lista})\n\n# sinElPrimero\nsnippet sinElPrimero\n\tsinElPrimero(\\${1:lista})\n\n# esVacía\nsnippet esVacía\n\tesVacía(\\${1:lista})\n\n# boom\nsnippet boom\n\tboom(\"\\${1:Mensaje de error}\")\n\n# Azul\nsnippet Azul\n\tAzul\n\n# Negro\nsnippet Negro\n\tNegro\n\n# Rojo\nsnippet Rojo\n\tRojo\n\n# Verde\nsnippet Verde\n\tVerde\n\n# Norte\nsnippet Norte\n\tNorte\n\n# Este\nsnippet Este\n\tEste\n\n# Sur\nsnippet Sur\n\tSur\n\n# Oeste\nsnippet Oeste\n\tOeste\n\n# True\nsnippet True\n\tTrue\n\n# False\nsnippet False\n\tFalse\n\n# INIT\nsnippet INIT\n\tINIT -> {\\$1:// cuerpo...}\n\n# TIMEOUT\nsnippet TIMEOUT\n\tTIMEOUT(\\${1:5000}) -> {\\$2:// cuerpo...}\n\n# K_A\nsnippet K_A\n\tK_A -> { \\${1://cuerpo...} }\n# K_CTRL_A\nsnippet K_CTRL_A\n\tK_CTRL_A -> { \\${1://cuerpo...} }\n# K_ALT_A\nsnippet K_ALT_A\n\tK_ALT_A -> { \\${1://cuerpo...} }\n# K_SHIFT_A\nsnippet K_SHIFT_A\n\tK_SHIFT_A -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_A\nsnippet K_CTRL_ALT_A\n\tK_CTRL_ALT_A -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_A\nsnippet K_CTRL_SHIFT_A\n\tK_CTRL_SHIFT_A -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_A\nsnippet K_CTRL_ALT_SHIFT_A\n\tK_CTRL_ALT_SHIFT_A -> { \\${1://cuerpo...} }\n\n# K_B\nsnippet K_B\n\tK_B -> { \\${1://cuerpo...} }\n# K_CTRL_B\nsnippet K_CTRL_B\n\tK_CTRL_B -> { \\${1://cuerpo...} }\n# K_ALT_B\nsnippet K_ALT_B\n\tK_ALT_B -> { \\${1://cuerpo...} }\n# K_SHIFT_B\nsnippet K_SHIFT_B\n\tK_SHIFT_B -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_B\nsnippet K_CTRL_ALT_B\n\tK_CTRL_ALT_B -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_B\nsnippet K_CTRL_SHIFT_B\n\tK_CTRL_SHIFT_B -> { \\${1://cuerpo...} }\n# K_ALT_SHIFT_C\nsnippet K_ALT_SHIFT_C\n\tK_ALT_SHIFT_C -> { \\${1://cuerpo...} }\n# K_CTRL_BLT_SHIFT_B\nsnippet K_CTRL_BLT_SHIFT_B\n\tK_CTRL_ALT_SHIFT_B -> { \\${1://cuerpo...} }\n\n# K_C\nsnippet K_C\n\tK_C -> { \\${1://cuerpo...} }\n# K_CTRL_C\nsnippet K_CTRL_C\n\tK_CTRL_C -> { \\${1://cuerpo...} }\n# K_ALT_C\nsnippet K_ALT_C\n\tK_ALT_C -> { \\${1://cuerpo...} }\n# K_SHIFT_C\nsnippet K_SHIFT_C\n\tK_SHIFT_C -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_C\nsnippet K_CTRL_ALT_C\n\tK_CTRL_ALT_C -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_C\nsnippet K_CTRL_SHIFT_C\n\tK_CTRL_SHIFT_C -> { \\${1://cuerpo...} }\n# K_ALT_SHIFT_C\nsnippet K_ALT_SHIFT_C\n\tK_ALT_SHIFT_C -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_C\nsnippet K_CTRL_ALT_SHIFT_C\n\tK_CTRL_ALT_SHIFT_C -> { \\${1://cuerpo...} }\n\n# K_D\nsnippet K_D\n\tK_D -> { \\${1://cuerpo...} }\n# K_CTRL_D\nsnippet K_CTRL_D\n\tK_CTRL_D -> { \\${1://cuerpo...} }\n# K_ALT_D\nsnippet K_ALT_D\n\tK_DLT_D -> { \\${1://cuerpo...} }\n# K_SHIFT_D\nsnippet K_SHIFT_D\n\tK_SHIFT_D -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_D\nsnippet K_CTRL_ALT_D\n\tK_CTRL_DLT_D -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_D\nsnippet K_CTRL_SHIFT_D\n\tK_CTRL_SHIFT_D -> { \\${1://cuerpo...} }\n# K_ALT_SHIFT_D\nsnippet K_ALT_SHIFT_D\n\tK_ALT_SHIFT_D -> { \\${1://cuerpo...} }\n# K_CTRL_DLT_SHIFT_D\nsnippet K_CTRL_DLT_SHIFT_D\n\tK_CTRL_ALT_SHIFT_D -> { \\${1://cuerpo...} }\n\n# K_E\nsnippet K_E\n\tK_E -> { \\${1://cuerpo...} }\n# K_CTRL_E\nsnippet K_CTRL_E\n\tK_CTRL_E -> { \\${1://cuerpo...} }\n# K_ALT_E\nsnippet K_ALT_E\n\tK_ALT_E -> { \\${1://cuerpo...} }\n# K_SHIFT_E\nsnippet K_SHIFT_E\n\tK_SHIFT_E -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_E\nsnippet K_CTRL_ALT_E\n\tK_CTRL_ALT_E -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_E\nsnippet K_CTRL_SHIFT_E\n\tK_CTRL_SHIFT_E -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_E\nsnippet K_CTRL_ALT_SHIFT_E\n\tK_CTRL_ALT_SHIFT_E -> { \\${1://cuerpo...} }\n\n# K_F\nsnippet K_F\n\tK_F -> { \\${1://cuerpo...} }\n# K_CTRL_F\nsnippet K_CTRL_F\n\tK_CTRL_F -> { \\${1://cuerpo...} }\n# K_ALT_F\nsnippet K_ALT_F\n\tK_ALT_F -> { \\${1://cuerpo...} }\n# K_SHIFT_F\nsnippet K_SHIFT_F\n\tK_SHIFT_F -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F\nsnippet K_CTRL_ALT_F\n\tK_CTRL_ALT_F -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F\nsnippet K_CTRL_SHIFT_F\n\tK_CTRL_SHIFT_F -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F\nsnippet K_CTRL_ALT_SHIFT_F\n\tK_CTRL_ALT_SHIFT_F -> { \\${1://cuerpo...} }\n\n# K_G\nsnippet K_G\n\tK_G -> { \\${1://cuerpo...} }\n# K_CTRL_G\nsnippet K_CTRL_G\n\tK_CTRL_G -> { \\${1://cuerpo...} }\n# K_ALT_G\nsnippet K_ALT_G\n\tK_ALT_G -> { \\${1://cuerpo...} }\n# K_SHIFT_G\nsnippet K_SHIFT_G\n\tK_SHIFT_G -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_G\nsnippet K_CTRL_ALT_G\n\tK_CTRL_ALT_G -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_G\nsnippet K_CTRL_SHIFT_G\n\tK_CTRL_SHIFT_G -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_G\nsnippet K_CTRL_ALT_SHIFT_G\n\tK_CTRL_ALT_SHIFT_G -> { \\${1://cuerpo...} }\n\n# K_H\nsnippet K_H\n\tK_H -> { \\${1://cuerpo...} }\n# K_CTRL_H\nsnippet K_CTRL_H\n\tK_CTRL_H -> { \\${1://cuerpo...} }\n# K_ALT_H\nsnippet K_ALT_H\n\tK_ALT_H -> { \\${1://cuerpo...} }\n# K_SHIFT_H\nsnippet K_SHIFT_H\n\tK_SHIFT_H -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_H\nsnippet K_CTRL_ALT_H\n\tK_CTRL_ALT_H -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_H\nsnippet K_CTRL_SHIFT_H\n\tK_CTRL_SHIFT_H -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_H\nsnippet K_CTRL_ALT_SHIFT_H\n\tK_CTRL_ALT_SHIFT_H -> { \\${1://cuerpo...} }\n\n# K_I\nsnippet K_I\n\tK_I -> { \\${1://cuerpo...} }\n# K_CTRL_I\nsnippet K_CTRL_I\n\tK_CTRL_I -> { \\${1://cuerpo...} }\n# K_ALT_I\nsnippet K_ALT_I\n\tK_ALT_I -> { \\${1://cuerpo...} }\n# K_SHIFT_I\nsnippet K_SHIFT_I\n\tK_SHIFT_I -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_I\nsnippet K_CTRL_ALT_I\n\tK_CTRL_ALT_I -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_I\nsnippet K_CTRL_SHIFT_I\n\tK_CTRL_SHIFT_I -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_I\nsnippet K_CTRL_ALT_SHIFT_I\n\tK_CTRL_ALT_SHIFT_I -> { \\${1://cuerpo...} }\n\n# K_J\nsnippet K_J\n\tK_J -> { \\${1://cuerpo...} }\n# K_CTRL_J\nsnippet K_CTRL_J\n\tK_CTRL_J -> { \\${1://cuerpo...} }\n# K_ALT_J\nsnippet K_ALT_J\n\tK_ALT_J -> { \\${1://cuerpo...} }\n# K_SHIFT_J\nsnippet K_SHIFT_J\n\tK_SHIFT_J -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_J\nsnippet K_CTRL_ALT_J\n\tK_CTRL_ALT_J -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_J\nsnippet K_CTRL_SHIFT_J\n\tK_CTRL_SHIFT_J -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_J\nsnippet K_CTRL_ALT_SHIFT_J\n\tK_CTRL_ALT_SHIFT_J -> { \\${1://cuerpo...} }\n\n# K_K\nsnippet K_K\n\tK_K -> { \\${1://cuerpo...} }\n# K_CTRL_K\nsnippet K_CTRL_K\n\tK_CTRL_K -> { \\${1://cuerpo...} }\n# K_ALT_K\nsnippet K_ALT_K\n\tK_ALT_K -> { \\${1://cuerpo...} }\n# K_SHIFT_K\nsnippet K_SHIFT_K\n\tK_SHIFT_K -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_K\nsnippet K_CTRL_ALT_K\n\tK_CTRL_ALT_K -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_K\nsnippet K_CTRL_SHIFT_K\n\tK_CTRL_SHIFT_K -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_K\nsnippet K_CTRL_ALT_SHIFT_K\n\tK_CTRL_ALT_SHIFT_K -> { \\${1://cuerpo...} }\n\n# K_L\nsnippet K_L\n\tK_L -> { \\${1://cuerpo...} }\n# K_CTRL_L\nsnippet K_CTRL_L\n\tK_CTRL_L -> { \\${1://cuerpo...} }\n# K_ALT_L\nsnippet K_ALT_L\n\tK_ALT_L -> { \\${1://cuerpo...} }\n# K_SHIFT_L\nsnippet K_SHIFT_L\n\tK_SHIFT_L -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_L\nsnippet K_CTRL_ALT_L\n\tK_CTRL_ALT_L -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_L\nsnippet K_CTRL_SHIFT_L\n\tK_CTRL_SHIFT_L -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_L\nsnippet K_CTRL_ALT_SHIFT_L\n\tK_CTRL_ALT_SHIFT_L -> { \\${1://cuerpo...} }\n\n# K_M\nsnippet K_M\n\tK_M -> { \\${1://cuerpo...} }\n# K_CTRL_M\nsnippet K_CTRL_M\n\tK_CTRL_M -> { \\${1://cuerpo...} }\n# K_ALT_M\nsnippet K_ALT_M\n\tK_ALT_M -> { \\${1://cuerpo...} }\n# K_SHIFT_M\nsnippet K_SHIFT_M\n\tK_SHIFT_M -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_M\nsnippet K_CTRL_ALT_M\n\tK_CTRL_ALT_M -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_M\nsnippet K_CTRL_SHIFT_M\n\tK_CTRL_SHIFT_M -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_M\nsnippet K_CTRL_ALT_SHIFT_M\n\tK_CTRL_ALT_SHIFT_M -> { \\${1://cuerpo...} }\n\n# K_N\nsnippet K_N\n\tK_N -> { \\${1://cuerpo...} }\n# K_CTRL_N\nsnippet K_CTRL_N\n\tK_CTRL_N -> { \\${1://cuerpo...} }\n# K_ALT_N\nsnippet K_ALT_N\n\tK_ALT_N -> { \\${1://cuerpo...} }\n# K_SHIFT_N\nsnippet K_SHIFT_N\n\tK_SHIFT_N -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_N\nsnippet K_CTRL_ALT_N\n\tK_CTRL_ALT_N -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_N\nsnippet K_CTRL_SHIFT_N\n\tK_CTRL_SHIFT_N -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_N\nsnippet K_CTRL_ALT_SHIFT_N\n\tK_CTRL_ALT_SHIFT_N -> { \\${1://cuerpo...} }\n\n# K_Ñ\nsnippet K_Ñ\n\tK_Ñ -> { \\${1://cuerpo...} }\n# K_CTRL_Ñ\nsnippet K_CTRL_Ñ\n\tK_CTRL_Ñ -> { \\${1://cuerpo...} }\n# K_ALT_Ñ\nsnippet K_ALT_Ñ\n\tK_ALT_Ñ -> { \\${1://cuerpo...} }\n# K_SHIFT_Ñ\nsnippet K_SHIFT_Ñ\n\tK_SHIFT_Ñ -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_Ñ\nsnippet K_CTRL_ALT_Ñ\n\tK_CTRL_ALT_Ñ -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_Ñ\nsnippet K_CTRL_SHIFT_Ñ\n\tK_CTRL_SHIFT_Ñ -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_Ñ\nsnippet K_CTRL_ALT_SHIFT_Ñ\n\tK_CTRL_ALT_SHIFT_Ñ -> { \\${1://cuerpo...} }\n\n# K_O\nsnippet K_O\n\tK_O -> { \\${1://cuerpo...} }\n# K_CTRL_O\nsnippet K_CTRL_O\n\tK_CTRL_O -> { \\${1://cuerpo...} }\n# K_ALT_O\nsnippet K_ALT_O\n\tK_ALT_O -> { \\${1://cuerpo...} }\n# K_SHIFT_O\nsnippet K_SHIFT_O\n\tK_SHIFT_O -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_O\nsnippet K_CTRL_ALT_O\n\tK_CTRL_ALT_O -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_O\nsnippet K_CTRL_SHIFT_O\n\tK_CTRL_SHIFT_O -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_O\nsnippet K_CTRL_ALT_SHIFT_O\n\tK_CTRL_ALT_SHIFT_O -> { \\${1://cuerpo...} }\n\n# K_P\nsnippet K_P\n\tK_P -> { \\${1://cuerpo...} }\n# K_CTRL_P\nsnippet K_CTRL_P\n\tK_CTRL_P -> { \\${1://cuerpo...} }\n# K_ALT_P\nsnippet K_ALT_P\n\tK_ALT_P -> { \\${1://cuerpo...} }\n# K_SHIFT_P\nsnippet K_SHIFT_P\n\tK_SHIFT_P -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_P\nsnippet K_CTRL_ALT_P\n\tK_CTRL_ALT_P -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_P\nsnippet K_CTRL_SHIFT_P\n\tK_CTRL_SHIFT_P -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_P\nsnippet K_CTRL_ALT_SHIFT_P\n\tK_CTRL_ALT_SHIFT_P -> { \\${1://cuerpo...} }\n\n# K_Q\nsnippet K_Q\n\tK_Q -> { \\${1://cuerpo...} }\n# K_CTRL_Q\nsnippet K_CTRL_Q\n\tK_CTRL_Q -> { \\${1://cuerpo...} }\n# K_ALT_Q\nsnippet K_ALT_Q\n\tK_ALT_Q -> { \\${1://cuerpo...} }\n# K_SHIFT_Q\nsnippet K_SHIFT_Q\n\tK_SHIFT_Q -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_Q\nsnippet K_CTRL_ALT_Q\n\tK_CTRL_ALT_Q -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_Q\nsnippet K_CTRL_SHIFT_Q\n\tK_CTRL_SHIFT_Q -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_Q\nsnippet K_CTRL_ALT_SHIFT_Q\n\tK_CTRL_ALT_SHIFT_Q -> { \\${1://cuerpo...} }\n\n# K_R\nsnippet K_R\n\tK_R -> { \\${1://cuerpo...} }\n# K_CTRL_R\nsnippet K_CTRL_R\n\tK_CTRL_R -> { \\${1://cuerpo...} }\n# K_ALT_R\nsnippet K_ALT_R\n\tK_ALT_R -> { \\${1://cuerpo...} }\n# K_SHIFT_R\nsnippet K_SHIFT_R\n\tK_SHIFT_R -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_R\nsnippet K_CTRL_ALT_R\n\tK_CTRL_ALT_R -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_R\nsnippet K_CTRL_SHIFT_R\n\tK_CTRL_SHIFT_R -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_R\nsnippet K_CTRL_ALT_SHIFT_R\n\tK_CTRL_ALT_SHIFT_R -> { \\${1://cuerpo...} }\n\n# K_S\nsnippet K_S\n\tK_S -> { \\${1://cuerpo...} }\n# K_CTRL_S\nsnippet K_CTRL_S\n\tK_CTRL_S -> { \\${1://cuerpo...} }\n# K_ALT_S\nsnippet K_ALT_S\n\tK_ALT_S -> { \\${1://cuerpo...} }\n# K_SHIFT_S\nsnippet K_SHIFT_S\n\tK_SHIFT_S -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_S\nsnippet K_CTRL_ALT_S\n\tK_CTRL_ALT_S -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_S\nsnippet K_CTRL_SHIFT_S\n\tK_CTRL_SHIFT_S -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_S\nsnippet K_CTRL_ALT_SHIFT_S\n\tK_CTRL_ALT_SHIFT_S -> { \\${1://cuerpo...} }\n\n# K_T\nsnippet K_T\n\tK_T -> { \\${1://cuerpo...} }\n# K_CTRL_T\nsnippet K_CTRL_T\n\tK_CTRL_T -> { \\${1://cuerpo...} }\n# K_ALT_T\nsnippet K_ALT_T\n\tK_ALT_T -> { \\${1://cuerpo...} }\n# K_SHIFT_T\nsnippet K_SHIFT_T\n\tK_SHIFT_T -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_T\nsnippet K_CTRL_ALT_T\n\tK_CTRL_ALT_T -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_T\nsnippet K_CTRL_SHIFT_T\n\tK_CTRL_SHIFT_T -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_T\nsnippet K_CTRL_ALT_SHIFT_T\n\tK_CTRL_ALT_SHIFT_T -> { \\${1://cuerpo...} }\n\n# K_U\nsnippet K_U\n\tK_U -> { \\${1://cuerpo...} }\n# K_CTRL_U\nsnippet K_CTRL_U\n\tK_CTRL_U -> { \\${1://cuerpo...} }\n# K_ALT_U\nsnippet K_ALT_U\n\tK_ALT_U -> { \\${1://cuerpo...} }\n# K_SHIFT_U\nsnippet K_SHIFT_U\n\tK_SHIFT_U -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_U\nsnippet K_CTRL_ALT_U\n\tK_CTRL_ALT_U -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_U\nsnippet K_CTRL_SHIFT_U\n\tK_CTRL_SHIFT_U -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_U\nsnippet K_CTRL_ALT_SHIFT_U\n\tK_CTRL_ALT_SHIFT_U -> { \\${1://cuerpo...} }\n\n# K_V\nsnippet K_V\n\tK_V -> { \\${1://cuerpo...} }\n# K_CTRL_V\nsnippet K_CTRL_V\n\tK_CTRL_V -> { \\${1://cuerpo...} }\n# K_ALT_V\nsnippet K_ALT_V\n\tK_ALT_V -> { \\${1://cuerpo...} }\n# K_SHIFT_V\nsnippet K_SHIFT_V\n\tK_SHIFT_V -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_V\nsnippet K_CTRL_ALT_V\n\tK_CTRL_ALT_V -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_V\nsnippet K_CTRL_SHIFT_V\n\tK_CTRL_SHIFT_V -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_V\nsnippet K_CTRL_ALT_SHIFT_V\n\tK_CTRL_ALT_SHIFT_V -> { \\${1://cuerpo...} }\n\n# K_W\nsnippet K_W\n\tK_W -> { \\${1://cuerpo...} }\n# K_CTRL_W\nsnippet K_CTRL_W\n\tK_CTRL_W -> { \\${1://cuerpo...} }\n# K_ALT_W\nsnippet K_ALT_W\n\tK_ALT_W -> { \\${1://cuerpo...} }\n# K_SHIFT_W\nsnippet K_SHIFT_W\n\tK_SHIFT_W -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_W\nsnippet K_CTRL_ALT_W\n\tK_CTRL_ALT_W -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_W\nsnippet K_CTRL_SHIFT_W\n\tK_CTRL_SHIFT_W -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_W\nsnippet K_CTRL_ALT_SHIFT_W\n\tK_CTRL_ALT_SHIFT_W -> { \\${1://cuerpo...} }\n\n# K_X\nsnippet K_X\n\tK_X -> { \\${1://cuerpo...} }\n# K_CTRL_X\nsnippet K_CTRL_X\n\tK_CTRL_X -> { \\${1://cuerpo...} }\n# K_ALT_X\nsnippet K_ALT_X\n\tK_ALT_X -> { \\${1://cuerpo...} }\n# K_SHIFT_X\nsnippet K_SHIFT_X\n\tK_SHIFT_X -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_X\nsnippet K_CTRL_ALT_X\n\tK_CTRL_ALT_X -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_X\nsnippet K_CTRL_SHIFT_X\n\tK_CTRL_SHIFT_X -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_X\nsnippet K_CTRL_ALT_SHIFT_X\n\tK_CTRL_ALT_SHIFT_X -> { \\${1://cuerpo...} }\n\n# K_Y\nsnippet K_Y\n\tK_Y -> { \\${1://cuerpo...} }\n# K_CTRL_Y\nsnippet K_CTRL_Y\n\tK_CTRL_Y -> { \\${1://cuerpo...} }\n# K_ALT_Y\nsnippet K_ALT_Y\n\tK_ALT_Y -> { \\${1://cuerpo...} }\n# K_SHIFT_Y\nsnippet K_SHIFT_Y\n\tK_SHIFT_Y -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_Y\nsnippet K_CTRL_ALT_Y\n\tK_CTRL_ALT_Y -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_Y\nsnippet K_CTRL_SHIFT_Y\n\tK_CTRL_SHIFT_Y -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_Y\nsnippet K_CTRL_ALT_SHIFT_Y\n\tK_CTRL_ALT_SHIFT_Y -> { \\${1://cuerpo...} }\n\n# K_Z\nsnippet K_Z\n\tK_Z -> { \\${1://cuerpo...} }\n# K_CTRL_Z\nsnippet K_CTRL_Z\n\tK_CTRL_Z -> { \\${1://cuerpo...} }\n# K_ALT_Z\nsnippet K_ALT_Z\n\tK_ALT_Z -> { \\${1://cuerpo...} }\n# K_SHIFT_Z\nsnippet K_SHIFT_Z\n\tK_SHIFT_Z -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_Z\nsnippet K_CTRL_ALT_Z\n\tK_CTRL_ALT_Z -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_Z\nsnippet K_CTRL_SHIFT_Z\n\tK_CTRL_SHIFT_Z -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_Z\nsnippet K_CTRL_ALT_SHIFT_Z\n\tK_CTRL_ALT_SHIFT_Z -> { \\${1://cuerpo...} }\n\n# K_0\nsnippet K_0\n\tK_0 -> { \\${1://cuerpo...} }\n# K_CTRL_0\nsnippet K_CTRL_0\n\tK_CTRL_0 -> { \\${1://cuerpo...} }\n# K_ALT_0\nsnippet K_ALT_0\n\tK_ALT_0 -> { \\${1://cuerpo...} }\n# K_SHIFT_0\nsnippet K_SHIFT_0\n\tK_SHIFT_0 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_0\nsnippet K_CTRL_ALT_0\n\tK_CTRL_ALT_0 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_0\nsnippet K_CTRL_SHIFT_0\n\tK_CTRL_SHIFT_0 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_0\nsnippet K_CTRL_ALT_SHIFT_0\n\tK_CTRL_ALT_SHIFT_0 -> { \\${1://cuerpo...} }\n\n# K_1\nsnippet K_1\n\tK_1 -> { \\${1://cuerpo...} }\n# K_CTRL_1\nsnippet K_CTRL_1\n\tK_CTRL_1 -> { \\${1://cuerpo...} }\n# K_ALT_1\nsnippet K_ALT_1\n\tK_ALT_1 -> { \\${1://cuerpo...} }\n# K_SHIFT_1\nsnippet K_SHIFT_1\n\tK_SHIFT_1 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_1\nsnippet K_CTRL_ALT_1\n\tK_CTRL_ALT_1 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_1\nsnippet K_CTRL_SHIFT_1\n\tK_CTRL_SHIFT_1 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_1\nsnippet K_CTRL_ALT_SHIFT_1\n\tK_CTRL_ALT_SHIFT_1 -> { \\${1://cuerpo...} }\n\n# K_2\nsnippet K_2\n\tK_2 -> { \\${1://cuerpo...} }\n# K_CTRL_2\nsnippet K_CTRL_2\n\tK_CTRL_2 -> { \\${1://cuerpo...} }\n# K_ALT_2\nsnippet K_ALT_2\n\tK_ALT_2 -> { \\${1://cuerpo...} }\n# K_SHIFT_2\nsnippet K_SHIFT_2\n\tK_SHIFT_2 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_2\nsnippet K_CTRL_ALT_2\n\tK_CTRL_ALT_2 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_2\nsnippet K_CTRL_SHIFT_2\n\tK_CTRL_SHIFT_2 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_2\nsnippet K_CTRL_ALT_SHIFT_2\n\tK_CTRL_ALT_SHIFT_2 -> { \\${1://cuerpo...} }\n\n# K_3\nsnippet K_3\n\tK_3 -> { \\${1://cuerpo...} }\n# K_CTRL_3\nsnippet K_CTRL_3\n\tK_CTRL_3 -> { \\${1://cuerpo...} }\n# K_ALT_3\nsnippet K_ALT_3\n\tK_ALT_3 -> { \\${1://cuerpo...} }\n# K_SHIFT_3\nsnippet K_SHIFT_3\n\tK_SHIFT_3 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_3\nsnippet K_CTRL_ALT_3\n\tK_CTRL_ALT_3 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_3\nsnippet K_CTRL_SHIFT_3\n\tK_CTRL_SHIFT_3 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_3\nsnippet K_CTRL_ALT_SHIFT_3\n\tK_CTRL_ALT_SHIFT_3 -> { \\${1://cuerpo...} }\n\n# K_4\nsnippet K_4\n\tK_4 -> { \\${1://cuerpo...} }\n# K_CTRL_4\nsnippet K_CTRL_4\n\tK_CTRL_4 -> { \\${1://cuerpo...} }\n# K_ALT_4\nsnippet K_ALT_4\n\tK_ALT_4 -> { \\${1://cuerpo...} }\n# K_SHIFT_4\nsnippet K_SHIFT_4\n\tK_SHIFT_4 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_4\nsnippet K_CTRL_ALT_4\n\tK_CTRL_ALT_4 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_4\nsnippet K_CTRL_SHIFT_4\n\tK_CTRL_SHIFT_4 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_4\nsnippet K_CTRL_ALT_SHIFT_4\n\tK_CTRL_ALT_SHIFT_4 -> { \\${1://cuerpo...} }\n\n# K_5\nsnippet K_5\n\tK_5 -> { \\${1://cuerpo...} }\n# K_CTRL_5\nsnippet K_CTRL_5\n\tK_CTRL_5 -> { \\${1://cuerpo...} }\n# K_ALT_5\nsnippet K_ALT_5\n\tK_ALT_5 -> { \\${1://cuerpo...} }\n# K_SHIFT_5\nsnippet K_SHIFT_5\n\tK_SHIFT_5 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_5\nsnippet K_CTRL_ALT_5\n\tK_CTRL_ALT_5 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_5\nsnippet K_CTRL_SHIFT_5\n\tK_CTRL_SHIFT_5 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_5\nsnippet K_CTRL_ALT_SHIFT_5\n\tK_CTRL_ALT_SHIFT_5 -> { \\${1://cuerpo...} }\n\n# K_6\nsnippet K_6\n\tK_6 -> { \\${1://cuerpo...} }\n# K_CTRL_6\nsnippet K_CTRL_6\n\tK_CTRL_6 -> { \\${1://cuerpo...} }\n# K_ALT_6\nsnippet K_ALT_6\n\tK_ALT_6 -> { \\${1://cuerpo...} }\n# K_SHIFT_6\nsnippet K_SHIFT_6\n\tK_SHIFT_6 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_6\nsnippet K_CTRL_ALT_6\n\tK_CTRL_ALT_6 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_6\nsnippet K_CTRL_SHIFT_6\n\tK_CTRL_SHIFT_6 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_6\nsnippet K_CTRL_ALT_SHIFT_6\n\tK_CTRL_ALT_SHIFT_6 -> { \\${1://cuerpo...} }\n\n# K_7\nsnippet K_7\n\tK_7 -> { \\${1://cuerpo...} }\n# K_CTRL_7\nsnippet K_CTRL_7\n\tK_CTRL_7 -> { \\${1://cuerpo...} }\n# K_ALT_7\nsnippet K_ALT_7\n\tK_ALT_7 -> { \\${1://cuerpo...} }\n# K_SHIFT_7\nsnippet K_SHIFT_7\n\tK_SHIFT_7 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_7\nsnippet K_CTRL_ALT_7\n\tK_CTRL_ALT_7 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_7\nsnippet K_CTRL_SHIFT_7\n\tK_CTRL_SHIFT_7 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_7\nsnippet K_CTRL_ALT_SHIFT_7\n\tK_CTRL_ALT_SHIFT_7 -> { \\${1://cuerpo...} }\n\n# K_8\nsnippet K_8\n\tK_8 -> { \\${1://cuerpo...} }\n# K_CTRL_8\nsnippet K_CTRL_8\n\tK_CTRL_8 -> { \\${1://cuerpo...} }\n# K_ALT_8\nsnippet K_ALT_8\n\tK_ALT_8 -> { \\${1://cuerpo...} }\n# K_SHIFT_8\nsnippet K_SHIFT_8\n\tK_SHIFT_8 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_8\nsnippet K_CTRL_ALT_8\n\tK_CTRL_ALT_8 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_8\nsnippet K_CTRL_SHIFT_8\n\tK_CTRL_SHIFT_8 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_8\nsnippet K_CTRL_ALT_SHIFT_8\n\tK_CTRL_ALT_SHIFT_8 -> { \\${1://cuerpo...} }\n\n# K_9\nsnippet K_9\n\tK_9 -> { \\${1://cuerpo...} }\n# K_CTRL_9\nsnippet K_CTRL_9\n\tK_CTRL_9 -> { \\${1://cuerpo...} }\n# K_ALT_9\nsnippet K_ALT_9\n\tK_ALT_9 -> { \\${1://cuerpo...} }\n# K_SHIFT_9\nsnippet K_SHIFT_9\n\tK_SHIFT_9 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_9\nsnippet K_CTRL_ALT_9\n\tK_CTRL_ALT_9 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_9\nsnippet K_CTRL_SHIFT_9\n\tK_CTRL_SHIFT_9 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_9\nsnippet K_CTRL_ALT_SHIFT_9\n\tK_CTRL_ALT_SHIFT_9 -> { \\${1://cuerpo...} }\n\n# K_F1\nsnippet K_F1\n\tK_F1 -> { \\${1://cuerpo...} }\n# K_CTRL_F1\nsnippet K_CTRL_F1\n\tK_CTRL_F1 -> { \\${1://cuerpo...} }\n# K_ALT_F1\nsnippet K_ALT_F1\n\tK_ALT_F1 -> { \\${1://cuerpo...} }\n# K_SHIFT_F1\nsnippet K_SHIFT_F1\n\tK_SHIFT_F1 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F1\nsnippet K_CTRL_ALT_F1\n\tK_CTRL_ALT_F1 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F1\nsnippet K_CTRL_SHIFT_F1\n\tK_CTRL_SHIFT_F1 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F1\nsnippet K_CTRL_ALT_SHIFT_F1\n\tK_CTRL_ALT_SHIFT_F1 -> { \\${1://cuerpo...} }\n\n# K_F2\nsnippet K_F2\n\tK_F2 -> { \\${1://cuerpo...} }\n# K_CTRL_F2\nsnippet K_CTRL_F2\n\tK_CTRL_F2 -> { \\${1://cuerpo...} }\n# K_ALT_F2\nsnippet K_ALT_F2\n\tK_ALT_F2 -> { \\${1://cuerpo...} }\n# K_SHIFT_F2\nsnippet K_SHIFT_F2\n\tK_SHIFT_F2 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F2\nsnippet K_CTRL_ALT_F2\n\tK_CTRL_ALT_F2 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F2\nsnippet K_CTRL_SHIFT_F2\n\tK_CTRL_SHIFT_F2 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F2\nsnippet K_CTRL_ALT_SHIFT_F2\n\tK_CTRL_ALT_SHIFT_F2 -> { \\${1://cuerpo...} }\n\n# K_F3\nsnippet K_F3\n\tK_F3 -> { \\${1://cuerpo...} }\n# K_CTRL_F3\nsnippet K_CTRL_F3\n\tK_CTRL_F3 -> { \\${1://cuerpo...} }\n# K_ALT_F3\nsnippet K_ALT_F3\n\tK_ALT_F3 -> { \\${1://cuerpo...} }\n# K_SHIFT_F3\nsnippet K_SHIFT_F3\n\tK_SHIFT_F3 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F3\nsnippet K_CTRL_ALT_F3\n\tK_CTRL_ALT_F3 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F3\nsnippet K_CTRL_SHIFT_F3\n\tK_CTRL_SHIFT_F3 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F3\nsnippet K_CTRL_ALT_SHIFT_F3\n\tK_CTRL_ALT_SHIFT_F3 -> { \\${1://cuerpo...} }\n\n# K_A\nsnippet K_A\n\tK_A -> { \\${1://cuerpo...} }\n# K_CTRL_A\nsnippet K_CTRL_A\n\tK_CTRL_A -> { \\${1://cuerpo...} }\n# K_ALT_A\nsnippet K_ALT_A\n\tK_ALT_A -> { \\${1://cuerpo...} }\n# K_SHIFT_A\nsnippet K_SHIFT_A\n\tK_SHIFT_A -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_A\nsnippet K_CTRL_ALT_A\n\tK_CTRL_ALT_A -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_A\nsnippet K_CTRL_SHIFT_A\n\tK_CTRL_SHIFT_A -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_A\nsnippet K_CTRL_ALT_SHIFT_A\n\tK_CTRL_ALT_SHIFT_A -> { \\${1://cuerpo...} }\n\n# K_F5\nsnippet K_F5\n\tK_F5 -> { \\${1://cuerpo...} }\n# K_CTRL_F5\nsnippet K_CTRL_F5\n\tK_CTRL_F5 -> { \\${1://cuerpo...} }\n# K_ALT_F5\nsnippet K_ALT_F5\n\tK_ALT_F5 -> { \\${1://cuerpo...} }\n# K_SHIFT_F5\nsnippet K_SHIFT_F5\n\tK_SHIFT_F5 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F5\nsnippet K_CTRL_ALT_F5\n\tK_CTRL_ALT_F5 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F5\nsnippet K_CTRL_SHIFT_F5\n\tK_CTRL_SHIFT_F5 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F5\nsnippet K_CTRL_ALT_SHIFT_F5\n\tK_CTRL_ALT_SHIFT_F5 -> { \\${1://cuerpo...} }\n\n# K_F6\nsnippet K_F6\n\tK_F6 -> { \\${1://cuerpo...} }\n# K_CTRL_F6\nsnippet K_CTRL_F6\n\tK_CTRL_F6 -> { \\${1://cuerpo...} }\n# K_ALT_F6\nsnippet K_ALT_F6\n\tK_ALT_F6 -> { \\${1://cuerpo...} }\n# K_SHIFT_F6\nsnippet K_SHIFT_F6\n\tK_SHIFT_F6 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F6\nsnippet K_CTRL_ALT_F6\n\tK_CTRL_ALT_F6 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F6\nsnippet K_CTRL_SHIFT_F6\n\tK_CTRL_SHIFT_F6 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F6\nsnippet K_CTRL_ALT_SHIFT_F6\n\tK_CTRL_ALT_SHIFT_F6 -> { \\${1://cuerpo...} }\n\n# K_F7\nsnippet K_F7\n\tK_F7 -> { \\${1://cuerpo...} }\n# K_CTRL_F7\nsnippet K_CTRL_F7\n\tK_CTRL_F7 -> { \\${1://cuerpo...} }\n# K_ALT_F7\nsnippet K_ALT_F7\n\tK_ALT_F7 -> { \\${1://cuerpo...} }\n# K_SHIFT_F7\nsnippet K_SHIFT_F7\n\tK_SHIFT_F7 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F7\nsnippet K_CTRL_ALT_F7\n\tK_CTRL_ALT_F7 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F7\nsnippet K_CTRL_SHIFT_F7\n\tK_CTRL_SHIFT_F7 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F7\nsnippet K_CTRL_ALT_SHIFT_F7\n\tK_CTRL_ALT_SHIFT_F7 -> { \\${1://cuerpo...} }\n\n# K_F8\nsnippet K_F8\n\tK_F8 -> { \\${1://cuerpo...} }\n# K_CTRL_F8\nsnippet K_CTRL_F8\n\tK_CTRL_F8 -> { \\${1://cuerpo...} }\n# K_ALT_F8\nsnippet K_ALT_F8\n\tK_ALT_F8 -> { \\${1://cuerpo...} }\n# K_SHIFT_F8\nsnippet K_SHIFT_F8\n\tK_SHIFT_F8 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F8\nsnippet K_CTRL_ALT_F8\n\tK_CTRL_ALT_F8 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F8\nsnippet K_CTRL_SHIFT_F8\n\tK_CTRL_SHIFT_F8 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F8\nsnippet K_CTRL_ALT_SHIFT_F8\n\tK_CTRL_ALT_SHIFT_F8 -> { \\${1://cuerpo...} }\n\n# K_F9\nsnippet K_F9\n\tK_F9 -> { \\${1://cuerpo...} }\n# K_CTRL_F9\nsnippet K_CTRL_F9\n\tK_CTRL_F9 -> { \\${1://cuerpo...} }\n# K_ALT_F9\nsnippet K_ALT_F9\n\tK_ALT_F9 -> { \\${1://cuerpo...} }\n# K_SHIFT_F9\nsnippet K_SHIFT_F9\n\tK_SHIFT_F9 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F9\nsnippet K_CTRL_ALT_F9\n\tK_CTRL_ALT_F9 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F9\nsnippet K_CTRL_SHIFT_F9\n\tK_CTRL_SHIFT_F9 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F9\nsnippet K_CTRL_ALT_SHIFT_F9\n\tK_CTRL_ALT_SHIFT_F9 -> { \\${1://cuerpo...} }\n\n# K_F10\nsnippet K_F10\n\tK_F10 -> { \\${1://cuerpo...} }\n# K_CTRL_F10\nsnippet K_CTRL_F10\n\tK_CTRL_F10 -> { \\${1://cuerpo...} }\n# K_ALT_F10\nsnippet K_ALT_F10\n\tK_ALT_F10 -> { \\${1://cuerpo...} }\n# K_SHIFT_F10\nsnippet K_SHIFT_F10\n\tK_SHIFT_F10 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F10\nsnippet K_CTRL_ALT_F10\n\tK_CTRL_ALT_F10 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F10\nsnippet K_CTRL_SHIFT_F10\n\tK_CTRL_SHIFT_F10 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F10\nsnippet K_CTRL_ALT_SHIFT_F10\n\tK_CTRL_ALT_SHIFT_F10 -> { \\${1://cuerpo...} }\n\n# K_F11\nsnippet K_F11\n\tK_F11 -> { \\${1://cuerpo...} }\n# K_CTRL_F11\nsnippet K_CTRL_F11\n\tK_CTRL_F11 -> { \\${1://cuerpo...} }\n# K_ALT_F11\nsnippet K_ALT_F11\n\tK_ALT_F11 -> { \\${1://cuerpo...} }\n# K_SHIFT_F11\nsnippet K_SHIFT_F11\n\tK_SHIFT_F11 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F11\nsnippet K_CTRL_ALT_F11\n\tK_CTRL_ALT_F11 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F11\nsnippet K_CTRL_SHIFT_F11\n\tK_CTRL_SHIFT_F11 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F11\nsnippet K_CTRL_ALT_SHIFT_F11\n\tK_CTRL_ALT_SHIFT_F11 -> { \\${1://cuerpo...} }\n\n# K_F12\nsnippet K_F12\n\tK_F12 -> { \\${1://cuerpo...} }\n# K_CTRL_F12\nsnippet K_CTRL_F12\n\tK_CTRL_F12 -> { \\${1://cuerpo...} }\n# K_ALT_F12\nsnippet K_ALT_F12\n\tK_ALT_F12 -> { \\${1://cuerpo...} }\n# K_SHIFT_F12\nsnippet K_SHIFT_F12\n\tK_SHIFT_F12 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_F12\nsnippet K_CTRL_ALT_F12\n\tK_CTRL_ALT_F12 -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_F12\nsnippet K_CTRL_SHIFT_F12\n\tK_CTRL_SHIFT_F12 -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_F12\nsnippet K_CTRL_ALT_SHIFT_F12\n\tK_CTRL_ALT_SHIFT_F12 -> { \\${1://cuerpo...} }\n\n# K_RETURN\nsnippet K_RETURN\n\tK_RETURN -> { \\${1://cuerpo...} }\n# K_CTRL_RETURN\nsnippet K_CTRL_RETURN\n\tK_CTRL_RETURN -> { \\${1://cuerpo...} }\n# K_ALT_RETURN\nsnippet K_ALT_RETURN\n\tK_ALT_RETURN -> { \\${1://cuerpo...} }\n# K_SHIFT_RETURN\nsnippet K_SHIFT_RETURN\n\tK_SHIFT_RETURN -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_RETURN\nsnippet K_CTRL_ALT_RETURN\n\tK_CTRL_ALT_RETURN -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_RETURN\nsnippet K_CTRL_SHIFT_RETURN\n\tK_CTRL_SHIFT_RETURN -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_RETURN\nsnippet K_CTRL_ALT_SHIFT_RETURN\n\tK_CTRL_ALT_SHIFT_RETURN -> { \\${1://cuerpo...} }\n\n# K_SPACE\nsnippet K_SPACE\n\tK_SPACE -> { \\${1://cuerpo...} }\n# K_CTRL_SPACE\nsnippet K_CTRL_SPACE\n\tK_CTRL_SPACE -> { \\${1://cuerpo...} }\n# K_ALT_SPACE\nsnippet K_ALT_SPACE\n\tK_ALT_SPACE -> { \\${1://cuerpo...} }\n# K_SHIFT_SPACE\nsnippet K_SHIFT_SPACE\n\tK_SHIFT_SPACE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SPACE\nsnippet K_CTRL_ALT_SPACE\n\tK_CTRL_ALT_SPACE -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_SPACE\nsnippet K_CTRL_SHIFT_SPACE\n\tK_CTRL_SHIFT_SPACE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_SPACE\nsnippet K_CTRL_ALT_SHIFT_SPACE\n\tK_CTRL_ALT_SHIFT_SPACE -> { \\${1://cuerpo...} }\n\n# K_ESCAPE\nsnippet K_ESCAPE\n\tK_ESCAPE -> { \\${1://cuerpo...} }\n# K_CTRL_ESCAPE\nsnippet K_CTRL_ESCAPE\n\tK_CTRL_ESCAPE -> { \\${1://cuerpo...} }\n# K_ALT_ESCAPE\nsnippet K_ALT_ESCAPE\n\tK_ALT_ESCAPE -> { \\${1://cuerpo...} }\n# K_SHIFT_ESCAPE\nsnippet K_SHIFT_ESCAPE\n\tK_SHIFT_ESCAPE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_ESCAPE\nsnippet K_CTRL_ALT_ESCAPE\n\tK_CTRL_ALT_ESCAPE -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_ESCAPE\nsnippet K_CTRL_SHIFT_ESCAPE\n\tK_CTRL_SHIFT_ESCAPE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_ESCAPE\nsnippet K_CTRL_ALT_SHIFT_ESCAPE\n\tK_CTRL_ALT_SHIFT_ESCAPE -> { \\${1://cuerpo...} }\n\n# K_BACKSPACE\nsnippet K_BACKSPACE\n\tK_BACKSPACE -> { \\${1://cuerpo...} }\n# K_CTRL_BACKSPACE\nsnippet K_CTRL_BACKSPACE\n\tK_CTRL_BACKSPACE -> { \\${1://cuerpo...} }\n# K_ALT_BACKSPACE\nsnippet K_ALT_BACKSPACE\n\tK_ALT_BACKSPACE -> { \\${1://cuerpo...} }\n# K_SHIFT_BACKSPACE\nsnippet K_SHIFT_BACKSPACE\n\tK_SHIFT_BACKSPACE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_BACKSPACE\nsnippet K_CTRL_ALT_BACKSPACE\n\tK_CTRL_ALT_BACKSPACE -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_BACKSPACE\nsnippet K_CTRL_SHIFT_BACKSPACE\n\tK_CTRL_SHIFT_BACKSPACE -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_BACKSPACE\nsnippet K_CTRL_ALT_SHIFT_BACKSPACE\n\tK_CTRL_ALT_SHIFT_BACKSPACE -> { \\${1://cuerpo...} }\n\n# K_TAB\nsnippet K_TAB\n\tK_TAB -> { \\${1://cuerpo...} }\n# K_CTRL_TAB\nsnippet K_CTRL_TAB\n\tK_CTRL_TAB -> { \\${1://cuerpo...} }\n# K_ALT_TAB\nsnippet K_ALT_TAB\n\tK_ALT_TAB -> { \\${1://cuerpo...} }\n# K_SHIFT_TAB\nsnippet K_SHIFT_TAB\n\tK_SHIFT_TAB -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_TAB\nsnippet K_CTRL_ALT_TAB\n\tK_CTRL_ALT_TAB -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_TAB\nsnippet K_CTRL_SHIFT_TAB\n\tK_CTRL_SHIFT_TAB -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_TAB\nsnippet K_CTRL_ALT_SHIFT_TAB\n\tK_CTRL_ALT_SHIFT_TAB -> { \\${1://cuerpo...} }\n\n# K_UP\nsnippet K_UP\n\tK_UP -> { \\${1://cuerpo...} }\n# K_CTRL_UP\nsnippet K_CTRL_UP\n\tK_CTRL_UP -> { \\${1://cuerpo...} }\n# K_ALT_UP\nsnippet K_ALT_UP\n\tK_ALT_UP -> { \\${1://cuerpo...} }\n# K_SHIFT_UP\nsnippet K_SHIFT_UP\n\tK_SHIFT_UP -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_UP\nsnippet K_CTRL_ALT_UP\n\tK_CTRL_ALT_UP -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_UP\nsnippet K_CTRL_SHIFT_UP\n\tK_CTRL_SHIFT_UP -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_UP\nsnippet K_CTRL_ALT_SHIFT_UP\n\tK_CTRL_ALT_SHIFT_UP -> { \\${1://cuerpo...} }\n\n# K_DOWN\nsnippet K_DOWN\n\tK_DOWN -> { \\${1://cuerpo...} }\n# K_CTRL_DOWN\nsnippet K_CTRL_DOWN\n\tK_CTRL_DOWN -> { \\${1://cuerpo...} }\n# K_ALT_DOWN\nsnippet K_ALT_DOWN\n\tK_ALT_DOWN -> { \\${1://cuerpo...} }\n# K_SHIFT_DOWN\nsnippet K_SHIFT_DOWN\n\tK_SHIFT_DOWN -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_DOWN\nsnippet K_CTRL_ALT_DOWN\n\tK_CTRL_ALT_DOWN -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_DOWN\nsnippet K_CTRL_SHIFT_DOWN\n\tK_CTRL_SHIFT_DOWN -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_DOWN\nsnippet K_CTRL_ALT_SHIFT_DOWN\n\tK_CTRL_ALT_SHIFT_DOWN -> { \\${1://cuerpo...} }\n\n# K_LEFT\nsnippet K_LEFT\n\tK_LEFT -> { \\${1://cuerpo...} }\n# K_CTRL_LEFT\nsnippet K_CTRL_LEFT\n\tK_CTRL_LEFT -> { \\${1://cuerpo...} }\n# K_ALT_LEFT\nsnippet K_ALT_LEFT\n\tK_ALT_LEFT -> { \\${1://cuerpo...} }\n# K_SHIFT_LEFT\nsnippet K_SHIFT_LEFT\n\tK_SHIFT_LEFT -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_LEFT\nsnippet K_CTRL_ALT_LEFT\n\tK_CTRL_ALT_LEFT -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_LEFT\nsnippet K_CTRL_SHIFT_LEFT\n\tK_CTRL_SHIFT_LEFT -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_LEFT\nsnippet K_CTRL_ALT_SHIFT_LEFT\n\tK_CTRL_ALT_SHIFT_LEFT -> { \\${1://cuerpo...} }\n\n# K_RIGHT\nsnippet K_RIGHT\n\tK_RIGHT -> { \\${1://cuerpo...} }\n# K_CTRL_RIGHT\nsnippet K_CTRL_RIGHT\n\tK_CTRL_RIGHT -> { \\${1://cuerpo...} }\n# K_ALT_RIGHT\nsnippet K_ALT_RIGHT\n\tK_ALT_RIGHT -> { \\${1://cuerpo...} }\n# K_SHIFT_RIGHT\nsnippet K_SHIFT_RIGHT\n\tK_SHIFT_RIGHT -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_RIGHT\nsnippet K_CTRL_ALT_RIGHT\n\tK_CTRL_ALT_RIGHT -> { \\${1://cuerpo...} }\n# K_CTRL_SHIFT_RIGHT\nsnippet K_CTRL_SHIFT_RIGHT\n\tK_CTRL_SHIFT_RIGHT -> { \\${1://cuerpo...} }\n# K_CTRL_ALT_SHIFT_RIGHT\nsnippet K_CTRL_ALT_SHIFT_RIGHT\n\tK_CTRL_ALT_SHIFT_RIGHT -> { \\${1://cuerpo...} }\n\n# recorrido (simple)\nsnippet recorrido (simple)\n\t\\${1:// Ir al inicio}\n\twhile (not \\${2:// es último elemento}) {\n\t\t\\${3:// Procesar el elemento}\n\t\t\\${4:// Ir al próximo elemento}\n\t}\n\t\\${5:// Finalizar}\n\n# recorrido (de acumulación)\nsnippet recorrido (de acumulación)\n\t\\${1:// Ir al inicio}\n\t\\${2:cantidadVistos} := \\${3:// contar elementos en lugar actual}\n\twhile (not \\${4:// es último elemento}) {\n\t\t\\${4:// Ir al próximo elemento}\n\t\t\\${2:cantidadVistos} := \\${2:cantidadVistos} + \\${3:// contar elementos en lugar actual}\n\t}\n\treturn (\\${2:cantidadVistos})\n\n# recorrido (de búsqueda)\nsnippet recorrido (de búsqueda)\n\t\\${1:// Ir al inicio}\n\twhile (not \\${2:// encontré lo que buscaba}) {\n\t\t\\${3:// Ir al próximo elemento}\n\t}\n\treturn (\\${2:// encontré lo que buscaba })\n\n# recorrido (de búsqueda con borde)\nsnippet recorrido (de búsqueda con borde)\n\t\\${1:// Ir al inicio}\n\twhile (not \\${2:// encontré lo que buscaba} && not \\${3:// es último elemento}) {\n\t\t\\${4:// Ir al próximo elemento}\n\t}\n\treturn (\\${2:// encontré lo que buscaba })\n\n# recorrido (de tipos enumerativos)\nsnippet recorrido (de tipos enumerativos)\n\t\\${1:elementoActual} := \\${2:minElemento()}\n\twhile (\\${1:elementoActual} /= \\${3:maxElemento()}) {\n\t\t\\${4:// Procesar con elemento actual}\n\t\t\\${1:elementoActual} := siguiente(\\${1:elementoActual})\n\t}\n\t\\${4:// Procesar con elemento actual}\n\n# recorrido (de búsqueda sobre lista)\nsnippet recorrido (de búsqueda sobre lista)\n\t\\${1:listaRecorrida} := \\${2:lista}\n\twhile (primero(\\${1:listaRecorrida}) /= \\${3://elemento buscado}) {\n\t\t\\${1:elementoActual} := sinElPrimero(\\${1:elementoActual})\n\t}\n\treturn (primero(\\${1:listaRecorrida}))\n\n# recorrido (de búsqueda sobre lista con borde)\nsnippet recorrido (de búsqueda sobre lista con borde)\n\t\\${1:listaRecorrida} := \\${2:lista}\n\twhile (not esVacía(\\${1:listaRecorrida}) && primero(\\${1:listaRecorrida}) /= \\${3://elemento buscado}) {\n\t\t\\${1:elementoActual} := sinElPrimero(\\${1:elementoActual})\n\t}\n\treturn (not esVacía(\\${1:listaRecorrida}))\n\n# docs (procedimiento)\nsnippet docs (procedimiento)\n\t/*\n\t\t@PROPÓSITO: \\${1:...}\n\t\t@PRECONDICIÓN: \\${2:...}\n\t*/\n\n# docs (procedimiento con parámetros)\nsnippet docs (procedimiento con parámetros)\n\t/*\n\t\t@PROPÓSITO: \\${1:...}\n\t\t@PRECONDICIÓN: \\${2:...}\n\t\t@PARÁMETROS:\n\t\t\t\t* \\${3:nombreDelParámetro} : \\${4:Tipo} - \\${5:descripción}\n\t*/\n\n# docs (función)\nsnippet docs (función)\n\t/*\n\t\t@PROPÓSITO: \\${1:...}\n\t\t@PRECONDICIÓN: \\${2:...}\n\t\t@TIPO: \\${3:...}\n\t*/\n\n# docs (función con parámetros)\nsnippet docs (función con parámetros)\n\t/*\n\t\t@PROPÓSITO: \\${1:...}\n\t\t@PRECONDICIÓN: \\${2:...}\n\t\t@PARÁMETROS:\n\t\t\t\t* \\${3:nombreDelParámetro} : \\${4:Tipo} - \\${5:descripción}\n\t\t@TIPO: \\${6:...}\n\t*/\n`;\n"
  },
  {
    "path": "src/snippets/graphqlschema.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./graphqlschema.snippets\");\nexports.scope = \"graphqlschema\";\n"
  },
  {
    "path": "src/snippets/graphqlschema.snippets.js",
    "content": "module.exports = `# Type Snippet\ntrigger type\nsnippet type\n\ttype \\${1:type_name} {\n\t\t\\${2:type_siblings}\n\t}\n\n# Input Snippet\ntrigger input\nsnippet input\n\tinput \\${1:input_name} {\n\t\t\\${2:input_siblings}\n\t}\n\n# Interface Snippet\ntrigger interface\nsnippet interface\n\tinterface \\${1:interface_name} {\n\t\t\\${2:interface_siblings}\n\t}\n\n# Interface Snippet\ntrigger union\nsnippet union\n\tunion \\${1:union_name} = \\${2:type} | \\${3: type}\n\n# Enum Snippet\ntrigger enum\nsnippet enum\n\tenum \\${1:enum_name} {\n\t\t\\${2:enum_siblings}\n\t}\n`;\n"
  },
  {
    "path": "src/snippets/haml.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./haml.snippets\");\nexports.scope = \"haml\";\n"
  },
  {
    "path": "src/snippets/haml.snippets.js",
    "content": "module.exports = `snippet t\n\t%table\n\t\t%tr\n\t\t\t%th\n\t\t\t\t\\${1:headers}\n\t\t%tr\n\t\t\t%td\n\t\t\t\t\\${2:headers}\nsnippet ul\n\t%ul\n\t\t%li\n\t\t\t\\${1:item}\n\t\t%li\nsnippet =rp\n\t= render :partial => '\\${1:partial}'\nsnippet =rpl\n\t= render :partial => '\\${1:partial}', :locals => {}\nsnippet =rpc\n\t= render :partial => '\\${1:partial}', :collection => @\\$1\n\n`;\n"
  },
  {
    "path": "src/snippets/haskell.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./haskell.snippets\");\nexports.scope = \"haskell\";\n"
  },
  {
    "path": "src/snippets/haskell.snippets.js",
    "content": "module.exports = `snippet lang\n\t{-# LANGUAGE \\${1:OverloadedStrings} #-}\nsnippet info\n\t-- |\n\t-- Module      :  \\${1:Module.Namespace}\n\t-- Copyright   :  \\${2:Author} \\${3:2011-2012}\n\t-- License     :  \\${4:BSD3}\n\t--\n\t-- Maintainer  :  \\${5:email@something.com}\n\t-- Stability   :  \\${6:experimental}\n\t-- Portability :  \\${7:unknown}\n\t--\n\t-- \\${8:Description}\n\t--\nsnippet import\n\timport           \\${1:Data.Text}\nsnippet import2\n\timport           \\${1:Data.Text} (\\${2:head})\nsnippet importq\n\timport qualified \\${1:Data.Text} as \\${2:T}\nsnippet inst\n\tinstance \\${1:Monoid} \\${2:Type} where\n\t\t\\${3}\nsnippet type\n\ttype \\${1:Type} = \\${2:Type}\nsnippet data\n\tdata \\${1:Type} = \\${2:\\$1} \\${3:Int}\nsnippet newtype\n\tnewtype \\${1:Type} = \\${2:\\$1} \\${3:Int}\nsnippet class\n\tclass \\${1:Class} a where\n\t\t\\${2}\nsnippet module\n\tmodule \\`substitute(substitute(expand('%:r'), '[/\\\\\\\\]','.','g'),'^\\\\%(\\\\l*\\\\.\\\\)\\\\?','','')\\` (\n\t)\twhere\n\t\\`expand('%') =~ 'Main' ? \"\\\\n\\\\nmain = do\\\\n  print \\\\\"hello world\\\\\"\" : \"\"\\`\n\nsnippet const\n\t\\${1:name} :: \\${2:a}\n\t\\$1 = \\${3:undefined}\nsnippet fn\n\t\\${1:fn} :: \\${2:a} -> \\${3:a}\n\t\\$1 \\${4} = \\${5:undefined}\nsnippet fn2\n\t\\${1:fn} :: \\${2:a} -> \\${3:a} -> \\${4:a}\n\t\\$1 \\${5} = \\${6:undefined}\nsnippet ap\n\t\\${1:map} \\${2:fn} \\${3:list}\nsnippet do\n\tdo\n\t\t\nsnippet λ\n\t\\\\\\${1:x} -> \\${2}\nsnippet \\\\\n\t\\\\\\${1:x} -> \\${2}\nsnippet <-\n\t\\${1:a} <- \\${2:m a}\nsnippet ←\n\t\\${1:a} <- \\${2:m a}\nsnippet ->\n\t\\${1:m a} -> \\${2:a}\nsnippet →\n\t\\${1:m a} -> \\${2:a}\nsnippet tup\n\t(\\${1:a}, \\${2:b})\nsnippet tup2\n\t(\\${1:a}, \\${2:b}, \\${3:c})\nsnippet tup3\n\t(\\${1:a}, \\${2:b}, \\${3:c}, \\${4:d})\nsnippet rec\n\t\\${1:Record} { \\${2:recFieldA} = \\${3:undefined}\n\t\t\t\t, \\${4:recFieldB} = \\${5:undefined}\n\t\t\t\t}\nsnippet case\n\tcase \\${1:something} of\n\t\t\\${2} -> \\${3}\nsnippet let\n\tlet \\${1} = \\${2}\n\tin \\${3}\nsnippet where\n\twhere\n\t\t\\${1:fn} = \\${2:undefined}\n`;\n"
  },
  {
    "path": "src/snippets/html.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./html.snippets\");\nexports.scope = \"html\";\n"
  },
  {
    "path": "src/snippets/html.snippets.js",
    "content": "module.exports = `# Some useful Unicode entities\n# Non-Breaking Space\nsnippet nbs\n\t&nbsp;\n# ←\nsnippet left\n\t&#x2190;\n# →\nsnippet right\n\t&#x2192;\n# ↑\nsnippet up\n\t&#x2191;\n# ↓\nsnippet down\n\t&#x2193;\n# ↩\nsnippet return\n\t&#x21A9;\n# ⇤\nsnippet backtab\n\t&#x21E4;\n# ⇥\nsnippet tab\n\t&#x21E5;\n# ⇧\nsnippet shift\n\t&#x21E7;\n# ⌃\nsnippet ctrl\n\t&#x2303;\n# ⌅\nsnippet enter\n\t&#x2305;\n# ⌘\nsnippet cmd\n\t&#x2318;\n# ⌥\nsnippet option\n\t&#x2325;\n# ⌦\nsnippet delete\n\t&#x2326;\n# ⌫\nsnippet backspace\n\t&#x232B;\n# ⎋\nsnippet esc\n\t&#x238B;\n# Generic Doctype\nsnippet doctype HTML 4.01 Strict\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\t\"http://www.w3.org/TR/html4/strict.dtd\">\nsnippet doctype HTML 4.01 Transitional\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\t\"http://www.w3.org/TR/html4/loose.dtd\">\nsnippet doctype HTML 5\n\t<!DOCTYPE HTML>\nsnippet doctype XHTML 1.0 Frameset\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\nsnippet doctype XHTML 1.0 Strict\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\nsnippet doctype XHTML 1.0 Transitional\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\nsnippet doctype XHTML 1.1\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n\t\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n# HTML Doctype 4.01 Strict\nsnippet docts\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\t\"http://www.w3.org/TR/html4/strict.dtd\">\n# HTML Doctype 4.01 Transitional\nsnippet doct\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\t\"http://www.w3.org/TR/html4/loose.dtd\">\n# HTML Doctype 5\nsnippet doct5\n\t<!DOCTYPE html>\n# XHTML Doctype 1.0 Frameset\nsnippet docxf\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n# XHTML Doctype 1.0 Strict\nsnippet docxs\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n# XHTML Doctype 1.0 Transitional\nsnippet docxt\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n# XHTML Doctype 1.1\nsnippet docx\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n\t\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n# html5shiv\nsnippet html5shiv\n\t<!--[if lte IE 8]>\n\t\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js\"></script>\n\t<![endif]-->\nsnippet html5printshiv\n\t<!--[if lte IE 8]>\n\t\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js\"></script>\n\t<![endif]-->\n# Attributes\nsnippet attr\n\t\\${1:attribute}=\"\\${2:property}\"\nsnippet attr+\n\t\\${1:attribute}=\"\\${2:property}\" attr+\\${3}\nsnippet .\n\tclass=\"\\${1}\"\\${2}\nsnippet #\n\tid=\"\\${1}\"\\${2}\nsnippet alt\n\talt=\"\\${1}\"\\${2}\nsnippet charset\n\tcharset=\"\\${1:utf-8}\"\\${2}\nsnippet data\n\tdata-\\${1}=\"\\${2:\\$1}\"\\${3}\nsnippet for\n\tfor=\"\\${1}\"\\${2}\nsnippet height\n\theight=\"\\${1}\"\\${2}\nsnippet href\n\thref=\"\\${1:#}\"\\${2}\nsnippet lang\n\tlang=\"\\${1:en}\"\\${2}\nsnippet media\n\tmedia=\"\\${1}\"\\${2}\nsnippet name\n\tname=\"\\${1}\"\\${2}\nsnippet rel\n\trel=\"\\${1}\"\\${2}\nsnippet scope\n\tscope=\"\\${1:row}\"\\${2}\nsnippet src\n\tsrc=\"\\${1}\"\\${2}\nsnippet title=\n\ttitle=\"\\${1}\"\\${2}\nsnippet type\n\ttype=\"\\${1}\"\\${2}\nsnippet value\n\tvalue=\"\\${1}\"\\${2}\nsnippet width\n\twidth=\"\\${1}\"\\${2}\n# Elements\nsnippet a\n\t<a href=\"\\${1:#}\">\\${2:\\$1}</a>\nsnippet a.\n\t<a class=\"\\${1}\" href=\"\\${2:#}\">\\${3:\\$1}</a>\nsnippet a#\n\t<a id=\"\\${1}\" href=\"\\${2:#}\">\\${3:\\$1}</a>\nsnippet a:ext\n\t<a href=\"http://\\${1:example.com}\">\\${2:\\$1}</a>\nsnippet a:mail\n\t<a href=\"mailto:\\${1:joe@example.com}?subject=\\${2:feedback}\">\\${3:email me}</a>\nsnippet abbr\n\t<abbr title=\"\\${1}\">\\${2}</abbr>\nsnippet address\n\t<address>\n\t\t\\${1}\n\t</address>\nsnippet area\n\t<area shape=\"\\${1:rect}\" coords=\"\\${2}\" href=\"\\${3}\" alt=\"\\${4}\" />\nsnippet area+\n\t<area shape=\"\\${1:rect}\" coords=\"\\${2}\" href=\"\\${3}\" alt=\"\\${4}\" />\n\tarea+\\${5}\nsnippet area:c\n\t<area shape=\"circle\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:d\n\t<area shape=\"default\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:p\n\t<area shape=\"poly\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:r\n\t<area shape=\"rect\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet article\n\t<article>\n\t\t\\${1}\n\t</article>\nsnippet article.\n\t<article class=\"\\${1}\">\n\t\t\\${2}\n\t</article>\nsnippet article#\n\t<article id=\"\\${1}\">\n\t\t\\${2}\n\t</article>\nsnippet aside\n\t<aside>\n\t\t\\${1}\n\t</aside>\nsnippet aside.\n\t<aside class=\"\\${1}\">\n\t\t\\${2}\n\t</aside>\nsnippet aside#\n\t<aside id=\"\\${1}\">\n\t\t\\${2}\n\t</aside>\nsnippet audio\n\t<audio src=\"\\${1}>\\${2}</audio>\nsnippet b\n\t<b>\\${1}</b>\nsnippet base\n\t<base href=\"\\${1}\" target=\"\\${2}\" />\nsnippet bdi\n\t<bdi>\\${1}</bdo>\nsnippet bdo\n\t<bdo dir=\"\\${1}\">\\${2}</bdo>\nsnippet bdo:l\n\t<bdo dir=\"ltr\">\\${1}</bdo>\nsnippet bdo:r\n\t<bdo dir=\"rtl\">\\${1}</bdo>\nsnippet blockquote\n\t<blockquote>\n\t\t\\${1}\n\t</blockquote>\nsnippet body\n\t<body>\n\t\t\\${1}\n\t</body>\nsnippet br\n\t<br />\\${1}\nsnippet button\n\t<button type=\"\\${1:submit}\">\\${2}</button>\nsnippet button.\n\t<button class=\"\\${1:button}\" type=\"\\${2:submit}\">\\${3}</button>\nsnippet button#\n\t<button id=\"\\${1}\" type=\"\\${2:submit}\">\\${3}</button>\nsnippet button:s\n\t<button type=\"submit\">\\${1}</button>\nsnippet button:r\n\t<button type=\"reset\">\\${1}</button>\nsnippet canvas\n\t<canvas id=\"\\${1:canvas}\"></canvas>\nsnippet caption\n\t<caption>\\${1}</caption>\nsnippet cite\n\t<cite>\\${1}</cite>\nsnippet code\n\t<code>\\${1}</code>\nsnippet col\n\t<col />\\${1}\nsnippet col+\n\t<col />\n\tcol+\\${1}\nsnippet colgroup\n\t<colgroup>\n\t\t\\${1}\n\t</colgroup>\nsnippet colgroup+\n\t<colgroup>\n\t\t<col />\n\t\tcol+\\${1}\n\t</colgroup>\nsnippet command\n\t<command type=\"command\" label=\"\\${1}\" icon=\"\\${2}\" />\nsnippet command:c\n\t<command type=\"checkbox\" label=\"\\${1}\" icon=\"\\${2}\" />\nsnippet command:r\n\t<command type=\"radio\" radiogroup=\"\\${1}\" label=\"\\${2}\" icon=\"\\${3}\" />\nsnippet datagrid\n\t<datagrid>\n\t\t\\${1}\n\t</datagrid>\nsnippet datalist\n\t<datalist>\n\t\t\\${1}\n\t</datalist>\nsnippet datatemplate\n\t<datatemplate>\n\t\t\\${1}\n\t</datatemplate>\nsnippet dd\n\t<dd>\\${1}</dd>\nsnippet dd.\n\t<dd class=\"\\${1}\">\\${2}</dd>\nsnippet dd#\n\t<dd id=\"\\${1}\">\\${2}</dd>\nsnippet del\n\t<del>\\${1}</del>\nsnippet details\n\t<details>\\${1}</details>\nsnippet dfn\n\t<dfn>\\${1}</dfn>\nsnippet dialog\n\t<dialog>\n\t\t\\${1}\n\t</dialog>\nsnippet div\n\t<div>\n\t\t\\${1}\n\t</div>\nsnippet div.\n\t<div class=\"\\${1}\">\n\t\t\\${2}\n\t</div>\nsnippet div#\n\t<div id=\"\\${1}\">\n\t\t\\${2}\n\t</div>\nsnippet dl\n\t<dl>\n\t\t\\${1}\n\t</dl>\nsnippet dl.\n\t<dl class=\"\\${1}\">\n\t\t\\${2}\n\t</dl>\nsnippet dl#\n\t<dl id=\"\\${1}\">\n\t\t\\${2}\n\t</dl>\nsnippet dl+\n\t<dl>\n\t\t<dt>\\${1}</dt>\n\t\t<dd>\\${2}</dd>\n\t\tdt+\\${3}\n\t</dl>\nsnippet dt\n\t<dt>\\${1}</dt>\nsnippet dt.\n\t<dt class=\"\\${1}\">\\${2}</dt>\nsnippet dt#\n\t<dt id=\"\\${1}\">\\${2}</dt>\nsnippet dt+\n\t<dt>\\${1}</dt>\n\t<dd>\\${2}</dd>\n\tdt+\\${3}\nsnippet em\n\t<em>\\${1}</em>\nsnippet embed\n\t<embed src=\\${1} type=\"\\${2} />\nsnippet fieldset\n\t<fieldset>\n\t\t\\${1}\n\t</fieldset>\nsnippet fieldset.\n\t<fieldset class=\"\\${1}\">\n\t\t\\${2}\n\t</fieldset>\nsnippet fieldset#\n\t<fieldset id=\"\\${1}\">\n\t\t\\${2}\n\t</fieldset>\nsnippet fieldset+\n\t<fieldset>\n\t\t<legend><span>\\${1}</span></legend>\n\t\t\\${2}\n\t</fieldset>\n\tfieldset+\\${3}\nsnippet figcaption\n\t<figcaption>\\${1}</figcaption>\nsnippet figure\n\t<figure>\\${1}</figure>\nsnippet footer\n\t<footer>\n\t\t\\${1}\n\t</footer>\nsnippet footer.\n\t<footer class=\"\\${1}\">\n\t\t\\${2}\n\t</footer>\nsnippet footer#\n\t<footer id=\"\\${1}\">\n\t\t\\${2}\n\t</footer>\nsnippet form\n\t<form action=\"\\${1}\" method=\"\\${2:get}\" accept-charset=\"utf-8\">\n\t\t\\${3}\n\t</form>\nsnippet form.\n\t<form class=\"\\${1}\" action=\"\\${2}\" method=\"\\${3:get}\" accept-charset=\"utf-8\">\n\t\t\\${4}\n\t</form>\nsnippet form#\n\t<form id=\"\\${1}\" action=\"\\${2}\" method=\"\\${3:get}\" accept-charset=\"utf-8\">\n\t\t\\${4}\n\t</form>\nsnippet h1\n\t<h1>\\${1}</h1>\nsnippet h1.\n\t<h1 class=\"\\${1}\">\\${2}</h1>\nsnippet h1#\n\t<h1 id=\"\\${1}\">\\${2}</h1>\nsnippet h2\n\t<h2>\\${1}</h2>\nsnippet h2.\n\t<h2 class=\"\\${1}\">\\${2}</h2>\nsnippet h2#\n\t<h2 id=\"\\${1}\">\\${2}</h2>\nsnippet h3\n\t<h3>\\${1}</h3>\nsnippet h3.\n\t<h3 class=\"\\${1}\">\\${2}</h3>\nsnippet h3#\n\t<h3 id=\"\\${1}\">\\${2}</h3>\nsnippet h4\n\t<h4>\\${1}</h4>\nsnippet h4.\n\t<h4 class=\"\\${1}\">\\${2}</h4>\nsnippet h4#\n\t<h4 id=\"\\${1}\">\\${2}</h4>\nsnippet h5\n\t<h5>\\${1}</h5>\nsnippet h5.\n\t<h5 class=\"\\${1}\">\\${2}</h5>\nsnippet h5#\n\t<h5 id=\"\\${1}\">\\${2}</h5>\nsnippet h6\n\t<h6>\\${1}</h6>\nsnippet h6.\n\t<h6 class=\"\\${1}\">\\${2}</h6>\nsnippet h6#\n\t<h6 id=\"\\${1}\">\\${2}</h6>\nsnippet head\n\t<head>\n\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\n\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\\${2}\n\t</head>\nsnippet header\n\t<header>\n\t\t\\${1}\n\t</header>\nsnippet header.\n\t<header class=\"\\${1}\">\n\t\t\\${2}\n\t</header>\nsnippet header#\n\t<header id=\"\\${1}\">\n\t\t\\${2}\n\t</header>\nsnippet hgroup\n\t<hgroup>\n\t\t\\${1}\n\t</hgroup>\nsnippet hgroup.\n\t<hgroup class=\"\\${1}>\n\t\t\\${2}\n\t</hgroup>\nsnippet hr\n\t<hr />\\${1}\nsnippet html\n\t<html>\n\t\\${1}\n\t</html>\nsnippet xhtml\n\t<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\\${1}\n\t</html>\nsnippet html5\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\t\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\t\\${2:meta}\n\t\t</head>\n\t\t<body>\n\t\t\t\\${3:body}\n\t\t</body>\n\t</html>\nsnippet xhtml5\n\t<!DOCTYPE html>\n\t<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\t<head>\n\t\t\t<meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=utf-8\" />\n\t\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\t\\${2:meta}\n\t\t</head>\n\t\t<body>\n\t\t\t\\${3:body}\n\t\t</body>\n\t</html>\nsnippet i\n\t<i>\\${1}</i>\nsnippet iframe\n\t<iframe src=\"\\${1}\" frameborder=\"0\"></iframe>\\${2}\nsnippet iframe.\n\t<iframe class=\"\\${1}\" src=\"\\${2}\" frameborder=\"0\"></iframe>\\${3}\nsnippet iframe#\n\t<iframe id=\"\\${1}\" src=\"\\${2}\" frameborder=\"0\"></iframe>\\${3}\nsnippet img\n\t<img src=\"\\${1}\" alt=\"\\${2}\" />\\${3}\nsnippet img.\n\t<img class=\"\\${1}\" src=\"\\${2}\" alt=\"\\${3}\" />\\${4}\nsnippet img#\n\t<img id=\"\\${1}\" src=\"\\${2}\" alt=\"\\${3}\" />\\${4}\nsnippet input\n\t<input type=\"\\${1:text/submit/hidden/button/image}\" name=\"\\${2}\" id=\"\\${3:\\$2}\" value=\"\\${4}\" />\\${5}\nsnippet input.\n\t<input class=\"\\${1}\" type=\"\\${2:text/submit/hidden/button/image}\" name=\"\\${3}\" id=\"\\${4:\\$3}\" value=\"\\${5}\" />\\${6}\nsnippet input:text\n\t<input type=\"text\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:submit\n\t<input type=\"submit\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:hidden\n\t<input type=\"hidden\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:button\n\t<input type=\"button\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:image\n\t<input type=\"image\" name=\"\\${1}\" id=\"\\${2:\\$1}\" src=\"\\${3}\" alt=\"\\${4}\" />\\${5}\nsnippet input:checkbox\n\t<input type=\"checkbox\" name=\"\\${1}\" id=\"\\${2:\\$1}\" />\\${3}\nsnippet input:radio\n\t<input type=\"radio\" name=\"\\${1}\" id=\"\\${2:\\$1}\" />\\${3}\nsnippet input:color\n\t<input type=\"color\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:date\n\t<input type=\"date\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:datetime\n\t<input type=\"datetime\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:datetime-local\n\t<input type=\"datetime-local\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:email\n\t<input type=\"email\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:file\n\t<input type=\"file\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:month\n\t<input type=\"month\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:number\n\t<input type=\"number\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:password\n\t<input type=\"password\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:range\n\t<input type=\"range\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:reset\n\t<input type=\"reset\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:search\n\t<input type=\"search\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:time\n\t<input type=\"time\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:url\n\t<input type=\"url\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:week\n\t<input type=\"week\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet ins\n\t<ins>\\${1}</ins>\nsnippet kbd\n\t<kbd>\\${1}</kbd>\nsnippet keygen\n\t<keygen>\\${1}</keygen>\nsnippet label\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\nsnippet label:i\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\n\t<input type=\"\\${3:text/submit/hidden/button}\" name=\"\\${4:\\$2}\" id=\"\\${5:\\$2}\" value=\"\\${6}\" />\\${7}\nsnippet label:s\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\n\t<select name=\"\\${3:\\$2}\" id=\"\\${4:\\$2}\">\n\t\t<option value=\"\\${5}\">\\${6:\\$5}</option>\n\t</select>\nsnippet legend\n\t<legend>\\${1}</legend>\nsnippet legend+\n\t<legend><span>\\${1}</span></legend>\nsnippet li\n\t<li>\\${1}</li>\nsnippet li.\n\t<li class=\"\\${1}\">\\${2}</li>\nsnippet li+\n\t<li>\\${1}</li>\n\tli+\\${2}\nsnippet lia\n\t<li><a href=\"\\${2:#}\">\\${1}</a></li>\nsnippet lia+\n\t<li><a href=\"\\${2:#}\">\\${1}</a></li>\n\tlia+\\${3}\nsnippet link\n\t<link rel=\"\\${1}\" href=\"\\${2}\" title=\"\\${3}\" type=\"\\${4}\" />\\${5}\nsnippet link:atom\n\t<link rel=\"alternate\" href=\"\\${1:atom.xml}\" title=\"Atom\" type=\"application/atom+xml\" />\\${2}\nsnippet link:css\n\t<link rel=\"stylesheet\" href=\"\\${2:style.css}\" type=\"text/css\" media=\"\\${3:all}\" />\\${4}\nsnippet link:favicon\n\t<link rel=\"shortcut icon\" href=\"\\${1:favicon.ico}\" type=\"image/x-icon\" />\\${2}\nsnippet link:rss\n\t<link rel=\"alternate\" href=\"\\${1:rss.xml}\" title=\"RSS\" type=\"application/atom+xml\" />\\${2}\nsnippet link:touch\n\t<link rel=\"apple-touch-icon\" href=\"\\${1:favicon.png}\" />\\${2}\nsnippet map\n\t<map name=\"\\${1}\">\n\t\t\\${2}\n\t</map>\nsnippet map.\n\t<map class=\"\\${1}\" name=\"\\${2}\">\n\t\t\\${3}\n\t</map>\nsnippet map#\n\t<map name=\"\\${1}\" id=\"\\${2:\\$1}>\n\t\t\\${3}\n\t</map>\nsnippet map+\n\t<map name=\"\\${1}\">\n\t\t<area shape=\"\\${2}\" coords=\"\\${3}\" href=\"\\${4}\" alt=\"\\${5}\" />\\${6}\n\t</map>\\${7}\nsnippet mark\n\t<mark>\\${1}</mark>\nsnippet menu\n\t<menu>\n\t\t\\${1}\n\t</menu>\nsnippet menu:c\n\t<menu type=\"context\">\n\t\t\\${1}\n\t</menu>\nsnippet menu:t\n\t<menu type=\"toolbar\">\n\t\t\\${1}\n\t</menu>\nsnippet meta\n\t<meta http-equiv=\"\\${1}\" content=\"\\${2}\" />\\${3}\nsnippet meta:compat\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=\\${1:7,8,edge}\" />\\${3}\nsnippet meta:refresh\n\t<meta http-equiv=\"refresh\" content=\"text/html;charset=UTF-8\" />\\${3}\nsnippet meta:utf\n\t<meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\" />\\${3}\nsnippet meter\n\t<meter>\\${1}</meter>\nsnippet nav\n\t<nav>\n\t\t\\${1}\n\t</nav>\nsnippet nav.\n\t<nav class=\"\\${1}\">\n\t\t\\${2}\n\t</nav>\nsnippet nav#\n\t<nav id=\"\\${1}\">\n\t\t\\${2}\n\t</nav>\nsnippet noscript\n\t<noscript>\n\t\t\\${1}\n\t</noscript>\nsnippet object\n\t<object data=\"\\${1}\" type=\"\\${2}\">\n\t\t\\${3}\n\t</object>\\${4}\n# Embed QT Movie\nsnippet movie\n\t<object width=\"\\$2\" height=\"\\$3\" classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\"\n\t codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\">\n\t\t<param name=\"src\" value=\"\\$1\" />\n\t\t<param name=\"controller\" value=\"\\$4\" />\n\t\t<param name=\"autoplay\" value=\"\\$5\" />\n\t\t<embed src=\"\\${1:movie.mov}\"\n\t\t\twidth=\"\\${2:320}\" height=\"\\${3:240}\"\n\t\t\tcontroller=\"\\${4:true}\" autoplay=\"\\${5:true}\"\n\t\t\tscale=\"tofit\" cache=\"true\"\n\t\t\tpluginspage=\"http://www.apple.com/quicktime/download/\" />\n\t</object>\\${6}\nsnippet ol\n\t<ol>\n\t\t\\${1}\n\t</ol>\nsnippet ol.\n\t<ol class=\"\\${1}>\n\t\t\\${2}\n\t</ol>\nsnippet ol#\n\t<ol id=\"\\${1}>\n\t\t\\${2}\n\t</ol>\nsnippet ol+\n\t<ol>\n\t\t<li>\\${1}</li>\n\t\tli+\\${2}\n\t</ol>\nsnippet opt\n\t<option value=\"\\${1}\">\\${2:\\$1}</option>\nsnippet opt+\n\t<option value=\"\\${1}\">\\${2:\\$1}</option>\n\topt+\\${3}\nsnippet optt\n\t<option>\\${1}</option>\nsnippet optgroup\n\t<optgroup>\n\t\t<option value=\"\\${1}\">\\${2:\\$1}</option>\n\t\topt+\\${3}\n\t</optgroup>\nsnippet output\n\t<output>\\${1}</output>\nsnippet p\n\t<p>\\${1}</p>\nsnippet param\n\t<param name=\"\\${1}\" value=\"\\${2}\" />\\${3}\nsnippet pre\n\t<pre>\n\t\t\\${1}\n\t</pre>\nsnippet progress\n\t<progress>\\${1}</progress>\nsnippet q\n\t<q>\\${1}</q>\nsnippet rp\n\t<rp>\\${1}</rp>\nsnippet rt\n\t<rt>\\${1}</rt>\nsnippet ruby\n\t<ruby>\n\t\t<rp><rt>\\${1}</rt></rp>\n\t</ruby>\nsnippet s\n\t<s>\\${1}</s>\nsnippet samp\n\t<samp>\n\t\t\\${1}\n\t</samp>\nsnippet script\n\t<script type=\"text/javascript\" charset=\"utf-8\">\n\t\t\\${1}\n\t</script>\nsnippet scriptsrc\n\t<script src=\"\\${1}.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\nsnippet newscript\n\t<script type=\"application/javascript\" charset=\"utf-8\">\n\t\t\\${1}\n\t</script>\nsnippet newscriptsrc\n\t<script src=\"\\${1}.js\" type=\"application/javascript\" charset=\"utf-8\"></script>\nsnippet section\n\t<section>\n\t\t\\${1}\n\t</section>\nsnippet section.\n\t<section class=\"\\${1}\">\n\t\t\\${2}\n\t</section>\nsnippet section#\n\t<section id=\"\\${1}\">\n\t\t\\${2}\n\t</section>\nsnippet select\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\">\n\t\t\\${3}\n\t</select>\nsnippet select.\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\" class=\"\\${3}>\n\t\t\\${4}\n\t</select>\nsnippet select+\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\">\n\t\t<option value=\"\\${3}\">\\${4:\\$3}</option>\n\t\topt+\\${5}\n\t</select>\nsnippet small\n\t<small>\\${1}</small>\nsnippet source\n\t<source src=\"\\${1}\" type=\"\\${2}\" media=\"\\${3}\" />\nsnippet span\n\t<span>\\${1}</span>\nsnippet strong\n\t<strong>\\${1}</strong>\nsnippet style\n\t<style type=\"text/css\" media=\"\\${1:all}\">\n\t\t\\${2}\n\t</style>\nsnippet sub\n\t<sub>\\${1}</sub>\nsnippet summary\n\t<summary>\n\t\t\\${1}\n\t</summary>\nsnippet sup\n\t<sup>\\${1}</sup>\nsnippet table\n\t<table border=\"\\${1:0}\">\n\t\t\\${2}\n\t</table>\nsnippet table.\n\t<table class=\"\\${1}\" border=\"\\${2:0}\">\n\t\t\\${3}\n\t</table>\nsnippet table#\n\t<table id=\"\\${1}\" border=\"\\${2:0}\">\n\t\t\\${3}\n\t</table>\nsnippet tbody\n\t<tbody>\n\t\t\\${1}\n\t</tbody>\nsnippet td\n\t<td>\\${1}</td>\nsnippet td.\n\t<td class=\"\\${1}\">\\${2}</td>\nsnippet td#\n\t<td id=\"\\${1}\">\\${2}</td>\nsnippet td+\n\t<td>\\${1}</td>\n\ttd+\\${2}\nsnippet textarea\n\t<textarea name=\"\\${1}\" id=\\${2:\\$1} rows=\"\\${3:8}\" cols=\"\\${4:40}\">\\${5}</textarea>\\${6}\nsnippet tfoot\n\t<tfoot>\n\t\t\\${1}\n\t</tfoot>\nsnippet th\n\t<th>\\${1}</th>\nsnippet th.\n\t<th class=\"\\${1}\">\\${2}</th>\nsnippet th#\n\t<th id=\"\\${1}\">\\${2}</th>\nsnippet th+\n\t<th>\\${1}</th>\n\tth+\\${2}\nsnippet thead\n\t<thead>\n\t\t\\${1}\n\t</thead>\nsnippet time\n\t<time datetime=\"\\${1}\" pubdate=\"\\${2:\\$1}>\\${3:\\$1}</time>\nsnippet title\n\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\nsnippet tr\n\t<tr>\n\t\t\\${1}\n\t</tr>\nsnippet tr+\n\t<tr>\n\t\t<td>\\${1}</td>\n\t\ttd+\\${2}\n\t</tr>\nsnippet track\n\t<track src=\"\\${1}\" srclang=\"\\${2}\" label=\"\\${3}\" default=\"\\${4:default}>\\${5}</track>\\${6}\nsnippet ul\n\t<ul>\n\t\t\\${1}\n\t</ul>\nsnippet ul.\n\t<ul class=\"\\${1}\">\n\t\t\\${2}\n\t</ul>\nsnippet ul#\n\t<ul id=\"\\${1}\">\n\t\t\\${2}\n\t</ul>\nsnippet ul+\n\t<ul>\n\t\t<li>\\${1}</li>\n\t\tli+\\${2}\n\t</ul>\nsnippet var\n\t<var>\\${1}</var>\nsnippet video\n\t<video src=\"\\${1}\" height=\"\\${2}\" width=\"\\${3}\" preload=\"\\${5:none}\" autoplay=\"\\${6:autoplay}\">\\${7}</video>\\${8}\nsnippet wbr\n\t<wbr />\\${1}\n`;\n"
  },
  {
    "path": "src/snippets/io.js",
    "content": "\"use strict\";\n\nexports.snippets = [\n    {\n        \"content\": \"assertEquals(${1:expected}, ${2:expr})\",\n        \"name\": \"assertEquals\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ae\"\n    },\n    {\n        \"content\": \"${1:${2:newValue} := ${3:Object} }clone do(\\n\\t$0\\n)\",\n        \"name\": \"clone do\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"cdo\"\n    },\n    {\n        \"content\": \"docSlot(\\\"${1:slotName}\\\", \\\"${2:documentation}\\\")\",\n        \"name\": \"docSlot\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ds\"\n    },\n    {\n        \"content\": \"(${1:header,}\\n\\t${2:body}\\n)$0\",\n        \"keyEquivalent\": \"@(\",\n        \"name\": \"Indented Bracketed Line\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"(\"\n    },\n    {\n        \"content\": \"\\n\\t$0\\n\",\n        \"keyEquivalent\": \"\\r\",\n        \"name\": \"Special: Return Inside Empty Parenthesis\",\n        \"scope\": \"io meta.empty-parenthesis.io, io meta.comma-parenthesis.io\"\n    },\n    {\n        \"content\": \"${1:methodName} := method(${2:args,}\\n\\t$0\\n)\",\n        \"name\": \"method\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"m\"\n    },\n    {\n        \"content\": \"newSlot(\\\"${1:slotName}\\\", ${2:defaultValue}, \\\"${3:docString}\\\")$0\",\n        \"name\": \"newSlot\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ns\"\n    },\n    {\n        \"content\": \"${1:name} := Object clone do(\\n\\t$0\\n)\",\n        \"name\": \"Object clone do\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ocdo\"\n    },\n    {\n        \"content\": \"test${1:SomeFeature} := method(\\n\\t$0\\n)\",\n        \"name\": \"testMethod\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ts\"\n    },\n    {\n        \"content\": \"${1:Something}Test := ${2:UnitTest} clone do(\\n\\t$0\\n)\",\n        \"name\": \"UnitTest\",\n        \"scope\": \"io\",\n        \"tabTrigger\": \"ut\"\n    }\n];\nexports.scope = \"io\";\n"
  },
  {
    "path": "src/snippets/java.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./java.snippets\");\nexports.scope = \"java\";\n"
  },
  {
    "path": "src/snippets/java.snippets.js",
    "content": "module.exports = `## Access Modifiers\nsnippet po\n\tprotected\nsnippet pu\n\tpublic\nsnippet pr\n\tprivate\n##\n## Annotations\nsnippet before\n\t@Before\n\tstatic void \\${1:intercept}(\\${2:args}) { \\${3} }\nsnippet mm\n\t@ManyToMany\n\t\\${1}\nsnippet mo\n\t@ManyToOne\n\t\\${1}\nsnippet om\n\t@OneToMany\\${1:(cascade=CascadeType.ALL)}\n\t\\${2}\nsnippet oo\n\t@OneToOne\n\t\\${1}\n##\n## Basic Java packages and import\nsnippet im\n\timport\nsnippet j.b\n\tjava.beans.\nsnippet j.i\n\tjava.io.\nsnippet j.m\n\tjava.math.\nsnippet j.n\n\tjava.net.\nsnippet j.u\n\tjava.util.\n##\n## Class\nsnippet cl\n\tclass \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2}\nsnippet in\n\tinterface \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2:extends Parent}\\${3}\nsnippet tc\n\tpublic class \\${1:\\`Filename()\\`} extends \\${2:TestCase}\n##\n## Class Enhancements\nsnippet ext\n\textends \nsnippet imp\n\timplements\n##\n## Comments\nsnippet /*\n\t/*\n\t * \\${1}\n\t */\n##\n## Constants\nsnippet co\n\tstatic public final \\${1:String} \\${2:var} = \\${3};\\${4}\nsnippet cos\n\tstatic public final String \\${1:var} = \"\\${2}\";\\${3}\n##\n## Control Statements\nsnippet case\n\tcase \\${1}:\n\t\t\\${2}\nsnippet def\n\tdefault:\n\t\t\\${2}\nsnippet el\n\telse\nsnippet elif\n\telse if (\\${1}) \\${2}\nsnippet if\n\tif (\\${1}) \\${2}\nsnippet sw\n\tswitch (\\${1}) {\n\t\t\\${2}\n\t}\n##\n## Create a Method\nsnippet m\n\t\\${1:void} \\${2:method}(\\${3}) \\${4:throws }\\${5}\n##\n## Create a Variable\nsnippet v\n\t\\${1:String} \\${2:var}\\${3: = null}\\${4};\\${5}\n##\n## Enhancements to Methods, variables, classes, etc.\nsnippet ab\n\tabstract\nsnippet fi\n\tfinal\nsnippet st\n\tstatic\nsnippet sy\n\tsynchronized\n##\n## Error Methods\nsnippet err\n\tSystem.err.print(\"\\${1:Message}\");\nsnippet errf\n\tSystem.err.printf(\"\\${1:Message}\", \\${2:exception});\nsnippet errln\n\tSystem.err.println(\"\\${1:Message}\");\n##\n## Exception Handling\nsnippet as\n\tassert \\${1:test} : \"\\${2:Failure message}\";\\${3}\nsnippet ca\n\tcatch(\\${1:Exception} \\${2:e}) \\${3}\nsnippet thr\n\tthrow\nsnippet ths\n\tthrows\nsnippet try\n\ttry {\n\t\t\\${3}\n\t} catch(\\${1:Exception} \\${2:e}) {\n\t}\nsnippet tryf\n\ttry {\n\t\t\\${3}\n\t} catch(\\${1:Exception} \\${2:e}) {\n\t} finally {\n\t}\n##\n## Find Methods\nsnippet findall\n\tList<\\${1:listName}> \\${2:items} = \\${1}.findAll();\\${3}\nsnippet findbyid\n\t\\${1:var} \\${2:item} = \\${1}.findById(\\${3});\\${4}\n##\n## Javadocs\nsnippet /**\n\t/**\n\t * \\${1}\n\t */\nsnippet @au\n\t@author \\`system(\"grep \\\\\\`id -un\\\\\\` /etc/passwd | cut -d \\\\\":\\\\\" -f5 | cut -d \\\\\",\\\\\" -f1\")\\`\nsnippet @br\n\t@brief \\${1:Description}\nsnippet @fi\n\t@file \\${1:\\`Filename()\\`}.java\nsnippet @pa\n\t@param \\${1:param}\nsnippet @re\n\t@return \\${1:param}\n##\n## Logger Methods\nsnippet debug\n\tLogger.debug(\\${1:param});\\${2}\nsnippet error\n\tLogger.error(\\${1:param});\\${2}\nsnippet info\n\tLogger.info(\\${1:param});\\${2}\nsnippet warn\n\tLogger.warn(\\${1:param});\\${2}\n##\n## Loops\nsnippet enfor\n\tfor (\\${1} : \\${2}) \\${3}\nsnippet for\n\tfor (\\${1}; \\${2}; \\${3}) \\${4}\nsnippet wh\n\twhile (\\${1}) \\${2}\n##\n## Main method\nsnippet main\n\tpublic static void main (String[] args) {\n\t\t\\${1:/* code */}\n\t}\n##\n## Print Methods\nsnippet print\n\tSystem.out.print(\"\\${1:Message}\");\nsnippet printf\n\tSystem.out.printf(\"\\${1:Message}\", \\${2:args});\nsnippet println\n\tSystem.out.println(\\${1});\n##\n## Render Methods\nsnippet ren\n\trender(\\${1:param});\\${2}\nsnippet rena\n\trenderArgs.put(\"\\${1}\", \\${2});\\${3}\nsnippet renb\n\trenderBinary(\\${1:param});\\${2}\nsnippet renj\n\trenderJSON(\\${1:param});\\${2}\nsnippet renx\n\trenderXml(\\${1:param});\\${2}\n##\n## Setter and Getter Methods\nsnippet set\n\t\\${1:public} void set\\${3:}(\\${2:String} \\${4:}){\n\t\tthis.\\$4 = \\$4;\n\t}\nsnippet get\n\t\\${1:public} \\${2:String} get\\${3:}(){\n\t\treturn this.\\${4:};\n\t}\n##\n## Terminate Methods or Loops\nsnippet re\n\treturn\nsnippet br\n\tbreak;\n##\n## Test Methods\nsnippet t\n\tpublic void test\\${1:Name}() throws Exception {\n\t\t\\${2}\n\t}\nsnippet test\n\t@Test\n\tpublic void test\\${1:Name}() throws Exception {\n\t\t\\${2}\n\t}\n##\n## Utils\nsnippet Sc\n\tScanner\n##\n## Miscellaneous\nsnippet action\n\tpublic static void \\${1:index}(\\${2:args}) { \\${3} }\nsnippet rnf\n\tnotFound(\\${1:param});\\${2}\nsnippet rnfin\n\tnotFoundIfNull(\\${1:param});\\${2}\nsnippet rr\n\tredirect(\\${1:param});\\${2}\nsnippet ru\n\tunauthorized(\\${1:param});\\${2}\nsnippet unless\n\t(unless=\\${1:param});\\${2}\n`;\n"
  },
  {
    "path": "src/snippets/javascript.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./javascript.snippets\");\nexports.scope = \"javascript\";\n"
  },
  {
    "path": "src/snippets/javascript.snippets.js",
    "content": "module.exports = `# Prototype\nsnippet proto\n\t\\${1:class_name}.prototype.\\${2:method_name} = function(\\${3:first_argument}) {\n\t\t\\${4:// body...}\n\t};\n# Function\nsnippet fun\n\tfunction \\${1?:function_name}(\\${2:argument}) {\n\t\t\\${3:// body...}\n\t}\n# Anonymous Function\nregex /((=)\\\\s*|(:)\\\\s*|(\\\\()|\\\\b)/f/(\\\\))?/\nsnippet f\n\tfunction\\${M1?: \\${1:functionName}}(\\$2) {\n\t\t\\${0:\\$TM_SELECTED_TEXT}\n\t}\\${M2?;}\\${M3?,}\\${M4?)}\n# Immediate function\ntrigger \\\\(?f\\\\(\nendTrigger \\\\)?\nsnippet f(\n\t(function(\\${1}) {\n\t\t\\${0:\\${TM_SELECTED_TEXT:/* code */}}\n\t}(\\${1}));\n# if\nsnippet if\n\tif (\\${1:true}) {\n\t\t\\${0}\n\t}\n# if ... else\nsnippet ife\n\tif (\\${1:true}) {\n\t\t\\${2}\n\t} else {\n\t\t\\${0}\n\t}\n# tertiary conditional\nsnippet ter\n\t\\${1:/* condition */} ? \\${2:a} : \\${3:b}\n# switch\nsnippet switch\n\tswitch (\\${1:expression}) {\n\t\tcase '\\${3:case}':\n\t\t\t\\${4:// code}\n\t\t\tbreak;\n\t\t\\${5}\n\t\tdefault:\n\t\t\t\\${2:// code}\n\t}\n# case\nsnippet case\n\tcase '\\${1:case}':\n\t\t\\${2:// code}\n\t\tbreak;\n\t\\${3}\n\n# while (...) {...}\nsnippet wh\n\twhile (\\${1:/* condition */}) {\n\t\t\\${0:/* code */}\n\t}\n# try\nsnippet try\n\ttry {\n\t\t\\${0:/* code */}\n\t} catch (e) {}\n# do...while\nsnippet do\n\tdo {\n\t\t\\${2:/* code */}\n\t} while (\\${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\\\s*/:f/\n\t\\${1:method_name}: function(\\${2:attribute}) {\n\t\t\\${0}\n\t}\\${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\\\b/st|timeout|setTimeo?u?t?/\n\tsetTimeout(function() {\\${3:\\$TM_SELECTED_TEXT}}, \\${1:10});\n# Get Elements\nsnippet gett\n\tgetElementsBy\\${1:TagName}('\\${2}')\\${3}\n# Get Element\nsnippet get\n\tgetElementBy\\${1:Id}('\\${2}')\\${3}\n# console.log (Firebug)\nsnippet cl\n\tconsole.log(\\${1});\n# return\nsnippet ret\n\treturn \\${1:result}\n# for (property in object ) { ... }\nsnippet fori\n\tfor (var \\${1:prop} in \\${2:Things}) {\n\t\t\\${0:\\$2[\\$1]}\n\t}\n# hasOwnProperty\nsnippet has\n\thasOwnProperty(\\${1})\n# docstring\nsnippet /**\n\t/**\n\t * \\${1:description}\n\t *\n\t */\nsnippet @par\nregex /^\\\\s*\\\\*\\\\s*/@(para?m?)?/\n\t@param {\\${1:type}} \\${2:name} \\${3:description}\nsnippet @ret\n\t@return {\\${1:type}} \\${2:description}\n# JSON.parse\nsnippet jsonp\n\tJSON.parse(\\${1:jstr});\n# JSON.stringify\nsnippet jsons\n\tJSON.stringify(\\${1:object});\n# self-defining function\nsnippet sdf\n\tvar \\${1:function_name} = function(\\${2:argument}) {\n\t\t\\${3:// initial code ...}\n\n\t\t\\$1 = function(\\$2) {\n\t\t\t\\${4:// main code}\n\t\t};\n\t}\n# singleton\nsnippet sing\n\tfunction \\${1:Singleton} (\\${2:argument}) {\n\t\t// the cached instance\n\t\tvar instance;\n\n\t\t// rewrite the constructor\n\t\t\\$1 = function \\$1(\\$2) {\n\t\t\treturn instance;\n\t\t};\n\t\t\n\t\t// carry over the prototype properties\n\t\t\\$1.prototype = this;\n\n\t\t// the instance\n\t\tinstance = new \\$1();\n\n\t\t// reset the constructor pointer\n\t\tinstance.constructor = \\$1;\n\n\t\t\\${3:// code ...}\n\n\t\treturn instance;\n\t}\n# class\nsnippet class\nregex /^\\\\s*/clas{0,2}/\n\tvar \\${1:class} = function(\\${20}) {\n\t\t\\$40\\$0\n\t};\n\t\n\t(function() {\n\t\t\\${60:this.prop = \"\"}\n\t}).call(\\${1:class}.prototype);\n\t\n\texports.\\${1:class} = \\${1:class};\n# \nsnippet for-\n\tfor (var \\${1:i} = \\${2:Things}.length; \\${1:i}--; ) {\n\t\t\\${0:\\${2:Things}[\\${1:i}];}\n\t}\n# for (...) {...}\nsnippet for\n\tfor (var \\${1:i} = 0; \\$1 < \\${2:Things}.length; \\$1++) {\n\t\t\\${3:\\$2[\\$1]}\\$0\n\t}\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n\tfor (var \\${1:i} = \\${2:Things}.length - 1; \\$1 >= 0; \\$1--) {\n\t\t\\${3:\\$2[\\$1]}\\$0\n\t}\n\n\n#modules\nsnippet def\n\tdefin\\x65(function(requir\\x65, exports, module) {\n\t\"use strict\";\n\tvar \\${1/.*\\\\///} = requir\\x65(\"\\${1}\");\n\t\n\t\\$TM_SELECTED_TEXT\n\t});\nsnippet req\nguard ^\\\\s*\n\tvar \\${1/.*\\\\///} = requir\\x65(\"\\${1}\");\n\t\\$0\nsnippet requ\nguard ^\\\\s*\n\tvar \\${1/.*\\\\/(.)/\\\\u\\$1/} = requir\\x65(\"\\${1}\").\\${1/.*\\\\/(.)/\\\\u\\$1/};\n\t\\$0\n`;\n"
  },
  {
    "path": "src/snippets/jsp.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./jsp.snippets\");\nexports.scope = \"jsp\";\n"
  },
  {
    "path": "src/snippets/jsp.snippets.js",
    "content": "module.exports = `snippet @page\n\t<%@page contentType=\"text/html\" pageEncoding=\"UTF-8\"%>\nsnippet jstl\n\t<%@ taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\n\t<%@ taglib uri=\"http://java.sun.com/jsp/jstl/functions\" prefix=\"fn\" %>\nsnippet jstl:c\n\t<%@ taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\nsnippet jstl:fn\n\t<%@ taglib uri=\"http://java.sun.com/jsp/jstl/functions\" prefix=\"fn\" %>\nsnippet cpath\n\t\\${pageContext.request.contextPath}\nsnippet cout\n\t<c:out value=\"\\${1}\" default=\"\\${2}\" />\nsnippet cset\n\t<c:set var=\"\\${1}\" value=\"\\${2}\" />\nsnippet cremove\n\t<c:remove var=\"\\${1}\" scope=\"\\${2:page}\" />\nsnippet ccatch\n\t<c:catch var=\"\\${1}\" />\nsnippet cif\n\t<c:if test=\"\\${\\${1}}\">\n\t\t\\${2}\n\t</c:if>\nsnippet cchoose\n\t<c:choose>\n\t\t\\${1}\n\t</c:choose>\nsnippet cwhen\n\t<c:when test=\"\\${\\${1}}\">\n\t\t\\${2}\n\t</c:when>\nsnippet cother\n\t<c:otherwise>\n\t\t\\${1}\n\t</c:otherwise>\nsnippet cfore\n\t<c:forEach items=\"\\${\\${1}}\" var=\"\\${2}\" varStatus=\"\\${3}\">\n\t\t\\${4:<c:out value=\"\\$2\" />}\n\t</c:forEach>\nsnippet cfort\n\t<c:set var=\"\\${1}\">\\${2:item1,item2,item3}</c:set>\n\t<c:forTokens var=\"\\${3}\" items=\"\\${\\$1}\" delims=\"\\${4:,}\">\n\t\t\\${5:<c:out value=\"\\$3\" />}\n\t</c:forTokens>\nsnippet cparam\n\t<c:param name=\"\\${1}\" value=\"\\${2}\" />\nsnippet cparam+\n\t<c:param name=\"\\${1}\" value=\"\\${2}\" />\n\tcparam+\\${3}\nsnippet cimport\n\t<c:import url=\"\\${1}\" />\nsnippet cimport+\n\t<c:import url=\"\\${1}\">\n\t\t<c:param name=\"\\${2}\" value=\"\\${3}\" />\n\t\tcparam+\\${4}\n\t</c:import>\nsnippet curl\n\t<c:url value=\"\\${1}\" var=\"\\${2}\" />\n\t<a href=\"\\${\\$2}\">\\${3}</a>\nsnippet curl+\n\t<c:url value=\"\\${1}\" var=\"\\${2}\">\n\t\t<c:param name=\"\\${4}\" value=\"\\${5}\" />\n\t\tcparam+\\${6}\n\t</c:url>\n\t<a href=\"\\${\\$2}\">\\${3}</a>\nsnippet credirect\n\t<c:redirect url=\"\\${1}\" />\nsnippet contains\n\t\\${fn:contains(\\${1:string}, \\${2:substr})}\nsnippet contains:i\n\t\\${fn:containsIgnoreCase(\\${1:string}, \\${2:substr})}\nsnippet endswith\n\t\\${fn:endsWith(\\${1:string}, \\${2:suffix})}\nsnippet escape\n\t\\${fn:escapeXml(\\${1:string})}\nsnippet indexof\n\t\\${fn:indexOf(\\${1:string}, \\${2:substr})}\nsnippet join\n\t\\${fn:join(\\${1:collection}, \\${2:delims})}\nsnippet length\n\t\\${fn:length(\\${1:collection_or_string})}\nsnippet replace\n\t\\${fn:replace(\\${1:string}, \\${2:substr}, \\${3:replace})}\nsnippet split\n\t\\${fn:split(\\${1:string}, \\${2:delims})}\nsnippet startswith\n\t\\${fn:startsWith(\\${1:string}, \\${2:prefix})}\nsnippet substr\n\t\\${fn:substring(\\${1:string}, \\${2:begin}, \\${3:end})}\nsnippet substr:a\n\t\\${fn:substringAfter(\\${1:string}, \\${2:substr})}\nsnippet substr:b\n\t\\${fn:substringBefore(\\${1:string}, \\${2:substr})}\nsnippet lc\n\t\\${fn:toLowerCase(\\${1:string})}\nsnippet uc\n\t\\${fn:toUpperCase(\\${1:string})}\nsnippet trim\n\t\\${fn:trim(\\${1:string})}\n`;\n"
  },
  {
    "path": "src/snippets/liquid.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./liquid.snippets\");\nexports.scope = \"liquid\";\n"
  },
  {
    "path": "src/snippets/liquid.snippets.js",
    "content": "module.exports = `\n# liquid specific snippets\nsnippet ife\n\t{% if \\${1:condition} %}\n\n\t{% else %}\n\n\t{% endif %}\nsnippet if\n\t{% if \\${1:condition} %}\n\t\t\n\t{% endif %}\nsnippet for\n\t{% for in \\${1:iterator} %}\n\n\t{% endfor %}\nsnippet capture\n\t{% capture \\${1} %}\n\n\t{% endcapture %}\nsnippet comment\n\t{% comment %}\n\t  \\${1:comment}\n\t{% endcomment %}\n\n# Include html.snippets\n# Some useful Unicode entities\n# Non-Breaking Space\nsnippet nbs\n\t&nbsp;\n# ←\nsnippet left\n\t&#x2190;\n# →\nsnippet right\n\t&#x2192;\n# ↑\nsnippet up\n\t&#x2191;\n# ↓\nsnippet down\n\t&#x2193;\n# ↩\nsnippet return\n\t&#x21A9;\n# ⇤\nsnippet backtab\n\t&#x21E4;\n# ⇥\nsnippet tab\n\t&#x21E5;\n# ⇧\nsnippet shift\n\t&#x21E7;\n# ⌃\nsnippet ctrl\n\t&#x2303;\n# ⌅\nsnippet enter\n\t&#x2305;\n# ⌘\nsnippet cmd\n\t&#x2318;\n# ⌥\nsnippet option\n\t&#x2325;\n# ⌦\nsnippet delete\n\t&#x2326;\n# ⌫\nsnippet backspace\n\t&#x232B;\n# ⎋\nsnippet esc\n\t&#x238B;\n# Generic Doctype\nsnippet doctype HTML 4.01 Strict\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\t\"http://www.w3.org/TR/html4/strict.dtd\">\nsnippet doctype HTML 4.01 Transitional\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\t\"http://www.w3.org/TR/html4/loose.dtd\">\nsnippet doctype HTML 5\n\t<!DOCTYPE HTML>\nsnippet doctype XHTML 1.0 Frameset\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\nsnippet doctype XHTML 1.0 Strict\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\nsnippet doctype XHTML 1.0 Transitional\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\nsnippet doctype XHTML 1.1\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n\t\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n# HTML Doctype 4.01 Strict\nsnippet docts\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\t\"http://www.w3.org/TR/html4/strict.dtd\">\n# HTML Doctype 4.01 Transitional\nsnippet doct\n\t<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\t\"http://www.w3.org/TR/html4/loose.dtd\">\n# HTML Doctype 5\nsnippet doct5\n\t<!DOCTYPE html>\n# XHTML Doctype 1.0 Frameset\nsnippet docxf\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n# XHTML Doctype 1.0 Strict\nsnippet docxs\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n# XHTML Doctype 1.0 Transitional\nsnippet docxt\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n# XHTML Doctype 1.1\nsnippet docx\n\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n\t\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n# html5shiv\nsnippet html5shiv\n\t<!--[if lte IE 8]>\n\t\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js\"></script>\n\t<![endif]-->\nsnippet html5printshiv\n\t<!--[if lte IE 8]>\n\t\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js\"></script>\n\t<![endif]-->\n# Attributes\nsnippet attr\n\t\\${1:attribute}=\"\\${2:property}\"\nsnippet attr+\n\t\\${1:attribute}=\"\\${2:property}\" attr+\\${3}\nsnippet .\n\tclass=\"\\${1}\"\\${2}\nsnippet #\n\tid=\"\\${1}\"\\${2}\nsnippet alt\n\talt=\"\\${1}\"\\${2}\nsnippet charset\n\tcharset=\"\\${1:utf-8}\"\\${2}\nsnippet data\n\tdata-\\${1}=\"\\${2:\\$1}\"\\${3}\nsnippet for\n\tfor=\"\\${1}\"\\${2}\nsnippet height\n\theight=\"\\${1}\"\\${2}\nsnippet href\n\thref=\"\\${1:#}\"\\${2}\nsnippet lang\n\tlang=\"\\${1:en}\"\\${2}\nsnippet media\n\tmedia=\"\\${1}\"\\${2}\nsnippet name\n\tname=\"\\${1}\"\\${2}\nsnippet rel\n\trel=\"\\${1}\"\\${2}\nsnippet scope\n\tscope=\"\\${1:row}\"\\${2}\nsnippet src\n\tsrc=\"\\${1}\"\\${2}\nsnippet title=\n\ttitle=\"\\${1}\"\\${2}\nsnippet type\n\ttype=\"\\${1}\"\\${2}\nsnippet value\n\tvalue=\"\\${1}\"\\${2}\nsnippet width\n\twidth=\"\\${1}\"\\${2}\n# Elements\nsnippet a\n\t<a href=\"\\${1:#}\">\\${2:\\$1}</a>\nsnippet a.\n\t<a class=\"\\${1}\" href=\"\\${2:#}\">\\${3:\\$1}</a>\nsnippet a#\n\t<a id=\"\\${1}\" href=\"\\${2:#}\">\\${3:\\$1}</a>\nsnippet a:ext\n\t<a href=\"http://\\${1:example.com}\">\\${2:\\$1}</a>\nsnippet a:mail\n\t<a href=\"mailto:\\${1:joe@example.com}?subject=\\${2:feedback}\">\\${3:email me}</a>\nsnippet abbr\n\t<abbr title=\"\\${1}\">\\${2}</abbr>\nsnippet address\n\t<address>\n\t\t\\${1}\n\t</address>\nsnippet area\n\t<area shape=\"\\${1:rect}\" coords=\"\\${2}\" href=\"\\${3}\" alt=\"\\${4}\" />\nsnippet area+\n\t<area shape=\"\\${1:rect}\" coords=\"\\${2}\" href=\"\\${3}\" alt=\"\\${4}\" />\n\tarea+\\${5}\nsnippet area:c\n\t<area shape=\"circle\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:d\n\t<area shape=\"default\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:p\n\t<area shape=\"poly\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet area:r\n\t<area shape=\"rect\" coords=\"\\${1}\" href=\"\\${2}\" alt=\"\\${3}\" />\nsnippet article\n\t<article>\n\t\t\\${1}\n\t</article>\nsnippet article.\n\t<article class=\"\\${1}\">\n\t\t\\${2}\n\t</article>\nsnippet article#\n\t<article id=\"\\${1}\">\n\t\t\\${2}\n\t</article>\nsnippet aside\n\t<aside>\n\t\t\\${1}\n\t</aside>\nsnippet aside.\n\t<aside class=\"\\${1}\">\n\t\t\\${2}\n\t</aside>\nsnippet aside#\n\t<aside id=\"\\${1}\">\n\t\t\\${2}\n\t</aside>\nsnippet audio\n\t<audio src=\"\\${1}>\\${2}</audio>\nsnippet b\n\t<b>\\${1}</b>\nsnippet base\n\t<base href=\"\\${1}\" target=\"\\${2}\" />\nsnippet bdi\n\t<bdi>\\${1}</bdo>\nsnippet bdo\n\t<bdo dir=\"\\${1}\">\\${2}</bdo>\nsnippet bdo:l\n\t<bdo dir=\"ltr\">\\${1}</bdo>\nsnippet bdo:r\n\t<bdo dir=\"rtl\">\\${1}</bdo>\nsnippet blockquote\n\t<blockquote>\n\t\t\\${1}\n\t</blockquote>\nsnippet body\n\t<body>\n\t\t\\${1}\n\t</body>\nsnippet br\n\t<br />\\${1}\nsnippet button\n\t<button type=\"\\${1:submit}\">\\${2}</button>\nsnippet button.\n\t<button class=\"\\${1:button}\" type=\"\\${2:submit}\">\\${3}</button>\nsnippet button#\n\t<button id=\"\\${1}\" type=\"\\${2:submit}\">\\${3}</button>\nsnippet button:s\n\t<button type=\"submit\">\\${1}</button>\nsnippet button:r\n\t<button type=\"reset\">\\${1}</button>\nsnippet canvas\n\t<canvas>\n\t\t\\${1}\n\t</canvas>\nsnippet caption\n\t<caption>\\${1}</caption>\nsnippet cite\n\t<cite>\\${1}</cite>\nsnippet code\n\t<code>\\${1}</code>\nsnippet col\n\t<col />\\${1}\nsnippet col+\n\t<col />\n\tcol+\\${1}\nsnippet colgroup\n\t<colgroup>\n\t\t\\${1}\n\t</colgroup>\nsnippet colgroup+\n\t<colgroup>\n\t\t<col />\n\t\tcol+\\${1}\n\t</colgroup>\nsnippet command\n\t<command type=\"command\" label=\"\\${1}\" icon=\"\\${2}\" />\nsnippet command:c\n\t<command type=\"checkbox\" label=\"\\${1}\" icon=\"\\${2}\" />\nsnippet command:r\n\t<command type=\"radio\" radiogroup=\"\\${1}\" label=\"\\${2}\" icon=\"\\${3}\" />\nsnippet datagrid\n\t<datagrid>\n\t\t\\${1}\n\t</datagrid>\nsnippet datalist\n\t<datalist>\n\t\t\\${1}\n\t</datalist>\nsnippet datatemplate\n\t<datatemplate>\n\t\t\\${1}\n\t</datatemplate>\nsnippet dd\n\t<dd>\\${1}</dd>\nsnippet dd.\n\t<dd class=\"\\${1}\">\\${2}</dd>\nsnippet dd#\n\t<dd id=\"\\${1}\">\\${2}</dd>\nsnippet del\n\t<del>\\${1}</del>\nsnippet details\n\t<details>\\${1}</details>\nsnippet dfn\n\t<dfn>\\${1}</dfn>\nsnippet dialog\n\t<dialog>\n\t\t\\${1}\n\t</dialog>\nsnippet div\n\t<div>\n\t\t\\${1}\n\t</div>\nsnippet div.\n\t<div class=\"\\${1}\">\n\t\t\\${2}\n\t</div>\nsnippet div#\n\t<div id=\"\\${1}\">\n\t\t\\${2}\n\t</div>\nsnippet dl\n\t<dl>\n\t\t\\${1}\n\t</dl>\nsnippet dl.\n\t<dl class=\"\\${1}\">\n\t\t\\${2}\n\t</dl>\nsnippet dl#\n\t<dl id=\"\\${1}\">\n\t\t\\${2}\n\t</dl>\nsnippet dl+\n\t<dl>\n\t\t<dt>\\${1}</dt>\n\t\t<dd>\\${2}</dd>\n\t\tdt+\\${3}\n\t</dl>\nsnippet dt\n\t<dt>\\${1}</dt>\nsnippet dt.\n\t<dt class=\"\\${1}\">\\${2}</dt>\nsnippet dt#\n\t<dt id=\"\\${1}\">\\${2}</dt>\nsnippet dt+\n\t<dt>\\${1}</dt>\n\t<dd>\\${2}</dd>\n\tdt+\\${3}\nsnippet em\n\t<em>\\${1}</em>\nsnippet embed\n\t<embed src=\\${1} type=\"\\${2} />\nsnippet fieldset\n\t<fieldset>\n\t\t\\${1}\n\t</fieldset>\nsnippet fieldset.\n\t<fieldset class=\"\\${1}\">\n\t\t\\${2}\n\t</fieldset>\nsnippet fieldset#\n\t<fieldset id=\"\\${1}\">\n\t\t\\${2}\n\t</fieldset>\nsnippet fieldset+\n\t<fieldset>\n\t\t<legend><span>\\${1}</span></legend>\n\t\t\\${2}\n\t</fieldset>\n\tfieldset+\\${3}\nsnippet figcaption\n\t<figcaption>\\${1}</figcaption>\nsnippet figure\n\t<figure>\\${1}</figure>\nsnippet footer\n\t<footer>\n\t\t\\${1}\n\t</footer>\nsnippet footer.\n\t<footer class=\"\\${1}\">\n\t\t\\${2}\n\t</footer>\nsnippet footer#\n\t<footer id=\"\\${1}\">\n\t\t\\${2}\n\t</footer>\nsnippet form\n\t<form action=\"\\${1}\" method=\"\\${2:get}\" accept-charset=\"utf-8\">\n\t\t\\${3}\n\t</form>\nsnippet form.\n\t<form class=\"\\${1}\" action=\"\\${2}\" method=\"\\${3:get}\" accept-charset=\"utf-8\">\n\t\t\\${4}\n\t</form>\nsnippet form#\n\t<form id=\"\\${1}\" action=\"\\${2}\" method=\"\\${3:get}\" accept-charset=\"utf-8\">\n\t\t\\${4}\n\t</form>\nsnippet h1\n\t<h1>\\${1}</h1>\nsnippet h1.\n\t<h1 class=\"\\${1}\">\\${2}</h1>\nsnippet h1#\n\t<h1 id=\"\\${1}\">\\${2}</h1>\nsnippet h2\n\t<h2>\\${1}</h2>\nsnippet h2.\n\t<h2 class=\"\\${1}\">\\${2}</h2>\nsnippet h2#\n\t<h2 id=\"\\${1}\">\\${2}</h2>\nsnippet h3\n\t<h3>\\${1}</h3>\nsnippet h3.\n\t<h3 class=\"\\${1}\">\\${2}</h3>\nsnippet h3#\n\t<h3 id=\"\\${1}\">\\${2}</h3>\nsnippet h4\n\t<h4>\\${1}</h4>\nsnippet h4.\n\t<h4 class=\"\\${1}\">\\${2}</h4>\nsnippet h4#\n\t<h4 id=\"\\${1}\">\\${2}</h4>\nsnippet h5\n\t<h5>\\${1}</h5>\nsnippet h5.\n\t<h5 class=\"\\${1}\">\\${2}</h5>\nsnippet h5#\n\t<h5 id=\"\\${1}\">\\${2}</h5>\nsnippet h6\n\t<h6>\\${1}</h6>\nsnippet h6.\n\t<h6 class=\"\\${1}\">\\${2}</h6>\nsnippet h6#\n\t<h6 id=\"\\${1}\">\\${2}</h6>\nsnippet head\n\t<head>\n\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\n\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\\${2}\n\t</head>\nsnippet header\n\t<header>\n\t\t\\${1}\n\t</header>\nsnippet header.\n\t<header class=\"\\${1}\">\n\t\t\\${2}\n\t</header>\nsnippet header#\n\t<header id=\"\\${1}\">\n\t\t\\${2}\n\t</header>\nsnippet hgroup\n\t<hgroup>\n\t\t\\${1}\n\t</hgroup>\nsnippet hgroup.\n\t<hgroup class=\"\\${1}>\n\t\t\\${2}\n\t</hgroup>\nsnippet hr\n\t<hr />\\${1}\nsnippet html\n\t<html>\n\t\\${1}\n\t</html>\nsnippet xhtml\n\t<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\\${1}\n\t</html>\nsnippet html5\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\t\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\t\\${2:meta}\n\t\t</head>\n\t\t<body>\n\t\t\t\\${3:body}\n\t\t</body>\n\t</html>\nsnippet xhtml5\n\t<!DOCTYPE html>\n\t<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\t<head>\n\t\t\t<meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=utf-8\" />\n\t\t\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\n\t\t\t\\${2:meta}\n\t\t</head>\n\t\t<body>\n\t\t\t\\${3:body}\n\t\t</body>\n\t</html>\nsnippet i\n\t<i>\\${1}</i>\nsnippet iframe\n\t<iframe src=\"\\${1}\" frameborder=\"0\"></iframe>\\${2}\nsnippet iframe.\n\t<iframe class=\"\\${1}\" src=\"\\${2}\" frameborder=\"0\"></iframe>\\${3}\nsnippet iframe#\n\t<iframe id=\"\\${1}\" src=\"\\${2}\" frameborder=\"0\"></iframe>\\${3}\nsnippet img\n\t<img src=\"\\${1}\" alt=\"\\${2}\" />\\${3}\nsnippet img.\n\t<img class=\"\\${1}\" src=\"\\${2}\" alt=\"\\${3}\" />\\${4}\nsnippet img#\n\t<img id=\"\\${1}\" src=\"\\${2}\" alt=\"\\${3}\" />\\${4}\nsnippet input\n\t<input type=\"\\${1:text/submit/hidden/button/image}\" name=\"\\${2}\" id=\"\\${3:\\$2}\" value=\"\\${4}\" />\\${5}\nsnippet input.\n\t<input class=\"\\${1}\" type=\"\\${2:text/submit/hidden/button/image}\" name=\"\\${3}\" id=\"\\${4:\\$3}\" value=\"\\${5}\" />\\${6}\nsnippet input:text\n\t<input type=\"text\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:submit\n\t<input type=\"submit\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:hidden\n\t<input type=\"hidden\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:button\n\t<input type=\"button\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:image\n\t<input type=\"image\" name=\"\\${1}\" id=\"\\${2:\\$1}\" src=\"\\${3}\" alt=\"\\${4}\" />\\${5}\nsnippet input:checkbox\n\t<input type=\"checkbox\" name=\"\\${1}\" id=\"\\${2:\\$1}\" />\\${3}\nsnippet input:radio\n\t<input type=\"radio\" name=\"\\${1}\" id=\"\\${2:\\$1}\" />\\${3}\nsnippet input:color\n\t<input type=\"color\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:date\n\t<input type=\"date\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:datetime\n\t<input type=\"datetime\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:datetime-local\n\t<input type=\"datetime-local\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:email\n\t<input type=\"email\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:file\n\t<input type=\"file\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:month\n\t<input type=\"month\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:number\n\t<input type=\"number\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:password\n\t<input type=\"password\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:range\n\t<input type=\"range\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:reset\n\t<input type=\"reset\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:search\n\t<input type=\"search\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:time\n\t<input type=\"time\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:url\n\t<input type=\"url\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet input:week\n\t<input type=\"week\" name=\"\\${1}\" id=\"\\${2:\\$1}\" value=\"\\${3}\" />\\${4}\nsnippet ins\n\t<ins>\\${1}</ins>\nsnippet kbd\n\t<kbd>\\${1}</kbd>\nsnippet keygen\n\t<keygen>\\${1}</keygen>\nsnippet label\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\nsnippet label:i\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\n\t<input type=\"\\${3:text/submit/hidden/button}\" name=\"\\${4:\\$2}\" id=\"\\${5:\\$2}\" value=\"\\${6}\" />\\${7}\nsnippet label:s\n\t<label for=\"\\${2:\\$1}\">\\${1}</label>\n\t<select name=\"\\${3:\\$2}\" id=\"\\${4:\\$2}\">\n\t\t<option value=\"\\${5}\">\\${6:\\$5}</option>\n\t</select>\nsnippet legend\n\t<legend>\\${1}</legend>\nsnippet legend+\n\t<legend><span>\\${1}</span></legend>\nsnippet li\n\t<li>\\${1}</li>\nsnippet li.\n\t<li class=\"\\${1}\">\\${2}</li>\nsnippet li+\n\t<li>\\${1}</li>\n\tli+\\${2}\nsnippet lia\n\t<li><a href=\"\\${2:#}\">\\${1}</a></li>\nsnippet lia+\n\t<li><a href=\"\\${2:#}\">\\${1}</a></li>\n\tlia+\\${3}\nsnippet link\n\t<link rel=\"\\${1}\" href=\"\\${2}\" title=\"\\${3}\" type=\"\\${4}\" />\\${5}\nsnippet link:atom\n\t<link rel=\"alternate\" href=\"\\${1:atom.xml}\" title=\"Atom\" type=\"application/atom+xml\" />\\${2}\nsnippet link:css\n\t<link rel=\"stylesheet\" href=\"\\${2:style.css}\" type=\"text/css\" media=\"\\${3:all}\" />\\${4}\nsnippet link:favicon\n\t<link rel=\"shortcut icon\" href=\"\\${1:favicon.ico}\" type=\"image/x-icon\" />\\${2}\nsnippet link:rss\n\t<link rel=\"alternate\" href=\"\\${1:rss.xml}\" title=\"RSS\" type=\"application/atom+xml\" />\\${2}\nsnippet link:touch\n\t<link rel=\"apple-touch-icon\" href=\"\\${1:favicon.png}\" />\\${2}\nsnippet map\n\t<map name=\"\\${1}\">\n\t\t\\${2}\n\t</map>\nsnippet map.\n\t<map class=\"\\${1}\" name=\"\\${2}\">\n\t\t\\${3}\n\t</map>\nsnippet map#\n\t<map name=\"\\${1}\" id=\"\\${2:\\$1}>\n\t\t\\${3}\n\t</map>\nsnippet map+\n\t<map name=\"\\${1}\">\n\t\t<area shape=\"\\${2}\" coords=\"\\${3}\" href=\"\\${4}\" alt=\"\\${5}\" />\\${6}\n\t</map>\\${7}\nsnippet mark\n\t<mark>\\${1}</mark>\nsnippet menu\n\t<menu>\n\t\t\\${1}\n\t</menu>\nsnippet menu:c\n\t<menu type=\"context\">\n\t\t\\${1}\n\t</menu>\nsnippet menu:t\n\t<menu type=\"toolbar\">\n\t\t\\${1}\n\t</menu>\nsnippet meta\n\t<meta http-equiv=\"\\${1}\" content=\"\\${2}\" />\\${3}\nsnippet meta:compat\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=\\${1:7,8,edge}\" />\\${3}\nsnippet meta:refresh\n\t<meta http-equiv=\"refresh\" content=\"text/html;charset=UTF-8\" />\\${3}\nsnippet meta:utf\n\t<meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\" />\\${3}\nsnippet meter\n\t<meter>\\${1}</meter>\nsnippet nav\n\t<nav>\n\t\t\\${1}\n\t</nav>\nsnippet nav.\n\t<nav class=\"\\${1}\">\n\t\t\\${2}\n\t</nav>\nsnippet nav#\n\t<nav id=\"\\${1}\">\n\t\t\\${2}\n\t</nav>\nsnippet noscript\n\t<noscript>\n\t\t\\${1}\n\t</noscript>\nsnippet object\n\t<object data=\"\\${1}\" type=\"\\${2}\">\n\t\t\\${3}\n\t</object>\\${4}\n# Embed QT Movie\nsnippet movie\n\t<object width=\"\\$2\" height=\"\\$3\" classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\"\n\t codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\">\n\t\t<param name=\"src\" value=\"\\$1\" />\n\t\t<param name=\"controller\" value=\"\\$4\" />\n\t\t<param name=\"autoplay\" value=\"\\$5\" />\n\t\t<embed src=\"\\${1:movie.mov}\"\n\t\t\twidth=\"\\${2:320}\" height=\"\\${3:240}\"\n\t\t\tcontroller=\"\\${4:true}\" autoplay=\"\\${5:true}\"\n\t\t\tscale=\"tofit\" cache=\"true\"\n\t\t\tpluginspage=\"http://www.apple.com/quicktime/download/\" />\n\t</object>\\${6}\nsnippet ol\n\t<ol>\n\t\t\\${1}\n\t</ol>\nsnippet ol.\n\t<ol class=\"\\${1}>\n\t\t\\${2}\n\t</ol>\nsnippet ol#\n\t<ol id=\"\\${1}>\n\t\t\\${2}\n\t</ol>\nsnippet ol+\n\t<ol>\n\t\t<li>\\${1}</li>\n\t\tli+\\${2}\n\t</ol>\nsnippet opt\n\t<option value=\"\\${1}\">\\${2:\\$1}</option>\nsnippet opt+\n\t<option value=\"\\${1}\">\\${2:\\$1}</option>\n\topt+\\${3}\nsnippet optt\n\t<option>\\${1}</option>\nsnippet optgroup\n\t<optgroup>\n\t\t<option value=\"\\${1}\">\\${2:\\$1}</option>\n\t\topt+\\${3}\n\t</optgroup>\nsnippet output\n\t<output>\\${1}</output>\nsnippet p\n\t<p>\\${1}</p>\nsnippet param\n\t<param name=\"\\${1}\" value=\"\\${2}\" />\\${3}\nsnippet pre\n\t<pre>\n\t\t\\${1}\n\t</pre>\nsnippet progress\n\t<progress>\\${1}</progress>\nsnippet q\n\t<q>\\${1}</q>\nsnippet rp\n\t<rp>\\${1}</rp>\nsnippet rt\n\t<rt>\\${1}</rt>\nsnippet ruby\n\t<ruby>\n\t\t<rp><rt>\\${1}</rt></rp>\n\t</ruby>\nsnippet s\n\t<s>\\${1}</s>\nsnippet samp\n\t<samp>\n\t\t\\${1}\n\t</samp>\nsnippet script\n\t<script type=\"text/javascript\" charset=\"utf-8\">\n\t\t\\${1}\n\t</script>\nsnippet scriptsrc\n\t<script src=\"\\${1}.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\nsnippet newscript\n\t<script type=\"application/javascript\" charset=\"utf-8\">\n\t\t\\${1}\n\t</script>\nsnippet newscriptsrc\n\t<script src=\"\\${1}.js\" type=\"application/javascript\" charset=\"utf-8\"></script>\nsnippet section\n\t<section>\n\t\t\\${1}\n\t</section>\nsnippet section.\n\t<section class=\"\\${1}\">\n\t\t\\${2}\n\t</section>\nsnippet section#\n\t<section id=\"\\${1}\">\n\t\t\\${2}\n\t</section>\nsnippet select\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\">\n\t\t\\${3}\n\t</select>\nsnippet select.\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\" class=\"\\${3}>\n\t\t\\${4}\n\t</select>\nsnippet select+\n\t<select name=\"\\${1}\" id=\"\\${2:\\$1}\">\n\t\t<option value=\"\\${3}\">\\${4:\\$3}</option>\n\t\topt+\\${5}\n\t</select>\nsnippet small\n\t<small>\\${1}</small>\nsnippet source\n\t<source src=\"\\${1}\" type=\"\\${2}\" media=\"\\${3}\" />\nsnippet span\n\t<span>\\${1}</span>\nsnippet strong\n\t<strong>\\${1}</strong>\nsnippet style\n\t<style type=\"text/css\" media=\"\\${1:all}\">\n\t\t\\${2}\n\t</style>\nsnippet sub\n\t<sub>\\${1}</sub>\nsnippet summary\n\t<summary>\n\t\t\\${1}\n\t</summary>\nsnippet sup\n\t<sup>\\${1}</sup>\nsnippet table\n\t<table border=\"\\${1:0}\">\n\t\t\\${2}\n\t</table>\nsnippet table.\n\t<table class=\"\\${1}\" border=\"\\${2:0}\">\n\t\t\\${3}\n\t</table>\nsnippet table#\n\t<table id=\"\\${1}\" border=\"\\${2:0}\">\n\t\t\\${3}\n\t</table>\nsnippet tbody\n\t<tbody>\n\t\t\\${1}\n\t</tbody>\nsnippet td\n\t<td>\\${1}</td>\nsnippet td.\n\t<td class=\"\\${1}\">\\${2}</td>\nsnippet td#\n\t<td id=\"\\${1}\">\\${2}</td>\nsnippet td+\n\t<td>\\${1}</td>\n\ttd+\\${2}\nsnippet textarea\n\t<textarea name=\"\\${1}\" id=\\${2:\\$1} rows=\"\\${3:8}\" cols=\"\\${4:40}\">\\${5}</textarea>\\${6}\nsnippet tfoot\n\t<tfoot>\n\t\t\\${1}\n\t</tfoot>\nsnippet th\n\t<th>\\${1}</th>\nsnippet th.\n\t<th class=\"\\${1}\">\\${2}</th>\nsnippet th#\n\t<th id=\"\\${1}\">\\${2}</th>\nsnippet th+\n\t<th>\\${1}</th>\n\tth+\\${2}\nsnippet thead\n\t<thead>\n\t\t\\${1}\n\t</thead>\nsnippet time\n\t<time datetime=\"\\${1}\" pubdate=\"\\${2:\\$1}>\\${3:\\$1}</time>\nsnippet title\n\t<title>\\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`}</title>\nsnippet tr\n\t<tr>\n\t\t\\${1}\n\t</tr>\nsnippet tr+\n\t<tr>\n\t\t<td>\\${1}</td>\n\t\ttd+\\${2}\n\t</tr>\nsnippet track\n\t<track src=\"\\${1}\" srclang=\"\\${2}\" label=\"\\${3}\" default=\"\\${4:default}>\\${5}</track>\\${6}\nsnippet ul\n\t<ul>\n\t\t\\${1}\n\t</ul>\nsnippet ul.\n\t<ul class=\"\\${1}\">\n\t\t\\${2}\n\t</ul>\nsnippet ul#\n\t<ul id=\"\\${1}\">\n\t\t\\${2}\n\t</ul>\nsnippet ul+\n\t<ul>\n\t\t<li>\\${1}</li>\n\t\tli+\\${2}\n\t</ul>\nsnippet var\n\t<var>\\${1}</var>\nsnippet video\n\t<video src=\"\\${1} height=\"\\${2}\" width=\"\\${3}\" preload=\"\\${5:none}\" autoplay=\"\\${6:autoplay}>\\${7}</video>\\${8}\nsnippet wbr\n\t<wbr />\\${1}\n`;\n"
  },
  {
    "path": "src/snippets/lsl.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./lsl.snippets\");\nexports.scope = \"lsl\";\n"
  },
  {
    "path": "src/snippets/lsl.snippets.js",
    "content": "module.exports = `snippet @\n\t@\\${1:label};\nsnippet CAMERA_ACTIVE\n\tCAMERA_ACTIVE, \\${1:integer isActive}, \\$0\nsnippet CAMERA_BEHINDNESS_ANGLE\n\tCAMERA_BEHINDNESS_ANGLE, \\${1:float degrees}, \\$0\nsnippet CAMERA_BEHINDNESS_LAG\n\tCAMERA_BEHINDNESS_LAG, \\${1:float seconds}, \\$0\nsnippet CAMERA_DISTANCE\n\tCAMERA_DISTANCE, \\${1:float meters}, \\$0\nsnippet CAMERA_FOCUS\n\tCAMERA_FOCUS, \\${1:vector position}, \\$0\nsnippet CAMERA_FOCUS_LAG\n\tCAMERA_FOCUS_LAG, \\${1:float seconds}, \\$0\nsnippet CAMERA_FOCUS_LOCKED\n\tCAMERA_FOCUS_LOCKED, \\${1:integer isLocked}, \\$0\nsnippet CAMERA_FOCUS_OFFSET\n\tCAMERA_FOCUS_OFFSET, \\${1:vector meters}, \\$0\nsnippet CAMERA_FOCUS_THRESHOLD\n\tCAMERA_FOCUS_THRESHOLD, \\${1:float meters}, \\$0\nsnippet CAMERA_PITCH\n\tCAMERA_PITCH, \\${1:float degrees}, \\$0\nsnippet CAMERA_POSITION\n\tCAMERA_POSITION, \\${1:vector position}, \\$0\nsnippet CAMERA_POSITION_LAG\n\tCAMERA_POSITION_LAG, \\${1:float seconds}, \\$0\nsnippet CAMERA_POSITION_LOCKED\n\tCAMERA_POSITION_LOCKED, \\${1:integer isLocked}, \\$0\nsnippet CAMERA_POSITION_THRESHOLD\n\tCAMERA_POSITION_THRESHOLD, \\${1:float meters}, \\$0\nsnippet CHARACTER_AVOIDANCE_MODE\n\tCHARACTER_AVOIDANCE_MODE, \\${1:integer flags}, \\$0\nsnippet CHARACTER_DESIRED_SPEED\n\tCHARACTER_DESIRED_SPEED, \\${1:float speed}, \\$0\nsnippet CHARACTER_DESIRED_TURN_SPEED\n\tCHARACTER_DESIRED_TURN_SPEED, \\${1:float speed}, \\$0\nsnippet CHARACTER_LENGTH\n\tCHARACTER_LENGTH, \\${1:float length}, \\$0\nsnippet CHARACTER_MAX_TURN_RADIUS\n\tCHARACTER_MAX_TURN_RADIUS, \\${1:float radius}, \\$0\nsnippet CHARACTER_ORIENTATION\n\tCHARACTER_ORIENTATION, \\${1:integer orientation}, \\$0\nsnippet CHARACTER_RADIUS\n\tCHARACTER_RADIUS, \\${1:float radius}, \\$0\nsnippet CHARACTER_STAY_WITHIN_PARCEL\n\tCHARACTER_STAY_WITHIN_PARCEL, \\${1:boolean stay}, \\$0\nsnippet CHARACTER_TYPE\n\tCHARACTER_TYPE, \\${1:integer type}, \\$0\nsnippet HTTP_BODY_MAXLENGTH\n\tHTTP_BODY_MAXLENGTH, \\${1:integer length}, \\$0\nsnippet HTTP_CUSTOM_HEADER\n\tHTTP_CUSTOM_HEADER, \\${1:string name}, \\${2:string value}, \\$0\nsnippet HTTP_METHOD\n\tHTTP_METHOD, \\${1:string method}, \\$0\nsnippet HTTP_MIMETYPE\n\tHTTP_MIMETYPE, \\${1:string mimeType}, \\$0\nsnippet HTTP_PRAGMA_NO_CACHE\n\tHTTP_PRAGMA_NO_CACHE, \\${1:integer send_header}, \\$0\nsnippet HTTP_VERBOSE_THROTTLE\n\tHTTP_VERBOSE_THROTTLE, \\${1:integer noisy}, \\$0\nsnippet HTTP_VERIFY_CERT\n\tHTTP_VERIFY_CERT, \\${1:integer verify}, \\$0\nsnippet RC_DATA_FLAGS\n\tRC_DATA_FLAGS, \\${1:integer flags}, \\$0\nsnippet RC_DETECT_PHANTOM\n\tRC_DETECT_PHANTOM, \\${1:integer dectedPhantom}, \\$0\nsnippet RC_MAX_HITS\n\tRC_MAX_HITS, \\${1:integer maxHits}, \\$0\nsnippet RC_REJECT_TYPES\n\tRC_REJECT_TYPES, \\${1:integer filterMask}, \\$0\nsnippet at_rot_target\n\tat_rot_target(\\${1:integer handle}, \\${2:rotation targetrot}, \\${3:rotation ourrot})\n\t{\n\t\t\\$0\n\t}\nsnippet at_target\n\tat_target(\\${1:integer tnum}, \\${2:vector targetpos}, \\${3:vector ourpos})\n\t{\n\t\t\\$0\n\t}\nsnippet attach\n\tattach(\\${1:key id})\n\t{\n\t\t\\$0\n\t}\nsnippet changed\n\tchanged(\\${1:integer change})\n\t{\n\t\t\\$0\n\t}\nsnippet collision\n\tcollision(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet collision_end\n\tcollision_end(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet collision_start\n\tcollision_start(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet control\n\tcontrol(\\${1:key id}, \\${2:integer level}, \\${3:integer edge})\n\t{\n\t\t\\$0\n\t}\nsnippet dataserver\n\tdataserver(\\${1:key query_id}, \\${2:string data})\n\t{\n\t\t\\$0\n\t}\nsnippet do\n\tdo\n\t{\n\t\t\\$0\n\t}\n\twhile (\\${1:condition});\nsnippet else\n\telse\n\t{\n\t\t\\$0\n\t}\nsnippet email\n\temail(\\${1:string time}, \\${2:string address}, \\${3:string subject}, \\${4:string message}, \\${5:integer num_left})\n\t{\n\t\t\\$0\n\t}\nsnippet experience_permissions\n\texperience_permissions(\\${1:key agent_id})\n\t{\n\t\t\\$0\n\t}\nsnippet experience_permissions_denied\n\texperience_permissions_denied(\\${1:key agent_id}, \\${2:integer reason})\n\t{\n\t\t\\$0\n\t}\nsnippet for\n\tfor (\\${1:start}; \\${3:condition}; \\${3:step})\n\t{\n\t\t\\$0\n\t}\nsnippet http_request\n\thttp_request(\\${1:key request_id}, \\${2:string method}, \\${3:string body})\n\t{\n\t\t\\$0\n\t}\nsnippet http_response\n\thttp_response(\\${1:key request_id}, \\${2:integer status}, \\${3:list metadata}, \\${4:string body})\n\t{\n\t\t\\$0\n\t}\nsnippet if\n\tif (\\${1:condition})\n\t{\n\t\t\\$0\n\t}\nsnippet jump\n\tjump \\${1:label};\nsnippet land_collision\n\tland_collision(\\${1:vector pos})\n\t{\n\t\t\\$0\n\t}\nsnippet land_collision_end\n\tland_collision_end(\\${1:vector pos})\n\t{\n\t\t\\$0\n\t}\nsnippet land_collision_start\n\tland_collision_start(\\${1:vector pos})\n\t{\n\t\t\\$0\n\t}\nsnippet link_message\n\tlink_message(\\${1:integer sender_num}, \\${2:integer num}, \\${3:string str}, \\${4:key id})\n\t{\n\t\t\\$0\n\t}\nsnippet listen\n\tlisten(\\${1:integer channel}, \\${2:string name}, \\${3:key id}, \\${4:string message})\n\t{\n\t\t\\$0\n\t}\nsnippet llAbs\n\tllAbs(\\${1:integer val})\nsnippet llAcos\n\tllAcos(\\${1:float val})\nsnippet llAddToLandBanList\n\tllAddToLandBanList(\\${1:key agent}, \\${2:float hours});\n\t\\$0\nsnippet llAddToLandPassList\n\tllAddToLandPassList(\\${1:key agent}, \\${2:float hours});\n\t\\$0\nsnippet llAdjustSoundVolume\n\tllAdjustSoundVolume(\\${1:float volume});\n\t\\$0\nsnippet llAgentInExperience\n\tllAgentInExperience(\\${1:key agent})\nsnippet llAllowInventoryDrop\n\tllAllowInventoryDrop(\\${1:integer add});\n\t\\$0\nsnippet llAngleBetween\n\tllAngleBetween(\\${1:rotation a}, \\${2:rotation b})\nsnippet llApplyImpulse\n\tllApplyImpulse(\\${1:vector force}, \\${2:integer local});\n\t\\$0\nsnippet llApplyRotationalImpulse\n\tllApplyRotationalImpulse(\\${1:vector force}, \\${2:integer local});\n\t\\$0\nsnippet llAsin\n\tllAsin(\\${1:float val})\nsnippet llAtan2\n\tllAtan2(\\${1:float y}, \\${2:float x})\nsnippet llAttachToAvatar\n\tllAttachToAvatar(\\${1:integer attach_point});\n\t\\$0\nsnippet llAttachToAvatarTemp\n\tllAttachToAvatarTemp(\\${1:integer attach_point});\n\t\\$0\nsnippet llAvatarOnLinkSitTarget\n\tllAvatarOnLinkSitTarget(\\${1:integer link})\nsnippet llAvatarOnSitTarget\n\tllAvatarOnSitTarget()\nsnippet llAxes2Rot\n\tllAxes2Rot(\\${1:vector fwd}, \\${2:vector left}, \\${3:vector up})\nsnippet llAxisAngle2Rot\n\tllAxisAngle2Rot(\\${1:vector axis}, \\${2:float angle})\nsnippet llBase64ToInteger\n\tllBase64ToInteger(\\${1:string str})\nsnippet llBase64ToString\n\tllBase64ToString(\\${1:string str})\nsnippet llBreakAllLinks\n\tllBreakAllLinks();\n\t\\$0\nsnippet llBreakLink\n\tllBreakLink(\\${1:integer link});\n\t\\$0\nsnippet llCastRay\n\tllCastRay(\\${1:vector start}, \\${2:vector end}, \\${3:list options});\n\t\\$0\nsnippet llCeil\n\tllCeil(\\${1:float val})\nsnippet llClearCameraParams\n\tllClearCameraParams();\n\t\\$0\nsnippet llClearLinkMedia\n\tllClearLinkMedia(\\${1:integer link}, \\${2:integer face});\n\t\\$0\nsnippet llClearPrimMedia\n\tllClearPrimMedia(\\${1:integer face});\n\t\\$0\nsnippet llCloseRemoteDataChannel\n\tllCloseRemoteDataChannel(\\${1:key channel});\n\t\\$0\nsnippet llCollisionFilter\n\tllCollisionFilter(\\${1:string name}, \\${2:key id}, \\${3:integer accept});\n\t\\$0\nsnippet llCollisionSound\n\tllCollisionSound(\\${1:string impact_sound}, \\${2:float impact_volume});\n\t\\$0\nsnippet llCos\n\tllCos(\\${1:float theta})\nsnippet llCreateCharacter\n\tllCreateCharacter(\\${1:list options});\n\t\\$0\nsnippet llCreateKeyValue\n\tllCreateKeyValue(\\${1:string k})\nsnippet llCreateLink\n\tllCreateLink(\\${1:key target}, \\${2:integer parent});\n\t\\$0\nsnippet llCSV2List\n\tllCSV2List(\\${1:string src})\nsnippet llDataSizeKeyValue\n\tllDataSizeKeyValue()\nsnippet llDeleteCharacter\n\tllDeleteCharacter();\n\t\\$0\nsnippet llDeleteKeyValue\n\tllDeleteKeyValue(\\${1:string k})\nsnippet llDeleteSubList\n\tllDeleteSubList(\\${1:list src}, \\${2:integer start}, \\${3:integer end})\nsnippet llDeleteSubString\n\tllDeleteSubString(\\${1:string src}, \\${2:integer start}, \\${3:integer end})\nsnippet llDetachFromAvatar\n\tllDetachFromAvatar();\n\t\\$0\nsnippet llDetectedGrab\n\tllDetectedGrab(\\${1:integer number})\nsnippet llDetectedGroup\n\tllDetectedGroup(\\${1:integer number})\nsnippet llDetectedKey\n\tllDetectedKey(\\${1:integer number})\nsnippet llDetectedLinkNumber\n\tllDetectedLinkNumber(\\${1:integer number})\nsnippet llDetectedName\n\tllDetectedName(\\${1:integer number})\nsnippet llDetectedOwner\n\tllDetectedOwner(\\${1:integer number})\nsnippet llDetectedPos\n\tllDetectedPosl(\\${1:integer number})\nsnippet llDetectedRot\n\tllDetectedRot(\\${1:integer number})\nsnippet llDetectedTouchBinormal\n\tllDetectedTouchBinormal(\\${1:integer number})\nsnippet llDetectedTouchFace\n\tllDetectedTouchFace(\\${1:integer number})\nsnippet llDetectedTouchNormal\n\tllDetectedTouchNormal(\\${1:integer number})\nsnippet llDetectedTouchPos\n\tllDetectedTouchPos(\\${1:integer number})\nsnippet llDetectedTouchST\n\tllDetectedTouchST(\\${1:integer number})\nsnippet llDetectedTouchUV\n\tllDetectedTouchUV(\\${1:integer number})\nsnippet llDetectedType\n\tllDetectedType(\\${1:integer number})\nsnippet llDetectedVel\n\tllDetectedVel(\\${1:integer number})\nsnippet llDialog\n\tllDialog(\\${1:key agent}, \\${2:string message}, \\${3:list buttons}, \\${4:integer channel});\n\t\\$0\nsnippet llDie\n\tllDie();\n\t\\$0\nsnippet llDumpList2String\n\tllDumpList2String(\\${1:list src}, \\${2:string separator})\nsnippet llEdgeOfWorld\n\tllEdgeOfWorld(\\${1:vector pos}, \\${2:vector dir})\nsnippet llEjectFromLand\n\tllEjectFromLand(\\${1:key agent});\n\t\\$0\nsnippet llEmail\n\tllEmail(\\${1:string address}, \\${2:string subject}, \\${3:string message});\n\t\\$0\nsnippet llEscapeURL\n\tllEscapeURL(\\${1:string url})\nsnippet llEuler2Rot\n\tllEuler2Rot(\\${1:vector v})\nsnippet llExecCharacterCmd\n\tllExecCharacterCmd(\\${1:integer command}, \\${2:list options});\n\t\\$0\nsnippet llEvade\n\tllEvade(\\${1:key target}, \\${2:list options});\n\t\\$0\nsnippet llFabs\n\tllFabs(\\${1:float val})\nsnippet llFleeFrom\n\tllFleeFrom(\\${1:vector position}, \\${2:float distance}, \\${3:list options});\n\t\\$0\nsnippet llFloor\n\tllFloor(\\${1:float val})\nsnippet llForceMouselook\n\tllForceMouselook(\\${1:integer mouselook});\n\t\\$0\nsnippet llFrand\n\tllFrand(\\${1:float mag})\nsnippet llGenerateKey\n\tllGenerateKey()\nsnippet llGetAccel\n\tllGetAccel()\nsnippet llGetAgentInfo\n\tllGetAgentInfo(\\${1:key id})\nsnippet llGetAgentLanguage\n\tllGetAgentLanguage(\\${1:key agent})\nsnippet llGetAgentList\n\tllGetAgentList(\\${1:integer scope}, \\${2:list options})\nsnippet llGetAgentSize\n\tllGetAgentSize(\\${1:key agent})\nsnippet llGetAlpha\n\tllGetAlpha(\\${1:integer face})\nsnippet llGetAndResetTime\n\tllGetAndResetTime()\nsnippet llGetAnimation\n\tllGetAnimation(\\${1:key id})\nsnippet llGetAnimationList\n\tllGetAnimationList(\\${1:key agent})\nsnippet llGetAnimationOverride\n\tllGetAnimationOverride(\\${1:string anim_state})\nsnippet llGetAttached\n\tllGetAttached()\nsnippet llGetAttachedList\n\tllGetAttachedList(\\${1:key id})\nsnippet llGetBoundingBox\n\tllGetBoundingBox(\\${1:key object})\nsnippet llGetCameraPos\n\tllGetCameraPos()\nsnippet llGetCameraRot\n\tllGetCameraRot()\nsnippet llGetCenterOfMass\n\tllGetCenterOfMass()\nsnippet llGetClosestNavPoint\n\tllGetClosestNavPoint(\\${1:vector point}, \\${2:list options})\nsnippet llGetColor\n\tllGetColor(\\${1:integer face})\nsnippet llGetCreator\n\tllGetCreator()\nsnippet llGetDate\n\tllGetDate()\nsnippet llGetDisplayName\n\tllGetDisplayName(\\${1:key id})\nsnippet llGetEnergy\n\tllGetEnergy()\nsnippet llGetEnv\n\tllGetEnv(\\${1:string name})\nsnippet llGetExperienceDetails\n\tllGetExperienceDetails(\\${1:key experience_id})\nsnippet llGetExperienceErrorMessage\n\tllGetExperienceErrorMessage(\\${1:integer error})\nsnippet llGetForce\n\tllGetForce()\nsnippet llGetFreeMemory\n\tllGetFreeMemory()\nsnippet llGetFreeURLs\n\tllGetFreeURLs()\nsnippet llGetGeometricCenter\n\tllGetGeometricCenter()\nsnippet llGetGMTclock\n\tllGetGMTclock()\nsnippet llGetHTTPHeader\n\tllGetHTTPHeader(\\${1:key request_id}, \\${2:string header})\nsnippet llGetInventoryCreator\n\tllGetInventoryCreator(\\${1:string item})\nsnippet llGetInventoryKey\n\tllGetInventoryKey(\\${1:string name})\nsnippet llGetInventoryName\n\tllGetInventoryName(\\${1:integer type}, \\${2:integer number})\nsnippet llGetInventoryNumber\n\tllGetInventoryNumber(\\${1:integer type})\nsnippet llGetInventoryPermMask\n\tllGetInventoryPermMask(\\${1:string item}, \\${2:integer mask})\nsnippet llGetInventoryType\n\tllGetInventoryType(\\${1:string name})\nsnippet llGetKey\n\tllGetKey()\nsnippet llGetLandOwnerAt\n\tllGetLandOwnerAt(\\${1:vector pos})\nsnippet llGetLinkKey\n\tllGetLinkKey(\\${1:integer link})\nsnippet llGetLinkMedia\n\tllGetLinkMedia(\\${1:integer link}, \\${2:integer face}, \\${3:list params})\nsnippet llGetLinkName\n\tllGetLinkName(\\${1:integer link})\nsnippet llGetLinkNumber\n\tllGetLinkNumber()\nsnippet llGetLinkNumberOfSides\n\tllGetLinkNumberOfSides(\\${1:integer link})\nsnippet llGetLinkPrimitiveParams\n\tllGetLinkPrimitiveParams(\\${1:integer link}, \\${2:list params})\nsnippet llGetListEntryType\n\tllGetListEntryType(\\${1:list src}, \\${2:integer index})\nsnippet llGetListLength\n\tllGetListLength(\\${1:list src})\nsnippet llGetLocalPos\n\tllGetLocalPos()\nsnippet llGetLocalRot\n\tllGetLocalRot()\nsnippet llGetMass\n\tllGetMass()\nsnippet llGetMassMKS\n\tllGetMassMKS()\nsnippet llGetMaxScaleFactor\n\tllGetMaxScaleFactor()\nsnippet llGetMemoryLimit\n\tllGetMemoryLimit()\nsnippet llGetMinScaleFactor\n\tllGetMinScaleFactor()\nsnippet llGetNextEmail\n\tllGetNextEmail(\\${1:string address}, \\${2:string subject});\n\t\\$0\nsnippet llGetNotecardLine\n\tllGetNotecardLine(\\${1:string name}, \\${2:integer line})\nsnippet llGetNumberOfNotecardLines\n\tllGetNumberOfNotecardLines(\\${1:string name})\nsnippet llGetNumberOfPrims\n\tllGetNumberOfPrims()\nsnippet llGetNumberOfSides\n\tllGetNumberOfSides()\nsnippet llGetObjectDesc\n\tllGetObjectDesc()\nsnippet llGetObjectDetails\n\tllGetObjectDetails(\\${1:key id}, \\${2:list params})\nsnippet llGetObjectMass\n\tllGetObjectMass(\\${1:key id})\nsnippet llGetObjectName\n\tllGetObjectName()\nsnippet llGetObjectPermMask\n\tllGetObjectPermMask(\\${1:integer mask})\nsnippet llGetObjectPrimCount\n\tllGetObjectPrimCount(\\${1:key prim})\nsnippet llGetOmega\n\tllGetOmega()\nsnippet llGetOwner\n\tllGetOwner()\nsnippet llGetOwnerKey\n\tllGetOwnerKey(\\${1:key id})\nsnippet llGetParcelDetails\n\tllGetParcelDetails(\\${1:vector pos}, \\${2:list params})\nsnippet llGetParcelFlags\n\tllGetParcelFlags(\\${1:vector pos})\nsnippet llGetParcelMaxPrims\n\tllGetParcelMaxPrims(\\${1:vector pos}, \\${2:integer sim_wide})\nsnippet llGetParcelMusicURL\n\tllGetParcelMusicURL()\nsnippet llGetParcelPrimCount\n\tllGetParcelPrimCount(\\${1:vector pos}, \\${2:integer category}, \\${3:integer sim_wide})\nsnippet llGetParcelPrimOwners\n\tllGetParcelPrimOwners(\\${1:vector pos})\nsnippet llGetPermissions\n\tllGetPermissions()\nsnippet llGetPermissionsKey\n\tllGetPermissionsKey()\nsnippet llGetPhysicsMaterial\n\tllGetPhysicsMaterial()\nsnippet llGetPos\n\tllGetPos()\nsnippet llGetPrimitiveParams\n\tllGetPrimitiveParams(\\${1:list params})\nsnippet llGetPrimMediaParams\n\tllGetPrimMediaParams(\\${1:integer face}, \\${2:list params})\nsnippet llGetRegionAgentCount\n\tllGetRegionAgentCount()\nsnippet llGetRegionCorner\n\tllGetRegionCorner()\nsnippet llGetRegionFlags\n\tllGetRegionFlags()\nsnippet llGetRegionFPS\n\tllGetRegionFPS()\nsnippet llGetRegionName\n\tllGetRegionName()\nsnippet llGetRegionTimeDilation\n\tllGetRegionTimeDilation()\nsnippet llGetRootPosition\n\tllGetRootPosition()\nsnippet llGetRootRotation\n\tllGetRootRotation()\nsnippet llGetRot\n\tllGetRot()\nsnippet llGetScale\n\tllGetScale()\nsnippet llGetScriptName\n\tllGetScriptName()\nsnippet llGetScriptState\n\tllGetScriptState(\\${1:string script})\nsnippet llGetSimStats\n\tllGetSimStats(\\${1:integer stat_type})\nsnippet llGetSimulatorHostname\n\tllGetSimulatorHostname()\nsnippet llGetSPMaxMemory\n\tllGetSPMaxMemory()\nsnippet llGetStartParameter\n\tllGetStartParameter()\nsnippet llGetStaticPath\n\tllGetStaticPath(\\${1:vector start}, \\${2:vector end}, \\${3:float radius}, \\${4:list params})\nsnippet llGetStatus\n\tllGetStatus(\\${1:integer status})\nsnippet llGetSubString\n\tllGetSubString(\\${1:string src}, \\${2:integer start}, \\${3:integer end})\nsnippet llGetSunDirection\n\tllGetSunDirection()\nsnippet llGetTexture\n\tllGetTexture(\\${1:integer face})\nsnippet llGetTextureOffset\n\tllGetTextureOffset(\\${1:integer face})\nsnippet llGetTextureRot\n\tllGetTextureRot(\\${1:integer face})\nsnippet llGetTextureScale\n\tllGetTextureScale(\\${1:integer face})\nsnippet llGetTime\n\tllGetTime()\nsnippet llGetTimeOfDay\n\tllGetTimeOfDay()\nsnippet llGetTimestamp\n\tllGetTimestamp()\nsnippet llGetTorque\n\tllGetTorque()\nsnippet llGetUnixTime\n\tllGetUnixTime()\nsnippet llGetUsedMemory\n\tllGetUsedMemory()\nsnippet llGetUsername\n\tllGetUsername(\\${1:key id})\nsnippet llGetVel\n\tllGetVel()\nsnippet llGetWallclock\n\tllGetWallclock()\nsnippet llGiveInventory\n\tllGiveInventory(\\${1:key destination}, \\${2:string inventory});\n\t\\$0\nsnippet llGiveInventoryList\n\tllGiveInventoryList(\\${1:key target}, \\${2:string folder}, \\${3:list inventory});\n\t\\$0\nsnippet llGiveMoney\n\tllGiveMoney(\\${1:key destination}, \\${2:integer amount})\nsnippet llGround\n\tllGround(\\${1:vector offset})\nsnippet llGroundContour\n\tllGroundContour(\\${1:vector offset})\nsnippet llGroundNormal\n\tllGroundNormal(\\${1:vector offset})\nsnippet llGroundRepel\n\tllGroundRepel(\\${1:float height}, \\${2:integer water}, \\${3:float tau});\n\t\\$0\nsnippet llGroundSlope\n\tllGroundSlope(\\${1:vector offset})\nsnippet llHTTPRequest\n\tllHTTPRequest(\\${1:string url}, \\${2:list parameters}, \\${3:string body})\nsnippet llHTTPResponse\n\tllHTTPResponse(\\${1:key request_id}, \\${2:integer status}, \\${3:string body});\n\t\\$0\nsnippet llInsertString\n\tllInsertString(\\${1:string dst}, \\${2:integer pos}, \\${3:string src})\nsnippet llInstantMessage\n\tllInstantMessage(\\${1:key user}, \\${2:string message});\n\t\\$0\nsnippet llIntegerToBase64\n\tllIntegerToBase64(\\${1:integer number})\nsnippet llJson2List\n\tllJson2List(\\${1:string json})\nsnippet llJsonGetValue\n\tllJsonGetValue(\\${1:string json}, \\${2:list specifiers})\nsnippet llJsonSetValue\n\tllJsonSetValue(\\${1:string json}, \\${2:list specifiers}, \\${3:string newValue})\nsnippet llJsonValueType\n\tllJsonValueType(\\${1:string json}, \\${2:list specifiers})\nsnippet llKey2Name\n\tllKey2Name(\\${1:key id})\nsnippet llKeyCountKeyValue\n\tllKeyCountKeyValue()\nsnippet llKeysKeyValue\n\tllKeysKeyValue(\\${1:integer first}, \\${2:integer count})\nsnippet llLinkParticleSystem\n\tllLinkParticleSystem(\\${1:integer link}, \\${2:list rules});\n\t\\$0\nsnippet llLinkSitTarget\n\tllLinkSitTarget(\\${1:integer link}, \\${2:vector offset}, \\${3:rotation rot});\n\t\\$0\nsnippet llList2CSV\n\tllList2CSV(\\${1:list src})\nsnippet llList2Float\n\tllList2Float(\\${1:list src}, \\${2:integer index})\nsnippet llList2Integer\n\tllList2Integer(\\${1:list src}, \\${2:integer index})\nsnippet llList2Json\n\tllList2Json(\\${1:string type}, \\${2:list values})\nsnippet llList2Key\n\tllList2Key(\\${1:list src}, \\${2:integer index})\nsnippet llList2List\n\tllList2List(\\${1:list src}, \\${2:integer start}, \\${3:integer end})\nsnippet llList2ListStrided\n\tllList2ListStrided(\\${1:list src}, \\${2:integer start}, \\${3:integer end}, \\${4:integer stride})\nsnippet llList2Rot\n\tllList2Rot(\\${1:list src}, \\${2:integer index})\nsnippet llList2String\n\tllList2String(\\${1:list src}, \\${2:integer index})\nsnippet llList2Vector\n\tllList2Vector(\\${1:list src}, \\${2:integer index})\nsnippet llListen\n\tllListen(\\${1:integer channel}, \\${2:string name}, \\${3:key id}, \\${4:string msg})\nsnippet llListenControl\n\tllListenControl(\\${1:integer handle}, \\${2:integer active});\n\t\\$0\nsnippet llListenRemove\n\tllListenRemove(\\${1:integer handle});\n\t\\$0\nsnippet llListFindList\n\tllListFindList(\\${1:list src}, \\${2:list test})\nsnippet llListInsertList\n\tllListInsertList(\\${1:list dest}, \\${2:list src}, \\${3:integer start})\nsnippet llListRandomize\n\tllListRandomize(\\${1:list src}, \\${2:integer stride})\nsnippet llListReplaceList\n\tllListReplaceList(\\${1:list dest}, \\${2:list src}, \\${3:integer start}, \\${4:integer end})\nsnippet llListSort\n\tllListSort(\\${1:list src}, \\${2:integer stride}, \\${3:integer ascending})\nsnippet llListStatistics\n\tllListStatistics(\\${1:integer operation}, \\${2:list src})\nsnippet llLoadURL\n\tllLoadURL(\\${1:key agent}, \\${2:string message}, \\${3:string url});\n\t\\$0\nsnippet llLog\n\tllLog(\\${1:float val})\nsnippet llLog10\n\tllLog10(\\${1:float val})\nsnippet llLookAt\n\tllLookAt(\\${1:vector target}, \\${2:float strength}, \\${3:float damping});\n\t\\$0\nsnippet llLoopSound\n\tllLoopSound(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llLoopSoundMaster\n\tllLoopSoundMaster(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llLoopSoundSlave\n\tllLoopSoundSlave(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llManageEstateAccess\n\tllManageEstateAccess(\\${1:integer action}, \\${2:key agent})\nsnippet llMapDestination\n\tllMapDestination(\\${1:string simname}, \\${2:vector pos}, \\${3:vector look_at});\n\t\\$0\nsnippet llMD5String\n\tllMD5String(\\${1:string src}, \\${2:integer nonce})\nsnippet llMessageLinked\n\tllMessageLinked(\\${1:integer link}, \\${2:integer num}, \\${3:string str}, \\${4:key id});\n\t\\$0\nsnippet llMinEventDelay\n\tllMinEventDelay(\\${1:float delay});\n\t\\$0\nsnippet llModifyLand\n\tllModifyLand(\\${1:integer action}, \\${2:integer brush});\n\t\\$0\nsnippet llModPow\n\tllModPow(\\${1:integer a}, \\${2:integer b}, \\${3:integer c})\nsnippet llMoveToTarget\n\tllMoveToTarget(\\${1:vector target}, \\${2:float tau});\n\t\\$0\nsnippet llNavigateTo\n\tllNavigateTo(\\${1:vector pos}, \\${2:list options});\n\t\\$0\nsnippet llOffsetTexture\n\tllOffsetTexture(\\${1:float u}, \\${2:float v}, \\${3:integer face});\n\t\\$0\nsnippet llOpenRemoteDataChannel\n\tllOpenRemoteDataChannel();\n\t\\$0\nsnippet llOverMyLand\n\tllOverMyLand(\\${1:key id})\nsnippet llOwnerSay\n\tllOwnerSay(\\${1:string msg});\n\t\\$0\nsnippet llParcelMediaCommandList\n\tllParcelMediaCommandList(\\${1:list commandList});\n\t\\$0\nsnippet llParcelMediaQuery\n\tllParcelMediaQuery(\\${1:list query})\nsnippet llParseString2List\n\tllParseString2List(\\${1:string src}, \\${2:list separators}, \\${3:list spacers})\nsnippet llParseStringKeepNulls\n\tllParseStringKeepNulls(\\${1:string src}, \\${2:list separators}, \\${3:list spacers})\nsnippet llParticleSystem\n\tllParticleSystem(\\${1:list rules});\n\t\\$0\nsnippet llPassCollisions\n\tllPassCollisions(\\${1:integer pass});\n\t\\$0\nsnippet llPassTouches\n\tllPassTouches(\\${1:integer pass});\n\t\\$0\nsnippet llPatrolPoints\n\tllPatrolPoints(\\${1:list patrolPoints}, \\${2:list options});\n\t\\$0\nsnippet llPlaySound\n\tllPlaySound(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llPlaySoundSlave\n\tllPlaySoundSlave(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llPow\n\tllPow(\\${1:float base}, \\${2:float exponent})\nsnippet llPreloadSound\n\tllPreloadSound(\\${1:string sound});\n\t\\$0\nsnippet llPursue\n\tllPursue(\\${1:key target}, \\${2:list options});\n\t\\$0\nsnippet llPushObject\n\tllPushObject(\\${1:key target}, \\${2:vector impulse}, \\${3:vector ang_impulse}, \\${4:integer local});\n\t\\$0\nsnippet llReadKeyValue\n\tllReadKeyValue(\\${1:string k})\nsnippet llRegionSay\n\tllRegionSay(\\${1:integer channel}, \\${2:string msg});\n\t\\$0\nsnippet llRegionSayTo\n\tllRegionSayTo(\\${1:key target}, \\${2:integer channel}, \\${3:string msg});\n\t\\$0\nsnippet llReleaseControls\n\tllReleaseControls();\n\t\\$0\nsnippet llReleaseURL\n\tllReleaseURL(\\${1:string url});\n\t\\$0\nsnippet llRemoteDataReply\n\tllRemoteDataReply(\\${1:key channel}, \\${2:key message_id}, \\${3:string sdata}, \\${4:integer idata});\n\t\\$0\nsnippet llRemoteLoadScriptPin\n\tllRemoteLoadScriptPin(\\${1:key target}, \\${2:string name}, \\${3:integer pin}, \\${4:integer running}, \\${5:integer start_param});\n\t\\$0\nsnippet llRemoveFromLandBanList\n\tllRemoveFromLandBanList(\\${1:key agent});\n\t\\$0\nsnippet llRemoveFromLandPassList\n\tllRemoveFromLandPassList(\\${1:key agent});\n\t\\$0\nsnippet llRemoveInventory\n\tllRemoveInventory(\\${1:string item});\n\t\\$0\nsnippet llRemoveVehicleFlags\n\tllRemoveVehicleFlags(\\${1:integer flags});\n\t\\$0\nsnippet llRequestAgentData\n\tllRequestAgentData(\\${1:key id}, \\${2:integer data})\nsnippet llRequestDisplayName\n\tllRequestDisplayName(\\${1:key id})\nsnippet llRequestExperiencePermissions\n\tllRequestExperiencePermissions(\\${1:key agent}, \\${2:string name})\nsnippet llRequestInventoryData\n\tllRequestInventoryData(\\${1:string name})\nsnippet llRequestPermissions\n\tllRequestPermissions(\\${1:key agent}, \\${2:integer permissions})\nsnippet llRequestSecureURL\n\tllRequestSecureURL()\nsnippet llRequestSimulatorData\n\tllRequestSimulatorData(\\${1:string region}, \\${2:integer data})\nsnippet llRequestURL\n\tllRequestURL()\nsnippet llRequestUsername\n\tllRequestUsername(\\${1:key id})\nsnippet llResetAnimationOverride\n\tllResetAnimationOverride(\\${1:string anim_state});\n\t\\$0\nsnippet llResetLandBanList\n\tllResetLandBanList();\n\t\\$0\nsnippet llResetLandPassList\n\tllResetLandPassList();\n\t\\$0\nsnippet llResetOtherScript\n\tllResetOtherScript(\\${1:string name});\n\t\\$0\nsnippet llResetScript\n\tllResetScript();\n\t\\$0\nsnippet llResetTime\n\tllResetTime();\n\t\\$0\nsnippet llReturnObjectsByID\n\tllReturnObjectsByID(\\${1:list objects})\nsnippet llReturnObjectsByOwner\n\tllReturnObjectsByOwner(\\${1:key owner}, \\${2:integer scope})\nsnippet llRezAtRoot\n\tllRezAtRoot(\\${1:string inventory}, \\${2:vector position}, \\${3:vector velocity}, \\${4:rotation rot}, \\${5:integer param});\n\t\\$0\nsnippet llRezObject\n\tllRezObject(\\${1:string inventory}, \\${2:vector pos}, \\${3:vector vel}, \\${4:rotation rot}, \\${5:integer param});\n\t\\$0\nsnippet llRot2Angle\n\tllRot2Angle(\\${1:rotation rot})\nsnippet llRot2Axis\n\tllRot2Axis(\\${1:rotation rot})\nsnippet llRot2Euler\n\tllRot2Euler(\\${1:rotation quat})\nsnippet llRot2Fwd\n\tllRot2Fwd(\\${1:rotation q})\nsnippet llRot2Left\n\tllRot2Left(\\${1:rotation q})\nsnippet llRot2Up\n\tllRot2Up(\\${1:rotation q})\nsnippet llRotateTexture\n\tllRotateTexture(\\${1:float angle}, \\${2:integer face});\n\t\\$0\nsnippet llRotBetween\n\tllRotBetween(\\${1:vector start}, \\${2:vector end})\nsnippet llRotLookAt\n\tllRotLookAt(\\${1:rotation target_direction}, \\${2:float strength}, \\${3:float damping});\n\t\\$0\nsnippet llRotTarget\n\tllRotTarget(\\${1:rotation rot}, \\${2:float error})\nsnippet llRotTargetRemove\n\tllRotTargetRemove(\\${1:integer handle});\n\t\\$0\nsnippet llRound\n\tllRound(\\${1:float val})\nsnippet llSameGroup\n\tllSameGroup(\\${1:key group})\nsnippet llSay\n\tllSay(\\${1:integer channel}, \\${2:string msg});\n\t\\$0\nsnippet llScaleByFactor\n\tllScaleByFactor(\\${1:float scaling_factor})\nsnippet llScaleTexture\n\tllScaleTexture(\\${1:float u}, \\${2:float v}, \\${3:integer face});\n\t\\$0\nsnippet llScriptDanger\n\tllScriptDanger(\\${1:vector pos})\nsnippet llScriptProfiler\n\tllScriptProfiler(\\${1:integer flags});\n\t\\$0\nsnippet llSendRemoteData\n\tllSendRemoteData(\\${1:key channel}, \\${2:string dest}, \\${3:integer idata}, \\${4:string sdata})\nsnippet llSensor\n\tllSensor(\\${1:string name}, \\${2:key id}, \\${3:integer type}, \\${4:float range}, \\${5:float arc});\n\t\\$0\nsnippet llSensorRepeat\n\tllSensorRepeat(\\${1:string name}, \\${2:key id}, \\${3:integer type}, \\${4:float range}, \\${5:float arc}, \\${6:float rate});\n\t\\$0\nsnippet llSetAlpha\n\tllSetAlpha(\\${1:float alpha}, \\${2:integer face});\n\t\\$0\nsnippet llSetAngularVelocity\n\tllSetAngularVelocity(\\${1:vector force}, \\${2:integer local});\n\t\\$0\nsnippet llSetAnimationOverride\n\tllSetAnimationOverride(\\${1:string anim_state}, \\${2:string anim})\nsnippet llSetBuoyancy\n\tllSetBuoyancy(\\${1:float buoyancy});\n\t\\$0\nsnippet llSetCameraAtOffset\n\tllSetCameraAtOffset(\\${1:vector offset});\n\t\\$0\nsnippet llSetCameraEyeOffset\n\tllSetCameraEyeOffset(\\${1:vector offset});\n\t\\$0\nsnippet llSetCameraParams\n\tllSetCameraParams(\\${1:list rules});\n\t\\$0\nsnippet llSetClickAction\n\tllSetClickAction(\\${1:integer action});\n\t\\$0\nsnippet llSetColor\n\tllSetColor(\\${1:vector color}, \\${2:integer face});\n\t\\$0\nsnippet llSetContentType\n\tllSetContentType(\\${1:key request_id}, \\${2:integer content_type});\n\t\\$0\nsnippet llSetDamage\n\tllSetDamage(\\${1:float damage});\n\t\\$0\nsnippet llSetForce\n\tllSetForce(\\${1:vector force}, \\${2:integer local});\n\t\\$0\nsnippet llSetForceAndTorque\n\tllSetForceAndTorque(\\${1:vector force}, \\${2:vector torque}, \\${3:integer local});\n\t\\$0\nsnippet llSetHoverHeight\n\tllSetHoverHeight(\\${1:float height}, \\${2:integer water}, \\${3:float tau});\n\t\\$0\nsnippet llSetKeyframedMotion\n\tllSetKeyframedMotion(\\${1:list keyframes}, \\${2:list options});\n\t\\$0\nsnippet llSetLinkAlpha\n\tllSetLinkAlpha(\\${1:integer link}, \\${2:float alpha}, \\${3:integer face});\n\t\\$0\nsnippet llSetLinkCamera\n\tllSetLinkCamera(\\${1:integer link}, \\${2:vector eye}, \\${3:vector at});\n\t\\$0\nsnippet llSetLinkColor\n\tllSetLinkColor(\\${1:integer link}, \\${2:vector color}, \\${3:integer face});\n\t\\$0\nsnippet llSetLinkMedia\n\tllSetLinkMedia(\\${1:integer link}, \\${2:integer face}, \\${3:list params});\n\t\\$0\nsnippet llSetLinkPrimitiveParams\n\tllSetLinkPrimitiveParams(\\${1:integer link}, \\${2:list rules});\n\t\\$0\nsnippet llSetLinkPrimitiveParamsFast\n\tllSetLinkPrimitiveParamsFast(\\${1:integer link}, \\${2:list rules});\n\t\\$0\nsnippet llSetLinkTexture\n\tllSetLinkTexture(\\${1:integer link}, \\${2:string texture}, \\${3:integer face});\n\t\\$0\nsnippet llSetLinkTextureAnim\n\tllSetLinkTextureAnim(\\${1:integer link}, \\${2:integer mode}, \\${3:integer face}, \\${4:integer sizex}, \\${5:integer sizey}, \\${6:float start}, \\${7:float length}, \\${8:float rate});\n\t\\$0\nsnippet llSetLocalRot\n\tllSetLocalRot(\\${1:rotation rot});\n\t\\$0\nsnippet llSetMemoryLimit\n\tllSetMemoryLimit(\\${1:integer limit})\nsnippet llSetObjectDesc\n\tllSetObjectDesc(\\${1:string description});\n\t\\$0\nsnippet llSetObjectName\n\tllSetObjectName(\\${1:string name});\n\t\\$0\nsnippet llSetParcelMusicURL\n\tllSetParcelMusicURL(\\${1:string url});\n\t\\$0\nsnippet llSetPayPrice\n\tllSetPayPrice(\\${1:integer price}, [\\${2:integer price_button_a}, \\${3:integer price_button_b}, \\${4:integer price_button_c}, \\${5:integer price_button_d}]);\n\t\\$0\nsnippet llSetPhysicsMaterial\n\tllSetPhysicsMaterial(\\${1:integer mask}, \\${2:float gravity_multiplier}, \\${3:float restitution}, \\${4:float friction}, \\${5:float density});\n\t\\$0\nsnippet llSetPos\n\tllSetPos(\\${1:vector pos});\n\t\\$0\nsnippet llSetPrimitiveParams\n\tllSetPrimitiveParams(\\${1:list rules});\n\t\\$0\nsnippet llSetPrimMediaParams\n\tllSetPrimMediaParams(\\${1:integer face}, \\${2:list params});\n\t\\$0\nsnippet llSetRegionPos\n\tllSetRegionPos(\\${1:vector position})\nsnippet llSetRemoteScriptAccessPin\n\tllSetRemoteScriptAccessPin(\\${1:integer pin});\n\t\\$0\nsnippet llSetRot\n\tllSetRot(\\${1:rotation rot});\n\t\\$0\nsnippet llSetScale\n\tllSetScale(\\${1:vector size});\n\t\\$0\nsnippet llSetScriptState\n\tllSetScriptState(\\${1:string name}, \\${2:integer run});\n\t\\$0\nsnippet llSetSitText\n\tllSetSitText(\\${1:string text});\n\t\\$0\nsnippet llSetSoundQueueing\n\tllSetSoundQueueing(\\${1:integer queue});\n\t\\$0\nsnippet llSetSoundRadius\n\tllSetSoundRadius(\\${1:float radius});\n\t\\$0\nsnippet llSetStatus\n\tllSetStatus(\\${1:integer status}, \\${2:integer value});\n\t\\$0\nsnippet llSetText\n\tllSetText(\\${1:string text}, \\${2:vector color}, \\${3:float alpha});\n\t\\$0\nsnippet llSetTexture\n\tllSetTexture(\\${1:string texture}, \\${2:integer face});\n\t\\$0\nsnippet llSetTextureAnim\n\tllSetTextureAnim(\\${1:integer mode}, \\${2:integer face}, \\${3:integer sizex}, \\${4:integer sizey}, \\${5:float start}, \\${6:float length}, \\${7:float rate});\n\t\\$0\nsnippet llSetTimerEvent\n\tllSetTimerEvent(\\${1:float sec});\n\t\\$0\nsnippet llSetTorque\n\tllSetTorque(\\${1:vector torque}, \\${2:integer local});\n\t\\$0\nsnippet llSetTouchText\n\tllSetTouchText(\\${1:string text});\n\t\\$0\nsnippet llSetVehicleFlags\n\tllSetVehicleFlags(\\${1:integer flags});\n\t\\$0\nsnippet llSetVehicleFloatParam\n\tllSetVehicleFloatParam(\\${1:integer param}, \\${2:float value});\n\t\\$0\nsnippet llSetVehicleRotationParam\n\tllSetVehicleRotationParam(\\${1:integer param}, \\${2:rotation rot});\n\t\\$0\nsnippet llSetVehicleType\n\tllSetVehicleType(\\${1:integer type});\n\t\\$0\nsnippet llSetVehicleVectorParam\n\tllSetVehicleVectorParam(\\${1:integer param}, \\${2:vector vec});\n\t\\$0\nsnippet llSetVelocity\n\tllSetVelocity(\\${1:vector force}, \\${2:integer local});\n\t\\$0\nsnippet llSHA1String\n\tllSHA1String(\\${1:string src})\nsnippet llShout\n\tllShout(\\${1:integer channel}, \\${2:string msg});\n\t\\$0\nsnippet llSin\n\tllSin(\\${1:float theta})\nsnippet llSitTarget\n\tllSitTarget(\\${1:vector offset}, \\${2:rotation rot});\n\t\\$0\nsnippet llSleep\n\tllSleep(\\${1:float sec});\n\t\\$0\nsnippet llSqrt\n\tllSqrt(\\${1:float val})\nsnippet llStartAnimation\n\tllStartAnimation(\\${1:string anim});\n\t\\$0\nsnippet llStopAnimation\n\tllStopAnimation(\\${1:string anim});\n\t\\$0\nsnippet llStopHover\n\tllStopHover();\n\t\\$0\nsnippet llStopLookAt\n\tllStopLookAt();\n\t\\$0\nsnippet llStopMoveToTarget\n\tllStopMoveToTarget();\n\t\\$0\nsnippet llStopSound\n\tllStopSound();\n\t\\$0\nsnippet llStringLength\n\tllStringLength(\\${1:string str})\nsnippet llStringToBase64\n\tllStringToBase64(\\${1:string str})\nsnippet llStringTrim\n\tllStringTrim(\\${1:string src}, \\${2:integer type})\nsnippet llSubStringIndex\n\tllSubStringIndex(\\${1:string source}, \\${2:string pattern})\nsnippet llTakeControls\n\tllTakeControls(\\${1:integer controls}, \\${2:integer accept}, \\${3:integer pass_on});\n\t\\$0\nsnippet llTan\n\tllTan(\\${1:float theta})\nsnippet llTarget\n\tllTarget(\\${1:vector position}, \\${2:float range})\nsnippet llTargetOmega\n\tllTargetOmega(\\${1:vector axis}, \\${2:float spinrate}, \\${3:float gain});\n\t\\$0\nsnippet llTargetRemove\n\tllTargetRemove(\\${1:integer handle});\n\t\\$0\nsnippet llTeleportAgent\n\tllTeleportAgent(\\${1:key agent}, \\${2:string landmark}, \\${3:vector position}, \\${4:vector look_at});\n\t\\$0\nsnippet llTeleportAgentGlobalCoords\n\tllTeleportAgentGlobalCoords(\\${1:key agent}, \\${2:vector global_coordinates}, \\${3:vector region_coordinates}, \\${4:vector look_at});\n\t\\$0\nsnippet llTeleportAgentHome\n\tllTeleportAgentHome(\\${1:key agent});\n\t\\$0\nsnippet llTextBox\n\tllTextBox(\\${1:key agent}, \\${2:string message}, \\${3:integer channel});\n\t\\$0\nsnippet llToLower\n\tllToLower(\\${1:string src})\nsnippet llToUpper\n\tllToUpper(\\${1:string src})\nsnippet llTransferLindenDollars\n\tllTransferLindenDollars(\\${1:key destination}, \\${2:integer amount})\nsnippet llTriggerSound\n\tllTriggerSound(\\${1:string sound}, \\${2:float volume});\n\t\\$0\nsnippet llTriggerSoundLimited\n\tllTriggerSoundLimited(\\${1:string sound}, \\${2:float volume}, \\${3:vector top_north_east}, \\${4:vector bottom_south_west});\n\t\\$0\nsnippet llUnescapeURL\n\tllUnescapeURL(\\${1:string url})\nsnippet llUnSit\n\tllUnSit(\\${1:key id});\n\t\\$0\nsnippet llUpdateCharacter\n\tllUpdateCharacter(\\${1:list options})\nsnippet llUpdateKeyValue\n\tllUpdateKeyValue(\\${1:string k}, \\${2:string v}, \\${3:integer checked}, \\${4:string ov})\nsnippet llVecDist\n\tllVecDist(\\${1:vector vec_a}, \\${2:vector vec_b})\nsnippet llVecMag\n\tllVecMag(\\${1:vector vec})\nsnippet llVecNorm\n\tllVecNorm(\\${1:vector vec})\nsnippet llVolumeDetect\n\tllVolumeDetect(\\${1:integer detect});\n\t\\$0\nsnippet llWanderWithin\n\tllWanderWithin(\\${1:vector origin}, \\${2:vector dist}, \\${3:list options});\n\t\\$0\nsnippet llWater\n\tllWater(\\${1:vector offset});\n\t\\$0\nsnippet llWhisper\n\tllWhisper(\\${1:integer channel}, \\${2:string msg});\n\t\\$0\nsnippet llWind\n\tllWind(\\${1:vector offset});\n\t\\$0\nsnippet llXorBase64\n\tllXorBase64(\\${1:string str1}, \\${2:string str2})\nsnippet money\n\tmoney(\\${1:key id}, \\${2:integer amount})\n\t{\n\t\t\\$0\n\t}\nsnippet object_rez\n\tobject_rez(\\${1:key id})\n\t{\n\t\t\\$0\n\t}\nsnippet on_rez\n\ton_rez(\\${1:integer start_param})\n\t{\n\t\t\\$0\n\t}\nsnippet path_update\n\tpath_update(\\${1:integer type}, \\${2:list reserved})\n\t{\n\t\t\\$0\n\t}\nsnippet remote_data\n\tremote_data(\\${1:integer event_type}, \\${2:key channel}, \\${3:key message_id}, \\${4:string sender}, \\${5:integer idata}, \\${6:string sdata})\n\t{\n\t\t\\$0\n\t}\nsnippet run_time_permissions\n\trun_time_permissions(\\${1:integer perm})\n\t{\n\t\t\\$0\n\t}\nsnippet sensor\n\tsensor(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet state\n\tstate \\${1:name}\nsnippet touch\n\ttouch(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet touch_end\n\ttouch_end(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet touch_start\n\ttouch_start(\\${1:integer index})\n\t{\n\t\t\\$0\n\t}\nsnippet transaction_result\n\ttransaction_result(\\${1:key id}, \\${2:integer success}, \\${3:string data})\n\t{\n\t\t\\$0\n\t}\nsnippet while\n\twhile (\\${1:condition})\n\t{\n\t\t\\$0\n\t}\n`;\n"
  },
  {
    "path": "src/snippets/lua.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./lua.snippets\");\nexports.scope = \"lua\";\n"
  },
  {
    "path": "src/snippets/lua.snippets.js",
    "content": "module.exports = `snippet #!\n\t#!/usr/bin/env lua\n\t\\$1\nsnippet local\n\tlocal \\${1:x} = \\${2:1}\nsnippet fun\n\tfunction \\${1:fname}(\\${2:...})\n\t\t\\${3:-- body}\n\tend\nsnippet for\n\tfor \\${1:i}=\\${2:1},\\${3:10} do\n\t\t\\${4:print(i)}\n\tend\nsnippet forp\n\tfor \\${1:i},\\${2:v} in pairs(\\${3:table_name}) do\n\t   \\${4:-- body}\n\tend\nsnippet fori\n\tfor \\${1:i},\\${2:v} in ipairs(\\${3:table_name}) do\n\t   \\${4:-- body}\n\tend\n`;\n"
  },
  {
    "path": "src/snippets/makefile.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./makefile.snippets\");\nexports.scope = \"makefile\";\n"
  },
  {
    "path": "src/snippets/makefile.snippets.js",
    "content": "module.exports = `snippet ifeq\n\tifeq (\\${1:cond0},\\${2:cond1})\n\t\t\\${3:code}\n\tendif\n`;\n"
  },
  {
    "path": "src/snippets/markdown.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./markdown.snippets\");\nexports.scope = \"markdown\";\n"
  },
  {
    "path": "src/snippets/markdown.snippets.js",
    "content": "module.exports = `# Markdown\n\n# Includes octopress (http://octopress.org/) snippets\n\nsnippet [\n\t[\\${1:text}](http://\\${2:address} \"\\${3:title}\")\nsnippet [*\n\t[\\${1:link}](\\${2:\\`@*\\`} \"\\${3:title}\")\\${4}\n\nsnippet [:\n\t[\\${1:id}]: http://\\${2:url} \"\\${3:title}\"\nsnippet [:*\n\t[\\${1:id}]: \\${2:\\`@*\\`} \"\\${3:title}\"\n\nsnippet ![\n\t![\\${1:alttext}](\\${2:/images/image.jpg} \"\\${3:title}\")\nsnippet ![*\n\t![\\${1:alt}](\\${2:\\`@*\\`} \"\\${3:title}\")\\${4}\n\nsnippet ![:\n\t![\\${1:id}]: \\${2:url} \"\\${3:title}\"\nsnippet ![:*\n\t![\\${1:id}]: \\${2:\\`@*\\`} \"\\${3:title}\"\n\nsnippet ===\nregex /^/=+/=*//\n\t\\${PREV_LINE/./=/g}\n\t\n\t\\${0}\nsnippet ---\nregex /^/-+/-*//\n\t\\${PREV_LINE/./-/g}\n\t\n\t\\${0}\nsnippet blockquote\n\t{% blockquote %}\n\t\\${1:quote}\n\t{% endblockquote %}\n\nsnippet blockquote-author\n\t{% blockquote \\${1:author}, \\${2:title} %}\n\t\\${3:quote}\n\t{% endblockquote %}\n\nsnippet blockquote-link\n\t{% blockquote \\${1:author} \\${2:URL} \\${3:link_text} %}\n\t\\${4:quote}\n\t{% endblockquote %}\n\nsnippet bt-codeblock-short\n\t\\`\\`\\`\n\t\\${1:code_snippet}\n\t\\`\\`\\`\n\nsnippet bt-codeblock-full\n\t\\`\\`\\` \\${1:language} \\${2:title} \\${3:URL} \\${4:link_text}\n\t\\${5:code_snippet}\n\t\\`\\`\\`\n\nsnippet codeblock-short\n\t{% codeblock %}\n\t\\${1:code_snippet}\n\t{% endcodeblock %}\n\nsnippet codeblock-full\n\t{% codeblock \\${1:title} lang:\\${2:language} \\${3:URL} \\${4:link_text} %}\n\t\\${5:code_snippet}\n\t{% endcodeblock %}\n\nsnippet gist-full\n\t{% gist \\${1:gist_id} \\${2:filename} %}\n\nsnippet gist-short\n\t{% gist \\${1:gist_id} %}\n\nsnippet img\n\t{% img \\${1:class} \\${2:URL} \\${3:width} \\${4:height} \\${5:title_text} \\${6:alt_text} %}\n\nsnippet youtube\n\t{% youtube \\${1:video_id} %}\n\n# The quote should appear only once in the text. It is inherently part of it.\n# See http://octopress.org/docs/plugins/pullquote/ for more info.\n\nsnippet pullquote\n\t{% pullquote %}\n\t\\${1:text} {\" \\${2:quote} \"} \\${3:text}\n\t{% endpullquote %}\n`;\n"
  },
  {
    "path": "src/snippets/maze.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./maze.snippets\");\nexports.scope = \"maze\";\n"
  },
  {
    "path": "src/snippets/maze.snippets.js",
    "content": "module.exports = `snippet >\ndescription assignment\nscope maze\n\t-> \\${1}= \\${2}\n\nsnippet >\ndescription if\nscope maze\n\t-> IF \\${2:**} THEN %\\${3:L} ELSE %\\${4:R}\n`;\n"
  },
  {
    "path": "src/snippets/perl.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./perl.snippets\");\nexports.scope = \"perl\";\n"
  },
  {
    "path": "src/snippets/perl.snippets.js",
    "content": "module.exports = `# #!/usr/bin/perl\nsnippet #!\n\t#!/usr/bin/env perl\n\n# Hash Pointer\nsnippet .\n\t =>\n# Function\nsnippet sub\n\tsub \\${1:function_name} {\n\t\t\\${2:#body ...}\n\t}\n# Conditional\nsnippet if\n\tif (\\${1}) {\n\t\t\\${2:# body...}\n\t}\n# Conditional if..else\nsnippet ife\n\tif (\\${1}) {\n\t\t\\${2:# body...}\n\t}\n\telse {\n\t\t\\${3:# else...}\n\t}\n# Conditional if..elsif..else\nsnippet ifee\n\tif (\\${1}) {\n\t\t\\${2:# body...}\n\t}\n\telsif (\\${3}) {\n\t\t\\${4:# elsif...}\n\t}\n\telse {\n\t\t\\${5:# else...}\n\t}\n# Conditional One-line\nsnippet xif\n\t\\${1:expression} if \\${2:condition};\\${3}\n# Unless conditional\nsnippet unless\n\tunless (\\${1}) {\n\t\t\\${2:# body...}\n\t}\n# Unless conditional One-line\nsnippet xunless\n\t\\${1:expression} unless \\${2:condition};\\${3}\n# Try/Except\nsnippet eval\n\tlocal \\$@;\n\teval {\n\t\t\\${1:# do something risky...}\n\t};\n\tif (my \\$e = \\$@) {\n\t\t\\${2:# handle failure...}\n\t}\n# While Loop\nsnippet wh\n\twhile (\\${1}) {\n\t\t\\${2:# body...}\n\t}\n# While Loop One-line\nsnippet xwh\n\t\\${1:expression} while \\${2:condition};\\${3}\n# C-style For Loop\nsnippet cfor\n\tfor (my \\$\\${2:var} = 0; \\$\\$2 < \\${1:count}; \\$\\$2\\${3:++}) {\n\t\t\\${4:# body...}\n\t}\n# For loop one-line\nsnippet xfor\n\t\\${1:expression} for @\\${2:array};\\${3}\n# Foreach Loop\nsnippet for\n\tforeach my \\$\\${1:x} (@\\${2:array}) {\n\t\t\\${3:# body...}\n\t}\n# Foreach Loop One-line\nsnippet fore\n\t\\${1:expression} foreach @\\${2:array};\\${3}\n# Package\nsnippet package\n\tpackage \\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`};\n\n\t\\${2}\n\n\t1;\n\n\t__END__\n# Package syntax perl >= 5.14\nsnippet packagev514\n\tpackage \\${1:\\`substitute(Filename('', 'Page Title'), '^.', '\\\\u&', '')\\`} \\${2:0.99};\n\n\t\\${3}\n\n\t1;\n\n\t__END__\n#moose\nsnippet moose\n\tuse Moose;\n\tuse namespace::autoclean;\n\t\\${1:#}BEGIN {extends '\\${2:ParentClass}'};\n\n\t\\${3}\n# parent\nsnippet parent\n\tuse parent qw(\\${1:Parent Class});\n# Read File\nsnippet slurp\n\tmy \\$\\${1:var} = do { local \\$/; open my \\$file, '<', \"\\${2:file}\"; <\\$file> };\n\t\\${3}\n# strict warnings\nsnippet strwar\n\tuse strict;\n\tuse warnings;\n# older versioning with perlcritic bypass\nsnippet vers\n\t## no critic\n\tour \\$VERSION = '\\${1:version}';\n\teval \\$VERSION;\n\t## use critic\n# new 'switch' like feature\nsnippet switch\n\tuse feature 'switch';\n\n# Anonymous subroutine\nsnippet asub\n\tsub {\n\t \t\\${1:# body }\n\t}\n\n\n\n# Begin block\nsnippet begin\n\tBEGIN {\n\t\t\\${1:# begin body}\n\t}\n\n# call package function with some parameter\nsnippet pkgmv\n\t__PACKAGE__->\\${1:package_method}(\\${2:var})\n\n# call package function without a parameter\nsnippet pkgm\n\t__PACKAGE__->\\${1:package_method}()\n\n# call package \"get_\" function without a parameter\nsnippet pkget\n\t__PACKAGE__->get_\\${1:package_method}()\n\n# call package function with a parameter\nsnippet pkgetv\n\t__PACKAGE__->get_\\${1:package_method}(\\${2:var})\n\n# complex regex\nsnippet qrx\n\tqr/\n\t     \\${1:regex}\n\t/xms\n\n#simpler regex\nsnippet qr/\n\tqr/\\${1:regex}/x\n\n#given\nsnippet given\n\tgiven (\\$\\${1:var}) {\n\t\t\\${2:# cases}\n\t\t\\${3:# default}\n\t}\n\n# switch-like case\nsnippet when\n\twhen (\\${1:case}) {\n\t\t\\${2:# body}\n\t}\n\n# hash slice\nsnippet hslice\n\t@{ \\${1:hash}  }{ \\${2:array} }\n\n\n# map\nsnippet map\n\tmap {  \\${2: body }    }  \\${1: @array } ;\n\n\n\n# Pod stub\nsnippet ppod\n\t=head1 NAME\n\n\t\\${1:ClassName} - \\${2:ShortDesc}\n\n\t=head1 SYNOPSIS\n\n\t  use \\$1;\n\n\t  \\${3:# synopsis...}\n\n\t=head1 DESCRIPTION\n\n\t\\${4:# longer description...}\n\n\n\t=head1 INTERFACE\n\n\n\t=head1 DEPENDENCIES\n\n\n\t=head1 SEE ALSO\n\n\n# Heading for a subroutine stub\nsnippet psub\n\t=head2 \\${1:MethodName}\n\n\t\\${2:Summary....}\n\n# Heading for inline subroutine pod\nsnippet psubi\n\t=head2 \\${1:MethodName}\n\n\t\\${2:Summary...}\n\n\n\t=cut\n# inline documented subroutine\nsnippet subpod\n\t=head2 \\$1\n\n\tSummary of \\$1\n\n\t=cut\n\n\tsub \\${1:subroutine_name} {\n\t\t\\${2:# body...}\n\t}\n# Subroutine signature\nsnippet parg\n\t=over 2\n\n\t=item\n\tArguments\n\n\n\t=over 3\n\n\t=item\n\tC<\\${1:DataStructure}>\n\n\t  \\${2:Sample}\n\n\n\t=back\n\n\n\t=item\n\tReturn\n\n\t=over 3\n\n\n\t=item\n\tC<\\${3:...return data}>\n\n\n\t=back\n\n\n\t=back\n\n\n\n# Moose has\nsnippet has\n\thas \\${1:attribute} => (\n\t\tis\t    => '\\${2:ro|rw}',\n\t\tisa \t=> '\\${3:Str|Int|HashRef|ArrayRef|etc}',\n\t\tdefault => sub {\n\t\t\t\\${4:defaultvalue}\n\t\t},\n\t\t\\${5:# other attributes}\n\t);\n\n\n# override\nsnippet override\n\toverride \\${1:attribute} => sub {\n\t\t\\${2:# my \\$self = shift;};\n\t\t\\${3:# my (\\$self, \\$args) = @_;};\n\t};\n\n\n# use test classes\nsnippet tuse\n\tuse Test::More;\n\tuse Test::Deep; # (); # uncomment to stop prototype errors\n\tuse Test::Exception;\n\n# local test lib\nsnippet tlib\n\tuse lib qw{ ./t/lib };\n\n#test methods\nsnippet tmeths\n\t\\$ENV{TEST_METHOD} = '\\${1:regex}';\n\n# runtestclass\nsnippet trunner\n\tuse \\${1:test_class};\n\t\\$1->runtests();\n\n# Test::Class-style test\nsnippet tsub\n\tsub t\\${1:number}_\\${2:test_case} :Test(\\${3:num_of_tests}) {\n\t\tmy \\$self = shift;\n\t\t\\${4:#  body}\n\n\t}\n\n# Test::Routine-style test\nsnippet trsub\n\ttest \\${1:test_name} => { description => '\\${2:Description of test.}'} => sub {\n\t\tmy (\\$self) = @_;\n\t\t\\${3:# test code}\n\t};\n\n#prep test method\nsnippet tprep\n\tsub prep\\${1:number}_\\${2:test_case} :Test(startup) {\n\t\tmy \\$self = shift;\n\t\t\\${4:#  body}\n\t}\n\n# cause failures to print stack trace\nsnippet debug_trace\n\tuse Carp; # 'verbose';\n\t# cloak \"die\"\n\t# warn \"warning\"\n\t\\$SIG{'__DIE__'} = sub {\n\t\trequire Carp; Carp::confess\n\t};\n\n`;\n"
  },
  {
    "path": "src/snippets/php.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./php.snippets\");\nexports.scope = \"php\";\n"
  },
  {
    "path": "src/snippets/php.snippets.js",
    "content": "module.exports = `snippet ec\n\techo \\${1};\nsnippet ns\n\tnamespace \\${1:Foo\\\\Bar\\\\Baz};\n\t\\${2}\nsnippet use\n\tuse \\${1:Foo\\\\Bar\\\\Baz};\n\t\\${2}\nsnippet c\n\t\\${1:abstract }class \\${2:\\$FILENAME}\n\t{\n\t\t\\${3}\n\t}\nsnippet i\n\tinterface \\${1:\\$FILENAME}\n\t{\n\t\t\\${2}\n\t}\nsnippet t.\n\t\\$this->\\${1}\nsnippet f\n\tfunction \\${1:foo}(\\${2:array }\\${3:\\$bar})\n\t{\n\t\t\\${4}\n\t}\n# method\nsnippet m\n\t\\${1:abstract }\\${2:protected}\\${3: static} function \\${4:foo}(\\${5:array }\\${6:\\$bar})\n\t{\n\t\t\\${7}\n\t}\n# setter method\nsnippet sm\n\t/**\n\t * Sets the value of \\${1:foo}\n\t *\n\t * @param \\${2:\\$1} \\$\\$1 \\${3:description}\n\t *\n\t * @return \\${4:\\$FILENAME}\n\t */\n\t\\${5:public} function set\\${6:\\$2}(\\${7:\\$2 }\\$\\$1)\n\t{\n\t\t\\$this->\\${8:\\$1} = \\$\\$1;\n\t\treturn \\$this;\n\t}\\${9}\n# getter method\nsnippet gm\n\t/**\n\t * Gets the value of \\${1:foo}\n\t *\n\t * @return \\${2:\\$1}\n\t */\n\t\\${3:public} function get\\${4:\\$2}()\n\t{\n\t\treturn \\$this->\\${5:\\$1};\n\t}\\${6}\n#setter\nsnippet \\$s\n\t\\${1:\\$foo}->set\\${2:Bar}(\\${3});\n#getter\nsnippet \\$g\n\t\\${1:\\$foo}->get\\${2:Bar}();\n\n# Tertiary conditional\nsnippet =?:\n\t\\$\\${1:foo} = \\${2:true} ? \\${3:a} : \\${4};\nsnippet ?:\n\t\\${1:true} ? \\${2:a} : \\${3}\n\nsnippet C\n\t\\$_COOKIE['\\${1:variable}']\\${2}\nsnippet E\n\t\\$_ENV['\\${1:variable}']\\${2}\nsnippet F\n\t\\$_FILES['\\${1:variable}']\\${2}\nsnippet G\n\t\\$_GET['\\${1:variable}']\\${2}\nsnippet P\n\t\\$_POST['\\${1:variable}']\\${2}\nsnippet R\n\t\\$_REQUEST['\\${1:variable}']\\${2}\nsnippet S\n\t\\$_SERVER['\\${1:variable}']\\${2}\nsnippet SS\n\t\\$_SESSION['\\${1:variable}']\\${2}\n\n# the following are old ones\nsnippet inc\n\tinclude '\\${1:file}';\\${2}\nsnippet inc1\n\tinclude_once '\\${1:file}';\\${2}\nsnippet req\n\trequire '\\${1:file}';\\${2}\nsnippet req1\n\trequire_once '\\${1:file}';\\${2}\n# Start Docblock\nsnippet /*\n\t/**\n\t * \\${1}\n\t */\n# Class - post doc\nsnippet doc_cp\n\t/**\n\t * \\${1:undocumented class}\n\t *\n\t * @package \\${2:default}\n\t * @subpackage \\${3:default}\n\t * @author \\${4:\\`g:snips_author\\`}\n\t */\\${5}\n# Class Variable - post doc\nsnippet doc_vp\n\t/**\n\t * \\${1:undocumented class variable}\n\t *\n\t * @var \\${2:string}\n\t */\\${3}\n# Class Variable\nsnippet doc_v\n\t/**\n\t * \\${3:undocumented class variable}\n\t *\n\t * @var \\${4:string}\n\t */\n\t\\${1:var} \\$\\${2};\\${5}\n# Class\nsnippet doc_c\n\t/**\n\t * \\${3:undocumented class}\n\t *\n\t * @package \\${4:default}\n\t * @subpackage \\${5:default}\n\t * @author \\${6:\\`g:snips_author\\`}\n\t */\n\t\\${1:}class \\${2:}\n\t{\n\t\t\\${7}\n\t} // END \\$1class \\$2\n# Constant Definition - post doc\nsnippet doc_dp\n\t/**\n\t * \\${1:undocumented constant}\n\t */\\${2}\n# Constant Definition\nsnippet doc_d\n\t/**\n\t * \\${3:undocumented constant}\n\t */\n\tdefine(\\${1}, \\${2});\\${4}\n# Function - post doc\nsnippet doc_fp\n\t/**\n\t * \\${1:undocumented function}\n\t *\n\t * @return \\${2:void}\n\t * @author \\${3:\\`g:snips_author\\`}\n\t */\\${4}\n# Function signature\nsnippet doc_s\n\t/**\n\t * \\${4:undocumented function}\n\t *\n\t * @return \\${5:void}\n\t * @author \\${6:\\`g:snips_author\\`}\n\t */\n\t\\${1}function \\${2}(\\${3});\\${7}\n# Function\nsnippet doc_f\n\t/**\n\t * \\${4:undocumented function}\n\t *\n\t * @return \\${5:void}\n\t * @author \\${6:\\`g:snips_author\\`}\n\t */\n\t\\${1}function \\${2}(\\${3})\n\t{\\${7}\n\t}\n# Header\nsnippet doc_h\n\t/**\n\t * \\${1}\n\t *\n\t * @author \\${2:\\`g:snips_author\\`}\n\t * @version \\${3:\\$Id\\$}\n\t * @copyright \\${4:\\$2}, \\`strftime('%d %B, %Y')\\`\n\t * @package \\${5:default}\n\t */\n\n# Interface\nsnippet interface\n\t/**\n\t * \\${2:undocumented class}\n\t *\n\t * @package \\${3:default}\n\t * @author \\${4:\\`g:snips_author\\`}\n\t */\n\tinterface \\${1:\\$FILENAME}\n\t{\n\t\t\\${5}\n\t}\n# class ...\nsnippet class\n\t/**\n\t * \\${1}\n\t */\n\tclass \\${2:\\$FILENAME}\n\t{\n\t\t\\${3}\n\t\t/**\n\t\t * \\${4}\n\t\t */\n\t\t\\${5:public} function \\${6:__construct}(\\${7:argument})\n\t\t{\n\t\t\t\\${8:// code...}\n\t\t}\n\t}\n# define(...)\nsnippet def\n\tdefine('\\${1}'\\${2});\\${3}\n# defined(...)\nsnippet def?\n\t\\${1}defined('\\${2}')\\${3}\nsnippet wh\n\twhile (\\${1:/* condition */}) {\n\t\t\\${2:// code...}\n\t}\n# do ... while\nsnippet do\n\tdo {\n\t\t\\${2:// code... }\n\t} while (\\${1:/* condition */});\nsnippet if\n\tif (\\${1:/* condition */}) {\n\t\t\\${2:// code...}\n\t}\nsnippet ife\n\tif (\\${1:/* condition */}) {\n\t\t\\${2:// code...}\n\t} else {\n\t\t\\${3:// code...}\n\t}\n\t\\${4}\nsnippet else\n\telse {\n\t\t\\${1:// code...}\n\t}\nsnippet elseif\n\telseif (\\${1:/* condition */}) {\n\t\t\\${2:// code...}\n\t}\nsnippet switch\n\tswitch (\\$\\${1:variable}) {\n\t\tcase '\\${2:value}':\n\t\t\t\\${3:// code...}\n\t\t\tbreak;\n\t\t\\${5}\n\t\tdefault:\n\t\t\t\\${4:// code...}\n\t\t\tbreak;\n\t}\nsnippet case\n\tcase '\\${1:value}':\n\t\t\\${2:// code...}\n\t\tbreak;\\${3}\nsnippet for\n\tfor (\\$\\${2:i} = 0; \\$\\$2 < \\${1:count}; \\$\\$2\\${3:++}) {\n\t\t\\${4: // code...}\n\t}\nsnippet foreach\n\tforeach (\\$\\${1:variable} as \\$\\${2:value}) {\n\t\t\\${3:// code...}\n\t}\nsnippet foreachk\n\tforeach (\\$\\${1:variable} as \\$\\${2:key} => \\$\\${3:value}) {\n\t\t\\${4:// code...}\n\t}\n# \\$... = array (...)\nsnippet array\n\t\\$\\${1:arrayName} = array('\\${2}' => \\${3});\\${4}\nsnippet try\n\ttry {\n\t\t\\${2}\n\t} catch (\\${1:Exception} \\$e) {\n\t}\n# lambda with closure\nsnippet lambda\n\t\\${1:static }function (\\${2:args}) use (\\${3:&\\$x, \\$y /*put vars in scope (closure) */}) {\n\t\t\\${4}\n\t};\n# pre_dump();\nsnippet pd\n\techo '<pre>'; var_dump(\\${1}); echo '</pre>';\n# pre_dump(); die();\nsnippet pdd\n\techo '<pre>'; var_dump(\\${1}); echo '</pre>'; die(\\${2:});\nsnippet vd\n\tvar_dump(\\${1});\nsnippet vdd\n\tvar_dump(\\${1}); die(\\${2:});\nsnippet http_redirect\n\theader (\"HTTP/1.1 301 Moved Permanently\");\n\theader (\"Location: \".URL);\n\texit();\n# Getters & Setters\nsnippet gs\n\t/**\n\t * Gets the value of \\${1:foo}\n\t *\n\t * @return \\${2:\\$1}\n\t */\n\tpublic function get\\${3:\\$2}()\n\t{\n\t\treturn \\$this->\\${4:\\$1};\n\t}\n\n\t/**\n\t * Sets the value of \\$1\n\t *\n\t * @param \\$2 \\$\\$1 \\${5:description}\n\t *\n\t * @return \\${6:\\$FILENAME}\n\t */\n\tpublic function set\\$3(\\${7:\\$2 }\\$\\$1)\n\t{\n\t\t\\$this->\\$4 = \\$\\$1;\n\t\treturn \\$this;\n\t}\\${8}\n# anotation, get, and set, useful for doctrine\nsnippet ags\n\t/**\n\t * \\${1:description}\n\t *\n\t * @\\${7}\n\t */\n\t\\${2:protected} \\$\\${3:foo};\n\n\tpublic function get\\${4:\\$3}()\n\t{\n\t\treturn \\$this->\\$3;\n\t}\n\n\tpublic function set\\$4(\\${5:\\$4 }\\$\\${6:\\$3})\n\t{\n\t\t\\$this->\\$3 = \\$\\$6;\n\t\treturn \\$this;\n\t}\nsnippet rett\n\treturn true;\nsnippet retf\n\treturn false;\nscope html\nsnippet <?\n\t<?php\n\n\t\\${1}\nsnippet <?e\n\t<?php echo \\${1} ?>\n# this one is for php5.4\nsnippet <?=\n\t<?=\\${1}?>\nsnippet ifil\n\t<?php if (\\${1:/* condition */}): ?>\n\t\t\\${2:<!-- code... -->}\n\t<?php endif; ?>\nsnippet ifeil\n\t<?php if (\\${1:/* condition */}): ?>\n\t\t\\${2:<!-- html... -->}\n\t<?php else: ?>\n\t\t\\${3:<!-- html... -->}\n\t<?php endif; ?>\n\t\\${4}\nsnippet foreachil\n\t<?php foreach (\\$\\${1:variable} as \\$\\${2:value}): ?>\n\t\t\\${3:<!-- html... -->}\n\t<?php endforeach; ?>\nsnippet foreachkil\n\t<?php foreach (\\$\\${1:variable} as \\$\\${2:key} => \\$\\${3:value}): ?>\n\t\t\\${4:<!-- html... -->}\n\t<?php endforeach; ?>\nscope html-tag\nsnippet ifil\\\\n\\\\\n\t<?php if (\\${1:true}): ?>\\${2:code}<?php endif; ?>\nsnippet ifeil\\\\n\\\\\n\t<?php if (\\${1:true}): ?>\\${2:code}<?php else: ?>\\${3:code}<?php endif; ?>\\${4}\n`;\n"
  },
  {
    "path": "src/snippets/python.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./python.snippets\");\nexports.scope = \"python\";\n"
  },
  {
    "path": "src/snippets/python.snippets.js",
    "content": "module.exports = `snippet #!\n\t#!/usr/bin/env python\nsnippet imp\n\timport \\${1:module}\nsnippet from\n\tfrom \\${1:package} import \\${2:module}\n# Module Docstring\nsnippet docs\n\t'''\n\tFile: \\${1:FILENAME:file_name}\n\tAuthor: \\${2:author}\n\tDescription: \\${3}\n\t'''\nsnippet wh\n\twhile \\${1:condition}:\n\t\t\\${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n\twhile True:\n\t\t\\${1:# TODO: write code...}\n\t\tif \\${2:condition}:\n\t\t\tbreak\nsnippet with\n\twith \\${1:expr} as \\${2:var}:\n\t\t\\${3:# TODO: write code...}\n# New Class\nsnippet cl\n\tclass \\${1:ClassName}(\\${2:object}):\n\t\t\"\"\"\\${3:docstring for \\$1}\"\"\"\n\t\tdef __init__(self, \\${4:arg}):\n\t\t\t\\${5:super(\\$1, self).__init__()}\n\t\t\tself.\\$4 = \\$4\n\t\t\t\\${6}\n# New Function\nsnippet def\n\tdef \\${1:fname}(\\${2:\\`indent('.') ? 'self' : ''\\`}):\n\t\t\"\"\"\\${3:docstring for \\$1}\"\"\"\n\t\t\\${4:# TODO: write code...}\nsnippet deff\n\tdef \\${1:fname}(\\${2:\\`indent('.') ? 'self' : ''\\`}):\n\t\t\\${3:# TODO: write code...}\n# New Method\nsnippet defs\n\tdef \\${1:mname}(self, \\${2:arg}):\n\t\t\\${3:# TODO: write code...}\n# New Property\nsnippet property\n\tdef \\${1:foo}():\n\t\tdoc = \"\\${2:The \\$1 property.}\"\n\t\tdef fget(self):\n\t\t\t\\${3:return self._\\$1}\n\t\tdef fset(self, value):\n\t\t\t\\${4:self._\\$1 = value}\n# Ifs\nsnippet if\n\tif \\${1:condition}:\n\t\t\\${2:# TODO: write code...}\nsnippet el\n\telse:\n\t\t\\${1:# TODO: write code...}\nsnippet ei\n\telif \\${1:condition}:\n\t\t\\${2:# TODO: write code...}\n# For\nsnippet for\n\tfor \\${1:item} in \\${2:items}:\n\t\t\\${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n\t# -*- coding: utf-8 -*-\nsnippet clatin1\n\t# -*- coding: latin-1 -*-\nsnippet cascii\n\t# -*- coding: ascii -*-\n# Lambda\nsnippet ld\n\t\\${1:var} = lambda \\${2:vars} : \\${3:action}\nsnippet .\n\tself.\nsnippet try Try/Except\n\ttry:\n\t\t\\${1:# TODO: write code...}\n\texcept \\${2:Exception}, \\${3:e}:\n\t\t\\${4:raise \\$3}\nsnippet try Try/Except/Else\n\ttry:\n\t\t\\${1:# TODO: write code...}\n\texcept \\${2:Exception}, \\${3:e}:\n\t\t\\${4:raise \\$3}\n\telse:\n\t\t\\${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n\ttry:\n\t\t\\${1:# TODO: write code...}\n\texcept \\${2:Exception}, \\${3:e}:\n\t\t\\${4:raise \\$3}\n\tfinally:\n\t\t\\${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n\ttry:\n\t\t\\${1:# TODO: write code...}\n\texcept \\${2:Exception}, \\${3:e}:\n\t\t\\${4:raise \\$3}\n\telse:\n\t\t\\${5:# TODO: write code...}\n\tfinally:\n\t\t\\${6:# TODO: write code...}\n# if __name__ == '__main__':\nsnippet ifmain\n\tif __name__ == '__main__':\n\t\t\\${1:main()}\n# __magic__\nsnippet _\n\t__\\${1:init}__\\${2}\n# python debugger (pdb)\nsnippet pdb\n\timport pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n\timport ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n\timport pdbpp; pdbpp.set_trace()\nsnippet pprint\n\timport pprint; pprint.pprint(\\${1})\\${2}\nsnippet \"\n\t\"\"\"\n\t\\${1:doc}\n\t\"\"\"\n# test function/method\nsnippet test\n\tdef test_\\${1:description}(\\${2:self}):\n\t\t\\${3:# TODO: write code...}\n# test case\nsnippet testcase\n\tclass \\${1:ExampleCase}(unittest.TestCase):\n\t\t\n\t\tdef test_\\${2:description}(self):\n\t\t\t\\${3:# TODO: write code...}\nsnippet fut\n\tfrom __future__ import \\${1}\n#getopt\nsnippet getopt\n\ttry:\n\t\t# Short option syntax: \"hv:\"\n\t\t# Long option syntax: \"help\" or \"verbose=\"\n\t\topts, args = getopt.getopt(sys.argv[1:], \"\\${1:short_options}\", [\\${2:long_options}])\n\t\n\texcept getopt.GetoptError, err:\n\t\t# Print debug info\n\t\tprint str(err)\n\t\t\\${3:error_action}\n\n\tfor option, argument in opts:\n\t\tif option in (\"-h\", \"--help\"):\n\t\t\t\\${4}\n\t\telif option in (\"-v\", \"--verbose\"):\n\t\t\tverbose = argument\n`;\n"
  },
  {
    "path": "src/snippets/r.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./r.snippets\");\nexports.scope = \"r\";\n"
  },
  {
    "path": "src/snippets/r.snippets.js",
    "content": "module.exports = `snippet #!\n\t#!/usr/bin/env Rscript\n\n# includes\nsnippet lib\n\tlibrary(\\${1:package})\nsnippet req\n\trequire(\\${1:package})\nsnippet source\n\tsource('\\${1:file}')\n\n# conditionals\nsnippet if\n\tif (\\${1:condition}) {\n\t\t\\${2:code}\n\t}\nsnippet el\n\telse {\n\t\t\\${1:code}\n\t}\nsnippet ei\n\telse if (\\${1:condition}) {\n\t\t\\${2:code}\n\t}\n\n# functions\nsnippet fun\n\t\\${1:name} = function (\\${2:variables}) {\n\t\t\\${3:code}\n\t}\nsnippet ret\n\treturn(\\${1:code})\n\n# dataframes, lists, etc\nsnippet df\n\t\\${1:name}[\\${2:rows}, \\${3:cols}]\nsnippet c\n\tc(\\${1:items})\nsnippet li\n\tlist(\\${1:items})\nsnippet mat\n\tmatrix(\\${1:data}, nrow=\\${2:rows}, ncol=\\${3:cols})\n\n# apply functions\nsnippet apply\n\tapply(\\${1:array}, \\${2:margin}, \\${3:function})\nsnippet lapply\n\tlapply(\\${1:list}, \\${2:function})\nsnippet sapply\n\tsapply(\\${1:list}, \\${2:function})\nsnippet vapply\n\tvapply(\\${1:list}, \\${2:function}, \\${3:type})\nsnippet mapply\n\tmapply(\\${1:function}, \\${2:...})\nsnippet tapply\n\ttapply(\\${1:vector}, \\${2:index}, \\${3:function})\nsnippet rapply\n\trapply(\\${1:list}, \\${2:function})\n\n# plyr functions\nsnippet dd\n\tddply(\\${1:frame}, \\${2:variables}, \\${3:function})\nsnippet dl\n\tdlply(\\${1:frame}, \\${2:variables}, \\${3:function})\nsnippet da\n\tdaply(\\${1:frame}, \\${2:variables}, \\${3:function})\nsnippet d_\n\td_ply(\\${1:frame}, \\${2:variables}, \\${3:function})\n\nsnippet ad\n\tadply(\\${1:array}, \\${2:margin}, \\${3:function})\nsnippet al\n\talply(\\${1:array}, \\${2:margin}, \\${3:function})\nsnippet aa\n\taaply(\\${1:array}, \\${2:margin}, \\${3:function})\nsnippet a_\n\ta_ply(\\${1:array}, \\${2:margin}, \\${3:function})\n\nsnippet ld\n\tldply(\\${1:list}, \\${2:function})\nsnippet ll\n\tllply(\\${1:list}, \\${2:function})\nsnippet la\n\tlaply(\\${1:list}, \\${2:function})\nsnippet l_\n\tl_ply(\\${1:list}, \\${2:function})\n\nsnippet md\n\tmdply(\\${1:matrix}, \\${2:function})\nsnippet ml\n\tmlply(\\${1:matrix}, \\${2:function})\nsnippet ma\n\tmaply(\\${1:matrix}, \\${2:function})\nsnippet m_\n\tm_ply(\\${1:matrix}, \\${2:function})\n\n# plot functions\nsnippet pl\n\tplot(\\${1:x}, \\${2:y})\nsnippet ggp\n\tggplot(\\${1:data}, aes(\\${2:aesthetics}))\nsnippet img\n\t\\${1:(jpeg,bmp,png,tiff)}(filename=\"\\${2:filename}\", width=\\${3}, height=\\${4}, unit=\"\\${5}\")\n\t\\${6:plot}\n\tdev.off()\n\n# statistical test functions\nsnippet fis\n\tfisher.test(\\${1:x}, \\${2:y})\nsnippet chi\n\tchisq.test(\\${1:x}, \\${2:y})\nsnippet tt\n\tt.test(\\${1:x}, \\${2:y})\nsnippet wil\n\twilcox.test(\\${1:x}, \\${2:y})\nsnippet cor\n\tcor.test(\\${1:x}, \\${2:y})\nsnippet fte\n\tvar.test(\\${1:x}, \\${2:y})\nsnippet kvt \n\tkv.test(\\${1:x}, \\${2:y})\n`;\n"
  },
  {
    "path": "src/snippets/razor.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./razor.snippets\");\nexports.scope = \"razor\";\n"
  },
  {
    "path": "src/snippets/razor.snippets.js",
    "content": "module.exports = `snippet if\n(\\${1} == \\${2}) {\n\t\\${3}\n}`;\n"
  },
  {
    "path": "src/snippets/robot.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./robot.snippets\");\nexports.scope = \"robot\";\n"
  },
  {
    "path": "src/snippets/robot.snippets.js",
    "content": "module.exports = `# scope: robot\n### Sections\nsnippet settingssection\ndescription *** Settings *** section\n\t*** Settings ***\n\tLibrary    \\${1}\n\nsnippet keywordssection\ndescription *** Keywords *** section\n\t*** Keywords ***\n\t\\${1:Keyword Name}\n\t    [Arguments]    \\\\\\${\\${2:Example Arg 1}}\n\t\nsnippet testcasessection\ndescription *** Test Cases *** section\n\t*** Test Cases ***\n\t\\${1:First Test Case}\n\t    \\${2:Log    Example Arg}\n\nsnippet variablessection\ndescription *** Variables *** section\n\t*** Variables ***\n\t\\\\\\${\\${1:Variable Name}}=    \\${2:Variable Value}\n\n### Helpful keywords\nsnippet testcase\ndescription A test case\n\t\\${1:Test Case Name}\n\t    \\${2:Log    Example log message}\n\t\nsnippet keyword\ndescription A keyword\n\t\\${1:Example Keyword}\n\t    [Arguments]    \\\\\\${\\${2:Example Arg 1}}\n\n### Built Ins\nsnippet forinr\ndescription For In Range Loop\n\tFOR    \\\\\\${\\${1:Index}}    IN RANGE     \\\\\\${\\${2:10}}\n\t    Log     \\\\\\${\\${1:Index}}\n\tEND\n\nsnippet forin\ndescription For In Loop\n\tFOR    \\\\\\${\\${1:Item}}    IN     @{\\${2:List Variable}}\n\t    Log     \\\\\\${\\${1:Item}}\n\tEND\n\nsnippet if\ndescription If Statement\n\tIF    \\${1:condition}\n\t    \\${2:Do something}\n\tEND\n\nsnippet else\ndescription If Statement\n\tIF    \\${1:Condition}\n\t    \\${2:Do something}\n\tELSE\n\t    \\${3:Otherwise do this}\n\tEND\n\nsnippet elif\ndescription Else-If Statement\n\tIF    \\${1:Condition 1}\n\t    \\${2:Do something}\n\tELSE IF    \\${3:Condition 2}\n\t    \\${4:Do something else}\n\tEND\n`;\n"
  },
  {
    "path": "src/snippets/rst.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./rst.snippets\");\nexports.scope = \"rst\";\n"
  },
  {
    "path": "src/snippets/rst.snippets.js",
    "content": "module.exports = `# rst\n\nsnippet :\n\t:\\${1:field name}: \\${2:field body}\nsnippet *\n\t*\\${1:Emphasis}*\nsnippet **\n\t**\\${1:Strong emphasis}**\nsnippet _\n\t\\\\\\`\\${1:hyperlink-name}\\\\\\`_\n\t.. _\\\\\\`\\$1\\\\\\`: \\${2:link-block}\nsnippet =\n\t\\${1:Title}\n\t=====\\${2:=}\n\t\\${3}\nsnippet -\n\t\\${1:Title}\n\t-----\\${2:-}\n\t\\${3}\nsnippet cont:\n\t.. contents::\n\t\n`;\n"
  },
  {
    "path": "src/snippets/ruby.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./ruby.snippets\");\nexports.scope = \"ruby\";\n"
  },
  {
    "path": "src/snippets/ruby.snippets.js",
    "content": "module.exports = `########################################\n# Ruby snippets - for Rails, see below #\n########################################\n\n# encoding for Ruby 1.9\nsnippet enc\n\t# encoding: utf-8\n\n# #!/usr/bin/env ruby\nsnippet #!\n\t#!/usr/bin/env ruby\n\t# encoding: utf-8\n\n# New Block\nsnippet =b\n\t=begin rdoc\n\t\t\\${1}\n\t=end\nsnippet y\n\t:yields: \\${1:arguments}\nsnippet rb\n\t#!/usr/bin/env ruby -wKU\nsnippet beg\n\tbegin\n\t\t\\${3}\n\trescue \\${1:Exception} => \\${2:e}\n\tend\n\nsnippet req require\n\trequire \"\\${1}\"\\${2}\nsnippet #\n\t# =>\nsnippet end\n\t__END__\nsnippet case\n\tcase \\${1:object}\n\twhen \\${2:condition}\n\t\t\\${3}\n\tend\nsnippet when\n\twhen \\${1:condition}\n\t\t\\${2}\nsnippet def\n\tdef \\${1:method_name}\n\t\t\\${2}\n\tend\nsnippet deft\n\tdef test_\\${1:case_name}\n\t\t\\${2}\n\tend\nsnippet if\n\tif \\${1:condition}\n\t\t\\${2}\n\tend\nsnippet ife\n\tif \\${1:condition}\n\t\t\\${2}\n\telse\n\t\t\\${3}\n\tend\nsnippet elsif\n\telsif \\${1:condition}\n\t\t\\${2}\nsnippet unless\n\tunless \\${1:condition}\n\t\t\\${2}\n\tend\nsnippet while\n\twhile \\${1:condition}\n\t\t\\${2}\n\tend\nsnippet for\n\tfor \\${1:e} in \\${2:c}\n\t\t\\${3}\n\tend\nsnippet until\n\tuntil \\${1:condition}\n\t\t\\${2}\n\tend\nsnippet cla class .. end\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\t\\${2}\n\tend\nsnippet cla class .. initialize .. end\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\tdef initialize(\\${2:args})\n\t\t\t\\${3}\n\t\tend\n\tend\nsnippet cla class .. < ParentClass .. initialize .. end\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`} < \\${2:ParentClass}\n\t\tdef initialize(\\${3:args})\n\t\t\t\\${4}\n\t\tend\n\tend\nsnippet cla ClassName = Struct .. do .. end\n\t\\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`} = Struct.new(:\\${2:attr_names}) do\n\t\tdef \\${3:method_name}\n\t\t\t\\${4}\n\t\tend\n\tend\nsnippet cla class BlankSlate .. initialize .. end\n\tclass \\${1:BlankSlate}\n\t\tinstance_methods.each { |meth| undef_method(meth) unless meth =~ /\\\\A__/ }\n\tend\nsnippet cla class << self .. end\n\tclass << \\${1:self}\n\t\t\\${2}\n\tend\n# class .. < DelegateClass .. initialize .. end\nsnippet cla-\n\tclass \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`} < DelegateClass(\\${2:ParentClass})\n\t\tdef initialize(\\${3:args})\n\t\t\tsuper(\\${4:del_obj})\n\n\t\t\t\\${5}\n\t\tend\n\tend\nsnippet mod module .. end\n\tmodule \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\t\\${2}\n\tend\nsnippet mod module .. module_function .. end\n\tmodule \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\tmodule_function\n\n\t\t\\${2}\n\tend\nsnippet mod module .. ClassMethods .. end\n\tmodule \\${1:\\`substitute(Filename(), '\\\\(_\\\\|^\\\\)\\\\(.\\\\)', '\\\\u\\\\2', 'g')\\`}\n\t\tmodule ClassMethods\n\t\t\t\\${2}\n\t\tend\n\n\t\tmodule InstanceMethods\n\n\t\tend\n\n\t\tdef self.included(receiver)\n\t\t\treceiver.extend         ClassMethods\n\t\t\treceiver.send :include, InstanceMethods\n\t\tend\n\tend\n# attr_reader\nsnippet r\n\tattr_reader :\\${1:attr_names}\n# attr_writer\nsnippet w\n\tattr_writer :\\${1:attr_names}\n# attr_accessor\nsnippet rw\n\tattr_accessor :\\${1:attr_names}\nsnippet atp\n\tattr_protected :\\${1:attr_names}\nsnippet ata\n\tattr_accessible :\\${1:attr_names}\n# include Enumerable\nsnippet Enum\n\tinclude Enumerable\n\n\tdef each(&block)\n\t\t\\${1}\n\tend\n# include Comparable\nsnippet Comp\n\tinclude Comparable\n\n\tdef <=>(other)\n\t\t\\${1}\n\tend\n# extend Forwardable\nsnippet Forw-\n\textend Forwardable\n# def self\nsnippet defs\n\tdef self.\\${1:class_method_name}\n\t\t\\${2}\n\tend\n# def method_missing\nsnippet defmm\n\tdef method_missing(meth, *args, &blk)\n\t\t\\${1}\n\tend\nsnippet defd\n\tdef_delegator :\\${1:@del_obj}, :\\${2:del_meth}, :\\${3:new_name}\nsnippet defds\n\tdef_delegators :\\${1:@del_obj}, :\\${2:del_methods}\nsnippet am\n\talias_method :\\${1:new_name}, :\\${2:old_name}\nsnippet app\n\tif __FILE__ == \\$PROGRAM_NAME\n\t\t\\${1}\n\tend\n# usage_if()\nsnippet usai\n\tif ARGV.\\${1}\n\t\tabort \"Usage: #{\\$PROGRAM_NAME} \\${2:ARGS_GO_HERE}\"\\${3}\n\tend\n# usage_unless()\nsnippet usau\n\tunless ARGV.\\${1}\n\t\tabort \"Usage: #{\\$PROGRAM_NAME} \\${2:ARGS_GO_HERE}\"\\${3}\n\tend\nsnippet array\n\tArray.new(\\${1:10}) { |\\${2:i}| \\${3} }\nsnippet hash\n\tHash.new { |\\${1:hash}, \\${2:key}| \\$1[\\$2] = \\${3} }\nsnippet file File.foreach() { |line| .. }\n\tFile.foreach(\\${1:\"path/to/file\"}) { |\\${2:line}| \\${3} }\nsnippet file File.read()\n\tFile.read(\\${1:\"path/to/file\"})\\${2}\nsnippet Dir Dir.global() { |file| .. }\n\tDir.glob(\\${1:\"dir/glob/*\"}) { |\\${2:file}| \\${3} }\nsnippet Dir Dir[\"..\"]\n\tDir[\\${1:\"glob/**/*.rb\"}]\\${2}\nsnippet dir\n\tFilename.dirname(__FILE__)\nsnippet deli\n\tdelete_if { |\\${1:e}| \\${2} }\nsnippet fil\n\tfill(\\${1:range}) { |\\${2:i}| \\${3} }\n# flatten_once()\nsnippet flao\n\tinject(Array.new) { |\\${1:arr}, \\${2:a}| \\$1.push(*\\$2)}\\${3}\nsnippet zip\n\tzip(\\${1:enums}) { |\\${2:row}| \\${3} }\n# downto(0) { |n| .. }\nsnippet dow\n\tdownto(\\${1:0}) { |\\${2:n}| \\${3} }\nsnippet ste\n\tstep(\\${1:2}) { |\\${2:n}| \\${3} }\nsnippet tim\n\ttimes { |\\${1:n}| \\${2} }\nsnippet upt\n\tupto(\\${1:1.0/0.0}) { |\\${2:n}| \\${3} }\nsnippet loo\n\tloop { \\${1} }\nsnippet ea\n\teach { |\\${1:e}| \\${2} }\nsnippet ead\n\teach do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet eab\n\teach_byte { |\\${1:byte}| \\${2} }\nsnippet eac- each_char { |chr| .. }\n\teach_char { |\\${1:chr}| \\${2} }\nsnippet eac- each_cons(..) { |group| .. }\n\teach_cons(\\${1:2}) { |\\${2:group}| \\${3} }\nsnippet eai\n\teach_index { |\\${1:i}| \\${2} }\nsnippet eaid\n\teach_index do |\\${1:i}|\n\t\t\\${2}\n\tend\nsnippet eak\n\teach_key { |\\${1:key}| \\${2} }\nsnippet eakd\n\teach_key do |\\${1:key}|\n\t\t\\${2}\n\tend\nsnippet eal\n\teach_line { |\\${1:line}| \\${2} }\nsnippet eald\n\teach_line do |\\${1:line}|\n\t\t\\${2}\n\tend\nsnippet eap\n\teach_pair { |\\${1:name}, \\${2:val}| \\${3} }\nsnippet eapd\n\teach_pair do |\\${1:name}, \\${2:val}|\n\t\t\\${3}\n\tend\nsnippet eas-\n\teach_slice(\\${1:2}) { |\\${2:group}| \\${3} }\nsnippet easd-\n\teach_slice(\\${1:2}) do |\\${2:group}|\n\t\t\\${3}\n\tend\nsnippet eav\n\teach_value { |\\${1:val}| \\${2} }\nsnippet eavd\n\teach_value do |\\${1:val}|\n\t\t\\${2}\n\tend\nsnippet eawi\n\teach_with_index { |\\${1:e}, \\${2:i}| \\${3} }\nsnippet eawid\n\teach_with_index do |\\${1:e},\\${2:i}|\n\t\t\\${3}\n\tend\nsnippet reve\n\treverse_each { |\\${1:e}| \\${2} }\nsnippet reved\n\treverse_each do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet inj\n\tinject(\\${1:init}) { |\\${2:mem}, \\${3:var}| \\${4} }\nsnippet injd\n\tinject(\\${1:init}) do |\\${2:mem}, \\${3:var}|\n\t\t\\${4}\n\tend\nsnippet map\n\tmap { |\\${1:e}| \\${2} }\nsnippet mapd\n\tmap do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet mapwi-\n\tenum_with_index.map { |\\${1:e}, \\${2:i}| \\${3} }\nsnippet sor\n\tsort { |a, b| \\${1} }\nsnippet sorb\n\tsort_by { |\\${1:e}| \\${2} }\nsnippet ran\n\tsort_by { rand }\nsnippet all\n\tall? { |\\${1:e}| \\${2} }\nsnippet any\n\tany? { |\\${1:e}| \\${2} }\nsnippet cl\n\tclassify { |\\${1:e}| \\${2} }\nsnippet col\n\tcollect { |\\${1:e}| \\${2} }\nsnippet cold\n\tcollect do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet det\n\tdetect { |\\${1:e}| \\${2} }\nsnippet detd\n\tdetect do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet fet\n\tfetch(\\${1:name}) { |\\${2:key}| \\${3} }\nsnippet fin\n\tfind { |\\${1:e}| \\${2} }\nsnippet find\n\tfind do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet fina\n\tfind_all { |\\${1:e}| \\${2} }\nsnippet finad\n\tfind_all do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet gre\n\tgrep(\\${1:/pattern/}) { |\\${2:match}| \\${3} }\nsnippet sub\n\t\\${1:g}sub(\\${2:/pattern/}) { |\\${3:match}| \\${4} }\nsnippet sca\n\tscan(\\${1:/pattern/}) { |\\${2:match}| \\${3} }\nsnippet scad\n\tscan(\\${1:/pattern/}) do |\\${2:match}|\n\t\t\\${3}\n\tend\nsnippet max\n\tmax { |a, b| \\${1} }\nsnippet min\n\tmin { |a, b| \\${1} }\nsnippet par\n\tpartition { |\\${1:e}| \\${2} }\nsnippet pard\n\tpartition do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet rej\n\treject { |\\${1:e}| \\${2} }\nsnippet rejd\n\treject do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet sel\n\tselect { |\\${1:e}| \\${2} }\nsnippet seld\n\tselect do |\\${1:e}|\n\t\t\\${2}\n\tend\nsnippet lam\n\tlambda { |\\${1:args}| \\${2} }\nsnippet doo\n\tdo\n\t\t\\${1}\n\tend\nsnippet dov\n\tdo |\\${1:variable}|\n\t\t\\${2}\n\tend\nsnippet :\n\t:\\${1:key} => \\${2:\"value\"}\\${3}\nsnippet ope\n\topen(\\${1:\"path/or/url/or/pipe\"}, \"\\${2:w}\") { |\\${3:io}| \\${4} }\n# path_from_here()\nsnippet fpath\n\tFile.join(File.dirname(__FILE__), *%2[\\${1:rel path here}])\\${2}\n# unix_filter {}\nsnippet unif\n\tARGF.each_line\\${1} do |\\${2:line}|\n\t\t\\${3}\n\tend\n# option_parse {}\nsnippet optp\n\trequire \"optparse\"\n\n\toptions = {\\${1:default => \"args\"}}\n\n\tARGV.options do |opts|\n\t\topts.banner = \"Usage: #{File.basename(\\$PROGRAM_NAME)}\nsnippet opt\n\topts.on( \"-\\${1:o}\", \"--\\${2:long-option-name}\", \\${3:String},\n\t         \"\\${4:Option description.}\") do |\\${5:opt}|\n\t\t\\${6}\n\tend\nsnippet tc\n\trequire \"test/unit\"\n\n\trequire \"\\${1:library_file_name}\"\n\n\tclass Test\\${2:\\$1} < Test::Unit::TestCase\n\t\tdef test_\\${3:case_name}\n\t\t\t\\${4}\n\t\tend\n\tend\nsnippet ts\n\trequire \"test/unit\"\n\n\trequire \"tc_\\${1:test_case_file}\"\n\trequire \"tc_\\${2:test_case_file}\"\\${3}\nsnippet as\n\tassert \\${1:test}, \"\\${2:Failure message.}\"\\${3}\nsnippet ase\n\tassert_equal \\${1:expected}, \\${2:actual}\\${3}\nsnippet asne\n\tassert_not_equal \\${1:unexpected}, \\${2:actual}\\${3}\nsnippet asid\n\tassert_in_delta \\${1:expected_float}, \\${2:actual_float}, \\${3:2 ** -20}\\${4}\nsnippet asio\n\tassert_instance_of \\${1:ExpectedClass}, \\${2:actual_instance}\\${3}\nsnippet asko\n\tassert_kind_of \\${1:ExpectedKind}, \\${2:actual_instance}\\${3}\nsnippet asn\n\tassert_nil \\${1:instance}\\${2}\nsnippet asnn\n\tassert_not_nil \\${1:instance}\\${2}\nsnippet asm\n\tassert_match /\\${1:expected_pattern}/, \\${2:actual_string}\\${3}\nsnippet asnm\n\tassert_no_match /\\${1:unexpected_pattern}/, \\${2:actual_string}\\${3}\nsnippet aso\n\tassert_operator \\${1:left}, :\\${2:operator}, \\${3:right}\\${4}\nsnippet asr\n\tassert_raise \\${1:Exception} { \\${2} }\nsnippet asrd\n\tassert_raise \\${1:Exception} do\n\t\t\\${2}\n\tend\nsnippet asnr\n\tassert_nothing_raised \\${1:Exception} { \\${2} }\nsnippet asnrd\n\tassert_nothing_raised \\${1:Exception} do\n\t\t\\${2}\n\tend\nsnippet asrt\n\tassert_respond_to \\${1:object}, :\\${2:method}\\${3}\nsnippet ass assert_same(..)\n\tassert_same \\${1:expected}, \\${2:actual}\\${3}\nsnippet ass assert_send(..)\n\tassert_send [\\${1:object}, :\\${2:message}, \\${3:args}]\\${4}\nsnippet asns\n\tassert_not_same \\${1:unexpected}, \\${2:actual}\\${3}\nsnippet ast\n\tassert_throws :\\${1:expected} { \\${2} }\nsnippet astd\n\tassert_throws :\\${1:expected} do\n\t\t\\${2}\n\tend\nsnippet asnt\n\tassert_nothing_thrown { \\${1} }\nsnippet asntd\n\tassert_nothing_thrown do\n\t\t\\${1}\n\tend\nsnippet fl\n\tflunk \"\\${1:Failure message.}\"\\${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n\tTESTS = \\${1:10_000}\n\tBenchmark.bmbm do |results|\n\t\t\\${2}\n\tend\nsnippet rep\n\tresults.report(\"\\${1:name}:\") { TESTS.times { \\${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n\tFile.open(\\${1:\"path/to/file.dump\"}, \"wb\") { |\\${2:file}| Marshal.dump(\\${3:obj}, \\$2) }\\${4}\n# Mashal.load(obj)\nsnippet Ml\n\tFile.open(\\${1:\"path/to/file.dump\"}, \"rb\") { |\\${2:file}| Marshal.load(\\$2) }\\${3}\n# deep_copy(..)\nsnippet deec\n\tMarshal.load(Marshal.dump(\\${1:obj_to_copy}))\\${2}\nsnippet Pn-\n\tPStore.new(\\${1:\"file_name.pstore\"})\\${2}\nsnippet tra\n\ttransaction(\\${1:true}) { \\${2} }\n# xmlread(..)\nsnippet xml-\n\tREXML::Document.new(File.read(\\${1:\"path/to/file\"}))\\${2}\n# xpath(..) { .. }\nsnippet xpa\n\telements.each(\\${1:\"//Xpath\"}) do |\\${2:node}|\n\t\t\\${3}\n\tend\n# class_from_name()\nsnippet clafn\n\tsplit(\"::\").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n\tclass << self; self end\nsnippet nam\n\tnamespace :\\${1:\\`Filename()\\`} do\n\t\t\\${2}\n\tend\nsnippet tas\n\tdesc \"\\${1:Task description}\"\n\ttask :\\${2:task_name => [:dependent, :tasks]} do\n\t\t\\${3}\n\tend\n# block\nsnippet b\n\t{ |\\${1:var}| \\${2} }\nsnippet begin\n\tbegin\n\t\traise 'A test exception.'\n\trescue Exception => e\n\t\tputs e.message\n\t\tputs e.backtrace.inspect\n\telse\n\t\t# other exception\n\tensure\n\t\t# always executed\n\tend\n\n#debugging\nsnippet debug\n\trequire 'ruby-debug'; debugger; true;\nsnippet pry\n\trequire 'pry'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n\tassert_redirected_to \\${1::action => \"\\${2:index}\"}\nsnippet artnp\n\tassert_redirected_to \\${1:parent}_\\${2:child}_path(\\${3:@\\$1}, \\${4:@\\$2})\nsnippet artnpp\n\tassert_redirected_to \\${1:parent}_\\${2:child}_path(\\${3:@\\$1})\nsnippet artp\n\tassert_redirected_to \\${1:model}_path(\\${2:@\\$1})\nsnippet artpp\n\tassert_redirected_to \\${1:model}s_path\nsnippet asd\n\tassert_difference \"\\${1:Model}.\\${2:count}\", \\$1 do\n\t\t\\${3}\n\tend\nsnippet asnd\n\tassert_no_difference \"\\${1:Model}.\\${2:count}\" do\n\t\t\\${3}\n\tend\nsnippet asre\n\tassert_response :\\${1:success}, @response.body\\${2}\nsnippet asrj\n\tassert_rjs :\\${1:replace}, \"\\${2:dom id}\"\nsnippet ass assert_select(..)\n\tassert_select '\\${1:path}', :\\${2:text} => '\\${3:inner_html' \\${4:do}\nsnippet bf\n\tbefore_filter :\\${1:method}\nsnippet bt\n\tbelongs_to :\\${1:association}\nsnippet crw\n\tcattr_accessor :\\${1:attr_names}\nsnippet defcreate\n\tdef create\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.new(params[:\\$1])\n\n\t\trespond_to do |wants|\n\t\t\tif @\\$1.save\n\t\t\t\tflash[:notice] = '\\$2 was successfully created.'\n\t\t\t\twants.html { redirect_to(@\\$1) }\n\t\t\t\twants.xml  { render :xml => @\\$1, :status => :created, :location => @\\$1 }\n\t\t\telse\n\t\t\t\twants.html { render :action => \"new\" }\n\t\t\t\twants.xml  { render :xml => @\\$1.errors, :status => :unprocessable_entity }\n\t\t\tend\n\t\tend\n\tend\\${3}\nsnippet defdestroy\n\tdef destroy\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.find(params[:id])\n\t\t@\\$1.destroy\n\n\t\trespond_to do |wants|\n\t\t\twants.html { redirect_to(\\$1s_url) }\n\t\t\twants.xml  { head :ok }\n\t\tend\n\tend\\${3}\nsnippet defedit\n\tdef edit\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.find(params[:id])\n\tend\nsnippet defindex\n\tdef index\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.all\n\n\t\trespond_to do |wants|\n\t\t\twants.html # index.html.erb\n\t\t\twants.xml  { render :xml => @\\$1s }\n\t\tend\n\tend\\${3}\nsnippet defnew\n\tdef new\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.new\n\n\t\trespond_to do |wants|\n\t\t\twants.html # new.html.erb\n\t\t\twants.xml  { render :xml => @\\$1 }\n\t\tend\n\tend\\${3}\nsnippet defshow\n\tdef show\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.find(params[:id])\n\n\t\trespond_to do |wants|\n\t\t\twants.html # show.html.erb\n\t\t\twants.xml  { render :xml => @\\$1 }\n\t\tend\n\tend\\${3}\nsnippet defupdate\n\tdef update\n\t\t@\\${1:model_class_name} = \\${2:ModelClassName}.find(params[:id])\n\n\t\trespond_to do |wants|\n\t\t\tif @\\$1.update_attributes(params[:\\$1])\n\t\t\t\tflash[:notice] = '\\$2 was successfully updated.'\n\t\t\t\twants.html { redirect_to(@\\$1) }\n\t\t\t\twants.xml  { head :ok }\n\t\t\telse\n\t\t\t\twants.html { render :action => \"edit\" }\n\t\t\t\twants.xml  { render :xml => @\\$1.errors, :status => :unprocessable_entity }\n\t\t\tend\n\t\tend\n\tend\\${3}\nsnippet flash\n\tflash[:\\${1:notice}] = \"\\${2}\"\nsnippet habtm\n\thas_and_belongs_to_many :\\${1:object}, :join_table => \"\\${2:table_name}\", :foreign_key => \"\\${3}_id\"\\${4}\nsnippet hm\n\thas_many :\\${1:object}\nsnippet hmd\n\thas_many :\\${1:other}s, :class_name => \"\\${2:\\$1}\", :foreign_key => \"\\${3:\\$1}_id\", :dependent => :destroy\\${4}\nsnippet hmt\n\thas_many :\\${1:object}, :through => :\\${2:object}\nsnippet ho\n\thas_one :\\${1:object}\nsnippet i18\n\tI18n.t('\\${1:type.key}')\\${2}\nsnippet ist\n\t<%= image_submit_tag(\"\\${1:agree.png}\", :id => \"\\${2:id}\"\\${3} %>\nsnippet log\n\tRails.logger.\\${1:debug} \\${2}\nsnippet log2\n\tRAILS_DEFAULT_LOGGER.\\${1:debug} \\${2}\nsnippet logd\n\tlogger.debug { \"\\${1:message}\" }\\${2}\nsnippet loge\n\tlogger.error { \"\\${1:message}\" }\\${2}\nsnippet logf\n\tlogger.fatal { \"\\${1:message}\" }\\${2}\nsnippet logi\n\tlogger.info { \"\\${1:message}\" }\\${2}\nsnippet logw\n\tlogger.warn { \"\\${1:message}\" }\\${2}\nsnippet mapc\n\t\\${1:map}.\\${2:connect} '\\${3:controller/:action/:id}'\nsnippet mapca\n\t\\${1:map}.catch_all \"*\\${2:anything}\", :controller => \"\\${3:default}\", :action => \"\\${4:error}\"\\${5}\nsnippet mapr\n\t\\${1:map}.resource :\\${2:resource}\nsnippet maprs\n\t\\${1:map}.resources :\\${2:resource}\nsnippet mapwo\n\t\\${1:map}.with_options :\\${2:controller} => '\\${3:thing}' do |\\$3|\n\t\t\\${4}\n\tend\nsnippet mbs\n\tbefore_save :\\${1:method}\nsnippet mcht\n\tchange_table :\\${1:table_name} do |t|\n\t\t\\${2}\n\tend\nsnippet mp\n\tmap(&:\\${1:id})\nsnippet mrw\n\tmattr_accessor :\\${1:attr_names}\nsnippet oa\n\torder(\"\\${1:field}\")\nsnippet od\n\torder(\"\\${1:field} DESC\")\nsnippet pa\n\tparams[:\\${1:id}]\\${2}\nsnippet ra\n\trender :action => \"\\${1:action}\"\nsnippet ral\n\trender :action => \"\\${1:action}\", :layout => \"\\${2:layoutname}\"\nsnippet rest\n\trespond_to do |wants|\n\t\twants.\\${1:html} { \\${2} }\n\tend\nsnippet rf\n\trender :file => \"\\${1:filepath}\"\nsnippet rfu\n\trender :file => \"\\${1:filepath}\", :use_full_path => \\${2:false}\nsnippet ri\n\trender :inline => \"\\${1:<%= 'hello' %>}\"\nsnippet ril\n\trender :inline => \"\\${1:<%= 'hello' %>}\", :locals => { \\${2::name} => \"\\${3:value}\"\\${4} }\nsnippet rit\n\trender :inline => \"\\${1:<%= 'hello' %>}\", :type => \\${2::rxml}\nsnippet rjson\n\trender :json => \\${1:text to render}\nsnippet rl\n\trender :layout => \"\\${1:layoutname}\"\nsnippet rn\n\trender :nothing => \\${1:true}\nsnippet rns\n\trender :nothing => \\${1:true}, :status => \\${2:401}\nsnippet rp\n\trender :partial => \"\\${1:item}\"\nsnippet rpc\n\trender :partial => \"\\${1:item}\", :collection => \\${2:@\\$1s}\nsnippet rpl\n\trender :partial => \"\\${1:item}\", :locals => { :\\${2:\\$1} => \\${3:@\\$1}\nsnippet rpo\n\trender :partial => \"\\${1:item}\", :object => \\${2:@\\$1}\nsnippet rps\n\trender :partial => \"\\${1:item}\", :status => \\${2:500}\nsnippet rt\n\trender :text => \"\\${1:text to render}\"\nsnippet rtl\n\trender :text => \"\\${1:text to render}\", :layout => \"\\${2:layoutname}\"\nsnippet rtlt\n\trender :text => \"\\${1:text to render}\", :layout => \\${2:true}\nsnippet rts\n\trender :text => \"\\${1:text to render}\", :status => \\${2:401}\nsnippet ru\n\trender :update do |\\${1:page}|\n\t\t\\$1.\\${2}\n\tend\nsnippet rxml\n\trender :xml => \\${1:text to render}\nsnippet sc\n\tscope :\\${1:name}, :where(:@\\${2:field} => \\${3:value})\nsnippet sl\n\tscope :\\${1:name}, lambda do |\\${2:value}|\n\t\twhere(\"\\${3:field = ?}\", \\${4:bind var})\n\tend\nsnippet sha1\n\tDigest::SHA1.hexdigest(\\${1:string})\nsnippet sweeper\n\tclass \\${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n\t\tobserve \\$1\n\n\t\tdef after_save(\\${2:model_class_name})\n\t\t\texpire_cache(\\$2)\n\t\tend\n\n\t\tdef after_destroy(\\$2)\n\t\t\texpire_cache(\\$2)\n\t\tend\n\n\t\tdef expire_cache(\\$2)\n\t\t\texpire_page\n\t\tend\n\tend\nsnippet tcb\n\tt.boolean :\\${1:title}\n\t\\${2}\nsnippet tcbi\n\tt.binary :\\${1:title}, :limit => \\${2:2}.megabytes\n\t\\${3}\nsnippet tcd\n\tt.decimal :\\${1:title}, :precision => \\${2:10}, :scale => \\${3:2}\n\t\\${4}\nsnippet tcda\n\tt.date :\\${1:title}\n\t\\${2}\nsnippet tcdt\n\tt.datetime :\\${1:title}\n\t\\${2}\nsnippet tcf\n\tt.float :\\${1:title}\n\t\\${2}\nsnippet tch\n\tt.change :\\${1:name}, :\\${2:string}, :\\${3:limit} => \\${4:80}\n\t\\${5}\nsnippet tci\n\tt.integer :\\${1:title}\n\t\\${2}\nsnippet tcl\n\tt.integer :lock_version, :null => false, :default => 0\n\t\\${1}\nsnippet tcr\n\tt.references :\\${1:taggable}, :polymorphic => { :default => '\\${2:Photo}' }\n\t\\${3}\nsnippet tcs\n\tt.string :\\${1:title}\n\t\\${2}\nsnippet tct\n\tt.text :\\${1:title}\n\t\\${2}\nsnippet tcti\n\tt.time :\\${1:title}\n\t\\${2}\nsnippet tcts\n\tt.timestamp :\\${1:title}\n\t\\${2}\nsnippet tctss\n\tt.timestamps\n\t\\${1}\nsnippet va\n\tvalidates_associated :\\${1:attribute}\nsnippet vao\n\tvalidates_acceptance_of :\\${1:terms}\nsnippet vc\n\tvalidates_confirmation_of :\\${1:attribute}\nsnippet ve\n\tvalidates_exclusion_of :\\${1:attribute}, :in => \\${2:%w( mov avi )}\nsnippet vf\n\tvalidates_format_of :\\${1:attribute}, :with => /\\${2:regex}/\nsnippet vi\n\tvalidates_inclusion_of :\\${1:attribute}, :in => %w(\\${2: mov avi })\nsnippet vl\n\tvalidates_length_of :\\${1:attribute}, :within => \\${2:3}..\\${3:20}\nsnippet vn\n\tvalidates_numericality_of :\\${1:attribute}\nsnippet vpo\n\tvalidates_presence_of :\\${1:attribute}\nsnippet vu\n\tvalidates_uniqueness_of :\\${1:attribute}\nsnippet wants\n\twants.\\${1:js|xml|html} { \\${2} }\nsnippet wc\n\twhere(\\${1:\"conditions\"}\\${2:, bind_var})\nsnippet wh\n\twhere(\\${1:field} => \\${2:value})\nsnippet xdelete\n\txhr :delete, :\\${1:destroy}, :id => \\${2:1}\\${3}\nsnippet xget\n\txhr :get, :\\${1:show}, :id => \\${2:1}\\${3}\nsnippet xpost\n\txhr :post, :\\${1:create}, :\\${2:object} => { \\${3} }\nsnippet xput\n\txhr :put, :\\${1:update}, :id => \\${2:1}, :\\${3:object} => { \\${4} }\\${5}\nsnippet test\n\ttest \"should \\${1:do something}\" do\n\t\t\\${2}\n\tend\n#migrations\nsnippet mac\n\tadd_column :\\${1:table_name}, :\\${2:column_name}, :\\${3:data_type}\nsnippet mrc\n\tremove_column :\\${1:table_name}, :\\${2:column_name}\nsnippet mrnc\n\trename_column :\\${1:table_name}, :\\${2:old_column_name}, :\\${3:new_column_name}\nsnippet mcc\n\tchange_column :\\${1:table}, :\\${2:column}, :\\${3:type}\nsnippet mccc\n\tt.column :\\${1:title}, :\\${2:string}\nsnippet mct\n\tcreate_table :\\${1:table_name} do |t|\n\t\tt.column :\\${2:name}, :\\${3:type}\n\tend\nsnippet migration\n\tclass \\${1:class_name} < ActiveRecord::Migration\n\t\tdef self.up\n\t\t\t\\${2}\n\t\tend\n\n\t\tdef self.down\n\t\tend\n\tend\n\nsnippet trc\n\tt.remove :\\${1:column}\nsnippet tre\n\tt.rename :\\${1:old_column_name}, :\\${2:new_column_name}\n\t\\${3}\nsnippet tref\n\tt.references :\\${1:model}\n\n#rspec\nsnippet it\n\tit \"\\${1:spec_name}\" do\n\t\t\\${2}\n\tend\nsnippet itp\n\tit \"\\${1:spec_name}\"\n\t\\${2}\nsnippet desc\n\tdescribe \\${1:class_name} do\n\t\t\\${2}\n\tend\nsnippet cont\n\tcontext \"\\${1:message}\" do\n\t\t\\${2}\n\tend\nsnippet bef\n\tbefore :\\${1:each} do\n\t\t\\${2}\n\tend\nsnippet aft\n\tafter :\\${1:each} do\n\t\t\\${2}\n\tend\n`;\n"
  },
  {
    "path": "src/snippets/sh.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./sh.snippets\");\nexports.scope = \"sh\";\n"
  },
  {
    "path": "src/snippets/sh.snippets.js",
    "content": "module.exports = `# Shebang. Executing bash via /usr/bin/env makes scripts more portable.\nsnippet #!\n\t#!/usr/bin/env bash\n\t\nsnippet if\n\tif [[ \\${1:condition} ]]; then\n\t\t\\${2:#statements}\n\tfi\nsnippet elif\n\telif [[ \\${1:condition} ]]; then\n\t\t\\${2:#statements}\nsnippet for\n\tfor (( \\${2:i} = 0; \\$2 < \\${1:count}; \\$2++ )); do\n\t\t\\${3:#statements}\n\tdone\nsnippet fori\n\tfor \\${1:needle} in \\${2:haystack} ; do\n\t\t\\${3:#statements}\n\tdone\nsnippet wh\n\twhile [[ \\${1:condition} ]]; do\n\t\t\\${2:#statements}\n\tdone\nsnippet until\n\tuntil [[ \\${1:condition} ]]; do\n\t\t\\${2:#statements}\n\tdone\nsnippet case\n\tcase \\${1:word} in\n\t\t\\${2:pattern})\n\t\t\t\\${3};;\n\tesac\nsnippet go \n\twhile getopts '\\${1:o}' \\${2:opts} \n\tdo \n\t\tcase \\$\\$2 in\n\t\t\\${3:o0})\n\t\t\t\\${4:#staments};;\n\t\tesac\n\tdone\n# Set SCRIPT_DIR variable to directory script is located.\nsnippet sdir\n\tSCRIPT_DIR=\"\\$( cd \"\\$( dirname \"\\${BASH_SOURCE[0]}\" )\" && pwd )\"\n# getopt\nsnippet getopt\n\t__ScriptVersion=\"\\${1:version}\"\n\n\t#===  FUNCTION  ================================================================\n\t#         NAME:  usage\n\t#  DESCRIPTION:  Display usage information.\n\t#===============================================================================\n\tfunction usage ()\n\t{\n\t\t\tcat <<- EOT\n\n\t  Usage :  \\$\\${0:0} [options] [--] \n\n\t  Options: \n\t  -h|help       Display this message\n\t  -v|version    Display script version\n\n\tEOT\n\t}    # ----------  end of function usage  ----------\n\n\t#-----------------------------------------------------------------------\n\t#  Handle command line arguments\n\t#-----------------------------------------------------------------------\n\n\twhile getopts \":hv\" opt\n\tdo\n\t  case \\$opt in\n\n\t\th|help     )  usage; exit 0   ;;\n\n\t\tv|version  )  echo \"\\$\\${0:0} -- Version \\$__ScriptVersion\"; exit 0   ;;\n\n\t\t\\\\? )  echo -e \"\\\\n  Option does not exist : \\$OPTARG\\\\n\"\n\t\t\t  usage; exit 1   ;;\n\n\t  esac    # --- end of case ---\n\tdone\n\tshift \\$((\\$OPTIND-1))\n\n`;\n"
  },
  {
    "path": "src/snippets/snippets.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./snippets.snippets\");\nexports.scope = \"snippets\";\n"
  },
  {
    "path": "src/snippets/snippets.snippets.js",
    "content": "module.exports = `# snippets for making snippets :)\nsnippet snip\n\tsnippet \\${1:trigger}\n\t\t\\${2}\nsnippet msnip\n\tsnippet \\${1:trigger} \\${2:description}\n\t\t\\${3}\nsnippet v\n\t{VISUAL}\n`;\n"
  },
  {
    "path": "src/snippets/sql.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./sql.snippets\");\nexports.scope = \"sql\";\n"
  },
  {
    "path": "src/snippets/sql.snippets.js",
    "content": "module.exports = `snippet tbl\n\tcreate table \\${1:table} (\n\t\t\\${2:columns}\n\t);\nsnippet col\n\t\\${1:name}\t\\${2:type}\t\\${3:default ''}\t\\${4:not null}\nsnippet ccol\n\t\\${1:name}\tvarchar2(\\${2:size})\t\\${3:default ''}\t\\${4:not null}\nsnippet ncol\n\t\\${1:name}\tnumber\t\\${3:default 0}\t\\${4:not null}\nsnippet dcol\n\t\\${1:name}\tdate\t\\${3:default sysdate}\t\\${4:not null}\nsnippet ind\n\tcreate index \\${3:\\$1_\\$2} on \\${1:table}(\\${2:column});\nsnippet uind\n\tcreate unique index \\${1:name} on \\${2:table}(\\${3:column});\nsnippet tblcom\n\tcomment on table \\${1:table} is '\\${2:comment}';\nsnippet colcom\n\tcomment on column \\${1:table}.\\${2:column} is '\\${3:comment}';\nsnippet addcol\n\talter table \\${1:table} add (\\${2:column} \\${3:type});\nsnippet seq\n\tcreate sequence \\${1:name} start with \\${2:1} increment by \\${3:1} minvalue \\${4:1};\nsnippet s*\n\tselect * from \\${1:table}\n`;\n"
  },
  {
    "path": "src/snippets/sqlserver.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./sqlserver.snippets\");\nexports.scope = \"sqlserver\";\n"
  },
  {
    "path": "src/snippets/sqlserver.snippets.js",
    "content": "module.exports = `# ISNULL\nsnippet isnull\n\tISNULL(\\${1:check_expression}, \\${2:replacement_value})\n# FORMAT\nsnippet format\n\tFORMAT(\\${1:value}, \\${2:format})\n# CAST\nsnippet cast\n\tCAST(\\${1:expression} AS \\${2:data_type})\n# CONVERT\nsnippet convert\n\tCONVERT(\\${1:data_type}, \\${2:expression})\n# DATEPART\nsnippet datepart\n\tDATEPART(\\${1:datepart}, \\${2:date})\n# DATEDIFF\nsnippet datediff\n\tDATEDIFF(\\${1:datepart}, \\${2:startdate}, \\${3:enddate})\n# DATEADD\nsnippet dateadd\n\tDATEADD(\\${1:datepart}, \\${2:number}, \\${3:date})\n# DATEFROMPARTS \nsnippet datefromparts\n\tDATEFROMPARTS(\\${1:year}, \\${2:month}, \\${3:day})\n# OBJECT_DEFINITION\nsnippet objectdef\n\tSELECT OBJECT_DEFINITION(OBJECT_ID('\\${1:sys.server_permissions /*object name*/}'))\n# STUFF XML\nsnippet stuffxml\n\tSTUFF((SELECT ', ' + \\${1:ColumnName}\n\t\tFROM \\${2:TableName}\n\t\tWHERE \\${3:WhereClause}\n\t\tFOR XML PATH('')), 1, 1, '') AS \\${4:Alias}\n\t\\${5:/*https://msdn.microsoft.com/en-us/library/ms188043.aspx*/}\n# Create Procedure\nsnippet createproc\n\t-- =============================================\n\t-- Author:\t\t\\${1:Author}\n\t-- Create date: \\${2:Date}\n\t-- Description:\t\\${3:Description}\n\t-- =============================================\n\tCREATE PROCEDURE \\${4:Procedure_Name}\n\t\t\\${5:/*Add the parameters for the stored procedure here*/}\n\tAS\n\tBEGIN\n\t\t-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.\n\t\tSET NOCOUNT ON;\n\t\t\n\t\t\\${6:/*Add the T-SQL statements to compute the return value here*/}\n\t\t\n\tEND\n\tGO\n# Create Scalar Function\nsnippet createfn\n\t-- =============================================\n\t-- Author:\t\t\\${1:Author}\n\t-- Create date: \\${2:Date}\n\t-- Description:\t\\${3:Description}\n\t-- =============================================\n\tCREATE FUNCTION \\${4:Scalar_Function_Name}\n\t\t-- Add the parameters for the function here\n\tRETURNS \\${5:Function_Data_Type}\n\tAS\n\tBEGIN\n\t\tDECLARE @Result \\${5:Function_Data_Type}\n\t\t\n\t\t\\${6:/*Add the T-SQL statements to compute the return value here*/}\n\t\t\n\tEND\n\tGO`;\n"
  },
  {
    "path": "src/snippets/tcl.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./tcl.snippets\");\nexports.scope = \"tcl\";\n"
  },
  {
    "path": "src/snippets/tcl.snippets.js",
    "content": "module.exports = `# #!/usr/bin/env tclsh\nsnippet #!\n\t#!/usr/bin/env tclsh\n\t\n# Process\nsnippet pro\n\tproc \\${1:function_name} {\\${2:args}} {\n\t\t\\${3:#body ...}\n\t}\n#xif\nsnippet xif\n\t\\${1:expr}? \\${2:true} : \\${3:false}\n# Conditional\nsnippet if\n\tif {\\${1}} {\n\t\t\\${2:# body...}\n\t}\n# Conditional if..else\nsnippet ife\n\tif {\\${1}} {\n\t\t\\${2:# body...}\n\t} else {\n\t\t\\${3:# else...}\n\t}\n# Conditional if..elsif..else\nsnippet ifee\n\tif {\\${1}} {\n\t\t\\${2:# body...}\n\t} elseif {\\${3}} {\n\t\t\\${4:# elsif...}\n\t} else {\n\t\t\\${5:# else...}\n\t}\n# If catch then\nsnippet ifc\n\tif { [catch {\\${1:#do something...}} \\${2:err}] } {\n\t\t\\${3:# handle failure...}\n\t}\n# Catch\nsnippet catch\n\tcatch {\\${1}} \\${2:err} \\${3:options}\n# While Loop\nsnippet wh\n\twhile {\\${1}} {\n\t\t\\${2:# body...}\n\t}\n# For Loop\nsnippet for\n\tfor {set \\${2:var} 0} {\\$\\$2 < \\${1:count}} {\\${3:incr} \\$2} {\n\t\t\\${4:# body...}\n\t}\n# Foreach Loop\nsnippet fore\n\tforeach \\${1:x} {\\${2:#list}} {\n\t\t\\${3:# body...}\n\t}\n# after ms script...\nsnippet af\n\tafter \\${1:ms} \\${2:#do something}\n# after cancel id\nsnippet afc\n\tafter cancel \\${1:id or script}\n# after idle\nsnippet afi\n\tafter idle \\${1:script}\n# after info id\nsnippet afin\n\tafter info \\${1:id}\n# Expr\nsnippet exp\n\texpr {\\${1:#expression here}}\n# Switch\nsnippet sw\n\tswitch \\${1:var} {\n\t\t\\${3:pattern 1} {\n\t\t\t\\${4:#do something}\n\t\t}\n\t\tdefault {\n\t\t\t\\${2:#do something}\n\t\t}\n\t}\n# Case\nsnippet ca\n\t\\${1:pattern} {\n\t\t\\${2:#do something}\n\t}\\${3}\n# Namespace eval\nsnippet ns\n\tnamespace eval \\${1:path} {\\${2:#script...}}\n# Namespace current\nsnippet nsc\n\tnamespace current\n`;\n"
  },
  {
    "path": "src/snippets/tex.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./tex.snippets\");\nexports.scope = \"tex\";\n"
  },
  {
    "path": "src/snippets/tex.snippets.js",
    "content": "module.exports = `#PREAMBLE\n#newcommand\nsnippet nc\n\t\\\\newcommand{\\\\\\${1:cmd}}[\\${2:opt}]{\\${3:realcmd}}\\${4}\n#usepackage\nsnippet up\n\t\\\\usepackage[\\${1:[options}]{\\${2:package}}\n#newunicodechar\nsnippet nuc\n\t\\\\newunicodechar{\\${1}}{\\${2:\\\\ensuremath}\\${3:tex-substitute}}}\n#DeclareMathOperator\nsnippet dmo\n\t\\\\DeclareMathOperator{\\${1}}{\\${2}}\n\n#DOCUMENT\n# \\\\begin{}...\\\\end{}\nsnippet begin\n\t\\\\begin{\\${1:env}}\n\t\t\\${2}\n\t\\\\end{\\$1}\n# Tabular\nsnippet tab\n\t\\\\begin{\\${1:tabular}}{\\${2:c}}\n\t\\${3}\n\t\\\\end{\\$1}\nsnippet thm\n\t\\\\begin[\\${1:author}]{\\${2:thm}}\n\t\\${3}\n\t\\\\end{\\$1}\nsnippet center\n\t\\\\begin{center}\n\t\t\\${1}\n\t\\\\end{center}\n# Align(ed)\nsnippet ali\n\t\\\\begin{align\\${1:ed}}\n\t\t\\${2}\n\t\\\\end{align\\$1}\n# Gather(ed)\nsnippet gat\n\t\\\\begin{gather\\${1:ed}}\n\t\t\\${2}\n\t\\\\end{gather\\$1}\n# Equation\nsnippet eq\n\t\\\\begin{equation}\n\t\t\\${1}\n\t\\\\end{equation}\n# Equation\nsnippet eq*\n\t\\\\begin{equation*}\n\t\t\\${1}\n\t\\\\end{equation*}\n# Unnumbered Equation\nsnippet \\\\\n\t\\\\[\n\t\t\\${1}\n\t\\\\]\n# Enumerate\nsnippet enum\n\t\\\\begin{enumerate}\n\t\t\\\\item \\${1}\n\t\\\\end{enumerate}\n# Itemize\nsnippet itemize\n\t\\\\begin{itemize}\n\t\t\\\\item \\${1}\n\t\\\\end{itemize}\n# Description\nsnippet desc\n\t\\\\begin{description}\n\t\t\\\\item[\\${1}] \\${2}\n\t\\\\end{description}\n# Matrix\nsnippet mat\n\t\\\\begin{\\${1:p/b/v/V/B/small}matrix}\n\t\t\\${2}\n\t\\\\end{\\$1matrix}\n# Cases\nsnippet cas\n\t\\\\begin{cases}\n\t\t\\${1:equation}, &\\\\text{ if }\\${2:case}\\\\\\\\\n\t\t\\${3}\n\t\\\\end{cases}\n# Split\nsnippet spl\n\t\\\\begin{split}\n\t\t\\${1}\n\t\\\\end{split}\n# Part\nsnippet part\n\t\\\\part{\\${1:part name}} % (fold)\n\t\\\\label{prt:\\${2:\\$1}}\n\t\\${3}\n\t% part \\$2 (end)\n# Chapter\nsnippet cha\n\t\\\\chapter{\\${1:chapter name}}\n\t\\\\label{cha:\\${2:\\$1}}\n\t\\${3}\n# Section\nsnippet sec\n\t\\\\section{\\${1:section name}}\n\t\\\\label{sec:\\${2:\\$1}}\n\t\\${3}\n# Sub Section\nsnippet sub\n\t\\\\subsection{\\${1:subsection name}}\n\t\\\\label{sub:\\${2:\\$1}}\n\t\\${3}\n# Sub Sub Section\nsnippet subs\n\t\\\\subsubsection{\\${1:subsubsection name}}\n\t\\\\label{ssub:\\${2:\\$1}}\n\t\\${3}\n# Paragraph\nsnippet par\n\t\\\\paragraph{\\${1:paragraph name}}\n\t\\\\label{par:\\${2:\\$1}}\n\t\\${3}\n# Sub Paragraph\nsnippet subp\n\t\\\\subparagraph{\\${1:subparagraph name}}\n\t\\\\label{subp:\\${2:\\$1}}\n\t\\${3}\n#References\nsnippet itd\n\t\\\\item[\\${1:description}] \\${2:item}\nsnippet figure\n\t\\${1:Figure}~\\\\ref{\\${2:fig:}}\\${3}\nsnippet table\n\t\\${1:Table}~\\\\ref{\\${2:tab:}}\\${3}\nsnippet listing\n\t\\${1:Listing}~\\\\ref{\\${2:list}}\\${3}\nsnippet section\n\t\\${1:Section}~\\\\ref{\\${2:sec:}}\\${3}\nsnippet page\n\t\\${1:page}~\\\\pageref{\\${2}}\\${3}\nsnippet index\n\t\\\\index{\\${1:index}}\\${2}\n#Citations\nsnippet cite\n\t\\\\cite[\\${1}]{\\${2}}\\${3}\nsnippet fcite\n\t\\\\footcite[\\${1}]{\\${2}}\\${3}\n#Formating text: italic, bold, underline, small capital, emphase ..\nsnippet it\n\t\\\\textit{\\${1:text}}\nsnippet bf\n\t\\\\textbf{\\${1:text}}\nsnippet under\n\t\\\\underline{\\${1:text}}\nsnippet emp\n\t\\\\emph{\\${1:text}}\nsnippet sc\n\t\\\\textsc{\\${1:text}}\n#Choosing font\nsnippet sf\n\t\\\\textsf{\\${1:text}}\nsnippet rm\n\t\\\\textrm{\\${1:text}}\nsnippet tt\n\t\\\\texttt{\\${1:text}}\n#misc\nsnippet ft\n\t\\\\footnote{\\${1:text}}\nsnippet fig\n\t\\\\begin{figure}\n\t\\\\begin{center}\n\t    \\\\includegraphics[scale=\\${1}]{Figures/\\${2}}\n\t\\\\end{center}\n\t\\\\caption{\\${3}}\n\t\\\\label{fig:\\${4}}\n\t\\\\end{figure}\nsnippet tikz\n\t\\\\begin{figure}\n\t\\\\begin{center}\n\t\\\\begin{tikzpicture}[scale=\\${1:1}]\n\t\t\\${2}\n\t\\\\end{tikzpicture}\n\t\\\\end{center}\n\t\\\\caption{\\${3}}\n\t\\\\label{fig:\\${4}}\n\t\\\\end{figure}\n#math\nsnippet stackrel\n\t\\\\stackrel{\\${1:above}}{\\${2:below}} \\${3}\nsnippet frac\n\t\\\\frac{\\${1:num}}{\\${2:denom}}\nsnippet sum\n\t\\\\sum^{\\${1:n}}_{\\${2:i=1}}{\\${3}}`;\n"
  },
  {
    "path": "src/snippets/textile.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./textile.snippets\");\nexports.scope = \"textile\";\n"
  },
  {
    "path": "src/snippets/textile.snippets.js",
    "content": "module.exports = `# Jekyll post header\nsnippet header\n\t---\n\ttitle: \\${1:title}\n\tlayout: post\n\tdate: \\${2:date} \\${3:hour:minute:second} -05:00\n\t---\n\n# Image\nsnippet img\n\t!\\${1:url}(\\${2:title}):\\${3:link}!\n\n# Table\nsnippet |\n\t|\\${1}|\\${2}\n\n# Link\nsnippet link\n\t\"\\${1:link text}\":\\${2:url}\n\n# Acronym\nsnippet (\n\t(\\${1:Expand acronym})\\${2}\n\n# Footnote\nsnippet fn\n\t[\\${1:ref number}] \\${3}\n\n\tfn\\$1. \\${2:footnote}\n\t\n`;\n"
  },
  {
    "path": "src/snippets/vala.js",
    "content": "\"use strict\";\n\nexports.snippets = [\n    {\n        \"content\": \"case ${1:condition}:\\n\\t$0\\n\\tbreak;\\n\",\n        \"name\": \"case\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"case\"\n    },\n    {\n        \"content\": \"/**\\n * ${6}\\n */\\n${1:public} class ${2:MethodName}${3: : GLib.Object} {\\n\\n\\t/**\\n\\t * ${7}\\n\\t */\\n\\tpublic ${2}(${4}) {\\n\\t\\t${5}\\n\\t}\\n\\n\\t$0\\n}\",\n        \"name\": \"class\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"class\"\n    },\n    {\n        \"content\": \"(${1}) => {\\n\\t${0}\\n}\\n\",\n        \"name\": \"closure\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"=>\"\n    },\n    {\n        \"content\": \"/*\\n * $0\\n */\",\n        \"name\": \"Comment (multiline)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"/*\"\n    },\n    {\n        \"content\": \"Console.WriteLine($1);\\n$0\",\n        \"name\": \"Console.WriteLine (writeline)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"writeline\"\n    },\n    {\n        \"content\": \"[DBus(name = \\\"$0\\\")]\",\n        \"name\": \"DBus annotation\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"[DBus\"\n    },\n    {\n        \"content\": \"delegate ${1:void} ${2:DelegateName}($0);\",\n        \"name\": \"delegate\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"delegate\"\n    },\n    {\n        \"content\": \"do {\\n\\t$0\\n} while ($1);\\n\",\n        \"name\": \"do while\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"dowhile\"\n    },\n    {\n        \"content\": \"/**\\n * $0\\n */\",\n        \"name\": \"DocBlock\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"/**\"\n    },\n    {\n        \"content\": \"else if ($1) {\\n\\t$0\\n}\\n\",\n        \"name\": \"else if (elseif)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"elseif\"\n    },\n    {\n        \"content\": \"else {\\n\\t$0\\n}\",\n        \"name\": \"else\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"else\"\n    },\n    {\n        \"content\": \"enum {$1:EnumName} {\\n\\t$0\\n}\",\n        \"name\": \"enum\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"enum\"\n    },\n    {\n        \"content\": \"public errordomain ${1:Error} {\\n\\t$0\\n}\",\n        \"name\": \"error domain\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"errordomain\"\n    },\n    {\n        \"content\": \"for ($1;$2;$3) {\\n\\t$0\\n}\",\n        \"name\": \"for\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"for\"\n    },\n    {\n        \"content\": \"foreach ($1 in $2) {\\n\\t$0\\n}\",\n        \"name\": \"foreach\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"foreach\"\n    },\n    {\n        \"content\": \"Gee.ArrayList<${1:G}>($0);\",\n        \"name\": \"Gee.ArrayList\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"ArrayList\"\n    },\n    {\n        \"content\": \"Gee.HashMap<${1:K},${2:V}>($0);\",\n        \"name\": \"Gee.HashMap\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"HashMap\"\n    },\n    {\n        \"content\": \"Gee.HashSet<${1:G}>($0);\",\n        \"name\": \"Gee.HashSet\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"HashSet\"\n    },\n    {\n        \"content\": \"if ($1) {\\n\\t$0\\n}\",\n        \"name\": \"if\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"if\"\n    },\n    {\n        \"content\": \"interface ${1:InterfaceName}{$2: : SuperInterface} {\\n\\t$0\\n}\",\n        \"name\": \"interface\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"interface\"\n    },\n    {\n        \"content\": \"public static int main(string [] argv) {\\n\\t${0}\\n\\treturn 0;\\n}\",\n        \"name\": \"Main function\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"main\"\n    },\n    {\n        \"content\": \"namespace $1 {\\n\\t$0\\n}\\n\",\n        \"name\": \"namespace (ns)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"ns\"\n    },\n    {\n        \"content\": \"stdout.printf($0);\",\n        \"name\": \"printf\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"printf\"\n    },\n    {\n        \"content\": \"${1:public} ${2:Type} ${3:Name} {\\n\\tset {\\n\\t\\t$0\\n\\t}\\n\\tget {\\n\\n\\t}\\n}\",\n        \"name\": \"property (prop)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"prop\"\n    },\n    {\n        \"content\": \"${1:public} ${2:Type} ${3:Name} {\\n\\tget {\\n\\t\\t$0\\n\\t}\\n}\",\n        \"name\": \"read-only property (roprop)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"roprop\"\n    },\n    {\n        \"content\": \"@\\\"${1:\\\\$var}\\\"\",\n        \"name\": \"String template (@)\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"@\"\n    },\n    {\n        \"content\": \"struct ${1:StructName} {\\n\\t$0\\n}\",\n        \"name\": \"struct\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"struct\"\n    },\n    {\n        \"content\": \"switch ($1) {\\n\\t$0\\n}\",\n        \"name\": \"switch\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"switch\"\n    },\n    {\n        \"content\": \"try {\\n\\t$2\\n} catch (${1:Error} e) {\\n\\t$0\\n}\",\n        \"name\": \"try/catch\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"try\"\n    },\n    {\n        \"content\": \"\\\"\\\"\\\"$0\\\"\\\"\\\";\",\n        \"name\": \"Verbatim string (\\\"\\\"\\\")\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"verbatim\"\n    },\n    {\n        \"content\": \"while ($1) {\\n\\t$0\\n}\",\n        \"name\": \"while\",\n        \"scope\": \"vala\",\n        \"tabTrigger\": \"while\"\n    }\n];\nexports.scope = \"\";\n"
  },
  {
    "path": "src/snippets/velocity.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./velocity.snippets\");\nexports.scope = \"velocity\";\nexports.includeScopes = [\"html\", \"javascript\", \"css\"];\n"
  },
  {
    "path": "src/snippets/velocity.snippets.js",
    "content": "module.exports = `# macro\nsnippet #macro\n\t#macro ( \\${1:macroName} \\${2:\\\\\\$var1, [\\\\\\$var2, ...]} )\n\t\t\\${3:## macro code}\n\t#end\n# foreach\nsnippet #foreach\n\t#foreach ( \\${1:\\\\\\$item} in \\${2:\\\\\\$collection} )\n\t\t\\${3:## foreach code}\n\t#end\n# if\nsnippet #if\n\t#if ( \\${1:true} )\n\t\t\\${0}\n\t#end\n# if ... else\nsnippet #ife\n\t#if ( \\${1:true} )\n\t\t\\${2}\n\t#else\n\t\t\\${0}\n\t#end\n#import\nsnippet #import\n\t#import ( \"\\${1:path/to/velocity/format}\" )\n# set\nsnippet #set\n\t#set ( \\$\\${1:var} = \\${0} )\n`;\n"
  },
  {
    "path": "src/snippets/wollok.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"./wollok.snippets\");\nexports.scope = \"wollok\";\n"
  },
  {
    "path": "src/snippets/wollok.snippets.js",
    "content": "module.exports = `##\n## Basic Java packages and import\nsnippet im\n\timport\nsnippet w.l\n\twollok.lang\nsnippet w.i\n\twollok.lib\n\n## Class and object\nsnippet cl\n\tclass \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2}\nsnippet obj\n\tobject \\${1:\\`Filename(\"\", \"untitled\")\\`} \\${2:inherits Parent}\\${3}\nsnippet te\n\ttest \\${1:\\`Filename(\"\", \"untitled\")\\`}\n\n##\n## Enhancements\nsnippet inh\n\tinherits\n\n##\n## Comments\nsnippet /*\n\t/*\n\t * \\${1}\n\t */\n\n##\n## Control Statements\nsnippet el\n\telse\nsnippet if\n\tif (\\${1}) \\${2}\n\n##\n## Create a Method\nsnippet m\n\tmethod \\${1:method}(\\${2}) \\${5}\n\n##  \n## Tests\nsnippet as\n\tassert.equals(\\${1:expected}, \\${2:actual})\n\n##\n## Exceptions\nsnippet ca\n\tcatch \\${1:e} : (\\${2:Exception} ) \\${3}\nsnippet thr\n\tthrow\nsnippet try\n\ttry {\n\t\t\\${3}\n\t} catch \\${1:e} : \\${2:Exception} {\n\t}\n\n##\n## Javadocs\nsnippet /**\n\t/**\n\t * \\${1}\n\t */\n\n##\n## Print Methods\nsnippet print\n\tconsole.println(\"\\${1:Message}\")\n\n##\n## Setter and Getter Methods\nsnippet set\n\tmethod set\\${1:}(\\${2:}) {\n\t\t\\$1 = \\$2\n\t}\nsnippet get\n\tmethod get\\${1:}() {\n\t\treturn \\${1:};\n\t}\n\n##\n## Terminate Methods or Loops\nsnippet re\n\treturn`;\n"
  },
  {
    "path": "src/snippets.js",
    "content": "\"use strict\";\n/**\n * @typedef Snippet\n * @property {string} [content]\n * @property {string} [replaceBefore]\n * @property {string} [replaceAfter]\n * @property {RegExp} [startRe]\n * @property {RegExp} [endRe]\n * @property {RegExp} [triggerRe]\n * @property {RegExp} [endTriggerRe]\n * @property {string} [trigger]\n * @property {string} [endTrigger]\n * @property {string[]} [matchBefore]\n * @property {string[]} [matchAfter]\n * @property {string} [name]\n * @property {string} [tabTrigger]\n * @property {string} [guard]\n * @property {string} [endGuard]\n */\nvar dom = require(\"./lib/dom\");\nvar oop = require(\"./lib/oop\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar lang = require(\"./lib/lang\");\nvar Range = require(\"./range\").Range;\nvar RangeList = require(\"./range_list\").RangeList;\nvar HashHandler = require(\"./keyboard/hash_handler\").HashHandler;\nvar Tokenizer = require(\"./tokenizer\").Tokenizer;\nvar clipboard = require(\"./clipboard\");\n\nvar VARIABLES = {\n    CURRENT_WORD: function(editor) {\n        return editor.session.getTextRange(editor.session.getWordRange());\n    },\n    SELECTION: function(editor, name, indentation) {\n        var text = editor.session.getTextRange();\n        if (indentation)\n            return text.replace(/\\n\\r?([ \\t]*\\S)/g, \"\\n\" + indentation + \"$1\");\n        return text;\n    },\n    CURRENT_LINE: function(editor) {\n        return editor.session.getLine(editor.getCursorPosition().row);\n    },\n    PREV_LINE: function(editor) {\n        return editor.session.getLine(editor.getCursorPosition().row - 1);\n    },\n    LINE_INDEX: function(editor) {\n        return editor.getCursorPosition().row;\n    },\n    LINE_NUMBER: function(editor) {\n        return editor.getCursorPosition().row + 1;\n    },\n    SOFT_TABS: function(editor) {\n        return editor.session.getUseSoftTabs() ? \"YES\" : \"NO\";\n    },\n    TAB_SIZE: function(editor) {\n        return editor.session.getTabSize();\n    },\n    CLIPBOARD: function(editor) {\n        return clipboard.getText && clipboard.getText();\n    },\n    // filenames\n    FILENAME: function(editor) {\n        return /[^/\\\\]*$/.exec(this.FILEPATH(editor))[0];\n    },\n    FILENAME_BASE: function(editor) {\n        return /[^/\\\\]*$/.exec(this.FILEPATH(editor))[0].replace(/\\.[^.]*$/, \"\");\n    },\n    DIRECTORY: function(editor) {\n        return this.FILEPATH(editor).replace(/[^/\\\\]*$/, \"\");\n    },\n    FILEPATH: function(editor) { return \"/not implemented.txt\"; },\n    WORKSPACE_NAME: function() { return \"Unknown\"; },\n    FULLNAME: function() { return \"Unknown\"; },\n    // comments\n    BLOCK_COMMENT_START: function(editor) {\n        var mode = editor.session.$mode || {};\n        return mode.blockComment && mode.blockComment.start || \"\";\n    },\n    BLOCK_COMMENT_END: function(editor) {\n        var mode = editor.session.$mode || {};\n        return mode.blockComment && mode.blockComment.end || \"\";\n    },\n    LINE_COMMENT: function(editor) {\n        var mode = editor.session.$mode || {};\n        return mode.lineCommentStart || \"\";\n    },\n    // dates\n    CURRENT_YEAR: date.bind(null, {year: \"numeric\"}),\n    CURRENT_YEAR_SHORT: date.bind(null, {year: \"2-digit\"}),\n    CURRENT_MONTH: date.bind(null, {month: \"numeric\"}),\n    CURRENT_MONTH_NAME: date.bind(null, {month: \"long\"}),\n    CURRENT_MONTH_NAME_SHORT: date.bind(null, {month: \"short\"}),\n    CURRENT_DATE: date.bind(null, {day: \"2-digit\"}),\n    CURRENT_DAY_NAME: date.bind(null, {weekday: \"long\"}),\n    CURRENT_DAY_NAME_SHORT: date.bind(null, {weekday: \"short\"}),\n    CURRENT_HOUR: date.bind(null, {hour: \"2-digit\", hour12: false}),\n    CURRENT_MINUTE: date.bind(null, {minute: \"2-digit\"}),\n    CURRENT_SECOND: date.bind(null, {second: \"2-digit\"})\n};\n\nVARIABLES.SELECTED_TEXT = VARIABLES.SELECTION;\n\nfunction date(dateFormat) {\n    var str = new Date().toLocaleString(\"en-us\", dateFormat);\n    return str.length == 1 ? \"0\" + str : str;\n}\n\nclass SnippetManager {\n    constructor() {\n        this.snippetMap = {};\n        this.snippetNameMap = {};\n        this.variables = VARIABLES;\n    }\n\n\n    /**\n     * @return {Tokenizer}\n     */\n    getTokenizer() {\n        return SnippetManager[\"$tokenizer\"] || this.createTokenizer();\n    }\n\n    createTokenizer() {\n        function TabstopToken(str) {\n            str = str.substr(1);\n            if (/^\\d+$/.test(str))\n                return [{tabstopId: parseInt(str, 10)}];\n            return [{text: str}];\n        }\n        function escape(ch) {\n            return \"(?:[^\\\\\\\\\" + ch + \"]|\\\\\\\\.)\";\n        }\n        var formatMatcher = {\n            regex: \"/(\" + escape(\"/\") + \"+)/\",\n            onMatch: function(val, state, stack) {\n                var ts = stack[0];\n                ts.fmtString = true;\n                ts.guard = val.slice(1, -1);\n                ts.flag = \"\";\n                return \"\";\n            },\n            next: \"formatString\"\n        };\n\n        SnippetManager[\"$tokenizer\"] = new Tokenizer({\n            start: [\n                {regex: /\\\\./, onMatch: function(val, state, stack) {\n                    var ch = val[1];\n                    if (ch == \"}\" && stack.length) {\n                        val = ch;\n                    } else if (\"`$\\\\\".indexOf(ch) != -1) {\n                        val = ch;\n                    }\n                    return [val];\n                }},\n                {regex: /}/, onMatch: function(val, state, stack) {\n                    return [stack.length ? stack.shift() : val];\n                }},\n                {regex: /\\$(?:\\d+|\\w+)/, onMatch: TabstopToken},\n                {regex: /\\$\\{[\\dA-Z_a-z]+/, onMatch: function(str, state, stack) {\n                    var t = TabstopToken(str.substr(1));\n                    stack.unshift(t[0]);\n                    return t;\n                }, next: \"snippetVar\"},\n                {regex: /\\n/, token: \"newline\", merge: false}\n            ],\n            snippetVar: [\n                {regex: \"\\\\|\" + escape(\"\\\\|\") + \"*\\\\|\", onMatch: function(val, state, stack) {\n                    var choices = val.slice(1, -1).replace(/\\\\[,|\\\\]|,/g, function(operator) {\n                        return operator.length == 2 ? operator[1] : \"\\x00\";\n                    }).split(\"\\x00\").map(function(value){\n                        return {value: value};\n                    });\n                    stack[0].choices = choices;\n                    return [choices[0]];\n                }, next: \"start\"},\n                formatMatcher,\n                {regex: \"([^:}\\\\\\\\]|\\\\\\\\.)*:?\", token: \"\", next: \"start\"}\n            ],\n            formatString: [\n                {regex: /:/, onMatch: function(val, state, stack) {\n                    if (stack.length && stack[0].expectElse) {\n                        stack[0].expectElse = false;\n                        stack[0].ifEnd = {elseEnd: stack[0]};\n                        return [stack[0].ifEnd];\n                    }\n                    return \":\";\n                }},\n                {regex: /\\\\./, onMatch: function(val, state, stack) {\n                    var ch = val[1];\n                    if (ch == \"}\" && stack.length)\n                        val = ch;\n                    else if (\"`$\\\\\".indexOf(ch) != -1)\n                        val = ch;\n                    else if (ch == \"n\")\n                        val = \"\\n\";\n                    else if (ch == \"t\")\n                        val = \"\\t\";\n                    else if (\"ulULE\".indexOf(ch) != -1)\n                        val = {changeCase: ch, local: ch > \"a\"};\n                    return [val];\n                }},\n                {regex: \"/\\\\w*}\", onMatch: function(val, state, stack) {\n                    var next = stack.shift();\n                    if (next)\n                        next.flag = val.slice(1, -1);\n                    this.next = next && next.tabstopId ? \"start\" : \"\";\n                    return [next || val];\n                }, next: \"start\"},\n                {regex: /\\$(?:\\d+|\\w+)/, onMatch: function(val, state, stack) {\n                    return [{text: val.slice(1)}];\n                }},\n                {regex: /\\${\\w+/, onMatch: function(val, state, stack) {\n                    var token = {text: val.slice(2)};\n                    stack.unshift(token);\n                    return [token];\n                }, next: \"formatStringVar\"},\n                {regex: /\\n/, token: \"newline\", merge: false},\n                {regex: /}/, onMatch: function(val, state, stack) {\n                    var next = stack.shift();\n                    this.next = next && next.tabstopId ? \"start\" : \"\";\n                    return [next || val];\n                }, next: \"start\"}\n            ],\n            formatStringVar: [\n                {regex: /:\\/\\w+}/, onMatch: function(val, state, stack) {\n                    var ts = stack[0];\n                    ts.formatFunction = val.slice(2, -1);\n                    return [stack.shift()];\n                }, next: \"formatString\"},\n                formatMatcher,\n                {regex: /:[\\?\\-+]?/, onMatch: function(val, state, stack) {\n                    if (val[1] == \"+\")\n                        stack[0].ifEnd = stack[0];\n                    if (val[1] == \"?\")\n                        stack[0].expectElse = true;\n                }, next: \"formatString\"},\n                {regex: \"([^:}\\\\\\\\]|\\\\\\\\.)*:?\", token: \"\", next: \"formatString\"}\n            ]\n        });\n        return SnippetManager[\"$tokenizer\"];\n    }\n\n    tokenizeTmSnippet(str, startState) {\n        return this.getTokenizer().getLineTokens(str, startState).tokens.map(function(x) {\n            return x.value || x;\n        });\n    }\n\n    getVariableValue(editor, name, indentation) {\n        if (/^\\d+$/.test(name))\n            return (this.variables.__ || {})[name] || \"\";\n        if (/^[A-Z]\\d+$/.test(name))\n            return (this.variables[name[0] + \"__\"] || {})[name.substr(1)] || \"\";\n\n        name = name.replace(/^TM_/, \"\");\n        if (!this.variables.hasOwnProperty(name))\n            return \"\";\n        var value = this.variables[name];\n        if (typeof value == \"function\")\n            value = this.variables[name](editor, name, indentation);\n        return value == null ? \"\" : value;\n    }\n\n    // returns string formatted according to http://manual.macromates.com/en/regular_expressions#replacement_string_syntax_format_strings\n    tmStrFormat(str, ch, editor) {\n        if (!ch.fmt) return str;\n        var flag = ch.flag || \"\";\n        var re = ch.guard;\n        re = new RegExp(re, flag.replace(/[^gim]/g, \"\"));\n        var fmtTokens = typeof ch.fmt == \"string\" ? this.tokenizeTmSnippet(ch.fmt, \"formatString\") : ch.fmt;\n        var _self = this;\n        var formatted = str.replace(re, function() {\n            var oldArgs = _self.variables.__;\n            _self.variables.__ = [].slice.call(arguments);\n            var fmtParts = _self.resolveVariables(fmtTokens, editor);\n            var gChangeCase = \"E\";\n            for (var i  = 0; i < fmtParts.length; i++) {\n                var ch = fmtParts[i];\n                if (typeof ch == \"object\") {\n                    fmtParts[i] = \"\";\n                    if (ch.changeCase && ch.local) {\n                        var next = fmtParts[i + 1];\n                        if (next && typeof next == \"string\") {\n                            if (ch.changeCase == \"u\")\n                                fmtParts[i] = next[0].toUpperCase();\n                            else\n                                fmtParts[i] = next[0].toLowerCase();\n                            fmtParts[i + 1] = next.substr(1);\n                        }\n                    } else if (ch.changeCase) {\n                        gChangeCase = ch.changeCase;\n                    }\n                } else if (gChangeCase == \"U\") {\n                    fmtParts[i] = ch.toUpperCase();\n                } else if (gChangeCase == \"L\") {\n                    fmtParts[i] = ch.toLowerCase();\n                }\n            }\n            _self.variables.__ = oldArgs;\n            return fmtParts.join(\"\");\n        });\n        return formatted;\n    }\n\n    tmFormatFunction(str, ch, editor) {\n        if (ch.formatFunction == \"upcase\")\n            return str.toUpperCase();\n        if (ch.formatFunction == \"downcase\")\n            return str.toLowerCase();\n        return str;\n    }\n\n    resolveVariables(snippet, editor) {\n        var result = [];\n        var indentation = \"\";\n        var afterNewLine = true;\n        for (var i = 0; i < snippet.length; i++) {\n            var ch = snippet[i];\n            if (typeof ch == \"string\") {\n                result.push(ch);\n                if (ch == \"\\n\") {\n                    afterNewLine = true;\n                    indentation = \"\";\n                }\n                else if (afterNewLine) {\n                    indentation = /^\\t*/.exec(ch)[0];\n                    afterNewLine = /\\S/.test(ch);\n                }\n                continue;\n            }\n            if (!ch)  continue;\n            afterNewLine = false;\n\n            if (ch.fmtString) {\n                var j = snippet.indexOf(ch, i + 1);\n                if (j == -1) j = snippet.length;\n                ch.fmt = snippet.slice(i + 1, j);\n                i = j;\n            }\n\n            if (ch.text) {\n                var value = this.getVariableValue(editor, ch.text, indentation) + \"\";\n                if (ch.fmtString)\n                    value = this.tmStrFormat(value, ch, editor);\n                if (ch.formatFunction)\n                    value = this.tmFormatFunction(value, ch, editor);\n\n                if (value && !ch.ifEnd) {\n                    result.push(value);\n                    gotoNext(ch);\n                } else if (!value && ch.ifEnd) {\n                    gotoNext(ch.ifEnd);\n                }\n            } else if (ch.elseEnd) {\n                gotoNext(ch.elseEnd);\n            } else if (ch.tabstopId != null) {\n                result.push(ch);\n            } else if (ch.changeCase != null) {\n                result.push(ch);\n            }\n        }\n        function gotoNext(ch) {\n            var i1 = snippet.indexOf(ch, i + 1);\n            if (i1 != -1)\n                i = i1;\n        }\n        return result;\n    }\n\n    getDisplayTextForSnippet(editor, snippetText) {\n        var processedSnippet = processSnippetText.call(this, editor, snippetText);\n        return processedSnippet.text;\n    }\n\n    insertSnippetForSelection(editor, snippetText, options={}) {\n        var processedSnippet = processSnippetText.call(this, editor, snippetText, options);\n\n        var range = editor.getSelectionRange();\n        var end = editor.session.replace(range, processedSnippet.text);\n\n        var tabstopManager = new TabstopManager(editor);\n        var selectionId = editor.inVirtualSelectionMode && editor.selection.index;\n        //@ts-expect-error TODO: potential wrong arguments\n        tabstopManager.addTabstops(processedSnippet.tabstops, range.start, end, selectionId);\n    }\n    insertSnippet(editor, snippetText, options={}) {\n        var self = this;\n        if (editor.inVirtualSelectionMode)\n            return self.insertSnippetForSelection(editor, snippetText, options);\n\n        editor.forEachSelection(function() {\n            self.insertSnippetForSelection(editor, snippetText, options);\n        }, null, {keepOrder: true});\n\n        if (editor.tabstopManager)\n            editor.tabstopManager.tabNext();\n    }\n\n    $getScope(editor) {\n        var scope = editor.session.$mode.$id || \"\";\n        scope = scope.split(\"/\").pop();\n        if (scope === \"html\" || scope === \"php\") {\n            // PHP is actually HTML\n            if (scope === \"php\" && !editor.session.$mode.inlinePhp)\n                scope = \"html\";\n            var c = editor.getCursorPosition();\n            var state = editor.session.getState(c.row);\n            if (typeof state === \"object\") {\n                state = state[0];\n            }\n            if (state.substring) {\n                if (state.substring(0, 3) == \"js-\")\n                    scope = \"javascript\";\n                else if (state.substring(0, 4) == \"css-\")\n                    scope = \"css\";\n                else if (state.substring(0, 4) == \"php-\")\n                    scope = \"php\";\n            }\n        }\n\n        return scope;\n    }\n\n    getActiveScopes(editor) {\n        var scope = this.$getScope(editor);\n        var scopes = [scope];\n        var snippetMap = this.snippetMap;\n        if (snippetMap[scope] && snippetMap[scope].includeScopes) {\n            scopes.push.apply(scopes, snippetMap[scope].includeScopes);\n        }\n        scopes.push(\"_\");\n        return scopes;\n    }\n\n    expandWithTab(editor, options) {\n        var self = this;\n        var result = editor.forEachSelection(function() {\n            return self.expandSnippetForSelection(editor, options);\n        }, null, {keepOrder: true});\n        if (result && editor.tabstopManager)\n            editor.tabstopManager.tabNext();\n        return result;\n    }\n\n    expandSnippetForSelection(editor, options) {\n        var cursor = editor.getCursorPosition();\n        var line = editor.session.getLine(cursor.row);\n        var before = line.substring(0, cursor.column);\n        var after = line.substr(cursor.column);\n\n        var snippetMap = this.snippetMap;\n        /**@type {Snippet}*/\n        var snippet;\n        this.getActiveScopes(editor).some(function(scope) {\n            var snippets = snippetMap[scope];\n            if (snippets)\n                snippet = this.findMatchingSnippet(snippets, before, after);\n            return !!snippet;\n        }, this);\n        if (!snippet)\n            return false;\n        if (options && options.dryRun)\n            return true;\n        editor.session.doc.removeInLine(cursor.row,\n            cursor.column - snippet.replaceBefore.length,\n            cursor.column + snippet.replaceAfter.length\n        );\n\n        this.variables.M__ = snippet.matchBefore;\n        this.variables.T__ = snippet.matchAfter;\n        this.insertSnippetForSelection(editor, snippet.content);\n\n        this.variables.M__ = this.variables.T__ = null;\n        return true;\n    }\n\n    /**\n     * @param {Snippet[]} snippetList\n     * @param {string} before\n     * @param {string} after\n     * @return {Snippet}\n     */\n    findMatchingSnippet(snippetList, before, after) {\n        for (var i = snippetList.length; i--;) {\n            var s = snippetList[i];\n            if (s.startRe && !s.startRe.test(before))\n                continue;\n            if (s.endRe && !s.endRe.test(after))\n                continue;\n            if (!s.startRe && !s.endRe)\n                continue;\n\n            s.matchBefore = s.startRe ? s.startRe.exec(before) : [\"\"];\n            s.matchAfter = s.endRe ? s.endRe.exec(after) : [\"\"];\n            s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : \"\";\n            s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : \"\";\n            return s;\n        }\n    }\n\n\n    /**\n     * @param {any[]} snippets\n     * @param {string} scope\n     */\n    register(snippets, scope) {\n        var snippetMap = this.snippetMap;\n        var snippetNameMap = this.snippetNameMap;\n        var self = this;\n\n        if (!snippets)\n            snippets = [];\n\n        function wrapRegexp(src) {\n            if (src && !/^\\^?\\(.*\\)\\$?$|^\\\\b$/.test(src))\n                src = \"(?:\" + src + \")\";\n\n            return src || \"\";\n        }\n        function guardedRegexp(re, guard, opening) {\n            re = wrapRegexp(re);\n            guard = wrapRegexp(guard);\n            if (opening) {\n                re = guard + re;\n                if (re && re[re.length - 1] != \"$\")\n                    re = re + \"$\";\n            } else {\n                re = re + guard;\n                if (re && re[0] != \"^\")\n                    re = \"^\" + re;\n            }\n            return new RegExp(re);\n        }\n\n        function addSnippet(s) {\n            if (!s.scope)\n                s.scope = scope || \"_\";\n            scope = s.scope;\n            if (!snippetMap[scope]) {\n                snippetMap[scope] = [];\n                snippetNameMap[scope] = {};\n            }\n\n            var map = snippetNameMap[scope];\n            if (s.name) {\n                var old = map[s.name];\n                if (old)\n                    self.unregister(old);\n                map[s.name] = s;\n            }\n            snippetMap[scope].push(s);\n\n            if (s.prefix)\n                s.tabTrigger = s.prefix;\n\n            if (!s.content && s.body)\n                s.content = Array.isArray(s.body) ? s.body.join(\"\\n\") : s.body;\n\n            if (s.tabTrigger && !s.trigger) {\n                if (!s.guard && /^\\w/.test(s.tabTrigger))\n                    s.guard = \"\\\\b\";\n                s.trigger = lang.escapeRegExp(s.tabTrigger);\n            }\n\n            if (!s.trigger && !s.guard && !s.endTrigger && !s.endGuard)\n                return;\n\n            s.startRe = guardedRegexp(s.trigger, s.guard, true);\n            s.triggerRe = new RegExp(s.trigger);\n\n            s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);\n            s.endTriggerRe = new RegExp(s.endTrigger);\n        }\n\n        if (Array.isArray(snippets)) {\n            snippets.forEach(addSnippet);\n        } else {\n            Object.keys(snippets).forEach(function(key) {\n                addSnippet(snippets[key]);\n            });\n        }\n\n        // @ts-ignore\n        this._signal(\"registerSnippets\", {scope: scope});\n    }\n    unregister(snippets, scope) {\n        var snippetMap = this.snippetMap;\n        var snippetNameMap = this.snippetNameMap;\n\n        function removeSnippet(s) {\n            var nameMap = snippetNameMap[s.scope||scope];\n            if (nameMap && nameMap[s.name]) {\n                delete nameMap[s.name];\n                var map = snippetMap[s.scope||scope];\n                var i = map && map.indexOf(s);\n                if (i >= 0)\n                    map.splice(i, 1);\n            }\n        }\n        if (snippets.content)\n            removeSnippet(snippets);\n        else if (Array.isArray(snippets))\n            snippets.forEach(removeSnippet);\n    }\n    parseSnippetFile(str) {\n        str = str.replace(/\\r/g, \"\");\n        var list = [], /**@type{Snippet}*/snippet = {};\n        var re = /^#.*|^({[\\s\\S]*})\\s*$|^(\\S+) (.*)$|^((?:\\n*\\t.*)+)/gm;\n        var m;\n        while (m = re.exec(str)) {\n            if (m[1]) {\n                try {\n                    snippet = JSON.parse(m[1]);\n                    list.push(snippet);\n                } catch (e) {}\n            } if (m[4]) {\n                snippet.content = m[4].replace(/^\\t/gm, \"\");\n                list.push(snippet);\n                snippet = {};\n            } else {\n                var key = m[2], val = m[3];\n                if (key == \"regex\") {\n                    var guardRe = /\\/((?:[^\\/\\\\]|\\\\.)*)|$/g;\n                    snippet.guard = guardRe.exec(val)[1];\n                    snippet.trigger = guardRe.exec(val)[1];\n                    snippet.endTrigger = guardRe.exec(val)[1];\n                    snippet.endGuard = guardRe.exec(val)[1];\n                } else if (key == \"snippet\") {\n                    snippet.tabTrigger = val.match(/^\\S*/)[0];\n                    if (!snippet.name)\n                        snippet.name = val;\n                } else if (key) {\n                    snippet[key] = val;\n                }\n            }\n        }\n        return list;\n    }\n    getSnippetByName(name, editor) {\n        var snippetMap = this.snippetNameMap;\n        var snippet;\n        this.getActiveScopes(editor).some(function(scope) {\n            var snippets = snippetMap[scope];\n            if (snippets)\n                snippet = snippets[name];\n            return !!snippet;\n        }, this);\n        return snippet;\n    }\n}\n\noop.implement(SnippetManager.prototype, EventEmitter);\n\nvar processSnippetText = function(editor, snippetText, options={}) {\n    var cursor = editor.getCursorPosition();\n    var line = editor.session.getLine(cursor.row);\n    var tabString = editor.session.getTabString();\n    var indentString = line.match(/^\\s*/)[0];\n\n    if (cursor.column < indentString.length)\n        indentString = indentString.slice(0, cursor.column);\n\n    snippetText = snippetText.replace(/\\r/g, \"\");\n    var tokens = this.tokenizeTmSnippet(snippetText);\n    tokens = this.resolveVariables(tokens, editor);\n    // indent\n    tokens = tokens.map(function(x) {\n        if (x == \"\\n\" && !options.excludeExtraIndent)\n            return x + indentString;\n        if (typeof x == \"string\")\n            return x.replace(/\\t/g, tabString);\n        return x;\n    });\n    // tabstop values\n    var tabstops = [];\n    tokens.forEach(function(p, i) {\n        if (typeof p != \"object\")\n            return;\n        var id = p.tabstopId;\n        var ts = tabstops[id];\n        if (!ts) {\n            ts = tabstops[id] = [];\n            ts.index = id;\n            ts.value = \"\";\n            ts.parents = {};\n        }\n        if (ts.indexOf(p) !== -1)\n            return;\n        if (p.choices && !ts.choices)\n            ts.choices = p.choices;\n        ts.push(p);\n        var i1 = tokens.indexOf(p, i + 1);\n        if (i1 === -1)\n            return;\n\n        var value = tokens.slice(i + 1, i1);\n        var isNested = value.some(function(t) {return typeof t === \"object\";});\n        if (isNested && !ts.value) {\n            ts.value = value;\n        } else if (value.length && (!ts.value || typeof ts.value !== \"string\")) {\n            ts.value = value.join(\"\");\n        }\n    });\n\n    // expand tabstop values\n    tabstops.forEach(function(ts) {ts.length = 0;});\n    var expanding = {};\n    function copyValue(val) {\n        var copy = [];\n        for (var i = 0; i < val.length; i++) {\n            var p = val[i];\n            if (typeof p == \"object\") {\n                if (expanding[p.tabstopId])\n                    continue;\n                var j = val.lastIndexOf(p, i - 1);\n                p = copy[j] || {tabstopId: p.tabstopId};\n            }\n            copy[i] = p;\n        }\n        return copy;\n    }\n    for (var i = 0; i < tokens.length; i++) {\n        var p = tokens[i];\n        if (typeof p != \"object\")\n            continue;\n        var id = p.tabstopId;\n        var ts = tabstops[id];\n        var i1 = tokens.indexOf(p, i + 1);\n        if (expanding[id]) {\n            // if reached closing bracket clear expanding state\n            if (expanding[id] === p) {\n                delete expanding[id];\n                Object.keys(expanding).forEach(function(parentId) {\n                    ts.parents[parentId] = true;\n                });\n            }\n            // otherwise just ignore recursive tabstop\n            continue;\n        }\n        expanding[id] = p;\n        var value = ts.value;\n        if (typeof value !== \"string\")\n            value = copyValue(value);\n        else if (p.fmt)\n            value = this.tmStrFormat(value, p, editor);\n        tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));\n\n        if (ts.indexOf(p) === -1)\n            ts.push(p);\n    }\n\n    // convert to plain text\n    var row = 0, column = 0;\n    var text = \"\";\n    tokens.forEach(function(t) {\n        if (typeof t === \"string\") {\n            var lines = t.split(\"\\n\");\n            if (lines.length > 1){\n                column = lines[lines.length - 1].length;\n                row += lines.length - 1;\n            } else\n                column += t.length;\n            text += t;\n        } else if (t) {\n            if (!t.start)\n                t.start = {row: row, column: column};\n            else\n                t.end = {row: row, column: column};\n        }\n    });\n\n    return {\n        text,\n        tabstops,\n        tokens\n    };\n};\n\nclass TabstopManager {\n    constructor(editor) {\n        this.index = 0;\n        this.ranges = [];\n        this.tabstops = [];\n        if (editor.tabstopManager)\n            return editor.tabstopManager;\n        editor.tabstopManager = this;\n        this.$onChange = this.onChange.bind(this);\n        this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;\n        this.$onChangeSession = this.onChangeSession.bind(this);\n        this.$onAfterExec = this.onAfterExec.bind(this);\n        this.attach(editor);\n    }\n\n    attach(editor) {\n        this.$openTabstops = null;\n        this.selectedTabstop = null;\n\n        this.editor = editor;\n        this.session = editor.session;\n        this.editor.on(\"change\", this.$onChange);\n        this.editor.on(\"changeSelection\", this.$onChangeSelection);\n        this.editor.on(\"changeSession\", this.$onChangeSession);\n        this.editor.commands.on(\"afterExec\", this.$onAfterExec);\n        this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);\n    }\n    detach() {\n        this.tabstops.forEach(this.removeTabstopMarkers, this);\n        this.ranges.length = 0;\n        this.tabstops.length = 0;\n        this.selectedTabstop = null;\n        this.editor.off(\"change\", this.$onChange);\n        this.editor.off(\"changeSelection\", this.$onChangeSelection);\n        this.editor.off(\"changeSession\", this.$onChangeSession);\n        this.editor.commands.off(\"afterExec\", this.$onAfterExec);\n        this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);\n        this.editor.tabstopManager = null;\n        this.session = null;\n        this.editor = null;\n    }\n    /**\n     * @internal\n     */\n    onChange(delta) {\n        var isRemove = delta.action[0] == \"r\";\n        var selectedTabstop = this.selectedTabstop || {};\n        var parents = selectedTabstop.parents || {};\n        var tabstops = this.tabstops.slice();\n        for (var i = 0; i < tabstops.length; i++) {\n            var ts = tabstops[i];\n            var active = ts == selectedTabstop || parents[ts.index];\n            ts.rangeList.$bias = active ? 0 : 1;\n\n            if (delta.action == \"remove\" && ts !== selectedTabstop) {\n                var parentActive = ts.parents && ts.parents[selectedTabstop.index];\n                var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);\n                startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;\n                var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);\n                endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;\n                var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);\n                for (var j = 0; j < toRemove.length; j++)\n                    this.removeRange(toRemove[j]);\n            }\n            ts.rangeList.$onChange(delta);\n        }\n        var session = this.session;\n        if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())\n            this.detach();\n    }\n    updateLinkedFields() {\n        var ts = this.selectedTabstop;\n        if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)\n            return;\n        this.$inChange = true;\n        var session = this.session;\n        var text = session.getTextRange(ts.firstNonLinked);\n        for (var i = 0; i < ts.length; i++) {\n            var range = ts[i];\n            if (!range.linked)\n                continue;\n            var original = range.original;\n            var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);\n            session.replace(range, fmt);\n        }\n        this.$inChange = false;\n    }\n    /**\n     * @internal\n     */\n    onAfterExec(e) {\n        if (e.command && !e.command.readOnly)\n            this.updateLinkedFields();\n    }\n    /**\n     * @internal\n     */\n    onChangeSelection() {\n        if (!this.editor)\n            return;\n        var lead = this.editor.selection.lead;\n        var anchor = this.editor.selection.anchor;\n        var isEmpty = this.editor.selection.isEmpty();\n        for (var i = 0; i < this.ranges.length; i++) {\n            if (this.ranges[i].linked)\n                continue;\n            var containsLead = this.ranges[i].contains(lead.row, lead.column);\n            var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);\n            if (containsLead && containsAnchor)\n                return;\n        }\n        this.detach();\n    }\n    /**\n     * @internal\n     */\n    onChangeSession() {\n        this.detach();\n    }\n    tabNext(dir) {\n        var max = this.tabstops.length;\n        var index = this.index + (dir || 1);\n        index = Math.min(Math.max(index, 1), max);\n        if (index == max)\n            index = 0;\n        this.selectTabstop(index);\n        this.updateTabstopMarkers();\n        if (index === 0) {\n            this.detach();\n        }\n    }\n    selectTabstop(index) {\n        this.$openTabstops = null;\n        var ts = this.tabstops[this.index];\n        if (ts)\n            this.addTabstopMarkers(ts);\n        this.index = index;\n        ts = this.tabstops[this.index];\n        if (!ts || !ts.length)\n            return;\n\n        this.selectedTabstop = ts;\n        var range = ts.firstNonLinked || ts;\n        if (ts.choices) range.cursor = range.start;\n        if (!this.editor.inVirtualSelectionMode) {\n            var sel = this.editor.multiSelect;\n            sel.toSingleRange(range);\n            for (var i = 0; i < ts.length; i++) {\n                if (ts.hasLinkedRanges && ts[i].linked)\n                    continue;\n                sel.addRange(ts[i].clone(), true);\n            }\n        } else {\n            this.editor.selection.fromOrientedRange(range);\n        }\n\n        this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);\n        if (this.selectedTabstop && this.selectedTabstop.choices)\n            this.editor.execCommand(\"startAutocomplete\", {matches: this.selectedTabstop.choices});\n    }\n    addTabstops(tabstops, start, end) {\n        var useLink = this.useLink || !this.editor.getOption(\"enableMultiselect\");\n\n        if (!this.$openTabstops)\n            this.$openTabstops = [];\n        // add final tabstop if missing\n        if (!tabstops[0]) {\n            var p = Range.fromPoints(end, end);\n            moveRelative(p.start, start);\n            moveRelative(p.end, start);\n            tabstops[0] = [p];\n            tabstops[0].index = 0;\n        }\n\n        var i = this.index;\n        var arg = [i + 1, 0];\n        var ranges = this.ranges;\n        var snippetId = this.snippetId = (this.snippetId || 0) + 1;\n        tabstops.forEach(function(ts, index) {\n            var dest = this.$openTabstops[index] || ts;\n            dest.snippetId = snippetId;\n            for (var i = 0; i < ts.length; i++) {\n                var p = ts[i];\n                /**@type {Range & {original?: Range, tabstop?: any, linked?: boolean}}}*/\n                var range = Range.fromPoints(p.start, p.end || p.start);\n                movePoint(range.start, start);\n                movePoint(range.end, start);\n                range.original = p;\n                range.tabstop = dest;\n                ranges.push(range);\n                if (dest != ts)\n                    dest.unshift(range);\n                else\n                    dest[i] = range;\n                if (p.fmtString || (dest.firstNonLinked && useLink)) {\n                    range.linked = true;\n                    dest.hasLinkedRanges = true;\n                } else if (!dest.firstNonLinked)\n                    dest.firstNonLinked = range;\n            }\n            if (!dest.firstNonLinked)\n                dest.hasLinkedRanges = false;\n            if (dest === ts) {\n                arg.push(dest);\n                this.$openTabstops[index] = dest;\n            }\n            this.addTabstopMarkers(dest);\n            dest.rangeList = dest.rangeList || new RangeList();\n            dest.rangeList.$bias = 0;\n            dest.rangeList.addList(dest);\n        }, this);\n\n        if (arg.length > 2) {\n            // when adding new snippet inside existing one, make sure 0 tabstop is at the end\n            if (this.tabstops.length)\n                arg.push(arg.splice(2, 1)[0]);\n            this.tabstops.splice.apply(this.tabstops, arg);\n        }\n    }\n\n    addTabstopMarkers(ts) {\n        var session = this.session;\n        ts.forEach(function(range) {\n            if  (!range.markerId)\n                range.markerId = session.addMarker(range, \"ace_snippet-marker\", \"text\");\n        });\n    }\n    removeTabstopMarkers(ts) {\n        var session = this.session;\n        ts.forEach(function(range) {\n            session.removeMarker(range.markerId);\n            range.markerId = null;\n        });\n    }\n    updateTabstopMarkers() {\n        if (!this.selectedTabstop) return;\n        var currentSnippetId =  this.selectedTabstop.snippetId;\n        // back to the parent snippet tabstops if $0\n        if ( this.selectedTabstop.index === 0) {\n            currentSnippetId--;\n        }\n        this.tabstops.forEach(function(ts) {\n            // show marker only for the tabstops of the currently active snippet\n            if (ts.snippetId === currentSnippetId) this.addTabstopMarkers(ts);\n            else this.removeTabstopMarkers(ts);\n        }, this);\n    }\n    removeRange(range) {\n        var i = range.tabstop.indexOf(range);\n        if (i != -1) range.tabstop.splice(i, 1);\n        i = this.ranges.indexOf(range);\n        if (i != -1) this.ranges.splice(i, 1);\n        i = range.tabstop.rangeList.ranges.indexOf(range);\n        if (i != -1) range.tabstop.splice(i, 1);\n        this.session.removeMarker(range.markerId);\n        if (!range.tabstop.length) {\n            i = this.tabstops.indexOf(range.tabstop);\n            if (i != -1)\n                this.tabstops.splice(i, 1);\n            if (!this.tabstops.length)\n                this.detach();\n        }\n    }\n}\n\n\nTabstopManager.prototype.keyboardHandler = new HashHandler();\nTabstopManager.prototype.keyboardHandler.bindKeys({\n    \"Tab\": function(editor) {\n        if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))\n            return;\n        editor.tabstopManager.tabNext(1);\n        editor.renderer.scrollCursorIntoView();\n    },\n    \"Shift-Tab\": function(editor) {\n        editor.tabstopManager.tabNext(-1);\n        editor.renderer.scrollCursorIntoView();\n    },\n    \"Esc\": function(editor) {\n        editor.tabstopManager.detach();\n    }\n});\n\n\nvar movePoint = function(point, diff) {\n    if (point.row == 0)\n        point.column += diff.column;\n    point.row += diff.row;\n};\n\nvar moveRelative = function(point, start) {\n    if (point.row == start.row)\n        point.column -= start.column;\n    point.row -= start.row;\n};\n\n\ndom.importCssString(`\n.ace_snippet-marker {\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    background: rgba(194, 193, 208, 0.09);\n    border: 1px dotted rgba(211, 208, 235, 0.62);\n    position: absolute;\n}`, \"snippets.css\", false);\n\nexports.snippetManager = new SnippetManager();\n\n\nvar Editor = require(\"./editor\").Editor;\n(function() {\n    this.insertSnippet = function(content, options) {\n        return exports.snippetManager.insertSnippet(this, content, options);\n    };\n    this.expandSnippet = function(options) {\n        return exports.snippetManager.expandWithTab(this, options);\n    };\n}).call(Editor.prototype);\n"
  },
  {
    "path": "src/snippets_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar JavascriptMode = require(\"./mode/javascript\").Mode;\nrequire(\"./multi_select\");\nrequire(\"./ext/language_tools\");\n\nvar snippetManager = require(\"./snippets\").snippetManager;\nvar assert = require(\"./test/assertions\");\nvar config = require(\"./config\");\nvar loadModule = config.loadModule;\n\nmodule.exports = {\n    setUp : function() {\n        this.editor = new Editor(new MockRenderer());\n    },\n    tearDown: function() {\n        config.loadModule = loadModule;\n    },\n    \n    \"test: textmate style format strings\" : function() {\n        snippetManager.tmStrFormat(\"hello\", {\n            guard: \"(..)(.)(.)\",\n            flag:\"g\",\n            fmt: \"a\\\\UO\\\\l$1\\\\E$2\"\n        }) == \"aOHElo\";\n    },\n    \"test: parse snipmate file\" : function() {\n        var expected = [{\n            name: \"a\",\n            guard: \"(?:(=)|(:))?\\\\s*)\",\n            trigger: \"\\\\(?f\",\n            endTrigger: \"\\\\)\",\n            endGuard: \"\",\n            content: \"{$0}\\n\"\n         }, {\n            tabTrigger: \"f\",\n            name: \"f function\",\n            content: \"function\"\n        }];\n        \n        var parsed = snippetManager.parseSnippetFile(\n            \"name a\\nregex /(?:(=)|(:))?\\\\s*)/\\\\(?f/\\\\)/\\n\\t{$0}\" +\n            \"\\n\\t\\n\\n#function\\nsnippet f function\\n\\tfunction\"\n        );\n\n        assert.equal(JSON.stringify(expected, null, 4), JSON.stringify(parsed, null, 4));\n    },\n    \"test: parse snippet\": function() {\n        var content = \"-\\\\$$2a${1:x${$2:y$3\\\\}\\\\n\\\\}$TM_SELECTION}\";\n        var tokens = snippetManager.tokenizeTmSnippet(content);\n        assert.equal(tokens.length, 14);\n        assert.equal(tokens[4], tokens[13]);\n        assert.equal(tokens[2].tabstopId, 2);\n\n        var content = \"\\\\}${var/as\\\\/d/\\\\ul\\\\//g}s\";\n        var tokens = snippetManager.tokenizeTmSnippet(content);\n        snippetManager.resolveVariables(tokens, this.editor);\n        assert.equal(tokens.length, 7);\n        assert.equal(tokens[1], tokens[5]);\n        assert.equal(tokens[6], \"s\");\n        assert.equal(tokens[1].text, \"var\");\n        assert.equal(tokens[1].fmt.length, 3);\n        assert.equal(tokens[1].fmt[0].changeCase, \"u\");\n        assert.equal(tokens[1].fmt[1], \"l\");\n        assert.equal(tokens[1].fmt[2], \"\\\\/\");\n        assert.equal(tokens[1].guard, \"as\\\\/d\");\n        assert.equal(tokens[1].flag, \"g\");\n    },\n    \"test: register snippets in json format\": function() {\n        config.loadModule = function() {};\n        this.editor.setOption(\"enableSnippets\", true);\n        this.editor.session.setMode(new JavascriptMode());\n        \n        snippetManager.register({\n            \"Snippet 1\": {\n                prefix: \"xy\",\n                body: [\n                    \"x\",\n                    \"$0\",\n                    \"y\"\n                ]\n            },\n            \"Snippet 2\": {\n                prefix: \"s\",\n                body: \"$0expanded\"\n            }\n        }, \"javascript\");\n        \n        this.editor.execCommand(\"paste\", \"xy\");\n        this.editor.onCommandKey(null, 0, 9);\n        this.editor.execCommand(\"paste\", \"s\");\n        this.editor.onCommandKey(null, 0, 9);\n        assert.equal(this.editor.getValue(), \"x\\nexpanded\\ny\");\n        assert.position(this.editor.getCursorPosition(), 1, 0);\n    },\n    \"test: expand snippet with nested tabstops\": function() {\n        var content = \"-${1}-${1:t\\n1}--${2:2 ${3} 2}-${3:3 $1 3}-${4:4 $2 4}\";\n        this.editor.setValue(\"\");\n        snippetManager.insertSnippet(this.editor, content);\n        assert.equal(this.editor.getValue(), [\n            \"-t\",\n            \"1-t\",\n            \"1--2 3 t\",\n            \"1 3 2-3 t\",\n            \"1 3-4 2 3 t\",\n            \"1 3 2 4\"\n        ].join(\"\\n\"));\n        \n        assert.equal(this.editor.getSelectedText(), \"t\\n1\\nt\\n1\\nt\\n1\\nt\\n1\\nt\\n1\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"2 3 t\\n1 3 2\\n2 3 t\\n1 3 2\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"3 t\\n1 3\\n3 t\\n1 3\\n3 t\\n1 3\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"4 2 3 t\\n1 3 2 4\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"\");\n        \n        this.editor.setValue(\"\");\n        snippetManager.insertSnippet(this.editor, \"-${1:a$2}-${2:b$1}\");\n        assert.equal(this.editor.getValue(), \"-ab-ba\");\n        \n        assert.equal(this.editor.getSelectedText(), \"ab\\na\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"b\\nba\");\n        this.editor.tabstopManager.tabNext();\n        assert.equal(this.editor.getSelectedText(), \"\");\n    },\n    \"test prevent infinite recursion\": function() {\n        var editor = this.editor;\n        editor.setValue(\"\");\n        editor.setValue(\"\");\n        editor.insertSnippet(\"CASE ${1:v} ${4:WHEN ${5:p} $10 $2$3\\n$4\\n\"\n            + \"THEN ${6:r}  } ${7:ELSE ${8:d}} END\"\n        );\n        assert.equal(this.editor.getValue(), \"CASE v WHEN p  \\n\\nTHEN r   ELSE d END\");\n    },\n    \"test: nested format strings\": function() {\n        var editor = this.editor;\n        editor.setValue(\"\");\n        editor.insertSnippet([\n            \"$1 --  ${1/(.)(\\\\d)?(\\\\w\\\\w?)?/\",\n            \"${3:?\",\n            \"    letter is ${3/(.)/\\\\u$1/}, ${2:?number is $2: number is missing}:\",\n            \"    letter is missing ${2:? but number is $2: number is missing too}},\" ,\n            \"    prefix is $1; text is ${0:/upcase};/g}\",\n            \"$0\"\n        ].join(\"\\n\"));\n        assert.equal(editor.getValue().length, 6);\n        editor.execCommand(\"insertstring\", \"q\");\n        assert.equal(editor.getValue().length, 82);\n        editor.execCommand(\"insertstring\", \"1\");\n        assert.equal(editor.getValue().length, 78);\n        editor.execCommand(\"insertstring\", \"w\");\n        assert.equal(editor.getValue().length, 70);\n        editor.execCommand(\"insertstring\", \"a\");\n        editor.execCommand(\"insertstring\", \"l\");\n        editor.execCommand(\"insertstring\", \"s\");\n        editor.execCommand(\"insertstring\", \"t\");\n        assert.equal(editor.getValue(), [\n            \"q1walst --  \",\n            \"\",\n            \"    letter is Wa, number is 1,\",\n            \"    prefix is q; text is Q1WA;\",\n            \"\",\n            \"    letter is St,  number is missing,\",\n            \"    prefix is l; text is LST;\",\n            \"\"\n        ].join(\"\\n\")); \n    },\n    \"test: format if/else\": function() {\n        var editor = this.editor;\n        var snippetText = [\n            \"${CURRENT_LINE/.*/1 ${0:else}/i}\",\n            \"${CURRENT_LINE/.*/2 ${0:-else}/i}\",\n            \"${CURRENT_LINE/.*/3 ${0:+if}/i}\",\n            \"${CURRENT_LINE/.*/4 ${0:?if:else}/i}\",\n            \"${CURRENT_LINE/.*/5 ${0:/downcase}/i}\"\n        ].join(\"\\n\");\n        editor.setValue(\"\");\n        editor.insertSnippet(snippetText);\n        assert.equal(editor.getValue(), \"1 else\\n2 else\\n3 \\n4 else\\n5 \");\n        editor.setValue(\"ACE\");\n        editor.insertSnippet(snippetText);\n        assert.equal(editor.getValue(), \"1 ACE\\n2 ACE\\n3 if\\n4 if\\n5 ace\");\n    },\n    \"test: file paths\": function() {\n        var editor = this.editor;\n        snippetManager.variables.FILEPATH = function() { return \"/dir/base name.ext\"; };\n        editor.setValue(\"\");\n        editor.insertSnippet(\n            \"${TM_FILENAME/^(.)|(?:[-_\\\\s](.))|(\\\\.\\\\w*$)/${1:/upcase}${2:/upcase}/g}\"\n            + \"\\n$FILENAME_BASE\\n$DIRECTORY\\n$FILEPATH\\n$FILENAME\"\n        );\n        assert.equal(editor.getValue(), \"BaseName\\nbase name\\n/dir/\\n/dir/base name.ext\\nbase name.ext\");\n    },\n    \"test: selected text\": function() {\n        var editor = this.editor;\n        editor.setValue(\"foo\\nbar\");\n        editor.selectAll();\n        editor.insertSnippet(\"<div>\\n\\t${1:$TM_SELECTED_TEXT}\\n</div>\");\n        editor.insertSnippet(\"<div>\\n\\t${1:$TM_SELECTED_TEXT}\\n</div>\");\n        editor.insertSnippet(\"<span>${1:$TM_SELECTED_TEXT}</span>\");\n        assert.equal(editor.getValue(), [\n            \"<div>\",\n            \"    <div>\",\n            \"        <span>foo\",\n            \"        bar</span>\",\n            \"    </div>\",\n            \"</div>\"\n        ].join(\"\\n\"));\n    },\n    \"test: date variables\": function() {\n        var editor = this.editor;\n        editor.setValue(\"foo\\nbar\");\n        editor.selectAll();\n        var D = Date;\n        var d = new Date('1970-01-01T00:00:00');\n        d.setHours(4);\n        d.setMinutes(0);\n        Date = function() { return d; }; // eslint-disable-line\n        try {\n            editor.insertSnippet([\n                \"$CURRENT_YEAR\",\n                \"$CURRENT_YEAR_SHORT\",\n                \"$CURRENT_MONTH\",\n                \"$CURRENT_MONTH_NAME\",\n                \"$CURRENT_MONTH_NAME_SHORT\",\n                \"$CURRENT_DATE\",\n                \"$CURRENT_DAY_NAME\",\n                \"$CURRENT_DAY_NAME_SHORT\",\n                \"$CURRENT_HOUR\",\n                \"$CURRENT_MINUTE\",\n                \"$CURRENT_SECOND\"\n            ].join(\"\\n\"));\n        } finally {\n            Date = D;  // eslint-disable-line\n        }\n        \n        assert.equal(editor.getValue(), \"1970\\n70\\n01\\nJanuary\\nJan\\n01\\nThursday\\nThu\\n04\\n00\\n00\");\n    },\n    \"test: choice\": function() {\n        var editor = this.editor;\n        editor.setValue(\"\");\n        editor.insertSnippet(\"${3:${1|and\\\\|\\\\,\\\\\\\\,another,trigger|}  ${2:$1}}\");\n        assert.equal(editor.getValue(), \"and|,\\\\  and|,\\\\\");\n        editor.execCommand(\"insertstring\", \"q\");\n        assert.equal(editor.getValue(), \"q  q\");\n        this.editor.tabstopManager.tabNext();\n        editor.execCommand(\"insertstring\", \"s\");\n        assert.equal(editor.getValue(), \"q  s\");\n        this.editor.tabstopManager.tabNext();\n        editor.execCommand(\"insertstring\", \"t\");\n        assert.equal(editor.getValue(), \"t\");\n    },\n    \"test: deletion\": function() {\n        var editor = this.editor;\n        editor.setValue(\"\");\n        editor.insertSnippet(\"CASE ${1:value} ${4:WHEN ${5:option2} \"\n            + \"THEN ${6:result2}} ${7:ELSE ${8:default}} END\"\n        );\n        editor.onCommandKey(null, 0, 9);\n        editor.onCommandKey(null, 0, 8);\n        editor.onCommandKey(null, 0, 9);\n        assert.equal(editor.getSelectedText(), \"ELSE default\");\n        editor.onCommandKey(null, 4, 9);\n        assert.equal(editor.getSelectedText(), \"\");\n        editor.onCommandKey(null, 4, 9);\n        assert.equal(editor.getSelectedText(), \"value\");\n        assert.ok(editor.tabstopManager);\n        editor.onCommandKey(null, 0, 27);\n        assert.ok(!editor.tabstopManager);\n    },\n    \"test: multiple cursors\": function() {\n        var editor = this.editor;\n        \n        editor.setValue(\"\\n\");\n        editor.selection.splitIntoLines();\n        editor.insertSnippet(\"a-${1:1}-\\na-$1-\\n${2:x}\");\n        editor.insertSnippet(\"b=$1-\\na-${1:2}-\\n${2:y}\");\n        editor.tabstopManager.tabNext();\n        assert.equal(editor.getCopyText(), \"y\\ny\\ny\\ny\");\n        editor.tabstopManager.tabNext();\n        editor.tabstopManager.tabNext();\n        assert.equal(editor.getCopyText(), \"x\\nx\");\n\n        editor.tabstopManager.tabNext(-4);\n        editor.execCommand(\"insertstring\", \".\");\n        editor.tabstopManager.tabNext(2);\n        assert.equal(editor.tabstopManager, null);\n        \n        assert.equal(editor.getValue(), \"a-.-\\na-.-\\nx\\na-.-\\na-.-\\nx\");\n    },\n    \"test: insert snippet inside snippet\": function() {\n        var editor = this.editor;\n        \n        editor.session.setValue(\"\");\n        editor.insertSnippet(\"1+${1:-}\\n1+$1\\ne+${2:end}\");\n        editor.insertSnippet(\"2+${1:-}\\n2+$1\\n3+${2:3}\");\n\n        function testTabstop(tabstop, expected) {\n            assert.equal(tabstop.join().replace(/Range: | -/g, \"\"), expected);\n        }\n        var tabstops = editor.tabstopManager.tabstops;\n        \n        testTabstop(tabstops[0], \"[6/5]> [6/5]\");\n        testTabstop(tabstops[1], \"[0/2]> [2/3],[3/2]> [5/3]\");\n        testTabstop(tabstops[2], \"[4/2]> [4/3],[3/4]> [3/5],[0/4]> [0/5],[1/2]> [1/3]\");\n        testTabstop(tabstops[3], \"[5/2]> [5/3],[2/2]> [2/3]\");\n        testTabstop(tabstops[4], \"[5/3]> [5/3],[2/3]> [2/3]\");\n        testTabstop(tabstops[5], \"[6/2]> [6/5]\");\n    },\n    \"test: insert snippet inside snippet and check markers\": function() {\n        var editor = this.editor;\n        editor.session.setValue(\"\");\n        editor.insertSnippet(\"{$1}\");\n\n        // check first snippet's marker\n        var snippetMarkers = Object.values(editor.session.$backMarkers).filter(function(i) {return i.clazz == \"ace_snippet-marker\";});\n        assert.jsonEquals(snippetMarkers[0].range.start, {row: 0, column: 2});\n        assert.jsonEquals(snippetMarkers[1].range.start, {row: 0, column: 1});\n\n        // check markers after insertion of the second snippet\n        editor.insertSnippet(\"\\\"examples\\\": [$1]\");\n        snippetMarkers = Object.values(editor.session.$backMarkers).filter(function(i) {return i.clazz == \"ace_snippet-marker\";});\n        assert.equal(snippetMarkers.length, 2);\n        assert.jsonEquals(snippetMarkers[0].range.start, {row: 0, column: 15});\n        assert.jsonEquals(snippetMarkers[1].range.start, {row: 0, column: 14});\n    },\n    \"test: linking\": function() {\n        var editor = this.editor;\n        editor.setOption(\"enableMultiselect\", false);\n        editor.setValue(\"\");\n        editor.insertSnippet(\"${1:x} $1 $1\");\n        assert.equal(editor.getValue(), \"x x x\");\n        editor.execCommand(\"insertstring\", \"qt\");\n        assert.equal(editor.getValue(), \"qt qt qt\");\n        this.editor.tabstopManager.tabNext();\n        editor.execCommand(\"insertstring\", \".\");\n        assert.equal(editor.getValue(), \"qt qt qt.\");\n    },\n    \"test: should work as expected with object of Range interface\": function () {\n        var content = \"test\";\n        this.editor.setValue(\"replace1\");\n        snippetManager.insertSnippet(this.editor, content, {\n            start: {row: 0, column: 0}, end: {row: 0, column: 8}\n        });\n        assert.equal(this.editor.getValue(), \"test\");\n    },\n    \"test: insert snippet without extra indentation\": function() {\n        var editor = this.editor;\n        const options = {\n            excludeExtraIndent: true\n        };\n        const correctlyFormattedCode = [\n            \"def multiply_with_random(array):\",\n            \"    for i in range(len(array)):\",\n            \"        array[i] *= random.randint(1, 10)\",\n            \"    return array\"\n        ].join(\"\\n\");\n\n        editor.setValue(\"\");\n        snippetManager.insertSnippet(this.editor, \"def multiply_with_random(array):\\n\\t\");\n        snippetManager.insertSnippet(this.editor, \"for i in range(len(array)):\\n\\t\\tarray[i] *= random.randint(1, 10)\\n\\treturn array\");\n        assert.notEqual(editor.getValue(), correctlyFormattedCode);\n\n        editor.setValue(\"\");\n        snippetManager.insertSnippet(this.editor, \"def multiply_with_random(array):\\n\\t\", options);\n        snippetManager.insertSnippet(this.editor, \"for i in range(len(array)):\\n\\t\\tarray[i] *= random.randint(1, 10)\\n\\treturn array\", options);\n        assert.equal(editor.getValue(), correctlyFormattedCode);\n    },\n    \n    \"test: snippets without multiselct\": function() {\n        var session = new EditSession([]);\n        var editor = new Editor(new MockRenderer());\n        editor.setOption(\"enableMultiselect\", false);\n        editor.setSession(session);\n\n        editor.insertSnippet(\"hello $1 world $1\");\n        editor.onTextInput(\"!\");\n        assert.equal(editor.getValue(), \"hello ! world !\");\n    },\n\n    \"test: TabstopManager does not throw unhandled errors when session becomes `undefined`\": function() {\n        var editor = new Editor(new MockRenderer());\n        var session = new EditSession(\"dummy content\");\n        editor.setSession(session);\n        snippetManager.insertSnippet(editor, \"snippet $1 with $2 tabstops\");\n        assert.equal(session.$backMarkers[5].clazz, \"ace_snippet-marker\");\n        editor.setSession(undefined);\n        assert.equal(session.$backMarkers[5], undefined);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/split.js",
    "content": "\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar lang = require(\"./lib/lang\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Editor = require(\"./editor\").Editor;\nvar Renderer = require(\"./virtual_renderer\").VirtualRenderer;\nvar EditSession = require(\"./edit_session\").EditSession;\n\n/**\n * @typedef {import(\"../ace-internal\").Ace.EventEmitter & {[key: string]: any}} ISplit\n */\n\nvar Split;\n/**\n * @constructor\n * @this {ISplit}\n */\nSplit = function(container, theme, splits) {\n    this.BELOW = 1;\n    this.BESIDE = 0;\n\n    this.$container = container;\n    this.$theme = theme;\n    this.$splits = 0;\n    this.$editorCSS = \"\";\n    this.$editors = [];\n    this.$orientation = this.BESIDE;\n\n    this.setSplits(splits || 1);\n    this.$cEditor = this.$editors[0];\n\n\n    this.on(\"focus\", function(editor) {\n        this.$cEditor = editor;\n    }.bind(this));\n};\n\n(function(){\n\n    oop.implement(this, EventEmitter);\n\n    /**\n     * @returns {Editor}\n     * @this {ISplit}\n     */\n    this.$createEditor = function() {\n        var el = document.createElement(\"div\");\n        el.className = this.$editorCSS;\n        el.style.cssText = \"position: absolute; top:0px; bottom:0px\";\n        this.$container.appendChild(el);\n        var editor = new Editor(new Renderer(el, this.$theme));\n\n        editor.on(\"focus\", function() {\n            this._emit(\"focus\", editor);\n        }.bind(this));\n\n        this.$editors.push(editor);\n        editor.setFontSize(this.$fontSize);\n        return editor;\n    };\n\n    /**\n     * \n     * @param splits\n     * @this {ISplit}\n     */\n    this.setSplits = function(splits) {\n        var editor;\n        if (splits < 1) {\n            throw \"The number of splits have to be > 0!\";\n        }\n\n        if (splits == this.$splits) {\n            return;\n        } else if (splits > this.$splits) {\n            while (this.$splits < this.$editors.length && this.$splits < splits) {\n                editor = this.$editors[this.$splits];\n                this.$container.appendChild(editor.container);\n                editor.setFontSize(this.$fontSize);\n                this.$splits ++;\n            }\n            while (this.$splits < splits) {\n                this.$createEditor();\n                this.$splits ++;\n            }\n        } else {\n            while (this.$splits > splits) {\n                editor = this.$editors[this.$splits - 1];\n                this.$container.removeChild(editor.container);\n                this.$splits --;\n            }\n        }\n        this.resize();\n    };\n\n    /**\n     * \n     * Returns the number of splits.\n     * @returns {Number}\n     * @this {ISplit}\n     **/\n    this.getSplits = function() {\n        return this.$splits;\n    };\n\n    /**\n     * @param {Number} idx The index of the editor you want\n     *\n     * Returns the editor identified by the index `idx`.\n     * @this {ISplit}\n     **/\n    this.getEditor = function(idx) {\n        return this.$editors[idx];\n    };\n\n    /**\n     * \n     * Returns the current editor.\n     * @returns {Editor}\n     * @this {ISplit}\n     **/\n    this.getCurrentEditor = function() {\n        return this.$cEditor;\n    };\n\n    /** \n     * Focuses the current editor.\n     * @related Editor.focus\n     * @this {ISplit}\n     **/\n    this.focus = function() {\n        this.$cEditor.focus();\n    };\n\n    /** \n     * Blurs the current editor.\n     * @related Editor.blur\n     * @this {ISplit}\n     **/\n    this.blur = function() {\n        this.$cEditor.blur();\n    };\n\n    /** \n     * \n     * @param {String} theme The name of the theme to set\n     * \n     * Sets a theme for each of the available editors.\n     * @related Editor.setTheme\n     * @this {ISplit}\n     **/\n    this.setTheme = function(theme) {\n        this.$editors.forEach(function(editor) {\n            editor.setTheme(theme);\n        });\n    };\n\n    /** \n     * \n     * @param {String} keybinding \n     * \n     * Sets the keyboard handler for the editor.\n     * @related editor.setKeyboardHandler\n     * @this {ISplit}\n     **/\n    this.setKeyboardHandler = function(keybinding) {\n        this.$editors.forEach(function(editor) {\n            editor.setKeyboardHandler(keybinding);\n        });\n    };\n\n    /** \n     * \n     * @param {Function} callback A callback function to execute\n     * @param {String} scope The default scope for the callback\n     * \n     * Executes `callback` on all of the available editors. \n     * @this {ISplit}\n     **/\n    this.forEach = function(callback, scope) {\n        this.$editors.forEach(callback, scope);\n    };\n\n\n    this.$fontSize = \"\";\n    /** \n     * @param {Number} size The new font size\n     * \n     * Sets the font size, in pixels, for all the available editors.\n     * @this {ISplit}\n     **/\n    this.setFontSize = function(size) {\n        this.$fontSize = size;\n        this.forEach(function(editor) {\n           editor.setFontSize(size);\n        });\n    };\n\n    /**\n     * \n     * @param {EditSession} session\n     * @return {EditSession}\n     */\n    this.$cloneSession = function(session) {\n        var s = new EditSession(session.getDocument(), session.getMode());\n\n        var undoManager = session.getUndoManager();\n        s.setUndoManager(undoManager);\n\n        // Copy over 'settings' from the session.\n        s.setTabSize(session.getTabSize());\n        s.setUseSoftTabs(session.getUseSoftTabs());\n        s.setOverwrite(session.getOverwrite());\n        // @ts-expect-error TODO: string[] != number[]\n        s.setBreakpoints(session.getBreakpoints());\n        s.setUseWrapMode(session.getUseWrapMode());\n        s.setUseWorker(session.getUseWorker());\n        s.setWrapLimitRange(session.$wrapLimitRange.min,\n                            session.$wrapLimitRange.max);\n        s.$foldData = session.$cloneFoldData();\n\n        return s;\n    };\n\n   /** \n     * \n     * @param {EditSession} session The new edit session\n     * @param {Number} idx The editor's index you're interested in\n     * \n     * Sets a new [[EditSession `EditSession`]] for the indicated editor.\n     * @related Editor.setSession\n     * @this {ISplit}\n     **/\n    this.setSession = function(session, idx) {\n        var editor;\n        if (idx == null) {\n            editor = this.$cEditor;\n        } else {\n            editor = this.$editors[idx];\n        }\n\n        // Check if the session is used already by any of the editors in the\n        // split. If it is, we have to clone the session as two editors using\n        // the same session can cause terrible side effects (e.g. UndoQueue goes\n        // wrong). This also gives the user of Split the possibility to treat\n        // each session on each split editor different.\n        var isUsed = this.$editors.some(function(editor) {\n           return editor.session === session;\n        });\n\n        if (isUsed) {\n            session = this.$cloneSession(session);\n        }\n        editor.setSession(session);\n\n        // Return the session set on the editor. This might be a cloned one.\n        return session;\n    };\n\n   /** \n     * \n     * Returns the orientation.\n     * @returns {Number}\n     * @this {ISplit}\n     **/\n    this.getOrientation = function() {\n        return this.$orientation;\n    };\n\n   /** \n     * \n     * Sets the orientation.\n     * @param {Number} orientation The new orientation value\n     * @this {ISplit}\n     *\n     **/\n    this.setOrientation = function(orientation) {\n        if (this.$orientation == orientation) {\n            return;\n        }\n        this.$orientation = orientation;\n        this.resize();\n    };\n\n   /**  \n     * Resizes the editor.\n     * @this {ISplit}\n     **/\n    this.resize = function() {\n        var width = this.$container.clientWidth;\n        var height = this.$container.clientHeight;\n        var editor;\n\n        if (this.$orientation == this.BESIDE) {\n            var editorWidth = width / this.$splits;\n            for (var i = 0; i < this.$splits; i++) {\n                editor = this.$editors[i];\n                editor.container.style.width = editorWidth + \"px\";\n                editor.container.style.top = \"0px\";\n                editor.container.style.left = i * editorWidth + \"px\";\n                editor.container.style.height = height + \"px\";\n                editor.resize();\n            }\n        } else {\n            var editorHeight = height / this.$splits;\n            for (var i = 0; i < this.$splits; i++) {\n                editor = this.$editors[i];\n                editor.container.style.width = width + \"px\";\n                editor.container.style.top = i * editorHeight + \"px\";\n                editor.container.style.left = \"0px\";\n                editor.container.style.height = editorHeight + \"px\";\n                editor.resize();\n            }\n        }\n    };\n\n}).call(Split.prototype);\n\nexports.Split = Split;\n"
  },
  {
    "path": "src/test/all.js",
    "content": "\"use strict\";\n\nvar test = require(\"asyncjs\").test;\ntest.walkTestCases(__dirname + \"/..\").exec();\n"
  },
  {
    "path": "src/test/all_browser.js",
    "content": "\"use strict\";\n\nrequire(\"ace/lib/fixoldbrowsers\");\n\nvar mockdom = require(\"../test/mockdom\");\nvar buildDom = require(\"../lib/dom\").buildDom;\nvar escapeRegExp = require(\"ace/lib/lang\").escapeRegExp;\n\nvar useMockdom = location.search.indexOf(\"mock=1\") != -1;\nvar forceShow = location.search.indexOf(\"show=1\") != -1;\n\nvar documentElement = document.documentElement;\nvar log = buildDom([\"div\", {id: \"log\"}], documentElement);\n\nvar undef = window.requirejs.undef;\n// change buildDom to use real document in mockdom \nvar createElement = document.createElement.bind(document);\nvar createTextNode = document.createTextNode.bind(document);\nvar buildDom = eval(\"(\" + buildDom.toString().replace(/document\\./g, \"\") + \")\");\n\nwindow.onerror = function name(...params) {\n};\nwindow.addEventListener('unhandledrejection', (event) => {\n    currentStep.error = event.reason instanceof Error ? event.reason : new Error(\"Unhandled promise rejection: \" + event.reason);\n    if (!currentStep.running) {\n        resume();\n    }\n});\n\nvar testNames = require(\"./test_list\").filter(name => !/_test\\/highlight_rules_test/.test(name));\n\nvar html = [\n    [\"div\", {ref: \"summary\"}],\n    useMockdom\n        ? [\"a\", {href: normalizeHref(location.search.replace('mock=1', '')) + location.hash}, \"do not use mockdom\"]\n        : [\"a\", {href: normalizeHref(location.search + '&mock=1') + location.hash}, \"use mockdom\"],\n    [\"br\"],\n    forceShow\n        ? [\"a\", {href: normalizeHref(location.search.replace('show=1', '')) + location.hash}, \"hide mock renderer\"]\n        : [\"a\", {href: normalizeHref(location.search + '&show=1') + location.hash}, \"show mock renderer\"],\n    [\"br\"],\n    [\"a\", {href: '?runall' + (useMockdom ? \"&mock=1\" : \"\")}, \"Run all tests\"], [\"br\"],\n    [\"hr\"]\n];\nfor (var i in testNames) {    \n    html.push(testLink(testNames[i]), [\"br\"]);\n}\nfunction testHref(suiteName, name) {\n    var href = '?' + suiteName + (useMockdom ? \"&mock=1\" : \"\");\n    if (name) href += \"#\" + escapeRegExp(name.replace(/^test\\s*/, \"\"));\n    return href;\n}\nfunction testLink(name) {\n    return [\"a\", {href: testHref(name)}, name.replace(/^ace\\//, \"\") + \".js\"];\n}\nfunction normalizeHref(str) {\n    return str.replace(/([?&])&+/g, \"$1\");\n}\n\nvar refs = {};\nvar nav = buildDom([\"div\", {id: \"sidebar\"}, html], documentElement, refs);\n\n\nif (forceShow) {\n    // @ts-ignore\n    require([\"ace/virtual_renderer\", \"ace/test/mockrenderer\"], function(real, mock) {\n        var VirtualRenderer = real.VirtualRenderer;\n        mock.MockRenderer = function() {\n            var el = document.createElement(\"div\");\n            el.style.position = \"fixed\";\n            el.style.left = \"20px\";\n            el.style.top = \"30px\";\n            el.style.width = \"500px\";\n            el.style.height = \"300px\";\n            document.body.appendChild(el);\n            \n            return new VirtualRenderer(el);\n        };\n    });\n}\n\nif (useMockdom) {\n    mockdom.loadInBrowser(window);\n    undef(\"ace/lib/\", true);\n}\n\nvar selectedTests = [];\nif (location.search) {\n    var parts = location.search.split(/[&?]|\\w+=\\w+/).filter(Boolean);\n    if (parts[0] == \"runall\")\n        selectedTests = testNames;\n    else\n        selectedTests = parts[0].split(\",\");\n}\nvar filter = decodeURIComponent(location.hash.substr(1));\nwindow.onhashchange = function() { location.reload(); };\n\nvar failed = 0;\nvar passed = 0;\nvar skipped = 0;\nvar reporter = {\n    beforeEach: function(test) {\n        if (!test.name) return;\n        var isScrolled = log.scrollTop - (log.scrollHeight - log.clientHeight) > -1;\n        var messageHeader =  \"[\" + test.index + \"/\" + test.count + \"]\";\n        var node = buildDom([\"div\", {class: test.skip ? \"skipped\" : \"waiting\"}, \n            [\"a\", {href: testHref(test.testSuite.href, test.name)}, messageHeader],\n            \" \",\n            test.name,\n            [\"span\", (test.skip ? \" SKIP\" : \" ...\")],\n        ], log);\n        test.reportNode = node;\n        console.log(messageHeader + test.name);\n        if (isScrolled) log.scrollTop = log.scrollHeight;\n    },\n    afterEach: function(test) {\n        if (!log.parentElement) {\n            documentElement.appendChild(log);\n        }\n        if (!test.name) return;\n        if (test.skip) {\n            skipped++;\n            return;\n        } else if (test.passed) {\n            passed++;\n        } else {\n            failed++;\n        }\n        var isScrolled = log.scrollTop - (log.scrollHeight - log.clientHeight) > -1;\n        \n        test.reportNode.className = test.passed ? \"passed\" : \"failed\";\n        test.reportNode.lastChild.remove();\n        buildDom([\"span\", (test.passed ? \" OK\" : \" FAIL\") + \"  \" + test.time + \"ms\"], test.reportNode);\n        if (test.error && test.error != true)\n            buildDom([\"pre\", {class: \"error\"}, test.error + \"\\n\" + test.error.stack.replace(/^\\w*Error/, \"\")], log);\n\n        refs.summary.innerText = \"Passed: \" + passed + \", Failed: \" + failed + \", Skipped: \" + skipped;\n        if (isScrolled) log.scrollTop = log.scrollHeight;\n    },\n    before: function(testSuite) {\n        var isScrolled = log.scrollTop - (log.scrollHeight - log.clientHeight) > -1;\n        var counter = \" [\" + testSuite.index + \"/\" + testSuite.count + \"]\";\n        var href = testSuite.href;\n        buildDom([\"div\", {}, testLink(href), counter], log);\n        console.log(href, counter);\n        if (isScrolled) log.scrollTop = log.scrollHeight;\n    },\n    after: function(testSuite) {\n\n    },\n    done: function() {\n        var isScrolled = log.scrollTop - (log.scrollHeight - log.clientHeight) > -1;\n        if (!log.parentElement) {\n            documentElement.appendChild(log);\n        }\n        var node = buildDom([\"div\", {class: \"summary\"},\n            [\"br\"], \"Summary:\", [\"br\"], [\"br\"],\n            \"Total number of tests: \" + (passed + failed + skipped), [\"br\"],\n            (passed && [null, \"Passed tests: \" + passed, [\"br\"]]),\n            (passed && [null, \"Passed tests: \" + skipped, [\"br\"]]),\n            (failed && [null, \"Failed tests: \" + failed])\n        ], log);\n        console.log(node.innerText);\n        if (isScrolled) log.scrollTop = log.scrollHeight;\n    },\n    beforeStep: function(step) {\n        if (step.type == \"before\") {\n            reporter.before(step.testSuite);\n        } else  {\n            reporter.beforeEach(step);\n        }\n    },\n    afterStep: function(step) {\n        if (step.type == \"after\") {\n            reporter.after(step.testSuite);\n        } else if (step.type == \"done\") {\n            reporter.done();\n        } else  {\n            reporter.afterEach(step);\n        }\n    },\n};\n\n\nvar currentStep;\nvar waitForStepCallback;\nvar watchdog;\nvar steps = [];\nfunction resume() {\n    if (currentStep) {\n        var step = currentStep;\n        currentStep = null;\n        reporter.afterStep(step);\n    }\n    waitForStepCallback(); \n}\nasync function runSteps() {\n    watchdog = setInterval(() => {\n        if (!currentStep) return;\n        currentStep.interactiveTime = (currentStep.interactiveTime || 0) + 50;\n        if (currentStep.interactiveTime >= currentStep.timeout) {\n            if (currentStep.error == undefined)\n                currentStep.error = new Error(\"Source did not respond after \" + (currentStep.timeout || 0) + \"ms!\");\n            resume();\n        }\n    }, 50);\n    while (currentStep = steps.shift()) {\n        currentStep.timeout = (currentStep.testSuite?.timeout || 3000);\n        var waitForStep = new Promise(resolve => { waitForStepCallback = resolve; });\n        setTimeout(runOne, 0);\n        await waitForStep;\n    }\n    clearInterval(watchdog);\n}\nasync function runOne() {\n    var step = currentStep;\n    var doneCalled = false;\n    var done = function(error) {\n        if (doneCalled) return;\n        if (error) step.error = error;\n        step.passed = !step.error;\n        step.time = Date.now() - t;\n        doneCalled = true;\n        resume();\n    };\n    var t = Date.now();\n\n    step.passed = false;\n    reporter.beforeStep(step);\n\n    if (!step.fn) return done();\n    step.running = true;\n    try {\n        if (step.fn.length) {\n            await step.fn.call(step.testSuite, done);\n        } else {\n            await step.fn.call(step.testSuite);\n            done();\n        }\n    } finally {\n        step.time = Date.now() - t;\n        step.running = false;\n    }\n}\n\n// @ts-ignore\nrequire(selectedTests, async function() {\n    var testSuites = selectedTests.map(function(x) {\n        var module = require(x);\n        module.href = x;\n        return module;\n    });\n\n    steps = [];\n    for (var i = 0; i < testSuites.length; i++) {\n        var testSuite = testSuites[i];\n        testSuite.index = i + 1;\n        testSuite.count = testSuites.length;\n\n        var testArray = [];\n        Object.keys(testSuite).forEach(name => {\n            if (!name.match(/^>?test/))\n                return;\n            var test = {name, testSuite, fn: testSuite[name]};\n            if (filter && !test.name.match(filter)) {\n                test.skip = true;\n            }\n            testArray.push(test);\n        });\n\n        if (!testArray.length) continue;\n\n        steps.push({type: \"before\", testSuite, fn: testSuite.setUpSuite});\n        for (var j = 0; j < testArray.length; j++) {\n            var test = testArray[j];\n            test.index = j + 1;\n            test.count = testArray.length;\n            steps.push({type: \"beforeEach\", testSuite, fn: testSuite.setUp});\n            steps.push(test);\n            steps.push({type: \"afterEach\", testSuite, fn: testSuite.tearDown});\n        } \n        steps.push({type: \"after\", testSuite, fn: testSuite.tearDownSuite});\n    }\n\n    steps.push({type: \"done\"});\n\n    runSteps();\n});\n"
  },
  {
    "path": "src/test/assertions.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\n    \nassert.position = function(cursor, row, column) {\n    assert.equal(cursor.row, row);\n    assert.equal(cursor.column, column);\n};\n\nassert.range = function(range, startRow, startColumn, endRow, endColumn) {\n    assert.position(range.start, startRow, startColumn);\n    assert.position(range.end, endRow, endColumn);\n};\n\nassert.notOk = function(value) {\n    assert.equal(value, false);   \n};\n\nassert.jsonEquals = function(foundJson, expectedJson) {\n    assert.equal(JSON.stringify(foundJson), JSON.stringify(expectedJson));\n};\n\nassert.domNode = function(foundDom, expectedDom) {\n    if (!Array.isArray(foundDom))\n        foundDom = serializeDom(foundDom);\n    assert.deepEqual(foundDom, expectedDom);\n};\n\nfunction serializeDom(node) {\n    var attributes = {};\n    var attributeArray = node.attributes;\n    if (!attributeArray)\n        return node.data;\n    if (typeof attributeArray.length == \"number\") {\n        for (var i = 0; i < attributeArray.length; i++)\n            attributes[attributeArray[i].name] = attributeArray[i].value;\n    }\n    var result = [node.localName, attributes];\n    for (var i = 0; i < node.childNodes.length; i++) {\n        var child = serializeDom(node.childNodes[i]);\n        if (child)\n            result.push(child);\n    }\n    return result;\n}\n\nmodule.exports = assert;\n"
  },
  {
    "path": "src/test/asyncjs/assert.js",
    "content": "// http://wiki.commonjs.org/wiki/Unit_Testing/1.0\n//\n// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!\n//\n// Originally from narwhal.js (http://narwhaljs.org)\n// Copyright (c) 2009 Thomas Robinson <280north.com>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// UTILITY\nvar oop = require(\"ace/lib/oop\");\nvar pSlice = Array.prototype.slice;\n\n// 1. The assert module provides functions that throw\n// AssertionError's when particular conditions are not met. The\n// assert module must conform to the following interface.\n\nvar assert = exports;\n\n// 2. The AssertionError is defined in assert.\n// new assert.AssertionError({ message: message,\n//                             actual: actual,\n//                             expected: expected })\n\nassert.AssertionError = function AssertionError(options) {\n  this.name = 'AssertionError';\n  this.message = options.message;\n  this.actual = options.actual;\n  this.expected = options.expected;\n  this.operator = options.operator;\n  var stackStartFunction = options.stackStartFunction || fail;\n\n  if (Error.captureStackTrace) {\n    Error.captureStackTrace(this, stackStartFunction);\n  }\n};\noop.inherits(assert.AssertionError, Error);\n\ntoJSON = function(obj) {\n    if (typeof JSON !== \"undefined\")\n        return JSON.stringify(obj);\n    else\n        return obj.toString();\n}\n\nassert.AssertionError.prototype.toString = function() {\n  if (this.message) {\n    return [this.name + ':', this.message].join(' ');\n  } else {\n    return [this.name + ':',\n            toJSON(this.expected),\n            this.operator,\n            toJSON(this.actual)].join(' ');\n  }\n};\n\n// assert.AssertionError instanceof Error\n\nassert.AssertionError.__proto__ = Error.prototype;\n\n// At present only the three keys mentioned above are used and\n// understood by the spec. Implementations or sub modules can pass\n// other keys to the AssertionError's constructor - they will be\n// ignored.\n\n// 3. All of the following functions must throw an AssertionError\n// when a corresponding condition is not met, with a message that\n// may be undefined if not provided.  All assertion methods provide\n// both the actual and expected values to the assertion error for\n// display purposes.\n\nfunction fail(actual, expected, message, operator, stackStartFunction) {\n  throw new assert.AssertionError({\n    message: message,\n    actual: actual,\n    expected: expected,\n    operator: operator,\n    stackStartFunction: stackStartFunction\n  });\n}\n\n// EXTENSION! allows for well behaved errors defined elsewhere.\nassert.fail = fail;\n\n// 4. Pure assertion tests whether a value is truthy, as determined\n// by !!guard.\n// assert.ok(guard, message_opt);\n// This statement is equivalent to assert.equal(true, guard,\n// message_opt);. To test strictly for the value true, use\n// assert.strictEqual(true, guard, message_opt);.\n\nassert.ok = function ok(value, message) {\n  if (!!!value) fail(value, true, message, '==', assert.ok);\n};\n\n// 5. The equality assertion tests shallow, coercive equality with\n// ==.\n// assert.equal(actual, expected, message_opt);\n\nassert.equal = function equal(actual, expected, message) {\n  if (actual != expected) fail(actual, expected, message, '==', assert.equal);\n};\n\n// 6. The non-equality assertion tests for whether two objects are not equal\n// with != assert.notEqual(actual, expected, message_opt);\n\nassert.notEqual = function notEqual(actual, expected, message) {\n  if (actual == expected) {\n    fail(actual, expected, message, '!=', assert.notEqual);\n  }\n};\n\n// 7. The equivalence assertion tests a deep equality relation.\n// assert.deepEqual(actual, expected, message_opt);\n\nassert.deepEqual = function deepEqual(actual, expected, message) {\n  if (!_deepEqual(actual, expected)) {\n    fail(actual, expected, message, 'deepEqual', assert.deepEqual);\n  }\n};\n\nfunction _deepEqual(actual, expected) {\n  // 7.1. All identical values are equivalent, as determined by ===.\n  if (actual === expected) {\n    return true;\n\n  } else if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {\n    if (actual.length != expected.length) return false;\n\n    for (var i = 0; i < actual.length; i++) {\n      if (actual[i] !== expected[i]) return false;\n    }\n\n    return true;\n\n  // 7.2. If the expected value is a Date object, the actual value is\n  // equivalent if it is also a Date object that refers to the same time.\n  } else if (actual instanceof Date && expected instanceof Date) {\n    return actual.getTime() === expected.getTime();\n\n  // 7.3. Other pairs that do not both pass typeof value == 'object',\n  // equivalence is determined by ==.\n  } else if (typeof actual != 'object' && typeof expected != 'object') {\n    return actual == expected;\n\n  // 7.4. For all other Object pairs, including Array objects, equivalence is\n  // determined by having the same number of owned properties (as verified\n  // with Object.prototype.hasOwnProperty.call), the same set of keys\n  // (although not necessarily the same order), equivalent values for every\n  // corresponding key, and an identical 'prototype' property. Note: this\n  // accounts for both named and indexed properties on Arrays.\n  } else {\n    return objEquiv(actual, expected);\n  }\n}\n\nfunction isUndefinedOrNull(value) {\n  return value === null || value === undefined;\n}\n\nfunction isArguments(object) {\n  return Object.prototype.toString.call(object) == '[object Arguments]';\n}\n\nfunction objEquiv(a, b) {\n  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))\n    return false;\n  // an identical 'prototype' property.\n  if (a.prototype !== b.prototype) return false;\n  //~~~I've managed to break Object.keys through screwy arguments passing.\n  //   Converting to array solves the problem.\n  if (isArguments(a)) {\n    if (!isArguments(b)) {\n      return false;\n    }\n    a = pSlice.call(a);\n    b = pSlice.call(b);\n    return _deepEqual(a, b);\n  }\n  try {\n    var ka = Object.keys(a),\n        kb = Object.keys(b),\n        key, i;\n  } catch (e) {//happens when one is a string literal and the other isn't\n    return false;\n  }\n  // having the same number of owned properties (keys incorporates\n  // hasOwnProperty)\n  if (ka.length != kb.length)\n    return false;\n  //the same set of keys (although not necessarily the same order),\n  ka.sort();\n  kb.sort();\n  //~~~cheap key test\n  for (i = ka.length - 1; i >= 0; i--) {\n    if (ka[i] != kb[i])\n      return false;\n  }\n  //equivalent values for every corresponding key, and\n  //~~~possibly expensive deep test\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!_deepEqual(a[key], b[key])) return false;\n  }\n  return true;\n}\n\n// 8. The non-equivalence assertion tests for any deep inequality.\n// assert.notDeepEqual(actual, expected, message_opt);\n\nassert.notDeepEqual = function notDeepEqual(actual, expected, message) {\n  if (_deepEqual(actual, expected)) {\n    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);\n  }\n};\n\n// 9. The strict equality assertion tests strict equality, as determined by ===.\n// assert.strictEqual(actual, expected, message_opt);\n\nassert.strictEqual = function strictEqual(actual, expected, message) {\n  if (actual !== expected) {\n    fail(actual, expected, message, '===', assert.strictEqual);\n  }\n};\n\n// 10. The strict non-equality assertion tests for strict inequality, as\n// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);\n\nassert.notStrictEqual = function notStrictEqual(actual, expected, message) {\n  if (actual === expected) {\n    fail(actual, expected, message, '!==', assert.notStrictEqual);\n  }\n};\n\nfunction expectedException(actual, expected) {\n  if (!actual || !expected) {\n    return false;\n  }\n\n  if (expected instanceof RegExp) {\n    return expected.test(actual);\n  } else if (actual instanceof expected) {\n    return true;\n  } else if (expected.call({}, actual) === true) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction _throws(shouldThrow, block, expected, message) {\n  var actual;\n\n  if (typeof expected === 'string') {\n    message = expected;\n    expected = null;\n  }\n\n  try {\n    block();\n  } catch (e) {\n    actual = e;\n  }\n\n  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +\n            (message ? ' ' + message : '.');\n\n  if (shouldThrow && !actual) {\n    fail('Missing expected exception' + message);\n  }\n\n  if (!shouldThrow && expectedException(actual, expected)) {\n    fail('Got unwanted exception' + message);\n  }\n\n  if ((shouldThrow && actual && expected &&\n      !expectedException(actual, expected)) || (!shouldThrow && actual)) {\n    throw actual;\n  }\n}\n\n// 11. Expected to throw an error:\n// assert.throws(block, Error_opt, message_opt);\n\nassert.throws = function(block, /*optional*/error, /*optional*/message) {\n  _throws.apply(this, [true].concat(pSlice.call(arguments)));\n};\n\n// EXTENSION! This is annoying to write outside this module.\nassert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {\n  _throws.apply(this, [false].concat(pSlice.call(arguments)));\n};\n\nassert.ifError = function(err) { if (err) {throw err;}};\n"
  },
  {
    "path": "src/test/benchmark.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"../edit_session\").EditSession;\n\nmodule.exports = {\n    setUp : function() {\n        this.start = Date.now();\n    },\n    \n    tearDown : function() {\n        console.log(\"took: \", Date.now() - this.start + \"ms\");\n    },\n    \n    \"test: document to screen position\": function() {\n        var s = new EditSession(Array(6000).join('someText\\n'));\n\n        for (var i=0; i<6000; i++)\n            s.documentToScreenPosition(i, 0);\n\n        for (var i=0; i<6000; i++)\n            s.documentToScreenPosition(i, 0);\n\n        console.log(s.$rowCache.length);\n    },\n    \n    \"test: screen to document position\": function() {\n        var s = new EditSession(Array(6000).join('someText\\n'));\n\n        for (var i=0; i<6000; i++)\n            s.screenToDocumentPosition(i, 0);\n\n        for (var i=0; i<6000; i++)\n            s.documentToScreenPosition(i, 0);\n\n        console.log(s.$rowCache.length);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/test/mockdom.js",
    "content": "\"use strict\";\n/*global Uint8ClampedArray*/\n\nvar dom = require(\"../lib/dom\");\n\nvar CHAR_HEIGHT = 10;\nvar CHAR_WIDTH = 6;\nvar WINDOW_HEIGHT = 768;\nvar WINDOW_WIDTH = 1024;\n\nfunction Style() {\n    \n}\nStyle.prototype.getPropertyValue = function() { return \"\"; };\nStyle.prototype.__defineGetter__(\"cssText\", function() {\n    var cssText = \"\";\n    Object.keys(this).forEach(function(key) {\n        if (this[key])\n            cssText += (cssText ? \" \" : \"\") +  key + \": \" + this[key] + \";\";\n    }, this);\n    return cssText;\n});\nStyle.prototype.__defineSetter__(\"cssText\", function(value) {\n    Object.keys(this).forEach(function(key) {\n        delete this[key];\n    }, this);\n    value.split(\";\").forEach(function(key) {\n        var parts = key.split(\":\");\n        if (parts.length == 2)\n            this[parts[0].trim()] = parts[1].trim();\n    }, this);\n});\n\nfunction ClassList(node) {\n    this.el = node;\n}\n(function() {\n    this.add = function(str) {\n       dom.addCssClass(this.el, str);\n    };\n    this.remove = function(str) {\n       dom.removeCssClass(this.el, str);\n    };\n    this.toggle = function(str) {\n       return dom.toggleCssClass(this.el, str);\n    };\n    this.contains = function(str) {\n       return dom.hasCssClass(this.el, str);\n    };\n}).call(ClassList.prototype);\n\n\nfunction Attr(name, value) {\n    this.name = name;\n    this.value = value;\n}\n(function() {\n    this.__defineGetter__(\"nodeValue\", function() {\n        return this.value;\n    });\n}).call(Attr.prototype);\n\nvar initializers = {\n    textarea: function() {\n        this.selectionStart = this.selectionEnd = 0;\n        this.setSelectionRange = function(start, end) {\n            this.selectionStart = Math.min(start, this.value.length, end);\n            this.selectionEnd = Math.min(end, this.value.length);\n        };\n        var value = \"\";\n        this.__defineGetter__(\"value\", function() {\n            return value;\n        });\n        this.__defineSetter__(\"value\", function(newValue) {\n            if (typeof newValue != \"string\") newValue = newValue.toString();\n            if (newValue != value) {\n                value = newValue;\n                this.selectionStart = this.selectionEnd = value.length;\n            }\n        });\n        this.oncut = this.oncopy = this.onpaste = null;\n        this.select = function() {\n            this.setSelectionRange(0, Infinity);\n        };\n    },\n    input: function() {\n        initializers.textarea.call(this);\n    },\n    style: function() {\n       this.sheet = {\n           insertRule: function() {},\n           cssRules: []\n       };\n    },\n    a: function() {\n        this.__defineGetter__(\"href\", function() {\n            return this.getAttribute(\"href\");\n        });\n        this.__defineSetter__(\"href\", function(v) {\n            return this.setAttribute(\"href\", v);\n        });\n    },\n    canvas: function() {\n        this.getContext = function (contextId, options) {\n            if (this._contextMock !== undefined) return this._contextMock;\n            return this._contextMock = new Context2d(this.width, this.height);\n        };\n    }\n};\n\nfunction Context2d(w, h) {\n    this.width = w;\n    this.height = h;\n    this.points = new Uint8ClampedArray(4 * this.width * this.height);\n    this.fillStyle = [0, 0, 0, 0];\n}\n(function() {\n    this.clearRect = function(x, y, w, h) {\n        var fillStyle = this.fillStyle;\n        this.fillStyle = [0, 0, 0, 0];\n        this.fillRect(x, y, w, h);\n        this.fillStyle = fillStyle;\n    };\n    this.fillRect = function(x, y, w, h) {\n        var fillStyle = this.fillStyle;\n        if (typeof fillStyle == \"string\")\n            fillStyle = this.fillStyle = this.$parseColor(this.fillStyle);\n        for (var i = x; i < w + x; i++) {\n            for (var j = y; j < h + y; j++) {\n                var index = (this.width * j + i) * 4;\n                for (var k = 0; k < 4; k++)\n                    this.points[index++] = fillStyle[k];\n            }\n        }\n    };\n    this.getImageData = function(sx, sy, sw, sh) {\n        var data = new Uint8ClampedArray(sw * sh * 4);\n        var newIndex = 0;\n        for (var i = sx; i < sw + sx; i++) {\n            for (var j = sy; j < sh + sy; j++) {\n                var index = (this.width * j + i) * 4;\n                for (var k = 0; k < 4; k++)\n                    data[newIndex++] = this.points[index++];\n            }\n        }\n        return {\n            data: data\n        };\n    };\n    this.$parseColor = function(str) {\n        var color = str.match(/\\(([^,)]+),([^,)]+),([^,)]+)(?:,([^,)]+))?/).slice(1);\n        color[3] = Math.round((color[3] ? parseFloat(color[3]) : 1) * 255);\n        for (var i = 0; i < 3; i++) {\n            color[i] = parseInt(color[i]);\n        }\n        return color;\n    };\n}).call(Context2d.prototype);\n\n\n\nfunction getItem(i) { return this[i]; }\n\nfunction Node(name) {\n    this.localName = name;\n    this.value = \"\";\n    this.childNodes = [];\n    this.children = [];\n    this.childNodes.item = getItem;\n    this.children.item = getItem;\n    this.ownerDocument = window.document || this;\n    this.$attributes = {};\n    this.style = new Style();\n    if (initializers.hasOwnProperty(name))\n        initializers[name].call(this);\n}\n(function() {\n    this.nodeType = 1;\n    this.ELEMENT_NODE = 1;\n    this.TEXT_NODE = 1;\n    this.cloneNode = function(recursive) {\n        var clone = new Node(this.localName);\n        for (var i in this.$attributes) {\n            clone.setAttribute(i, this.$attributes[i]);\n        }\n        if (recursive) {\n            this.childNodes.forEach(function(ch) {\n                clone.appendChild(ch.cloneNode(true));\n            }, this);\n        }\n        return clone;\n    };\n    this.appendChild = function(node) {\n        return this.insertBefore(node, null);\n    };\n    this.removeChild = function(node) {\n        var i = this.childNodes.indexOf(node);\n        if (i == -1)\n            throw new Error(\"not a child\");\n        if (node.previousSibling)\n            node.previousSibling.nextSibling = node.nextSibling;\n        if (node.nextSibling)\n            node.nextSibling.previousSibling = node.previousSibling;\n        node.parentNode = node.nextSibling = node.previousSibling = null;\n        this.childNodes.splice(i, 1);\n        if (!document.contains(document.activeElement))\n            document.activeElement = document.body;\n        i = this.children.indexOf(node);\n        if (i !== -1)\n            this.children.splice(i, 1);\n    };\n    this.remove = function() {\n        this.parentNode && this.parentNode.removeChild(this);\n    };\n    this.replaceChild = function(node, oldNode) {\n        this.insertBefore(node, oldNode);\n        this.removeChild(oldNode);\n        return oldNode;\n    };\n    this.insertBefore = function(node, before) {\n        if (node.parentNode)\n            node.parentNode.removeChild(node);\n        var i = this.childNodes.indexOf(before);\n        if (i == -1) i = this.childNodes.length + 1;\n        if (node.localName == \"#fragment\") {\n            var children = node.childNodes.slice();\n            for (var j = 0; j < children.length; j++)\n                this.insertBefore(children[j], before);\n        }\n        else {\n            this.childNodes.splice(i, 0, node);\n            node.nextSibling = this.childNodes[i];\n            node.previousSibling = this.childNodes[i - 2];\n            if (node.nextSibling)\n                node.nextSibling.previousSibling = node;\n            if (node.previousSibling)\n                node.previousSibling.nextSibling = node;\n            node.parentNode = this;\n            i = this.children.indexOf(before);\n            if (i == -1) i = this.children.length + 1;\n            this.children.splice(i, 0, node);\n        }\n        \n        return node;\n    };\n    this.before = function(node) {\n        if (this.parentNode) this.parentNode.insertBefore(node, this);\n    };\n    this.hasChildNodes = function() {\n        return this.childNodes.length > 0;\n    };\n    this.__defineGetter__(\"childElementCount\", function() {\n        return this.children.length;\n    });\n    this.hasAttribute = function(x) {\n        return this.$attributes.hasOwnProperty(x);\n    };\n    this.hasAttributes = function() {\n        return Object.keys(this.$attributes).length > 0;\n    };\n    this.querySelectorAll = function(selector) {\n        return querySelector(this, selector, true);\n    };\n    this.querySelector = function(selector) {\n        return querySelector(this, selector, false)[0];\n    };\n    function querySelector(node, selector, all) {\n        var parts = parseSelector(selector);\n        \n        var nodes = [];\n        walk(node, function(node) {\n            if (node.matches && node.matches(parts)) {\n                nodes.push(node);\n                if (!all) return true;\n            }\n        });\n        return nodes;\n    }\n    this.getElementsByTagName = function(s) {\n        var nodes = [];\n        walk(this, function(node) {\n            if (node.localName == s)\n                nodes.push(node);\n        });\n        return nodes;\n    };\n    this.matches = function(selector) {\n        var parts = parseSelector(selector);\n        var node = this;\n        var operator = parts.pop();\n        var tests = parts.pop();\n        while (node && node.nodeType != 9) {\n            if (!tests) return true;\n            var isAMatch = tests.every(function(t) {return t(node);});\n            if (!isAMatch) {\n                if (!operator || operator === \">\")\n                    return false;\n            } else {\n                operator = parts.pop();\n                tests = parts.pop();\n            }\n            node = node.parentNode;\n        }\n        return !tests;\n    };\n    this.closest = function(s) {\n        var el = this;\n        do {\n            if (el.matches(s)) return el;\n            el = el.parentElement || el.parentNode;\n        } while (el != null && el.nodeType === 1);\n        return null;\n    };\n    this.removeAttribute = function(a) {\n        delete this.$attributes[a];\n    };\n    this.setAttribute = function(a, v) {\n        this.$attributes[a] = v;\n    };\n    this.getAttribute = function(a, v) {\n        return String(this.$attributes[a] || \"\");\n    };\n    this.__defineGetter__(\"nodeName\", function() {\n        return this.localName;\n    });\n    this.__defineGetter__(\"tagName\", function() {\n        return this.localName;\n    });\n    this.__defineGetter__(\"attributes\", function() {\n        var style = this.style.cssText;\n        if (style)\n            this.$attributes.style = style;\n        var attributes = Object.keys(this.$attributes).map(function(key) {\n            return new Attr(key, this.$attributes[key]);\n        }, this);\n        attributes.item = getItem;\n        return attributes;\n    });\n    this.__defineGetter__(\"classList\", function() {\n        return this.$classList || (this.$classList = new ClassList(this));\n    });\n    this.__defineGetter__(\"className\", function() {\n        return this.$attributes.class || \"\";\n    });\n    this.__defineSetter__(\"className\", function(v) {\n        this.$attributes.class = v;\n    });\n    this.__defineGetter__(\"textContent\", function() {\n        var v = \"\";\n        walk(this, function(node) {\n            if (node instanceof TextNode)\n                v += node.data;\n        });\n        return v;\n    });\n    this.__defineSetter__(\"textContent\", function(v) {\n        removeAllChildren(this);\n        this.appendChild(new TextNode(v));\n    });\n    this.__defineGetter__(\"innerText\", function() {\n        if (!this.documentElement)\n            throw new Error(\"use textContent\");\n    });\n    this.__defineSetter__(\"innerText\", function(v) {\n        throw new Error(\"use textContent\");\n    });\n    \n    this.__defineGetter__(\"id\", function() {\n        return this.getAttribute(\"id\");\n    });\n    this.__defineSetter__(\"id\", function(v) {\n        this.setAttribute(\"id\", v);\n    });\n    this.__defineGetter__(\"parentElement\", function() {\n        return this.parentNode == document ? null : this.parentNode;\n    });\n    this.__defineGetter__(\"innerHTML\", function() {\n        return this.childNodes.map(function(ch) {\n            return \"outerHTML\" in ch ? ch.outerHTML : escapeHTML(ch.data);\n        }).join(\"\");\n    });\n    this.__defineGetter__(\"outerHTML\", function() {\n        var attributes = this.attributes.map(function(attr) {\n            return attr.name + \"=\" + JSON.stringify(attr.value + \"\");\n        }, this).join(\" \");\n        return \"<\" + this.localName + (attributes ? \" \" + attributes : \"\") + \">\" + this.innerHTML + \"</\" + this.localName + \">\";\n    });\n    this.__format = function(indent) {\n        if (!indent) indent = \"\";\n        var attributes = this.attributes.map(function(attr) {\n            return attr.name + \"=\" + JSON.stringify(attr.value);\n        }, this).join(\" \");\n        return indent + \"<\" + this.localName + (attributes ? \" \" + attributes : \"\") + \">\" + \n            this.childNodes.map(function(ch) {\n                return \"__format\" in ch ? \"\\n\" + ch.__format(indent + \"    \") : escapeHTML(ch.data);\n            }).join(\"\")\n            + \"\\n\" + indent + \"</\" + this.localName + \">\";\n    };\n    this.__defineSetter__(\"innerHTML\", function(v) {\n        removeAllChildren(this);\n        setInnerHTML(v, this);\n    });\n    this.insertAdjacentHTML = function(position, markup) {\n        var element = document.createDocumentFragment();\n        setInnerHTML(markup, element);\n        this.insertAdjacentElement(position, element);\n    };\n    this.insertAdjacentElement = function(position, element) {\n        position = position.toLowerCase();\n        if (position === \"beforeend\") this.appendChild(element);\n        if (position === \"afterend\") this.parentElement.insertBefore(element, this.nextSibling);\n        if (position === \"afterbegin\") this.insertBefore(element, this.firstChild);\n        if (position === \"beforebegin\") this.parentElement.insertBefore(element, this);\n    };\n    this.getBoundingClientRect = function(fromChild) {\n        var width = 0;\n        var height = 0;\n        var top = 0;\n        var left = 0;\n        if (this == document.documentElement) {\n            width = WINDOW_WIDTH;\n            height = WINDOW_HEIGHT;\n        }\n        else if (!document.contains(this) || this.style.display == \"none\") {\n            width = height = 0;\n        }\n        else if (this.style.width == \"auto\" || this.localName == \"span\" || /^inline/.test(this.style.display)) {\n            width = this.textContent.length * CHAR_WIDTH;\n            var node = this;\n            while (node) {\n                if (node.style.fontSize) {\n                    height = parseInt(node.style.fontSize);\n                    break;\n                }\n                node = node.parentNode;\n            }\n            if (!height) height = CHAR_HEIGHT;\n        }\n        else if (this.parentNode) {\n            var isFixed = this.style.position == \"fixed\" \n                || this.style.positionHint == \"fixed\"\n                || this.getAttribute(\"role\") == \"tooltip\";\n            // prevent recursion by passing -1\n            var rect = fromChild == -1 || isFixed\n                ? {top: 0, left: 0, width: 0, height: 0, right: 0, bottom: 0} \n                : this.parentNode.getBoundingClientRect();\n            if (isFixed) {\n                rect.height = rect.bottom = WINDOW_HEIGHT;\n                rect.width = rect.right = WINDOW_WIDTH;\n            }\n\n            left = parseCssLength(this.style.left || \"0\", rect.width);\n            top = parseCssLength(this.style.top || \"0\", rect.height);\n            var right = parseCssLength(this.style.right || \"0\", rect.width);\n            var bottom = parseCssLength(this.style.bottom || \"0\", rect.width);\n\n            if (this.style.width)\n                width = parseCssLength(this.style.width || \"100%\", rect.width);\n            else if (this.style.widthHint)\n                width = this.style.widthHint;\n            else\n                width = rect.width - right - left;\n            \n            if (this.style.height)\n                height = parseCssLength(this.style.height || \"100%\", rect.height);\n            else if (this.style.heightHint)\n                height = this.style.heightHint;\n            else\n                height = rect.height - top - bottom;\n\n            var maxWidth = this.style.maxWidth && parseCssLength(this.style.maxWidth, rect.width);\n            var maxHeight = this.style.maxHeight && parseCssLength(this.style.maxHeight, rect.height);\n            \n            if (maxWidth >= 0) width = Math.min(width, maxWidth);\n            if (maxHeight >= 0) height = Math.min(height, maxHeight);\n            \n            if (!height && !this.style.height && this.firstChild && this.firstChild.getBoundingClientRect && !fromChild) {\n                height = this.firstChild.getBoundingClientRect(-1).height;\n            }\n\n            if (!this.style.left &&  this.style.right) {\n                left = rect.width - right - width;\n            }\n            if (!this.style.top &&  this.style.bottom) {\n                top = rect.height - bottom - height;\n            }\n            \n            top += rect.top;\n            left += rect.left;\n        }\n        return {top: top, left: left, width: width, height: height, right: left + width, bottom: top + height};\n    };\n\n    function parseCssLength(styleString, parentSize) {\n        // TODO support calc\n        var size = parseFloat(styleString) || 0;\n        if (/%/.test(styleString))\n            size = parentSize * size / 100;\n        return size;\n    }\n\n    this.__defineGetter__(\"clientHeight\", function() {\n        return this.getBoundingClientRect().height;\n    });\n    this.__defineGetter__(\"clientWidth\", function() {\n        return this.getBoundingClientRect().width;\n    });\n    this.__defineGetter__(\"offsetHeight\", function() {\n        return this.getBoundingClientRect().height;\n    });\n    this.__defineGetter__(\"offsetWidth\", function() {\n        return this.getBoundingClientRect().width;\n    });\n\n    this.__defineGetter__(\"lastChild\", function() {\n        return this.childNodes[this.childNodes.length - 1];\n    });\n    this.__defineGetter__(\"firstChild\", function() {\n        return this.childNodes[0];\n    });\n    // TODO this is a waorkaround for scrollHeight usage in virtualRenderer\n    this.scrollHeight = 1;\n\n\n    this.addEventListener = function(name, listener, capturing) {\n        if (!listener) {\n            console.trace();\n            throw new Error(\"attempting to add empty listener\");\n        }\n        if (!this._events) this._events = {};\n        var id = capturing ? \"__c__:\" + name : name;\n        if (!this._events[id]) this._events[id] = [];\n        var i = this._events[id].indexOf(listener);\n        if (i == -1)\n            this._events[id].push(listener);\n    };\n    this.removeEventListener = function(name, listener, capturing) {\n        if (!this._events) return;\n        var id = capturing ? \"__c__:\" + name : name;\n        if (!this._events[id]) return;\n        var i = this._events[id].indexOf(listener);\n        if (i !== -1)\n            this._events[id].splice(i, 1);\n    };\n    this.createEvent = function(v) {\n        return new Event();\n    };\n    this.dispatchEvent = function(e) {\n        var parents = [];\n        var node = this.parentNode;\n        \n        while (node) {\n            parents.push(node);\n            node = node.parentNode;\n        }\n        parents.push(window);\n        \n        if (!e.target) e.target = this;\n        if (!e.timeStamp) e.timeStamp = Date.now();\n        \n        e.eventPhase = 1;\n        for (var i = parents.length - 1; i >= 0; i--) {\n            var node = parents[i];\n            if (call(node, true)) return;\n        }\n        e.eventPhase = 2;\n        if (call(this, true)) return;\n        if (call(this, false)) return;\n        e.eventPhase = 3;\n        for (var i = 0; i < parents.length; i++) {\n            var node = parents[i];\n            if (call(node, false)) return;\n        }\n        \n        function call(node, capturing) {\n            e.currentTarget = node;\n            if (!capturing && node[\"on\" + e.type])\n                node[\"on\" + e.type](e);\n            var id = capturing ? \"__c__:\" + e.type : e.type;\n            var events = node._events && node._events[id];\n            events && events.slice().forEach(function(listener) {\n                listener.call(node, e);\n            });\n            if (e.stopped) return true;\n            if (!capturing && !e.bubbles) return true;\n        }        \n    };\n    this.contains = function(node) {\n        while (node) {\n            if (node == this) return true;\n            node = node.parentNode;\n        }\n    };\n    this.focus = function() {\n        if (document.activeElement == this)\n            return;\n        var oldFocused = document.activeElement;\n        document.activeElement = this;\n        if (oldFocused)\n            oldFocused.dispatchEvent({type: \"blur\"});\n        this.dispatchEvent({type: \"focus\"});\n    };\n    this.blur = function() {\n        if (document.activeElement == this)\n            document.body.focus();\n    };\n    function removeAllChildren(node) {\n        node.childNodes.forEach(function(node) {\n            node.parentNode = null;\n        });\n        node.childNodes.length = 0;\n        if (!document.contains(document.activeElement))\n            document.activeElement = document.body;\n    }\n}).call(Node.prototype);\n\nfunction parseSelector(selector) {\n    if (Array.isArray(selector)) return selector.slice();\n    var parts = selector.split(/((?:[^\\s>\"[]|\"[^\"]+\"?|\\[[^\\]]*\\]?)+)/);\n    for (var i = 1; i < parts.length; i += 2) {\n        parts[i] = parseSimpleSelector(parts[i]);\n        if (/^ +$/.test(parts[i + 1])) parts[i + 1] = \" \";\n    }\n    return parts;\n}\nfunction parseSimpleSelector(selector) {\n    var tests = [];\n    selector.replace(\n        /([#.])?([\\w-]+)|\\[\\s*([\\w-]+)\\s*(?:=\\s*[\"']?([\\w-]+)[\"']?\\s*)?\\]|\\*|./g,\n        function(_, hash, name, attr, attrValue) {\n            if (hash == \"#\") {\n                tests.push(function(node) { return node.id == name; });\n            }\n            else if (hash == \".\") {\n                var re = new RegExp(\"(^|\\\\s)\" + name + \"($|\\\\s)\");\n                tests.push(function(node) { return re.test(node.className); });\n            }\n            else if (name) {\n                tests.push(function(node) { return node.localName == name; });\n            }\n            else if (attr) {\n                tests.push(attrValue != undefined ? function(node) {\n                    return node.getAttribute && node.getAttribute(attr) == attrValue;\n                } : function(node) {\n                    return node.hasAttribute && node.hasAttribute(attr);\n                });\n            }\n            else if (_ == \"*\") {\n                tests.push(function(node) {\n                    return true;\n                });\n            }\n            else {\n                throw new Error(\"Error parsing selector \" + selector + \"|\" + _);\n            }\n        }\n    );\n    return tests;\n}\n\nfunction setInnerHTML(markup, parent, strict) {\n    var root = parent;\n    var tagRe = /<(\\/?[\\w:\\-]+|!)|&(?:(#?\\w+);)|$/g;\n    var skipped = \"\";\n\n    for (var m, lastIndex = 0; m = tagRe.exec(markup);) {\n        skipped += markup.substring(lastIndex, m.index);\n        var encoded = m[2];\n        if (encoded) {\n            skipped += parseCharacterEntity(encoded);\n            lastIndex = tagRe.lastIndex;\n        } else {\n            if (m[1] == \"!\") {\n                skipped += parseDocType(markup, tagRe, strict);\n                lastIndex = tagRe.lastIndex;\n                continue;\n            }\n            if (skipped) {\n                root.appendChild(document.createTextNode(skipped));\n                skipped = \"\";\n            }\n            var end = markup.indexOf(\">\", tagRe.lastIndex);\n            var selfClosing = markup[end - 1] === \"/\" ? 1 : 0;\n            var attributes = markup.slice(tagRe.lastIndex, end - selfClosing).trim();\n            \n            tagRe.lastIndex = lastIndex = end < 0 ? markup.length : end + 1;\n        \n            if (!m[1]) {\n                if (strict && root != parent)\n                    throw new Error(\"Invalid XML message:\");\n                return;\n            }\n            if (m[1][0] !== \"/\") {\n                var tagName = m[1];\n                if (/:/.test(tagName)) {\n                    var i = tagName.indexOf(\":\");\n                    var prefix = tagName.slice(0, i);\n                    tagName = tagName.slice(i+1);\n                    root = root.appendChild(document.createElement(tagName));\n                    root.prefix = prefix;\n                } else {\n                    root = root.appendChild(document.createElement(tagName));\n                }\n                attributes && attributes.replace(/([\\w:-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|(\\w+))/g, function(_, key, v1,v2,v3) {\n                    root.setAttribute(key, v1 || v2 || v3 || key);\n                });\n            } \n            if (m[1][0] === \"/\" || selfClosing) {\n                if (root != parent)\n                    root = root.parentNode;\n            }\n        }\n    }\n    if (strict && root != parent)\n        throw new Error(\"Invalid XML message:\");\n}\nfunction parseCharacterEntity(encoded) {\n    if (encoded[0] == \"#\") {\n        var charCode = encoded.slice(1);\n        if (charCode[0] == \"x\")\n            return String.fromCharCode(parseInt(charCode.slice(1), 16));\n        return String.fromCharCode(parseInt(charCode, 10));\n    }\n    if (encoded == \"gt\") return \">\";\n    if (encoded == \"lt\") return \"<\";\n    if (encoded == \"amp\") return \"&\";\n    if (encoded == \"quot\") return '\"';\n    \n    console.error(\"Skipping unsupported character entity\", encoded);\n    return \"\";\n}\nfunction parseDocType(markup, tagRe, strict) {\n    var start = tagRe.lastIndex;\n    var end = -1;\n    var text = \"\";\n    if (markup[start] == \"-\" && markup[start + 1] == \"-\") {\n        end = markup.indexOf(\"-->\", start + 2);\n        if (end != -1) end += 3;\n    } else if (strict && markup.substr(start, 7) == \"[CDATA[\") {\n        end = markup.indexOf(\"]]>\", start);\n        text = markup.slice(start + 7, end);\n        end += 3;\n    } else {\n        end = markup.indexOf(\">\", start);\n        if (end != -1) end += 1;\n    }\n    if (end == -1) end = markup.length;\n    tagRe.lastIndex = end;\n    return text;\n}\nfunction escapeHTML(str) {\n    return str.replace(/[<>&]/g, function(char) {\n        if (char == \"<\") return \"&lt;\";\n        if (char == \">\") return \"&gt;\";\n        if (char == \"&\") return \"&amp;\";\n    });\n}\n\nfunction Event(type, options) {\n    this.type = type;\n    Object.assign(this, options);\n}\n(function() {\n    this.initMouseEvent = function(\n        type, _1, _2, window,\n        detail, x, y, _x, _y,\n        ctrl, alt, shift, meta,\n        button, relatedTarget\n    ) {\n        this.bubbles = true;\n        this.type = type;\n        this.detail = detail || 0;\n        this.clientX = x;\n        this.clientY = y;\n        this.button = button;\n        this.relatedTarget = relatedTarget;\n        this.ctrlKey = ctrl;\n        this.altKey = alt;\n        this.shiftKey = shift;\n        this.metaKey = meta;\n        this.which = button + 1;\n    };\n    this.preventDefault = function() {\n        this.defaultPrevented = true;\n    };\n    this.stopPropagation = function() {\n        this.stopped = true;\n    };\n}).call(Event.prototype);\n\nfunction walk(node, fn) {\n    var children = node.childNodes || [];\n    for (var i = 0; i < children.length; i++) {\n        var result = fn(children[i]) || walk(children[i], fn);\n        if (result)\n            return result;\n    }\n}\n\nfunction TextNode(value) {\n    this.data = value || \"\";\n}\n(function() {\n    this.nodeType = 3;\n    this.ELEMENT_NODE = 1;\n    this.TEXT_NODE = 1;\n    this.cloneNode = function() {\n        return new TextNode(this.data);\n    };\n    this.__defineGetter__(\"nodeValue\", function() {\n        return this.data;\n    });\n    this.__defineGetter__(\"textContent\", function() {\n        return this.data;\n    });\n}).call(TextNode.prototype);\n\nvar window = {\n    get innerHeight() {\n        return WINDOW_HEIGHT;\n    },\n    get innerWidth() {\n        return WINDOW_WIDTH;\n    }\n};\nwindow.navigator = {userAgent: \"node\", platform: \"win\", appName: \"\"};\nwindow.HTMLDocument = window.XMLDocument = window.Document = function() {\n    var document = this;\n    if (!window.document) window.document = document;\n    Node.call(this, \"#document\");\n    this.nodeType = 9;\n    document.navigator = window.navigator;\n    document.styleSheets = [];\n    document.createElementNS = function(ns, t) {\n        return new Node(t);\n    };\n    document.createElement = function(t) {\n        return new Node(t);\n    };\n    document.createComment =\n    document.createTextNode = function(v) {\n        return new TextNode(v);\n    };\n    document.createDocumentFragment = function() {\n        return new Node(\"#fragment\");\n    };\n    document.hasFocus = function() {\n        return true;\n    };\n    document.execCommand = function() {};\n    document.documentElement = document.appendChild(new Node(\"html\"));\n    document.body = new Node(\"body\");\n    document.activeElement = document.body;\n    document.head = new Node(\"head\");\n    document.documentElement.appendChild(document.head);\n    document.documentElement.appendChild(document.body);\n    return document;\n};\nwindow.Document.prototype = Object.create(Node.prototype);\n(function() {\n    this.getElementById = function(s) {\n        return walk(this, function(node) {\n            if (node.getAttribute && node.getAttribute(\"id\") == s)\n                return node;\n        });\n    };\n}.call(window.Document.prototype));\n\nwindow.DOMParser = function() {\n    this.parseFromString = function(str, mode) {\n        var document = new window.Document({});\n        if (mode == \"text/xml\" || mode == \"application/xml\") {\n            var markup = str.replace(/<\\?([^?]|\\?[^>])+\\?>/g, \"\").trim();\n            document.innerHTML = \"\";\n            setInnerHTML(markup, document, true);\n            document.documentElement = document.firstChild;\n        } else {\n            document.body.innerHTML = str;\n        }\n        return document;\n    };\n};\n\nvar document = new window.Document();\nwindow.__defineGetter__(\"document\", function() {return document;});\nwindow.document.defaultView = window;\n\nwindow.setTimeout = setTimeout;\nwindow.clearTimeout = clearTimeout;\nwindow.getComputedStyle = function(node) {\n    return node.style;\n};\nwindow.addEventListener = document.addEventListener.bind(window);\nwindow.removeEventListener = document.removeEventListener.bind(window);\nwindow.dispatchEvent = document.dispatchEvent.bind(window);\nwindow.name = \"nodejs\";\nwindow.focus = function() {};\n\nwindow.Node = window.Element = Node;\nwindow.Text = window.TextNode = TextNode;\nwindow.Attr = Attr;\nwindow.window = window;\nwindow.CustomEvent = window.Event = window.KeyboardEvent = Event;\nwindow.requestAnimationFrame = function(callback) {\n    return setTimeout(function() {\n        callback();\n    });\n};\n\n/*global Buffer*/\nif (typeof Buffer != \"undefined\") {\n    window.btoa = function(str) {\n        return Buffer.from(str.toString(), \"binary\").toString(\"base64\");\n    };\n    window.atob = function(str) {\n        return Buffer.from(str, \"base64\").toString(\"binary\");\n    };\n}\n\nvar originalProperties = {};\nvar overriddenValues = {};\nvar loaded = false;\nvar overridableProperties = [\"setTimeout\", \"clearTimeout\", \"getComputedStyle\"];\nexports.load = function() {\n    if (loaded || typeof global == \"undefined\") return;\n    window.window = global;\n    Object.keys(window).forEach(function(i) {\n        var desc = Object.getOwnPropertyDescriptor(global, i);\n        originalProperties[i] = desc;\n        global.__defineGetter__(i, function() {\n            return overriddenValues[i] || window[i];\n        });\n        global.__defineSetter__(i, function(value) {\n            if (!overridableProperties.includes(i)) {\n                console.log(\"attempt to set \" + i);\n            } else if (value === window[i]) {\n                delete overriddenValues[i];\n                if (!loaded) {\n                    unloadProperty(i);\n                }\n            } else {\n                overriddenValues[i] = value;\n            }\n        });\n    });\n    loaded = true;\n};\n\nexports.loadInBrowser = function(global, $setSize) {\n    if ($setSize) {\n        WINDOW_HEIGHT = global.innerHeight;\n        WINDOW_WIDTH = global.innerWidth;\n    }\n    delete global.ResizeObserver;\n    global.__origRoot__ = global.document.documentElement;\n    global.__origBody__ = global.document.body;\n    Object.keys(window).forEach(function(i) {\n        if (i != \"document\" && i != \"window\") {\n            delete global[i];\n            global[i] = window[i];\n        }\n    });\n    for (var i in window.document) {\n        var val = window.document[i];\n        if (typeof val == \"function\") {\n            if (i == \"createElement\") {\n                global.document.createElementOrig = global.document.createElement;\n                val = function(n) {\n                    if (n == \"script\")\n                        return global.document.createElementOrig(n);\n                    return window.document.createElement(n);\n                };\n            }\n            val = val.bind(window.document);\n            Object.defineProperty(\n                global.document, \n                i, \n                {\n                    value: val,\n                    enumerable: true,\n                    configurable: true\n                }\n            );\n        } else {\n            Object.defineProperty(\n                global.document, \n                i, \n                {\n                    get: function(name) {\n                        return window.document[name];\n                    }.bind(null, i),\n                    enumerable: true,\n                    configurable: true\n                }\n            );\n        }\n    }\n    loaded = true;\n};\n\nfunction unloadProperty(name) {\n    if (global[name] === window[name]) {\n        delete global[name];\n        if (originalProperties[name]) {\n            Object.defineProperty(global, name, originalProperties[name]);\n            delete originalProperties[name];\n        }\n    }\n}\n\nexports.unload = function() {\n    if (typeof global == \"undefined\") return;\n    var req = require;\n    var cache = req(\"module\")._cache;\n    delete cache[__filename];\n    Object.keys(originalProperties).forEach(function(name) {\n        unloadProperty(name);\n    });\n    loaded = false;\n};\n\nexports.load();\n"
  },
  {
    "path": "src/test/mockdom_test.js",
    "content": "/*global CustomEvent*/\n\nif (typeof process !== \"undefined\") {\n    require(\"./mockdom\");\n}\n\n\"use strict\";\n\nvar assert = require(\"./assertions\");\n\nmodule.exports = {\n    \"test: selectors\": function() {\n        document.body.innerHTML = `<div x=1 y='2'>\n            <span z=dd>span1</span>\n            xxx\n            <span class=x>some text </span>\n            <a x=3></a>\n        </div>`;\n        var spans = document.querySelectorAll(\"span\");\n        assert.equal(spans[0].matches(\"[z=dd]\"), true);\n        assert.equal(spans[0].matches(\"[z=dde]\"), false);\n        assert.equal(spans[1].matches(\"div>[class=x]\"), true);\n        assert.equal(spans[1].matches(\"body>[class=x]\"), false);\n        assert.equal(spans[0].matches(\"body [z=dd]\"), true);\n        \n        assert.equal(document.querySelectorAll(\"body     [x]\").length, 2);\n        assert.equal(document.querySelectorAll(\"html *>  [x]\").length, 2);\n        assert.equal(document.querySelectorAll(\"html * * [x]\").length, 1);\n        assert.equal(document.querySelectorAll(\" * * * * [x]\").length, 0);\n\n    },\n    \"test: getBoundingClientRect\" : function() {\n        var span = document.createElement(\"span\");\n        span.textContent = \"x\";\n        \n        assert.equal(span.offsetWidth, 0);\n        assert.equal(span.offsetHeight, 0);\n        \n        document.body.appendChild(span);\n        \n        var w = span.offsetWidth;\n        var h = span.offsetHeight;\n        \n        assert.ok(h != 0);\n        assert.ok(w != 0);\n        \n        span.textContent = \"xxx\";\n        assert.equal(span.offsetWidth, w * 3);\n        assert.equal(span.offsetHeight, h);\n        \n        var div = document.createElement(\"div\");\n        document.body.appendChild(div);\n        div.style.position = \"absolute\";\n        div.style.top = \"20px\";\n        div.style.left = \"40px\";\n        div.style.bottom = \"20px\";\n        div.style.right = \"12%\";\n        var rect = div.getBoundingClientRect();\n        var parentWidth = div.parentElement.clientWidth;\n        assert.ok(parentWidth != 0);\n        assert.equal(rect.top, 20);\n        assert.equal(rect.left, 40);\n        assert.equal(rect.width, parentWidth * (1 - 0.12) - 40);\n        assert.equal(rect.height, window.innerHeight - 40);\n        assert.equal(rect.right, parentWidth * (1 - 0.12));\n        assert.equal(rect.bottom, window.innerHeight - 20);\n        \n        div.style.width = \"40px\";\n        rect = div.getBoundingClientRect();\n        assert.equal(rect.width, 40);\n        assert.equal(rect.right, 80);\n        \n        div.style.height = \"150%\";\n        rect = div.getBoundingClientRect();\n        assert.equal(rect.height, window.innerHeight * 1.5);\n    },\n    \n   \"test: eventListener\" : function() {\n        var div = document.createElement(\"div\");\n        document.body.appendChild(div);\n        \n        var windowMousedown = 0;\n        window.addEventListener(\"mousedown\", function onWindowMousedown() {\n            windowMousedown++;\n            window.removeEventListener(\"mousedown\", onWindowMousedown);\n        });\n        \n        var divMousedown = 0;\n        div.addEventListener(\"mousedown\", function() {\n            divMousedown++;\n        });\n        \n        div.dispatchEvent(new CustomEvent(\"mousedown\"));\n        assert.equal(divMousedown, 1);\n        assert.equal(windowMousedown, 0);\n        \n        var event = new CustomEvent(\"mousedown\", {bubbles: true});\n        div.dispatchEvent(event);\n        assert.equal(divMousedown, 2);\n        assert.equal(windowMousedown, 1);\n        \n        var event = new CustomEvent(\"mousedown\", {bubbles: true});\n        div.dispatchEvent(event);\n        assert.equal(divMousedown, 3);\n        assert.equal(windowMousedown, 1);\n    }\n};\n\n\nrequire(\"../test/run\")(module);"
  },
  {
    "path": "src/test/mockrenderer.js",
    "content": "\"use strict\";\n\nvar MockRenderer = exports.MockRenderer = function(visibleRowCount) {\n    if (typeof document == \"object\") {\n        this.container = document.createElement(\"div\");\n        this.scroller = document.createElement(\"div\");\n        this.$gutter = document.createElement(\"div\");\n    }\n    this.visibleRowCount = visibleRowCount || 20;\n\n    this.layerConfig = {\n        firstVisibleRow : 0,\n        lastVisibleRow : this.visibleRowCount\n    };\n\n    this.isMockRenderer = true;\n};\n\n\nMockRenderer.prototype.getFirstVisibleRow = function() {\n    return this.layerConfig.firstVisibleRow;\n};\n\nMockRenderer.prototype.getLastVisibleRow = function() {\n    return this.layerConfig.lastVisibleRow;\n};\n\nMockRenderer.prototype.getFirstFullyVisibleRow = function() {\n    return this.layerConfig.firstVisibleRow;\n};\n\nMockRenderer.prototype.getLastFullyVisibleRow = function() {\n    return this.layerConfig.lastVisibleRow;\n};\n\nMockRenderer.prototype.getContainerElement = function() {\n    return this.container;\n};\n\nMockRenderer.prototype.getMouseEventTarget = function() {\n    return this.container;\n};\n\nMockRenderer.prototype.getTextAreaContainer = function() {\n    return this.container;\n};\n\nMockRenderer.prototype.addGutterDecoration = function() {\n};\n\nMockRenderer.prototype.removeGutterDecoration = function() {\n};\n\nMockRenderer.prototype.moveTextAreaToCursor = function() {\n};\n\nMockRenderer.prototype.setSession = function(session) {\n    this.session = session;\n};\n\nMockRenderer.prototype.getSession = function(session) {\n    return this.session;\n};\n\nMockRenderer.prototype.setTokenizer = function() {\n};\n\nMockRenderer.prototype.on = function() {\n};\n\nMockRenderer.prototype.updateCursor = function() {\n};\n\nMockRenderer.prototype.animateScrolling = function(fromValue, callback) {\n    callback && callback();\n};\n\nMockRenderer.prototype.scrollToX = function(scrollTop) {};\nMockRenderer.prototype.scrollToY = function(scrollLeft) {};\n\nMockRenderer.prototype.scrollToLine = function(line, center) {\n    var lineHeight = 16;\n    var row = 0;\n    for (var l = 1; l < line; l++) {\n        row += this.session.getRowLength(l-1);\n    }\n\n    if (center) {\n        row -= this.visibleRowCount / 2;\n    }\n    this.scrollToRow(row);\n};\n\nMockRenderer.prototype.scrollSelectionIntoView = function() {\n};\n\nMockRenderer.prototype.scrollCursorIntoView = function() {\n    var cursor = this.session.getSelection().getCursor();\n    if (cursor.row < this.layerConfig.firstVisibleRow) {\n        this.scrollToRow(cursor.row);\n    }\n    else if (cursor.row > this.layerConfig.lastVisibleRow) {\n        this.scrollToRow(cursor.row);\n    }\n};\n\nMockRenderer.prototype.scrollToRow = function(row) {\n    var row = Math.min(this.session.getLength() - this.visibleRowCount, Math.max(0,\n                                                                          row));\n    this.layerConfig.firstVisibleRow = row;\n    this.layerConfig.lastVisibleRow = row + this.visibleRowCount;\n};\n\nMockRenderer.prototype.getScrollTopRow = function() {\n  return this.layerConfig.firstVisibleRow;\n};\n\nMockRenderer.prototype.draw = function() {\n};\n\nMockRenderer.prototype.onChangeTabSize = function(startRow, endRow) {\n};\n\nMockRenderer.prototype.updateLines = function(startRow, endRow) {\n};\n\nMockRenderer.prototype.updateBackMarkers = function() {\n};\n\nMockRenderer.prototype.updateFrontMarkers = function() {\n};\n\nMockRenderer.prototype.updateBreakpoints = function() {\n};\n\nMockRenderer.prototype.onResize = function() {\n};\n\nMockRenderer.prototype.updateFull = function() {\n};\n\nMockRenderer.prototype.updateText = function() {\n};\n\nMockRenderer.prototype.showCursor = function() {\n};\n\nMockRenderer.prototype.visualizeFocus = function() {\n};\n\nMockRenderer.prototype.setAnnotations = function() {\n};\n\nMockRenderer.prototype.setStyle = function() {\n};\n\nMockRenderer.prototype.unsetStyle = function() {\n};\n\nMockRenderer.prototype.textToScreenCoordinates = function() {\n    return {\n        pageX: 0,\n        pageY: 0\n    };\n};\n\nMockRenderer.prototype.screenToTextCoordinates = function() {\n    return {\n        row: 0,\n        column: 0\n    };\n};\n\nMockRenderer.prototype.adjustWrapLimit = function () {\n\n};\n\nMockRenderer.prototype.getHighlightIndentGuides = function() {\n};\n\nMockRenderer.prototype.setHighlightIndentGuides = function() {\n};\n"
  },
  {
    "path": "src/test/run.js",
    "content": "\n\nmodule.exports = function(testModule) {\n    if (testModule === require.main) {\n        require(\"asyncjs\").test.testcase(testModule.exports).exec();\n    }\n    else if (typeof global == \"object\" && global.describe && (global.it || global.test)) {\n        if (!global.it) global.it = global.test;\n        global.describe(\"# file: \" + testModule.id, function() {\n            for (let i in testModule.exports) {\n                if (/^test/.test(i)) {\n                    let fn = testModule.exports[i];\n                    if (fn.length > 0) {\n                        global.it(i, async function() {\n                            var done;\n                            var p = new Promise(function(resolve) {\n                                done = resolve;\n                            });\n                            await fn.call(testModule.exports, done);\n                            return p;\n                        });\n                    } else {\n                        global.it(i, testModule.exports[i].bind(testModule.exports));\n                    }\n                } if (/^!test/.test(i)) {\n                    global.it.skip(i, testModule.exports[i].bind(testModule.exports));\n                } else if (i == \"setUp\") {\n                    global.beforeEach(testModule.exports[i].bind(testModule.exports));\n                } else if (i == \"tearDown\") {\n                    global.afterEach(testModule.exports[i].bind(testModule.exports));\n                } else if (i == \"setUpSuite\") {\n                    global.before(testModule.exports[i].bind(testModule.exports));\n                } else if (i == \"tearDownSuite\") {\n                    global.after(testModule.exports[i].bind(testModule.exports));\n                }\n            }\n        });\n    }\n};"
  },
  {
    "path": "src/test/test_list.js",
    "content": "module.exports = [\n    \"ace/ace_test\",\n    \"ace/anchor_test\",\n    \"ace/autocomplete/inline_test\",\n    \"ace/autocomplete/popup_test\",\n    \"ace/autocomplete_test\",\n    \"ace/background_tokenizer_test\",\n    \"ace/commands/command_manager_test\",\n    \"ace/config_test\",\n    \"ace/document_test\",\n    \"ace/edit_session_test\",\n    \"ace/editor_change_document_test\",\n    \"ace/editor_commands_test\",\n    \"ace/editor_highlight_selected_word_test\",\n    \"ace/editor_navigation_test\",\n    \"ace/editor_options_test\",\n    \"ace/editor_text_edit_test\",\n    \"ace/ext/beautify_test\",\n    \"ace/ext/code_lens_test\",\n    \"ace/ext/command_bar_test\",\n    \"ace/ext/diff/diff_test\",\n    \"ace/ext/diff_test\",\n    \"ace/ext/emmet_test\",\n    \"ace/ext/error_marker_test\",\n    \"ace/ext/hardwrap_test\",\n    \"ace/ext/inline_autocomplete_test\",\n    \"ace/ext/simple_tokenizer_test\",\n    \"ace/ext/static_highlight_test\",\n    \"ace/ext/whitespace_test\",\n    \"ace/ext/whitespaces_in_selection_test\",\n    \"ace/incremental_search_test\",\n    \"ace/keyboard/emacs_test\",\n    \"ace/keyboard/gutter_handler_test\",\n    \"ace/keyboard/keybinding_test\",\n    \"ace/keyboard/sublime_test\",\n    \"ace/keyboard/textinput_test\",\n    \"ace/keyboard/vim_ace_test\",\n    \"ace/keyboard/vim_test\",\n    \"ace/layer/gutter_test\",\n    \"ace/layer/text_markers_test\",\n    \"ace/layer/text_test\",\n    \"ace/lib/event_emitter_test\",\n    \"ace/marker_group_test\",\n    \"ace/mode/_test/highlight_rules_test\",\n    \"ace/mode/ada_test\",\n    \"ace/mode/behaviour/behaviour_test\",\n    \"ace/mode/coldfusion_test\",\n    \"ace/mode/css_test\",\n    \"ace/mode/folding/basic_test\",\n    \"ace/mode/folding/coffee_test\",\n    \"ace/mode/folding/cstyle_test\",\n    \"ace/mode/folding/drools_test\",\n    \"ace/mode/folding/fold_mode_test\",\n    \"ace/mode/folding/html_test\",\n    \"ace/mode/folding/javascript_test\",\n    \"ace/mode/folding/latex_test\",\n    \"ace/mode/folding/lua_test\",\n    \"ace/mode/folding/nunjucks_test\",\n    \"ace/mode/folding/php_test\",\n    \"ace/mode/folding/pythonic_test\",\n    \"ace/mode/folding/ruby_test\",\n    \"ace/mode/folding/vbscript_test\",\n    \"ace/mode/folding/xml_test\",\n    \"ace/mode/folding/yaml_test\",\n    \"ace/mode/html_test\",\n    \"ace/mode/javascript_test\",\n    \"ace/mode/logiql_test\",\n    \"ace/mode/odin_test\",\n    \"ace/mode/php_test\",\n    \"ace/mode/plain_text_test\",\n    \"ace/mode/python_test\",\n    \"ace/mode/ruby_test\",\n    \"ace/mode/text_test\",\n    \"ace/mode/vbscript_test\",\n    \"ace/mode/xml_test\",\n    \"ace/mouse/default_gutter_handler_test\",\n    \"ace/mouse/mouse_handler_test\",\n    \"ace/multi_select_test\",\n    \"ace/occur_test\",\n    \"ace/placeholder_test\",\n    \"ace/range_list_test\",\n    \"ace/range_test\",\n    \"ace/scrollbar_test\",\n    \"ace/search_test\",\n    \"ace/selection_test\",\n    \"ace/snippets_test\",\n    \"ace/test/mockdom_test\",\n    \"ace/token_iterator_test\",\n    \"ace/tokenizer_test\",\n    \"ace/tooltip_test\",\n    \"ace/undomanager_test\",\n    \"ace/virtual_renderer_test\"\n];"
  },
  {
    "path": "src/test/tests.html",
    "content": "\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Ace Unit Tests</title>\n  <style type=\"text/css\" media=\"screen\">\n\n    #log .passed {\n        color: green;\n    }\n    \n    #log .failed {\n        color: red;\n    }\n    \n    #log pre.error {\n        color: black;\n    }\n    #log  .skipped {\n        color: lightblue;\n    }\n    #sidebar {\n        height: calc(100vh - 30px);\n        overflow: auto;\n        position: absolute;\n        right: 10px;\n        top: 10px\n    }\n\n    #log {\n        height: calc(100vh - 30px);\n        overflow: auto;\n        position: absolute;\n        left:10px;\n\n        right:30em;\n        top:10px;\n    }\n    body {\n        overflow: scroll;\n    }\n  </style>\n</head>\n<body>\n    \n<div id=\"log\"></div>\n\n<script src=\"../../demo/kitchen-sink/require.js\" ></script>\n<script type=\"text/javascript\">\n    require.config({\n        paths: {\n            ace: new URL(\"../\", location).toString()\n        },\n        packages : [{\n            name: \"assert\",\n            location: \"./asyncjs\",\n            main: \"assert\"\n        }]\n    });\n    define(\"asyncjs\", {})\n    require([\"ace/test/all_browser\"])\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "src/test/update_test_list.js",
    "content": "#!/usr/bin/env node\nvar { execSync } = require(\"child_process\");\nvar fs = require(\"fs\");\n \n// Run the git command to list files\nvar stdout = execSync(\"git ls-tree -r HEAD --name-only\", { cwd: __dirname + \"/../../\" }).toString();\n\n// Filter the list for files matching /src.*_test.js/\nvar testFiles = stdout\n    .split(\"\\n\")\n    .filter(file => /src.*_test\\.js$/.test(file))\n    .map(file => file.replace(/^src\\//, \"ace/\").replace(/.js$/, \"\"));\n\nif (testFiles.length === 0) {\n    console.log(\"No matching test files found.\");\n    process.exit(1);\n}\n\nvar testListFilePath = __dirname + \"/test_list.js\";\nvar data = `module.exports = [\\n    \"${testFiles.join('\",\\n    \"')}\"\\n];`;\n\n// Write the updated content back to the file\nfs.writeFileSync(testListFilePath, data, \"utf8\");\nconsole.log(`Updated testNames array in ${testListFilePath} successfully.`);\n"
  },
  {
    "path": "src/test/user.js",
    "content": "\"use strict\";\n\n/* global window, KeyboardEvent */\n\nvar keyCodeToKey = {};\nvar keyCodeToCode = {};\n\nvar alias = {};\nalias.Ctrl = \"Control\";\nalias.Option = \"Alt\";\nalias.Cmd = alias.Super = alias.Meta = \"Command\";\n\nvar controlKeys = {\n    Shift: 16, Control: 17, Alt: 18, Meta: 224, Command: 224,\n    Backspace:8, Tab:9, Return: 13, Enter: 13,\n    Pause: 19, Escape: 27, PageUp: 33, PageDown: 34, End: 35, Home: 36,\n    Left: 37, Up: 38, Right: 39, Down: 40, Insert: 45, Delete: 46,\n    ArrowLeft: 37, ArrowUp: 38, ArrowRight: 39, ArrowDown: 40\n};\n\nvar shiftedKeys = {};\nvar printableKeys = {};\nvar specialKeys = {\n    Backquote: [192, \"`\", \"~\"], Minus: [189, \"-\", \"_\"], Equal: [187, \"=\", \"+\"],\n    BracketLeft: [219, \"[\", \"{\"], Backslash: [220, \"\\\\\", \"|\"], BracketRight: [221, \"]\", \"}\"],\n    Semicolon: [186, \";\", \":\"], Quote: [222, \"'\", '\"'], Comma: [188, \",\", \"<\"],\n    Period: [190, \".\", \">\"], Slash: [191, \"/\", \"?\"], Space: [32, \" \"], NumpadAdd: [107, \"+\"],\n    NumpadDecimal: [110, \".\"], NumpadSubtract: [109, \"-\"], NumpadDivide: [111, \"/\"], NumpadMultiply: [106, \"*\"]\n};\nfor (var i in specialKeys) {\n    var key = specialKeys[i];\n    printableKeys[i] = printableKeys[key[1]] = shiftedKeys[key[2]] = key[0];\n    keyCodeToCode[key[0]] = i;\n}\nfor (var i = 0; i < 10; i++) {\n    printableKeys[i] = shiftedKeys[\"!@#$%^&*()\"[i]] = 48 + i;\n    keyCodeToCode[48 + i] = \"Digit\" + i;\n}\nfor (var i = 65; i < 91; i++) {\n    var chr = String.fromCharCode(i + 32);\n    printableKeys[chr] = shiftedKeys[chr.toUpperCase()] = i;\n    keyCodeToCode[i] = \"Key\" + chr.toUpperCase();\n}\nfor (var i = 1; i < 13; i++) {\n    controlKeys[\"F\" + i] = 111 + i;\n}\n\nfor (var i in controlKeys) {\n    keyCodeToKey[controlKeys[i]] = i;\n    keyCodeToCode[controlKeys[i]] = i;\n}\ncontrolKeys[\"\\n\"] = controlKeys.Return;\n\nvar shift = false;\nvar ctrl = false;\nvar meta = false;\nvar alt = false;\nfunction reset() {\n    shift = ctrl = meta = alt = false;\n}\nfunction updateModifierStates(keyCode) {\n    if (keyCode == controlKeys.Shift)\n        return shift = true;\n    if (keyCode == controlKeys.Control)\n        return ctrl = true;\n    if (keyCode == controlKeys.Meta)\n        return meta = true;\n    if (keyCode == controlKeys.Alt)\n        return alt = true;\n}\n\nfunction sendKey(letter, timeout) {\n    var keyCode = controlKeys[letter] || printableKeys[letter] || shiftedKeys[letter];\n    var isModifier = updateModifierStates(keyCode);\n            \n    var text = letter;\n    if (ctrl || alt || meta || controlKeys[letter]) {\n        text = \"\";\n    }\n    else if (shift) {\n        text = text.toUpperCase();\n    }\n\n    var target = document.activeElement;\n    var prevented = emit(\"keydown\", true);\n    if (isModifier) return;\n    if (text) emit(\"keypress\", true);\n    if (!prevented) updateTextInput();\n    // if (timeout != undefined) await wait(timeout)\n    emit(\"keyup\", true);\n            \n    function emit(type, bubbles) {\n        var data = {bubbles: bubbles, cancelable:true};\n        data.charCode = text.charCodeAt(0);\n        data.keyCode = type == \"keypress\" ? data.charCode : keyCode;\n        data.which = data.keyCode;\n        data.shiftKey = shift || shiftedKeys[text];\n        data.ctrlKey = ctrl;\n        data.altKey = alt;\n        data.metaKey = meta;\n        data.key = text || keyCodeToKey[keyCode];\n        data.code = keyCodeToCode[keyCode];\n        var event = new KeyboardEvent(type, data);\n        \n        var el = document.activeElement;\n        el.dispatchEvent(event);\n        return event.defaultPrevented;\n    }\n    \n    function updateTextInput() {\n        var el = target;\n        var isTextarea = \"selectionStart\" in el && typeof el.value == \"string\";\n        var isContentEditable = /text|true/.test(el.contentEditable);\n        if (!isTextarea && !isContentEditable) return;\n                \n        var s = el.selectionStart;\n        var e = el.selectionEnd;\n        var value = el.value;\n                \n        if (isContentEditable) {\n            value = el.textContent;\n            var range = window.getSelection().getRangeAt(0);\n            s = range.startOffset;\n            e = range.endOffset;\n        }\n                \n        if (!text) {\n            if (keyCode == 13) { // enter\n                text = \"\\n\";\n            }\n            else if (keyCode == 8) { // backspace\n                if (s != e) s = Math.max(s-1, 0);\n            }\n            else if (keyCode == 46) { // delete\n                if (s != e) e = Math.min(e+1, value.length);\n            }\n            else {\n                return;\n            }\n        }\n        var newValue = value.slice(0, s) + text + value.slice(e);\n        s = e = s + text.length;\n        if (newValue != value) {\n            if (isContentEditable) {\n                el.textContent = newValue;\n                range.setStart(el.firstChild, s);\n                range.setEnd(el.firstChild, e);\n            }\n            else {\n                el.value = newValue;\n                el.setSelectionRange(s, e);\n            }\n            emit(\"input\", false);\n        }\n    }\n}\n\nfunction type() {\n    var keys = Array.prototype.slice.call(arguments);\n    for (var i = 0; i < keys.length; i++) {\n        var key = keys[i];\n        if (Array.isArray(key)) {\n            type.apply(null, key);\n            continue;\n        }\n        reset();\n        if (key.length > 1) {\n            var isKeyName = controlKeys[key] || printableKeys[key] || shiftedKeys[key];\n            if (!isKeyName) {\n                var parts = key.split(\"-\");\n                var modifier = alias[parts[0]] || parts[0];\n                if (!updateModifierStates(controlKeys[modifier])) {\n                    type.apply(null, key.split(\"\"));\n                    continue;\n                } \n                key = parts.pop();\n                parts.forEach(function(part) {\n                    var keyCode = controlKeys[part];\n                    updateModifierStates(keyCode);\n                });\n            }\n        }\n        sendKey(key);\n    }\n}\n\nexports.type = type;\n"
  },
  {
    "path": "src/theme/ambiance-css.js",
    "content": "module.exports = `.ace-ambiance .ace_gutter {\n  background-color: #3d3d3d;\n  background-image: linear-gradient(left, #3D3D3D, #333);\n  background-repeat: repeat-x;\n  border-right: 1px solid #4d4d4d;\n  text-shadow: 0px 1px 1px #4d4d4d;\n  color: #222;\n}\n\n.ace-ambiance .ace_gutter-layer {\n  background: repeat left top;\n}\n\n.ace-ambiance .ace_gutter-active-line {\n  background-color: #3F3F3F;\n}\n\n.ace-ambiance .ace_fold-widget {\n  text-align: center;\n}\n\n.ace-ambiance .ace_fold-widget:hover {\n  color: #777;\n}\n\n.ace-ambiance .ace_fold-widget.ace_start,\n.ace-ambiance .ace_fold-widget.ace_end,\n.ace-ambiance .ace_fold-widget.ace_closed{\n  background: none !important;\n  border: none;\n  box-shadow: none;\n}\n\n.ace-ambiance .ace_fold-widget.ace_start:after {\n  content: '▾'\n}\n\n.ace-ambiance .ace_fold-widget.ace_end:after {\n  content: '▴'\n}\n\n.ace-ambiance .ace_fold-widget.ace_closed:after {\n  content: '‣'\n}\n\n.ace-ambiance .ace_print-margin {\n  border-left: 1px dotted #2D2D2D;\n  right: 0;\n  background: #262626;\n}\n\n.ace-ambiance .ace_scroller {\n  -webkit-box-shadow: inset 0 0 10px black;\n  -moz-box-shadow: inset 0 0 10px black;\n  -o-box-shadow: inset 0 0 10px black;\n  box-shadow: inset 0 0 10px black;\n}\n\n.ace-ambiance {\n  color: #E6E1DC;\n  background-color: #202020;\n}\n\n.ace-ambiance .ace_cursor {\n  border-left: 1px solid #7991E8;\n}\n\n.ace-ambiance .ace_overwrite-cursors .ace_cursor {\n  border: 1px solid #FFE300;\n  background: #766B13;\n}\n\n.ace-ambiance.normal-mode .ace_cursor-layer {\n  z-index: 0;\n}\n \n.ace-ambiance .ace_marker-layer .ace_selection {\n  background: rgba(221, 240, 255, 0.20);\n}\n\n.ace-ambiance .ace_marker-layer .ace_selected-word {\n  border-radius: 4px;\n  border: 8px solid #3f475d;\n  box-shadow: 0 0 4px black;\n}\n\n.ace-ambiance .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174);\n}\n\n.ace-ambiance .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n.ace-ambiance .ace_marker-layer .ace_active-line {\n  background: rgba(255, 255, 255, 0.031);\n}\n\n.ace-ambiance .ace_invisible {\n  color: #333;\n}\n\n.ace-ambiance .ace_paren {\n  color: #24C2C7;\n}\n\n.ace-ambiance .ace_keyword {\n  color: #cda869;\n}\n\n.ace-ambiance .ace_keyword.ace_operator {\n  color: #fa8d6a;\n}\n\n.ace-ambiance .ace_punctuation.ace_operator {\n  color: #fa8d6a;\n}\n\n.ace-ambiance .ace_identifier {\n}\n\n.ace-ambiance .ace-statement {\n  color: #cda869;\n}\n\n.ace-ambiance .ace_constant {\n  color: #CF7EA9;\n}\n\n.ace-ambiance .ace_constant.ace_language {\n  color: #CF7EA9;\n}\n\n.ace-ambiance .ace_constant.ace_library {\n  \n}\n\n.ace-ambiance .ace_constant.ace_numeric {\n  color: #78CF8A;\n}\n\n.ace-ambiance .ace_invalid {\n  text-decoration: underline;\n}\n\n.ace-ambiance .ace_invalid.ace_illegal {\n  color:#F8F8F8;\n  background-color: rgba(86, 45, 86, 0.75);\n}\n\n.ace-ambiance .ace_invalid,\n.ace-ambiance .ace_deprecated {\n  text-decoration: underline;\n  font-style: italic;\n  color: #D2A8A1;\n}\n\n.ace-ambiance .ace_support {\n  color: #9B859D;\n}\n\n.ace-ambiance .ace_support.ace_function {\n  color: #DAD085;\n}\n\n.ace-ambiance .ace_function.ace_buildin {\n  color: #9b859d;\n}\n\n.ace-ambiance .ace_string {\n  color: #8f9d6a;\n}\n\n.ace-ambiance .ace_string.ace_regexp {\n  color: #DAD085;\n}\n\n.ace-ambiance .ace_comment {\n  font-style: italic;\n  color: #555;\n}\n\n.ace-ambiance .ace_comment.ace_doc {\n}\n\n.ace-ambiance .ace_comment.ace_doc.ace_tag {\n  color: #666;\n  font-style: normal;\n}\n\n.ace-ambiance .ace_definition,\n.ace-ambiance .ace_type {\n  color: #aac6e3;\n}\n\n.ace-ambiance .ace_variable {\n  color: #9999cc;\n}\n\n.ace-ambiance .ace_variable.ace_language {\n  color: #9b859d;\n}\n\n.ace-ambiance .ace_xml-pe {\n  color: #494949;\n}\n\n.ace-ambiance .ace_gutter-layer,\n.ace-ambiance .ace_text-layer {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC\");\n}\n\n.ace-ambiance .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC\") right repeat-y;\n}\n\n.ace-ambiance .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/ambiance.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-ambiance\";\nexports.cssText = require(\"./ambiance-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/chaos-css.js",
    "content": "module.exports = `.ace-chaos .ace_gutter {\n  background: #141414;\n  color: #595959;\n  border-right: 1px solid #282828;\n}\n.ace-chaos .ace_gutter-cell.ace_warning {\n  background-image: none;\n  background: #FC0;\n  border-left: none;\n  padding-left: 0;\n  color: #000;\n}\n.ace-chaos .ace_gutter-cell.ace_error {\n  background-position: -6px center;\n  background-image: none;\n  background: #F10;\n  border-left: none;\n  padding-left: 0;\n  color: #000;\n}\n.ace-chaos .ace_print-margin {\n  border-left: 1px solid #555;\n  right: 0;\n  background: #1D1D1D;\n}\n.ace-chaos {\n  background-color: #161616;\n  color: #E6E1DC;\n}\n\n.ace-chaos .ace_cursor {\n  border-left: 2px solid #FFFFFF;\n}\n.ace-chaos .ace_cursor.ace_overwrite {\n  border-left: 0px;\n  border-bottom: 1px solid #FFFFFF;\n}\n.ace-chaos .ace_marker-layer .ace_selection {\n  background: #494836;\n}\n.ace-chaos .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174);\n}\n.ace-chaos .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #FCE94F;\n}\n.ace-chaos .ace_marker-layer .ace_active-line {\n  background: #333;\n}\n.ace-chaos .ace_gutter-active-line {\n  background-color: #222;\n}\n.ace-chaos .ace_invisible {\n  color: #404040;\n}\n.ace-chaos .ace_keyword {\n  color:#00698F;\n}\n.ace-chaos .ace_keyword.ace_operator {\n  color:#FF308F;\n}\n.ace-chaos .ace_constant {\n  color:#1EDAFB;\n}\n.ace-chaos .ace_constant.ace_language {\n  color:#FDC251;\n}\n.ace-chaos .ace_constant.ace_library {\n  color:#8DFF0A;\n}\n.ace-chaos .ace_constant.ace_numeric {\n  color:#58C554;\n}\n.ace-chaos .ace_invalid {\n  color:#FFFFFF;\n  background-color:#990000;\n}\n.ace-chaos .ace_invalid.ace_deprecated {\n  color:#FFFFFF;\n  background-color:#990000;\n}\n.ace-chaos .ace_support {\n  color: #999;\n}\n.ace-chaos .ace_support.ace_function {\n  color:#00AEEF;\n}\n.ace-chaos .ace_function {\n  color:#00AEEF;\n}\n.ace-chaos .ace_string {\n  color:#58C554;\n}\n.ace-chaos .ace_comment {\n  color:#555;\n  font-style:italic;\n  padding-bottom: 0px;\n}\n.ace-chaos .ace_variable {\n  color:#997744;\n}\n.ace-chaos .ace_meta.ace_tag {\n  color:#BE53E6;\n}\n.ace-chaos .ace_entity.ace_other.ace_attribute-name {\n  color:#FFFF89;\n}\n.ace-chaos .ace_markup.ace_underline {\n  text-decoration: underline;\n}\n.ace-chaos .ace_fold-widget {\n  text-align: center;\n}\n\n.ace-chaos .ace_fold-widget:hover {\n  color: #777;\n}\n\n.ace-chaos .ace_fold-widget.ace_start,\n.ace-chaos .ace_fold-widget.ace_end,\n.ace-chaos .ace_fold-widget.ace_closed{\n  background: none !important;\n  border: none;\n  box-shadow: none;\n}\n\n.ace-chaos .ace_fold-widget.ace_start:after {\n  content: '▾'\n}\n\n.ace-chaos .ace_fold-widget.ace_end:after {\n  content: '▴'\n}\n\n.ace-chaos .ace_fold-widget.ace_closed:after {\n  content: '‣'\n}\n\n.ace-chaos .ace_indent-guide {\n  border-right:1px dotted #333333;\n  margin-right:-1px;\n}\n\n.ace-chaos .ace_indent-guide-active {\n  border-right:1px dotted #afafaf;\n  margin-right:-1px;\n}\n\n.ace-chaos .ace_fold { \n  background: #222; \n  border-radius: 3px; \n  color: #7AF; \n  border: none; \n}\n.ace-chaos .ace_fold:hover {\n  background: #CCC; \n  color: #000;\n}\n`;\n"
  },
  {
    "path": "src/theme/chaos.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-chaos\";\nexports.cssText = require(\"./chaos-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/chrome-css.js",
    "content": "module.exports = `.ace-chrome .ace_gutter {\n  background: #ebebeb;\n  color: #333;\n  overflow : hidden;\n}\n\n.ace-chrome .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-chrome {\n  background-color: #FFFFFF;\n  color: black;\n}\n\n.ace-chrome .ace_cursor {\n  color: black;\n}\n\n.ace-chrome .ace_invisible {\n  color: rgb(191, 191, 191);\n}\n\n.ace-chrome .ace_constant.ace_buildin {\n  color: rgb(88, 72, 246);\n}\n\n.ace-chrome .ace_constant.ace_language {\n  color: rgb(88, 92, 246);\n}\n\n.ace-chrome .ace_constant.ace_library {\n  color: rgb(6, 150, 14);\n}\n\n.ace-chrome .ace_invalid {\n  background-color: rgb(153, 0, 0);\n  color: white;\n}\n\n.ace-chrome .ace_fold {\n}\n\n.ace-chrome .ace_support.ace_function {\n  color: rgb(60, 76, 114);\n}\n\n.ace-chrome .ace_support.ace_constant {\n  color: rgb(6, 150, 14);\n}\n\n.ace-chrome .ace_support.ace_type,\n.ace-chrome .ace_support.ace_class\n.ace-chrome .ace_support.ace_other {\n  color: rgb(109, 121, 222);\n}\n\n.ace-chrome .ace_variable.ace_parameter {\n  font-style:italic;\n  color:#FD971F;\n}\n.ace-chrome .ace_keyword.ace_operator {\n  color: rgb(104, 118, 135);\n}\n\n.ace-chrome .ace_comment {\n  color: #236e24;\n}\n\n.ace-chrome .ace_comment.ace_doc {\n  color: #236e24;\n}\n\n.ace-chrome .ace_comment.ace_doc.ace_tag {\n  color: #236e24;\n}\n\n.ace-chrome .ace_constant.ace_numeric {\n  color: rgb(0, 0, 205);\n}\n\n.ace-chrome .ace_variable {\n  color: rgb(49, 132, 149);\n}\n\n.ace-chrome .ace_xml-pe {\n  color: rgb(104, 104, 91);\n}\n\n.ace-chrome .ace_entity.ace_name.ace_function {\n  color: #0000A2;\n}\n\n\n.ace-chrome .ace_heading {\n  color: rgb(12, 7, 255);\n}\n\n.ace-chrome .ace_list {\n  color:rgb(185, 6, 144);\n}\n\n.ace-chrome .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n\n.ace-chrome .ace_marker-layer .ace_step {\n  background: rgb(252, 255, 0);\n}\n\n.ace-chrome .ace_marker-layer .ace_stack {\n  background: rgb(164, 229, 101);\n}\n\n.ace-chrome .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-chrome .ace_marker-layer .ace_active-line {\n  background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-chrome .ace_gutter-active-line {\n    background-color : #dcdcdc;\n}\n\n.ace-chrome .ace_marker-layer .ace_selected-word {\n  background: rgb(250, 250, 255);\n  border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-chrome .ace_storage,\n.ace-chrome .ace_keyword,\n.ace-chrome .ace_meta.ace_tag {\n  color: rgb(147, 15, 128);\n}\n\n.ace-chrome .ace_string.ace_regex {\n  color: rgb(255, 0, 0)\n}\n\n.ace-chrome .ace_string {\n  color: #1A1AA6;\n}\n\n.ace-chrome .ace_entity.ace_other.ace_attribute-name {\n  color: #994409;\n}\n\n.ace-chrome .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n  \n.ace-chrome .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/chrome.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-chrome\";\nexports.cssText = require(\"./chrome-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cloud9_day-css.js",
    "content": "module.exports = `.ace-cloud9-day .ace_gutter {\n    background: #ECECEC;\n    color: #333;\n}\n\n.ace-cloud9-day .ace_print-margin {\n    width: 1px;\n    background: #e8e8e8;\n}\n\n.ace-cloud9-day .ace_fold {\n    background-color: #6B72E6;\n}\n\n.ace-cloud9-day {\n    background-color: #FBFBFB;\n    color: black;\n}\n\n.ace-cloud9-day .ace_cursor {\n    color: black;\n}\n\n.ace-cloud9-day .ace_invisible {\n    color: rgb(191, 191, 191);\n}\n\n.ace-cloud9-day .ace_storage,\n.ace-cloud9-day .ace_keyword {\n    color: rgb(24, 122, 234);\n}\n\n.ace-cloud9-day .ace_constant {\n    color: rgb(197, 6, 11);\n}\n\n.ace-cloud9-day .ace_constant.ace_buildin {\n    color: rgb(88, 72, 246);\n}\n\n.ace-cloud9-day .ace_constant.ace_language {\n    color: rgb(88, 92, 246);\n}\n\n.ace-cloud9-day .ace_constant.ace_library {\n    color: rgb(6, 150, 14);\n}\n\n.ace-cloud9-day .ace_invalid {\n    background-color: rgba(255, 0, 0, 0.1);\n    color: red;\n}\n\n.ace-cloud9-day .ace_support.ace_function {\n    color: rgb(60, 76, 114);\n}\n\n.ace-cloud9-day .ace_support.ace_constant {\n    color: rgb(6, 150, 14);\n}\n\n.ace-cloud9-day .ace_support.ace_type,\n.ace-cloud9-day .ace_support.ace_class {\n    color: rgb(109, 121, 222);\n}\n\n.ace-cloud9-day .ace_keyword.ace_operator {\n    color: rgb(104, 118, 135);\n}\n\n.ace-cloud9-day .ace_string {\n    color: rgb(3, 106, 7);\n}\n\n.ace-cloud9-day .ace_comment {\n    color: rgb(76, 136, 107);\n}\n\n.ace-cloud9-day .ace_comment.ace_doc {\n    color: rgb(0, 102, 255);\n}\n\n.ace-cloud9-day .ace_comment.ace_doc.ace_tag {\n    color: rgb(128, 159, 191);\n}\n\n.ace-cloud9-day .ace_constant.ace_numeric {\n    color: rgb(0, 0, 205);\n}\n\n.ace-cloud9-day .ace_variable {\n    color: rgb(49, 132, 149);\n}\n\n.ace-cloud9-day .ace_xml-pe {\n    color: rgb(104, 104, 91);\n}\n\n.ace-cloud9-day .ace_entity.ace_name.ace_function {\n    color: #0000A2;\n}\n\n\n.ace-cloud9-day .ace_heading {\n    color: rgb(12, 7, 255);\n}\n\n.ace-cloud9-day .ace_list {\n    color: rgb(185, 6, 144);\n}\n\n.ace-cloud9-day .ace_meta.ace_tag {\n    color: rgb(0, 22, 142);\n}\n\n.ace-cloud9-day .ace_string.ace_regex {\n    color: rgb(255, 0, 0)\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_selection {\n    background: rgb(181, 213, 255);\n}\n\n.ace-cloud9-day.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px white;\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_step {\n    background: rgb(247, 237, 137);\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_stack {\n    background: #BAE0A0;\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_active-line {\n    background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-cloud9-day .ace_gutter-active-line {\n    background-color: #E5E5E5;\n}\n\n.ace-cloud9-day .ace_marker-layer .ace_selected-word {\n    background: rgb(250, 250, 255);\n    border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-cloud9-day .ace_indent-guide {\n    background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-cloud9-day .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/cloud9_day.js",
    "content": "\"use strict\";\n\n  exports.isDark = false;\n  exports.cssClass = \"ace-cloud9-day\";\n  exports.cssText = require(\"./cloud9_day-css\");\n\n  var dom = require(\"../lib/dom\");\n  dom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cloud9_night-css.js",
    "content": "module.exports = `.ace-cloud9-night .ace_gutter {\n    background: #303130;\n    color: #eee\n}\n\n.ace-cloud9-night .ace_print-margin {\n    width: 1px;\n    background: #222\n}\n\n.ace-cloud9-night {\n    background-color: #181818;\n    color: #EBEBEB\n}\n\n.ace-cloud9-night .ace_cursor {\n    color: #9F9F9F\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_selection {\n    background: #424242\n}\n\n.ace-cloud9-night.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px #000000;\n    border-radius: 2px\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_step {\n    background: rgb(102, 82, 0)\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid #888888\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_highlight {\n    border: 1px solid rgb(110, 119, 0);\n    border-bottom: 0;\n    box-shadow: inset 0 -1px rgb(110, 119, 0);\n    margin: -1px 0 0 -1px;\n    background: rgba(255, 235, 0, 0.1);\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_active-line {\n    background: #292929\n}\n\n.ace-cloud9-night .ace_gutter-active-line {\n    background-color: #3D3D3D\n}\n\n.ace-cloud9-night .ace_stack {\n    background-color: rgb(66, 90, 44)\n}\n\n.ace-cloud9-night .ace_marker-layer .ace_selected-word {\n    border: 1px solid #888888\n}\n\n.ace-cloud9-night .ace_invisible {\n    color: #343434\n}\n\n.ace-cloud9-night .ace_keyword,\n.ace-cloud9-night .ace_meta,\n.ace-cloud9-night .ace_storage,\n.ace-cloud9-night .ace_storage.ace_type,\n.ace-cloud9-night .ace_support.ace_type {\n    color: #C397D8\n}\n\n.ace-cloud9-night .ace_keyword.ace_operator {\n    color: #70C0B1\n}\n\n.ace-cloud9-night .ace_constant.ace_character,\n.ace-cloud9-night .ace_constant.ace_language,\n.ace-cloud9-night .ace_constant.ace_numeric,\n.ace-cloud9-night .ace_keyword.ace_other.ace_unit,\n.ace-cloud9-night .ace_support.ace_constant,\n.ace-cloud9-night .ace_variable.ace_parameter {\n    color: #E78C45\n}\n\n.ace-cloud9-night .ace_constant.ace_other {\n    color: #EEEEEE\n}\n\n.ace-cloud9-night .ace_invalid {\n    color: #CED2CF;\n    background-color: #DF5F5F\n}\n\n.ace-cloud9-night .ace_invalid.ace_deprecated {\n    color: #CED2CF;\n    background-color: #B798BF\n}\n\n.ace-cloud9-night .ace_fold {\n    background-color: #7AA6DA;\n    border-color: #DEDEDE\n}\n\n.ace-cloud9-night .ace_entity.ace_name.ace_function,\n.ace-cloud9-night .ace_support.ace_function,\n.ace-cloud9-night .ace_variable:not(.ace_parameter),\n.ace-cloud9-night .ace_constant:not(.ace_numeric) {\n    color: #7AA6DA\n}\n\n.ace-cloud9-night .ace_support.ace_class,\n.ace-cloud9-night .ace_support.ace_type {\n    color: #E7C547\n}\n\n.ace-cloud9-night .ace_heading,\n.ace-cloud9-night .ace_markup.ace_heading,\n.ace-cloud9-night .ace_string {\n    color: #B9CA4A\n}\n\n.ace-cloud9-night .ace_entity.ace_name.ace_tag,\n.ace-cloud9-night .ace_entity.ace_other.ace_attribute-name,\n.ace-cloud9-night .ace_meta.ace_tag,\n.ace-cloud9-night .ace_string.ace_regexp,\n.ace-cloud9-night .ace_variable {\n    color: #D54E53\n}\n\n.ace-cloud9-night .ace_comment {\n    color: #969896\n}\n\n.ace-cloud9-night .ace_c9searchresults.ace_keyword {\n    color: #C2C280;\n}\n\n.ace-cloud9-night .ace_indent-guide {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-cloud9-night .ace_indent-guide-active {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/cloud9_night.js",
    "content": "exports.isDark = true;\n  exports.cssClass = \"ace-cloud9-night\";\n  exports.cssText = require(\"./cloud9_night-css\");\n\n  var dom = require(\"../lib/dom\");\n  dom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cloud9_night_low_color-css.js",
    "content": "module.exports = `.ace-cloud9-night-low-color .ace_gutter {\n    background: #303130;\n    color: #eee\n}\n\n.ace-cloud9-night-low-color .ace_print-margin {\n    width: 1px;\n    background: #222\n}\n\n.ace-cloud9-night-low-color {\n    background-color: #181818;\n    color: #EBEBEB\n}\n\n.ace-cloud9-night-low-color .ace_cursor {\n    color: #9F9F9F\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_selection {\n    background: #424242\n}\n\n.ace-cloud9-night-low-color.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px #000000;\n    border-radius: 2px\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_step {\n    background: rgb(102, 82, 0)\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid #888888\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_highlight {\n    border: 1px solid rgb(110, 119, 0);\n    border-bottom: 0;\n    box-shadow: inset 0 -1px rgb(110, 119, 0);\n    margin: -1px 0 0 -1px;\n    background: rgba(255, 235, 0, 0.1);\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_active-line {\n    background: #292929\n}\n\n.ace-cloud9-night-low-color .ace_gutter-active-line {\n    background-color: #3D3D3D\n}\n\n.ace-cloud9-night-low-color .ace_stack {\n    background-color: rgb(66, 90, 44)\n}\n\n.ace-cloud9-night-low-color .ace_marker-layer .ace_selected-word {\n    border: 1px solid #888888\n}\n\n.ace-cloud9-night-low-color .ace_invisible {\n    color: #343434\n}\n\n.ace-cloud9-night-low-color .ace_keyword,\n.ace-cloud9-night-low-color .ace_meta,\n.ace-cloud9-night-low-color .ace_storage {\n    color: #C397D8\n}\n\n.ace-cloud9-night-low-color .ace_keyword.ace_operator {\n    color: #70C0B1\n}\n\n.ace-cloud9-night-low-color .ace_constant.ace_character,\n.ace-cloud9-night-low-color .ace_constant.ace_language,\n.ace-cloud9-night-low-color .ace_constant.ace_numeric,\n.ace-cloud9-night-low-color .ace_keyword.ace_other.ace_unit {\n    color: #DAA637\n}\n\n.ace-cloud9-night-low-color .ace_constant.ace_other {\n    color: #EEEEEE\n}\n\n.ace-cloud9-night-low-color .ace_invalid {\n    color: #CED2CF;\n    background-color: #DF5F5F\n}\n\n.ace-cloud9-night-low-color .ace_invalid.ace_deprecated {\n    color: #CED2CF;\n    background-color: #B798BF\n}\n\n.ace-cloud9-night-low-color .ace_fold {\n    background-color: #7AA6DA;\n    border-color: #DEDEDE\n}\n\n.ace-cloud9-night-low-color .ace_entity.ace_name.ace_function,\n.ace-cloud9-night-low-color .ace_support.ace_function,\n.ace-cloud9-night-low-color .ace_variable:not(.ace_parameter),\n.ace-cloud9-night-low-color .ace_constant:not(.ace_numeric) {\n    color: #7AA6DA\n}\n\n.ace-cloud9-night-low-color .ace_support.ace_class,\n.ace-cloud9-night-low-color .ace_support.ace_type {\n    color: #E7C547\n}\n\n.ace-cloud9-night-low-color .ace_heading,\n.ace-cloud9-night-low-color .ace_markup.ace_heading,\n.ace-cloud9-night-low-color .ace_string {\n    color: #B9CA4A\n}\n\n.ace-cloud9-night-low-color .ace_comment {\n    color: #969896\n}\n\n.ace-cloud9-night-low-color .ace_c9searchresults.ace_keyword {\n    color: #C2C280;\n}\n\n.ace-cloud9-night-low-color .ace_indent-guide {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-cloud9-night-low-color .ace_indent-guide-active {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/cloud9_night_low_color.js",
    "content": "exports.isDark = true;\n  exports.cssClass = \"ace-cloud9-night-low-color\";\n  exports.cssText = require(\"./cloud9_night_low_color-css\");\n\n  var dom = require(\"../lib/dom\");\n  dom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cloud_editor-css.js",
    "content": "module.exports = `\n.ace-cloud_editor .ace_gutter {\n    background: #ffffff;\n    color: #3a3a42;\n}\n\n.ace-cloud_editor .ace_tooltip-marker-error.ace_tooltip-marker {\n    background-color: #d13212;\n}\n.ace-cloud_editor .ace_tooltip-marker-security.ace_tooltip-marker {\n    background-color: #d13212;\n}\n.ace-cloud_editor .ace_tooltip-marker-warning.ace_tooltip-marker {\n    background-color: #906806;\n}\n\n.ace-cloud_editor .ace_print-margin {\n    width: 1px;\n    background: #697077;\n}\n\n.ace-cloud_editor {\n    background-color: #ffffff;\n    color: #3a3a42;\n}\n\n.ace-cloud_editor .ace_cursor {\n    color: #3a3a42;\n}\n\n.ace-cloud_editor .ace_marker-layer .ace_selection {\n    background: #bfceff;\n}\n\n.ace-cloud_editor.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px #ffffff;\n    border-radius: 2px;\n}\n\n.ace-cloud_editor .ace_marker-layer .ace_step {\n    background: #697077;\n}\n\n.ace-cloud_editor .ace_marker-layer .ace_bracket {\n    margin: 0 0 0 -1px;\n    border: 1px solid #697077;\n}\n\n.ace-cloud_editor .ace_gutter-cursor,\n.ace-cloud_editor .ace_marker-layer .ace_active-line {\n    box-sizing: border-box;\n    border-top: 1px solid #9191ac;\n    border-bottom: 1px solid #9191ac;\n}\n\n.ace-cloud_editor .ace_gutter-cursor {\n    position: absolute;\n    width: 100%;\n}\n\n.ace-cloud_editor .ace_marker-layer .ace_selected-word {\n    border: 1px solid #bfceff;\n}\n\n.ace-cloud_editor .ace_fold {\n    background-color: #0E45B4;\n    border-color: #3a3a42;\n}\n\n.ace-cloud_editor .ace_keyword {\n    color: #9749d1;\n}\n\n.ace-cloud_editor .ace_meta.ace_tag {\n    color: #0E45B4;\n}\n\n.ace-cloud_editor .ace_constant {\n    color: #A16101;\n}\n\n.ace-cloud_editor .ace_constant.ace_numeric {\n    color: #A16101;\n}\n\n.ace-cloud_editor .ace_constant.ace_character.ace_escape {\n    color: #BD1880;\n}\n\n.ace-cloud_editor .ace_support.ace_function {\n    color: #A81700;\n}\n\n.ace-cloud_editor .ace_support.ace_class {\n    color: #A16101;\n}\n\n.ace-cloud_editor .ace_storage {\n    color: #9749d1;\n}\n\n.ace-cloud_editor .ace_invalid.ace_illegal {\n    color: #ffffff;\n    background-color: #0E45B4;\n}\n\n.ace-cloud_editor .ace_invalid.ace_deprecated {\n    color: #ffffff;\n    background-color: #A16101;\n}\n\n.ace-cloud_editor .ace_string {\n    color: #207A7F;\n}\n\n.ace-cloud_editor .ace_string.ace_regexp {\n    color: #207A7F;\n}\n\n.ace-cloud_editor .ace_comment,\n.ace-cloud_editor .ace_ghost_text {\n    color: #697077;\n    opacity: 1;\n}\n\n.ace-cloud_editor .ace_variable {\n    color: #0E45B4;\n}\n\n.ace-cloud_editor .ace_meta.ace_selector {\n    color: #9749d1;\n}\n\n.ace-cloud_editor .ace_entity.ace_other.ace_attribute-name {\n    color: #A16101;\n}\n\n.ace-cloud_editor .ace_entity.ace_name.ace_function {\n    color: #A81700;\n}\n\n.ace-cloud_editor .ace_entity.ace_name.ace_tag {\n    color: #0E45B4;\n}\n\n.ace-cloud_editor .ace_heading {\n    color: #A81700;\n}\n\n.ace-cloud_editor .ace_xml-pe {\n    color: #A16101;\n}\n.ace-cloud_editor .ace_doctype {\n    color: #0E45B4;\n}\n\n.ace-cloud_editor .ace_tooltip {\n    background-color: #ffffff;\n    color: #3a3a42;\n}\n\n.ace-cloud_editor .ace_icon_svg.ace_error,\n.ace-cloud_editor .ace_icon_svg.ace_error_fold {\n    background-color: #d13212;\n}\n.ace-cloud_editor .ace_icon_svg.ace_security,\n.ace-cloud_editor .ace_icon_svg.ace_security_fold {\n    background-color: #d13212;\n}\n.ace-cloud_editor .ace_icon_svg.ace_warning,\n.ace-cloud_editor .ace_icon_svg.ace_warning_fold {\n    background-color: #906806;\n}\n.ace-cloud_editor .ace_icon_svg.ace_info {\n    background-color: #0073bb;\n}\n.ace-cloud_editor .ace_icon_svg.ace_hint {\n    background-color: #0073bb;\n}\n.ace-cloud_editor .ace_highlight-marker {\n    background: none;\n    border: #0E45B4 1px solid;\n}\n.ace-cloud_editor .ace_tooltip.ace_hover-tooltip:focus > div {\n    outline: 1px solid #0073bb;\n}\n.ace-cloud_editor .ace_snippet-marker {\n    background-color: #CED6E0;\n    border: 0;\n}\n\n.ace-cloud_editor.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #f2f3f3;\n    border: #0F68AE 1.5px solid;\n}\n.ace-cloud_editor.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid #16191f;\n    background: #f2f3f3;\n}\n.ace-cloud_editor.ace_editor.ace_autocomplete .ace_completion-meta {\n    color: #545b64;\n    opacity: 1;\n}\n.ace-cloud_editor.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #0F68AE;\n}\n.ace-cloud_editor.ace_editor.ace_autocomplete {\n    box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;\n    line-height: 1.5;\n    border: 1px solid #eaeded;\n    background: #ffffff;\n    color: #16191f;\n}\n\n`;"
  },
  {
    "path": "src/theme/cloud_editor.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-cloud_editor\";\nexports.cssText = require(\"./cloud_editor-css\");\n/**@internal */\nexports.$showGutterCursorMarker = true;\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cloud_editor_dark-css.js",
    "content": "module.exports = `\n.ace-cloud_editor_dark .ace_gutter {\n    background: #282c34;\n    color: #8e96a9;\n}\n\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-error.ace_tooltip-marker {\n    background-color: #ff5d64;\n}\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-security.ace_tooltip-marker {\n    background-color: #ff5d64;\n}\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-warning.ace_tooltip-marker {\n    background-color: #e0ca57;\n}\n\n.ace-cloud_editor_dark .ace_print-margin {\n    width: 1px;\n    background: #e8e8e8;\n}\n\n.ace-cloud_editor_dark {\n    background-color: #282c34;\n    color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_cursor {\n    color: #66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_selection {\n    background: #4376bd;\n}\n\n.ace-cloud_editor_dark.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px #8e96a9;\n    border-radius: 2px;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_step {\n    background: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_bracket {\n    margin: 0 0 0 -1px;\n    border: 1px solid #e8e8e8;\n}\n\n.ace-cloud_editor_dark .ace_gutter-cursor,\n.ace-cloud_editor_dark .ace_marker-layer .ace_active-line {\n    box-sizing: border-box;\n    border-top: 1px solid #75777a;\n    border-bottom: 1px solid #75777a;\n}\n\n.ace-cloud_editor_dark .ace_gutter-cursor {\n    position: absolute;\n    width: 100%;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_selected-word {\n    border: 1px solid #9bd0f7;\n}\n\n.ace-cloud_editor_dark .ace_fold {\n    background-color: #66b2f0;\n    border-color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_keyword {\n    color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_constant {\n    color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_constant.ace_numeric {\n    color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_constant.ace_character.ace_escape {\n    color: #71ccc7;\n}\n\n.ace-cloud_editor_dark .ace_support.ace_function {\n    color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_support.ace_class {\n    color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_storage {\n    color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_invalid.ace_illegal {\n    color: #dcdfe4;\n    background-color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_invalid.ace_deprecated {\n    color: #dcdfe4;\n    background-color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_string {\n    color: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_string.ace_regexp {\n    color: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_comment,\n.ace-cloud_editor_dark .ace_ghost_text {\n    color: #b5bac0;\n    opacity: 1;\n}\n\n.ace-cloud_editor_dark .ace_variable {\n    color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_meta.ace_selector {\n    color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_other.ace_attribute-name {\n    color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_function {\n    color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_tag {\n    color:#66b2f0;\n}\n.ace-cloud_editor_dark .ace_heading {\n    color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_xml-pe {\n    color: #e5c383;\n}\n.ace-cloud_editor_dark .ace_doctype {\n    color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_tag,\n.ace-cloud_editor_dark .ace_entity.ace_other.ace_attribute-name,\n.ace-cloud_editor_dark .ace_meta.ace_tag,\n.ace-cloud_editor_dark .ace_string.ace_regexp,\n.ace-cloud_editor_dark .ace_variable {\n    color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_tooltip {\n    background-color: #282c34;\n    color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_icon_svg.ace_error,\n.ace-cloud_editor_dark .ace_icon_svg.ace_error_fold {\n    background-color: #ff5d64;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_security,\n.ace-cloud_editor_dark .ace_icon_svg.ace_security_fold {\n    background-color: #ff5d64;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_warning,\n.ace-cloud_editor_dark .ace_icon_svg.ace_warning_fold {\n    background-color: #e0ca57;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_info {\n    background-color: #44b9d6;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_hint {\n    background-color: #44b9d6;\n}\n.ace-cloud_editor_dark .ace_highlight-marker {\n    background: none;\n    border: #66b2f0 1px solid;\n}\n.ace-cloud_editor_dark .ace_tooltip.ace_hover-tooltip:focus > div {\n    outline: 1px solid #44b9d6;\n}\n.ace-cloud_editor_dark .ace_snippet-marker {\n    background-color: #434650;\n    border: 0;\n}\n\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #272A30;\n    border: #299FBC 1.5px solid;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid #d5dbdb;\n    background: #272A30;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_completion-meta {\n    color: #95a5a6;\n    opacity: 1;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #2AA0BC;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete {\n    box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;\n    line-height: 1.5;\n    border: 1px solid #2a2e33;\n    background: #050506;\n    color: #ffffff;\n}\n\n`;"
  },
  {
    "path": "src/theme/cloud_editor_dark.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-cloud_editor_dark\";\nexports.cssText = require(\"./cloud_editor_dark-css\");\n/**@internal */\nexports.$showGutterCursorMarker = true;\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/clouds-css.js",
    "content": "module.exports = `.ace-clouds .ace_gutter {\n  background: #ebebeb;\n  color: #333\n}\n\n.ace-clouds .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-clouds {\n  background-color: #FFFFFF;\n  color: #000000\n}\n\n.ace-clouds .ace_cursor {\n  color: #000000\n}\n\n.ace-clouds .ace_marker-layer .ace_selection {\n  background: #BDD5FC\n}\n\n.ace-clouds.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #FFFFFF;\n}\n\n.ace-clouds .ace_marker-layer .ace_step {\n  background: rgb(255, 255, 0)\n}\n\n.ace-clouds .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #BFBFBF\n}\n\n.ace-clouds .ace_marker-layer .ace_active-line {\n  background: #FFFBD1\n}\n\n.ace-clouds .ace_gutter-active-line {\n  background-color : #dcdcdc\n}\n\n.ace-clouds .ace_marker-layer .ace_selected-word {\n  border: 1px solid #BDD5FC\n}\n\n.ace-clouds .ace_invisible {\n  color: #BFBFBF\n}\n\n.ace-clouds .ace_keyword,\n.ace-clouds .ace_meta,\n.ace-clouds .ace_support.ace_constant.ace_property-value {\n  color: #AF956F\n}\n\n.ace-clouds .ace_keyword.ace_operator {\n  color: #484848\n}\n\n.ace-clouds .ace_keyword.ace_other.ace_unit {\n  color: #96DC5F\n}\n\n.ace-clouds .ace_constant.ace_language {\n  color: #39946A\n}\n\n.ace-clouds .ace_constant.ace_numeric {\n  color: #46A609\n}\n\n.ace-clouds .ace_constant.ace_character.ace_entity {\n  color: #BF78CC\n}\n\n.ace-clouds .ace_invalid {\n  background-color: #FF002A\n}\n\n.ace-clouds .ace_fold {\n  background-color: #AF956F;\n  border-color: #000000\n}\n\n.ace-clouds .ace_storage,\n.ace-clouds .ace_support.ace_class,\n.ace-clouds .ace_support.ace_function,\n.ace-clouds .ace_support.ace_other,\n.ace-clouds .ace_support.ace_type {\n  color: #C52727\n}\n\n.ace-clouds .ace_string {\n  color: #5D90CD\n}\n\n.ace-clouds .ace_comment {\n  color: #BCC8BA\n}\n\n.ace-clouds .ace_entity.ace_name.ace_tag,\n.ace-clouds .ace_entity.ace_other.ace_attribute-name {\n  color: #606060\n}\n\n.ace-clouds .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y\n}\n\n.ace-clouds .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/clouds.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-clouds\";\nexports.cssText = require(\"./clouds-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/clouds_midnight-css.js",
    "content": "module.exports = `.ace-clouds-midnight .ace_gutter {\n  background: #232323;\n  color: #929292\n}\n\n.ace-clouds-midnight .ace_print-margin {\n  width: 1px;\n  background: #232323\n}\n\n.ace-clouds-midnight {\n  background-color: #191919;\n  color: #929292\n}\n\n.ace-clouds-midnight .ace_cursor {\n  color: #7DA5DC\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_selection {\n  background: #000000\n}\n\n.ace-clouds-midnight.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #191919;\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #BFBFBF\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_active-line {\n  background: rgba(215, 215, 215, 0.031)\n}\n\n.ace-clouds-midnight .ace_gutter-active-line {\n  background-color: rgba(215, 215, 215, 0.031)\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_selected-word {\n  border: 1px solid #000000\n}\n\n.ace-clouds-midnight .ace_invisible {\n  color: #666\n}\n\n.ace-clouds-midnight .ace_keyword,\n.ace-clouds-midnight .ace_meta,\n.ace-clouds-midnight .ace_support.ace_constant.ace_property-value {\n  color: #927C5D\n}\n\n.ace-clouds-midnight .ace_keyword.ace_operator {\n  color: #4B4B4B\n}\n\n.ace-clouds-midnight .ace_keyword.ace_other.ace_unit {\n  color: #366F1A\n}\n\n.ace-clouds-midnight .ace_constant.ace_language {\n  color: #39946A\n}\n\n.ace-clouds-midnight .ace_constant.ace_numeric {\n  color: #46A609\n}\n\n.ace-clouds-midnight .ace_constant.ace_character.ace_entity {\n  color: #A165AC\n}\n\n.ace-clouds-midnight .ace_invalid {\n  color: #FFFFFF;\n  background-color: #E92E2E\n}\n\n.ace-clouds-midnight .ace_fold {\n  background-color: #927C5D;\n  border-color: #929292\n}\n\n.ace-clouds-midnight .ace_storage,\n.ace-clouds-midnight .ace_support.ace_class,\n.ace-clouds-midnight .ace_support.ace_function,\n.ace-clouds-midnight .ace_support.ace_other,\n.ace-clouds-midnight .ace_support.ace_type {\n  color: #E92E2E\n}\n\n.ace-clouds-midnight .ace_string {\n  color: #5D90CD\n}\n\n.ace-clouds-midnight .ace_comment {\n  color: #3C403B\n}\n\n.ace-clouds-midnight .ace_entity.ace_name.ace_tag,\n.ace-clouds-midnight .ace_entity.ace_other.ace_attribute-name {\n  color: #606060\n}\n\n.ace-clouds-midnight .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-clouds-midnight .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/clouds_midnight.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-clouds-midnight\";\nexports.cssText = require(\"./clouds_midnight-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/cobalt-css.js",
    "content": "module.exports = `.ace-cobalt .ace_gutter {\n  background: #011e3a;\n  color: rgb(128,145,160)\n}\n\n.ace-cobalt .ace_print-margin {\n  width: 1px;\n  background: #555555\n}\n\n.ace-cobalt {\n  background-color: #002240;\n  color: #FFFFFF\n}\n\n.ace-cobalt .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-cobalt .ace_marker-layer .ace_selection {\n  background: rgba(179, 101, 57, 0.75)\n}\n\n.ace-cobalt.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #002240;\n}\n\n.ace-cobalt .ace_marker-layer .ace_step {\n  background: rgb(127, 111, 19)\n}\n\n.ace-cobalt .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(255, 255, 255, 0.15)\n}\n\n.ace-cobalt .ace_marker-layer .ace_active-line {\n  background: rgba(0, 0, 0, 0.35)\n}\n\n.ace-cobalt .ace_gutter-active-line {\n  background-color: rgba(0, 0, 0, 0.35)\n}\n\n.ace-cobalt .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(179, 101, 57, 0.75)\n}\n\n.ace-cobalt .ace_invisible {\n  color: rgba(255, 255, 255, 0.15)\n}\n\n.ace-cobalt .ace_keyword,\n.ace-cobalt .ace_meta {\n  color: #FF9D00\n}\n\n.ace-cobalt .ace_constant,\n.ace-cobalt .ace_constant.ace_character,\n.ace-cobalt .ace_constant.ace_character.ace_escape,\n.ace-cobalt .ace_constant.ace_other {\n  color: #FF628C\n}\n\n.ace-cobalt .ace_invalid {\n  color: #F8F8F8;\n  background-color: #800F00\n}\n\n.ace-cobalt .ace_support {\n  color: #80FFBB\n}\n\n.ace-cobalt .ace_support.ace_constant {\n  color: #EB939A\n}\n\n.ace-cobalt .ace_fold {\n  background-color: #FF9D00;\n  border-color: #FFFFFF\n}\n\n.ace-cobalt .ace_support.ace_function {\n  color: #FFB054\n}\n\n.ace-cobalt .ace_storage {\n  color: #FFEE80\n}\n\n.ace-cobalt .ace_entity {\n  color: #FFDD00\n}\n\n.ace-cobalt .ace_string {\n  color: #3AD900\n}\n\n.ace-cobalt .ace_string.ace_regexp {\n  color: #80FFC2\n}\n\n.ace-cobalt .ace_comment {\n  font-style: italic;\n  color: #0088FF\n}\n\n.ace-cobalt .ace_heading,\n.ace-cobalt .ace_markup.ace_heading {\n  color: #C8E4FD;\n  background-color: #001221\n}\n\n.ace-cobalt .ace_list,\n.ace-cobalt .ace_markup.ace_list {\n  background-color: #130D26\n}\n\n.ace-cobalt .ace_variable {\n  color: #CCCCCC\n}\n\n.ace-cobalt .ace_variable.ace_language {\n  color: #FF80E1\n}\n\n.ace-cobalt .ace_meta.ace_tag {\n  color: #9EFFFF\n}\n\n.ace-cobalt .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHCLSvkPAAP3AgSDTRd4AAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-cobalt .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/cobalt.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-cobalt\";\nexports.cssText = require(\"./cobalt-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/crimson_editor-css.js",
    "content": "module.exports = `.ace-crimson-editor .ace_gutter {\n  background: #ebebeb;\n  color: #333;\n  overflow : hidden;\n}\n\n.ace-crimson-editor .ace_gutter-layer {\n  width: 100%;\n  text-align: right;\n}\n\n.ace-crimson-editor .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-crimson-editor {\n  background-color: #FFFFFF;\n  color: rgb(64, 64, 64);\n}\n\n.ace-crimson-editor .ace_cursor {\n  color: black;\n}\n\n.ace-crimson-editor .ace_invisible {\n  color: rgb(191, 191, 191);\n}\n\n.ace-crimson-editor .ace_identifier {\n  color: black;\n}\n\n.ace-crimson-editor .ace_keyword {\n  color: blue;\n}\n\n.ace-crimson-editor .ace_constant.ace_buildin {\n  color: rgb(88, 72, 246);\n}\n\n.ace-crimson-editor .ace_constant.ace_language {\n  color: rgb(255, 156, 0);\n}\n\n.ace-crimson-editor .ace_constant.ace_library {\n  color: rgb(6, 150, 14);\n}\n\n.ace-crimson-editor .ace_invalid {\n  text-decoration: line-through;\n  color: rgb(224, 0, 0);\n}\n\n.ace-crimson-editor .ace_fold {\n}\n\n.ace-crimson-editor .ace_support.ace_function {\n  color: rgb(192, 0, 0);\n}\n\n.ace-crimson-editor .ace_support.ace_constant {\n  color: rgb(6, 150, 14);\n}\n\n.ace-crimson-editor .ace_support.ace_type,\n.ace-crimson-editor .ace_support.ace_class {\n  color: rgb(109, 121, 222);\n}\n\n.ace-crimson-editor .ace_keyword.ace_operator {\n  color: rgb(49, 132, 149);\n}\n\n.ace-crimson-editor .ace_string {\n  color: rgb(128, 0, 128);\n}\n\n.ace-crimson-editor .ace_comment {\n  color: rgb(76, 136, 107);\n}\n\n.ace-crimson-editor .ace_comment.ace_doc {\n  color: rgb(0, 102, 255);\n}\n\n.ace-crimson-editor .ace_comment.ace_doc.ace_tag {\n  color: rgb(128, 159, 191);\n}\n\n.ace-crimson-editor .ace_constant.ace_numeric {\n  color: rgb(0, 0, 64);\n}\n\n.ace-crimson-editor .ace_variable {\n  color: rgb(0, 64, 128);\n}\n\n.ace-crimson-editor .ace_xml-pe {\n  color: rgb(104, 104, 91);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_step {\n  background: rgb(252, 255, 0);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_stack {\n  background: rgb(164, 229, 101);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_active-line {\n  background: rgb(232, 242, 254);\n}\n\n.ace-crimson-editor .ace_gutter-active-line {\n    background-color : #dcdcdc;\n}\n\n.ace-crimson-editor .ace_meta.ace_tag {\n  color:rgb(28, 2, 255);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_selected-word {\n  background: rgb(250, 250, 255);\n  border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-crimson-editor .ace_string.ace_regex {\n  color: rgb(192, 0, 192);\n}\n\n.ace-crimson-editor .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-crimson-editor .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/crimson_editor.js",
    "content": "exports.isDark = false;\nexports.cssText = require(\"./crimson_editor-css\");\n\nexports.cssClass = \"ace-crimson-editor\";\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/dawn-css.js",
    "content": "module.exports = `.ace-dawn .ace_gutter {\n  background: #ebebeb;\n  color: #333\n}\n\n.ace-dawn .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-dawn {\n  background-color: #F9F9F9;\n  color: #080808\n}\n\n.ace-dawn .ace_cursor {\n  color: #000000\n}\n\n.ace-dawn .ace_marker-layer .ace_selection {\n  background: rgba(39, 95, 255, 0.30)\n}\n\n.ace-dawn.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #F9F9F9;\n}\n\n.ace-dawn .ace_marker-layer .ace_step {\n  background: rgb(255, 255, 0)\n}\n\n.ace-dawn .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(75, 75, 126, 0.50)\n}\n\n.ace-dawn .ace_marker-layer .ace_active-line {\n  background: rgba(36, 99, 180, 0.12)\n}\n\n.ace-dawn .ace_gutter-active-line {\n  background-color : #dcdcdc\n}\n\n.ace-dawn .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(39, 95, 255, 0.30)\n}\n\n.ace-dawn .ace_invisible {\n  color: rgba(75, 75, 126, 0.50)\n}\n\n.ace-dawn .ace_keyword,\n.ace-dawn .ace_meta {\n  color: #794938\n}\n\n.ace-dawn .ace_constant,\n.ace-dawn .ace_constant.ace_character,\n.ace-dawn .ace_constant.ace_character.ace_escape,\n.ace-dawn .ace_constant.ace_other {\n  color: #811F24\n}\n\n.ace-dawn .ace_invalid.ace_illegal {\n  text-decoration: underline;\n  font-style: italic;\n  color: #F8F8F8;\n  background-color: #B52A1D\n}\n\n.ace-dawn .ace_invalid.ace_deprecated {\n  text-decoration: underline;\n  font-style: italic;\n  color: #B52A1D\n}\n\n.ace-dawn .ace_support {\n  color: #691C97\n}\n\n.ace-dawn .ace_support.ace_constant {\n  color: #B4371F\n}\n\n.ace-dawn .ace_fold {\n  background-color: #794938;\n  border-color: #080808\n}\n\n.ace-dawn .ace_list,\n.ace-dawn .ace_markup.ace_list,\n.ace-dawn .ace_support.ace_function {\n  color: #693A17\n}\n\n.ace-dawn .ace_storage {\n  font-style: italic;\n  color: #A71D5D\n}\n\n.ace-dawn .ace_string {\n  color: #0B6125\n}\n\n.ace-dawn .ace_string.ace_regexp {\n  color: #CF5628\n}\n\n.ace-dawn .ace_comment {\n  font-style: italic;\n  color: #5A525F\n}\n\n.ace-dawn .ace_heading,\n.ace-dawn .ace_markup.ace_heading {\n  color: #19356D\n}\n\n.ace-dawn .ace_variable {\n  color: #234A97\n}\n\n.ace-dawn .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-dawn .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/dawn.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-dawn\";\nexports.cssText = require(\"./dawn-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/dracula-css.js",
    "content": "module.exports = `/*\n * Copyright © 2017 Zeno Rocha <hi@zenorocha.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n.ace-dracula .ace_gutter {\n  background: #282a36;\n  color: rgb(144,145,148)\n}\n\n.ace-dracula .ace_print-margin {\n  width: 1px;\n  background: #44475a\n}\n\n.ace-dracula {\n  background-color: #282a36;\n  color: #f8f8f2\n}\n\n.ace-dracula .ace_cursor {\n  color: #f8f8f0\n}\n\n.ace-dracula .ace_marker-layer .ace_selection {\n  background: #44475a\n}\n\n.ace-dracula.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #282a36;\n  border-radius: 2px\n}\n\n.ace-dracula .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174)\n}\n\n.ace-dracula .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #a29709\n}\n\n.ace-dracula .ace_marker-layer .ace_active-line {\n  background: #44475a\n}\n\n.ace-dracula .ace_gutter-active-line {\n  background-color: #44475a\n}\n\n.ace-dracula .ace_marker-layer .ace_selected-word {\n  box-shadow: 0px 0px 0px 1px #a29709;\n  border-radius: 3px;\n}\n\n.ace-dracula .ace_fold {\n  background-color: #50fa7b;\n  border-color: #f8f8f2\n}\n\n.ace-dracula .ace_keyword {\n  color: #ff79c6\n}\n\n.ace-dracula .ace_constant.ace_language {\n  color: #bd93f9\n}\n\n.ace-dracula .ace_constant.ace_numeric {\n  color: #bd93f9\n}\n\n.ace-dracula .ace_constant.ace_character {\n  color: #bd93f9\n}\n\n.ace-dracula .ace_constant.ace_character.ace_escape {\n  color: #ff79c6\n}\n\n.ace-dracula .ace_constant.ace_other {\n  color: #bd93f9\n}\n\n.ace-dracula .ace_support.ace_function {\n  color: #8be9fd\n}\n\n.ace-dracula .ace_support.ace_constant {\n  color: #6be5fd\n}\n\n.ace-dracula .ace_support.ace_class {\n  font-style: italic;\n  color: #66d9ef\n}\n\n.ace-dracula .ace_support.ace_type {\n  font-style: italic;\n  color: #66d9ef\n}\n\n.ace-dracula .ace_storage {\n  color: #ff79c6\n}\n\n.ace-dracula .ace_storage.ace_type {\n  font-style: italic;\n  color: #8be9fd\n}\n\n.ace-dracula .ace_invalid {\n  color: #F8F8F0;\n  background-color: #ff79c6\n}\n\n.ace-dracula .ace_invalid.ace_deprecated {\n  color: #F8F8F0;\n  background-color: #bd93f9\n}\n\n.ace-dracula .ace_string {\n  color: #f1fa8c\n}\n\n.ace-dracula .ace_comment {\n  color: #6272a4\n}\n\n.ace-dracula .ace_variable {\n  color: #50fa7b\n}\n\n.ace-dracula .ace_variable.ace_parameter {\n  font-style: italic;\n  color: #ffb86c\n}\n\n.ace-dracula .ace_entity.ace_other.ace_attribute-name {\n  color: #50fa7b\n}\n\n.ace-dracula .ace_entity.ace_name.ace_function {\n  color: #50fa7b\n}\n\n.ace-dracula .ace_entity.ace_name.ace_tag {\n  color: #ff79c6\n}\n.ace-dracula .ace_invisible {\n  color: #626680;\n}\n\n.ace-dracula .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-dracula .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACAQMAAACjTyRkAAAABlBMVEUAAADCwsK76u2xAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjYGBoAAAAhACBGFbxzQAAAABJRU5ErkJggg==\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/dracula.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-dracula\";\nexports.cssText = require(\"./dracula-css\");\nexports.$selectionColorConflict = true;\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/dreamweaver-css.js",
    "content": "module.exports = `.ace-dreamweaver .ace_gutter {\n  background: #e8e8e8;\n  color: #333;\n}\n\n.ace-dreamweaver .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-dreamweaver {\n  background-color: #FFFFFF;\n  color: black;\n}\n\n.ace-dreamweaver .ace_fold {\n    background-color: #757AD8;\n}\n\n.ace-dreamweaver .ace_cursor {\n  color: black;\n}\n        \n.ace-dreamweaver .ace_invisible {\n  color: rgb(191, 191, 191);\n}\n\n.ace-dreamweaver .ace_storage,\n.ace-dreamweaver .ace_keyword {\n  color: blue;\n}\n\n.ace-dreamweaver .ace_constant.ace_buildin {\n  color: rgb(88, 72, 246);\n}\n\n.ace-dreamweaver .ace_constant.ace_language {\n  color: rgb(88, 92, 246);\n}\n\n.ace-dreamweaver .ace_constant.ace_library {\n  color: rgb(6, 150, 14);\n}\n\n.ace-dreamweaver .ace_invalid {\n  background-color: rgb(153, 0, 0);\n  color: white;\n}\n\n.ace-dreamweaver .ace_support.ace_function {\n  color: rgb(60, 76, 114);\n}\n\n.ace-dreamweaver .ace_support.ace_constant {\n  color: rgb(6, 150, 14);\n}\n\n.ace-dreamweaver .ace_support.ace_type,\n.ace-dreamweaver .ace_support.ace_class {\n  color: #009;\n}\n\n.ace-dreamweaver .ace_support.ace_php_tag {\n  color: #f00;\n}\n\n.ace-dreamweaver .ace_keyword.ace_operator {\n  color: rgb(104, 118, 135);\n}\n\n.ace-dreamweaver .ace_string {\n  color: #00F;\n}\n\n.ace-dreamweaver .ace_comment {\n  color: rgb(76, 136, 107);\n}\n\n.ace-dreamweaver .ace_comment.ace_doc {\n  color: rgb(0, 102, 255);\n}\n\n.ace-dreamweaver .ace_comment.ace_doc.ace_tag {\n  color: rgb(128, 159, 191);\n}\n\n.ace-dreamweaver .ace_constant.ace_numeric {\n  color: rgb(0, 0, 205);\n}\n\n.ace-dreamweaver .ace_variable {\n  color: #06F\n}\n\n.ace-dreamweaver .ace_xml-pe {\n  color: rgb(104, 104, 91);\n}\n\n.ace-dreamweaver .ace_entity.ace_name.ace_function {\n  color: #00F;\n}\n\n\n.ace-dreamweaver .ace_heading {\n  color: rgb(12, 7, 255);\n}\n\n.ace-dreamweaver .ace_list {\n  color:rgb(185, 6, 144);\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_step {\n  background: rgb(252, 255, 0);\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_stack {\n  background: rgb(164, 229, 101);\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_active-line {\n  background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-dreamweaver .ace_gutter-active-line {\n  background-color : #DCDCDC;\n}\n\n.ace-dreamweaver .ace_marker-layer .ace_selected-word {\n  background: rgb(250, 250, 255);\n  border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-dreamweaver .ace_meta.ace_tag {\n  color:#009;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_anchor {\n  color:#060;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_form {\n  color:#F90;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_image {\n  color:#909;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_script {\n  color:#900;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_style {\n  color:#909;\n}\n\n.ace-dreamweaver .ace_meta.ace_tag.ace_table {\n  color:#099;\n}\n\n.ace-dreamweaver .ace_string.ace_regex {\n  color: rgb(255, 0, 0)\n}\n\n.ace-dreamweaver .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-dreamweaver .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/dreamweaver.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-dreamweaver\";\nexports.cssText = require(\"./dreamweaver-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/eclipse-css.js",
    "content": "module.exports = `.ace-eclipse .ace_gutter {\n  background: #ebebeb;\n  border-right: 1px solid rgb(159, 159, 159);\n  color: rgb(136, 136, 136);\n}\n\n.ace-eclipse .ace_print-margin {\n  width: 1px;\n  background: #ebebeb;\n}\n\n.ace-eclipse {\n  background-color: #FFFFFF;\n  color: black;\n}\n\n.ace-eclipse .ace_fold {\n    background-color: rgb(60, 76, 114);\n}\n\n.ace-eclipse .ace_cursor {\n  color: black;\n}\n\n.ace-eclipse .ace_storage,\n.ace-eclipse .ace_keyword,\n.ace-eclipse .ace_variable {\n  color: rgb(127, 0, 85);\n}\n\n.ace-eclipse .ace_constant.ace_buildin {\n  color: rgb(88, 72, 246);\n}\n\n.ace-eclipse .ace_constant.ace_library {\n  color: rgb(6, 150, 14);\n}\n\n.ace-eclipse .ace_function {\n  color: rgb(60, 76, 114);\n}\n\n.ace-eclipse .ace_string {\n  color: rgb(42, 0, 255);\n}\n\n.ace-eclipse .ace_comment {\n  color: rgb(113, 150, 130);\n}\n\n.ace-eclipse .ace_comment.ace_doc {\n  color: rgb(63, 95, 191);\n}\n\n.ace-eclipse .ace_comment.ace_doc.ace_tag {\n  color: rgb(127, 159, 191);\n}\n\n.ace-eclipse .ace_constant.ace_numeric {\n  color: darkblue;\n}\n\n.ace-eclipse .ace_tag {\n  color: rgb(25, 118, 116);\n}\n\n.ace-eclipse .ace_type {\n  color: rgb(127, 0, 127);\n}\n\n.ace-eclipse .ace_xml-pe {\n  color: rgb(104, 104, 91);\n}\n\n.ace-eclipse .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n\n.ace-eclipse .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-eclipse .ace_meta.ace_tag {\n  color:rgb(25, 118, 116);\n}\n\n.ace-eclipse .ace_invisible {\n  color: #ddd;\n}\n\n.ace-eclipse .ace_entity.ace_other.ace_attribute-name {\n  color:rgb(127, 0, 127);\n}\n.ace-eclipse .ace_marker-layer .ace_step {\n  background: rgb(255, 255, 0);\n}\n\n.ace-eclipse .ace_active-line {\n  background: rgb(232, 242, 254);\n}\n\n.ace-eclipse .ace_gutter-active-line {\n  background-color : #DADADA;\n}\n\n.ace-eclipse .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgb(181, 213, 255);\n}\n\n.ace-eclipse .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-eclipse .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/eclipse.js",
    "content": "\"use strict\";\n\nexports.isDark = false;\nexports.cssText = require(\"./eclipse-css\");\n\nexports.cssClass = \"ace-eclipse\";\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/github-css.js",
    "content": "module.exports = `/* CSS style content from github's default pygments highlighter template.\n   Cursor and selection styles from textmate.css. */\n.ace-github .ace_gutter {\n  background: #e8e8e8;\n  color: #AAA;\n}\n\n.ace-github  {\n  background: #fff;\n  color: #000;\n}\n\n.ace-github .ace_keyword {\n  font-weight: bold;\n}\n\n.ace-github .ace_string {\n  color: #D14;\n}\n\n.ace-github .ace_variable.ace_class {\n  color: teal;\n}\n\n.ace-github .ace_constant.ace_numeric {\n  color: #099;\n}\n\n.ace-github .ace_constant.ace_buildin {\n  color: #0086B3;\n}\n\n.ace-github .ace_support.ace_function {\n  color: #0086B3;\n}\n\n.ace-github .ace_comment {\n  color: #998;\n  font-style: italic;\n}\n\n.ace-github .ace_variable.ace_language  {\n  color: #0086B3;\n}\n\n.ace-github .ace_paren {\n  font-weight: bold;\n}\n\n.ace-github .ace_boolean {\n  font-weight: bold;\n}\n\n.ace-github .ace_string.ace_regexp {\n  color: #009926;\n  font-weight: normal;\n}\n\n.ace-github .ace_variable.ace_instance {\n  color: teal;\n}\n\n.ace-github .ace_constant.ace_language {\n  font-weight: bold;\n}\n\n.ace-github .ace_cursor {\n  color: black;\n}\n\n.ace-github.ace_focus .ace_marker-layer .ace_active-line {\n  background: rgb(255, 255, 204);\n}\n.ace-github .ace_marker-layer .ace_active-line {\n  background: rgb(245, 245, 245);\n}\n\n.ace-github .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n\n.ace-github.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px white;\n}\n/* bold keywords cause cursor issues for some fonts */\n/* this disables bold style for editor and keeps for static highlighter */\n.ace-github.ace_nobold .ace_line > span {\n    font-weight: normal !important;\n}\n\n.ace-github .ace_marker-layer .ace_step {\n  background: rgb(252, 255, 0);\n}\n\n.ace-github .ace_marker-layer .ace_stack {\n  background: rgb(164, 229, 101);\n}\n\n.ace-github .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-github .ace_gutter-active-line {\n    background-color : rgba(0, 0, 0, 0.07);\n}\n\n.ace-github .ace_marker-layer .ace_selected-word {\n  background: rgb(250, 250, 255);\n  border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-github .ace_invisible {\n  color: #BFBFBF\n}\n\n.ace-github .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-github .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-github .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/github.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-github\";\nexports.cssText = require(\"./github-css\");\n\n    var dom = require(\"../lib/dom\");\n    dom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/github_dark-css.js",
    "content": "module.exports = `.ace-github-dark .ace_gutter {\n  background: #24292e;\n  color: #7388b5\n}\n\n.ace-github-dark .ace_print-margin {\n  width: 1px;\n  background: #00204b\n}\n\n.ace-github-dark {\n  background-color: #24292e;\n  color: #FFFFFF\n}\n\n.ace-github-dark .ace_constant.ace_other,\n.ace-github-dark .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-github-dark .ace_marker-layer .ace_selection {\n  background: #003F8E\n}\n\n.ace-github-dark.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #24292e;\n}\n\n.ace-github-dark .ace_marker-layer .ace_step {\n  background: rgb(127, 111, 19)\n}\n\n.ace-github-dark .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404F7D\n}\n\n.ace-github-dark .ace_marker-layer .ace_active-line {\n  background: #00346E\n}\n\n.ace-github-dark .ace_gutter-active-line {\n  background-color: #24292e\n}\n\n.ace-github-dark .ace_marker-layer .ace_selected-word {\n  border: 1px solid #003F8E\n}\n\n.ace-github-dark .ace_invisible {\n  color: #404F7D\n}\n\n.ace-github-dark .ace_keyword,\n.ace-github-dark .ace_meta,\n.ace-github-dark .ace_storage,\n.ace-github-dark .ace_storage.ace_type,\n.ace-github-dark .ace_support.ace_type {\n  color: #ff7b72\n}\n\n.ace-github-dark .ace_keyword.ace_operator {\n  color: #79c0ff\n}\n\n.ace-github-dark .ace_constant.ace_character,\n.ace-github-dark .ace_constant.ace_language,\n.ace-github-dark .ace_constant.ace_numeric,\n.ace-github-dark .ace_keyword.ace_other.ace_unit,\n.ace-github-dark .ace_support.ace_constant,\n.ace-github-dark .ace_variable.ace_parameter {\n  color: #FFC58F\n}\n\n.ace-github-dark .ace_invalid {\n  color: #FFFFFF;\n  background-color: #F99DA5\n}\n\n.ace-github-dark .ace_invalid.ace_deprecated {\n  color: #FFFFFF;\n  background-color: #ff7b72\n}\n\n.ace-github-dark .ace_fold {\n  background-color: #BBDAFF;\n  border-color: #FFFFFF\n}\n\n.ace-github-dark .ace_entity.ace_name.ace_function,\n.ace-github-dark .ace_support.ace_function,\n.ace-github-dark .ace_variable {\n  color: #BBDAFF\n}\n\n.ace-github-dark .ace_support.ace_class,\n.ace-github-dark .ace_support.ace_type {\n  color: #FFEEAD\n}\n\n.ace-github-dark .ace_heading,\n.ace-github-dark .ace_markup.ace_heading,\n.ace-github-dark .ace_string {\n  color: #9fcef6\n}\n\n.ace-github-dark .ace_entity.ace_name.ace_tag,\n.ace-github-dark .ace_entity.ace_other.ace_attribute-name,\n.ace-github-dark .ace_meta.ace_tag,\n.ace-github-dark .ace_string.ace_regexp,\n.ace-github-dark .ace_variable {\n  color: #FF9DA4\n}\n\n.ace-github-dark .ace_comment {\n  color: #7285B7\n}\n\n.ace-github-dark .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-github-dark .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n\n.ace-github-dark .ace_constant.ace_buildin {\n  color: #0086B3;\n}\n\n.ace-github-dark .ace_variable.ace_language {\n  color: #ffffff;\n}\n  `;\n"
  },
  {
    "path": "src/theme/github_dark.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-github-dark\";\nexports.cssText = require(\"./github_dark-css\");\n\n    var dom = require(\"../lib/dom\");\n    dom.importCssString(exports.cssText, exports.cssClass, false);\n\n"
  },
  {
    "path": "src/theme/github_light_default-css.js",
    "content": "module.exports = `.ace-github-light-default .ace_gutter {\n    background: #ffffff;\n    color: rgba(27, 31, 35, 0.3);\n}\n\n.ace-github-light-default .ace_print-margin {\n    width: 1px;\n    background: #e8e8e8;\n}\n\n.ace-github-light-default {\n    background-color: #FFFFFF;\n    color: #24292E;\n}\n\n.ace-github-light-default .ace_cursor {\n    color: #044289;\n    background: none;\n}\n\n.ace-github-light-default .ace_marker-layer .ace_selection {\n    background: rgba(3, 102, 214, 0.14);\n}\n\n.ace-github-light-default.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0px #FFFFFF;\n    border-radius: 2px;\n}\n\n.ace-github-light-default .ace_marker-layer .ace_step {\n    background: rgb(198, 219, 174);\n}\n\n.ace-github-light-default .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid rgba(52, 208, 88, 0);\n    background: rgba(52, 208, 88, 0.25);\n}\n\n.ace-github-light-default .ace_marker-layer .ace_active-line {\n    background: #f6f8fa;\n    border: 2px solid #eeeeee;\n}\n\n.ace-github-light-default .ace_gutter-active-line {\n    background-color: #f6f8fa;\n    color: #24292e\n}\n\n.ace-github-light-default .ace_marker-layer .ace_selected-word {\n    border: 1px solid rgba(3, 102, 214, 0.14);\n}\n\n.ace-github-light-default .ace_fold {\n    background-color: #D73A49;\n    border-color: #24292E;\n}\n\n.ace_tooltip.ace-github-light-default {\n    background-color: #f6f8fa !important;\n    color: #444d56 !important;\n    border: 1px solid #444d56\n}\n\n.ace-github-light-default .language_highlight_error {\n    border-bottom: dotted 1px #cb2431;\n    background: none;\n}\n\n.ace-github-light-default .language_highlight_warning {\n    border-bottom: solid 1px #f9c513;\n    background: none;\n}\n\n.ace-github-light-default .language_highlight_info {\n    border-bottom: dotted 1px #1a85ff;\n    background: none;\n}\n\n.ace-github-light-default .ace_keyword {\n    color: #D73A49;\n}\n\n.ace-github-light-default .ace_constant {\n    color: #005CC5;\n}\n\n.ace-github-light-default .ace_support {\n    color: #005CC5;\n}\n\n.ace-github-light-default .ace_support.ace_constant {\n    color: #005CC5;\n}\n\n.ace-github-light-default .ace_support.ace_type {\n    color: #D73A49;\n}\n\n.ace-github-light-default .ace_storage {\n    color: #D73A49;\n}\n\n.ace-github-light-default .ace_storage.ace_type {\n    color: #D73A49;\n}\n\n.ace-github-light-default .ace_invalid.ace_illegal {\n    font-style: italic;\n    color: #B31D28;\n}\n\n.ace-github-light-default .ace_invalid.ace_deprecated {\n    font-style: italic;\n    color: #B31D28;\n}\n\n.ace-github-light-default .ace_string {\n    color: #032F62;\n}\n\n.ace-github-light-default .ace_string.ace_regexp {\n    color: #032F62;\n}\n\n.ace-github-light-default .ace_comment {\n    color: #6A737D;\n}\n\n.ace-github-light-default .ace_variable {\n    color: #E36209;\n}\n\n.ace-github-light-default .ace_variable.ace_language {\n    color: #005CC5;\n}\n\n.ace-github-light-default .ace_entity.ace_name {\n    color: #6F42C1;\n}\n\n.ace-github-light-default .ace_entity {\n    color: #6F42C1;\n}\n\n.ace-github-light-default .ace_entity.ace_name.ace_tag {\n    color: #22863A;\n}\n\n.ace-github-light-default .ace_meta.ace_tag {\n    color: #22863A;\n}\n\n.ace-github-light-default .ace_markup.ace_heading {\n    color: #005CC5;\n}\n\n.ace-github-light-default .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-github-light-default .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/github_light_default.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-github-light-default\";\nexports.cssText = require(\"./github_light_default-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/gob-css.js",
    "content": "module.exports = `.ace-gob .ace_gutter {\n  background: #0B1818;\n  color: #03EE03\n}\n\n.ace-gob .ace_print-margin {\n  width: 1px;\n  background: #131313\n}\n\n.ace-gob {\n  background-color: #0B0B0B;\n  color: #00FF00\n}\n\n.ace-gob .ace_cursor {\n  border-color: rgba(16, 248, 255, 0.90);\n  background-color: rgba(16, 240, 248, 0.70);\n  opacity: 0.4;\n}\n\n.ace-gob .ace_marker-layer .ace_selection {\n  background: rgba(221, 240, 255, 0.20)\n}\n\n.ace-gob.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #141414;\n}\n\n.ace-gob .ace_marker-layer .ace_step {\n  background: rgb(16, 128, 0)\n}\n\n.ace-gob .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(64, 255, 255, 0.25)\n}\n\n.ace-gob .ace_marker-layer .ace_active-line {\n  background: rgba(255, 255, 255, 0.04)\n}\n\n.ace-gob .ace_gutter-active-line {\n  background-color: rgba(255, 255, 255, 0.04)\n}\n\n.ace-gob .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(192, 240, 255, 0.20)\n}\n\n.ace-gob .ace_invisible {\n  color: rgba(255, 255, 255, 0.25)\n}\n\n.ace-gob .ace_keyword,\n.ace-gob .ace_meta {\n  color: #10D8E8\n}\n\n.ace-gob .ace_constant,\n.ace-gob .ace_constant.ace_character,\n.ace-gob .ace_constant.ace_character.ace_escape,\n.ace-gob .ace_constant.ace_other,\n.ace-gob .ace_heading,\n.ace-gob .ace_markup.ace_heading,\n.ace-gob .ace_support.ace_constant {\n  color: #10F0A0\n}\n\n.ace-gob .ace_invalid.ace_illegal {\n  color: #F8F8F8;\n  background-color: rgba(86, 45, 86, 0.75)\n}\n\n.ace-gob .ace_invalid.ace_deprecated {\n  text-decoration: underline;\n  font-style: italic;\n  color: #20F8C0\n}\n\n.ace-gob .ace_support {\n  color: #20E8B0\n}\n\n.ace-gob .ace_fold {\n  background-color: #50B8B8;\n  border-color: #70F8F8\n}\n\n.ace-gob .ace_support.ace_function {\n  color: #00F800\n}\n\n.ace-gob .ace_list,\n.ace-gob .ace_markup.ace_list,\n.ace-gob .ace_storage {\n  color: #10FF98\n}\n\n.ace-gob .ace_entity.ace_name.ace_function,\n.ace-gob .ace_meta.ace_tag,\n.ace-gob .ace_variable {\n  color: #00F868\n}\n\n.ace-gob .ace_string {\n  color: #10F060\n}\n\n.ace-gob .ace_string.ace_regexp {\n  color: #20F090;\n}\n\n.ace-gob .ace_comment {\n  font-style: italic;\n  color: #00E060;\n}\n\n.ace-gob .ace_variable {\n  color: #00F888;\n}\n\n.ace-gob .ace_xml-pe {\n  color: #488858;\n}\n\n.ace-gob .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-gob .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/gob.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-gob\";\nexports.cssText = require(\"./gob-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/gruvbox-css.js",
    "content": "module.exports = `.ace-gruvbox .ace_gutter-active-line {\n  background-color: #3C3836;\n}\n\n.ace-gruvbox {\n  color: #EBDAB4;\n  background-color: #1D2021;\n}\n\n.ace-gruvbox .ace_invisible {\n  color: #504945;\n}\n\n.ace-gruvbox .ace_marker-layer .ace_selection {\n  background: rgba(179, 101, 57, 0.75)\n}\n\n.ace-gruvbox.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #002240;\n}\n\n.ace-gruvbox .ace_keyword {\n  color: #8ec07c;\n}\n\n.ace-gruvbox .ace_comment {\n  font-style: italic;\n  color: #928375;\n}\n\n.ace-gruvbox .ace-statement {\n  color: red;\n}\n\n.ace-gruvbox .ace_variable {\n  color: #84A598;\n}\n\n.ace-gruvbox .ace_variable.ace_language {\n  color: #D2879B;\n}\n\n.ace-gruvbox .ace_constant {\n  color: #C2859A;\n}\n\n.ace-gruvbox .ace_constant.ace_language {\n  color: #C2859A;\n}\n\n.ace-gruvbox .ace_constant.ace_numeric {\n  color: #C2859A;\n}\n\n.ace-gruvbox .ace_string {\n  color: #B8BA37;\n}\n\n.ace-gruvbox .ace_support {\n  color: #F9BC41;\n}\n\n.ace-gruvbox .ace_support.ace_function {\n  color: #F84B3C;\n}\n\n.ace-gruvbox .ace_storage {\n  color: #8FBF7F;\n}\n\n.ace-gruvbox .ace_keyword.ace_operator {\n  color: #EBDAB4;\n}\n\n.ace-gruvbox .ace_punctuation.ace_operator {\n  color: yellow;\n}\n\n.ace-gruvbox .ace_marker-layer .ace_active-line {\n  background: #3C3836;\n}\n\n.ace-gruvbox .ace_marker-layer .ace_selected-word {\n  border-radius: 4px;\n  border: 8px solid #3f475d;\n}\n\n.ace-gruvbox .ace_print-margin {\n  width: 5px;\n  background: #3C3836;\n}\n\n.ace-gruvbox .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC\") right repeat-y;\n}\n\n.ace-gruvbox .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/gruvbox.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-gruvbox\";\nexports.cssText = require(\"./gruvbox-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/gruvbox_dark_hard-css.js",
    "content": "module.exports = `.ace-gruvbox-dark-hard .ace_gutter {\n  background: #1d2021;\n  color: rgb(132,126,106)\n}\n\n.ace-gruvbox-dark-hard .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-gruvbox-dark-hard {\n  background-color: #1d2021;\n  color: rgba(235, 219, 178, 0.50)\n}\n\n.ace-gruvbox-dark-hard .ace_cursor {\n  color: #a89984\n}\n\n.ace-gruvbox-dark-hard .ace_marker-layer .ace_selection {\n  background: #3c3836\n}\n\n.ace-gruvbox-dark-hard.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #1d2021;\n  border-radius: 2px\n}\n\n.ace-gruvbox-dark-hard .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174)\n}\n\n.ace-gruvbox-dark-hard .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(235, 219, 178, 0.15)\n}\n\n.ace-gruvbox-dark-hard .ace_marker-layer .ace_active-line {\n  background: #3c3836\n}\n\n.ace-gruvbox-dark-hard .ace_gutter-active-line {\n  background-color: #3c3836\n}\n\n.ace-gruvbox-dark-hard .ace_marker-layer .ace_selected-word {\n  border: 1px solid #3c3836\n}\n\n.ace-gruvbox-dark-hard .ace_fold {\n  background-color: #b8bb26;\n  border-color: rgba(235, 219, 178, 0.50)\n}\n\n.ace-gruvbox-dark-hard .ace_keyword {\n  color: #fb4934\n}\n\n.ace-gruvbox-dark-hard .ace_keyword.ace_operator {\n  color: #8ec07c\n}\n\n.ace-gruvbox-dark-hard .ace_keyword.ace_other.ace_unit {\n  color: #b16286\n}\n\n.ace-gruvbox-dark-hard .ace_constant {\n  color: #d3869b\n}\n\n.ace-gruvbox-dark-hard .ace_constant.ace_numeric {\n  color: #d3869b\n}\n\n.ace-gruvbox-dark-hard .ace_constant.ace_character.ace_escape {\n  color: #fb4934\n}\n\n.ace-gruvbox-dark-hard .ace_constant.ace_other {\n  color: #d3869b\n}\n\n.ace-gruvbox-dark-hard .ace_support.ace_function {\n  color: #8ec07c\n}\n\n.ace-gruvbox-dark-hard .ace_support.ace_constant {\n  color: #d3869b\n}\n\n.ace-gruvbox-dark-hard .ace_support.ace_constant.ace_property-value {\n  color: #f9f5d7\n}\n\n.ace-gruvbox-dark-hard .ace_support.ace_class {\n  color: #fabd2f\n}\n\n.ace-gruvbox-dark-hard .ace_support.ace_type {\n  color: #fabd2f\n}\n\n.ace-gruvbox-dark-hard .ace_storage {\n  color: #fb4934\n}\n\n.ace-gruvbox-dark-hard .ace_invalid {\n  color: #f9f5d7;\n  background-color: #fb4934\n}\n\n.ace-gruvbox-dark-hard .ace_string {\n  color: #b8bb26\n}\n\n.ace-gruvbox-dark-hard .ace_string.ace_regexp {\n  color: #b8bb26\n}\n\n.ace-gruvbox-dark-hard .ace_comment {\n  font-style: italic;\n  color: #928374\n}\n\n.ace-gruvbox-dark-hard .ace_variable {\n  color: #83a598\n}\n\n.ace-gruvbox-dark-hard .ace_variable.ace_language {\n  color: #d3869b\n}\n\n.ace-gruvbox-dark-hard .ace_variable.ace_parameter {\n  color: #f9f5d7\n}\n\n.ace-gruvbox-dark-hard .ace_meta.ace_tag {\n  color: #f9f5d7\n}\n\n.ace-gruvbox-dark-hard .ace_entity.ace_other.ace_attribute-name {\n  color: #fabd2f\n}\n\n.ace-gruvbox-dark-hard .ace_entity.ace_name.ace_function {\n  color: #b8bb26\n}\n\n.ace-gruvbox-dark-hard .ace_entity.ace_name.ace_tag {\n  color: #83a598\n}\n\n.ace-gruvbox-dark-hard .ace_markup.ace_heading {\n  color: #b8bb26\n}\n\n.ace-gruvbox-dark-hard .ace_markup.ace_list {\n  color: #83a598\n}\n\n.ace-gruvbox-dark-hard .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/gruvbox_dark_hard.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-gruvbox-dark-hard\";\nexports.cssText = require(\"./gruvbox_dark_hard-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/gruvbox_light_hard-css.js",
    "content": "module.exports = `.ace-gruvbox-light-hard .ace_gutter {\n  background: #f9f5d7;\n  color: rgb(155,151,135)\n}\n\n.ace-gruvbox-light-hard .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-gruvbox-light-hard {\n  background-color: #f9f5d7;\n  color: rgba(60, 56, 54, 0.50)\n}\n\n.ace-gruvbox-light-hard .ace_cursor {\n  color: #7c6f64\n}\n\n.ace-gruvbox-light-hard .ace_marker-layer .ace_selection {\n  background: #ebdbb2\n}\n\n.ace-gruvbox-light-hard.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #f9f5d7;\n  border-radius: 2px\n}\n\n.ace-gruvbox-light-hard .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174)\n}\n\n.ace-gruvbox-light-hard .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(60, 56, 54, 0.15)\n}\n\n.ace-gruvbox-light-hard .ace_marker-layer .ace_active-line {\n  background: #ebdbb2\n}\n\n.ace-gruvbox-light-hard .ace_gutter-active-line {\n  background-color: #ebdbb2\n}\n\n.ace-gruvbox-light-hard .ace_marker-layer .ace_selected-word {\n  border: 1px solid #ebdbb2\n}\n\n.ace-gruvbox-light-hard .ace_fold {\n  background-color: #79740e;\n  border-color: rgba(60, 56, 54, 0.50)\n}\n\n.ace-gruvbox-light-hard .ace_keyword {\n  color: #9d0006\n}\n\n.ace-gruvbox-light-hard .ace_keyword.ace_operator {\n  color: #427b58\n}\n\n.ace-gruvbox-light-hard .ace_keyword.ace_other.ace_unit {\n  color: #b16286\n}\n\n.ace-gruvbox-light-hard .ace_constant {\n  color: #8f3f71\n}\n\n.ace-gruvbox-light-hard .ace_constant.ace_numeric {\n  color: #8f3f71\n}\n\n.ace-gruvbox-light-hard .ace_constant.ace_character.ace_escape {\n  color: #9d0006\n}\n\n.ace-gruvbox-light-hard .ace_constant.ace_other {\n  color: #8f3f71\n}\n\n.ace-gruvbox-light-hard .ace_support.ace_function {\n  color: #427b58\n}\n\n.ace-gruvbox-light-hard .ace_support.ace_constant {\n  color: #8f3f71\n}\n\n.ace-gruvbox-light-hard .ace_support.ace_constant.ace_property-value {\n  color: #1d2021\n}\n\n.ace-gruvbox-light-hard .ace_support.ace_class {\n  color: #b57614\n}\n\n.ace-gruvbox-light-hard .ace_support.ace_type {\n  color: #b57614\n}\n\n.ace-gruvbox-light-hard .ace_storage {\n  color: #9d0006\n}\n\n.ace-gruvbox-light-hard .ace_invalid {\n  color: #1d2021;\n  background-color: #9d0006\n}\n\n.ace-gruvbox-light-hard .ace_string {\n  color: #79740e\n}\n\n.ace-gruvbox-light-hard .ace_string.ace_regexp {\n  color: #79740e\n}\n\n.ace-gruvbox-light-hard .ace_comment {\n  font-style: italic;\n  color: #928374\n}\n\n.ace-gruvbox-light-hard .ace_variable {\n  color: #076678\n}\n\n.ace-gruvbox-light-hard .ace_variable.ace_language {\n  color: #8f3f71\n}\n\n.ace-gruvbox-light-hard .ace_variable.ace_parameter {\n  color: #1d2021\n}\n\n.ace-gruvbox-light-hard .ace_meta.ace_tag {\n  color: #1d2021\n}\n\n.ace-gruvbox-light-hard .ace_entity.ace_other.ace_attribute-name {\n  color: #b57614\n}\n\n.ace-gruvbox-light-hard .ace_entity.ace_name.ace_function {\n  color: #79740e\n}\n\n.ace-gruvbox-light-hard .ace_entity.ace_name.ace_tag {\n  color: #076678\n}\n\n.ace-gruvbox-light-hard .ace_markup.ace_heading {\n  color: #79740e\n}\n\n.ace-gruvbox-light-hard .ace_markup.ace_list {\n  color: #076678\n}\n\n.ace-gruvbox-light-hard .ace_indent-guide {\n    background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-gruvbox-light-hard .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/gruvbox_light_hard.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-gruvbox-light-hard\";\nexports.cssText = require(\"./gruvbox_light_hard-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/idle_fingers-css.js",
    "content": "module.exports = `.ace-idle-fingers .ace_gutter {\n  background: #3b3b3b;\n  color: rgb(153,153,153)\n}\n\n.ace-idle-fingers .ace_print-margin {\n  width: 1px;\n  background: #3b3b3b\n}\n\n.ace-idle-fingers {\n  background-color: #323232;\n  color: #FFFFFF\n}\n\n.ace-idle-fingers .ace_cursor {\n  color: #91FF00\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_selection {\n  background: rgba(90, 100, 126, 0.88)\n}\n\n.ace-idle-fingers.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #323232;\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404040\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_active-line {\n  background: #353637\n}\n\n.ace-idle-fingers .ace_gutter-active-line {\n  background-color: #353637\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(90, 100, 126, 0.88)\n}\n\n.ace-idle-fingers .ace_invisible {\n  color: #404040\n}\n\n.ace-idle-fingers .ace_keyword,\n.ace-idle-fingers .ace_meta {\n  color: #CC7833\n}\n\n.ace-idle-fingers .ace_constant,\n.ace-idle-fingers .ace_constant.ace_character,\n.ace-idle-fingers .ace_constant.ace_character.ace_escape,\n.ace-idle-fingers .ace_constant.ace_other,\n.ace-idle-fingers .ace_support.ace_constant {\n  color: #6C99BB\n}\n\n.ace-idle-fingers .ace_invalid {\n  color: #FFFFFF;\n  background-color: #FF0000\n}\n\n.ace-idle-fingers .ace_fold {\n  background-color: #CC7833;\n  border-color: #FFFFFF\n}\n\n.ace-idle-fingers .ace_support.ace_function {\n  color: #B83426\n}\n\n.ace-idle-fingers .ace_variable.ace_parameter {\n  font-style: italic\n}\n\n.ace-idle-fingers .ace_string {\n  color: #A5C261\n}\n\n.ace-idle-fingers .ace_string.ace_regexp {\n  color: #CCCC33\n}\n\n.ace-idle-fingers .ace_comment {\n  font-style: italic;\n  color: #BC9458\n}\n\n.ace-idle-fingers .ace_meta.ace_tag {\n  color: #FFE5BB\n}\n\n.ace-idle-fingers .ace_entity.ace_name {\n  color: #FFC66D\n}\n\n.ace-idle-fingers .ace_collab.ace_user1 {\n  color: #323232;\n  background-color: #FFF980\n}\n\n.ace-idle-fingers .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjLyZYiPj/8PAAreAwAI1+g0AAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-idle-fingers .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/idle_fingers.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-idle-fingers\";\nexports.cssText = require(\"./idle_fingers-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/iplastic-css.js",
    "content": "module.exports = `.ace-iplastic .ace_gutter {\n  background: #dddddd;\n  color: #666666\n}\n\n.ace-iplastic .ace_print-margin {\n  width: 1px;\n  background: #bbbbbb\n}\n\n.ace-iplastic {\n  background-color: #eeeeee;\n  color: #333333\n}\n\n.ace-iplastic .ace_cursor {\n  color: #333\n}\n\n.ace-iplastic .ace_marker-layer .ace_selection {\n  background: #BAD6FD;\n}\n\n.ace-iplastic.ace_multiselect .ace_selection.ace_start {\n  border-radius: 4px\n}\n\n.ace-iplastic .ace_marker-layer .ace_step {\n  background: #444444\n}\n\n.ace-iplastic .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #49483E;\n  background: #FFF799\n}\n\n.ace-iplastic .ace_marker-layer .ace_active-line {\n  background: #e5e5e5\n}\n\n.ace-iplastic .ace_gutter-active-line {\n  background-color: #eeeeee\n}\n\n.ace-iplastic .ace_marker-layer .ace_selected-word {\n  border: 1px solid #555555;\n  border-radius:4px\n}\n\n.ace-iplastic .ace_invisible {\n  color: #999999\n}\n\n.ace-iplastic .ace_entity.ace_name.ace_tag,\n.ace-iplastic .ace_keyword,\n.ace-iplastic .ace_meta.ace_tag,\n.ace-iplastic .ace_storage {\n  color: #0000FF\n}\n\n.ace-iplastic .ace_punctuation,\n.ace-iplastic .ace_punctuation.ace_tag {\n  color: #000\n}\n\n.ace-iplastic .ace_constant {\n  color: #333333;\n  font-weight: 700\n}\n\n.ace-iplastic .ace_constant.ace_character,\n.ace-iplastic .ace_constant.ace_language,\n.ace-iplastic .ace_constant.ace_numeric,\n.ace-iplastic .ace_constant.ace_other {\n  color: #0066FF;\n  font-weight: 700\n}\n\n.ace-iplastic .ace_constant.ace_numeric{\n  font-weight: 100\n}\n\n.ace-iplastic .ace_invalid {\n  color: #F8F8F0;\n  background-color: #F92672\n}\n\n.ace-iplastic .ace_invalid.ace_deprecated {\n  color: #F8F8F0;\n  background-color: #AE81FF\n}\n\n.ace-iplastic .ace_support.ace_constant,\n.ace-iplastic .ace_support.ace_function {\n  color: #333333;\n  font-weight: 700\n}\n\n.ace-iplastic .ace_fold {\n  background-color: #464646;\n  border-color: #F8F8F2\n}\n\n.ace-iplastic .ace_storage.ace_type,\n.ace-iplastic .ace_support.ace_class,\n.ace-iplastic .ace_support.ace_type {\n  color: #3333fc;\n  font-weight: 700\n}\n\n.ace-iplastic .ace_entity.ace_name.ace_function,\n.ace-iplastic .ace_entity.ace_other,\n.ace-iplastic .ace_entity.ace_other.ace_attribute-name,\n.ace-iplastic .ace_variable {\n  color: #3366cc;\n  font-style: italic\n}\n\n.ace-iplastic .ace_variable.ace_parameter {\n  font-style: italic;\n  color: #2469E0\n}\n\n.ace-iplastic .ace_string {\n  color: #a55f03\n}\n\n.ace-iplastic .ace_comment {\n  color: #777777;\n  font-style: italic\n}\n\n.ace-iplastic .ace_fold-widget {\n  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==);\n}\n\n.ace-iplastic .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAABlJREFUeNpi+P//PwMzMzPzfwAAAAD//wMAGRsECSML/RIAAAAASUVORK5CYII=) right repeat-y\n}\n\n.ace-iplastic .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/iplastic.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-iplastic\";\nexports.cssText = require(\"./iplastic-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/katzenmilch-css.js",
    "content": "module.exports = `.ace-katzenmilch .ace_gutter,\n/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: ) */\n\n.ace-katzenmilch .ace_gutter {\n  background: #e8e8e8;\n  color: #333\n}\n\n.ace-katzenmilch .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-katzenmilch {\n  background-color: #f3f2f3;\n  color: rgba(15, 0, 9, 1.0)\n}\n\n.ace-katzenmilch .ace_cursor {\n  border-left: 2px solid #100011\n}\n\n.ace-katzenmilch .ace_overwrite-cursors .ace_cursor {\n  border-left: 0px;\n  border-bottom: 1px solid #100011\n}\n\n.ace-katzenmilch .ace_marker-layer .ace_selection {\n  background: rgba(100, 5, 208, 0.27)\n}\n\n.ace-katzenmilch.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #f3f2f3;\n}\n\n.ace-katzenmilch .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174)\n}\n\n.ace-katzenmilch .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(0, 0, 0, 0.33);\n}\n\n.ace-katzenmilch .ace_marker-layer .ace_active-line {\n  background: rgb(232, 242, 254)\n}\n\n.ace-katzenmilch .ace_gutter-active-line {\n  background-color: rgb(232, 242, 254)\n}\n\n.ace-katzenmilch .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(100, 5, 208, 0.27)\n}\n\n.ace-katzenmilch .ace_invisible {\n  color: #BFBFBF\n}\n\n.ace-katzenmilch .ace_fold {\n  background-color: rgba(2, 95, 73, 0.97);\n  border-color: rgba(15, 0, 9, 1.0)\n}\n\n.ace-katzenmilch .ace_keyword {\n  color: #674Aa8;\n  rbackground-color: rgba(163, 170, 216, 0.055)\n}\n\n.ace-katzenmilch .ace_constant.ace_language {\n  color: #7D7e52;\n  rbackground-color: rgba(189, 190, 130, 0.059)\n}\n\n.ace-katzenmilch .ace_constant.ace_numeric {\n  color: rgba(79, 130, 123, 0.93);\n  rbackground-color: rgba(119, 194, 187, 0.059)\n}\n\n.ace-katzenmilch .ace_constant.ace_character,\n.ace-katzenmilch .ace_constant.ace_other {\n  color: rgba(2, 95, 105, 1.0);\n  rbackground-color: rgba(127, 34, 153, 0.063)\n}\n\n.ace-katzenmilch .ace_support.ace_function {\n  color: #9D7e62;\n  rbackground-color: rgba(189, 190, 130, 0.039)\n}\n\n.ace-katzenmilch .ace_support.ace_class {\n  color: rgba(239, 106, 167, 1.0);\n  rbackground-color: rgba(239, 106, 167, 0.063)\n}\n\n.ace-katzenmilch .ace_storage {\n  color: rgba(123, 92, 191, 1.0);\n  rbackground-color: rgba(139, 93, 223, 0.051)\n}\n\n.ace-katzenmilch .ace_invalid {\n  color: #DFDFD5;\n  rbackground-color: #CC1B27\n}\n\n.ace-katzenmilch .ace_string {\n  color: #5a5f9b;\n  rbackground-color: rgba(170, 175, 219, 0.035)\n}\n\n.ace-katzenmilch .ace_comment {\n  font-style: italic;\n  color: rgba(64, 79, 80, 0.67);\n  rbackground-color: rgba(95, 15, 255, 0.0078)\n}\n\n.ace-katzenmilch .ace_entity.ace_name.ace_function,\n.ace-katzenmilch .ace_variable {\n  color: rgba(2, 95, 73, 0.97);\n  rbackground-color: rgba(34, 255, 73, 0.12)\n}\n\n.ace-katzenmilch .ace_variable.ace_language {\n  color: #316fcf;\n  rbackground-color: rgba(58, 175, 255, 0.039)\n}\n\n.ace-katzenmilch .ace_variable.ace_parameter {\n  font-style: italic;\n  color: rgba(51, 150, 159, 0.87);\n  rbackground-color: rgba(5, 214, 249, 0.043)\n}\n\n.ace-katzenmilch .ace_entity.ace_other.ace_attribute-name {\n  color: rgba(73, 70, 194, 0.93);\n  rbackground-color: rgba(73, 134, 194, 0.035)\n}\n\n.ace-katzenmilch .ace_entity.ace_name.ace_tag {\n  color: #3976a2;\n  rbackground-color: rgba(73, 166, 210, 0.039)\n}\n\n.ace-katzenmilch .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-katzenmilch .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/katzenmilch.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-katzenmilch\";\nexports.cssText = require(\"./katzenmilch-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/kr_theme-css.js",
    "content": "module.exports = `.ace-kr-theme .ace_gutter {\n  background: #1c1917;\n  color: #FCFFE0\n}\n\n.ace-kr-theme .ace_print-margin {\n  width: 1px;\n  background: #1c1917\n}\n\n.ace-kr-theme {\n  background-color: #0B0A09;\n  color: #FCFFE0\n}\n\n.ace-kr-theme .ace_cursor {\n  color: #FF9900\n}\n\n.ace-kr-theme .ace_marker-layer .ace_selection {\n  background: rgba(170, 0, 255, 0.45)\n}\n\n.ace-kr-theme.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #0B0A09;\n}\n\n.ace-kr-theme .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-kr-theme .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(255, 177, 111, 0.32)\n}\n\n.ace-kr-theme .ace_marker-layer .ace_active-line {\n  background: #38403D\n}\n\n.ace-kr-theme .ace_gutter-active-line {\n  background-color : #38403D\n}\n\n.ace-kr-theme .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(170, 0, 255, 0.45)\n}\n\n.ace-kr-theme .ace_invisible {\n  color: rgba(255, 177, 111, 0.32)\n}\n\n.ace-kr-theme .ace_keyword,\n.ace-kr-theme .ace_meta {\n  color: #949C8B\n}\n\n.ace-kr-theme .ace_constant,\n.ace-kr-theme .ace_constant.ace_character,\n.ace-kr-theme .ace_constant.ace_character.ace_escape,\n.ace-kr-theme .ace_constant.ace_other {\n  color: rgba(210, 117, 24, 0.76)\n}\n\n.ace-kr-theme .ace_invalid {\n  color: #F8F8F8;\n  background-color: #A41300\n}\n\n.ace-kr-theme .ace_support {\n  color: #9FC28A\n}\n\n.ace-kr-theme .ace_support.ace_constant {\n  color: #C27E66\n}\n\n.ace-kr-theme .ace_fold {\n  background-color: #949C8B;\n  border-color: #FCFFE0\n}\n\n.ace-kr-theme .ace_support.ace_function {\n  color: #85873A\n}\n\n.ace-kr-theme .ace_storage {\n  color: #FFEE80\n}\n\n.ace-kr-theme .ace_string {\n  color: rgba(164, 161, 181, 0.8)\n}\n\n.ace-kr-theme .ace_string.ace_regexp {\n  color: rgba(125, 255, 192, 0.65)\n}\n\n.ace-kr-theme .ace_comment {\n  font-style: italic;\n  color: #706D5B\n}\n\n.ace-kr-theme .ace_variable {\n  color: #D1A796\n}\n\n.ace-kr-theme .ace_list,\n.ace-kr-theme .ace_markup.ace_list {\n  background-color: #0F0040\n}\n\n.ace-kr-theme .ace_variable.ace_language {\n  color: #FF80E1\n}\n\n.ace-kr-theme .ace_meta.ace_tag {\n  color: #BABD9C\n}\n\n.ace-kr-theme .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-kr-theme .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/kr_theme.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-kr-theme\";\nexports.cssText = require(\"./kr_theme-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/kuroir-css.js",
    "content": "module.exports = `/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: 467560D0-6ACE-4409-82FD-4791420837AC) */\n\n.ace-kuroir .ace_gutter {\n  background: #e8e8e8;\n  color: #333;\n}\n\n.ace-kuroir .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-kuroir {\n  background-color: #E8E9E8;\n  color: #363636;\n}\n\n.ace-kuroir .ace_cursor {\n  color: #202020;\n}\n\n.ace-kuroir .ace_marker-layer .ace_selection {\n  background: rgba(245, 170, 0, 0.57);\n}\n\n.ace-kuroir.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #E8E9E8;\n}\n\n.ace-kuroir .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174);\n}\n\n.ace-kuroir .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(0, 0, 0, 0.29);\n}\n\n.ace-kuroir .ace_marker-layer .ace_active-line {\n  background: rgba(203, 220, 47, 0.22);\n}\n\n.ace-kuroir .ace_gutter-active-line {\n  background-color: rgba(203, 220, 47, 0.22);\n}\n\n.ace-kuroir .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(245, 170, 0, 0.57);\n}\n\n.ace-kuroir .ace_invisible {\n  color: #BFBFBF\n}\n\n.ace-kuroir .ace_fold {\n  border-color: #363636;\n}\n\n\n\n\n\n.ace-kuroir .ace_constant{color:#CD6839;}.ace-kuroir .ace_constant.ace_numeric{color:#9A5925;}.ace-kuroir .ace_support{color:#104E8B;}.ace-kuroir .ace_support.ace_function{color:#005273;}.ace-kuroir .ace_support.ace_constant{color:#CF6A4C;}.ace-kuroir .ace_storage{color:#A52A2A;}.ace-kuroir .ace_invalid.ace_illegal{color:#FD1224;\nbackground-color:rgba(255, 6, 0, 0.15);}.ace-kuroir .ace_invalid.ace_deprecated{text-decoration:underline;\nfont-style:italic;\ncolor:#FD1732;\nbackground-color:#E8E9E8;}.ace-kuroir .ace_string{color:#639300;}.ace-kuroir .ace_string.ace_regexp{color:#417E00;\nbackground-color:#C9D4BE;}.ace-kuroir .ace_comment{color:rgba(148, 148, 148, 0.91);\nbackground-color:rgba(220, 220, 220, 0.56);}.ace-kuroir .ace_variable{color:#009ACD;}.ace-kuroir .ace_meta.ace_tag{color:#005273;}.ace-kuroir .ace_markup.ace_heading{color:#B8012D;\nbackground-color:rgba(191, 97, 51, 0.051);}.ace-kuroir .ace_markup.ace_list{color:#8F5B26;}\n\n.ace-kuroir .ace_indent-guide {\n    background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-kuroir .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/kuroir.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-kuroir\";\nexports.cssText = require(\"./kuroir-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/merbivore-css.js",
    "content": "module.exports = `.ace-merbivore .ace_gutter {\n  background: #202020;\n  color: #E6E1DC\n}\n\n.ace-merbivore .ace_print-margin {\n  width: 1px;\n  background: #555651\n}\n\n.ace-merbivore {\n  background-color: #161616;\n  color: #E6E1DC\n}\n\n.ace-merbivore .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-merbivore .ace_marker-layer .ace_selection {\n  background: #454545\n}\n\n.ace-merbivore.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #161616;\n}\n\n.ace-merbivore .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-merbivore .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404040\n}\n\n.ace-merbivore .ace_marker-layer .ace_active-line {\n  background: #333435\n}\n\n.ace-merbivore .ace_gutter-active-line {\n  background-color: #333435\n}\n\n.ace-merbivore .ace_marker-layer .ace_selected-word {\n  border: 1px solid #454545\n}\n\n.ace-merbivore .ace_invisible {\n  color: #404040\n}\n\n.ace-merbivore .ace_entity.ace_name.ace_tag,\n.ace-merbivore .ace_keyword,\n.ace-merbivore .ace_meta,\n.ace-merbivore .ace_meta.ace_tag,\n.ace-merbivore .ace_storage,\n.ace-merbivore .ace_support.ace_function {\n  color: #FC6F09\n}\n\n.ace-merbivore .ace_constant,\n.ace-merbivore .ace_constant.ace_character,\n.ace-merbivore .ace_constant.ace_character.ace_escape,\n.ace-merbivore .ace_constant.ace_other,\n.ace-merbivore .ace_support.ace_type {\n  color: #1EDAFB\n}\n\n.ace-merbivore .ace_constant.ace_character.ace_escape {\n  color: #519F50\n}\n\n.ace-merbivore .ace_constant.ace_language {\n  color: #FDC251\n}\n\n.ace-merbivore .ace_constant.ace_library,\n.ace-merbivore .ace_string,\n.ace-merbivore .ace_support.ace_constant {\n  color: #8DFF0A\n}\n\n.ace-merbivore .ace_constant.ace_numeric {\n  color: #58C554\n}\n\n.ace-merbivore .ace_invalid {\n  color: #FFFFFF;\n  background-color: #990000\n}\n\n.ace-merbivore .ace_fold {\n  background-color: #FC6F09;\n  border-color: #E6E1DC\n}\n\n.ace-merbivore .ace_comment {\n  font-style: italic;\n  color: #AD2EA4\n}\n\n.ace-merbivore .ace_entity.ace_other.ace_attribute-name {\n  color: #FFFF89\n}\n\n.ace-merbivore .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-merbivore .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/merbivore.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-merbivore\";\nexports.cssText = require(\"./merbivore-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/merbivore_soft-css.js",
    "content": "module.exports = `.ace-merbivore-soft .ace_gutter {\n  background: #262424;\n  color: #E6E1DC\n}\n\n.ace-merbivore-soft .ace_print-margin {\n  width: 1px;\n  background: #262424\n}\n\n.ace-merbivore-soft {\n  background-color: #1C1C1C;\n  color: #E6E1DC\n}\n\n.ace-merbivore-soft .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-merbivore-soft .ace_marker-layer .ace_selection {\n  background: #494949\n}\n\n.ace-merbivore-soft.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #1C1C1C;\n}\n\n.ace-merbivore-soft .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-merbivore-soft .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404040\n}\n\n.ace-merbivore-soft .ace_marker-layer .ace_active-line {\n  background: #333435\n}\n\n.ace-merbivore-soft .ace_gutter-active-line {\n  background-color: #333435\n}\n\n.ace-merbivore-soft .ace_marker-layer .ace_selected-word {\n  border: 1px solid #494949\n}\n\n.ace-merbivore-soft .ace_invisible {\n  color: #404040\n}\n\n.ace-merbivore-soft .ace_entity.ace_name.ace_tag,\n.ace-merbivore-soft .ace_keyword,\n.ace-merbivore-soft .ace_meta,\n.ace-merbivore-soft .ace_meta.ace_tag,\n.ace-merbivore-soft .ace_storage {\n  color: #FC803A\n}\n\n.ace-merbivore-soft .ace_constant,\n.ace-merbivore-soft .ace_constant.ace_character,\n.ace-merbivore-soft .ace_constant.ace_character.ace_escape,\n.ace-merbivore-soft .ace_constant.ace_other,\n.ace-merbivore-soft .ace_support.ace_type {\n  color: #68C1D8\n}\n\n.ace-merbivore-soft .ace_constant.ace_character.ace_escape {\n  color: #B3E5B4\n}\n\n.ace-merbivore-soft .ace_constant.ace_language {\n  color: #E1C582\n}\n\n.ace-merbivore-soft .ace_constant.ace_library,\n.ace-merbivore-soft .ace_string,\n.ace-merbivore-soft .ace_support.ace_constant {\n  color: #8EC65F\n}\n\n.ace-merbivore-soft .ace_constant.ace_numeric {\n  color: #7FC578\n}\n\n.ace-merbivore-soft .ace_invalid,\n.ace-merbivore-soft .ace_invalid.ace_deprecated {\n  color: #FFFFFF;\n  background-color: #FE3838\n}\n\n.ace-merbivore-soft .ace_fold {\n  background-color: #FC803A;\n  border-color: #E6E1DC\n}\n\n.ace-merbivore-soft .ace_comment,\n.ace-merbivore-soft .ace_meta {\n  font-style: italic;\n  color: #AC4BB8\n}\n\n.ace-merbivore-soft .ace_entity.ace_other.ace_attribute-name {\n  color: #EAF1A3\n}\n\n.ace-merbivore-soft .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQkpLyZfD09PwPAAfYAnaStpHRAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-merbivore-soft .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/merbivore_soft.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-merbivore-soft\";\nexports.cssText = require(\"./merbivore_soft-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/mono_industrial-css.js",
    "content": "module.exports = `.ace-mono-industrial .ace_gutter {\n  background: #1d2521;\n  color: #C5C9C9\n}\n\n.ace-mono-industrial .ace_print-margin {\n  width: 1px;\n  background: #555651\n}\n\n.ace-mono-industrial {\n  background-color: #222C28;\n  color: #FFFFFF\n}\n\n.ace-mono-industrial .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_selection {\n  background: rgba(145, 153, 148, 0.40)\n}\n\n.ace-mono-industrial.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #222C28;\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(102, 108, 104, 0.50)\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_active-line {\n  background: rgba(12, 13, 12, 0.25)\n}\n\n.ace-mono-industrial .ace_gutter-active-line {\n  background-color: rgba(12, 13, 12, 0.25)\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(145, 153, 148, 0.40)\n}\n\n.ace-mono-industrial .ace_invisible {\n  color: rgba(102, 108, 104, 0.50)\n}\n\n.ace-mono-industrial .ace_string {\n  background-color: #151C19;\n  color: #FFFFFF\n}\n\n.ace-mono-industrial .ace_keyword,\n.ace-mono-industrial .ace_meta {\n  color: #A39E64\n}\n\n.ace-mono-industrial .ace_constant,\n.ace-mono-industrial .ace_constant.ace_character,\n.ace-mono-industrial .ace_constant.ace_character.ace_escape,\n.ace-mono-industrial .ace_constant.ace_numeric,\n.ace-mono-industrial .ace_constant.ace_other {\n  color: #E98800\n}\n\n.ace-mono-industrial .ace_entity.ace_name.ace_function,\n.ace-mono-industrial .ace_keyword.ace_operator,\n.ace-mono-industrial .ace_variable {\n  color: #A8B3AB\n}\n\n.ace-mono-industrial .ace_invalid {\n  color: #FFFFFF;\n  background-color: rgba(153, 0, 0, 0.68)\n}\n\n.ace-mono-industrial .ace_support.ace_constant {\n  color: #C87500\n}\n\n.ace-mono-industrial .ace_fold {\n  background-color: #A8B3AB;\n  border-color: #FFFFFF\n}\n\n.ace-mono-industrial .ace_support.ace_function {\n  color: #588E60\n}\n\n.ace-mono-industrial .ace_entity.ace_name,\n.ace-mono-industrial .ace_support.ace_class,\n.ace-mono-industrial .ace_support.ace_type {\n  color: #5778B6\n}\n\n.ace-mono-industrial .ace_storage {\n  color: #C23B00\n}\n\n.ace-mono-industrial .ace_variable.ace_language,\n.ace-mono-industrial .ace_variable.ace_parameter {\n  color: #648BD2\n}\n\n.ace-mono-industrial .ace_comment {\n  color: #666C68;\n  background-color: #151C19\n}\n\n.ace-mono-industrial .ace_entity.ace_other.ace_attribute-name {\n  color: #909993\n}\n\n.ace-mono-industrial .ace_entity.ace_name.ace_tag {\n  color: #A65EFF\n}\n\n.ace-mono-industrial .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ1NbwZfALD/4PAAlTArlEC4r/AAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-mono-industrial .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/mono_industrial.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-mono-industrial\";\nexports.cssText = require(\"./mono_industrial-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/monokai-css.js",
    "content": "module.exports = `.ace-monokai .ace_gutter {\n  background: #2F3129;\n  color: #8F908A\n}\n\n.ace-monokai .ace_print-margin {\n  width: 1px;\n  background: #555651\n}\n\n.ace-monokai {\n  background-color: #272822;\n  color: #F8F8F2\n}\n\n.ace-monokai .ace_cursor {\n  color: #F8F8F0\n}\n\n.ace-monokai .ace_marker-layer .ace_selection {\n  background: #49483E\n}\n\n.ace-monokai.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #272822;\n}\n\n.ace-monokai .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-monokai .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #49483E\n}\n\n.ace-monokai .ace_marker-layer .ace_active-line {\n  background: #202020\n}\n\n.ace-monokai .ace_gutter-active-line {\n  background-color: #272727\n}\n\n.ace-monokai .ace_marker-layer .ace_selected-word {\n  border: 1px solid #49483E\n}\n\n.ace-monokai .ace_invisible {\n  color: #52524d\n}\n\n.ace-monokai .ace_entity.ace_name.ace_tag,\n.ace-monokai .ace_keyword,\n.ace-monokai .ace_meta.ace_tag,\n.ace-monokai .ace_storage {\n  color: #F92672\n}\n\n.ace-monokai .ace_punctuation,\n.ace-monokai .ace_punctuation.ace_tag {\n  color: #fff\n}\n\n.ace-monokai .ace_constant.ace_character,\n.ace-monokai .ace_constant.ace_language,\n.ace-monokai .ace_constant.ace_numeric,\n.ace-monokai .ace_constant.ace_other {\n  color: #AE81FF\n}\n\n.ace-monokai .ace_invalid {\n  color: #F8F8F0;\n  background-color: #F92672\n}\n\n.ace-monokai .ace_invalid.ace_deprecated {\n  color: #F8F8F0;\n  background-color: #AE81FF\n}\n\n.ace-monokai .ace_support.ace_constant,\n.ace-monokai .ace_support.ace_function {\n  color: #66D9EF\n}\n\n.ace-monokai .ace_fold {\n  background-color: #A6E22E;\n  border-color: #F8F8F2\n}\n\n.ace-monokai .ace_storage.ace_type,\n.ace-monokai .ace_support.ace_class,\n.ace-monokai .ace_support.ace_type {\n  font-style: italic;\n  color: #66D9EF\n}\n\n.ace-monokai .ace_entity.ace_name.ace_function,\n.ace-monokai .ace_entity.ace_other,\n.ace-monokai .ace_entity.ace_other.ace_attribute-name,\n.ace-monokai .ace_variable {\n  color: #A6E22E\n}\n\n.ace-monokai .ace_variable.ace_parameter {\n  font-style: italic;\n  color: #FD971F\n}\n\n.ace-monokai .ace_string {\n  color: #E6DB74\n}\n\n.ace-monokai .ace_comment {\n  color: #75715E\n}\n\n.ace-monokai .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-monokai .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/monokai.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-monokai\";\nexports.cssText = require(\"./monokai-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/nord_dark-css.js",
    "content": "module.exports = `.ace-nord-dark .ace_gutter {\n  color: #616e88;\n}\n\n.ace-nord-dark .ace_print-margin {\n  width: 1px;\n  background: #4c566a;\n}\n\n.ace-nord-dark {\n  background-color: #2e3440;\n  color: #d8dee9;\n}\n\n.ace-nord-dark .ace_entity.ace_other.ace_attribute-name,\n.ace-nord-dark .ace_storage {\n  color: #d8dee9;\n}\n\n.ace-nord-dark .ace_cursor {\n  color: #d8dee9;\n}\n\n.ace-nord-dark .ace_string.ace_regexp {\n  color: #bf616a;\n}\n\n.ace-nord-dark .ace_marker-layer .ace_active-line {\n  background: #434c5ecc;\n}\n.ace-nord-dark .ace_marker-layer .ace_selection {\n  background: #434c5ecc;\n}\n\n.ace-nord-dark.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #2e3440;\n}\n\n.ace-nord-dark .ace_marker-layer .ace_step {\n  background: #ebcb8b;\n}\n\n.ace-nord-dark .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #88c0d066;\n}\n\n.ace-nord-dark .ace_gutter-active-line {\n  background-color: #434c5ecc;\n}\n\n.ace-nord-dark .ace_marker-layer .ace_selected-word {\n  border: 1px solid #88c0d066;\n}\n\n.ace-nord-dark .ace_invisible {\n  color: #4c566a;\n}\n\n.ace-nord-dark .ace_keyword,\n.ace-nord-dark .ace_meta,\n.ace-nord-dark .ace_support.ace_class,\n.ace-nord-dark .ace_support.ace_type {\n  color: #81a1c1;\n}\n\n.ace-nord-dark .ace_constant.ace_character,\n.ace-nord-dark .ace_constant.ace_other {\n  color: #d8dee9;\n}\n\n.ace-nord-dark .ace_constant.ace_language {\n  color: #5e81ac;\n}\n\n.ace-nord-dark .ace_constant.ace_escape {\n  color: #ebcB8b;\n}\n\n.ace-nord-dark .ace_constant.ace_numeric {\n  color: #b48ead;\n}\n\n.ace-nord-dark .ace_fold {\n  background-color: #4c566a;\n  border-color: #d8dee9;\n}\n\n.ace-nord-dark .ace_entity.ace_name.ace_function,\n.ace-nord-dark .ace_entity.ace_name.ace_tag,\n.ace-nord-dark .ace_support.ace_function,\n.ace-nord-dark .ace_variable,\n.ace-nord-dark .ace_variable.ace_language {\n  color: #8fbcbb;\n}\n\n.ace-nord-dark .ace_string {\n  color: #a3be8c;\n}\n\n.ace-nord-dark .ace_comment {\n  color: #616e88;\n}\n\n.ace-nord-dark .ace_indent-guide {\n  box-shadow: inset -1px 0 0 0 #434c5eb3;\n}\n\n.ace-nord-dark .ace_indent-guide-active {\n  box-shadow: inset -1px 0 0 0 #8395b8b3;\n}\n`;\n"
  },
  {
    "path": "src/theme/nord_dark.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-nord-dark\";\nexports.cssText = require(\"./nord_dark-css\");\nexports.$selectionColorConflict = true;\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/one_dark-css.js",
    "content": "module.exports = `.ace-one-dark .ace_gutter {\n    background: #282c34;\n    color: #6a6f7a\n}\n\n.ace-one-dark .ace_print-margin {\n    width: 1px;\n    background: #e8e8e8\n}\n\n.ace-one-dark {\n    background-color: #282c34;\n    color: #abb2bf\n}\n\n.ace-one-dark .ace_cursor {\n    color: #528bff\n}\n\n.ace-one-dark .ace_marker-layer .ace_selection {\n    background: #3d4350\n}\n\n.ace-one-dark.ace_multiselect .ace_selection.ace_start {\n    box-shadow: 0 0 3px 0 #282c34;\n    border-radius: 2px\n}\n\n.ace-one-dark .ace_marker-layer .ace_step {\n    background: #c6dbae\n}\n\n.ace-one-dark .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid #747369\n}\n\n.ace-one-dark .ace_marker-layer .ace_active-line {\n    background: rgba(76, 87, 103, .19)\n}\n\n.ace-one-dark .ace_gutter-active-line {\n    background-color: rgba(76, 87, 103, .19)\n}\n\n.ace-one-dark .ace_marker-layer .ace_selected-word {\n    border: 1px solid #3d4350\n}\n\n.ace-one-dark .ace_fold {\n    background-color: #61afef;\n    border-color: #abb2bf\n}\n\n.ace-one-dark .ace_keyword {\n    color: #c678dd\n}\n\n.ace-one-dark .ace_keyword.ace_operator {\n    color: #c678dd\n}\n\n.ace-one-dark .ace_keyword.ace_other.ace_unit {\n    color: #d19a66\n}\n\n.ace-one-dark .ace_constant.ace_language {\n    color: #d19a66\n}\n\n.ace-one-dark .ace_constant.ace_numeric {\n    color: #d19a66\n}\n\n.ace-one-dark .ace_constant.ace_character {\n    color: #56b6c2\n}\n\n.ace-one-dark .ace_constant.ace_other {\n    color: #56b6c2\n}\n\n.ace-one-dark .ace_support.ace_function {\n    color: #61afef\n}\n\n.ace-one-dark .ace_support.ace_constant {\n    color: #d19a66\n}\n\n.ace-one-dark .ace_support.ace_class {\n    color: #e5c07b\n}\n\n.ace-one-dark .ace_support.ace_type {\n    color: #e5c07b\n}\n\n.ace-one-dark .ace_storage {\n    color: #c678dd\n}\n\n.ace-one-dark .ace_storage.ace_type {\n    color: #c678dd\n}\n\n.ace-one-dark .ace_invalid {\n    color: #fff;\n    background-color: #f2777a\n}\n\n.ace-one-dark .ace_invalid.ace_deprecated {\n    color: #272b33;\n    background-color: #d27b53\n}\n\n.ace-one-dark .ace_string {\n    color: #98c379\n}\n\n.ace-one-dark .ace_string.ace_regexp {\n    color: #e06c75\n}\n\n.ace-one-dark .ace_comment {\n    font-style: italic;\n    color: #5c6370\n}\n\n.ace-one-dark .ace_variable {\n    color: #e06c75\n}\n\n.ace-one-dark .ace_variable.ace_parameter {\n    color: #d19a66\n}\n\n.ace-one-dark .ace_meta.ace_tag {\n    color: #e06c75\n}\n\n.ace-one-dark .ace_entity.ace_other.ace_attribute-name {\n    color: #e06c75\n}\n\n.ace-one-dark .ace_entity.ace_name.ace_function {\n    color: #61afef\n}\n\n.ace-one-dark .ace_entity.ace_name.ace_tag {\n    color: #e06c75\n}\n\n.ace-one-dark .ace_markup.ace_heading {\n    color: #98c379\n}\n\n.ace-one-dark .ace_indent-guide {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-one-dark .ace_indent-guide-active {\n    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/one_dark.js",
    "content": "exports.isDark = true;\n    exports.cssClass = \"ace-one-dark\";\n    exports.cssText = require(\"./one_dark-css\");\n    \n    var dom = require(\"../lib/dom\");\n    dom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/pastel_on_dark-css.js",
    "content": "module.exports = `.ace-pastel-on-dark .ace_gutter {\n  background: #353030;\n  color: #8F938F\n}\n\n.ace-pastel-on-dark .ace_print-margin {\n  width: 1px;\n  background: #353030\n}\n\n.ace-pastel-on-dark {\n  background-color: #2C2828;\n  color: #8F938F\n}\n\n.ace-pastel-on-dark .ace_cursor {\n  color: #A7A7A7\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_selection {\n  background: rgba(221, 240, 255, 0.20)\n}\n\n.ace-pastel-on-dark.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #2C2828;\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(255, 255, 255, 0.25)\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_active-line {\n  background: rgba(255, 255, 255, 0.031)\n}\n\n.ace-pastel-on-dark .ace_gutter-active-line {\n  background-color: rgba(255, 255, 255, 0.031)\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(221, 240, 255, 0.20)\n}\n\n.ace-pastel-on-dark .ace_invisible {\n  color: rgba(255, 255, 255, 0.25)\n}\n\n.ace-pastel-on-dark .ace_keyword,\n.ace-pastel-on-dark .ace_meta {\n  color: #757aD8\n}\n\n.ace-pastel-on-dark .ace_constant,\n.ace-pastel-on-dark .ace_constant.ace_character,\n.ace-pastel-on-dark .ace_constant.ace_character.ace_escape,\n.ace-pastel-on-dark .ace_constant.ace_other {\n  color: #4FB7C5\n}\n\n.ace-pastel-on-dark .ace_keyword.ace_operator {\n  color: #797878\n}\n\n.ace-pastel-on-dark .ace_constant.ace_character {\n  color: #AFA472\n}\n\n.ace-pastel-on-dark .ace_constant.ace_language {\n  color: #DE8E30\n}\n\n.ace-pastel-on-dark .ace_constant.ace_numeric {\n  color: #CCCCCC\n}\n\n.ace-pastel-on-dark .ace_invalid,\n.ace-pastel-on-dark .ace_invalid.ace_illegal {\n  color: #F8F8F8;\n  background-color: rgba(86, 45, 86, 0.75)\n}\n\n.ace-pastel-on-dark .ace_invalid.ace_deprecated {\n  text-decoration: underline;\n  font-style: italic;\n  color: #D2A8A1\n}\n\n.ace-pastel-on-dark .ace_fold {\n  background-color: #757aD8;\n  border-color: #8F938F\n}\n\n.ace-pastel-on-dark .ace_support.ace_function {\n  color: #AEB2F8\n}\n\n.ace-pastel-on-dark .ace_string {\n  color: #66A968\n}\n\n.ace-pastel-on-dark .ace_string.ace_regexp {\n  color: #E9C062\n}\n\n.ace-pastel-on-dark .ace_comment {\n  color: #A6C6FF\n}\n\n.ace-pastel-on-dark .ace_variable {\n  color: #BEBF55\n}\n\n.ace-pastel-on-dark .ace_variable.ace_language {\n  color: #C1C144\n}\n\n.ace-pastel-on-dark .ace_xml-pe {\n  color: #494949\n}\n\n.ace-pastel-on-dark .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYIiPj/8PAARgAh2NTMh8AAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-pastel-on-dark .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/pastel_on_dark.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-pastel-on-dark\";\nexports.cssText = require(\"./pastel_on_dark-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/solarized_dark-css.js",
    "content": "module.exports = `.ace-solarized-dark .ace_gutter {\n  background: #01313f;\n  color: #d0edf7\n}\n\n.ace-solarized-dark .ace_print-margin {\n  width: 1px;\n  background: #33555E\n}\n\n.ace-solarized-dark {\n  background-color: #002B36;\n  color: #839496\n}\n\n.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name,\n.ace-solarized-dark .ace_storage {\n  color: #839496\n}\n\n.ace-solarized-dark .ace_cursor,\n.ace-solarized-dark .ace_string.ace_regexp {\n  color: #D30102\n}\n\n.ace-solarized-dark .ace_marker-layer .ace_active-line,\n.ace-solarized-dark .ace_marker-layer .ace_selection {\n  background: rgba(255, 255, 255, 0.1)\n}\n\n.ace-solarized-dark.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #002B36;\n}\n\n.ace-solarized-dark .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-solarized-dark .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-dark .ace_gutter-active-line {\n  background-color: #0d3440\n}\n\n.ace-solarized-dark .ace_marker-layer .ace_selected-word {\n  border: 1px solid #073642\n}\n\n.ace-solarized-dark .ace_invisible {\n  color: rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-dark .ace_keyword,\n.ace-solarized-dark .ace_meta,\n.ace-solarized-dark .ace_support.ace_class,\n.ace-solarized-dark .ace_support.ace_type {\n  color: #859900\n}\n\n.ace-solarized-dark .ace_constant.ace_character,\n.ace-solarized-dark .ace_constant.ace_other {\n  color: #CB4B16\n}\n\n.ace-solarized-dark .ace_constant.ace_language {\n  color: #B58900\n}\n\n.ace-solarized-dark .ace_constant.ace_numeric {\n  color: #D33682\n}\n\n.ace-solarized-dark .ace_fold {\n  background-color: #268BD2;\n  border-color: #93A1A1\n}\n\n.ace-solarized-dark .ace_entity.ace_name.ace_function,\n.ace-solarized-dark .ace_entity.ace_name.ace_tag,\n.ace-solarized-dark .ace_support.ace_function,\n.ace-solarized-dark .ace_variable,\n.ace-solarized-dark .ace_variable.ace_language {\n  color: #268BD2\n}\n\n.ace-solarized-dark .ace_string {\n  color: #2AA198\n}\n\n.ace-solarized-dark .ace_comment {\n  font-style: italic;\n  color: #657B83\n}\n\n.ace-solarized-dark .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db1ZVCxc/sPAAd4AlUHlLenAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-solarized-dark .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/solarized_dark.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-solarized-dark\";\nexports.cssText = require(\"./solarized_dark-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/solarized_light-css.js",
    "content": "module.exports = `.ace-solarized-light .ace_gutter {\n  background: #fbf1d3;\n  color: #333\n}\n\n.ace-solarized-light .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-solarized-light {\n  background-color: #FDF6E3;\n  color: #586E75\n}\n\n.ace-solarized-light .ace_cursor {\n  color: #000000\n}\n\n.ace-solarized-light .ace_marker-layer .ace_selection {\n  background: rgba(7, 54, 67, 0.09)\n}\n\n.ace-solarized-light.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #FDF6E3;\n}\n\n.ace-solarized-light .ace_marker-layer .ace_step {\n  background: rgb(255, 255, 0)\n}\n\n.ace-solarized-light .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-light .ace_marker-layer .ace_active-line {\n  background: #EEE8D5\n}\n\n.ace-solarized-light .ace_gutter-active-line {\n  background-color : #EDE5C1\n}\n\n.ace-solarized-light .ace_marker-layer .ace_selected-word {\n  border: 1px solid #7f9390\n}\n\n.ace-solarized-light .ace_invisible {\n  color: rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-light .ace_keyword,\n.ace-solarized-light .ace_meta,\n.ace-solarized-light .ace_support.ace_class,\n.ace-solarized-light .ace_support.ace_type {\n  color: #859900\n}\n\n.ace-solarized-light .ace_constant.ace_character,\n.ace-solarized-light .ace_constant.ace_other {\n  color: #CB4B16\n}\n\n.ace-solarized-light .ace_constant.ace_language {\n  color: #B58900\n}\n\n.ace-solarized-light .ace_constant.ace_numeric {\n  color: #D33682\n}\n\n.ace-solarized-light .ace_fold {\n  background-color: #268BD2;\n  border-color: #586E75\n}\n\n.ace-solarized-light .ace_entity.ace_name.ace_function,\n.ace-solarized-light .ace_entity.ace_name.ace_tag,\n.ace-solarized-light .ace_support.ace_function,\n.ace-solarized-light .ace_variable,\n.ace-solarized-light .ace_variable.ace_language {\n  color: #268BD2\n}\n\n.ace-solarized-light .ace_storage {\n  color: #073642\n}\n\n.ace-solarized-light .ace_string {\n  color: #2AA198\n}\n\n.ace-solarized-light .ace_string.ace_regexp {\n  color: #D30102\n}\n\n.ace-solarized-light .ace_comment,\n.ace-solarized-light .ace_entity.ace_other.ace_attribute-name {\n  color: #93A1A1\n}\n\n.ace-solarized-light .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHjy8NJ/AAjgA5fzQUmBAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-solarized-light .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/solarized_light.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-solarized-light\";\nexports.cssText = require(\"./solarized_light-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/sqlserver-css.js",
    "content": "module.exports = `.ace-sqlserver .ace_gutter {\n    background: #ebebeb;\n    color: #333;\n    overflow: hidden;\n}\n\n.ace-sqlserver .ace_print-margin {\n    width: 1px;\n    background: #e8e8e8;\n}\n\n.ace-sqlserver {\n    background-color: #FFFFFF;\n    color: black;\n}\n\n.ace-sqlserver .ace_identifier {\n    color: black;\n}\n\n.ace-sqlserver .ace_keyword {\n    color: #0000FF;\n}\n\n.ace-sqlserver .ace_numeric {\n    color: black;\n}\n\n.ace-sqlserver .ace_storage {\n    color: #11B7BE;\n}\n\n.ace-sqlserver .ace_keyword.ace_operator,\n.ace-sqlserver .ace_lparen,\n.ace-sqlserver .ace_rparen,\n.ace-sqlserver .ace_punctuation {\n    color: #808080;\n}\n\n.ace-sqlserver .ace_set.ace_statement {\n    color: #0000FF;\n    text-decoration: underline;\n}\n\n.ace-sqlserver .ace_cursor {\n    color: black;\n}\n\n.ace-sqlserver .ace_invisible {\n    color: rgb(191, 191, 191);\n}\n\n.ace-sqlserver .ace_constant.ace_buildin {\n    color: rgb(88, 72, 246);\n}\n\n.ace-sqlserver .ace_constant.ace_language {\n    color: #979797;\n}\n\n.ace-sqlserver .ace_constant.ace_library {\n    color: rgb(6, 150, 14);\n}\n\n.ace-sqlserver .ace_invalid {\n    background-color: rgb(153, 0, 0);\n    color: white;\n}\n\n.ace-sqlserver .ace_support.ace_function {\n    color: #FF00FF;\n}\n\n.ace-sqlserver .ace_support.ace_constant {\n    color: rgb(6, 150, 14);\n}\n\n.ace-sqlserver .ace_class {\n    color: #008080;\n}\n\n.ace-sqlserver .ace_support.ace_other {\n    color: #6D79DE;\n}\n\n.ace-sqlserver .ace_variable.ace_parameter {\n    font-style: italic;\n    color: #FD971F;\n}\n\n.ace-sqlserver .ace_comment {\n    color: #008000;\n}\n\n.ace-sqlserver .ace_constant.ace_numeric {\n    color: black;\n}\n\n.ace-sqlserver .ace_variable {\n    color: rgb(49, 132, 149);\n}\n\n.ace-sqlserver .ace_xml-pe {\n    color: rgb(104, 104, 91);\n}\n\n.ace-sqlserver .ace_support.ace_storedprocedure {\n    color: #800000;\n}\n\n.ace-sqlserver .ace_heading {\n    color: rgb(12, 7, 255);\n}\n\n.ace-sqlserver .ace_list {\n    color: rgb(185, 6, 144);\n}\n\n.ace-sqlserver .ace_marker-layer .ace_selection {\n    background: rgb(181, 213, 255);\n}\n\n.ace-sqlserver .ace_marker-layer .ace_step {\n    background: rgb(252, 255, 0);\n}\n\n.ace-sqlserver .ace_marker-layer .ace_stack {\n    background: rgb(164, 229, 101);\n}\n\n.ace-sqlserver .ace_marker-layer .ace_bracket {\n    margin: -1px 0 0 -1px;\n    border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-sqlserver .ace_marker-layer .ace_active-line {\n    background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-sqlserver .ace_gutter-active-line {\n    background-color: #dcdcdc;\n}\n\n.ace-sqlserver .ace_marker-layer .ace_selected-word {\n    background: rgb(250, 250, 255);\n    border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-sqlserver .ace_meta.ace_tag {\n    color: #0000FF;\n}\n\n.ace-sqlserver .ace_string.ace_regex {\n    color: #FF0000;\n}\n\n.ace-sqlserver .ace_string {\n    color: #FF0000;\n}\n\n.ace-sqlserver .ace_entity.ace_other.ace_attribute-name {\n    color: #994409;\n}\n\n.ace-sqlserver .ace_indent-guide {\n    background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-sqlserver .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/sqlserver.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-sqlserver\";\nexports.cssText = require(\"./sqlserver-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/terminal-css.js",
    "content": "module.exports = `.ace-terminal-theme .ace_gutter {\n  background: #1a0005;\n  color: steelblue\n}\n\n.ace-terminal-theme .ace_print-margin {\n  width: 1px;\n  background: #1a1a1a\n}\n\n.ace-terminal-theme {\n  background-color: black;\n  color: #DEDEDE\n}\n\n.ace-terminal-theme .ace_cursor {\n  color: #9F9F9F\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_selection {\n  background: #424242\n}\n\n.ace-terminal-theme.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px black;\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_step {\n  background: rgb(0, 0, 0)\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_bracket {\n  background: #090;\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_bracket-start {\n  background: #090;\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_bracket-unmatched {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #900\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_active-line {\n  background: #2A2A2A\n}\n\n.ace-terminal-theme .ace_gutter-active-line {\n  background-color: #2A112A\n}\n\n.ace-terminal-theme .ace_marker-layer .ace_selected-word {\n  border: 1px solid #424242\n}\n\n.ace-terminal-theme .ace_invisible {\n  color: #343434\n}\n\n.ace-terminal-theme .ace_keyword,\n.ace-terminal-theme .ace_meta,\n.ace-terminal-theme .ace_storage,\n.ace-terminal-theme .ace_storage.ace_type,\n.ace-terminal-theme .ace_support.ace_type {\n  color: tomato\n}\n\n.ace-terminal-theme .ace_keyword.ace_operator {\n  color: deeppink\n}\n\n.ace-terminal-theme .ace_constant.ace_character,\n.ace-terminal-theme .ace_constant.ace_language,\n.ace-terminal-theme .ace_constant.ace_numeric,\n.ace-terminal-theme .ace_keyword.ace_other.ace_unit,\n.ace-terminal-theme .ace_support.ace_constant,\n.ace-terminal-theme .ace_variable.ace_parameter {\n  color: #E78C45\n}\n\n.ace-terminal-theme .ace_constant.ace_other {\n  color: gold\n}\n\n.ace-terminal-theme .ace_invalid {\n  color: yellow;\n  background-color: red\n}\n\n.ace-terminal-theme .ace_invalid.ace_deprecated {\n  color: #CED2CF;\n  background-color: #B798BF\n}\n\n.ace-terminal-theme .ace_fold {\n  background-color: #7AA6DA;\n  border-color: #DEDEDE\n}\n\n.ace-terminal-theme .ace_entity.ace_name.ace_function,\n.ace-terminal-theme .ace_support.ace_function,\n.ace-terminal-theme .ace_variable {\n  color: #7AA6DA\n}\n\n.ace-terminal-theme .ace_support.ace_class,\n.ace-terminal-theme .ace_support.ace_type {\n  color: #E7C547\n}\n\n.ace-terminal-theme .ace_heading,\n.ace-terminal-theme .ace_string {\n  color: #B9CA4A\n}\n\n.ace-terminal-theme .ace_entity.ace_name.ace_tag,\n.ace-terminal-theme .ace_entity.ace_other.ace_attribute-name,\n.ace-terminal-theme .ace_meta.ace_tag,\n.ace-terminal-theme .ace_string.ace_regexp,\n.ace-terminal-theme .ace_variable {\n  color: #D54E53\n}\n\n.ace-terminal-theme .ace_comment {\n  color: orangered\n}\n\n.ace-terminal-theme .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y;\n}\n\n.ace-terminal-theme .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/terminal.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-terminal-theme\";\nexports.cssText = require(\"./terminal-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/textmate-css.js",
    "content": "module.exports = `.ace-tm .ace_gutter {\n  background: #f0f0f0;\n  color: #333;\n}\n\n.ace-tm .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8;\n}\n\n.ace-tm .ace_fold {\n    background-color: #6B72E6;\n}\n\n.ace-tm {\n  background-color: #FFFFFF;\n  color: black;\n}\n\n.ace-tm .ace_cursor {\n  color: black;\n}\n        \n.ace-tm .ace_invisible {\n  color: rgb(191, 191, 191);\n}\n\n.ace-tm .ace_storage,\n.ace-tm .ace_keyword {\n  color: blue;\n}\n\n.ace-tm .ace_constant {\n  color: rgb(197, 6, 11);\n}\n\n.ace-tm .ace_constant.ace_buildin {\n  color: rgb(88, 72, 246);\n}\n\n.ace-tm .ace_constant.ace_language {\n  color: rgb(88, 92, 246);\n}\n\n.ace-tm .ace_constant.ace_library {\n  color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_invalid {\n  background-color: rgba(255, 0, 0, 0.1);\n  color: red;\n}\n\n.ace-tm .ace_support.ace_function {\n  color: rgb(60, 76, 114);\n}\n\n.ace-tm .ace_support.ace_constant {\n  color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_support.ace_type,\n.ace-tm .ace_support.ace_class {\n  color: rgb(109, 121, 222);\n}\n\n.ace-tm .ace_keyword.ace_operator {\n  color: rgb(104, 118, 135);\n}\n\n.ace-tm .ace_string {\n  color: rgb(3, 106, 7);\n}\n\n.ace-tm .ace_comment {\n  color: rgb(76, 136, 107);\n}\n\n.ace-tm .ace_comment.ace_doc {\n  color: rgb(0, 102, 255);\n}\n\n.ace-tm .ace_comment.ace_doc.ace_tag {\n  color: rgb(128, 159, 191);\n}\n\n.ace-tm .ace_constant.ace_numeric {\n  color: rgb(0, 0, 205);\n}\n\n.ace-tm .ace_variable {\n  color: rgb(49, 132, 149);\n}\n\n.ace-tm .ace_xml-pe {\n  color: rgb(104, 104, 91);\n}\n\n.ace-tm .ace_entity.ace_name.ace_function {\n  color: #0000A2;\n}\n\n\n.ace-tm .ace_heading {\n  color: rgb(12, 7, 255);\n}\n\n.ace-tm .ace_list {\n  color:rgb(185, 6, 144);\n}\n\n.ace-tm .ace_meta.ace_tag {\n  color:rgb(0, 22, 142);\n}\n\n.ace-tm .ace_string.ace_regex {\n  color: rgb(255, 0, 0)\n}\n\n.ace-tm .ace_marker-layer .ace_selection {\n  background: rgb(181, 213, 255);\n}\n.ace-tm.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px white;\n}\n.ace-tm .ace_marker-layer .ace_step {\n  background: rgb(252, 255, 0);\n}\n\n.ace-tm .ace_marker-layer .ace_stack {\n  background: rgb(164, 229, 101);\n}\n\n.ace-tm .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-tm .ace_marker-layer .ace_active-line {\n  background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-tm .ace_gutter-active-line {\n    background-color : #dcdcdc;\n}\n\n.ace-tm .ace_marker-layer .ace_selected-word {\n  background: rgb(250, 250, 255);\n  border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-tm .ace_indent-guide {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\n}\n\n.ace-tm .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/textmate.js",
    "content": "\"use strict\";\n\nexports.isDark = false;\nexports.cssClass = \"ace-tm\";\nexports.cssText = require(\"./textmate-css\");\nexports.$id = \"ace/theme/textmate\";\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/tomorrow-css.js",
    "content": "module.exports = `.ace-tomorrow .ace_gutter {\n  background: #f6f6f6;\n  color: #4D4D4C\n}\n\n.ace-tomorrow .ace_print-margin {\n  width: 1px;\n  background: #f6f6f6\n}\n\n.ace-tomorrow {\n  background-color: #FFFFFF;\n  color: #4D4D4C\n}\n\n.ace-tomorrow .ace_cursor {\n  color: #AEAFAD\n}\n\n.ace-tomorrow .ace_marker-layer .ace_selection {\n  background: #D6D6D6\n}\n\n.ace-tomorrow.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #FFFFFF;\n}\n\n.ace-tomorrow .ace_marker-layer .ace_step {\n  background: rgb(255, 255, 0)\n}\n\n.ace-tomorrow .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #D1D1D1\n}\n\n.ace-tomorrow .ace_marker-layer .ace_active-line {\n  background: #EFEFEF\n}\n\n.ace-tomorrow .ace_gutter-active-line {\n  background-color : #dcdcdc\n}\n\n.ace-tomorrow .ace_marker-layer .ace_selected-word {\n  border: 1px solid #D6D6D6\n}\n\n.ace-tomorrow .ace_invisible {\n  color: #D1D1D1\n}\n\n.ace-tomorrow .ace_keyword,\n.ace-tomorrow .ace_meta,\n.ace-tomorrow .ace_storage,\n.ace-tomorrow .ace_storage.ace_type,\n.ace-tomorrow .ace_support.ace_type {\n  color: #8959A8\n}\n\n.ace-tomorrow .ace_keyword.ace_operator {\n  color: #3E999F\n}\n\n.ace-tomorrow .ace_constant.ace_character,\n.ace-tomorrow .ace_constant.ace_language,\n.ace-tomorrow .ace_constant.ace_numeric,\n.ace-tomorrow .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow .ace_support.ace_constant,\n.ace-tomorrow .ace_variable.ace_parameter {\n  color: #F5871F\n}\n\n.ace-tomorrow .ace_constant.ace_other {\n  color: #666969\n}\n\n.ace-tomorrow .ace_invalid {\n  color: #FFFFFF;\n  background-color: #C82829\n}\n\n.ace-tomorrow .ace_invalid.ace_deprecated {\n  color: #FFFFFF;\n  background-color: #8959A8\n}\n\n.ace-tomorrow .ace_fold {\n  background-color: #4271AE;\n  border-color: #4D4D4C\n}\n\n.ace-tomorrow .ace_entity.ace_name.ace_function,\n.ace-tomorrow .ace_support.ace_function,\n.ace-tomorrow .ace_variable {\n  color: #4271AE\n}\n\n.ace-tomorrow .ace_support.ace_class,\n.ace-tomorrow .ace_support.ace_type {\n  color: #C99E00\n}\n\n.ace-tomorrow .ace_heading,\n.ace-tomorrow .ace_markup.ace_heading,\n.ace-tomorrow .ace_string {\n  color: #718C00\n}\n\n.ace-tomorrow .ace_entity.ace_name.ace_tag,\n.ace-tomorrow .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow .ace_meta.ace_tag,\n.ace-tomorrow .ace_string.ace_regexp,\n.ace-tomorrow .ace_variable {\n  color: #C82829\n}\n\n.ace-tomorrow .ace_comment {\n  color: #8E908C\n}\n\n.ace-tomorrow .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y\n}\n\n.ace-tomorrow .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/tomorrow.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-tomorrow\";\nexports.cssText = require(\"./tomorrow-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/tomorrow_night-css.js",
    "content": "module.exports = `.ace-tomorrow-night .ace_gutter {\n  background: #25282c;\n  color: #C5C8C6\n}\n\n.ace-tomorrow-night .ace_print-margin {\n  width: 1px;\n  background: #25282c\n}\n\n.ace-tomorrow-night {\n  background-color: #1D1F21;\n  color: #C5C8C6\n}\n\n.ace-tomorrow-night .ace_cursor {\n  color: #AEAFAD\n}\n\n.ace-tomorrow-night .ace_marker-layer .ace_selection {\n  background: #373B41\n}\n\n.ace-tomorrow-night.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #1D1F21;\n}\n\n.ace-tomorrow-night .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-tomorrow-night .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #4B4E55\n}\n\n.ace-tomorrow-night .ace_marker-layer .ace_active-line {\n  background: #282A2E\n}\n\n.ace-tomorrow-night .ace_gutter-active-line {\n  background-color: #282A2E\n}\n\n.ace-tomorrow-night .ace_marker-layer .ace_selected-word {\n  border: 1px solid #373B41\n}\n\n.ace-tomorrow-night .ace_invisible {\n  color: #4B4E55\n}\n\n.ace-tomorrow-night .ace_keyword,\n.ace-tomorrow-night .ace_meta,\n.ace-tomorrow-night .ace_storage,\n.ace-tomorrow-night .ace_storage.ace_type,\n.ace-tomorrow-night .ace_support.ace_type {\n  color: #B294BB\n}\n\n.ace-tomorrow-night .ace_keyword.ace_operator {\n  color: #8ABEB7\n}\n\n.ace-tomorrow-night .ace_constant.ace_character,\n.ace-tomorrow-night .ace_constant.ace_language,\n.ace-tomorrow-night .ace_constant.ace_numeric,\n.ace-tomorrow-night .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow-night .ace_support.ace_constant,\n.ace-tomorrow-night .ace_variable.ace_parameter {\n  color: #DE935F\n}\n\n.ace-tomorrow-night .ace_constant.ace_other {\n  color: #CED1CF\n}\n\n.ace-tomorrow-night .ace_invalid {\n  color: #CED2CF;\n  background-color: #DF5F5F\n}\n\n.ace-tomorrow-night .ace_invalid.ace_deprecated {\n  color: #CED2CF;\n  background-color: #B798BF\n}\n\n.ace-tomorrow-night .ace_fold {\n  background-color: #81A2BE;\n  border-color: #C5C8C6\n}\n\n.ace-tomorrow-night .ace_entity.ace_name.ace_function,\n.ace-tomorrow-night .ace_support.ace_function,\n.ace-tomorrow-night .ace_variable {\n  color: #81A2BE\n}\n\n.ace-tomorrow-night .ace_support.ace_class,\n.ace-tomorrow-night .ace_support.ace_type {\n  color: #F0C674\n}\n\n.ace-tomorrow-night .ace_heading,\n.ace-tomorrow-night .ace_markup.ace_heading,\n.ace-tomorrow-night .ace_string {\n  color: #B5BD68\n}\n\n.ace-tomorrow-night .ace_entity.ace_name.ace_tag,\n.ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow-night .ace_meta.ace_tag,\n.ace-tomorrow-night .ace_string.ace_regexp,\n.ace-tomorrow-night .ace_variable {\n  color: #CC6666\n}\n\n.ace-tomorrow-night .ace_comment {\n  color: #969896\n}\n\n.ace-tomorrow-night .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-tomorrow-night .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/tomorrow_night.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-tomorrow-night\";\nexports.cssText = require(\"./tomorrow_night-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/tomorrow_night_blue-css.js",
    "content": "module.exports = `.ace-tomorrow-night-blue .ace_gutter {\n  background: #00204b;\n  color: #7388b5\n}\n\n.ace-tomorrow-night-blue .ace_print-margin {\n  width: 1px;\n  background: #00204b\n}\n\n.ace-tomorrow-night-blue {\n  background-color: #002451;\n  color: #FFFFFF\n}\n\n.ace-tomorrow-night-blue .ace_constant.ace_other,\n.ace-tomorrow-night-blue .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-tomorrow-night-blue .ace_marker-layer .ace_selection {\n  background: #003F8E\n}\n\n.ace-tomorrow-night-blue.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #002451;\n}\n\n.ace-tomorrow-night-blue .ace_marker-layer .ace_step {\n  background: rgb(127, 111, 19)\n}\n\n.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404F7D\n}\n\n.ace-tomorrow-night-blue .ace_marker-layer .ace_active-line {\n  background: #00346E\n}\n\n.ace-tomorrow-night-blue .ace_gutter-active-line {\n  background-color: #022040\n}\n\n.ace-tomorrow-night-blue .ace_marker-layer .ace_selected-word {\n  border: 1px solid #003F8E\n}\n\n.ace-tomorrow-night-blue .ace_invisible {\n  color: #404F7D\n}\n\n.ace-tomorrow-night-blue .ace_keyword,\n.ace-tomorrow-night-blue .ace_meta,\n.ace-tomorrow-night-blue .ace_storage,\n.ace-tomorrow-night-blue .ace_storage.ace_type,\n.ace-tomorrow-night-blue .ace_support.ace_type {\n  color: #EBBBFF\n}\n\n.ace-tomorrow-night-blue .ace_keyword.ace_operator {\n  color: #99FFFF\n}\n\n.ace-tomorrow-night-blue .ace_constant.ace_character,\n.ace-tomorrow-night-blue .ace_constant.ace_language,\n.ace-tomorrow-night-blue .ace_constant.ace_numeric,\n.ace-tomorrow-night-blue .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow-night-blue .ace_support.ace_constant,\n.ace-tomorrow-night-blue .ace_variable.ace_parameter {\n  color: #FFC58F\n}\n\n.ace-tomorrow-night-blue .ace_invalid {\n  color: #FFFFFF;\n  background-color: #F99DA5\n}\n\n.ace-tomorrow-night-blue .ace_invalid.ace_deprecated {\n  color: #FFFFFF;\n  background-color: #EBBBFF\n}\n\n.ace-tomorrow-night-blue .ace_fold {\n  background-color: #BBDAFF;\n  border-color: #FFFFFF\n}\n\n.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function,\n.ace-tomorrow-night-blue .ace_support.ace_function,\n.ace-tomorrow-night-blue .ace_variable {\n  color: #BBDAFF\n}\n\n.ace-tomorrow-night-blue .ace_support.ace_class,\n.ace-tomorrow-night-blue .ace_support.ace_type {\n  color: #FFEEAD\n}\n\n.ace-tomorrow-night-blue .ace_heading,\n.ace-tomorrow-night-blue .ace_markup.ace_heading,\n.ace-tomorrow-night-blue .ace_string {\n  color: #D1F1A9\n}\n\n.ace-tomorrow-night-blue .ace_entity.ace_name.ace_tag,\n.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow-night-blue .ace_meta.ace_tag,\n.ace-tomorrow-night-blue .ace_string.ace_regexp,\n.ace-tomorrow-night-blue .ace_variable {\n  color: #FF9DA4\n}\n\n.ace-tomorrow-night-blue .ace_comment {\n  color: #7285B7\n}\n\n.ace-tomorrow-night-blue .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-tomorrow-night-blue .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/tomorrow_night_blue.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-tomorrow-night-blue\";\nexports.cssText = require(\"./tomorrow_night_blue-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/tomorrow_night_bright-css.js",
    "content": "module.exports = `.ace-tomorrow-night-bright .ace_gutter {\n  background: #1a1a1a;\n  color: #DEDEDE\n}\n\n.ace-tomorrow-night-bright .ace_print-margin {\n  width: 1px;\n  background: #1a1a1a\n}\n\n.ace-tomorrow-night-bright {\n  background-color: #000000;\n  color: #DEDEDE\n}\n\n.ace-tomorrow-night-bright .ace_cursor {\n  color: #9F9F9F\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_selection {\n  background: #424242\n}\n\n.ace-tomorrow-night-bright.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #000000;\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #888888\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_highlight {\n  border: 1px solid rgb(110, 119, 0);\n  border-bottom: 0;\n  box-shadow: inset 0 -1px rgb(110, 119, 0);\n  margin: -1px 0 0 -1px;\n  background: rgba(255, 235, 0, 0.1)\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_active-line {\n  background: #2A2A2A\n}\n\n.ace-tomorrow-night-bright .ace_gutter-active-line {\n  background-color: #2A2A2A\n}\n\n.ace-tomorrow-night-bright .ace_stack {\n  background-color: rgb(66, 90, 44)\n}\n\n.ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word {\n  border: 1px solid #888888\n}\n\n.ace-tomorrow-night-bright .ace_invisible {\n  color: #343434\n}\n\n.ace-tomorrow-night-bright .ace_keyword,\n.ace-tomorrow-night-bright .ace_meta,\n.ace-tomorrow-night-bright .ace_storage,\n.ace-tomorrow-night-bright .ace_storage.ace_type,\n.ace-tomorrow-night-bright .ace_support.ace_type {\n  color: #C397D8\n}\n\n.ace-tomorrow-night-bright .ace_keyword.ace_operator {\n  color: #70C0B1\n}\n\n.ace-tomorrow-night-bright .ace_constant.ace_character,\n.ace-tomorrow-night-bright .ace_constant.ace_language,\n.ace-tomorrow-night-bright .ace_constant.ace_numeric,\n.ace-tomorrow-night-bright .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow-night-bright .ace_support.ace_constant,\n.ace-tomorrow-night-bright .ace_variable.ace_parameter {\n  color: #E78C45\n}\n\n.ace-tomorrow-night-bright .ace_constant.ace_other {\n  color: #EEEEEE\n}\n\n.ace-tomorrow-night-bright .ace_invalid {\n  color: #CED2CF;\n  background-color: #DF5F5F\n}\n\n.ace-tomorrow-night-bright .ace_invalid.ace_deprecated {\n  color: #CED2CF;\n  background-color: #B798BF\n}\n\n.ace-tomorrow-night-bright .ace_fold {\n  background-color: #7AA6DA;\n  border-color: #DEDEDE\n}\n\n.ace-tomorrow-night-bright .ace_entity.ace_name.ace_function,\n.ace-tomorrow-night-bright .ace_support.ace_function,\n.ace-tomorrow-night-bright .ace_variable {\n  color: #7AA6DA\n}\n\n.ace-tomorrow-night-bright .ace_support.ace_class,\n.ace-tomorrow-night-bright .ace_support.ace_type {\n  color: #E7C547\n}\n\n.ace-tomorrow-night-bright .ace_heading,\n.ace-tomorrow-night-bright .ace_markup.ace_heading,\n.ace-tomorrow-night-bright .ace_string {\n  color: #B9CA4A\n}\n\n.ace-tomorrow-night-bright .ace_entity.ace_name.ace_tag,\n.ace-tomorrow-night-bright .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow-night-bright .ace_meta.ace_tag,\n.ace-tomorrow-night-bright .ace_string.ace_regexp,\n.ace-tomorrow-night-bright .ace_variable {\n  color: #D54E53\n}\n\n.ace-tomorrow-night-bright .ace_comment {\n  color: #969896\n}\n\n.ace-tomorrow-night-bright .ace_c9searchresults.ace_keyword {\n  color: #C2C280\n}\n\n.ace-tomorrow-night-bright .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-tomorrow-night-bright .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/tomorrow_night_bright.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-tomorrow-night-bright\";\nexports.cssText = require(\"./tomorrow_night_bright-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/tomorrow_night_eighties-css.js",
    "content": "module.exports = `.ace-tomorrow-night-eighties .ace_gutter {\n  background: #272727;\n  color: #CCC\n}\n\n.ace-tomorrow-night-eighties .ace_print-margin {\n  width: 1px;\n  background: #272727\n}\n\n.ace-tomorrow-night-eighties {\n  background-color: #2D2D2D;\n  color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_constant.ace_other,\n.ace-tomorrow-night-eighties .ace_cursor {\n  color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection {\n  background: #515151\n}\n\n.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #2D2D2D;\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #6A6A6A\n}\n\n.ace-tomorrow-night-bright .ace_stack {\n  background: rgb(66, 90, 44)\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line {\n  background: #393939\n}\n\n.ace-tomorrow-night-eighties .ace_gutter-active-line {\n  background-color: #393939\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word {\n  border: 1px solid #515151\n}\n\n.ace-tomorrow-night-eighties .ace_invisible {\n  color: #6A6A6A\n}\n\n.ace-tomorrow-night-eighties .ace_keyword,\n.ace-tomorrow-night-eighties .ace_meta,\n.ace-tomorrow-night-eighties .ace_storage,\n.ace-tomorrow-night-eighties .ace_storage.ace_type,\n.ace-tomorrow-night-eighties .ace_support.ace_type {\n  color: #CC99CC\n}\n\n.ace-tomorrow-night-eighties .ace_keyword.ace_operator {\n  color: #66CCCC\n}\n\n.ace-tomorrow-night-eighties .ace_constant.ace_character,\n.ace-tomorrow-night-eighties .ace_constant.ace_language,\n.ace-tomorrow-night-eighties .ace_constant.ace_numeric,\n.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow-night-eighties .ace_support.ace_constant,\n.ace-tomorrow-night-eighties .ace_variable.ace_parameter {\n  color: #F99157\n}\n\n.ace-tomorrow-night-eighties .ace_invalid {\n  color: #CDCDCD;\n  background-color: #F2777A\n}\n\n.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated {\n  color: #CDCDCD;\n  background-color: #CC99CC\n}\n\n.ace-tomorrow-night-eighties .ace_fold {\n  background-color: #6699CC;\n  border-color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function,\n.ace-tomorrow-night-eighties .ace_support.ace_function,\n.ace-tomorrow-night-eighties .ace_variable {\n  color: #6699CC\n}\n\n.ace-tomorrow-night-eighties .ace_support.ace_class,\n.ace-tomorrow-night-eighties .ace_support.ace_type {\n  color: #FFCC66\n}\n\n.ace-tomorrow-night-eighties .ace_heading,\n.ace-tomorrow-night-eighties .ace_markup.ace_heading,\n.ace-tomorrow-night-eighties .ace_string {\n  color: #99CC99\n}\n\n.ace-tomorrow-night-eighties .ace_comment {\n  color: #999999\n}\n\n.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag,\n.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow-night-eighties .ace_meta.ace_tag,\n.ace-tomorrow-night-eighties .ace_variable {\n  color: #F2777A\n}\n\n.ace-tomorrow-night-eighties .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-tomorrow-night-eighties .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/tomorrow_night_eighties.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-tomorrow-night-eighties\";\nexports.cssText = require(\"./tomorrow_night_eighties-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/twilight-css.js",
    "content": "module.exports = `.ace-twilight .ace_gutter {\n  background: #232323;\n  color: #E2E2E2\n}\n\n.ace-twilight .ace_print-margin {\n  width: 1px;\n  background: #232323\n}\n\n.ace-twilight {\n  background-color: #141414;\n  color: #F8F8F8\n}\n\n.ace-twilight .ace_cursor {\n  color: #A7A7A7\n}\n\n.ace-twilight .ace_marker-layer .ace_selection {\n  background: rgba(221, 240, 255, 0.20)\n}\n\n.ace-twilight.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #141414;\n}\n\n.ace-twilight .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-twilight .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid rgba(255, 255, 255, 0.25)\n}\n\n.ace-twilight .ace_marker-layer .ace_active-line {\n  background: rgba(255, 255, 255, 0.031)\n}\n\n.ace-twilight .ace_gutter-active-line {\n  background-color: rgba(255, 255, 255, 0.031)\n}\n\n.ace-twilight .ace_marker-layer .ace_selected-word {\n  border: 1px solid rgba(221, 240, 255, 0.20)\n}\n\n.ace-twilight .ace_invisible {\n  color: rgba(255, 255, 255, 0.25)\n}\n\n.ace-twilight .ace_keyword,\n.ace-twilight .ace_meta {\n  color: #CDA869\n}\n\n.ace-twilight .ace_constant,\n.ace-twilight .ace_constant.ace_character,\n.ace-twilight .ace_constant.ace_character.ace_escape,\n.ace-twilight .ace_constant.ace_other,\n.ace-twilight .ace_heading,\n.ace-twilight .ace_markup.ace_heading,\n.ace-twilight .ace_support.ace_constant {\n  color: #CF6A4C\n}\n\n.ace-twilight .ace_invalid.ace_illegal {\n  color: #F8F8F8;\n  background-color: rgba(86, 45, 86, 0.75)\n}\n\n.ace-twilight .ace_invalid.ace_deprecated {\n  text-decoration: underline;\n  font-style: italic;\n  color: #D2A8A1\n}\n\n.ace-twilight .ace_support {\n  color: #9B859D\n}\n\n.ace-twilight .ace_fold {\n  background-color: #AC885B;\n  border-color: #F8F8F8\n}\n\n.ace-twilight .ace_support.ace_function {\n  color: #DAD085\n}\n\n.ace-twilight .ace_list,\n.ace-twilight .ace_markup.ace_list,\n.ace-twilight .ace_storage {\n  color: #F9EE98\n}\n\n.ace-twilight .ace_entity.ace_name.ace_function,\n.ace-twilight .ace_meta.ace_tag {\n  color: #AC885B\n}\n\n.ace-twilight .ace_string {\n  color: #8F9D6A\n}\n\n.ace-twilight .ace_string.ace_regexp {\n  color: #E9C062\n}\n\n.ace-twilight .ace_comment {\n  font-style: italic;\n  color: #5F5A60\n}\n\n.ace-twilight .ace_variable {\n  color: #7587A6\n}\n\n.ace-twilight .ace_xml-pe {\n  color: #494949\n}\n\n.ace-twilight .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-twilight .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/twilight.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-twilight\";\nexports.cssText = require(\"./twilight-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/vibrant_ink-css.js",
    "content": "module.exports = `.ace-vibrant-ink .ace_gutter {\n  background: #1a1a1a;\n  color: #BEBEBE\n}\n\n.ace-vibrant-ink .ace_print-margin {\n  width: 1px;\n  background: #1a1a1a\n}\n\n.ace-vibrant-ink {\n  background-color: #0F0F0F;\n  color: #FFFFFF\n}\n\n.ace-vibrant-ink .ace_cursor {\n  color: #FFFFFF\n}\n\n.ace-vibrant-ink .ace_marker-layer .ace_selection {\n  background: #6699CC\n}\n\n.ace-vibrant-ink.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #0F0F0F;\n}\n\n.ace-vibrant-ink .ace_marker-layer .ace_step {\n  background: rgb(102, 82, 0)\n}\n\n.ace-vibrant-ink .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #404040\n}\n\n.ace-vibrant-ink .ace_marker-layer .ace_active-line {\n  background: #333333\n}\n\n.ace-vibrant-ink .ace_gutter-active-line {\n  background-color: #333333\n}\n\n.ace-vibrant-ink .ace_marker-layer .ace_selected-word {\n  border: 1px solid #6699CC\n}\n\n.ace-vibrant-ink .ace_invisible {\n  color: #404040\n}\n\n.ace-vibrant-ink .ace_keyword,\n.ace-vibrant-ink .ace_meta {\n  color: #FF6600\n}\n\n.ace-vibrant-ink .ace_constant,\n.ace-vibrant-ink .ace_constant.ace_character,\n.ace-vibrant-ink .ace_constant.ace_character.ace_escape,\n.ace-vibrant-ink .ace_constant.ace_other {\n  color: #339999\n}\n\n.ace-vibrant-ink .ace_constant.ace_numeric {\n  color: #99CC99\n}\n\n.ace-vibrant-ink .ace_invalid,\n.ace-vibrant-ink .ace_invalid.ace_deprecated {\n  color: #CCFF33;\n  background-color: #000000\n}\n\n.ace-vibrant-ink .ace_fold {\n  background-color: #FFCC00;\n  border-color: #FFFFFF\n}\n\n.ace-vibrant-ink .ace_entity.ace_name.ace_function,\n.ace-vibrant-ink .ace_support.ace_function,\n.ace-vibrant-ink .ace_variable {\n  color: #FFCC00\n}\n\n.ace-vibrant-ink .ace_variable.ace_parameter {\n  font-style: italic\n}\n\n.ace-vibrant-ink .ace_string {\n  color: #66FF00\n}\n\n.ace-vibrant-ink .ace_string.ace_regexp {\n  color: #44B4CC\n}\n\n.ace-vibrant-ink .ace_comment {\n  color: #9933CC\n}\n\n.ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name {\n  font-style: italic;\n  color: #99CC99\n}\n\n.ace-vibrant-ink .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYNDTc/oPAALPAZ7hxlbYAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-vibrant-ink .ace_indent-guide-active {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n`;\n"
  },
  {
    "path": "src/theme/vibrant_ink.js",
    "content": "exports.isDark = true;\nexports.cssClass = \"ace-vibrant-ink\";\nexports.cssText = require(\"./vibrant_ink-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/theme/xcode-css.js",
    "content": "module.exports = `/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: EE3AD170-2B7F-4DE1-B724-C75F13FE0085) */\n\n.ace-xcode .ace_gutter {\n  background: #e8e8e8;\n  color: #333\n}\n\n.ace-xcode .ace_print-margin {\n  width: 1px;\n  background: #e8e8e8\n}\n\n.ace-xcode {\n  background-color: #FFFFFF;\n  color: #000000\n}\n\n.ace-xcode .ace_cursor {\n  color: #000000\n}\n\n.ace-xcode .ace_marker-layer .ace_selection {\n  background: #B5D5FF\n}\n\n.ace-xcode.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px #FFFFFF;\n}\n\n.ace-xcode .ace_marker-layer .ace_step {\n  background: rgb(198, 219, 174)\n}\n\n.ace-xcode .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid #BFBFBF\n}\n\n.ace-xcode .ace_marker-layer .ace_active-line {\n  background: rgba(0, 0, 0, 0.071)\n}\n\n.ace-xcode .ace_gutter-active-line {\n  background-color: rgba(0, 0, 0, 0.071)\n}\n\n.ace-xcode .ace_marker-layer .ace_selected-word {\n  border: 1px solid #B5D5FF\n}\n\n.ace-xcode .ace_constant.ace_language,\n.ace-xcode .ace_keyword,\n.ace-xcode .ace_meta,\n.ace-xcode .ace_variable.ace_language {\n  color: #C800A4\n}\n\n.ace-xcode .ace_invisible {\n  color: #BFBFBF\n}\n\n.ace-xcode .ace_constant.ace_character,\n.ace-xcode .ace_constant.ace_other {\n  color: #275A5E\n}\n\n.ace-xcode .ace_constant.ace_numeric {\n  color: #3A00DC\n}\n\n.ace-xcode .ace_entity.ace_other.ace_attribute-name,\n.ace-xcode .ace_support.ace_constant,\n.ace-xcode .ace_support.ace_function {\n  color: #450084\n}\n\n.ace-xcode .ace_fold {\n  background-color: #C800A4;\n  border-color: #000000\n}\n\n.ace-xcode .ace_entity.ace_name.ace_tag,\n.ace-xcode .ace_support.ace_class,\n.ace-xcode .ace_support.ace_type {\n  color: #790EAD\n}\n\n.ace-xcode .ace_storage {\n  color: #C900A4\n}\n\n.ace-xcode .ace_string {\n  color: #DF0002\n}\n\n.ace-xcode .ace_comment {\n  color: #008E00\n}\n\n.ace-xcode .ace_indent-guide {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y\n}\n\n.ace-xcode .ace_indent-guide-active {\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC\") right repeat-y;\n} \n`;\n"
  },
  {
    "path": "src/theme/xcode.js",
    "content": "exports.isDark = false;\nexports.cssClass = \"ace-xcode\";\nexports.cssText = require(\"./xcode-css\");\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "src/token_iterator.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n */\n\nvar Range = require(\"./range\").Range;\n\n/**\n * This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.\n **/\nclass TokenIterator {\n    /**\n     * Creates a new token iterator object. The inital token index is set to the provided row and column coordinates.\n     * @param {EditSession} session The session to associate with\n     * @param {Number} initialRow The row to start the tokenizing at\n     * @param {Number} initialColumn The column to start the tokenizing at\n     **/\n    constructor(session, initialRow, initialColumn) {\n        this.$session = session;\n        this.$row = initialRow;\n        this.$rowTokens = session.getTokens(initialRow);\n\n        var token = session.getTokenAt(initialRow, initialColumn);\n        this.$tokenIndex = token ? token.index : -1;\n    }\n    \n    /**\n     * Moves iterator position to the start of previous token.\n     * @returns {import(\"../ace-internal\").Ace.Token|null}\n     **/ \n    stepBackward() {\n        this.$tokenIndex -= 1;\n        \n        while (this.$tokenIndex < 0) {\n            this.$row -= 1;\n            if (this.$row < 0) {\n                this.$row = 0;\n                return null;\n            }\n                \n            this.$rowTokens = this.$session.getTokens(this.$row);\n            this.$tokenIndex = this.$rowTokens.length - 1;\n        }\n            \n        return this.$rowTokens[this.$tokenIndex];\n    }\n\n    /**\n     * Moves iterator position to the start of next token.\n     * @returns {import(\"../ace-internal\").Ace.Token|null}\n     **/   \n    stepForward() {\n        this.$tokenIndex += 1;\n        var rowCount;\n        while (this.$tokenIndex >= this.$rowTokens.length) {\n            this.$row += 1;\n            if (!rowCount)\n                rowCount = this.$session.getLength();\n            if (this.$row >= rowCount) {\n                this.$row = rowCount - 1;\n                return null;\n            }\n\n            this.$rowTokens = this.$session.getTokens(this.$row);\n            this.$tokenIndex = 0;\n        }\n            \n        return this.$rowTokens[this.$tokenIndex];\n    }\n \n    /**\n     * \n     * Returns current token.\n     * @returns {import(\"../ace-internal\").Ace.Token}\n     **/      \n    getCurrentToken() {\n        return this.$rowTokens[this.$tokenIndex];\n    }\n\n    /**\n     * \n     * Returns the current row.\n     * @returns {Number}\n     **/      \n    getCurrentTokenRow() {\n        return this.$row;\n    }\n\n    /**\n     * \n     * Returns the current column.\n     * @returns {Number}\n     **/     \n    getCurrentTokenColumn() {\n        var rowTokens = this.$rowTokens;\n        var tokenIndex = this.$tokenIndex;\n        \n        // If a column was cached by EditSession.getTokenAt, then use it\n        var column = rowTokens[tokenIndex].start;\n        if (column !== undefined)\n            return column;\n            \n        column = 0;\n        while (tokenIndex > 0) {\n            tokenIndex -= 1;\n            column += rowTokens[tokenIndex].value.length;\n        }\n        \n        return column;  \n    }\n\n    /**\n     * Return the current token position.\n     * @returns {import(\"../ace-internal\").Ace.Point}\n     */\n    getCurrentTokenPosition() {\n        return {row: this.$row, column: this.getCurrentTokenColumn()};\n    }\n    \n    /**\n     * Return the current token range.\n     * @returns {Range}\n     */\n    getCurrentTokenRange() {\n        var token = this.$rowTokens[this.$tokenIndex];\n        var column = this.getCurrentTokenColumn();\n        return new Range(this.$row, column, this.$row, column + token.value.length);\n    }\n    \n}\n\nexports.TokenIterator = TokenIterator;\n"
  },
  {
    "path": "src/token_iterator_test.js",
    "content": "\"use strict\";\n\nvar EditSession = require(\"./edit_session\").EditSession;\nvar JavaScriptMode = require(\"./mode/javascript\").Mode;\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\nvar assert = require(\"./test/assertions\");\n\nmodule.exports = {\n    \"test: token iterator initialization in JavaScript document\" : function() {\n        var lines = [\n            \"function foo(items) {\",\n            \"    for (var i=0; i<items.length; i++) {\",\n            \"        alert(items[i] + \\\"juhu\\\");\",\n            \"    } // Real Tab.\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        var iterator = new TokenIterator(session, 0, 0);\n        assert.equal(iterator.getCurrentToken().value, \"function\");\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        iterator.stepForward();\n        assert.equal(iterator.getCurrentToken().value, \" \");\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 8);\n\n        var iterator = new TokenIterator(session, 0, 4);\n        assert.equal(iterator.getCurrentToken().value, \"function\");\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        iterator.stepForward();\n        assert.equal(iterator.getCurrentToken().value, \" \");\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 8);\n\n        var iterator = new TokenIterator(session, 2, 18);\n        assert.equal(iterator.getCurrentToken().value, \"items\");\n        assert.equal(iterator.getCurrentTokenRow(), 2);\n        assert.equal(iterator.getCurrentTokenColumn(), 14);\n\n        iterator.stepForward();\n        assert.equal(iterator.getCurrentToken().value, \"[\");\n        assert.equal(iterator.getCurrentTokenRow(), 2);\n        assert.equal(iterator.getCurrentTokenColumn(), 19);\n\n        var iterator = new TokenIterator(session, 4, 0);\n        assert.equal(iterator.getCurrentToken().value, \"}\");\n        assert.equal(iterator.getCurrentTokenRow(), 4);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        iterator.stepBackward();\n        assert.equal(iterator.getCurrentToken().value, \"// Real Tab.\");\n        assert.equal(iterator.getCurrentTokenRow(), 3);\n        assert.equal(iterator.getCurrentTokenColumn(), 6);\n\n        var iterator = new TokenIterator(session, 5, 0);\n        assert.equal(iterator.getCurrentToken(), null);\n    },\n\n    \"test: token iterator initialization in text document\" : function() {\n        var lines = [\n            \"Lorem ipsum dolor sit amet, consectetur adipisicing elit,\",\n            \"sed do eiusmod tempor incididunt ut labore et dolore magna\",\n            \"aliqua. Ut enim ad minim veniam, quis nostrud exercitation\",\n            \"ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"));\n\n        var iterator = new TokenIterator(session, 0, 0);\n        assert.equal(iterator.getCurrentToken().value, lines[0]);\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        var iterator = new TokenIterator(session, 0, 4);\n        assert.equal(iterator.getCurrentToken().value, lines[0]);\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        var iterator = new TokenIterator(session, 2, 18);\n        assert.equal(iterator.getCurrentToken().value, lines[2]);\n        assert.equal(iterator.getCurrentTokenRow(), 2);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        var iterator = new TokenIterator(session, 3, lines[3].length-1);\n        assert.equal(iterator.getCurrentToken().value, lines[3]);\n        assert.equal(iterator.getCurrentTokenRow(), 3);\n        assert.equal(iterator.getCurrentTokenColumn(), 0);\n\n        var iterator = new TokenIterator(session, 4, 0);\n        assert.equal(iterator.getCurrentToken(), null);\n    },\n\n    \"test: token iterator step forward in JavaScript document\" : function() {\n        var lines = [\n            \"function foo(items) {\",\n            \"    for (var i=0; i<items.length; i++) {\",\n            \"        alert(items[i] + \\\"juhu\\\");\",\n            \"    } // Real Tab.\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        var tokens = [];\n        var len = session.getLength();\n        for (var i = 0; i < len; i++)\n            tokens = tokens.concat(session.getTokens(i));\n\n        var iterator = new TokenIterator(session, 0, 0);\n        for (var i = 1; i < tokens.length; i++)\n            assert.equal(iterator.stepForward(), tokens[i]);\n        assert.equal(iterator.stepForward(), null);\n        assert.equal(iterator.getCurrentToken(), null);\n    },\n\n    \"test: token iterator step backward in JavaScript document\" : function() {\n        var lines = [\n            \"function foo(items) {\",\n            \"     for (var i=0; i<items.length; i++) {\",\n            \"         alert(items[i] + \\\"juhu\\\");\",\n            \"     } // Real Tab.\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        var tokens = [];\n        var len = session.getLength();\n        for (var i = 0; i < len; i++)\n            tokens = tokens.concat(session.getTokens(i));\n\n        var iterator = new TokenIterator(session, 4, 0);\n        for (var i = tokens.length-2; i >= 0; i--)\n            assert.equal(iterator.stepBackward(), tokens[i]);\n        assert.equal(iterator.stepBackward(), null);\n        assert.equal(iterator.getCurrentToken(), null);\n    },\n\n    \"test: token iterator reports correct row and column\" : function() {\n        var lines = [\n            \"function foo(items) {\",\n            \"    for (var i=0; i<items.length; i++) {\",\n            \"        alert(items[i] + \\\"juhu\\\");\",\n            \"    } // Real Tab.\",\n            \"}\"\n        ];\n        var session = new EditSession(lines.join(\"\\n\"), new JavaScriptMode());\n\n        var iterator = new TokenIterator(session, 0, 0);\n\n        iterator.stepForward();\n        iterator.stepForward();\n\n        assert.equal(iterator.getCurrentToken().value, \"foo\");\n        assert.equal(iterator.getCurrentTokenRow(), 0);\n        assert.equal(iterator.getCurrentTokenColumn(), 9);\n\n        iterator.stepForward();\n        iterator.stepForward();\n        iterator.stepForward();\n        iterator.stepForward();\n        iterator.stepForward();\n        iterator.stepForward();\n        iterator.stepForward();\n\n        assert.equal(iterator.getCurrentToken().value, \"for\");\n        assert.equal(iterator.getCurrentTokenRow(), 1);\n        assert.equal(iterator.getCurrentTokenColumn(), 4);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/tokenizer.js",
    "content": "\"use strict\";\nconst reportError = require(\"./lib/report_error\").reportError;\n\n// tokenizing lines longer than this makes editor very slow\nvar MAX_TOKEN_COUNT = 2000;\n/**\n * This class takes a set of highlighting rules, and creates a tokenizer out of them. For more information, see [the wiki on extending highlighters](https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-extendingTheHighlighter).\n **/\nclass Tokenizer {\n    /**\n     * Constructs a new tokenizer based on the given rules and flags.\n     * @param {Object} rules The highlighting rules\n     **/\n    constructor(rules) {\n        /**@type {RegExp}*/\n        this.splitRegex;\n        this.states = rules;\n\n        this.regExps = {};\n        this.matchMappings = {};\n        for (var key in this.states) {\n            var state = this.states[key];\n            var ruleRegExps = [];\n            var matchTotal = 0;\n            var mapping = this.matchMappings[key] = {defaultToken: \"text\"};\n            var flag = \"g\";\n\n            var splitterRurles = [];\n            for (var i = 0; i < state.length; i++) {\n                var rule = state[i];\n                if (rule.defaultToken)\n                    mapping.defaultToken = rule.defaultToken;\n                if (rule.caseInsensitive && flag.indexOf(\"i\") === -1)\n                    flag += \"i\";\n                if (rule.unicode && flag.indexOf(\"u\") === -1)\n                    flag += \"u\";\n                if (rule.regex == null)\n                    continue;\n\n                if (rule.regex instanceof RegExp)\n                    rule.regex = rule.regex.toString().slice(1, -1);\n\n                // Count number of matching groups. 2 extra groups from the full match\n                // And the catch-all on the end (used to force a match);\n                var adjustedregex = rule.regex;\n                var matchcount = new RegExp(\"(?:(\" + adjustedregex + \")|(.))\").exec(\"a\").length - 2;\n                if (Array.isArray(rule.token)) {\n                    if (rule.token.length == 1 || matchcount == 1) {\n                        rule.token = rule.token[0];\n                    } else if (matchcount - 1 != rule.token.length) {\n                        this.reportError(\"number of classes and regexp groups doesn't match\", {\n                            rule: rule,\n                            groupCount: matchcount - 1\n                        });\n                        rule.token = rule.token[0];\n                    } else {\n                        rule.tokenArray = rule.token;\n                        rule.token = null;\n                        rule.onMatch = this.$arrayTokens;\n                    }\n                } else if (typeof rule.token == \"function\" && !rule.onMatch) {\n                    if (matchcount > 1)\n                        rule.onMatch = this.$applyToken;\n                    else\n                        rule.onMatch = rule.token;\n                }\n\n                if (matchcount > 1) {\n                    if (/\\\\\\d/.test(rule.regex)) {\n                        // Replace any backreferences and offset appropriately.\n                        adjustedregex = rule.regex.replace(/\\\\([0-9]+)/g, function(match, digit) {\n                            return \"\\\\\" + (parseInt(digit, 10) + matchTotal + 1);\n                        });\n                    } else {\n                        matchcount = 1;\n                        adjustedregex = this.removeCapturingGroups(rule.regex);\n                    }\n                    if (!rule.splitRegex && typeof rule.token != \"string\")\n                        splitterRurles.push(rule); // flag will be known only at the very end\n                }\n\n                mapping[matchTotal] = i;\n                matchTotal += matchcount;\n\n                ruleRegExps.push(adjustedregex);\n\n                // makes property access faster\n                if (!rule.onMatch)\n                    rule.onMatch = null;\n            }\n\n            if (!ruleRegExps.length) {\n                mapping[0] = 0;\n                ruleRegExps.push(\"$\");\n            }\n\n            splitterRurles.forEach(function(rule) {\n                rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);\n            }, this);\n\n            this.regExps[key] = new RegExp(\"(\" + ruleRegExps.join(\")|(\") + \")|($)\", flag);\n        }\n    }\n\n    /**\n     * @param {number} m\n     */\n    $setMaxTokenCount(m) {\n        MAX_TOKEN_COUNT = m | 0;\n    }\n\n    /**\n     * @param {string} str\n     * @return {import(\"../ace-internal\").Ace.Token[]}\n     */\n    $applyToken(str) {\n        var values = this.splitRegex.exec(str).slice(1);\n        //@ts-ignore\n        var types = this.token.apply(this, values);\n\n        // required for compatibility with old modes\n        if (typeof types === \"string\")\n            return [{type: types, value: str}];\n\n        var tokens = [];\n        for (var i = 0, l = types.length; i < l; i++) {\n            if (values[i])\n                tokens[tokens.length] = {\n                    type: types[i],\n                    value: values[i]\n                };\n        }\n        return tokens;\n    }\n\n    /**\n     * @param {string} str\n     * @return {import(\"../ace-internal\").Ace.Token[] | string}\n     */\n    $arrayTokens(str) {\n        if (!str)\n            return [];\n        var values = this.splitRegex.exec(str);\n        if (!values)\n            return \"text\";\n        var tokens = [];\n        //@ts-ignore\n        var types = this.tokenArray;\n        for (var i = 0, l = types.length; i < l; i++) {\n            if (values[i + 1])\n                tokens[tokens.length] = {\n                    type: types[i],\n                    value: values[i + 1]\n                };\n        }\n        return tokens;\n    }\n\n    /**\n     * @param {string} src\n     * @returns {string}\n     */\n    removeCapturingGroups(src) {\n        var r = src.replace(\n            /\\\\.|\\[(?:\\\\.|[^\\\\\\]])*|\\(\\?[:=!<]|(\\()/g,\n            function(x, y) {return y ? \"(?:\" : x;}\n        );\n        return r;\n    }\n\n    /**\n     * @param {string} src\n     * @param {string} flag\n     */\n    createSplitterRegexp(src, flag) {\n        if (src.indexOf(\"(?=\") != -1) {\n            var stack = 0;\n            var inChClass = false;\n            var lastCapture = {};\n            src.replace(/(\\\\.)|(\\((?:\\?[=!])?)|(\\))|([\\[\\]])/g, function(\n                m, esc, parenOpen, parenClose, square, index\n            ) {\n                if (inChClass) {\n                    inChClass = square != \"]\";\n                } else if (square) {\n                    inChClass = true;\n                } else if (parenClose) {\n                    if (stack == lastCapture.stack) {\n                        lastCapture.end = index+1;\n                        lastCapture.stack = -1;\n                    }\n                    stack--;\n                } else if (parenOpen) {\n                    stack++;\n                    if (parenOpen.length != 1) {\n                        lastCapture.stack = stack;\n                        lastCapture.start = index;\n                    }\n                }\n                return m;\n            });\n\n            if (lastCapture.end != null && /^\\)*$/.test(src.substr(lastCapture.end)))\n                src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);\n        }\n        \n        // this is needed for regexps that can match in multiple ways\n        if (src.charAt(0) != \"^\") src = \"^\" + src;\n        if (src.charAt(src.length - 1) != \"$\") src += \"$\";\n        \n        return new RegExp(src, (flag||\"\").replace(\"g\", \"\"));\n    }\n\n    /**\n     * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.\n     * @param {string} line\n     * @param {string | string[]} startState\n     * @returns {{tokens:import(\"../ace-internal\").Ace.Token[], state: string|string[]}}\n     */\n    getLineTokens(line, startState) {\n        if (startState && typeof startState != \"string\") {\n            /**@type {any[]}*/\n            var stack = startState.slice(0);\n            startState = stack[0];\n            if (startState === \"#tmp\") {\n                stack.shift();\n                startState = stack.shift();\n            }\n        } else\n            var stack = [];\n\n        var currentState = /**@type{string}*/(startState) || \"start\";\n        var state = this.states[currentState];\n        if (!state) {\n            currentState = \"start\";\n            state = this.states[currentState];\n        }\n        var mapping = this.matchMappings[currentState];\n        var re = this.regExps[currentState];\n        re.lastIndex = 0;\n\n        var match, tokens = [];\n        var lastIndex = 0;\n        var matchAttempts = 0;\n\n        var token = {type: null, value: \"\"};\n\n        while (match = re.exec(line)) {\n            var type = mapping.defaultToken;\n            var rule = null;\n            var value = match[0];\n            var index = re.lastIndex;\n\n            if (index - value.length > lastIndex) {\n                var skipped = line.substring(lastIndex, index - value.length);\n                if (token.type == type) {\n                    token.value += skipped;\n                } else {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: type, value: skipped};\n                }\n            }\n\n            for (var i = 0; i < match.length-2; i++) {\n                if (match[i + 1] === undefined)\n                    continue;\n\n                rule = state[mapping[i]];\n\n                if (rule.onMatch)\n                    type = rule.onMatch(value, currentState, stack, line);\n                else\n                    type = rule.token;\n\n                if (rule.next) {\n                    if (typeof rule.next == \"string\") {\n                        currentState = rule.next;\n                    } else {\n                        currentState = rule.next(currentState, stack);\n                    }\n                    \n                    state = this.states[currentState];\n                    if (!state) {\n                        this.reportError(\"state doesn't exist\", currentState);\n                        currentState = \"start\";\n                        state = this.states[currentState];\n                    }\n                    mapping = this.matchMappings[currentState];\n                    lastIndex = index;\n                    re = this.regExps[currentState];\n                    re.lastIndex = index;\n                }\n                if (rule.consumeLineEnd)\n                    lastIndex = index;\n                break;\n            }\n\n            if (value) {\n                if (typeof type === \"string\") {\n                    if ((!rule || rule.merge !== false) && token.type === type) {\n                        token.value += value;\n                    } else {\n                        if (token.type)\n                            tokens.push(token);\n                        token = {type: type, value: value};\n                    }\n                } else if (type) {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: null, value: \"\"};\n                    for (var i = 0; i < type.length; i++)\n                        tokens.push(type[i]);\n                }\n            }\n\n            if (lastIndex == line.length)\n                break;\n\n            lastIndex = index;\n\n            if (matchAttempts++ > MAX_TOKEN_COUNT) {\n                if (matchAttempts > 2 * line.length) {\n                    this.reportError(\"infinite loop with in ace tokenizer\", {\n                        startState: startState,\n                        line: line\n                    });\n                }\n                // chrome doens't show contents of text nodes with very long text\n                while (lastIndex < line.length) {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {\n                        value: line.substring(lastIndex, lastIndex += 500),\n                        type: \"overflow\"\n                    };\n                }\n                currentState = \"start\";\n                stack = [];\n                break;\n            }\n        }\n\n        if (token.type)\n            tokens.push(token);\n        \n        if (stack.length > 1) {\n            if (stack[0] !== currentState)\n                stack.unshift(\"#tmp\", currentState);\n        }\n        return {\n            tokens : tokens,\n            state : stack.length ? stack : currentState\n        };\n    }\n}\n\nTokenizer.prototype.reportError = reportError;\nexports.Tokenizer = Tokenizer;\n"
  },
  {
    "path": "src/tokenizer_dev.js",
    "content": "var BaseTokenizer = require(\"./tokenizer\").Tokenizer;\n\n// tokenizing lines longer than this makes editor very slow\nvar MAX_TOKEN_COUNT = 2000;\n/*\n * version of Tokenizer with additional logging\n * and infinite loop checks\n * can be used for developing/testing new modes\n **/\n\nclass Tokenizer extends BaseTokenizer {\n    \n    /**\n     * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.\n     * @returns {Object}\n     **/\n    getLineTokens(line, startState) {\n        if (startState && typeof startState != \"string\") {\n            /**@type {any[]}*/\n            var stack = startState.slice(0);\n            startState = stack[0];\n        } else\n            var stack = [];\n\n        var currentState = startState || \"start\";\n        var state = this.states[currentState];\n        var mapping = this.matchMappings[currentState];\n        var re = this.regExps[currentState];\n        re.lastIndex = 0;\n\n        var match, tokens = [];\n\n        var lastIndex = 0;\n\n        var stateTransitions = [];\n        function onStateChange() {\n            stateTransitions.push(startState+\"@\"+lastIndex);\n        }\n        function initState() {\n            onStateChange();\n            stateTransitions = [];\n            onStateChange();\n        }\n\n        /**@type {any}*/\n        var token = {\n            type: null,\n            value: \"\",\n            state: currentState\n        };\n        initState();\n        \n        var maxRecur = 20000;\n        \n        while (match = re.exec(line)) {\n            var type = mapping.defaultToken;\n            var rule = null;\n            var value = match[0];\n            var index = re.lastIndex;\n\n            if (index - value.length > lastIndex) {\n                var skipped = line.substring(lastIndex, index - value.length);\n                if (token.type == type) {\n                    token.value += skipped;\n                } else {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: type, value: skipped};\n                }\n            }\n\n            for (var i = 0; i < match.length-2; i++) {\n                if (match[i + 1] === undefined)\n                    continue;\n                \n                if (!maxRecur--) {\n                    throw \"infinite\" + state[mapping[i]] + currentState;\n                }\n\n                rule = state[mapping[i]];\n\n                if (rule.onMatch)\n                    type = rule.onMatch(value, currentState, stack, line);\n                else\n                    type = rule.token;\n\n                if (rule.next) {\n                    if (typeof rule.next == \"string\")\n                        currentState = rule.next;\n                    else\n                        currentState = rule.next(currentState, stack);\n\n                    state = this.states[currentState];\n                    if (!state) {\n                        window.console && console.error && console.error(currentState, \"doesn't exist\");\n                        currentState = \"start\";\n                        state = this.states[currentState];\n                    }\n                    mapping = this.matchMappings[currentState];\n                    lastIndex = index;\n                    re = this.regExps[currentState];\n                    re.lastIndex = index;\n\n                    onStateChange();\n                }\n                if (rule.consumeLineEnd)\n                    lastIndex = index;\n                break;\n            }\n\n            if (value) {\n                if (typeof type == \"string\") {\n                    if ((!rule || rule.merge !== false) && token.type === type) {\n                        token.value += value;\n                    } else {\n                        if (token.type)\n                            tokens.push(token);\n                        token = {type: type, value: value};\n                    }\n                } else {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: null, value: \"\"};\n                    for (var i = 0; i < type.length; i++)\n                        tokens.push(type[i]);\n                }\n            }\n\n            if (lastIndex == line.length)\n                break;\n\n            lastIndex = index;\n\n            if (tokens.length > MAX_TOKEN_COUNT) {\n                token.value += line.substr(lastIndex);\n                currentState = \"start\";\n                break;\n            }\n        }\n\n        if (token.type)\n            tokens.push(token);\n\n        return {\n            tokens : tokens,\n            state : stack.length ? stack : currentState\n        };\n    }\n\n}\n\nTokenizer.prototype = BaseTokenizer.prototype;\n\nexports.Tokenizer = Tokenizer;\n"
  },
  {
    "path": "src/tokenizer_test.js",
    "content": "\"use strict\";\n\nvar Tokenizer = require(\"./tokenizer\").Tokenizer;\nvar assert = require(\"./test/assertions\");\n\nmodule.exports = {\n    \"test: createSplitterRegexp\" : function() {\n        var t = new Tokenizer({});\n        var re = t.createSplitterRegexp(\"(a)(b)(?=[x)(])\");\n        assert.equal(re.source, \"^(a)(b)$\");\n        var re = t.createSplitterRegexp(\"xc(?=([x)(]))\");\n        assert.equal(re.source, \"^xc$\");\n        var re = t.createSplitterRegexp(\"(xc(?=([x)(])))\");\n        assert.equal(re.source, \"^(xc)$\");\n        var re = t.createSplitterRegexp(\"(?=r)[(?=)](?=([x)(]))\");\n        assert.equal(re.source, \"^(?=r)[(?=)]$\");\n        var re = t.createSplitterRegexp(\"(?=r)[(?=)](\\\\?=t)\");\n        assert.equal(re.source, \"^(?=r)[(?=)](\\\\?=t)$\");\n        var re = t.createSplitterRegexp(\"[(?=)](\\\\?=t)\");\n        assert.equal(re.source, \"^[(?=)](\\\\?=t)$\");\n    },\n\n    \"test: removeCapturingGroups\" : function() {\n        var t = new Tokenizer({});\n        var re = t.removeCapturingGroups(\"(ax(by))[()]\");\n        assert.equal(re, \"(?:ax(?:by))[()]\");\n    },\n    \n    \"test: broken highlight rules\": function() {\n        var t = new Tokenizer({\n            start: [{ \n                token: 's',\n                regex: '&&&|^^^' \n            }, {\n                defaultToken: \"def\"\n            }],\n            state1: [{ \n                token: 'x',\n                regex: /\\b([\\w]*)(\\s*)((?::)?)/\n            }]\n        });\n        var errorReports = 0;\n        t.reportError = function() { errorReports++; };\n        var tokens = t.getLineTokens(\"x|\", \"start\");\n        assert.deepEqual(tokens, {\n            tokens: [{value: 'x|', type: 'overflow'}],\n            state: 'start'\n        });\n        var tokens = t.getLineTokens(\"x|\", \"state1\");\n        assert.deepEqual(tokens, {\n            tokens: [{value: 'x', type: 'x'}, {value: '|', type: 'overflow'}],\n            state: 'start'\n        });\n        assert.equal(errorReports, 2);\n    } \n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/tooltip.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./editor\").Editor} Editor\n * @typedef {import(\"./mouse/mouse_event\").MouseEvent} MouseEvent\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n */\n\nvar dom = require(\"./lib/dom\");\nvar event = require(\"./lib/event\");\nvar Range = require(\"./range\").Range;\nvar preventParentScroll = require(\"./lib/scroll\").preventParentScroll;\n\nvar CLASSNAME = \"ace_tooltip\";\n\nclass Tooltip {\n    /**\n     * @param {Element} parentNode\n     **/\n    constructor(parentNode) {\n        this.isOpen = false;\n        this.$element = null;\n        this.$parentNode = parentNode;\n    }\n\n    $init() {\n        this.$element = dom.createElement(\"div\");\n        this.$element.className = CLASSNAME;\n        this.$element.style.display = \"none\";\n        this.$parentNode.appendChild(this.$element);\n        return this.$element;\n    }\n\n    /**\n     * @returns {HTMLElement}\n     **/\n    getElement() {\n        return this.$element || this.$init();\n    }\n\n    /**\n     * @param {String} text\n     **/\n    setText(text) {\n        this.getElement().textContent = text;\n    }\n\n    /**\n     * @param {String} html\n     **/\n    setHtml(html) {\n        this.getElement().innerHTML = html;\n    }\n\n    /**\n     * @param {Number} x\n     * @param {Number} y\n     **/\n    setPosition(x, y) {\n        this.getElement().style.left = x + \"px\";\n        this.getElement().style.top = y + \"px\";\n    }\n\n    /**\n     * @param {String} className\n     **/\n    setClassName(className) {\n        dom.addCssClass(this.getElement(), className);\n    }\n\n    /**\n     * @param {import(\"../ace-internal\").Ace.Theme} theme\n     */\n    setTheme(theme) {\n        if (this.theme) {\n            this.theme.isDark && dom.removeCssClass(this.getElement(), \"ace_dark\");\n            this.theme.cssClass && dom.removeCssClass(this.getElement(), this.theme.cssClass);\n        }\n        if (theme.isDark) {\n            dom.addCssClass(this.getElement(), \"ace_dark\");\n        }\n        if (theme.cssClass) {\n            dom.addCssClass(this.getElement(), theme.cssClass);\n        }\n        this.theme = {\n            isDark: theme.isDark,\n            cssClass: theme.cssClass\n        };\n    }\n\n    /**\n     * @param {String} [text]\n     * @param {Number} [x]\n     * @param {Number} [y]\n     **/\n    show(text, x, y) {\n        if (text != null)\n            this.setText(text);\n        if (x != null && y != null)\n            this.setPosition(x, y);\n        if (!this.isOpen) {\n            this.getElement().style.display = \"block\";\n            this.isOpen = true;\n        }\n    }\n\n    hide(e) {\n        if (this.isOpen) {\n            this.getElement().style.display = \"none\";\n            this.getElement().className = CLASSNAME;\n            this.isOpen = false;\n        }\n    }\n\n    /**\n     * @returns {Number}\n     **/\n    getHeight() {\n        return this.getElement().offsetHeight;\n    }\n\n    /**\n     * @returns {Number}\n     **/\n    getWidth() {\n        return this.getElement().offsetWidth;\n    }\n\n    destroy() {\n        this.isOpen = false;\n        if (this.$element && this.$element.parentNode) {\n            this.$element.parentNode.removeChild(this.$element);\n        }\n    }\n\n}\n\nclass PopupManager {\n    constructor () {\n        /**@type{Tooltip[]} */\n        this.popups = [];\n    }\n\n    /**\n     * @param {Tooltip} popup\n     */\n    addPopup(popup) {\n        this.popups.push(popup);\n        this.updatePopups();\n    }\n\n    /**\n     * @param {Tooltip} popup\n     */\n    removePopup(popup) {\n        var index = this.popups.indexOf(popup);\n        if (index !== -1) {\n            this.popups.splice(index, 1);\n            this.updatePopups();\n        }\n    }\n\n    updatePopups() {\n        // @ts-expect-error TODO: could be actually an error\n        this.popups.sort((a, b) => b.priority - a.priority);\n        let visiblepopups = [];\n\n        for (let popup of this.popups) {\n            let shouldDisplay = true;\n            for (let visiblePopup of visiblepopups) {\n                if (this.doPopupsOverlap(visiblePopup, popup)) {\n                    shouldDisplay = false;\n                    break;\n                }\n            }\n\n            if (shouldDisplay) {\n                visiblepopups.push(popup);\n            } else {\n                popup.hide();\n            }\n        }\n    }\n\n    /**\n     * @param {Tooltip} popupA\n     * @param {Tooltip} popupB\n     * @return {boolean}\n     */\n    doPopupsOverlap(popupA, popupB) {\n        var rectA = popupA.getElement().getBoundingClientRect();\n        var rectB = popupB.getElement().getBoundingClientRect();\n\n        return (rectA.left < rectB.right && rectA.right > rectB.left && rectA.top < rectB.bottom && rectA.bottom\n            > rectB.top);\n    }\n}\n\nvar popupManager = new PopupManager();\nexports.popupManager = popupManager;\n\nexports.Tooltip = Tooltip;\n\n\nclass HoverTooltip extends Tooltip {\n    constructor(parentNode=document.body) {\n        super(parentNode);\n\n        /**@type{ReturnType<typeof setTimeout> | undefined}*/\n        this.timeout = undefined;\n        this.lastT = 0;\n        this.idleTime = 350;\n        this.lastEvent = undefined;\n\n        this.onMouseOut = this.onMouseOut.bind(this);\n        this.onMouseMove = this.onMouseMove.bind(this);\n        this.waitForHover = this.waitForHover.bind(this);\n        this.hide = this.hide.bind(this);\n\n        var el = this.getElement();\n        el.style.whiteSpace = \"pre-wrap\";\n        el.style.pointerEvents = \"auto\";\n        el.addEventListener(\"mouseout\", this.onMouseOut);\n        el.tabIndex = -1;\n\n        el.addEventListener(\"blur\", function() {\n            if (!el.contains(document.activeElement)) this.hide();\n        }.bind(this));\n\n        el.addEventListener(\"wheel\", preventParentScroll);\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    addToEditor(editor) {\n        editor.on(\"mousemove\", this.onMouseMove);\n        editor.on(\"mousedown\", this.hide);\n        var target = editor.renderer.getMouseEventTarget();\n        if (target && typeof target.removeEventListener === \"function\") {\n            target.addEventListener(\"mouseout\", this.onMouseOut, true);\n        }\n\n    }\n\n    /**\n     * @param {Editor} editor\n     */\n    removeFromEditor(editor) {\n        editor.off(\"mousemove\", this.onMouseMove);\n        editor.off(\"mousedown\", this.hide);\n        var target = editor.renderer.getMouseEventTarget();\n        if (target && typeof target.removeEventListener === \"function\") {\n            target.removeEventListener(\"mouseout\", this.onMouseOut, true);\n        }\n        if (this.timeout) {\n            clearTimeout(this.timeout);\n            this.timeout = null;\n        }\n    }\n\n    /**\n     * @param {MouseEvent} e\n     * @param {Editor} editor\n     * @internal\n     */\n    onMouseMove(e, editor) {\n        this.lastEvent = e;\n        this.lastT = Date.now();\n        var isMousePressed = editor.$mouseHandler.isMousePressed;\n        if (this.isOpen) {\n            var pos = this.lastEvent && this.lastEvent.getDocumentPosition();\n            if (\n                !this.range\n                || !this.range.contains(pos.row, pos.column)\n                || isMousePressed\n                || this.isOutsideOfText(this.lastEvent)\n            ) {\n                this.hide();\n            }\n        }\n        if (this.timeout || isMousePressed) return;\n        this.lastEvent = e;\n        this.timeout = setTimeout(this.waitForHover, this.idleTime);\n    }\n    waitForHover() {\n        if (this.timeout) clearTimeout(this.timeout);\n        var dt = Date.now() - this.lastT;\n        if (this.idleTime - dt > 10) {\n            this.timeout = setTimeout(this.waitForHover, this.idleTime - dt);\n            return;\n        }\n\n        this.timeout = null;\n        if (this.lastEvent && !this.isOutsideOfText(this.lastEvent)) {\n            this.$gatherData(this.lastEvent, this.lastEvent.editor);\n        }\n    }\n\n    /**\n     * @param {MouseEvent} e\n     */\n    isOutsideOfText(e) {\n        var editor = e.editor;\n        var docPos = e.getDocumentPosition();\n        var line = editor.session.getLine(docPos.row);\n        if (docPos.column == line.length) {\n            var screenPos = editor.renderer.pixelToScreenCoordinates(e.clientX, e.clientY);\n            var clippedPos = editor.session.documentToScreenPosition(docPos.row, docPos.column);\n            if (\n                clippedPos.column != screenPos.column\n                || clippedPos.row != screenPos.row\n            ) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * @param {(event: MouseEvent, editor: Editor) => void} value\n     */\n    setDataProvider(value) {\n        this.$gatherData = value;\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {Range} range\n     * @param {HTMLElement} domNode\n     * @param {MouseEvent} [startingEvent]\n     */\n    showForRange(editor, range, domNode, startingEvent) {\n        if (startingEvent && startingEvent != this.lastEvent) return;\n        if (this.isOpen && document.activeElement == this.getElement()) return;\n\n        var renderer = editor.renderer;\n        if (!this.isOpen) {\n            popupManager.addPopup(this);\n            this.$registerCloseEvents();\n            this.setTheme(renderer.theme);\n        }\n        this.isOpen = true;\n\n        this.range = Range.fromPoints(range.start, range.end);\n        var position = renderer.textToScreenCoordinates(range.start.row, range.start.column);\n\n        var rect = renderer.scroller.getBoundingClientRect();\n        // clip position to visible area of the editor\n        if (position.pageX < rect.left) position.pageX = rect.left;\n\n        var element = this.getElement();\n        element.innerHTML = \"\";\n        element.appendChild(domNode);\n\n        element.style.maxHeight = \"\";\n        element.style.display = \"block\";\n\n        this.$setPosition(editor, position, true, range);\n        \n        dom.$fixPositionBug(element);\n    }\n\n    /**\n     * @param {Editor} editor\n     * @param {{pageX: number;pageY: number;}} position\n     * @param {boolean} withMarker\n     * @param {Range} [range]\n     */\n    $setPosition(editor, position, withMarker, range) {\n        var MARGIN = 10;\n\n        withMarker && this.addMarker(range, editor.session);\n\n        var renderer = editor.renderer;\n        var element = this.getElement();\n\n        // measure the size of tooltip, without constraints on its height\n        var labelHeight = element.offsetHeight;\n        var labelWidth = element.offsetWidth;\n        var anchorTop = position.pageY;\n        var anchorLeft = position.pageX;\n        var spaceBelow = window.innerHeight - anchorTop - renderer.lineHeight;\n\n        // if tooltip fits above the line, or space below the line is smaller, show tooltip above\n        var isAbove = this.$shouldPlaceAbove(labelHeight, anchorTop, spaceBelow - MARGIN);\n\n        element.style.maxHeight = (isAbove ? anchorTop : spaceBelow) - MARGIN + \"px\";\n        element.style.top = isAbove ? \"\" : anchorTop + renderer.lineHeight + \"px\";\n        element.style.bottom = isAbove ? window.innerHeight - anchorTop + \"px\" : \"\";\n\n        // try to align tooltip left with the range, but keep it on screen\n        element.style.left = Math.min(anchorLeft, window.innerWidth - labelWidth - MARGIN) + \"px\";\n    }\n\n    /**\n     * @param {number} labelHeight\n     * @param {number} anchorTop\n     * @param {number} spaceBelow\n     */\n    $shouldPlaceAbove(labelHeight, anchorTop, spaceBelow) {\n        return !(anchorTop - labelHeight < 0 && anchorTop < spaceBelow);\n    }\n\n    /**\n     * @param {Range} range\n     * @param {EditSession} [session]\n     */\n    addMarker(range, session) {\n        if (this.marker) {\n            this.$markerSession.removeMarker(this.marker);\n        }\n        this.$markerSession = session;\n        this.marker = session && session.addMarker(range, \"ace_highlight-marker\", \"text\");\n    }\n\n    hide(e) {\n        if (e && this.$fromKeyboard && e.type == \"keydown\") {\n            if (e.code == \"Escape\") {\n                return;\n            }\n        }\n\n        if (!e && document.activeElement == this.getElement()) return;\n        if (e && e.target && (e.type != \"keydown\" || e.ctrlKey || e.metaKey) && this.$element.contains(\n            e.target)) return;\n        this.lastEvent = null;\n        if (this.timeout) clearTimeout(this.timeout);\n        this.timeout = null;\n        this.addMarker(null);\n        if (this.isOpen) {\n            this.$fromKeyboard = false;\n            this.$removeCloseEvents();\n            this.getElement().style.display = \"none\";\n            this.isOpen = false;\n            popupManager.removePopup(this);\n        }\n    }\n\n    $registerCloseEvents() {\n        window.addEventListener(\"keydown\", this.hide, true);\n        window.addEventListener(\"wheel\", this.hide, true);\n        window.addEventListener(\"mousedown\", this.hide, true);\n    }\n\n    $removeCloseEvents() {\n        window.removeEventListener(\"keydown\", this.hide, true);\n        window.removeEventListener(\"wheel\", this.hide, true);\n        window.removeEventListener(\"mousedown\", this.hide, true);\n    }\n\n    /**\n     * @internal\n     */\n    onMouseOut(e) {\n        if (this.timeout) {\n            clearTimeout(this.timeout);\n            this.timeout = null;\n        }\n        this.lastEvent = null;\n        if (!this.isOpen) return;\n\n        if (!e.relatedTarget || this.getElement().contains(e.relatedTarget)) return;\n\n        if (e && e.currentTarget.contains(e.relatedTarget)) return;\n        if (!e.relatedTarget.classList.contains(\"ace_content\")) this.hide();\n    }\n}\n\nexports.HoverTooltip = HoverTooltip;\n"
  },
  {
    "path": "src/tooltip_test.js",
    "content": "/*global CustomEvent*/\nif (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar ace = require(\"./ace\");\nvar assert = require(\"./test/assertions\");\nvar HoverTooltip = require(\"./tooltip\").HoverTooltip;\nvar Range = require(\"./range\").Range;\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\n\nvar editor, docTooltip;\nmodule.exports = {\n    setUp: function() {\n        docTooltip = new HoverTooltip();\n        editor = ace.edit(null, {\n            value: \"Hello empty world\"\n        });\n        document.body.appendChild(editor.container);\n        editor.container.style.height = \"200px\";\n        editor.container.style.width = \"300px\";\n        editor.container.style.position = \"absolute\";\n        \n        docTooltip.setDataProvider(function(e, editor) {\n            let session = editor.session;\n            let docPos = e.getDocumentPosition();\n            \n            var range = session.getWordRange(docPos.row, docPos.column);\n\n            var domNode = document.createElement(\"span\");\n            domNode.textContent = \"tooltip \" + range;\n            domNode.className = \"doc-tooltip\";\n            docTooltip.showForRange(editor, range, domNode, e);\n        });\n    },\n    tearDown: function() {\n        editor.destroy();\n        docTooltip.destroy();\n        editor = docTooltip = null;\n    },\n    \"test: show doc tooltip\" : async function(next) {\n        docTooltip.addToEditor(editor);\n        \n        editor.resize(true);\n        docTooltip.idleTime = 3;\n        mouse(\"move\", {row: 0, column: 1});\n\n        await lang.sleep(6);\n        var nodes = document.querySelectorAll(\".doc-tooltip\");\n        assert.equal(nodes.length, 1);\n        assert.equal(nodes[0].textContent, \"tooltip Range: [0/0] -> [0/5]\");\n        assert.equal(docTooltip.$element.style.display, \"block\");\n            mouse(\"move\", {row: 0, column: 9});\n        assert.equal(docTooltip.$element.style.display, \"none\");\n\n        await lang.sleep(6);\n        assert.equal(docTooltip.$element.textContent, \"tooltip Range: [0/6] -> [0/11]\");\n        assert.equal(docTooltip.$element.style.display, \"block\");\n        mouse(\"down\", docTooltip.$element, {button: 0});\n        mouse(\"up\", docTooltip.$element, {button: 0});\n        assert.equal(docTooltip.$element.style.display, \"block\");\n        mouse(\"down\", {row: 0, column: 8}, {button: 0});\n        assert.ok(editor.$mouseHandler.isMousePressed);\n        assert.equal(docTooltip.$element.style.display, \"none\");\n\n        await lang.sleep(6);\n        assert.equal(docTooltip.$element.style.display, \"none\");\n        assert.ok(editor.$mouseHandler.isMousePressed);\n        mouse(\"move\", {row: 0, column: 13}, {which: 1});\n        assert.ok(editor.$mouseHandler.isMousePressed);\n\n        await lang.sleep(6);\n        assert.equal(docTooltip.$element.style.display, \"none\");\n        mouse(\"up\", {row: 0, column: 13});\n        assert.ok(!editor.$mouseHandler.isMousePressed);\n\n        docTooltip.idleTime = 20;\n        assert.ok(!docTooltip.timeout);\n        mouse(\"move\", {row: 0, column: 1});\n        assert.ok(docTooltip.timeout);\n        docTooltip.lastT = Date.now();\n        docTooltip.waitForHover();\n        assert.equal(docTooltip.$element.style.display, \"none\");\n        mouse(\"move\", {row: 0, column: 13});\n        docTooltip.lastT = Date.now() - docTooltip.idleTime;\n        docTooltip.waitForHover();\n        assert.equal(docTooltip.$element.style.display, \"block\");\n\n        assert.equal(docTooltip.$element.textContent, \"tooltip Range: [0/12] -> [0/17]\");\n        mouse(\"out\", docTooltip.$element, {relatedTarget: document.body});\n        assert.equal(docTooltip.$element.style.display, \"none\");\n        assert.ok(!docTooltip.timeout);\n\n        docTooltip.idleTime = 3;\n        mouse(\"move\", editor.container);\n\n        await lang.sleep(6);\n        mouse(\"move\", {row: 0, column: 13});\n        assert.equal(docTooltip.$element.style.display, \"none\");\n\n        await lang.sleep(6);\n        assert.equal(docTooltip.$element.style.display, \"block\");\n        assert.equal(docTooltip.$element.textContent, \"tooltip Range: [0/12] -> [0/17]\");\n        mouse(\"move\", editor.renderer.scroller);\n        assert.equal(docTooltip.$element.style.display, \"none\");\n        next();\n    },\n    \"test: find best position\": function() {\n        editor.resize(true); \n        editor.setValue(\"very long text \".repeat(100), 1);\n        editor.renderer.scrollCursorIntoView();\n        var domNode = dom.buildDom([\"div\"]);\n        var w = window.innerWidth;\n        var h = window.innerHeight;\n        editor.resize(true); \n        \n        // workaround for css styles not being applied in mockdom\n        docTooltip.$element.style.maxWidth = \"300px\";\n        \n        // prefer showing above if possible\n        editor.container.style.top = 20 + \"px\";\n        editor.container.style.top = h / 3 + \"px\";\n        domNode.style.width = 2 * w + \"px\";\n        domNode.style.height = h / 4 + \"px\";\n        var range = new Range(0, 0, 0, editor.session.getLine(0).length);\n        docTooltip.showForRange(editor, range, domNode);\n        \n        var position = editor.renderer.textToScreenCoordinates(range.start.row, range.start.column);\n        assert.ok(position.pageX < 0);\n        var rect = docTooltip.$element.getBoundingClientRect();\n        assert.ok(rect.left > 0);\n        assert.ok(rect.top < h / 3);\n        \n        // show below if height is large\n        domNode.style.height = 2 * h + \"px\";\n        docTooltip.showForRange(editor, range, domNode);\n        rect = docTooltip.$element.getBoundingClientRect();\n        assert.ok(rect.top > h / 3);\n        \n        // show above if there is more space there\n        editor.container.style.top = h / 2 + \"px\";\n        domNode.style.height = 2 * h + \"px\";\n        docTooltip.showForRange(editor, range, domNode);\n        rect = docTooltip.$element.getBoundingClientRect();\n        assert.ok(rect.top < h / 3);\n        \n        editor.container.style.left = w - 20 + \"px\";\n        docTooltip.showForRange(editor, range, domNode);\n        rect = docTooltip.$element.getBoundingClientRect();\n        assert.ok(rect.left < w - 100);\n    },\n    \"test: remove listeners\": function() {\n        var l = editor._eventRegistry.mousemove.length;\n        docTooltip.addToEditor(editor);\n        assert.ok(!docTooltip.timeout);\n        assert.equal(editor._eventRegistry.mousemove.length, l + 1);\n        mouse(\"move\", {row: 0, column: 1});\n        assert.ok(docTooltip.timeout);\n        docTooltip.removeFromEditor(editor);\n        assert.ok(!docTooltip.timeout);\n        assert.equal(editor._eventRegistry.mousemove.length, l);\n    }\n};\n\nfunction mouse(type, pos, properties) {\n    var target = editor.renderer.getMouseEventTarget();\n    var event = new CustomEvent(\"mouse\" + type, {bubbles: true});\n\n    if (\"row\" in pos) {\n        var pagePos = editor.renderer.textToScreenCoordinates(pos.row, pos.column);\n        event.clientX = pagePos.pageX;\n        event.clientY = pagePos.pageY;\n    } else {\n        target = pos;\n        var rect = target.getBoundingClientRect();\n        event.clientX = rect.left + rect.width / 2;\n        event.clientY = rect.top + rect.height / 2;\n    }\n    Object.assign(event, properties);\n    target.dispatchEvent(event);\n}\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/undomanager.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"../ace-internal\").Ace.Delta} Delta\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.IRange} IRange\n */\n\n/**\n * This object maintains the undo stack for an [[EditSession `EditSession`]].\n **/\nclass UndoManager {\n    /**\n     * Resets the current undo state and creates a new `UndoManager`.\n     **/\n    constructor() {\n        /**@type {boolean}*/\n        this.$keepRedoStack;\n        this.$maxRev = 0;\n        this.$fromUndo = false;\n        this.$undoDepth = Infinity;\n        this.reset();\n    }\n\n    /**\n     * \n     * @param {EditSession} session\n     */\n    addSession(session) {\n        this.$session = session;\n    }\n    /**\n     * Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements:\n     *\n     * - `args[0]` is an array of deltas\n     * - `args[1]` is the document to associate with\n     *\n     * @param {import(\"../ace-internal\").Ace.Delta} delta\n     * @param {boolean} allowMerge\n     * @param {EditSession} [session]\n     **/\n    add(delta, allowMerge, session) {\n        if (this.$fromUndo) return;\n        if (delta == this.$lastDelta) return;\n        if (!this.$keepRedoStack) this.$redoStack.length = 0;\n        if (allowMerge === false || !this.lastDeltas) {\n            this.lastDeltas = [];\n            var undoStackLength = this.$undoStack.length;\n            if (undoStackLength > this.$undoDepth - 1) {\n                this.$undoStack.splice(0, undoStackLength - this.$undoDepth + 1);\n            }\n            this.$undoStack.push(this.lastDeltas);\n            delta.id = this.$rev = ++this.$maxRev;\n        }\n        if (delta.action == \"remove\" || delta.action == \"insert\")\n            this.$lastDelta = delta;\n        this.lastDeltas.push(delta);\n    }\n\n    /**\n     * \n     * @param {any} selection\n     * @param {number} [rev]\n     */\n    addSelection(selection, rev) {\n        this.selections.push({\n            value: selection,\n            rev: rev || this.$rev\n        });\n    }\n    \n    startNewGroup() {\n        this.lastDeltas = null;\n        return this.$rev;\n    }\n\n    /**\n     * \n     * @param {number} from\n     * @param {number} [to]\n     */\n    markIgnored(from, to) {\n        if (to == null) to = this.$rev + 1;\n        var stack = this.$undoStack;\n        for (var i = stack.length; i--;) {\n            var delta = stack[i][0];\n            if (delta.id <= from)\n                break;\n            if (delta.id < to)\n                delta.ignore = true;\n        }\n        this.lastDeltas = null;\n    }\n\n    /**\n     * \n     * @param {number} rev\n     * @param {boolean} [after]\n     * @return {{ value: string, rev: number }}\n     */\n    getSelection(rev, after) {\n        var stack = this.selections;\n        for (var i = stack.length; i--;) {\n            var selection = stack[i];\n            if (selection.rev < rev) {\n                if (after)\n                    selection = stack[i + 1];\n                return selection;\n            }\n        }\n    }\n\n    /**\n     * @return {number}\n     */\n    getRevision() {\n        return this.$rev;\n    }\n\n    /**\n     * \n     * @param {number} from\n     * @param {number} [to]\n     * @return {import(\"../ace-internal\").Ace.Delta[]}\n     */\n    getDeltas(from, to) {\n        if (to == null) to = this.$rev + 1;\n        var stack = this.$undoStack;\n        var end = null, start = 0;\n        for (var i = stack.length; i--;) {\n            var delta = stack[i][0];\n            if (delta.id < to && !end)\n                end = i+1;\n            if (delta.id <= from) {\n                start = i + 1;\n                break;\n            }\n        }\n        return stack.slice(start, end);\n    }\n\n    /**\n     * \n     * @param {number} from\n     * @param {number} [to]\n     */\n    getChangedRanges(from, to) {\n        if (to == null) to = this.$rev + 1;\n    }\n\n    /**\n     *\n     * @param {number} from\n     * @param {number} [to]\n     */\n    getChangedLines(from, to) {\n        if (to == null) to = this.$rev + 1;\n        \n    }\n\n    /**\n     * [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo}\n     * @param {EditSession} session\n     * @param {Boolean} [dontSelect] {:dontSelect}\n     **/\n    undo(session, dontSelect) {\n        this.lastDeltas = null;\n        var stack = this.$undoStack;\n        \n        if (!rearrangeUndoStack(stack, stack.length))\n            return;\n        \n        if (!session)\n            session = this.$session;\n        \n        if (this.$redoStackBaseRev !== this.$rev && this.$redoStack.length)\n            this.$redoStack = [];\n        \n        this.$fromUndo = true;\n        \n        var deltaSet = stack.pop();\n        var undoSelectionRange = null;\n        if (deltaSet) {\n            undoSelectionRange = session.undoChanges(deltaSet, dontSelect);\n            this.$redoStack.push(deltaSet);\n            this.$syncRev();\n        }\n        \n        this.$fromUndo = false;\n\n        return undoSelectionRange;\n    }\n    \n    /**\n     * [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo}\n     * @param {EditSession} session\n     * @param {Boolean} [dontSelect] {:dontSelect}\n     *\n     **/\n    redo(session, dontSelect) {\n        this.lastDeltas = null;\n        \n        if (!session)\n            session = this.$session;\n        \n        this.$fromUndo = true;\n        if (this.$redoStackBaseRev != this.$rev) {\n            var diff = this.getDeltas(this.$redoStackBaseRev, this.$rev + 1);\n            rebaseRedoStack(this.$redoStack, diff);\n            this.$redoStackBaseRev = this.$rev;\n            this.$redoStack.forEach(function(x) {\n                x[0].id = ++this.$maxRev;\n            }, this);\n        }\n        var deltaSet = this.$redoStack.pop();\n        var redoSelectionRange = null;\n        \n        if (deltaSet) {\n            redoSelectionRange = session.redoChanges(deltaSet, dontSelect);\n            this.$undoStack.push(deltaSet);\n            this.$syncRev();\n        }\n        this.$fromUndo = false;\n        \n        return redoSelectionRange;\n    }\n    \n    $syncRev() {\n        var stack = this.$undoStack;\n        var nextDelta = stack[stack.length - 1];\n        var id = nextDelta && nextDelta[0].id || 0;\n        this.$redoStackBaseRev = id;\n        this.$rev = id;\n    }\n\n    /**\n     * Destroys the stack of undo and redo redo operations.\n     **/\n    reset() {\n        this.lastDeltas = null;\n        this.$lastDelta = null;\n        this.$undoStack = [];\n        this.$redoStack = [];\n        this.$rev = 0;\n        this.mark = 0;\n        this.$redoStackBaseRev = this.$rev;\n        this.selections = [];\n    }\n\n    \n    /**\n     * Returns `true` if there are undo operations left to perform.\n     * @returns {Boolean}\n     **/\n    canUndo() {\n        return this.$undoStack.length > 0;\n    }\n\n    /**\n     * Returns `true` if there are redo operations left to perform.\n     * @returns {Boolean}\n     **/\n    canRedo() {\n        return this.$redoStack.length > 0;\n    }\n\n    /**\n     * Marks the current status clean\n     * @param {number} [rev]\n     */\n    bookmark(rev) {\n        if (rev == undefined)\n            rev = this.$rev;\n        this.mark = rev;\n    }\n\n    /**\n     * Returns if the current status is clean\n     * @returns {Boolean}\n     **/\n    isAtBookmark() {\n        return this.$rev === this.mark;\n    }\n    \n    /**\n     * Returns an object which can be safely stringified into JSON\n     * @returns {object}\n     */\n    toJSON() {\n        return {\n            $redoStack: this.$redoStack,\n            $undoStack: this.$undoStack\n        };\n    }\n\n    // NOTE: The above and below function require you to JSON.stringify and JSON.parse externally.\n    \n    /**\n     * Takes in an object which was returned from the toJSON method above,\n     * and resets the current undoManager instance to use the previously exported\n     * instance state.\n     * @param {object} json \n     */\n    fromJSON(json) {\n        this.reset();\n        this.$undoStack = json.$undoStack;\n        this.$redoStack = json.$redoStack;\n    }\n\n\n    /**\n     * @param {Delta} delta\n     */\n    $prettyPrint(delta) {\n        if (delta) return stringifyDelta(delta);\n        return stringifyDelta(this.$undoStack) + \"\\n---\\n\" + stringifyDelta(this.$redoStack);\n    }\n}\n\n\nUndoManager.prototype.hasUndo = UndoManager.prototype.canUndo;\nUndoManager.prototype.hasRedo = UndoManager.prototype.canRedo;\nUndoManager.prototype.isClean = UndoManager.prototype.isAtBookmark;\nUndoManager.prototype.markClean = UndoManager.prototype.bookmark;\n\n/**\n * @param {any[]} stack\n * @param {number} pos\n */\nfunction rearrangeUndoStack(stack, pos) {\n    for (var i = pos; i--; ) {\n        var deltaSet = stack[i];\n        if (deltaSet && !deltaSet[0].ignore) {\n            while(i < pos - 1) {\n                var swapped = swapGroups(stack[i], stack[i + 1]);\n                stack[i] = swapped[0];\n                stack[i + 1] = swapped[1];\n                i++;\n            }\n            return true;\n        }\n    }\n}\n\nvar Range = require(\"./range\").Range;\nvar cmp = Range.comparePoints;\nvar comparePoints = Range.comparePoints;\n\n/**\n * @param {Delta} delta\n */\nfunction $updateMarkers(delta) {\n    var isInsert = delta.action == \"insert\";\n    var start = delta.start;\n    var end = delta.end;\n    var rowShift = (end.row - start.row) * (isInsert ? 1 : -1);\n    var colShift = (end.column - start.column) * (isInsert ? 1 : -1);\n    if (isInsert) end = start;\n\n    for (var i in this.marks) {\n        var point = this.marks[i];\n        var cmp = comparePoints(point, start);\n        if (cmp < 0) {\n            continue; // delta starts after the range\n        }\n        if (cmp === 0) {\n            if (isInsert) {\n                if (point.bias == 1) {\n                    cmp = 1;\n                }\n                else {\n                    point.bias == -1;\n                    continue;\n                }\n            }\n        }\n        var cmp2 = isInsert ? cmp : comparePoints(point, end);\n        if (cmp2 > 0) {\n            point.row += rowShift;\n            point.column += point.row == end.row ? colShift : 0;\n            continue;\n        }\n        if (!isInsert && cmp2 <= 0) {\n            point.row = start.row;\n            point.column = start.column;\n            if (cmp2 === 0)\n                point.bias = 1;\n        }\n    }\n}\n\n/**\n * @param {Point} pos\n */\nfunction clonePos(pos) {\n    return {row: pos.row,column: pos.column};\n}\n\n/**\n * @param {Delta} d\n */\nfunction cloneDelta(d) {\n    return {\n        start: clonePos(d.start),\n        end: clonePos(d.end),\n        action: d.action,\n        lines: d.lines.slice()\n    };\n}\nfunction stringifyDelta(d) {\n    d = d || this;\n    if (Array.isArray(d)) {\n        return d.map(stringifyDelta).join(\"\\n\");\n    }\n    var type = \"\";\n    if (d.action) {\n        type = d.action == \"insert\" ? \"+\" : \"-\";\n        type += \"[\" + d.lines + \"]\";\n    } else if (d.value) {\n        if (Array.isArray(d.value)) {\n            type = d.value.map(stringifyRange).join(\"\\n\");\n        } else {\n            type = stringifyRange(d.value);\n        }\n    }\n    if (d.start) {\n        type += stringifyRange(d);\n    }\n    if (d.id || d.rev) {\n        type += \"\\t(\" + (d.id || d.rev) + \")\";\n    }\n    return type;\n}\n\n/**\n * @param {Range} r\n * @return {string}\n */\nfunction stringifyRange(r) {\n    return r.start.row + \":\" + r.start.column \n        + \"=>\" + r.end.row + \":\" + r.end.column;\n}\n/*\n * i i  d1  d2\n *      |/  |/  d2.s >= d1.e shift(d2, d1, -1)\n *              d2.s <= d1.s shift(d1, d2, +1)\n *       d1.s < d2.s < d1.e // can split\n * \n * i r  d1  d2\n *      |/  |\\  d2.s >= d1.e shift(d2, d1, -1)\n *              d2.e <= d1.s shift(d1, d2, -1)\n *       else // can't swap\n * \n * r i  d1  d2\n *      |\\  |/  d2.s >= d1.s shift(d2, d1, +1)\n *              d2.s <= d1.s shift(d1, d2, +1)\n *       // no else\n * \n * r r  d1  d2\n *      |\\  |\\  d2.s >= d1.s shift(d2, d1, +1)\n *              d2.e <= d1.s shift(d1, d2, -1)\n *       d2.s < d1.s < d2.e // can split\n */\n\n/**\n * @param {Delta} d1\n * @param {Delta} d2\n */\nfunction swap(d1, d2) {\n    var i1 = d1.action == \"insert\";\n    var i2 = d2.action == \"insert\";\n    \n    if (i1 && i2) {\n        if (cmp(d2.start, d1.end) >= 0) {\n            shift(d2, d1, -1);\n        } else if (cmp(d2.start, d1.start) <= 0) {\n            shift(d1, d2, +1);\n        } else {\n            return null;\n        }\n    } else if (i1 && !i2) {\n        if (cmp(d2.start, d1.end) >= 0) {\n            shift(d2, d1, -1);\n        } else if (cmp(d2.end, d1.start) <= 0) {\n            shift(d1, d2, -1);\n        } else {\n            return null;\n        }\n    } else if (!i1 && i2) {\n        if (cmp(d2.start, d1.start) >= 0) {\n            shift(d2, d1, +1);\n        } else if (cmp(d2.start, d1.start) <= 0) {\n            shift(d1, d2, +1);\n        } else {\n            return null;\n        }\n    } else if (!i1 && !i2) {\n        if (cmp(d2.start, d1.start) >= 0) {\n            shift(d2, d1, +1);\n        } else if (cmp(d2.end, d1.start) <= 0) {\n            shift(d1, d2, -1);\n        } else {\n            return null;\n        }\n    }\n    return [d2, d1];\n}\nfunction swapGroups(ds1, ds2) {\n    for (var i = ds1.length; i--; ) {\n        for (var j = 0; j < ds2.length; j++) {\n            if (!swap(ds1[i], ds2[j])) {\n                // rollback, we have to undo ds2 first\n                while (i < ds1.length) {\n                    while (j--) {\n                        swap(ds2[j], ds1[i]);\n                    }\n                    j = ds2.length;\n                    i++;\n                }                \n                return [ds1, ds2];\n            }\n        }\n    }\n    ds1.selectionBefore = ds2.selectionBefore = \n    ds1.selectionAfter = ds2.selectionAfter = null;\n    return [ds2, ds1];\n}\n\n/*\n      d2          xform(d1, c1) = [d2, c2]\n    o<---o        xform(c1, d1) = [c2, d2]\n c2 |    | d1     \n    o<---o\n      c1\n*/\n/**\n * \n * @param {Delta} d1\n * @param {Delta} c1\n */\nfunction xform(d1, c1) {\n    var i1 = d1.action == \"insert\";\n    var i2 = c1.action == \"insert\";\n    \n    if (i1 && i2) {\n        if (cmp(d1.start, c1.start) < 0) {\n            shift(c1, d1, 1);\n        } else {\n            shift(d1, c1, 1);\n        }\n    } else if (i1 && !i2) {\n        if (cmp(d1.start, c1.end) >= 0) {\n            shift(d1, c1, -1);\n        } else if (cmp(d1.start, c1.start) <= 0) {\n            shift(c1, d1, +1);\n        } else {\n            shift(d1, Range.fromPoints(c1.start, d1.start), -1);\n            shift(c1, d1, +1);\n        }\n    } else if (!i1 && i2) {\n        if (cmp(c1.start, d1.end) >= 0) {\n            shift(c1, d1, -1);\n        } else if (cmp(c1.start, d1.start) <= 0) {\n            shift(d1, c1, +1);\n        } else {\n            shift(c1, Range.fromPoints(d1.start, c1.start), -1);\n            shift(d1, c1, +1);\n        }\n    } else if (!i1 && !i2) {\n        if (cmp(c1.start, d1.end) >= 0) {\n            shift(c1, d1, -1);\n        } else if (cmp(c1.end, d1.start) <= 0) {\n            shift(d1, c1, -1);\n        } else {\n            var before, after;\n            if (cmp(d1.start, c1.start) < 0) {\n                before = d1;\n                d1 = splitDelta(d1, c1.start);\n            }\n            if (cmp(d1.end, c1.end) > 0) {\n                after = splitDelta(d1, c1.end);\n            }\n\n            shiftPos(c1.end, d1.start, d1.end, -1);\n            if (after && !before) {\n                d1.lines = after.lines;\n                d1.start = after.start;\n                d1.end = after.end;\n                after = d1;\n            }\n\n            return [c1, before, after].filter(Boolean);\n        }\n    }\n    return [c1, d1];\n}\n\n/**\n * \n * @param {IRange} d1\n * @param {IRange} d2\n * @param {number} dir\n */\nfunction shift(d1, d2, dir) {\n    shiftPos(d1.start, d2.start, d2.end, dir);\n    shiftPos(d1.end, d2.start, d2.end, dir);\n}\n\n/**\n * \n * @param {Point} pos\n * @param {Point} start\n * @param {Point} end\n * @param {number} dir\n */\nfunction shiftPos(pos, start, end, dir) {\n    if (pos.row == (dir == 1 ? start : end).row) {\n        pos.column += dir * (end.column - start.column);\n    }\n    pos.row += dir * (end.row - start.row);\n}\n\n/**\n * \n * @param {Delta} c\n * @param {Point} pos\n * @return {Delta}\n */\nfunction splitDelta(c, pos) {\n    var lines = c.lines;\n    var end = c.end;\n    c.end = clonePos(pos);    \n    var rowsBefore = c.end.row - c.start.row;\n    var otherLines = lines.splice(rowsBefore, lines.length);\n    \n    var col = rowsBefore ? pos.column : pos.column - c.start.column;\n    lines.push(otherLines[0].substring(0, col));\n    otherLines[0] = otherLines[0].substr(col)   ; \n    var rest = {\n        start: clonePos(pos),\n        end: end,\n        lines: otherLines,\n        action: c.action\n    };\n    return rest;\n}\n\n/**\n * @param {any[]} redoStack\n * @param {Delta} d\n */\nfunction moveDeltasByOne(redoStack, d) {\n    d = cloneDelta(d);\n    for (var j = redoStack.length; j--;) {\n        var deltaSet = redoStack[j];\n        for (var i = 0; i < deltaSet.length; i++) {\n            var x = deltaSet[i];\n            var xformed = xform(x, d);\n            d = xformed[0];\n            if (xformed.length != 2) {\n                if (xformed[2]) {\n                    deltaSet.splice(i + 1, 1, xformed[1], xformed[2]);\n                    i++;\n                } else if (!xformed[1]) {\n                    deltaSet.splice(i, 1);\n                    i--;\n                }\n            }\n        }\n        if (!deltaSet.length) {\n            redoStack.splice(j, 1); \n        }\n    }\n    return redoStack;\n}\n\nfunction rebaseRedoStack(redoStack, deltaSets) {\n    for (var i = 0; i < deltaSets.length; i++) {\n        var deltas = deltaSets[i];\n        for (var j = 0; j < deltas.length; j++) {\n            moveDeltasByOne(redoStack, deltas[j]);\n        }\n    }\n}\nexports.UndoManager = UndoManager;\n"
  },
  {
    "path": "src/undomanager_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nrequire(\"./multi_select\");\nvar assert = require(\"./test/assertions\");\nvar Range = require(\"./range\").Range;\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar MockRenderer = require(\"./test/mockrenderer\").MockRenderer;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar lang = require(\"./lib/lang\");\n\nvar editor, session, undoManager;\n\nmodule.exports = {\n\n    name: \"ACE undoManager.js\",\n    setUp: function() {\n        editor = editor || new Editor(new MockRenderer());\n        session = new EditSession(\"\");\n        undoManager = new UndoManager();\n        undoManager.$keepRedoStack = true;\n        session.setUndoManager(undoManager);\n        editor.setSession(session);\n    },\n\n    \"test: merging\": async function(done) {\n        editor.session.setValue(\"-\");\n        editor.execCommand(\"insertstring\", \"a\");\n        editor.execCommand(\"insertstring\", \"b\");\n        editor.execCommand(\"insertstring\", \"c\");\n        editor.execCommand(\"gotolinestart\");\n\n        // TODO remove setTimeout when timeout from informUndoManager is removed\n        await lang.sleep(0);\n        editor.execCommand(\"insertstring\", \"x\");\n        editor.execCommand(\"insertstring\", \"y\");\n        editor.execCommand(\"insertstring\", \"z\");\n        editor.execCommand(\"undo\");\n        assert.equal(editor.getValue(), \"abc-\");\n        editor.execCommand(\"redo\");\n        assert.equal(editor.getValue(), \"xyzabc-\");\n        editor.execCommand(\"gotolineend\");\n\n        editor.execCommand(\"insertstring\", \"k\");\n        editor.execCommand(\"insertstring\", \"l\");\n\n        await lang.sleep(0);\n        editor.sequenceStartTime = Date.now() - 3000;\n        editor.execCommand(\"insertstring\", \"m\");\n        editor.execCommand(\"insertstring\", \"n\");\n        assert.equal(editor.getValue(), \"xyzabc-klmn\");\n        editor.execCommand(\"undo\");\n        assert.equal(editor.getValue(), \"xyzabc-kl\");\n        done();\n    },\n    \"test: reabsing\": function() {\n        session.setValue(\"012345-012345-012345\");\n        session.insert({row: 0, column: 0}, \"xx\");\n        session.markUndoGroup();\n        session.remove(new Range(0, 10, 0, 15));\n        session.markUndoGroup();\n        session.insert({row: 0, column: 5}, \"yy\");\n        session.markUndoGroup();\n        editor.undo();\n        editor.undo();\n        var rev = undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"z\\nz\");\n        undoManager.markIgnored(rev);\n        // editor.undo()\n        editor.redo();\n        editor.redo();\n        var val1 = editor.getValue();\n        editor.undo();\n        editor.undo();\n        editor.undo();\n        \n        editor.redo();\n        editor.redo();\n        editor.redo();\n        var val2 = editor.getValue();\n        assert.equal(val1, val2);\n    },\n    \"test: conflicting deletes\": function() {\n        session.setValue(\"012345\\nabcdefg\\nxyz\");\n        session.remove(new Range(0, 2, 0, 4));\n        assert.equal(session.getLine(0), \"0145\");\n        session.markUndoGroup();\n        editor.undo();\n        session.remove(new Range(0, 1, 0, 5));\n        assert.equal(session.getLine(0), \"05\");\n        session.markUndoGroup();\n        editor.redo();\n        assert.equal(session.getLine(0), \"05\");\n        editor.undo();\n        assert.equal(session.getLine(0), \"012345\");\n    },\n    \"test: several deltas ignored\": function() {\n        session.setValue(\"012345\\nabcdefg\\nxyz\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        var rev = undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        session.insert({row: 0, column: 5}, \"aaaa\");\n        undoManager.markIgnored(rev, undoManager.getRevision() + 1);\n        editor.undo();\n        assert.equal(editor.getValue(), \"01234aaaayyyy5\\nabcdefg\\nxyz\");\n    },\n    \"test: canUndo/canRedo and bookmarks\": function() {\n        session.setValue(\"012345\\nabcdefg\\nxyz\");\n        assert.ok(undoManager.isAtBookmark());\n        editor.execCommand(\"removewordright\");\n        assert.ok(!undoManager.isAtBookmark());\n        var rev = undoManager.getRevision();\n        undoManager.bookmark();\n        assert.ok(undoManager.isAtBookmark());\n        editor.undo();\n        assert.ok(!undoManager.isAtBookmark());\n        undoManager.bookmark(rev);\n        assert.ok(!undoManager.canUndo());\n        assert.ok(undoManager.canRedo());\n        editor.redo();\n        assert.ok(undoManager.isAtBookmark());\n\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        assert.ok(undoManager.canUndo());\n        assert.ok(!undoManager.canRedo());\n    },\n    \"test: getRevision\": function () {\n        session.setValue(\"012345\\nabcdefg\\nxyz\");\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        var rev = undoManager.getRevision();\n        assert.equal(rev, 2);\n        editor.undo();\n        rev = undoManager.getRevision();\n        assert.equal(rev, 0);\n    },\n    \"test: swap deltas delete/insert\": function () {\n        session.setValue(\"012345\\nabcdefg\\nxyz\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        session.remove(new Range(0, 5, 0, 9));\n        var rev = undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"aaaa\");\n        undoManager.markIgnored(rev);\n        editor.undo();\n        assert.equal(editor.getValue(), \"01234aaaazzzz5\\nabcdefg\\nxyz\");\n    },\n    \"test: swap deltas insert/delete\": function () {\n        session.setValue(\"012345\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        var rev = undoManager.startNewGroup();\n        session.remove(new Range(0, 5, 0, 9));\n        undoManager.markIgnored(rev);\n        editor.undo();\n        assert.equal(editor.getValue(), \"01234yyyy5\");\n\n        editor.redo();\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        var rev1 = undoManager.startNewGroup();\n        session.remove(new Range(0, 1, 0, 4));\n        undoManager.markIgnored(rev1);\n        editor.undo();\n        assert.equal(editor.getValue(), \"045\");\n\n        editor.redo();\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 1}, \"yyyy\");\n        var rev2 = undoManager.startNewGroup();\n        session.remove(new Range(0, 7, 0, 9));\n        undoManager.markIgnored(rev2);\n        editor.undo();\n        assert.equal(editor.getValue(), \"04yy5\");\n    },\n    \"test: swap deltas insert/insert\": function () {\n        session.setValue(\"012345\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 1}, \"yyyy\");\n        var rev = undoManager.startNewGroup();\n        session.insert({row: 0, column: 2}, \"xxxx\");\n        undoManager.markIgnored(rev);\n        editor.undo();\n        assert.equal(editor.getValue(), \"0yyyy12345\");\n    },\n    \"test: swap deltas delete/delete\": function () {\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 5}, \"yyyy\");\n        session.remove(new Range(0, 5, 0, 9));\n        session.insert({row: 0, column: 5}, \"aaaa\");\n        var rev = undoManager.startNewGroup();\n        session.remove(new Range(0, 5, 0, 9));\n        undoManager.markIgnored(rev);\n        editor.undo();\n        assert.equal(editor.getValue(), \"01234aaaazzzz5\");\n\n        editor.undo();\n        assert.equal(editor.getValue(), \"01234zzzz5\");\n\n        editor.redo();\n        var rev1=undoManager.startNewGroup();\n        session.insert({row: 0, column: 1}, \"yyyy\");\n        session.remove(new Range(0, 0, 0, 1));\n        undoManager.markIgnored(rev1);\n        editor.undo();\n        assert.equal(editor.getValue(), \"yyyy1234zzzz5\");\n\n        undoManager.startNewGroup();\n        session.remove(new Range(0, 0, 0, 1));\n        var rev2=undoManager.startNewGroup();\n        session.remove(new Range(0, 3, 0, 5));\n        undoManager.markIgnored(rev2);\n        editor.undo();\n        assert.equal(editor.getValue(), \"yyyy34zzzz5\");\n\n        editor.redo();\n        undoManager.startNewGroup();\n        session.remove(new Range(0, 3, 0, 5));\n        var rev3=undoManager.startNewGroup();\n        session.remove(new Range(0, 1, 0, 5));\n        undoManager.markIgnored(rev3);\n        editor.undo();\n        assert.equal(editor.getValue(), \"yyyzzzz5\");\n\n    },\n    \"test: xform deltas insert/insert\": function () {\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        editor.undo();\n        session.insert({row: 0, column: 5}, \"aaaa\");\n        editor.redo();\n        assert.equal(editor.getValue(), \"yyyy01234aaaazzzz5\");\n    },\n    \"test: xform deltas insert/delete\": function () {\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        editor.undo();\n        session.remove(new Range(0, 0, 0, 1));\n        editor.redo();\n        assert.equal(editor.getValue(), \"yyyy1234zzzz5\");\n\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        undoManager.startNewGroup();\n        var rev=undoManager.startNewGroup();\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        undoManager.markIgnored(rev);\n        editor.undo();\n        session.remove(new Range(0, 0, 0, 1));\n        editor.redo();\n        assert.equal(editor.getValue(), \"yyy01234zzzz5\");\n    },\n    \"test: xform deltas delete/insert\": function () {\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        undoManager.startNewGroup();\n        session.remove(new Range(0, 0, 0, 1));\n        editor.undo();\n        session.insert({row: 0, column: 5}, \"zzzz\");\n        editor.redo();\n        assert.equal(editor.getValue(), \"yyy0zzzz12345\");\n    },\n    \"test: xform deltas delete/delete\": function () {\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        undoManager.startNewGroup();\n        session.remove(new Range(0, 3, 0, 4));\n        editor.undo();\n        session.remove(new Range(0, 4, 0, 5));\n        editor.redo();\n        assert.equal(editor.getValue(), \"yyy12345\");\n\n        session.setValue(\"012345\");\n        session.insert({row: 0, column: 0}, \"yyyy\");\n        session.remove(new Range(0, 2, 0, 5));\n        assert.equal(editor.getValue(), \"yy12345\");\n        editor.undo();\n        assert.equal(editor.getValue(), \"012345\");\n        session.remove(new Range(0, 1, 0, 2));\n        editor.redo();\n        assert.equal(editor.getValue(), \"yy2345\");\n\n        session.setValue(\"1234abcd ---\");\n        session.insert({row: 0, column: 0}, \"ijkl\");\n        session.remove(new Range(0, 2, 0, 8));\n        editor.undo();\n        session.remove(new Range(0, 4, 0, 7));\n        editor.redo();\n        assert.equal(editor.getValue(), \"ijd ---\");\n        assert.equal(undoManager.$prettyPrint(), '-[abc]0:4=>0:7\\t(12)\\n+[ijkl]0:0=>0:4\\t(13)\\n-[kl1234]0:2=>0:8\\n---\\n');\n    },\n    \"test: clear redo stack after insert\": function () {\n        undoManager.$keepRedoStack = false;\n        session.insert({row: 0, column: 0}, \"y\");\n        editor.undo();\n        assert.equal(session.$undoManager.$redoStack.length, 1);\n        session.insert({row: 0, column: 0}, \"y\");\n        assert.equal(session.$undoManager.$redoStack.length, 0);\n    },\n    \"test: ignore deltas with incorrect boundaries\": function () {\n        session.setValue(\"012\\n345\\n678\");\n        undoManager.add({\n            action: \"remove\",\n            start: {row: 1, column: 0},\n            end: {row: 3, column: 0},\n            lines: [\"hello\", \"world\"]\n        });\n        editor.undo();\n        assert.equal(editor.getValue(), \"012\\nhello\\nworld345\\n678\");\n\n        session.setValue(\"012\\n345\\n678\");\n        undoManager.add({\n            action: \"remove\",\n            start: {row: 3, column: 0},\n            end: {row: 5, column: 0},\n            lines: [\"hello\", \"world\"]\n        });\n        editor.undo();\n        assert.equal(editor.getValue(), \"012\\n345\\n678\\nhello\\nworld\");\n\n\n        session.setValue(\"012\\n345\\n678\");\n        undoManager.add({\n            action: \"remove\",\n            start: {row: 5, column: 0},\n            end: {row: 7, column: 0},\n            lines: [\"hello\", \"world\"]\n        });\n        editor.undo();\n        assert.equal(editor.getValue(), \"012\\n345\\n678\");\n\n        session.setValue(\"012\\n345\\n678\");\n        undoManager.add({\n            action: \"insert\",\n            start: {row: 3, column: 0},\n            end: {row: 5, column: 0},\n            lines: [\"hello\", \"world\"]\n        });\n        editor.undo();\n        assert.equal(editor.getValue(), \"012\\n345\\n678\");\n\n        session.setValue(\"012\\n345\\n678\");\n        undoManager.$redoStack.push([{\n            action: \"remove\",\n            start: {row: 2, column: 0},\n            end: {row: 4, column: 0},\n            lines: [\"hello\", \"world\"]\n        }]);\n        editor.redo();\n        assert.equal(editor.getValue(), \"012\\n345\\n678\");\n    },\n    \"test: do not ignore valid deltas\": function () {\n        editor.setValue(\"\");\n        editor.insert(\"\\n\");\n        editor.insert(\"\\n\");\n        editor.insert(\"\\n\");\n        editor.insert(\"\\n\");\n        editor.undo();\n        assert.equal(editor.getValue(), \"\");\n        editor.redo();\n        assert.equal(editor.getValue(), \"\\n\\n\\n\\n\");\n    },\n    \"test: limit possible undos amount\": function() {\n        editor.setValue(\"\");\n        undoManager.startNewGroup();\n        editor.insert(\"a\");\n        undoManager.startNewGroup();\n        editor.insert(\"b\");\n        undoManager.startNewGroup();\n        editor.insert(\"c\");\n        assert.equal(undoManager.$undoStack.length, 3);\n\n        undoManager.$undoDepth = 1;\n        editor.setValue(\"\");\n        undoManager.startNewGroup();\n        editor.insert(\"a\");\n        undoManager.startNewGroup();\n        editor.insert(\"b\");\n        undoManager.startNewGroup();\n        editor.insert(\"c\");\n        assert.equal(undoManager.$undoStack[0][0].lines[0], \"c\");\n        assert.equal(undoManager.$undoStack.length, undoManager.$undoDepth);\n    },\n    \"test: export instance using toJSON\": function() {\n        let state = undoManager.toJSON();\n        assert.equal(typeof state, \"object\");\n        assert.equal(state.$redoStack.length, 0);\n        assert.equal(state.$undoStack.length, 0);\n\n        session.insert({row: 0, column: 0}, \"j\");\n        undoManager.startNewGroup();\n        session.insert({row: 0, column: 0}, \"s\");\n        editor.undo();\n\n        state = undoManager.toJSON();\n        assert.equal(state.$undoStack, undoManager.$undoStack);\n        assert.equal(state.$redoStack, undoManager.$redoStack);\n        assert.equal(state.$redoStack.length, 1);\n        assert.equal(state.$undoStack.length, 1);\n\n    },\n    \"test: import instance using fromJSON\": function() {\n        const JSONwithundo = `{\"$redoStack\":[],\"$undoStack\":[[{\"start\":{\"row\":0,\"column\":0},\"end\":{\"row\":0,\"column\":1},\"action\":\"insert\",\"lines\":[\"j\"],\"id\":1}]]}`;\n        const JSONwithredo = `{\"$redoStack\":[[{\"start\":{\"row\":0,\"column\":0},\"end\":{\"row\":0,\"column\":1},\"action\":\"insert\",\"lines\":[\"s\"],\"id\":2}]],\"$undoStack\":[]}`;\n        const JSONwithboth = `{\"$redoStack\":[[{\"start\":{\"row\":0,\"column\":0},\"end\":{\"row\":0,\"column\":1},\"action\":\"insert\",\"lines\":[\"s\"],\"id\":2}]],\"$undoStack\":[[{\"start\":{\"row\":0,\"column\":0},\"end\":{\"row\":0,\"column\":1},\"action\":\"insert\",\"lines\":[\"j\"],\"id\":1}]]}`;\n        const JSONwithnone = `{\"$redoStack\":[],\"$undoStack\":[]}`;\n\n        let state = JSON.parse(JSONwithundo);\n        undoManager.fromJSON(state);\n        assert.equal(undoManager.canUndo(), true);\n        assert.equal(undoManager.canRedo(), false);\n        state = JSON.parse(JSONwithredo);\n        undoManager.fromJSON(state);\n        assert.equal(undoManager.canUndo(), false);\n        assert.equal(undoManager.canRedo(), true);\n        state = JSON.parse(JSONwithboth);\n        undoManager.fromJSON(state);\n        assert.equal(undoManager.canUndo(), true);\n        assert.equal(undoManager.canRedo(), true);\n        state = JSON.parse(JSONwithnone);\n        undoManager.fromJSON(state);\n        assert.equal(undoManager.canUndo(), false);\n        assert.equal(undoManager.canRedo(), false);\n    }\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/unicode.js",
    "content": "\"use strict\";\n\n// generated by tool/unicode.js\nvar wordChars = [48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2];\n\nvar code = 0;\nvar str = [];\nfor (var i = 0; i < wordChars.length; i += 2) {\n    str.push(code += wordChars[i]);\n    if (wordChars[i + 1])\n        str.push(45, code += wordChars[i + 1]);\n}\n\nexports.wordChars = String.fromCharCode.apply(null, str);\n"
  },
  {
    "path": "src/virtual_renderer.js",
    "content": "\"use strict\";\n/**\n * @typedef {import(\"./edit_session\").EditSession} EditSession\n * @typedef {import(\"../ace-internal\").Ace.Point} Point\n * @typedef {import(\"../ace-internal\").Ace.Theme} Theme\n */\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar config = require(\"./config\");\nvar GutterLayer = require(\"./layer/gutter\").Gutter;\nvar MarkerLayer = require(\"./layer/marker\").Marker;\nvar TextLayer = require(\"./layer/text\").Text;\nvar CursorLayer = require(\"./layer/cursor\").Cursor;\nvar HScrollBar = require(\"./scrollbar\").HScrollBar;\nvar VScrollBar = require(\"./scrollbar\").VScrollBar;\nvar HScrollBarCustom = require(\"./scrollbar_custom\").HScrollBar;\nvar VScrollBarCustom = require(\"./scrollbar_custom\").VScrollBar;\nvar RenderLoop = require(\"./renderloop\").RenderLoop;\nvar FontMetrics = require(\"./layer/font_metrics\").FontMetrics;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar editorCss = require(\"./css/editor-css\");\nvar Decorator = require(\"./layer/decorators\").Decorator;\n\nvar useragent = require(\"./lib/useragent\");\nconst isTextToken = require(\"./layer/text_util\").isTextToken;\n\ndom.importCssString(editorCss, \"ace_editor.css\", false);\n\n/**\n * The class that is responsible for drawing everything you see on the screen!\n * @related editor.renderer\n **/\nclass VirtualRenderer {\n    /**\n     * Constructs a new `VirtualRenderer` within the `container` specified, applying the given `theme`.\n     * @param {HTMLElement | null} [container] The root element of the editor\n     * @param {String} [theme] The starting theme\n\n     **/\n    constructor(container, theme) {\n        var _self = this;\n        this.container = container || dom.createElement(\"div\");\n\n        dom.addCssClass(this.container, \"ace_editor\");\n        if (dom.HI_DPI) dom.addCssClass(this.container, \"ace_hidpi\");\n\n        this.setTheme(theme);\n        if (config.get(\"useStrictCSP\") == null)\n            config.set(\"useStrictCSP\", false);\n\n        this.$gutter = dom.createElement(\"div\");\n        this.$gutter.className = \"ace_gutter\";\n        this.container.appendChild(this.$gutter);\n        this.$gutter.setAttribute(\"aria-hidden\", \"true\");\n        /**@type {HTMLElement}*/\n        this.scroller = dom.createElement(\"div\");\n        this.scroller.className = \"ace_scroller\";\n\n        this.container.appendChild(this.scroller);\n        /**@type {HTMLElement}*/\n        this.content = dom.createElement(\"div\");\n        this.content.className = \"ace_content\";\n        this.scroller.appendChild(this.content);\n\n        this.$gutterLayer = new GutterLayer(this.$gutter);\n        this.$gutterLayer.on(\"changeGutterWidth\", this.onGutterResize.bind(this));\n\n        this.$markerBack = new MarkerLayer(this.content);\n        var textLayer = this.$textLayer = new TextLayer(this.content);\n        this.canvas = textLayer.element;\n\n        this.$markerFront = new MarkerLayer(this.content);\n\n        this.$cursorLayer = new CursorLayer(this.content);\n\n        // Indicates whether the horizontal scrollbar is visible\n        this.$horizScroll = false;\n        this.$vScroll = false;\n\n        this.scrollBar =\n            this.scrollBarV = new VScrollBar(this.container, this);\n        this.scrollBarH = new HScrollBar(this.container, this);\n        this.scrollBarV.on(\"scroll\", function(e) {\n            if (!_self.$scrollAnimation)\n                _self.session.setScrollTop(e.data - _self.scrollMargin.top);\n        });\n        this.scrollBarH.on(\"scroll\", function(e) {\n            if (!_self.$scrollAnimation)\n                _self.session.setScrollLeft(e.data - _self.scrollMargin.left);\n        });\n\n        this.scrollTop = 0;\n        this.scrollLeft = 0;\n\n        this.cursorPos = {\n            row : 0,\n            column : 0\n        };\n\n        this.$fontMetrics = new FontMetrics(this.container);\n        this.$textLayer.$setFontMetrics(this.$fontMetrics);\n        this.$textLayer.on(\"changeCharacterSize\", function(e) {\n            _self.updateCharacterSize();\n            _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);\n            _self._signal(\"changeCharacterSize\", e);\n        });\n\n        this.$size = {\n            width: 0,\n            height: 0,\n            scrollerHeight: 0,\n            scrollerWidth: 0,\n            $dirty: true\n        };\n\n        this.layerConfig = {\n            width : 1,\n            padding : 0,\n            firstRow : 0,\n            firstRowScreen: 0,\n            lastRow : 0,\n            lineHeight : 0,\n            characterWidth : 0,\n            minHeight : 1,\n            maxHeight : 1,\n            offset : 0,\n            height : 1,\n            gutterOffset: 1\n        };\n\n        this.scrollMargin = {\n            left: 0,\n            right: 0,\n            top: 0,\n            bottom: 0,\n            v: 0,\n            h: 0\n        };\n\n        this.margin = {\n            left: 0,\n            right: 0,\n            top: 0,\n            bottom: 0,\n            v: 0,\n            h: 0\n        };\n\n        this.$keepTextAreaAtCursor = !useragent.isIOS;\n\n        this.$loop = new RenderLoop(\n            this.$renderChanges.bind(this),\n            this.container.ownerDocument.defaultView\n        );\n        this.$loop.schedule(this.CHANGE_FULL);\n\n        this.updateCharacterSize();\n        this.setPadding(4);\n        this.$addResizeObserver();\n        config.resetOptions(this);\n        config._signal(\"renderer\", this);\n    }\n\n\n    // this.$logChanges = function(changes) {\n    //     var a = \"\"\n    //     if (changes & this.CHANGE_CURSOR) a += \" cursor\";\n    //     if (changes & this.CHANGE_MARKER) a += \" marker\";\n    //     if (changes & this.CHANGE_GUTTER) a += \" gutter\";\n    //     if (changes & this.CHANGE_SCROLL) a += \" scroll\";\n    //     if (changes & this.CHANGE_LINES) a += \" lines\";\n    //     if (changes & this.CHANGE_TEXT) a += \" text\";\n    //     if (changes & this.CHANGE_SIZE) a += \" size\";\n    //     if (changes & this.CHANGE_MARKER_BACK) a += \" marker_back\";\n    //     if (changes & this.CHANGE_MARKER_FRONT) a += \" marker_front\";\n    //     if (changes & this.CHANGE_FULL) a += \" full\";\n    //     if (changes & this.CHANGE_H_SCROLL) a += \" h_scroll\";\n    //     console.log(a.trim())\n    // };\n\n    updateCharacterSize() {\n        // @ts-expect-error TODO: missing property initialization anywhere in codebase\n        if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {\n            // @ts-expect-error TODO: missing property initialization anywhere in codebase\n            this.$allowBoldFonts = this.$textLayer.allowBoldFonts;\n            this.setStyle(\"ace_nobold\", !this.$allowBoldFonts);\n        }\n\n        this.layerConfig.characterWidth =\n        this.characterWidth = this.$textLayer.getCharacterWidth();\n        this.layerConfig.lineHeight =\n        this.lineHeight = this.$textLayer.getLineHeight();\n        this.$updatePrintMargin();\n        // set explicit line height to avoid normal resolving to different values based on text\n        dom.setStyle(this.scroller.style, \"line-height\", this.lineHeight + \"px\");\n    }\n\n    /**\n     *\n     * Associates the renderer with an [[EditSession `EditSession`]].\n     * @param {EditSession} session The session to associate with\n     **/\n    setSession(session) {\n        if (this.session)\n            this.session.doc.off(\"changeNewLineMode\", this.onChangeNewLineMode);\n\n        this.session = session;\n        if (session && this.scrollMargin.top && session.getScrollTop() <= 0)\n            session.setScrollTop(-this.scrollMargin.top);\n\n        this.$cursorLayer.setSession(session);\n        this.$markerBack.setSession(session);\n        this.$markerFront.setSession(session);\n        this.$gutterLayer.setSession(session);\n        this.$textLayer.setSession(session);\n        if (!session)\n            return;\n\n        this.$loop.schedule(this.CHANGE_FULL);\n        this.session.$setFontMetrics(this.$fontMetrics);\n        this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;\n\n        this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);\n        this.onChangeNewLineMode();\n        this.session.doc.on(\"changeNewLineMode\", this.onChangeNewLineMode);\n    }\n\n    /**\n     * Triggers a partial update of the text, from the range given by the two parameters.\n     * @param {Number} firstRow The first row to update\n     * @param {Number} lastRow The last row to update\n     * @param {boolean} [force]\n     **/\n    updateLines(firstRow, lastRow, force) {\n        if (lastRow === undefined)\n            lastRow = Infinity;\n\n        if (!this.$changedLines) {\n            this.$changedLines = {\n                firstRow: firstRow,\n                lastRow: lastRow\n            };\n        }\n        else {\n            if (this.$changedLines.firstRow > firstRow)\n                this.$changedLines.firstRow = firstRow;\n\n            if (this.$changedLines.lastRow < lastRow)\n                this.$changedLines.lastRow = lastRow;\n        }\n\n        // If the change happened offscreen above us then it's possible\n        // that a new line wrap will affect the position of the lines on our\n        // screen so they need redrawn.\n        // TODO: better solution is to not change scroll position when text is changed outside of visible area\n        if (this.$changedLines.lastRow < this.layerConfig.firstRow) {\n            if (force)\n                this.$changedLines.lastRow = this.layerConfig.lastRow;\n            else\n                return;\n        }\n        if (this.$changedLines.firstRow > this.layerConfig.lastRow)\n            return;\n        this.$loop.schedule(this.CHANGE_LINES);\n    }\n\n    /**\n     * @internal\n     */\n    onChangeNewLineMode() {\n        this.$loop.schedule(this.CHANGE_TEXT);\n        this.$textLayer.$updateEolChar();\n        this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR);\n    }\n\n    /**\n     * @internal\n     */\n    onChangeTabSize() {\n        this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);\n        this.$textLayer.onChangeTabSize();\n    }\n\n    /**\n     * Triggers a full update of the text, for all the rows.\n     **/\n    updateText() {\n        this.$loop.schedule(this.CHANGE_TEXT);\n    }\n\n    /**\n     * Triggers a full update of all the layers, for all the rows.\n     * @param {Boolean} [force] If `true`, forces the changes through\n\n     **/\n    updateFull(force) {\n        if (force)\n            this.$renderChanges(this.CHANGE_FULL, true);\n        else\n            this.$loop.schedule(this.CHANGE_FULL);\n    }\n\n    /**\n     * Updates the font size.\n     **/\n    updateFontSize() {\n        this.$textLayer.checkForSizeChanges();\n    }\n\n    $updateSizeAsync() {\n        if (this.$loop.pending)\n            this.$size.$dirty = true;\n        else\n            this.onResize();\n    }\n    /**\n     * [Triggers a resize of the editor.]{: #VirtualRenderer.onResize}\n     * @param {Boolean} [force] If `true`, recomputes the size, even if the height and width haven't changed\n     * @param {Number} [gutterWidth] The width of the gutter in pixels\n     * @param {Number} [width] The width of the editor in pixels\n     * @param {Number} [height] The hiehgt of the editor, in pixels\n     * @internal\n     **/\n    onResize(force, gutterWidth, width, height) {\n        if (this.resizing > 2)\n            return;\n        else if (this.resizing > 0)\n            this.resizing++;\n        else\n            this.resizing = force ? 1 : 0;\n        // `|| el.scrollHeight` is required for autosizing editors on ie\n        // where elements with clientHeight = 0 also have clientWidth = 0\n        var el = this.container;\n        if (!height)\n            height = el.clientHeight || el.scrollHeight;\n        if (!height && this.$maxLines && this.lineHeight > 1) {\n            // if we are supposed to fit to content set height at least to 1\n            // so that render does not exit early before calling $autosize\n            if (!el.style.height || el.style.height == \"0px\") {\n                el.style.height = \"1px\";\n                height = el.clientHeight || el.scrollHeight;\n            }\n        }\n        if (!width)\n            width = el.clientWidth || el.scrollWidth;\n        var changes = this.$updateCachedSize(force, gutterWidth, width, height);\n\n        if (this.$resizeTimer) this.$resizeTimer.cancel();\n\n        if (!this.$size.scrollerHeight || (!width && !height))\n            return this.resizing = 0;\n\n        if (force)\n            this.$gutterLayer.$padding = null;\n\n        if (force)\n            this.$renderChanges(changes | this.$changes, true);\n        else\n            this.$loop.schedule(changes | this.$changes);\n\n        if (this.resizing)\n            this.resizing = 0;\n        // reset cached values on scrollbars, needs to be removed when switching to non-native scrollbars\n        // see https://github.com/ajaxorg/ace/issues/2195\n        this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;\n        if (this.$customScrollbar) {\n            this.$updateCustomScrollbar(true);\n        }\n    }\n\n    /**\n     * @param [force]\n     * @param [gutterWidth]\n     * @param [width]\n     * @param [height]\n     * @return {number}\n\n     */\n    $updateCachedSize(force, gutterWidth, width, height) {\n        height -= (this.$extraHeight || 0);\n        var changes = 0;\n        var size = this.$size;\n        var oldSize = {\n            width: size.width,\n            height: size.height,\n            scrollerHeight: size.scrollerHeight,\n            scrollerWidth: size.scrollerWidth\n        };\n        if (height && (force || size.height != height)) {\n            size.height = height;\n            changes |= this.CHANGE_SIZE;\n\n            size.scrollerHeight = size.height;\n            if (this.$horizScroll)\n                size.scrollerHeight -= this.scrollBarH.getHeight();\n\n            this.scrollBarV.setHeight(size.scrollerHeight);\n            this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + \"px\";\n\n            changes = changes | this.CHANGE_SCROLL;\n        }\n\n        if (width && (force || size.width != width)) {\n            changes |= this.CHANGE_SIZE;\n            size.width = width;\n\n            if (gutterWidth == null)\n                gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;\n\n            this.gutterWidth = gutterWidth;\n\n            dom.setStyle(this.scrollBarH.element.style, \"left\", gutterWidth + \"px\");\n            dom.setStyle(this.scroller.style, \"left\", gutterWidth + this.margin.left + \"px\");\n            size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth() - this.margin.h);\n            dom.setStyle(this.$gutter.style, \"left\", this.margin.left + \"px\");\n\n            var right = this.scrollBarV.getWidth() + \"px\";\n            dom.setStyle(this.scrollBarH.element.style, \"right\", right);\n            dom.setStyle(this.scroller.style, \"right\", right);\n            dom.setStyle(this.scroller.style, \"bottom\", this.scrollBarH.getHeight());\n\n            this.scrollBarH.setWidth(size.scrollerWidth);\n\n            if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) {\n                changes |= this.CHANGE_FULL;\n            }\n        }\n\n        size.$dirty = !width || !height;\n\n        if (changes)\n            this._signal(\"resize\", oldSize);\n\n        return changes;\n    }\n\n    /**\n     *\n     * @param {number} width\n     * @internal\n     */\n    onGutterResize(width) {\n        var gutterWidth = this.$showGutter ? width : 0;\n        if (gutterWidth != this.gutterWidth)\n            this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);\n\n        if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {\n            this.$loop.schedule(this.CHANGE_FULL);\n        } else if (this.$size.$dirty) {\n            this.$loop.schedule(this.CHANGE_FULL);\n        } else {\n            this.$computeLayerConfig();\n        }\n    }\n\n    /**\n     * Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.\n\n     **/\n    adjustWrapLimit() {\n        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;\n        var limit = Math.floor(availableWidth / this.characterWidth);\n        return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);\n    }\n\n    /**\n     * Identifies whether you want to have an animated scroll or not.\n     * @param {Boolean} shouldAnimate Set to `true` to show animated scrolls\n\n     **/\n    setAnimatedScroll(shouldAnimate){\n        this.setOption(\"animatedScroll\", shouldAnimate);\n    }\n\n    /**\n     * Returns whether an animated scroll happens or not.\n     * @returns {Boolean}\n\n     **/\n    getAnimatedScroll() {\n        return this.$animatedScroll;\n    }\n\n    /**\n     * Identifies whether you want to show invisible characters or not.\n     * @param {Boolean} showInvisibles Set to `true` to show invisibles\n\n     **/\n    setShowInvisibles(showInvisibles) {\n        this.setOption(\"showInvisibles\", showInvisibles);\n        this.session.$bidiHandler.setShowInvisibles(showInvisibles);\n    }\n\n    /**\n     * Returns whether invisible characters are being shown or not.\n     * @returns {Boolean}\n\n     **/\n    getShowInvisibles() {\n        return this.getOption(\"showInvisibles\");\n    }\n\n    /**\n     * @return {boolean}\n\n     */\n    getDisplayIndentGuides() {\n        return this.getOption(\"displayIndentGuides\");\n    }\n\n    /**\n     * @param {boolean} display\n\n     */\n    setDisplayIndentGuides(display) {\n        this.setOption(\"displayIndentGuides\", display);\n    }\n\n    /**\n\n     * @return {boolean}\n     */\n    getHighlightIndentGuides() {\n        return this.getOption(\"highlightIndentGuides\");\n    }\n\n    /**\n\n     * @param {boolean} highlight\n     */\n    setHighlightIndentGuides(highlight) {\n        this.setOption(\"highlightIndentGuides\", highlight);\n    }\n\n    /**\n     * Identifies whether you want to show the print margin or not.\n     * @param {Boolean} showPrintMargin Set to `true` to show the print margin\n\n     **/\n    setShowPrintMargin(showPrintMargin) {\n        this.setOption(\"showPrintMargin\", showPrintMargin);\n    }\n\n    /**\n     * Returns whether the print margin is being shown or not.\n     * @returns {Boolean}\n\n     **/\n    getShowPrintMargin() {\n        return this.getOption(\"showPrintMargin\");\n    }\n    /**\n     * Identifies whether you want to show the print margin column or not.\n     * @param {number} printMarginColumn Set to `true` to show the print margin column\n\n     **/\n    setPrintMarginColumn(printMarginColumn) {\n        this.setOption(\"printMarginColumn\", printMarginColumn);\n    }\n\n    /**\n     * Returns whether the print margin column is being shown or not.\n     * @returns {number}\n\n     **/\n    getPrintMarginColumn() {\n        return this.getOption(\"printMarginColumn\");\n    }\n\n    /**\n     * Returns `true` if the gutter is being shown.\n     * @returns {Boolean}\n\n     **/\n    getShowGutter(){\n        return this.getOption(\"showGutter\");\n    }\n\n    /**\n     * Identifies whether you want to show the gutter or not.\n     * @param {Boolean} show Set to `true` to show the gutter\n\n     **/\n    setShowGutter(show){\n        return this.setOption(\"showGutter\", show);\n    }\n\n    /**\n\n     * @returns {boolean}\n     */\n    getFadeFoldWidgets(){\n        return this.getOption(\"fadeFoldWidgets\");\n    }\n\n    /**\n\n     * @param {boolean} show\n     */\n    setFadeFoldWidgets(show) {\n        this.setOption(\"fadeFoldWidgets\", show);\n    }\n\n    /**\n      *\n     * @param {boolean} shouldHighlight\n     */\n    setHighlightGutterLine(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    }\n\n    /**\n\n     * @returns {boolean}\n     */\n    getHighlightGutterLine() {\n        return this.getOption(\"highlightGutterLine\");\n    }\n\n    /**\n\n     */\n    $updatePrintMargin() {\n        if (!this.$showPrintMargin && !this.$printMarginEl)\n            return;\n\n        if (!this.$printMarginEl) {\n            var containerEl = dom.createElement(\"div\");\n            containerEl.className = \"ace_layer ace_print-margin-layer\";\n            this.$printMarginEl = dom.createElement(\"div\");\n            this.$printMarginEl.className = \"ace_print-margin\";\n            containerEl.appendChild(this.$printMarginEl);\n            this.content.insertBefore(containerEl, this.content.firstChild);\n        }\n\n        var style = this.$printMarginEl.style;\n        style.left = Math.round(this.characterWidth * this.$printMarginColumn + this.$padding) + \"px\";\n        style.visibility = this.$showPrintMargin ? \"visible\" : \"hidden\";\n\n        if (this.session && this.session.$wrap == -1)\n            this.adjustWrapLimit();\n    }\n\n    /**\n     *\n     * Returns the root element containing this renderer.\n     * @returns {HTMLElement}\n     **/\n    getContainerElement() {\n        return this.container;\n    }\n\n    /**\n     *\n     * Returns the element that the mouse events are attached to\n     * @returns {HTMLElement}\n     **/\n    getMouseEventTarget() {\n        return this.scroller;\n    }\n\n    /**\n     *\n     * Returns the element to which the hidden text area is added.\n     * @returns {HTMLElement}\n     **/\n    getTextAreaContainer() {\n        return this.container;\n    }\n\n    // move text input over the cursor\n    // this is required for IME\n    /**\n\n     */\n    $moveTextAreaToCursor() {\n        if (this.$isMousePressed) return;\n        var style = this.textarea.style;\n        var composition = this.$composition;\n        if (!this.$keepTextAreaAtCursor && !composition) {\n            dom.translate(this.textarea, -100, 0);\n            return;\n        }\n        var pixelPos = this.$cursorLayer.$pixelPos;\n        if (!pixelPos)\n            return;\n        if (composition && composition.markerRange)\n            pixelPos = this.$cursorLayer.getPixelPosition(composition.markerRange.start, true);\n\n        var config = this.layerConfig;\n        var posTop = pixelPos.top;\n        var posLeft = pixelPos.left;\n        posTop -= config.offset;\n\n        var h = composition && composition.useTextareaForIME || useragent.isMobile ? this.lineHeight : 1;\n        if (posTop < 0 || posTop > config.height - h) {\n            dom.translate(this.textarea, 0, 0);\n            return;\n        }\n\n        var w = 1;\n        var maxTop = this.$size.height - h;\n        if (!composition) {\n            posTop += this.lineHeight;\n        }\n        else {\n            if (composition.useTextareaForIME) {\n                var val = this.textarea.value;\n                w = this.characterWidth * (this.session.$getStringScreenWidth(val)[0]);\n            }\n            else {\n                posTop += this.lineHeight + 2;\n            }\n        }\n\n        posLeft -= this.scrollLeft;\n        if (posLeft > this.$size.scrollerWidth - w)\n            posLeft = this.$size.scrollerWidth - w;\n\n        posLeft += this.gutterWidth + this.margin.left;\n\n        dom.setStyle(style, \"height\", h + \"px\");\n        dom.setStyle(style, \"width\", w + \"px\");\n        dom.translate(this.textarea, Math.min(posLeft, this.$size.scrollerWidth - w), Math.min(posTop, maxTop));\n    }\n\n    /**\n     * [Returns the index of the first visible row.]{: #VirtualRenderer.getFirstVisibleRow}\n     * @returns {Number}\n     **/\n    getFirstVisibleRow() {\n        return this.layerConfig.firstRow;\n    }\n\n    /**\n     *\n     * Returns the index of the first fully visible row. \"Fully\" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.\n     * @returns {Number}\n     **/\n    getFirstFullyVisibleRow() {\n        return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);\n    }\n\n    /**\n     *\n     * Returns the index of the last fully visible row. \"Fully\" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.\n     * @returns {Number}\n     **/\n    getLastFullyVisibleRow() {\n        var config = this.layerConfig;\n        var lastRow = config.lastRow;\n        var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight;\n        if (top - this.session.getScrollTop() > config.height - config.lineHeight)\n            return lastRow - 1;\n        return lastRow;\n    }\n\n    /**\n     *\n     * [Returns the index of the last visible row.]{: #VirtualRenderer.getLastVisibleRow}\n     * @returns {Number}\n     **/\n    getLastVisibleRow() {\n        return this.layerConfig.lastRow;\n    }\n\n    /**\n     * Sets the padding for all the layers.\n     * @param {Number} padding A new padding value (in pixels)\n\n     **/\n    setPadding(padding) {\n        this.$padding = padding;\n        this.$textLayer.setPadding(padding);\n        this.$cursorLayer.setPadding(padding);\n        this.$markerFront.setPadding(padding);\n        this.$markerBack.setPadding(padding);\n        this.$loop.schedule(this.CHANGE_FULL);\n        this.$updatePrintMargin();\n    }\n\n    /**\n     *\n     * @param {number} [top]\n     * @param {number} [bottom]\n     * @param {number} [left]\n     * @param {number} [right]\n\n     */\n    setScrollMargin(top, bottom, left, right) {\n        var sm = this.scrollMargin;\n        sm.top = top|0;\n        sm.bottom = bottom|0;\n        sm.right = right|0;\n        sm.left = left|0;\n        sm.v = sm.top + sm.bottom;\n        sm.h = sm.left + sm.right;\n        if (sm.top && this.scrollTop <= 0 && this.session)\n            this.session.setScrollTop(-sm.top);\n        this.updateFull();\n    }\n\n    /**\n     *\n     * @param {number} [top]\n     * @param {number} [bottom]\n     * @param {number} [left]\n     * @param {number} [right]\n\n     */\n    setMargin(top, bottom, left, right) {\n        var sm = this.margin;\n        sm.top = top|0;\n        sm.bottom = bottom|0;\n        sm.right = right|0;\n        sm.left = left|0;\n        sm.v = sm.top + sm.bottom;\n        sm.h = sm.left + sm.right;\n        this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height);\n        this.updateFull();\n    }\n\n    /**\n     * Returns whether the horizontal scrollbar is set to be always visible.\n     * @returns {Boolean}\n\n     **/\n    getHScrollBarAlwaysVisible() {\n        return this.$hScrollBarAlwaysVisible;\n    }\n\n    /**\n     * Identifies whether you want to show the horizontal scrollbar or not.\n     * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible\n\n     **/\n    setHScrollBarAlwaysVisible(alwaysVisible) {\n        this.setOption(\"hScrollBarAlwaysVisible\", alwaysVisible);\n    }\n    /**\n     * Returns whether the horizontal scrollbar is set to be always visible.\n     * @returns {Boolean}\n\n     **/\n    getVScrollBarAlwaysVisible() {\n        return this.$vScrollBarAlwaysVisible;\n    }\n\n    /**\n     * Identifies whether you want to show the horizontal scrollbar or not.\n     * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible\n     **/\n    setVScrollBarAlwaysVisible(alwaysVisible) {\n        this.setOption(\"vScrollBarAlwaysVisible\", alwaysVisible);\n    }\n\n    /**\n\n     */\n    $updateScrollBarV() {\n        var scrollHeight = this.layerConfig.maxHeight;\n        var scrollerHeight = this.$size.scrollerHeight;\n        if (!this.$maxLines && this.$scrollPastEnd) {\n            scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;\n            if (this.scrollTop > scrollHeight - scrollerHeight) {\n                scrollHeight = this.scrollTop + scrollerHeight;\n                this.scrollBarV.scrollTop = null;\n            }\n        }\n        this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);\n        this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);\n    }\n    $updateScrollBarH() {\n        this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);\n        this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);\n    }\n\n    freeze() {\n        this.$frozen = true;\n    }\n\n    unfreeze() {\n        this.$frozen = false;\n    }\n\n    /**\n     *\n     * @param {number} changes\n     * @param {boolean} [force]\n     * @returns {number}\n\n     */\n    $renderChanges(changes, force) {\n        if (this.$changes) {\n            changes |= this.$changes;\n            this.$changes = 0;\n        }\n        if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {\n            this.$changes |= changes;\n            return;\n        }\n        if (this.$size.$dirty) {\n            this.$changes |= changes;\n            return this.onResize(true);\n        }\n        if (!this.lineHeight) {\n            this.$textLayer.checkForSizeChanges();\n        }\n        // this.$logChanges(changes);\n\n        this._signal(\"beforeRender\", changes);\n\n        if (this.session && this.session.$bidiHandler)\n            this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);\n\n        var config = this.layerConfig;\n        // text, scrolling and resize changes can cause the view port size to change\n        if (changes & this.CHANGE_FULL ||\n            changes & this.CHANGE_SIZE ||\n            changes & this.CHANGE_TEXT ||\n            changes & this.CHANGE_LINES ||\n            changes & this.CHANGE_SCROLL ||\n            changes & this.CHANGE_H_SCROLL\n        ) {\n            changes |= this.$computeLayerConfig() | this.$loop.clear();\n            // If a change is made offscreen and wrapMode is on, then the onscreen\n            // lines may have been pushed down. If so, the first screen row will not\n            // have changed, but the first actual row will. In that case, adjust\n            // scrollTop so that the cursor and onscreen content stays in the same place.\n            // TODO: find a better way to handle this, that works non wrapped case and doesn't compute layerConfig twice\n            if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) {\n                var st = this.scrollTop + (config.firstRow - Math.max(this.layerConfig.firstRow, 0)) * this.lineHeight;\n                if (st > 0) {\n                    // this check is needed as a workaround for the documentToScreenRow returning -1 if document.length == 0\n                    this.scrollTop = st;\n                    changes = changes | this.CHANGE_SCROLL;\n                    changes |= this.$computeLayerConfig() | this.$loop.clear();\n                }\n            }\n            config = this.layerConfig;\n            // update scrollbar first to not lose scroll position when gutter calls resize\n            this.$updateScrollBarV();\n            if (changes & this.CHANGE_H_SCROLL)\n                this.$updateScrollBarH();\n\n            dom.translate(this.content, -this.scrollLeft, -config.offset);\n\n            var width = config.width + 2 * this.$padding + \"px\";\n            var height = config.minHeight + \"px\";\n\n            dom.setStyle(this.content.style, \"width\", width);\n            dom.setStyle(this.content.style, \"height\", height);\n        }\n\n        // horizontal scrolling\n        if (changes & this.CHANGE_H_SCROLL) {\n            dom.translate(this.content, -this.scrollLeft, -config.offset);\n            this.scroller.className = this.scrollLeft <= 0 ? \"ace_scroller \" : \"ace_scroller ace_scroll-left \";\n            if (this.enableKeyboardAccessibility)\n                this.scroller.className += this.keyboardFocusClassName;\n        }\n\n        // full\n        if (changes & this.CHANGE_FULL) {\n            this.$changedLines = null;\n            this.$textLayer.update(config);\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n            this.$markerBack.update(config);\n            this.$markerFront.update(config);\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n            this._signal(\"afterRender\", changes);\n            return;\n        }\n\n        // scrolling\n        if (changes & this.CHANGE_SCROLL) {\n            this.$changedLines = null;\n            if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)\n                this.$textLayer.update(config);\n            else\n                this.$textLayer.scrollLines(config);\n\n            if (this.$showGutter) {\n                if (changes & this.CHANGE_GUTTER || changes & this.CHANGE_LINES)\n                    this.$gutterLayer.update(config);\n                else\n                    this.$gutterLayer.scrollLines(config);\n            }\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n            this.$markerBack.update(config);\n            this.$markerFront.update(config);\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n            this._signal(\"afterRender\", changes);\n            return;\n        }\n\n        if (changes & this.CHANGE_TEXT) {\n            this.$changedLines = null;\n            this.$textLayer.update(config);\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n        }\n        else if (changes & this.CHANGE_LINES) {\n            if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)\n                this.$gutterLayer.update(config);\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n        }\n        else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n        }\n        else if (changes & this.CHANGE_CURSOR) {\n            if (this.$highlightGutterLine)\n                // @ts-expect-error TODO: potential wrong param\n                this.$gutterLayer.updateLineHighlight(config);\n            if (this.$customScrollbar) {\n                this.$scrollDecorator.$updateDecorators(config);\n            }\n        }\n\n        if (changes & this.CHANGE_CURSOR) {\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n        }\n\n        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {\n            this.$markerFront.update(config);\n        }\n\n        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {\n            this.$markerBack.update(config);\n        }\n\n        this._signal(\"afterRender\", changes);\n    }\n\n    /**\n\n     */\n    $autosize() {\n        var height = this.session.getScreenLength() * this.lineHeight;\n        var maxHeight = this.$maxLines * this.lineHeight;\n        var desiredHeight = Math.min(maxHeight,\n            Math.max((this.$minLines || 1) * this.lineHeight, height)\n        ) + this.scrollMargin.v + (this.$extraHeight || 0);\n        if (this.$horizScroll)\n            desiredHeight += this.scrollBarH.getHeight();\n        if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight)\n            desiredHeight = this.$maxPixelHeight;\n\n        var hideScrollbars = desiredHeight <= 2 * this.lineHeight;\n        var vScroll = !hideScrollbars && height > maxHeight;\n\n        if (desiredHeight != this.desiredHeight ||\n            this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {\n            if (vScroll != this.$vScroll) {\n                this.$vScroll = vScroll;\n                this.scrollBarV.setVisible(vScroll);\n            }\n\n            var w = this.container.clientWidth;\n            this.container.style.height = desiredHeight + \"px\";\n            this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);\n            // this.$loop.changes = 0;\n            this.desiredHeight = desiredHeight;\n\n            this._signal(\"autosize\");\n        }\n    }\n\n    /**\n\n     * @returns {number}\n     */\n    $computeLayerConfig() {\n        var session = this.session;\n        var size = this.$size;\n\n        var hideScrollbars = size.height <= 2 * this.lineHeight;\n        var screenLines = this.session.getScreenLength();\n        var maxHeight = screenLines * this.lineHeight;\n\n        var longestLine = this.$getLongestLine();\n\n        var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||\n            size.scrollerWidth - longestLine - 2 * this.$padding < 0);\n\n        var hScrollChanged = this.$horizScroll !== horizScroll;\n        if (hScrollChanged) {\n            this.$horizScroll = horizScroll;\n            this.scrollBarH.setVisible(horizScroll);\n        }\n        var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine\n        // autoresize only after updating hscroll to include scrollbar height in desired height\n        if (this.$maxLines && this.lineHeight > 1){\n            this.$autosize();\n            // recalculate this after $autosize so we take vertical scroll into account when calculating width\n            hideScrollbars = size.height <= 2 * this.lineHeight;\n        }\n\n        var minHeight = size.scrollerHeight + this.lineHeight;\n\n        var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd\n            ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd\n            : 0;\n        maxHeight += scrollPastEnd;\n\n        var sm = this.scrollMargin;\n        this.session.setScrollTop(Math.max(-sm.top,\n            Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));\n\n        this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft,\n            longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));\n\n        var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||\n            size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top);\n        var vScrollChanged = vScrollBefore !== vScroll;\n        if (vScrollChanged) {\n            this.$vScroll = vScroll;\n            this.scrollBarV.setVisible(vScroll);\n        }\n\n        var offset = this.scrollTop % this.lineHeight;\n        var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;\n        var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));\n        var lastRow = firstRow + lineCount;\n\n        // Map lines on the screen to lines in the document.\n        var firstRowScreen, firstRowHeight;\n        var lineHeight = this.lineHeight;\n        firstRow = session.screenToDocumentRow(firstRow, 0);\n\n        // Check if firstRow is inside of a foldLine. If true, then use the first\n        // row of the foldLine.\n        var foldLine = session.getFoldLine(firstRow);\n        if (foldLine) {\n            firstRow = foldLine.start.row;\n        }\n\n        firstRowScreen = session.documentToScreenRow(firstRow, 0);\n        firstRowHeight = session.getRowLength(firstRow) * lineHeight;\n\n        lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);\n        minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +\n                                                firstRowHeight;\n\n        offset = this.scrollTop - firstRowScreen * lineHeight;\n        // adjust firstRowScreen and offset in case there is a line widget above the first row\n        if (offset < 0 && firstRowScreen > 0) {\n            firstRowScreen = Math.max(0, firstRowScreen + Math.floor(offset / lineHeight));\n            offset = this.scrollTop - firstRowScreen * lineHeight;\n        }\n\n        var changes = 0;\n        if (this.layerConfig.width != longestLine || hScrollChanged)\n            changes = this.CHANGE_H_SCROLL;\n        // Horizontal scrollbar visibility may have changed, which changes\n        // the client height of the scroller\n        if (hScrollChanged || vScrollChanged) {\n            changes |= this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);\n            this._signal(\"scrollbarVisibilityChanged\");\n            if (vScrollChanged)\n                longestLine = this.$getLongestLine();\n        }\n\n        this.layerConfig = {\n            width : longestLine,\n            padding : this.$padding,\n            firstRow : firstRow,\n            firstRowScreen: firstRowScreen,\n            lastRow : lastRow,\n            lineHeight : lineHeight,\n            characterWidth : this.characterWidth,\n            minHeight : minHeight,\n            maxHeight : maxHeight,\n            offset : offset,\n            gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0,\n            height : this.$size.scrollerHeight\n        };\n\n        if (this.session.$bidiHandler)\n            this.session.$bidiHandler.setContentWidth(longestLine - this.$padding);\n        // For debugging.\n        // console.log(JSON.stringify(this.layerConfig));\n\n        return changes;\n    }\n\n    /**\n     * @returns {boolean | undefined}\n\n     */\n    $updateLines() {\n        if (!this.$changedLines) return;\n        var firstRow = this.$changedLines.firstRow;\n        var lastRow = this.$changedLines.lastRow;\n        this.$changedLines = null;\n\n        var layerConfig = this.layerConfig;\n\n        if (firstRow > layerConfig.lastRow + 1) { return; }\n        if (lastRow < layerConfig.firstRow) { return; }\n\n        // if the last row is unknown -> redraw everything\n        if (lastRow === Infinity) {\n            if (this.$showGutter)\n                this.$gutterLayer.update(layerConfig);\n            this.$textLayer.update(layerConfig);\n            return;\n        }\n\n        // else update only the changed rows\n        this.$textLayer.updateLines(layerConfig, firstRow, lastRow);\n        return true;\n    }\n\n    /**\n     *\n     * @returns {number}\n\n     */\n    $getLongestLine() {\n        var charCount = this.session.getScreenWidth();\n        if (this.showInvisibles && !this.session.$useWrapMode)\n            charCount += 1;\n\n        if (this.$textLayer && charCount > this.$textLayer.MAX_LINE_LENGTH)\n            charCount = this.$textLayer.MAX_LINE_LENGTH + 30;\n\n        return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));\n    }\n\n    /**\n     * Schedules an update to all the front markers in the document.\n     **/\n    updateFrontMarkers() {\n        this.$markerFront.setMarkers(this.session.getMarkers(true));\n        this.$loop.schedule(this.CHANGE_MARKER_FRONT);\n    }\n\n    /**\n     *\n     * Schedules an update to all the back markers in the document.\n     **/\n    updateBackMarkers() {\n        this.$markerBack.setMarkers(this.session.getMarkers());\n        this.$loop.schedule(this.CHANGE_MARKER_BACK);\n    }\n\n    /**\n     *\n     * Deprecated; (moved to [[EditSession]])\n     * @deprecated\n     **/\n    addGutterDecoration(row, className){\n        this.$gutterLayer.addGutterDecoration(row, className);\n    }\n\n    /**\n     * Deprecated; (moved to [[EditSession]])\n     * @deprecated\n     **/\n    removeGutterDecoration(row, className){\n        this.$gutterLayer.removeGutterDecoration(row, className);\n    }\n\n    /**\n     *\n     * Redraw breakpoints.\n     * @param {any} [rows]\n     */\n    updateBreakpoints(rows) {\n        this._rows = rows;\n        this.$loop.schedule(this.CHANGE_GUTTER);\n    }\n\n    /**\n     * Sets annotations for the gutter.\n     * @param {import(\"../ace-internal\").Ace.Annotation[]} annotations An array containing annotations\n     *\n     **/\n    setAnnotations(annotations) {\n        this.$gutterLayer.setAnnotations(annotations);\n        this.$loop.schedule(this.CHANGE_GUTTER);\n    }\n\n    /**\n     *\n     * Updates the cursor icon.\n     **/\n    updateCursor() {\n        this.$loop.schedule(this.CHANGE_CURSOR);\n    }\n\n    /**\n     *\n     * Hides the cursor icon.\n     **/\n    hideCursor() {\n        this.$cursorLayer.hideCursor();\n    }\n\n    /**\n     *\n     * Shows the cursor icon.\n     **/\n    showCursor() {\n        this.$cursorLayer.showCursor();\n    }\n\n    /**\n     *\n     * @param {Point} anchor\n     * @param {Point} lead\n     * @param {number} [offset]\n     */\n    scrollSelectionIntoView(anchor, lead, offset) {\n        // first scroll anchor into view then scroll lead into view\n        this.scrollCursorIntoView(anchor, offset);\n        this.scrollCursorIntoView(lead, offset);\n    }\n\n    /**\n     *\n     * Scrolls the cursor into the first visibile area of the editor\n     * @param {Point} [cursor]\n     * @param {number} [offset]\n     * @param {{ top?: any; bottom?: any; }} [$viewMargin]\n     */\n    scrollCursorIntoView(cursor, offset, $viewMargin) {\n        // the editor is not visible\n        if (this.$size.scrollerHeight === 0)\n            return;\n\n        var pos = this.$cursorLayer.getPixelPosition(cursor);\n\n        var newLeft = pos.left;\n        var newTop = pos.top;\n\n        var topMargin = $viewMargin && $viewMargin.top || 0;\n        var bottomMargin = $viewMargin && $viewMargin.bottom || 0;\n\n        if (this.$scrollAnimation) {\n            this.$stopAnimation = true;\n        }\n\n        var currentTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;\n\n        if (currentTop + topMargin > newTop) {\n            if (offset && currentTop + topMargin > newTop + this.lineHeight)\n                newTop -= offset * this.$size.scrollerHeight;\n            if (newTop === 0)\n                newTop = -this.scrollMargin.top;\n            this.session.setScrollTop(newTop);\n        } else if (currentTop + this.$size.scrollerHeight - bottomMargin < newTop + this.lineHeight) {\n            if (offset && currentTop + this.$size.scrollerHeight - bottomMargin < newTop -  this.lineHeight)\n                newTop += offset * this.$size.scrollerHeight;\n            this.session.setScrollTop(newTop + this.lineHeight + bottomMargin - this.$size.scrollerHeight);\n        }\n\n        var currentLeft = this.scrollLeft;\n        // Show 2 context characters of the line when moving to it\n        var twoCharsWidth = 2 * this.layerConfig.characterWidth;\n\n        if (newLeft - twoCharsWidth < currentLeft) {\n            newLeft -= twoCharsWidth;\n            if (newLeft < this.$padding + twoCharsWidth) {\n                newLeft = -this.scrollMargin.left;\n            }\n            this.session.setScrollLeft(newLeft);\n        } else {\n            newLeft += twoCharsWidth;\n            if (currentLeft + this.$size.scrollerWidth < newLeft + this.characterWidth) {\n                this.session.setScrollLeft(Math.round(newLeft + this.characterWidth - this.$size.scrollerWidth));\n            } else if (currentLeft <= this.$padding && newLeft - currentLeft < this.characterWidth) {\n                this.session.setScrollLeft(0);\n            }\n        }\n    }\n\n    /**\n     * {:EditSession.getScrollTop}\n     * @related EditSession.getScrollTop\n     * @returns {Number}\n     **/\n    getScrollTop() {\n        return this.session.getScrollTop();\n    }\n\n    /**\n     * {:EditSession.getScrollLeft}\n     * @related EditSession.getScrollLeft\n     * @returns {Number}\n     **/\n    getScrollLeft() {\n        return this.session.getScrollLeft();\n    }\n\n    /**\n     * Returns the first visible row, regardless of whether it's fully visible or not.\n     * @returns {Number}\n     **/\n    getScrollTopRow() {\n        return this.scrollTop / this.lineHeight;\n    }\n\n    /**\n     * Returns the last visible row, regardless of whether it's fully visible or not.\n     * @returns {Number}\n     **/\n    getScrollBottomRow() {\n        return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);\n    }\n\n    /**\n     * Gracefully scrolls from the top of the editor to the row indicated.\n     * @param {Number} row A row id\n     *\n     * @related EditSession.setScrollTop\n     **/\n    scrollToRow(row) {\n        this.session.setScrollTop(row * this.lineHeight);\n    }\n\n    /**\n     *\n     * @param {Point} cursor\n     * @param {number} [alignment]\n     * @returns {number}\n     */\n    alignCursor(cursor, alignment) {\n        if (typeof cursor == \"number\")\n            cursor = {row: cursor, column: 0};\n\n        var pos = this.$cursorLayer.getPixelPosition(cursor);\n        var h = this.$size.scrollerHeight - this.lineHeight;\n        var offset = pos.top - h * (alignment || 0);\n\n        this.session.setScrollTop(offset);\n        return offset;\n    }\n\n    /**\n     *\n     * @param {number} fromValue\n     * @param {number} toValue\n     * @returns {*[]}\n     */\n    $calcSteps(fromValue, toValue){\n        var i = 0;\n        var l = this.STEPS;\n        var steps = [];\n\n        var func  = function(t, x_min, dx) {\n            return dx * (Math.pow(t - 1, 3) + 1) + x_min;\n        };\n\n        for (i = 0; i < l; ++i)\n            steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));\n\n        return steps;\n    }\n\n    /**\n     * Gracefully scrolls the editor to the row indicated.\n     * @param {Number} line A line number\n     * @param {Boolean} center If `true`, centers the editor the to indicated line\n     * @param {Boolean} animate If `true` animates scrolling\n     * @param {() => void} [callback] Function to be called after the animation has finished\n\n     **/\n    scrollToLine(line, center, animate, callback) {\n        var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});\n        var offset = pos.top;\n        if (center)\n            offset -= this.$size.scrollerHeight / 2;\n\n        var initialScroll = this.scrollTop;\n        this.session.setScrollTop(offset);\n        if (animate !== false)\n            this.animateScrolling(initialScroll, callback);\n    }\n\n    /**\n     *\n     * @param fromValue\n     * @param [callback]\n\n     */\n    animateScrolling(fromValue, callback) {\n        var toValue = this.scrollTop;\n        if (!this.$animatedScroll)\n            return;\n        var _self = this;\n\n        if (fromValue == toValue)\n            return;\n\n        if (this.$scrollAnimation) {\n            var oldSteps = this.$scrollAnimation.steps;\n            if (oldSteps.length) {\n                fromValue = oldSteps[0];\n                if (fromValue == toValue)\n                    return;\n            }\n        }\n\n        var steps = _self.$calcSteps(fromValue, toValue);\n        this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};\n\n        clearInterval(this.$timer);\n\n        _self.session.setScrollTop(steps.shift());\n        // trick session to think it's already scrolled to not loose toValue\n        _self.session.$scrollTop = toValue;\n\n        function endAnimation() {\n            // @ts-ignore\n            _self.$timer = clearInterval(_self.$timer);\n            _self.$scrollAnimation = null;\n            _self.$stopAnimation = false;\n            callback && callback();\n        }\n\n        this.$timer = setInterval(function() {\n            if (_self.$stopAnimation) {\n                endAnimation();\n                return;\n            }\n\n            if (!_self.session)\n                return clearInterval(_self.$timer);\n            if (steps.length) {\n                _self.session.setScrollTop(steps.shift());\n                _self.session.$scrollTop = toValue;\n            } else if (toValue != null) {\n                _self.session.$scrollTop = -1;\n                _self.session.setScrollTop(toValue);\n                toValue = null;\n            } else {\n                // do this on separate step to not get spurious scroll event from scrollbar\n                endAnimation();\n            }\n        }, 10);\n    }\n\n    /**\n     * Scrolls the editor to the y pixel indicated.\n     * @param {Number} scrollTop The position to scroll to\n     **/\n    scrollToY(scrollTop) {\n        // after calling scrollBar.setScrollTop\n        // scrollbar sends us event with same scrollTop. ignore it\n        if (this.scrollTop !== scrollTop) {\n            this.$loop.schedule(this.CHANGE_SCROLL);\n            this.scrollTop = scrollTop;\n        }\n    }\n\n    /**\n     * Scrolls the editor across the x-axis to the pixel indicated.\n     * @param {Number} scrollLeft The position to scroll to\n     **/\n    scrollToX(scrollLeft) {\n        if (this.scrollLeft !== scrollLeft)\n            this.scrollLeft = scrollLeft;\n        this.$loop.schedule(this.CHANGE_H_SCROLL);\n    }\n\n    /**\n     * Scrolls the editor across both x- and y-axes.\n     * @param {Number} x The x value to scroll to\n     * @param {Number} y The y value to scroll to\n     **/\n    scrollTo(x, y) {\n        this.session.setScrollTop(y);\n        this.session.setScrollLeft(x);\n    }\n\n    /**\n     * Scrolls the editor across both x- and y-axes.\n     * @param {Number} deltaX The x value to scroll by\n     * @param {Number} deltaY The y value to scroll by\n     **/\n    scrollBy(deltaX, deltaY) {\n        deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);\n        deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);\n    }\n\n    /**\n     * Returns `true` if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.\n     * @param {Number} deltaX The x value to scroll by\n     * @param {Number} deltaY The y value to scroll by\n     *\n     * @returns {Boolean}\n     **/\n    isScrollableBy(deltaX, deltaY) {\n        if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)\n           return true;\n        if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight\n            - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)\n           return true;\n        if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)\n            return true;\n        if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth\n            - this.layerConfig.width < -1 + this.scrollMargin.right)\n           return true;\n    }\n\n    /**\n     *\n     * @param {number} x\n     * @param {number} y\n     * @returns {import(\"../ace-internal\").Ace.ScreenCoordinates}\n\n     */\n    pixelToScreenCoordinates(x, y) {\n        var canvasPos;\n        if (this.$hasCssTransforms) {\n            canvasPos = {top:0, left: 0};\n            var p = this.$fontMetrics.transformCoordinates([x, y]);\n            x = p[1] - this.gutterWidth - this.margin.left;\n            y = p[0];\n        } else {\n            canvasPos = this.scroller.getBoundingClientRect();\n        }\n\n        var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;\n        var offset = offsetX / this.characterWidth;\n        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);\n        var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset);\n\n        return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX:  offsetX};\n    }\n\n    /**\n     *\n     * @param {number} x\n     * @param {number} y\n     * @returns {Point}\n\n     */\n    screenToTextCoordinates(x, y) {\n        var canvasPos;\n        if (this.$hasCssTransforms) {\n            canvasPos = {top:0, left: 0};\n            var p = this.$fontMetrics.transformCoordinates([x, y]);\n            x = p[1] - this.gutterWidth - this.margin.left;\n            y = p[0];\n        } else {\n            canvasPos = this.scroller.getBoundingClientRect();\n        }\n\n        var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;\n        var offset = offsetX / this.characterWidth;\n        var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset);\n\n        var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;\n\n        return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX);\n    }\n\n    /**\n     * Returns an object containing the `pageX` and `pageY` coordinates of the document position.\n     * @param {Number} row The document row position\n     * @param {Number} column The document column position\n     *\n     * @returns {{ pageX: number, pageY: number}}\n     **/\n    textToScreenCoordinates(row, column) {\n        var canvasPos = this.scroller.getBoundingClientRect();\n        var pos = this.session.documentToScreenPosition(row, column);\n\n        var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row)\n             ? this.session.$bidiHandler.getPosLeft(pos.column)\n             : Math.round(pos.column * this.characterWidth));\n\n        var y = pos.row * this.lineHeight;\n\n        return {\n            pageX: canvasPos.left + x - this.scrollLeft,\n            pageY: canvasPos.top + y - this.scrollTop\n        };\n    }\n\n    /**\n     *\n     * Focuses the current container.\n     **/\n    visualizeFocus() {\n        dom.addCssClass(this.container, \"ace_focus\");\n    }\n\n    /**\n     *\n     * Blurs the current container.\n     **/\n    visualizeBlur() {\n        dom.removeCssClass(this.container, \"ace_focus\");\n    }\n\n    /**\n     * @param {Object} composition\n\n     **/\n    showComposition(composition) {\n        this.$composition = composition;\n        if (!composition.cssText) {\n            composition.cssText = this.textarea.style.cssText;\n        }\n        if (composition.useTextareaForIME == undefined)\n            composition.useTextareaForIME = this.$useTextareaForIME;\n\n        if (this.$useTextareaForIME) {\n            dom.addCssClass(this.textarea, \"ace_composition\");\n            this.textarea.style.cssText = \"\";\n            this.$moveTextAreaToCursor();\n            this.$cursorLayer.element.style.display = \"none\";\n        }\n        else {\n            composition.markerId = this.session.addMarker(composition.markerRange, \"ace_composition_marker\", \"text\");\n        }\n    }\n\n    /**\n     * @param {String} text A string of text to use\n     *\n     * Sets the inner text of the current composition to `text`.\n\n     **/\n    setCompositionText(text) {\n        var cursor = this.session.selection.cursor;\n        this.addToken(text, \"composition_placeholder\", cursor.row, cursor.column);\n        this.$moveTextAreaToCursor();\n    }\n\n    /**\n     *\n     * Hides the current composition.\n\n     **/\n    hideComposition() {\n        if (!this.$composition)\n            return;\n\n        if (this.$composition.markerId)\n            this.session.removeMarker(this.$composition.markerId);\n\n        dom.removeCssClass(this.textarea, \"ace_composition\");\n        this.textarea.style.cssText = this.$composition.cssText;\n        var cursor = this.session.selection.cursor;\n        this.removeExtraToken(cursor.row, cursor.column);\n        this.$composition = null;\n        this.$cursorLayer.element.style.display = \"\";\n    }\n\n    /**\n     * @param {string} text\n     * @param {Point} [position]\n     */\n    setGhostText(text, position) {\n        var cursor = this.session.selection.cursor;\n        var insertPosition = position || { row: cursor.row, column: cursor.column };\n\n        this.removeGhostText();\n\n        var textChunks = this.$calculateWrappedTextChunks(text, insertPosition);\n        this.addToken(textChunks[0].text, \"ghost_text\", insertPosition.row, insertPosition.column);\n\n        this.$ghostText = {\n            text: text,\n            position: {\n                row: insertPosition.row,\n                column: insertPosition. column\n            }\n        };\n\n        var widgetDiv = dom.createElement(\"div\");\n        if (textChunks.length > 1) {\n            // If there are tokens to the right of the cursor, hide those.\n            var hiddenTokens = this.hideTokensAfterPosition(insertPosition.row, insertPosition.column);\n\n            var lastLineDiv;\n            textChunks.slice(1).forEach(el => {\n                var chunkDiv = dom.createElement(\"div\");\n                var chunkSpan = dom.createElement(\"span\");\n                chunkSpan.className = \"ace_ghost_text\";\n\n                // If the line is wider than the viewport, wrap the line\n                if (el.wrapped) chunkDiv.className = \"ghost_text_line_wrapped\";\n\n                // If a given line doesn't have text (e.g. it's a line of whitespace), set a space as the\n                // textcontent so that browsers render the empty line div.\n                if (el.text.length === 0) el.text = \" \";\n\n                chunkSpan.appendChild(dom.createTextNode(el.text));\n                chunkDiv.appendChild(chunkSpan);\n                widgetDiv.appendChild(chunkDiv);\n\n                // Overwrite lastLineDiv every iteration so at the end it points to\n                // the last added element.\n                lastLineDiv = chunkDiv;\n            });\n\n            // Add the hidden tokens to the last line of the ghost text.\n            hiddenTokens.forEach(token => {\n                var element = dom.createElement(\"span\");\n                if (!isTextToken(token.type)) element.className = \"ace_\" + token.type.replace(/\\./g, \" ace_\");\n                element.appendChild(dom.createTextNode(token.value));\n                lastLineDiv.appendChild(element);\n            });\n\n            this.$ghostTextWidget = {\n                el: widgetDiv,\n                row: insertPosition.row,\n                column: insertPosition.column,\n                className: \"ace_ghost_text_container\"\n            };\n            this.session.widgetManager.addLineWidget(this.$ghostTextWidget);\n\n            // Check wether the line widget fits in the part of the screen currently in view\n            var pixelPosition = this.$cursorLayer.getPixelPosition(insertPosition, true);\n            var el = this.container;\n            var height = el.getBoundingClientRect().height;\n            var ghostTextHeight = textChunks.length * this.lineHeight;\n            var fitsY = ghostTextHeight < (height - pixelPosition.top);\n\n            // If it fits, no action needed\n            if (fitsY) return;\n\n            // If it can fully fit in the screen, scroll down until it fits on the screen\n            // if it cannot fully fit, scroll so that the row with the cursor\n            // is at the top of the screen.\n            if (ghostTextHeight < height) {\n                this.scrollBy(0, (textChunks.length - 1) * this.lineHeight);\n            } else {\n                this.scrollToRow(insertPosition.row);\n            }\n        }\n\n    }\n\n    /**\n     * Calculates and organizes text into wrapped chunks. Initially splits the text by newline characters,\n     * then further processes each line based on display tokens and session settings for tab size and wrapping limits.\n     *\n     * @param {string} text\n     * @param {Point} position\n     * @return {{text: string, wrapped: boolean}[]}\n     */\n    $calculateWrappedTextChunks(text, position) {\n        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;\n        var limit = Math.floor(availableWidth / this.characterWidth) - 2;\n        limit = limit <= 0 ? 60 : limit; // this is a hack to prevent the editor from crashing when the window is too small\n\n        var textLines = text.split(/\\r?\\n/);\n        var textChunks = [];\n        for (var i = 0; i < textLines.length; i++) {\n            var displayTokens = this.session.$getDisplayTokens(textLines[i], position.column);\n            var wrapSplits = this.session.$computeWrapSplits(displayTokens, limit, this.session.$tabSize);\n\n            if (wrapSplits.length > 0) {\n                var start = 0;\n                wrapSplits.push(textLines[i].length);\n\n                for (var j = 0; j < wrapSplits.length; j++) {\n                    let textSlice = textLines[i].slice(start, wrapSplits[j]);\n                    textChunks.push({text: textSlice, wrapped: true});\n                    start = wrapSplits[j];\n                }\n            }\n            else {\n                textChunks.push({text: textLines[i], wrapped: false});\n            }\n        }\n        return textChunks;\n    }\n\n    removeGhostText() {\n        if (!this.$ghostText) return;\n\n        var position = this.$ghostText.position;\n        this.removeExtraToken(position.row, position.column);\n        if (this.$ghostTextWidget) {\n            this.session.widgetManager.removeLineWidget(this.$ghostTextWidget);\n            this.$ghostTextWidget = null;\n        }\n        this.$ghostText = null;\n    }\n\n    /**\n     * @param {string} text\n     * @param {string} type\n     * @param {number} row\n     * @param {number} [column]\n     */\n    addToken(text, type, row, column) {\n        var session = this.session;\n        session.bgTokenizer.lines[row] = null;\n        var newToken = {type: type, value: text};\n        var tokens = session.getTokens(row);\n        if (column == null || !tokens.length) {\n            tokens.push(newToken);\n        } else {\n            var l = 0;\n            for (var i =0; i < tokens.length; i++) {\n                var token = tokens[i];\n                l += token.value.length;\n                if (column <= l) {\n                    var diff = token.value.length - (l - column);\n                    var before = token.value.slice(0, diff);\n                    var after = token.value.slice(diff);\n\n                    tokens.splice(i, 1, {type: token.type, value: before},  newToken,  {type: token.type, value: after});\n                    break;\n                }\n            }\n        }\n        this.updateLines(row, row);\n    }\n\n    // Hide all non-ghost-text tokens to the right of a given position.\n    hideTokensAfterPosition(row, column) {\n        var tokens = this.session.getTokens(row);\n        var l = 0;\n        var hasPassedCursor = false;\n        var hiddenTokens = [];\n        // Loop over all tokens and track at what position in the line they end.\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            l += token.value.length;\n\n            if (token.type === \"ghost_text\") continue;\n\n            // If we've already passed the current cursor position, mark all of them as hidden.\n            if (hasPassedCursor) {\n                hiddenTokens.push({type: token.type, value: token.value});\n                token.type = \"hidden_token\";\n                continue;\n            }\n            // We call this method after we call addToken, so we are guaranteed a new token starts at the cursor position.\n            // Once we reached that point in the loop, flip the flag.\n            if (l === column) {\n                hasPassedCursor = true;\n            }\n        }\n        this.updateLines(row, row);\n        return hiddenTokens;\n    }\n\n    removeExtraToken(row, column) {\n        this.session.bgTokenizer.lines[row] = null;\n        this.updateLines(row, row);\n    }\n\n    /**\n     * [Sets a new theme for the editor. `theme` should exist, and be a directory path, like `ace/theme/textmate`.]{: #VirtualRenderer.setTheme}\n     * @param {String | Theme} [theme] The path to a theme\n     * @param {() => void} [cb] optional callback\n\n     **/\n    setTheme(theme, cb) {\n        var _self = this;\n        /**@type {any}*/\n        this.$themeId = theme;\n        _self._dispatchEvent('themeChange',{theme:theme});\n\n        if (!theme || typeof theme == \"string\") {\n            // @ts-ignore\n            var moduleName = theme || this.$options.theme.initialValue;\n            config.loadModule([\"theme\", moduleName], afterLoad);\n        } else {\n            afterLoad(theme);\n        }\n\n        /**\n         * @param {Theme} module\n         */\n        function afterLoad(module) {\n            if (_self.$themeId != theme)\n                return cb && cb();\n            if (!module || !module.cssClass)\n                throw new Error(\"couldn't load module \" + theme + \" or it didn't call define\");\n            if (module.$id)\n                _self.$themeId = module.$id;\n            dom.importCssString(\n                module.cssText,\n                module.cssClass,\n                _self.container\n            );\n            if (_self.theme)\n                dom.removeCssClass(_self.container, _self.theme.cssClass);\n            /**@type {any}*/\n            var padding = \"padding\" in module ? module.padding\n                : \"padding\" in (_self.theme || {}) ? 4 : _self.$padding;\n            if (_self.$padding && padding != _self.$padding)\n                _self.setPadding(padding);\n\n            if (_self.$gutterLayer) {\n                var showGutterCursor = module[\"$showGutterCursorMarker\"];\n                if (showGutterCursor && !_self.$gutterLayer.$showCursorMarker) {\n                    _self.$gutterLayer.$showCursorMarker = \"theme\";\n                } else if (!showGutterCursor && _self.$gutterLayer.$showCursorMarker == \"theme\") {\n                    _self.$gutterLayer.$showCursorMarker = null;\n                }\n            }\n\n            // this is kept only for backwards compatibility\n            _self.$theme = module.cssClass;\n\n            _self.theme = module;\n            dom.addCssClass(_self.container, module.cssClass);\n            dom.setCssClass(_self.container, \"ace_dark\", module.isDark);\n\n            // force re-measure of the gutter width\n            if (_self.$size) {\n                _self.$size.width = 0;\n                _self.$updateSizeAsync();\n            }\n\n            _self._dispatchEvent('themeLoaded', {theme:module});\n            cb && cb();\n\n            // workaround for safari not redrawing the editor\n            // https://github.com/ajaxorg/ace/issues/5569\n            if (useragent.isSafari && _self.scroller) {\n                _self.scroller.style.background = \"red\";\n                _self.scroller.style.background = \"\";\n            }\n        }\n    }\n\n    /**\n     * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme}\n     * @returns {String}\n     **/\n    getTheme() {\n        return this.$themeId;\n    }\n\n    // Methods allows to add / remove CSS classnames to the editor element.\n    // This feature can be used by plug-ins to provide a visual indication of\n    // a certain mode that editor is in.\n\n    /**\n     * [Adds a new class, `style`, to the editor.]{: #VirtualRenderer.setStyle}\n     * @param {String} style A class name\n     * @param {boolean}[include]\n     **/\n    setStyle(style, include) {\n        dom.setCssClass(this.container, style, include !== false);\n    }\n\n    /**\n     * [Removes the class `style` from the editor.]{: #VirtualRenderer.unsetStyle}\n     * @param {String} style A class name\n     *\n     **/\n    unsetStyle(style) {\n        dom.removeCssClass(this.container, style);\n    }\n\n    /**\n     * @param {string} style\n     */\n    setCursorStyle(style) {\n        dom.setStyle(this.scroller.style, \"cursor\", style);\n    }\n\n    /**\n     * @param {String} cursorStyle A css cursor style\n     **/\n    setMouseCursor(cursorStyle) {\n        dom.setStyle(this.scroller.style, \"cursor\", cursorStyle);\n    }\n\n    attachToShadowRoot() {\n        dom.importCssString(editorCss, \"ace_editor.css\", this.container);\n    }\n\n    /**\n     * Destroys the text and cursor layers for this renderer.\n\n     **/\n    destroy() {\n        this.freeze();\n        this.$fontMetrics.destroy();\n        this.$cursorLayer.destroy();\n        this.removeAllListeners();\n        this.container.textContent = \"\";\n        this.setOption(\"useResizeObserver\", false);\n    }\n\n    /**\n     *\n     * @param {boolean} [val]\n     */\n    $updateCustomScrollbar(val) {\n        var _self = this;\n        this.$horizScroll = this.$vScroll = null;\n        this.scrollBarV.element.remove();\n        this.scrollBarH.element.remove();\n        if (val === true) {\n            /**@type {import(\"../ace-internal\").Ace.VScrollbar}*/\n            this.scrollBarV = new VScrollBarCustom(this.container, this);\n            /**@type {import(\"../ace-internal\").Ace.HScrollbar}*/\n            this.scrollBarH = new HScrollBarCustom(this.container, this);\n            this.scrollBarV.setHeight(this.$size.scrollerHeight);\n            this.scrollBarH.setWidth(this.$size.scrollerWidth);\n\n            this.scrollBarV.addEventListener(\"scroll\", function (e) {\n                if (!_self.$scrollAnimation) _self.session.setScrollTop(e.data - _self.scrollMargin.top);\n            });\n            this.scrollBarH.addEventListener(\"scroll\", function (e) {\n                if (!_self.$scrollAnimation) _self.session.setScrollLeft(e.data - _self.scrollMargin.left);\n            });\n            if (!this.$scrollDecorator) {\n                this.$scrollDecorator = new Decorator(this.scrollBarV, this);\n                this.$scrollDecorator.$updateDecorators();\n            } else {\n                this.$scrollDecorator.setScrollBarV(this.scrollBarV);\n                this.$scrollDecorator.$updateDecorators();\n            }\n        }\n        else {\n            this.scrollBarV = new VScrollBar(this.container, this);\n            this.scrollBarH = new HScrollBar(this.container, this);\n            this.scrollBarV.addEventListener(\"scroll\", function (e) {\n                if (!_self.$scrollAnimation) _self.session.setScrollTop(e.data - _self.scrollMargin.top);\n            });\n            this.scrollBarH.addEventListener(\"scroll\", function (e) {\n                if (!_self.$scrollAnimation) _self.session.setScrollLeft(e.data - _self.scrollMargin.left);\n            });\n        }\n    }\n\n    /**\n\n     */\n    $addResizeObserver() {\n        if (!window.ResizeObserver || this.$resizeObserver) return;\n        var self = this;\n        this.$resizeTimer = lang.delayedCall(function() {\n            if (!self.destroyed)  self.onResize();\n        }, 50);\n        this.$resizeObserver = new window.ResizeObserver(function(e) {\n            var w = e[0].contentRect.width;\n            var h = e[0].contentRect.height;\n            if (\n                Math.abs(self.$size.width - w) > 1\n                || Math.abs(self.$size.height - h) > 1\n            ) {\n                self.$resizeTimer.delay();\n            } else {\n                self.$resizeTimer.cancel();\n            }\n        });\n        this.$resizeObserver.observe(this.container);\n    }\n\n}\n\nVirtualRenderer.prototype.CHANGE_CURSOR = 1;\nVirtualRenderer.prototype.CHANGE_MARKER = 2;\nVirtualRenderer.prototype.CHANGE_GUTTER = 4;\nVirtualRenderer.prototype.CHANGE_SCROLL = 8;\nVirtualRenderer.prototype.CHANGE_LINES = 16;\nVirtualRenderer.prototype.CHANGE_TEXT = 32;\nVirtualRenderer.prototype.CHANGE_SIZE = 64;\nVirtualRenderer.prototype.CHANGE_MARKER_BACK = 128;\nVirtualRenderer.prototype.CHANGE_MARKER_FRONT = 256;\nVirtualRenderer.prototype.CHANGE_FULL = 512;\nVirtualRenderer.prototype.CHANGE_H_SCROLL = 1024;\nVirtualRenderer.prototype.$changes = 0;\nVirtualRenderer.prototype.$padding = null;\nVirtualRenderer.prototype.$frozen = false;\nVirtualRenderer.prototype.STEPS = 8;\n\noop.implement(VirtualRenderer.prototype, EventEmitter);\n\nconfig.defineOptions(VirtualRenderer.prototype, \"renderer\", {\n    useResizeObserver: {\n        /**\n         * @param value\n         * @this{VirtualRenderer}\n         */\n        set: function(value) {\n            if (!value && this.$resizeObserver) {\n                this.$resizeObserver.disconnect();\n                this.$resizeTimer.cancel();\n                this.$resizeTimer = this.$resizeObserver = null;\n            } else if (value && !this.$resizeObserver) {\n                this.$addResizeObserver();\n            }\n        }\n    },\n    animatedScroll: {initialValue: false},\n    showInvisibles: {\n        set: function(value) {\n            if (this.$textLayer.setShowInvisibles(value))\n                this.$loop.schedule(this.CHANGE_TEXT);\n        },\n        initialValue: false\n    },\n    showPrintMargin: {\n        set: function() { this.$updatePrintMargin(); },\n        initialValue: true\n    },\n    printMarginColumn: {\n        set: function() { this.$updatePrintMargin(); },\n        initialValue: 80\n    },\n    printMargin: {\n        /**\n         * @param val\n         * @this{VirtualRenderer}\n         */\n        set: function(val) {\n            if (typeof val == \"number\")\n                this.$printMarginColumn = val;\n            this.$showPrintMargin = !!val;\n            this.$updatePrintMargin();\n        },\n        get: function() {\n            return this.$showPrintMargin && this.$printMarginColumn;\n        }\n    },\n    showGutter: {\n        set: function(show){\n            this.$gutter.style.display = show ? \"block\" : \"none\";\n            this.$loop.schedule(this.CHANGE_FULL);\n            this.onGutterResize();\n        },\n        initialValue: true\n    },\n    useSvgGutterIcons: {\n        set: function(value){\n            this.$gutterLayer.$useSvgGutterIcons = value;\n        },\n        initialValue: false\n    },\n    showFoldedAnnotations: {\n        set: function(value){\n            this.$gutterLayer.$showFoldedAnnotations = value;\n        },\n        initialValue: false\n    },\n    fadeFoldWidgets: {\n        set: function(show) {\n            dom.setCssClass(this.$gutter, \"ace_fade-fold-widgets\", show);\n        },\n        initialValue: false\n    },\n    showFoldWidgets: {\n        set: function(show) {\n            this.$gutterLayer.setShowFoldWidgets(show);\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        },\n        initialValue: true\n    },\n    displayIndentGuides: {\n        set: function(show) {\n            if (this.$textLayer.setDisplayIndentGuides(show))\n                this.$loop.schedule(this.CHANGE_TEXT);\n        },\n        initialValue: true\n    },\n    highlightIndentGuides: {\n        set: function (show) {\n            if (this.$textLayer.setHighlightIndentGuides(show) == true) {\n                this.$textLayer.$highlightIndentGuide();\n            }\n            else {\n                this.$textLayer.$clearActiveIndentGuide(this.$textLayer.$lines.cells);\n            }\n        },\n        initialValue: true\n    },\n    highlightGutterLine: {\n        set: function(shouldHighlight) {\n            this.$gutterLayer.setHighlightGutterLine(shouldHighlight);\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        },\n        initialValue: true\n    },\n    hScrollBarAlwaysVisible: {\n        set: function(val) {\n            if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)\n                this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: false\n    },\n    vScrollBarAlwaysVisible: {\n        set: function(val) {\n            if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)\n                this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: false\n    },\n    fontSize: {\n        set: function(size) {\n            if (typeof size == \"number\")\n                size = size + \"px\";\n            this.container.style.fontSize = size;\n            this.updateFontSize();\n        },\n        initialValue: 12\n    },\n    fontFamily: {\n        set: function(name) {\n            this.container.style.fontFamily = name;\n            this.updateFontSize();\n        }\n    },\n    maxLines: {\n        set: function(val) {\n            this.updateFull();\n        }\n    },\n    minLines: {\n        /**\n         * @param val\n         * @this{VirtualRenderer}\n         */\n        set: function(val) {\n            if (!(this.$minLines < 0x1ffffffffffff))\n                this.$minLines = 0;\n            this.updateFull();\n        }\n    },\n    maxPixelHeight: {\n        set: function(val) {\n            this.updateFull();\n        },\n        initialValue: 0\n    },\n    scrollPastEnd: {\n        /**\n         * @param val\n         * @this{VirtualRenderer}\n         */\n        set: function(val) {\n            val = +val || 0;\n            if (this.$scrollPastEnd == val)\n                return;\n            this.$scrollPastEnd = val;\n            this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: 0,\n        handlesSet: true\n    },\n    fixedWidthGutter: {\n        set: function(val) {\n            this.$gutterLayer.$fixedWidth = !!val;\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        }\n    },\n    customScrollbar: {\n        set: function(val) {\n            this.$updateCustomScrollbar(val);\n        },\n        initialValue: false\n    },\n    theme: {\n        set: function(val) { this.setTheme(val); },\n        get: function() { return this.$themeId || this.theme; },\n        initialValue: \"./theme/textmate\",\n        handlesSet: true\n    },\n    hasCssTransforms: {\n    },\n    useTextareaForIME: {\n        initialValue: !useragent.isMobile && !useragent.isIE\n    }\n});\n\nexports.VirtualRenderer = VirtualRenderer;\n"
  },
  {
    "path": "src/virtual_renderer_test.js",
    "content": "if (typeof process !== \"undefined\") {\n    require(\"./test/mockdom\");\n}\n\n\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar VirtualRenderer = require(\"./virtual_renderer\").VirtualRenderer;\nvar vim = require(\"./keyboard/vim\");\nvar assert = require(\"./test/assertions\");\nvar lang = require(\"./lib/lang\");\n\nfunction setScreenPosition(node, rect) {\n    node.style.left = rect[0] + \"px\";\n    node.style.top = rect[1] + \"px\";\n    node.style.width = rect[2] + \"px\";\n    node.style.height = rect[3] + \"px\";\n}\n\nvar editor = null;\nmodule.exports = {\n    setUp: function() {\n        require(\"./config\").setLoader(function(moduleName, cb) {\n            if (moduleName == \"ace/ext/error_marker\")\n                return cb(null, require(\"./ext/error_marker\"));\n            if (moduleName == \"ace/mode/javascript\")\n                return cb(null, require(\"./mode/javascript\"));\n            throw new Error(\"module not configured \" + moduleName);\n        });\n        \n        if (editor)\n            editor.destroy();\n        var el = document.createElement(\"div\");\n\n        el.style.left = \"20px\";\n        el.style.top = \"30px\";\n        el.style.width = \"300px\";\n        el.style.height = \"100px\";\n        document.body.appendChild(el);\n        var renderer = new VirtualRenderer(el);\n        editor = new Editor(renderer);\n        editor.on(\"destroy\", function() {\n            el.remove();\n        });\n    },\n    tearDown: function() {\n        editor && editor.destroy();\n        editor = null;\n    },\n    \"test: screen2text the column should be rounded to the next character edge\" : function() {\n        var renderer = editor.renderer;\n\n        renderer.setPadding(0);\n        renderer.setSession(new EditSession(\"1234\"));\n\n        var r = renderer.scroller.getBoundingClientRect();\n        function testPixelToText(x, y, row, column) {\n            assert.position(renderer.screenToTextCoordinates(x+r.left, y+r.top), row, column);\n        }\n\n        renderer.characterWidth = 10;\n        renderer.lineHeight = 15;\n\n        testPixelToText(4, 0, 0, 0);\n        testPixelToText(5, 0, 0, 1);\n        testPixelToText(9, 0, 0, 1);\n        testPixelToText(10, 0, 0, 1);\n        testPixelToText(14, 0, 0, 1);\n        testPixelToText(15, 0, 0, 2);\n    },\n    \"test: handle css transforms\" : function() {\n        var renderer = editor.renderer;\n        var fontMetrics = renderer.$fontMetrics;\n        setScreenPosition(editor.container, [20, 30, 300, 100]);\n        var measureNode = fontMetrics.$measureNode;\n        setScreenPosition(measureNode, [0, 0, 10 * measureNode.textContent.length, 15]);\n        setScreenPosition(fontMetrics.$main, [0, 0, 10 * measureNode.textContent.length, 15]);\n        \n        fontMetrics.$characterSize.width = 10;\n        renderer.setPadding(0);\n        renderer.onResize(true);\n        \n        assert.equal(fontMetrics.getCharacterWidth(), 1);\n        \n        renderer.characterWidth = 10;\n        renderer.lineHeight = 15;\n        \n        renderer.gutterWidth = 40;\n        editor.setOption(\"hasCssTransforms\", true);\n        editor.container.style.transform = \"matrix3d(0.7, 0, 0, -0.00066, 0, 0.82, 0, -0.001, 0, 0, 1, 0, -100, -20, 10, 1)\";\n        editor.container.style.zoom = 1.5;\n        var pos = renderer.pixelToScreenCoordinates(100, 200);\n        \n        var els = fontMetrics.els;\n        var rects = [\n            [0, 0],\n            [-37.60084843635559, 161.62494659423828],\n            [114.50254130363464, -6.890693664550781],\n            [98.85665202140808, 179.16063690185547]\n        ];\n        rects.forEach(function(rect, i) {\n            els[i].getBoundingClientRect = function() { \n                return { left: rect[0], top: rect[1] };\n            };\n        });\n        \n        var r0 = els[0].getBoundingClientRect();\n        pos = renderer.pixelToScreenCoordinates(r0.left + 100, r0.top + 200);\n        assert.position(pos, 10, 11);\n        \n        var pos1 = fontMetrics.transformCoordinates(null, [0, 200]);\n        assert.ok(pos1[0] - rects[2][0] < 10e-6);\n        assert.ok(pos1[1] - rects[2][1] < 10e-6);\n        editor.renderer.$loop._flush();\n    },\n    \n    \"test scrollmargin + autosize\": async function(done) {\n        editor.setOptions({\n            maxLines: 100,\n            wrap: true\n        });        \n        editor.renderer.setScrollMargin(10, 10);\n        editor.setValue(\"\\n\\n\");\n        editor.setValue(\"\\n\\n\\n\\n\");\n        await editor.renderer.once(\"afterRender\");\n        done();\n    },\n\n    \"test scrollbars after value change\": function() {\n        editor.container.style.height = \"0px\";\n        editor.setOptions({\n            maxLines: 8,\n        });\n        var renderCount = 0;\n        editor.renderer.on(\"afterRender\", function(e) {\n            renderCount++;\n        });\n        // horizontal scroll\n        editor.setValue(\"\\n\");\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 1\n        assert.notOk(editor.renderer.scrollBarH.isVisible);\n        assert.notOk(editor.renderer.scrollBar.isVisible);\n        editor.setValue(\"\\n\\n\\n\\n\" + \"_\".repeat(30));\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 2\n        assert.notOk(editor.renderer.scrollBarH.isVisible);\n        assert.notOk(editor.renderer.scrollBar.isVisible);\n        editor.setValue(\"\\n\\n\\n\\n\" + \"_\".repeat(100));\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 3\n        assert.ok(editor.renderer.scrollBarH.isVisible);\n        assert.notOk(editor.renderer.scrollBar.isVisible);\n        // vertical scroll\n        editor.setValue(\"\\n\".repeat(9));\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 4\n        assert.notOk(editor.renderer.scrollBarH.isVisible);\n        assert.ok(editor.renderer.scrollBar.isVisible);\n        // vertical and horizontal scroll\n        editor.setValue(\"\\n\");\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 5\n        editor.setValue(\"\\n\".repeat(9) + \"_\".repeat(100));\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 6\n        assert.notOk(editor.renderer.scrollBarH.isVisible);\n        assert.ok(editor.renderer.scrollBar.isVisible);\n        editor.resize(true);\n        editor.renderer.$loop._flush(); // 7\n        // autosize changes vscroll value in which case updates longestLine\n        // this is why it renders an extra time\n        assert.ok(editor.renderer.scrollBarH.isVisible);\n        assert.ok(editor.renderer.scrollBar.isVisible);\n        assert.equal(renderCount, 7);\n    },\n\n    \"test autosize from 0 height\": function() {\n        editor.container.style.height = \"0px\";\n        editor.textInput.getElement().style.position = \"fixed\";\n        editor.container.style.lineHeight = 1;\n        editor.setOptions({\n            fontSize: 9\n        });\n\n        editor.resize(true);\n        editor.setOptions({\n            maxLines: 100\n        });\n\n        editor.resize(true);\n\n        editor.resize(true);\n        editor.renderer.$size = {};\n\n        var renderCount = 0;\n        editor.renderer.on(\"afterRender\", function(e) {\n            renderCount++;\n        });\n        editor.setValue(\"1\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.style.height, \"9px\");\n\n        editor.setValue(\"\\n\\n\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.container.style.height, \"27px\");\n        \n        editor.container.remove();\n        editor.setValue(\"\\n\\n\\n\");\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n        editor.resize(true);\n        assert.equal(renderCount, 2);\n    },\n    \n    \"test invalid valus of minLines\": function() {\n        editor.setOptions({\n            maxLines: Infinity,\n            minLines: Infinity\n        });\n        editor.renderer.$loop._flush();\n        editor.setOptions({\n            maxLines: NaN,\n            minLines: NaN\n        });\n        editor.renderer.$loop._flush();\n        editor.setOptions({\n            maxLines: Number.MAX_SAFE_INTEGER + 1,\n            minLines: Number.MAX_SAFE_INTEGER + 1\n        });\n        editor.renderer.$loop._flush();\n    },\n    \n    \"test line widgets\": function() {\n        editor.session.setValue(\"a\\nb|c\\nd\");\n        editor.session.setAnnotations([{row: 1, column: 2, type: \"error\"}]);\n        editor.execCommand(editor.commands.byName.goToNextError);\n        assert.position(editor.getCursorPosition(), 1, 2);\n        editor.renderer.$loop._flush();\n        assert.ok(editor.session.lineWidgets[1]);\n    },\n    \n    \"test wrapped text rendering\": function() {\n        editor.setValue(\"a\".repeat(452) + \"\\n\" + \"b\".repeat(100) + \"\\nxxxxxx\", -1);\n        editor.container.style.height = \"500px\";\n        editor.setOption(\"wrap\", 40);\n        editor.resize(true);\n        editor.renderer.$loop._flush();\n        \n        assert.equal(editor.renderer.$changedLines, null);\n        editor.session.remove(new Range(0, 10, 0, 350));\n        editor.session.insert({row: 1, column: 1}, \"l\".repeat(350));\n        editor.renderer.$loop._flush();\n        var lines = editor.renderer.$textLayer.element.children;\n        assert.notEqual(lines[0].style.height, lines[1].style.height);\n        assert.equal(lines[0].style.height, lines[1].style.top);\n    },\n    \n    \"test resize\": function() {\n        editor.setValue(\"Juhu kinners!\");\n        editor.resize(true);\n    },\n\n    \"test placeholder\": function() {\n        editor.setOption(\"placeholder\", \"hello\");\n        assert.equal(editor.renderer.content.textContent, \"hello\");\n\n        editor.setOption(\"placeholder\", \"new\");\n        assert.equal(editor.renderer.content.textContent, \"new\");\n\n        editor.setValue(\"test\");\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"test\");\n\n        editor.setOption(\"placeholder\", \"only visible for empty value\");\n        assert.equal(editor.renderer.content.textContent, \"test\");\n\n        editor.setValue(\"\");\n        editor.renderer.$loop._flush();\n        editor._signal(\"input\", {});\n        assert.equal(editor.renderer.content.textContent, \"only visible for empty value\");\n    },\n    \"test: highlight indent guide\": async function (done) {\n        editor.session.setValue(\n            \"function Test() {\\n\" + \"    function Inner() {\\n\" + \"        \\n\" + \"        \\n\" + \"    }\\n\" + \"}\");\n        editor.setOption(\"highlightIndentGuides\", false);\n        editor.setOption(\"wrap\", 10); // to make sure higlight works with wrapped lines\n        editor.session.selection.$setSelection(1, 22, 1, 22);\n        editor.resize(true);\n\n        function assertIndentGuides(activeIndentGuidesCount) {\n            var activeIndentGuides = editor.container.querySelectorAll(\".ace_indent-guide-active\");\n            assert.equal(activeIndentGuides.length, activeIndentGuidesCount);\n        }\n\n        assertIndentGuides( 0);\n\n        editor.setOption(\"highlightIndentGuides\", true);\n        assertIndentGuides( 2);\n\n        editor.session.selection.clearSelection();\n        editor.session.selection.$setSelection(1, 15, 1, 15);\n        editor.resize(true);\n        assertIndentGuides( 0);\n\n        editor.session.selection.clearSelection();\n        editor.session.selection.$setSelection(4, 5, 4, 5);\n\n        await lang.sleep(100);\n        assertIndentGuides(2);\n        done();\n    },\n    \"test annotation marks\": function() {\n        function findPointFillStyle(imageData, x, y) {\n            var data = imageData.slice(4 * y, 4 * (y + 1));\n            var a = Math.round(data[3] / 256 * 100);\n            if (a == 100) return \"rgb(\" + data.slice(0, 3).join(\",\") + \")\";\n            return \"rgba(\" + data.slice(0, 3).join(\",\") + \",\" + (a / 100) + \")\";\n        }\n\n        function assertCoordsColor(expected) {\n            var imageData = context.getImageData(0, 0, 1, 100).data;\n            for (var el of expected) {\n                assert.equal(findPointFillStyle(imageData, el.x, el.y), el.color);\n            }\n        }\n\n        var renderer = editor.renderer;\n        renderer.container.scrollHeight = 100;\n        renderer.layerConfig.maxHeight = 200;\n        renderer.layerConfig.lineHeight = 14;\n\n        editor.setOptions({\n            customScrollbar: true,\n            vScrollBarAlwaysVisible: true\n        });\n        editor.setValue(\"a\" + \"\\n\".repeat(100) + \"b\" + \"\\nxxxxxx\", -1);\n        editor.session.setAnnotations([\n            {\n                row: 1,\n                column: 2,\n                type: \"error\"\n            }, {\n                row: 4,\n                column: 1,\n                type: \"warning\"\n            }, {\n                row: 20,\n                column: 1,\n                type: \"info\"\n            }\n        ]);\n        renderer.$loop._flush();\n        var context = renderer.$scrollDecorator.canvas.getContext(\"2d\");\n        var scrollDecoratorColors = renderer.$scrollDecorator.colors.light;\n        var values = [\n            // reflects cursor position on canvas\n            {x: 0, y: 0, color: \"rgba(0,0,0,0.5)\"},\n            // reflects error annotation mark on canvas overlapped by cursor\n            {x: 0, y: 2, color: scrollDecoratorColors.error},\n            // default value\n            {x: 0, y: 3, color: \"rgba(0,0,0,0)\"},\n            // reflects warning annotation mark on canvas\n            {x: 0, y: 4, color: scrollDecoratorColors.warning},\n            {x: 0, y: 5, color: scrollDecoratorColors.warning},\n            {x: 0, y: 6, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 20, color: scrollDecoratorColors.info},\n            {x: 0, y: 21, color: scrollDecoratorColors.info}\n        ];\n        assertCoordsColor(values);\n        editor.moveCursorTo(5, 6);\n        renderer.$loop._flush();\n        values = [\n            {x: 0, y: 0, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 1, color: scrollDecoratorColors.error},\n            {x: 0, y: 2, color: scrollDecoratorColors.error},\n            {x: 0, y: 3, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 4, color: scrollDecoratorColors.warning},\n            {x: 6, y: 6, color: \"rgba(0,0,0,0.5)\"}\n        ];\n        assertCoordsColor(values);\n        renderer.session.addFold(\"...\", new Range(0, 0, 3, 2));\n        editor.moveCursorTo(10, 0);\n        renderer.$loop._flush();\n        values = [\n            {x: 0, y: 0, color: scrollDecoratorColors.error},\n            {x: 0, y: 1, color: scrollDecoratorColors.error},\n            {x: 0, y: 2, color: scrollDecoratorColors.warning},\n            {x: 0, y: 3, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 4, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 5, color: \"rgba(0,0,0,0)\"},\n            {x: 0, y: 6, color: \"rgba(0,0,0,0)\"}\n        ];\n        assertCoordsColor(values);\n    },\n    \"test ghost text\": function() {\n        editor.session.setValue(\"abcdef\");\n        editor.setGhostText(\"Ghost\");\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"Ghostabcdef\");\n\n        editor.setGhostText(\"Ghost\", {row: 0, column: 3});\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcGhostdef\");\n\n        editor.setGhostText(\"Ghost\", {row: 0, column: 6});\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdefGhost\");\n\n        editor.removeGhostText();\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdef\");\n    },\n\n    \"test multiline ghost text\": function() {\n        editor.session.setValue(\"abcdef\");\n        editor.renderer.$loop._flush();\n\n        editor.setGhostText(\"Ghost1\\nGhost2\\nGhost3\", {row: 0, column: 6});\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdefGhost1\");\n        \n        assert.equal(editor.session.lineWidgets[0].el.innerHTML, `<div><span class=\"ace_ghost_text\">Ghost2</span></div><div><span class=\"ace_ghost_text\">Ghost3</span><span></span></div>`);\n\n        editor.removeGhostText();\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdef\");\n        \n        assert.equal(editor.session.lineWidgets, null);\n    },\n    \"test long multiline ghost text\": function() {\n        editor.session.setValue(\"abcdef\");\n        editor.renderer.$loop._flush();\n\n        editor.setGhostText(\"This is a long test text that is longer than 30 characters\\n\\nGhost3\", \n            {row: 0, column: 6});\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdefThis is a long test text that is longer than \");\n\n        assert.equal(editor.session.lineWidgets[0].el.innerHTML, `<div class=\"ghost_text_line_wrapped\"><span class=\"ace_ghost_text\">30 characters</span></div><div><span class=\"ace_ghost_text\"> </span></div><div><span class=\"ace_ghost_text\">Ghost3</span><span></span></div>`);\n\n        editor.removeGhostText();\n\n        editor.renderer.$loop._flush();\n        assert.equal(editor.renderer.content.textContent, \"abcdef\");\n\n        assert.equal(editor.session.lineWidgets, null);\n    },\n    \"test: brackets highlighting\": async function (done) {\n        var renderer = editor.renderer;\n        editor.session.setValue(\n            \"function Test() {\\n\" + \"    function Inner(){\\n\" + \"        \\n\" + \"        \\n\" + \"    }\\n\" + \"}\");\n        editor.session.selection.$setSelection(1, 21, 1, 21);\n        renderer.$loop._flush();\n\n        await lang.sleep(60);\n        assert.ok(editor.session.$bracketHighlight);\n        assert.range(editor.session.$bracketHighlight.ranges[0], 1, 20, 1, 21);\n        assert.range(editor.session.$bracketHighlight.ranges[1], 4, 4, 4, 5);\n\n        editor.session.selection.$setSelection(1, 16, 1, 16);\n\n        await lang.sleep(60);\n        assert.ok(editor.session.$bracketHighlight == null);\n        editor.setKeyboardHandler(vim.handler);\n        editor.session.selection.$setSelection(1, 20, 1, 20);\n\n        await lang.sleep(60);\n        assert.ok(editor.session.$bracketHighlight);\n        assert.range(editor.session.$bracketHighlight.ranges[0], 1, 20, 1, 21);\n        assert.range(editor.session.$bracketHighlight.ranges[1], 4, 4, 4, 5);\n        done();\n    },\n    \"test: scroll cursor into view\": function() {\n        editor.renderer.$loop._flush();\n        \n        function X(n) {\n            return \"X\".repeat(n);\n        }\n        editor.session.setValue(`${X(10)}\\n${X(1000)}}`);\n\n        var initialContentLeft = editor.renderer.content.getBoundingClientRect().left;\n\n        // Scroll so far to the right that the first line is completely hidden\n        editor.session.selection.$setSelection(1, 1000, 1, 1000);\n        editor.renderer.scrollCursorIntoView();\n        editor.renderer.$loop._flush();\n\n        editor.session.selection.$setSelection(0, 10, 0, 10);\n        editor.renderer.scrollCursorIntoView();\n        editor.renderer.$loop._flush();\n\n        var contentLeft = editor.renderer.content.getBoundingClientRect().left;\n        var scrollDelta = initialContentLeft - contentLeft;\n\n        const leftBoundPixelPos = editor.renderer.$cursorLayer.getPixelPosition({row: 0, column: 8}).left;\n        const rightBoundPixelPos = editor.renderer.$cursorLayer.getPixelPosition({row: 0, column: 9}).left;\n        assert.ok(\n            scrollDelta >= leftBoundPixelPos && scrollDelta < rightBoundPixelPos,\n            \"Expected content to have been scrolled two characters beyond the cursor\"\n        );\n    },\n    \"test: set gutter class\": function(done) {\n        editor.session.setMode(\"ace/mode/javascript\", function() {\n            editor.session.setValue(\"x = {\\n  foo: 1\\n}\");\n            editor.execCommand(\"toggleFoldWidget\");\n            editor.renderer.$loop._flush();\n            assert.equal(editor.renderer.$loop.changes, 0);\n            var cell = editor.renderer.$gutterLayer.$lines.cells[0];\n            assert.equal(cell.element.childNodes[1].className, \"ace_fold-widget ace_start ace_closed\");\n            assert.equal(cell.element.className.trim(), \"ace_gutter-cell ace_gutter-active-line\");\n\n            editor.session.setBreakpoint(0, \"hello\");\n            assert.notEqual(editor.renderer.$loop.changes, 0);\n            editor.renderer.$loop._flush();\n\n            cell = editor.renderer.$gutterLayer.$lines.cells[0];\n            assert.equal(editor.renderer.$loop.changes, 0);\n            assert.equal(cell.element.className, \"ace_gutter-cell ace_gutter-active-line hello\");\n            done();\n        });\n    },\n    \"test: screenToTextCoordinates with line widget offset, issue #5874\": function() {\n        var renderer = editor.renderer;\n        editor.setValue(\"line0\\nline1\\nline2\\nline3\\nline4\");\n        renderer.setPadding(0);\n        renderer.characterWidth = 10;\n        renderer.lineHeight = renderer.layerConfig.lineHeight = 13;\n\n        var widgetEl = document.createElement(\"div\");\n        widgetEl.style.height = \"40px\";\n        editor.session.widgetManager.addLineWidget({\n            el: widgetEl,\n            row: 1,\n            pixelHeight: 40\n        });\n        renderer.$loop._flush();\n\n        var r = renderer.scroller.getBoundingClientRect();\n\n        // Line 2 starts at: line0(13) + line1(13) + widget(40) = 66px\n        // Clicking in top half of line 2 (y=69) should return row 2\n        var pos = renderer.screenToTextCoordinates(r.left + 5, r.top + 69);\n        assert.equal(pos.row, 2);\n\n        // Clicking bottom half of line 2 (y=75) should also return row 2\n        pos = renderer.screenToTextCoordinates(r.left + 5, r.top + 75);\n        assert.equal(pos.row, 2);\n    }\n\n    // change tab size after setDocument (for text layer)\n};\n\n\nrequire(\"./test/run\")(module);"
  },
  {
    "path": "src/worker/worker_client.js",
    "content": "// not implemented\nvar WorkerClient;\nWorkerClient = function() {\n    this.attachToDocument = function() {};\n    this.on = function() {};\n    this.terminate = function() {};\n};\n\nexports.WorkerClient = WorkerClient;\n"
  },
  {
    "path": "static.js",
    "content": "#!/usr/bin/env node\n\nvar http = require(\"http\")\n  , path = require(\"path\")\n  , url = require(\"url\")\n  , fs = require(\"fs\")\n  , port = process.env.PORT || 8888\n  , ip = process.env.IP || \"0.0.0.0\";\n\nfunction lookupMime(filename) {\n    var ext = /[^\\/\\\\.]*$/.exec(filename)[0];\n    return {\n        js: \"application/javascript\",\n        ico: \"image/x-icon\",\n        css: \"text/css\",\n        svg: \"image/svg+xml\",\n        png: \"image/png\",\n        jpg: \"image/jpg\",\n        html: \"text/html\",\n        jpeg: \"image/jpeg\",\n        wasm: \"application/wasm\",\n        json: \"application/json\",\n        xml: \"application/xml\",\n        ttf: \"font/ttf\",\n    }[ext];\n}\n  \n// compatibility with node 0.6\nif (!fs.exists)\n    fs.exists = path.exists;\n\nvar allowSave = process.argv.indexOf(\"--allow-save\") != -1;\nif (allowSave)\n    console.warn(\"writing files from browser is enabled\");\n\nhttp.createServer(function(req, res) {\n    var uri = unescape(url.parse(req.url).pathname);\n    console.log(\"[\" + req.method + \"]\", uri);\n    var root = process.cwd() + path.sep;\n    var filename = path.join(root, uri);\n\n    if (filename.slice(0, root.length) !== root) {\n        return error(res, 400, \"400 Bad request: Directory traversal is not allowed.\");\n    }\n\n    if (req.method == \"OPTIONS\") {\n        writeHead(res, 200);\n        return res.end();\n    }\n    \n    if (req.method == \"PUT\") {\n        if (!allowSave)\n            return error(res, 404, \"Saving not allowed (pass --allow-save to enable)\");\n        return save(req, res, filename);\n    }\n\n    fs.stat(filename, function(err, stat) {\n        if (err)\n            return error(res, 404, \"404 Not Found\\n\" + filename);\n\n        if (stat.isDirectory())\n            return serveDirectory(filename, uri, req, res);\n\n        var contentType = lookupMime(filename);\n        writeHead(res, 200, contentType);\n        res.setHeader(\"Content-Length\", stat.size);\n        var stream = fs.createReadStream(filename, {});\n        req.on(\"close\", stream.destroy.bind(stream));\n        stream.on(\"error\", function(err){\n            if (res._header)\n                return req.destroy();\n            writeHead(res, 500, \"text/plain\");\n            res.end();\n        });\n        stream.pipe(res);\n    });\n}).listen(port, ip);\n\nfunction writeHead(res, code, contentType) {\n    res.setHeader(\"Access-Control-Allow-Origin\", \"file://\");\n    res.setHeader(\"Access-Control-Allow-Methods\", \"PUT, GET, OPTIONS, HEAD\");\n    res.setHeader(\"Content-Type\", contentType || \"text/plain\");\n    res.statusCode = code;\n}\n\nfunction escapeHTML(str) {\n    return (\"\" + str).replace(/&/g, \"&#38;\").replace(/\"/g, \"&#34;\").replace(/'/g, \"&#39;\").replace(/</g, \"&#60;\");\n}\nfunction serveDirectory(filename, uri, req, res) {\n    var files = fs.readdirSync(filename);\n    writeHead(res, 200, \"text/html\");\n    \n    files.push(\"..\");\n    var html = files.map(function(name) {\n        try {\n            var stat = fs.statSync(filename + \"/\" + name);\n        } catch(e) {}\n        var index = name == \".\" ? 2 : name == \"..\" ? 3 : stat.isDirectory() ? 1 : 0;\n        return { name: name, index: index, size: stat.size };\n    }).filter(Boolean).sort(function(a, b) {\n        if (a.index == b.index)\n            return a.name.localeCompare(b.name);\n        return b.index - a.index;\n    }).map(function(stat) {\n        var name = stat.name;\n        if (stat.index) name += \"/\";\n        var size = \"\";\n        if (!stat.size) size = \"\";\n        else if (stat.size < 1024) size = stat.size + \"b\";\n        else if (stat.size < 1024 * 1024) size = (stat.size / 1024).toFixed(2) + \"kb\";\n        else size = (stat.size / 1024 / 1024).toFixed(2) + \"mb\";\n        return \"<tr>\"\n            + \"<td>&nbsp;&nbsp;\" + size + \"&nbsp;&nbsp;</td>\"\n            + \"<td><a href='\" + escapeHTML(name) + \"'>\" + escapeHTML(name) + \"</a></td>\"\n        + \"</tr>\";\n    }).join(\"\");\n    html = \"<table>\" + html + \"</table>\";\n\n    var baseUri = uri.replace(/\\/?$/, \"/\");\n    html = \"<base href='\"+ escapeHTML(baseUri) + \"'>\" \n        + \"<meta charset='utf-8'>\" + html;\n    res._hasBody && res.write(html);\n    res.end();\n}\n\nfunction error(res, status, message, error) {\n    console.error(error || message);\n    writeHead(res, status, \"text/plain\");\n    res.write(message);\n    res.end();\n}\n\nfunction save(req, res, filePath) {\n    var data = \"\";\n    req.on(\"data\", function(chunk) {\n        data += chunk;\n    });\n    req.on(\"error\", function() {\n        error(res, 404, \"Could't save file\");\n    });\n    req.on(\"end\", function() {\n        try {\n            fs.writeFileSync(filePath, data);\n        }\n        catch (e) {\n            return error(res, 404, \"Could't save file\", e);\n        }\n        writeHead(res, 200);\n        res.end(\"OK\");\n        console.log(\"saved \", filePath);\n    });\n}\n\nfunction getLocalIps() {\n    var os = require(\"os\");\n\n    var interfaces = os.networkInterfaces ? os.networkInterfaces() : {};\n    var addresses = [];\n    for (var k in interfaces) {\n        for (var k2 in interfaces[k]) {\n            var address = interfaces[k][k2];\n            if (address.family === \"IPv4\" && !address.internal) {\n                addresses.push(address.address);\n            }\n        }\n    }\n    return addresses;\n}\n\nconsole.log(\"http://\" + (ip == \"0.0.0.0\" ? getLocalIps()[0] : ip) + \":\" + port);\n\n"
  },
  {
    "path": "tool/Readme.md",
    "content": "Helper Scripts for Ace\n======================\n\nTo use this you need to install node.js. and run `npm install` in this directory.\n\n\n# add_mode.js\n\n  Run \n```\nnode add_mode.js ModeName \"extension1|extension2|^FullName\"\n```\n  to create all the files needed for a new mode named `ModeName` \n  this adds stubs for:\n    `ace/mode/mode_name.js`\n    `ace/mode/mode_name_hightlight_rules.js`\n    `ace/snippets/mode_name.js`\n    `ace/demo/kitchen_sink/docs/mode_name.extension1`\n  and adds entry for the new mode to `ace/ext/modelist.js`\n \n \n# tmlanguage.js\n\n```\nnode tmlanguage.js ./templates/dummy.JSON-tmLanguage\n```\n\n# update_deps.js\nTo update `jshint` to new version:\n1. Clone last version from https://github.com/jshint/jshint\n2. Replace all `lodash` with `underscore` in requires in `jshint/src/*.js`\n3. Add `_.slice = require(\"lodash.slice\");` to `src/scope-manager.js` after `var _ = ...`\n4. Add `_.clone = require(\"lodash.clone\");` to `src/jshint.js` after `var _ = ...`\n5. Add ```  \n   \"underscore\": latest\n   \"lodash.clone\": \"^4.5.0\",\n   \"lodash.slice\": \"^4.2.0\"\n   ``` to `package.json`, remove `lodash` and run `npm i`\n6. Change in `ace/tool/update_deps.js` jshint path `deps.jshint.browserify.path` with your path to changed jshint\n7. Run `node update_deps.js jshint`"
  },
  {
    "path": "tool/ace_declaration_generator.js",
    "content": "const ts = require('typescript');\nconst fs = require(\"fs\");\nconst path = require(\"path\");\n\nconst SEPARATE_MODULES = [\"ext\", \"theme\", \"snippets\", \"lib\"]; // adjust this list for more granularity\n\nconst AUTO_GENERATED_HEADER = \"/* This file is generated using `npm run update-types` */\\n\\n\";\n\nconst defaultFormatCodeSettings = {\n    baseIndentSize: 0,\n    indentSize: 4,\n    tabSize: 4,\n    indentStyle: ts.IndentStyle.Smart,\n    newLineCharacter: \"\\n\",\n    convertTabsToSpaces: true,\n    insertSpaceAfterCommaDelimiter: true,\n    insertSpaceAfterSemicolonInForStatements: true,\n    insertSpaceBeforeAndAfterBinaryOperators: true,\n    insertSpaceAfterConstructor: false,\n    insertSpaceAfterKeywordsInControlFlowStatements: true,\n    insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,\n    insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,\n    insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,\n    insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,\n    insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,\n    insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,\n    insertSpaceAfterTypeAssertion: false,\n    insertSpaceBeforeFunctionParenthesis: false,\n    placeOpenBraceOnNewLineForFunctions: false,\n    placeOpenBraceOnNewLineForControlBlocks: false,\n    insertSpaceBeforeTypeAnnotation: false\n};\n\n/**\n * @param {string} directoryPath\n */\nfunction getParsedConfigFromDirectory(directoryPath) {\n    const configPath = ts.findConfigFile(directoryPath, ts.sys.fileExists, 'tsconfig.json');\n    if (!configPath) throw new Error(\"Could not find tsconfig.json\");\n\n    const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n    const parseConfigHost = {\n        fileExists: ts.sys.fileExists,\n        readFile: ts.sys.readFile,\n        readDirectory: ts.sys.readDirectory,\n        useCaseSensitiveFileNames: true\n    };\n    configFile.config.compilerOptions.noEmit = false;\n    configFile.config.compilerOptions.emitDeclarationOnly = true;\n    configFile.config.compilerOptions.outFile = \"./types/index.d.ts\";\n\n    return ts.parseJsonConfigFileContent(configFile.config, parseConfigHost, directoryPath);\n}\n\n/**\n * @return {string}\n */\nfunction generateInitialDeclaration(excludeDir) {\n    const baseDirectory = path.resolve(__dirname, '..');\n    const parsedConfig = getParsedConfigFromDirectory(baseDirectory);\n    const defaultCompilerHost = ts.createCompilerHost({});\n    let fileContent;\n\n    const customCompilerHost = {\n        ...defaultCompilerHost,\n        writeFile: function (fileName, content) {\n            fileContent = content;\n            return;\n        },\n        getSourceFile: function (fileName, languageVersion, onError, shouldCreateNewSourceFile) {\n            if (fileName.includes(excludeDir)) {\n                return undefined;\n            }\n            return defaultCompilerHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);\n        }\n    };\n\n    const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options, customCompilerHost);\n    program.emit();\n    return fileContent;\n}\n\n/**\n * Creates a custom TypeScript compiler host that uses the provided source file content instead of reading from the file system.\n * @param {string} fileName - The name of the source file.\n * @param {string} content - The content of the source file.\n * @returns {ts.CompilerHost} - A custom compiler host that uses the provided source file content.\n */\nfunction createCustomCompilerHost(fileName, content) {\n    const newSourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);\n\n    const defaultCompilerHost = ts.createCompilerHost({});\n    return {\n        ...defaultCompilerHost,\n        getSourceFile: (name, languageVersion) => {\n            if (name === fileName) {\n                return newSourceFile;\n            }\n            return defaultCompilerHost.getSourceFile(name, languageVersion);\n        },\n        fileExists: (name) => {\n            if (name === fileName) {\n                return true;\n            }\n            return defaultCompilerHost.fileExists(name);\n        },\n        readFile: (name) => {\n            if (name === fileName) {\n                return content;\n            }\n            return defaultCompilerHost.readFile(name);\n        }\n    };\n}\n\nfunction updateMainAceModule(node) {\n    if (node.body && ts.isModuleBlock(node.body)) {\n        const updatedStatements = node.body.statements.map(statement => {\n            //create type alias for config\n            if (ts.isVariableStatement(statement) && statement.declarationList.declarations[0]?.name?.text\n                === \"config\") {\n\n                const originalDeclaration = statement.declarationList.declarations[0];\n\n                const importTypeNode = ts.factory.createImportTypeNode(\n                    ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('ace-code/src/config')), undefined,\n                    undefined, false\n                );\n\n                const typeOfImportTypeNode = ts.factory.createTypeOperatorNode(\n                    ts.SyntaxKind.TypeOfKeyword, importTypeNode);\n\n                return ts.factory.updateVariableStatement(statement, statement.modifiers,\n                    ts.factory.updateVariableDeclarationList(statement.declarationList, [\n                        ts.factory.updateVariableDeclaration(originalDeclaration, originalDeclaration.name,\n                            originalDeclaration.exclamationToken, typeOfImportTypeNode, undefined\n                        )\n                    ])\n                );\n            }\n            return statement;\n        });\n\n        return ts.factory.updateModuleDeclaration(node, node.modifiers, node.name,\n            ts.factory.createModuleBlock(updatedStatements)\n        );\n    }\n}\n\n/**\n * Updates the module declaration for the \"keys\" and \"linking\" modules by adding the corresponding internal statements\n * to support mixins (EventEmitter, OptionsProvider, etc.).\n *\n * @param {ts.ModuleDeclaration} node - The module declaration node to update.\n * @param {Object<string, ts.Statement[]>} internalStatements - An object containing the internal statements to add to the module.\n * @returns {ts.ModuleDeclaration} - The updated module declaration.\n */\nfunction updateKeysAndLinksStatements(node, internalStatements) {\n    let statements = [];\n    if (node.body && ts.isModuleBlock(node.body)) {\n        statements = node.body.statements.filter(statement =>\n            ts.isFunctionDeclaration(statement)\n        );\n    }\n    if (internalStatements[node.name.text]) {\n        statements = [...internalStatements[node.name.text]];\n    }\n    const newBody = ts.factory.createModuleBlock(statements);\n    return ts.factory.updateModuleDeclaration(node, node.modifiers, node.name, newBody);\n}\n\n/**\n * Updates a module declaration by adding internal statements to support mixins (EventEmitter, OptionsProvider, etc.).\n *\n * @param {ts.ModuleDeclaration} node - The module declaration node to update.\n * @param {Object<string, ts.Statement[]>} internalStatements - An object containing the internal statements to add to the module.\n * @returns {ts.ModuleDeclaration} - The updated module declaration.\n */\nfunction updateModuleWithInternalStatements(node, internalStatements) {\n    const newBody = ts.factory.createModuleBlock(\n        node.body.statements.concat(internalStatements[node.name.text]).filter(statement => {\n            if (node.name.text.endsWith(\"autocomplete\")) {\n                return !(ts.isModuleDeclaration(statement) && statement.name.text === 'Autocomplete');\n            }\n            return true;\n        }));\n    return ts.factory.updateModuleDeclaration(node, node.modifiers, node.name, newBody);\n}\n\n/**\n * Fixes interfaces with empty extends clauses by either removing the entire interface declaration if it has no members,\n * or by removing the empty extends clause.\n *\n * @param {ts.InterfaceDeclaration} node - The interface declaration node to fix.\n * @param {ts.TransformationContext} context - The transformation context.\n * @returns {ts.InterfaceDeclaration} - The updated interface declaration.\n */\nfunction fixWrongInterfaces(node, context) {\n    for (const clause of node.heritageClauses) {\n        if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length === 0) {\n            if (node.members.length === 0) {\n                return; // remove entire interface declaration\n            }\n            // Remove the extends clause if it's empty\n            return context.factory.updateInterfaceDeclaration(node, node.modifiers, node.name, node.typeParameters, [],\n                node.members\n            );\n        }\n    }\n    return node;\n}\n\n/**\n * Fixes heritage clauses in class declarations by removing any inheritance from undefined types.\n *\n * @param {ts.ClassDeclaration} node - The class declaration node to fix.\n * @param {ts.TransformationContext} context - The transformation context.\n * @param {ts.TypeChecker} checker - The TypeScript type checker.\n * @returns {ts.ClassDeclaration} - The updated class declaration with fixed heritage clauses.\n */\nfunction fixWrongHeritageClauses(node, context, checker) {\n    let updatedHeritageClauses = [];\n    // remove inheritances from undefined types\n    for (let i = 0; i < node.heritageClauses.length; i++) {\n        let clause = node.heritageClauses[i];\n        if (clause.token === ts.SyntaxKind.ExtendsKeyword) {\n            const updatedTypes = clause.types.filter(type => {\n                const symbol = checker.getSymbolAtLocation(type.expression);\n                if (symbol) {\n                    const declaredType = checker.getDeclaredTypeOfSymbol(symbol);\n\n                    return declaredType.flags !== ts.TypeFlags.Undefined && declaredType[\"intrinsicName\"] !== \"error\";\n                }\n                return true;  // keep the type if the symbol can't be resolved\n            });\n            if (updatedTypes.length === 0) {\n                continue;\n            }\n            var updatedHeritageClause = clause;\n            if (updatedTypes.length !== clause.types.length) {\n                updatedHeritageClause = context.factory.createHeritageClause(\n                    ts.SyntaxKind.ExtendsKeyword, updatedTypes);\n            }\n        }\n        if (updatedHeritageClause) {\n            updatedHeritageClauses.push(updatedHeritageClause);\n        }\n        else {\n            updatedHeritageClauses.push(clause);\n        }\n    }\n    return context.factory.updateClassDeclaration(node, node.modifiers, node.name, node.typeParameters,\n        updatedHeritageClauses, node.members\n    );\n}\n\n/**\n * @param {string} content\n * @param {string} aceNamespacePath\n */\nfunction fixDeclaration(content, aceNamespacePath) {\n    const temporaryName = \"temp.d.ts\";\n    const customCompilerHost = createCustomCompilerHost(temporaryName, content);\n    const program = ts.createProgram([temporaryName], {\n        noEmit: true\n    }, customCompilerHost);\n\n    var checker = program.getTypeChecker();\n    let internalStatements = collectStatements(aceNamespacePath);\n    const finalDeclarations = [];\n\n    /**\n     * Transforms the source file by updating certain module declarations and interface/class heritage clauses.\n     *\n     * @param {ts.TransformationContext} context - The transformation context.\n     * @returns {function(ts.SourceFile): ts.SourceFile} - A function that transforms the source file.\n     */\n    function transformer(context) {\n        return (sourceFile) => {\n            function visit(node) {\n                let updatedNode = node;\n                // Update module declarations for certain module names\n                if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {\n                    if (node.name.text === \"ace-code\") {\n                        return updateMainAceModule(node);\n                    } else if (node.name.text.endsWith(\"lib/keys\") || node.name.text.endsWith(\"linking\")) {\n                        updatedNode = updateKeysAndLinksStatements(node, internalStatements);\n                    } else if (internalStatements[node.name.text]) {\n                        updatedNode = updateModuleWithInternalStatements(node, internalStatements);\n                    } else if (node.name.text.endsWith(\"static_highlight\")) {\n                        if (node.body && ts.isModuleBlock(node.body)) {\n                            const newBody = ts.factory.createModuleBlock(node.body.statements.filter(statement => {\n                                return !ts.isExportAssignment(statement);\n                            }));\n                            updatedNode = ts.factory.updateModuleDeclaration(node, node.modifiers, node.name, newBody);\n                        }\n                    }\n                }\n                // Fix wrong interface and class heritage clauses\n                else if (ts.isInterfaceDeclaration(node) && node.heritageClauses) {\n                    return fixWrongInterfaces(node, context);\n                } else if (ts.isClassDeclaration(node) && node.heritageClauses) {\n                    return fixWrongHeritageClauses(node, context, checker);\n                }\n                return ts.visitEachChild(updatedNode, visit, context);\n            };\n\n            return ts.visitNode(sourceFile, visit);\n        };\n    }\n\n    function pathBasedTransformer(context) {\n        return (sourceFile) => {\n            const moduleOutputs = {};\n\n            function visit(node) {\n                if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {\n                    let pathKey = 'modules';\n                    if (node.name.text === \"ace-code\") {\n                        pathKey = \"ace\";\n                        if (!moduleOutputs[pathKey]) {\n                            moduleOutputs[pathKey] = [];\n                        } //TODO:\n                        moduleOutputs[pathKey].push(node);\n                    }\n                    else {\n                        SEPARATE_MODULES.some(module => {\n                            if (node.name.text.includes(\"/\" + module + \"/\")) {\n                                pathKey = module;\n                                return true;\n                            }\n                        });\n                        if (!moduleOutputs[pathKey]) {\n                            moduleOutputs[pathKey] = [];\n                        }\n                        moduleOutputs[pathKey].push(node);\n                    }\n\n                    return node;\n                }\n                return ts.visitEachChild(node, visit, context);\n            }\n\n            ts.visitNode(sourceFile, visit);\n\n            // Generate new source files for each module path\n            let modules = Object.keys(moduleOutputs);\n\n            modules.forEach(key => {\n                const newSourceFile = context.factory.updateSourceFile(sourceFile, moduleOutputs[key]);\n                const dirPath = path.dirname(aceNamespacePath.replace(\"ace-internal\", \"ace\"));\n                if (!fs.existsSync(dirPath + \"/types\")) {\n                    fs.mkdirSync(dirPath + \"/types\");\n                }\n                const outputName = key === \"ace\" ? `${dirPath}/ace.d.ts` : `${dirPath}/types/ace-${key}.d.ts`;\n                finalDeclarations.push(outputName);\n\n                const printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed}, {\n                    substituteNode(hint, node) {\n                        if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name) && node.name.text === \"ace-code/src/ext/textarea\") {\n                            return ts.factory.createNotEmittedStatement(node);\n                        } else\n                        // remove all private members\n                        if (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertyDeclaration(node)\n                            || ts.isPropertySignature(node)) {\n                            const isPrivate = node.modifiers?.some(\n                                modifier => modifier.kind === ts.SyntaxKind.PrivateKeyword);\n\n                            const startsWithDollar = ts.isIdentifier(node.name) && /^[$_]/.test(node.name.text);\n\n                            if (isPrivate || (startsWithDollar && !hasExternalTag(node)) || hasInternalTag(node)) {\n                                return ts.factory.createNotEmittedStatement(node);\n                            }\n                        }\n                        else if (ts.isVariableStatement(node)) {\n                            if (node.text && node.getText().indexOf(\"export const $\") > -1) {\n                                return ts.factory.createNotEmittedStatement(node);\n                            }\n                            // Remove variable statements like 'const {any_identifier}_base: undefined;'\n                            const declarations = node.declarationList.declarations;\n\n                            // Filter out declarations that match the pattern\n                            const filteredDeclarations = declarations.filter(declaration => {\n                                if (ts.isIdentifier(declaration.name) && /_base\\w*$/.test(declaration.name.text)\n                                    && /:\\s*undefined$/.test(declaration.getText())) {\n                                    return false;\n                                }\n                                return true;\n                            });\n\n                            if (filteredDeclarations.length === 0) {\n                                return ts.factory.createNotEmittedStatement(node);\n                            }\n                            else if (filteredDeclarations.length < declarations.length) {\n                                return ts.factory.updateVariableStatement(node, node.modifiers,\n                                    ts.factory.updateVariableDeclarationList(node.declarationList, filteredDeclarations)\n                                );\n                            }\n                        }\n                        //remove empty exports\n                        else if (ts.isExportDeclaration(node) && /export\\s*{\\s*}/.test(node.getText())) {\n                            return ts.factory.createNotEmittedStatement(node);\n                        }\n                    }\n                });\n                let output = printer.printFile(newSourceFile);\n                if (key === \"ace\") {\n                    let referencePaths = modules.filter((el) => el != \"ace\").map((el) => {\n                        return `/// <reference path=\"./types/ace-${el}.d.ts\" />`;\n                    });\n                    let allReferences = referencePaths.join(\"\\n\") + \"\\n/// <reference path=\\\"./ace-modes.d.ts\\\" />\\n\";\n                    output = allReferences + output;\n                }\n                output = correctImportStatements(output);\n                output = cleanComments(output);\n                output = formatDts(outputName, output);\n                output = AUTO_GENERATED_HEADER + output;\n                fs.writeFileSync(outputName, output);\n            });\n\n            return sourceFile;\n        };\n    }\n\n    const sourceCode = program.getSourceFile(temporaryName);\n    const result = ts.transform(sourceCode, [transformer, pathBasedTransformer]);\n\n    result.dispose();\n\n    checkFinalDeclaration(finalDeclarations);\n}\n\n/**\n * Corrects the import statements in the provided text by replacing the old-style\n * `require()` imports with modern ES6 `import` statements.\n */\nfunction correctImportStatements(text) {\n    text = text.replace(\n        /import\\s*\\w+_\\d+\\s*=\\s*require\\(([\\w\\/\"-]+)\\);?.\\s*import\\s*(\\w+)\\s*=\\s*\\w+_\\d+\\.(\\w+);?/gs,\n        (match, path, importName, exportName) => {\n            if (importName !== exportName) {\n                return `import {${exportName} as ${importName}} from ${path};`;\n            }\n            return `import {${exportName}} from ${path};`;\n        }\n    );\n    return text;\n}\n\nfunction cleanComments(text) {\n    text = text.replace(/^\\s*\\*\\s*@(param|template|returns?|this|typedef)\\s*({.+})?(\\s*\\[?[$\\w]+\\]?)?\\s*$/gm, '');\n    text = text.replace(/@type\\s*({.+})/g, '');\n    text = text.replace(/\\/\\*(\\s|\\*)*\\*\\//g, '');\n    text = text.replace(/^\\s*[\\r\\n]/gm, '');\n\n    return text;\n}\n\nfunction hasInternalTag(node) {\n    const sourceFile = node.getSourceFile();\n    if (!sourceFile) return false;\n\n    const jsDocs = ts.getJSDocTags(node).filter(tag => tag.tagName.text === 'internal');\n    return jsDocs.length > 0;\n}\n\nfunction hasExternalTag(node) {\n    const sourceFile = node.getSourceFile();\n    if (!sourceFile) return false;\n\n    const jsDocs = ts.getJSDocTags(node).filter(tag => tag.tagName.text === 'external');\n    return jsDocs.length > 0;\n}\n\nfunction createMinimalLanguageServiceHost() {\n    return {\n        files: {},\n        addFile(fileName, text) {\n            this.files[fileName] = ts.ScriptSnapshot.fromString(text);\n        },\n        \"getCompilationSettings\": function () {\n            return ts.getDefaultCompilerOptions();\n        },\n        \"getScriptFileNames\": function () {\n            return Object.keys(this.files);\n        },\n        \"getScriptVersion\": function (_fileName) {\n            return \"0\";\n        },\n        \"getScriptSnapshot\": function (fileName) {\n            return this.files[fileName];\n        },\n        \"getCurrentDirectory\": function () {\n            return \"\";\n        }\n    };\n\n}\n\nfunction formatDts(filename, text) {\n    var host = createMinimalLanguageServiceHost();\n    host.addFile(filename, text);\n    const languageService = ts.createLanguageService(host);\n    let formatEdits = languageService.getFormattingEditsForDocument(filename, defaultFormatCodeSettings);\n    formatEdits\n        .sort((a, b) => a.span.start - b.span.start)\n        .reverse()\n        .forEach(edit => {\n            const head = text.slice(0, edit.span.start);\n            const tail = text.slice(edit.span.start + edit.span.length);\n            text = `${head}${edit.newText}${tail}`;\n        });\n    return text;\n}\n\n\n/**\n * @param {string[]} declarationNames\n */\nfunction checkFinalDeclaration(declarationNames) {\n    const program = ts.createProgram(declarationNames, {\n        noEmit: true,\n        target: ts.ScriptTarget.ES2019,\n        lib: [\"lib.es2019.d.ts\", \"lib.dom.d.ts\"]\n    });\n    const diagnostics = ts.getPreEmitDiagnostics(program);\n\n    diagnostics.forEach(diagnostic => {\n        if (diagnostic.file) {\n            const {\n                line,\n                character\n            } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n            const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n');\n            console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);\n        }\n        else {\n            console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n'));\n        }\n    });\n}\n\n/**\n * Collect statements (interfaces and function declarations) from the ace-internal.\n * @param {string} aceNamespacePath\n */\nfunction collectStatements(aceNamespacePath) {\n    const program = ts.createProgram([aceNamespacePath], {\n        noEmit: true\n    });\n    const sourceFile = program.getSourceFile(aceNamespacePath);\n    const result = {};\n    const printer = ts.createPrinter();\n    let packageName = \"ace-code\";\n\n    function visit(node) {\n        if (node && ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {\n            let nodes = [];\n            if (node.body && ts.isModuleBlock(node.body)) {\n                ts.forEachChild(node.body, (child) => {\n                    if (ts.isInterfaceDeclaration(child) || ts.isFunctionDeclaration(child)) nodes.push(child);\n                });\n            }\n            if (nodes.length > 0) {\n                const interfaceStrings = nodes.map(\n                    interfaceNode => printer.printNode(ts.EmitHint.Unspecified, interfaceNode, sourceFile));\n\n                let concatenatedInterfaceStrings = interfaceStrings.join('\\n\\n');\n                let identifiers = concatenatedInterfaceStrings.match(/Ace\\.[\\w]+<?/g);\n                if (identifiers && identifiers.length > 0) {\n                    identifiers = [...new Set(identifiers)];\n                    let importAlias = '';\n                    identifiers.forEach(identifier => {\n                        let typeName = identifier.replace(\"Ace.\", \"\");\n                        let rightSide = typeName;\n\n                        if (typeName.includes(\"EventEmitter<\")) {\n                            typeName = typeName + \"T extends { [K in keyof T]: (...args: any[]) => any }>\";\n                            rightSide = rightSide + \"T>\";\n                        } else if (typeName.includes(\"<\")) {\n                            typeName = rightSide = rightSide + \"T>\";\n                        }\n                        importAlias += \"type \" + typeName + \" = import(\\\"\" + packageName + \"\\\").Ace.\" + rightSide\n                            + \";\\n\\n\";\n                    });\n                    concatenatedInterfaceStrings = \"namespace Ace {\" + importAlias + \"}\" + concatenatedInterfaceStrings;\n                }\n\n                const newSourceFile = ts.createSourceFile(\n                    'temp.d.ts', concatenatedInterfaceStrings, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);\n                nodes = newSourceFile.statements;\n            }\n            result[node.name.text.replace(\"./\", packageName + \"/\")] = nodes;\n        }\n        ts.forEachChild(node, visit);\n    }\n\n    visit(sourceFile);\n\n    return result;\n}\n\n/**\n * @param {string} aceNamespacePath\n * @return {string}\n */\nfunction cloneAceNamespace(aceNamespacePath) {\n\n    const program = ts.createProgram([aceNamespacePath], {\n        noEmit: true\n    });\n    const sourceFile = program.getSourceFile(aceNamespacePath);\n    if (!sourceFile) {\n        throw new Error(\"Could not find ace.d.ts\");\n    }\n    const printer = ts.createPrinter();\n    for (let i = 0; i < sourceFile.statements.length; i++) {\n        const node = sourceFile.statements[i];\n        if (ts.isModuleDeclaration(node) && node.name.text == \"Ace\") {\n            let aceModule = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);\n            aceModule = aceModule.replace(/\"\\.\\/src/g, \"\\\"ace-code/src\");\n            aceModule = '\\n' + aceModule + '\\n';\n            return aceModule;\n        }\n    }\n}\n\n/**\n * @param {string} [aceNamespacePath]\n */\nfunction generateDeclaration(aceNamespacePath) {\n    if (!aceNamespacePath) {\n        aceNamespacePath = __dirname + \"/../ace-internal.d.ts\";\n    }\n    const excludeDir = \"src/mode\"; //TODO: remove, when modes are ES6\n\n    let data = generateInitialDeclaration(excludeDir);\n    let packageName = \"ace-code\";\n\n    let updatedContent = data.replace(/(declare module \")/g, \"$1\" + packageName + \"/src/\");\n\n    updatedContent = updatedContent.replace(/(require\\(\")/g, \"$1\" + packageName + \"/src/\");\n    updatedContent = updatedContent.replace(/(import\\(\")[./]*ace(?:\\-internal)?(\"\\).Ace)/g, \"$1\" + packageName + \"$2\");\n    updatedContent = updatedContent.replace(/(import\\(\")(?:[./]*)(?!(?:ace\\-code))/g, \"$1\" + packageName + \"/src/\");\n    updatedContent = updatedContent.replace(/ace\\-(?:code|builds)(\\/src)?\\/ace(?:\\-internal)?/g, packageName);\n    let aceModule = cloneAceNamespace(aceNamespacePath);\n\n    updatedContent = updatedContent.replace(/(declare\\s+module\\s+\"ace-(?:code|builds)\"\\s+{)/, \"$1\" + aceModule);\n    updatedContent = updatedContent.replace(/(?:export)?\\snamespace(?!\\sAce)/g, \"export namespace\");\n    fixDeclaration(updatedContent, aceNamespacePath);\n}\n\n/**\n * Updates the declaration module names in the provided content.\n * This function replaces references to \"ace-code\" with \"ace-builds\" and \"ace-builds-internal\" as appropriate.\n *\n * @param {string} content - The content to update.\n * @returns {string} The updated content with the module names replaced.\n */\nfunction updateDeclarationModuleNames(content) {\n    let output = content.replace(\n        /ace\\-code(?:\\/src)?\\/(mode(?!\\/(?:matching_brace_outdent|matching_parens_outdent|behaviour|folding))|theme|ext|keybinding|snippets)\\//g,\n        \"ace-builds/src-noconflict/$1-\"\n    );\n    output = output.replace(/\"ace\\-code\"/g, \"\\\"ace-builds\\\"\");\n    output = output.replace(/ace\\-code(?:\\/src)?/g, \"ace-builds-internal\");\n    return output;\n}\n\n\nif (!module.parent) {\n    require(\"./modes-declaration-generator\");\n    generateDeclaration();\n}\nelse {\n    exports.generateDeclaration = generateDeclaration;\n    exports.updateDeclarationModuleNames = updateDeclarationModuleNames;\n    exports.SEPARATE_MODULES = SEPARATE_MODULES;\n}\n"
  },
  {
    "path": "tool/add_mode.js",
    "content": "var fs = require('fs');\nvar lib = require('./lib');\nvar path = require('path');\n\nfunction main(displayName, extRe) {\n    var name = lib.snakeCase(displayName).replace(/[^\\w]/g, \"\");\n\n    /** demo **/\n    var demoFileExt = extRe.split(\"|\")[0] || name;\n    var demoFileName = demoFileExt[0] == \"^\" ? demoFileExt.substr(1) : name + \".\" + demoFileExt;\n    var demoFilePath = lib.AceRoot + \"demo/kitchen-sink/docs/\" + demoFileName;\n    fs.writeFileSync(demoFilePath, \"TODO add a nice demo!\\nTry to keep it short!\", \"utf8\");\n    console.log(\"Created demo file at: \" + path.normalize(demoFilePath));\n\n    /** mode **/\n    var template = fs.readFileSync(__dirname + \"/templates/mode.js\", \"utf8\");\n    var modePath = lib.AceRoot + \"src/mode/\" + name + \".js\";\n    var text = lib.fillTemplate(template, {\n        languageHighlightFilename: name,\n        languagename: name,\n        lineCommentStart: \"TODO\",\n        blockCommentStart: \"TODO\",\n        blockCommentEnd: \"TODO\"\n    });\n    fs.writeFileSync(modePath, text);\n    console.log(\"Created mode file at: \" + path.normalize(modePath));\n\n    /** highlight rules **/\n    template = fs.readFileSync(__dirname + \"/templates/highlight_rules.js\", \"utf8\");\n    var hlPath = lib.AceRoot + \"src/mode/\" + name + \"_highlight_rules.js\";\n    template = template.replace(/\\/\\* THIS[\\s\\S]*?\\*{3}\\/\\s*/, \"\");\n    text = lib.fillTemplate(template, {\n        language: name,\n        languageTokens: '{\\n\\\n            start: [{\\n\\\n                token: \"string.start\",\\n\\\n                regex: \\'\"\\',\\n\\\n                next: \"qstring\"\\n\\\n            }],\\n\\\n            qstring: [{\\n\\\n                token: \"escape\",\\n\\\n                regex: /\\\\\\\\./,\\n\\\n            }, {\\n\\\n                token: \"string.end\",\\n\\\n                regex: \\'\"\\',\\n\\\n                next: \"start\"\\n\\\n            }],\\n\\\n        }'\n    });\n    fs.writeFileSync(hlPath, text);\n    console.log(\"Created mode file at: \" + path.normalize(hlPath));\n\n    /** snippets **/\n    template = fs.readFileSync(__dirname + \"/templates/snippets.js\", \"utf8\");\n    var snipetsPath = lib.AceLib + \"ace/snippets/\" + name + \".js\";\n    text = lib.fillTemplate(template, {\n        languagename: name,\n        snippets: \"\"\n    });\n    fs.writeFileSync(snipetsPath, text);\n    console.log(\"Created snippets file at: \" + path.normalize(snipetsPath));\n\n    /** modelist **/\n    var modelistPath = lib.AceRoot + \"src/ext/modelist.js\";\n    var modelist = fs.readFileSync(modelistPath, \"utf8\").replace(/\\r\\n?/g, \"\\n\");\n    modelist = modelist.replace(/(supportedModes = {\\n)([\\s\\S]*?)(\\n^};)/m, function(_, m1, m2, m3) {\n        var langs = m2.split(/,\\n/);\n        var unsorted = [];\n        for (var i = langs.length; i--;) {\n            if (/\\s*\\/\\//.test(langs[i])) {\n                unsorted = langs.splice(i, langs.length);\n                break;\n            }\n        }\n        console.log(unsorted)\n        var offset = langs[0].trim().indexOf(\"[\");\n        var padding = Array(Math.max(offset - displayName.length - 1, 0) + 1).join(\" \");\n        var newLang = \"    \" + displayName + \":\" + padding + \"[\\\"\" + extRe + \"\\\"]\";\n        langs = langs.concat(newLang).map(function(x) {\n            return {\n                value: x,\n                id: x.match(/[^\"':\\s]+/)[0].toLowerCase()\n            };\n        });\n        langs[langs.length - 1].isNew = true;\n        \n        langs = langs.filter(function(x) {\n            console.log(x.id, displayName)\n            return x.id != displayName.toLowerCase() || x.isNew;\n        });\n        langs = langs.sort(function(a, b) {\n            return a.id.localeCompare(b.id);\n        }).map(function(x) {\n            return x.value;\n        });\n        \n        return m1 + langs.concat(unsorted).join(\",\\n\") + m3;\n    });\n    fs.writeFileSync(modelistPath, modelist, \"utf8\");\n    console.log(\"Updated modelist at: \" + path.normalize(modelistPath));\n}\n\nif (!module.parent) {\n    var args = process.argv.slice(2);\n    var displayName = args[0];\n    var extRe = args[1];\n    if (!displayName || ! extRe) {\n        console.log(\"Usage: ModeName ext1|ext2\");\n        process.exit(1);\n    }\n    main(displayName, extRe);\n} else {\n    module.exports = main;\n}\n\n"
  },
  {
    "path": "tool/esm_resolver_generator.js",
    "content": "var fs = require(\"fs\");\nconst {modeList, jsFileList} = require(\"../Makefile.dryice\");\n\nfunction buildResolver() {\n    var moduleNames = getModuleNames();\n    var loader = \"import ace from \\\"./src/ace\\\";\\n\";\n    loader = loader + moduleNames.map(function (moduleName) {\n        return `ace.config.setModuleLoader('${moduleName}', () => import('./${moduleName.replace(\"ace\", \"src\") + \".js\"}'));`;\n    }).join('\\n') + \"\\n\\nexport * as default from \\\"./src/ace\\\";\";\n\n    var declaration = 'export * from \"./ace\"';\n\n    fs.writeFileSync(__dirname + '/../esm-resolver.js', loader, \"utf8\");\n    fs.writeFileSync(__dirname + '/../esm-resolver.d.ts', declaration, \"utf8\");\n}\n\nfunction getModuleNames() {\n    let paths = [];\n    var modeNames = modeList(\"src/mode\");\n    // modes\n    let modeNamePaths = modeNames.map(function (name) {\n        return \"ace/mode/\" + name;\n    });\n    // snippets\n    let snippetsPaths = jsFileList(\"src/snippets\").map(function (name) {\n        return \"ace/snippets/\" + name;\n    });\n    // themes\n    let themesPaths = jsFileList(\"src/theme\").map(function (name) {\n        return \"ace/theme/\" + name;\n    });\n    // keybindings\n    let keyBindingsPaths = [\"vim\", \"emacs\", \"sublime\", \"vscode\"].map(function (name) {\n        return \"ace/keyboard/\" + name;\n    });\n    // extensions\n    let extPaths = jsFileList(\"src/ext\").map(function (name) {\n        return \"ace/ext/\" + name;\n    });\n    paths.push(...modeNamePaths, ...snippetsPaths, ...themesPaths, ...keyBindingsPaths, ...extPaths);\n    return paths;\n}\n\nbuildResolver();\n"
  },
  {
    "path": "tool/lib.js",
    "content": "var plist = require(\"plist\");\nvar util = require(\"util\");\nvar url = require(\"url\");\nvar cson = require(\"cson\");\n\nvar https = require(\"https\");\nvar http = require(\"http\");\n\nexports.parsePlist = function(xmlOrJSON, callback) {\n    var json;\n    if (xmlOrJSON[0] == \"<\") {\n        json = plist.parse(xmlOrJSON);\n    } else {\n        try {\n            xmlOrJSON = xmlOrJSON.replace(\n                /(\"(?:\\\\.|[^\"])*\")|(?:,\\s*)+([\\]\\}])|(\\w+)\\s*:|([\\]\\}]\\s*[\\[\\{])|(\\/\\/.*|\\/\\*(?:[^\\*]|\\*(?=[^\\/]))*?\\*\\/)/g,\n                function(_, str, extraComma, noQuote, missingComma, comment) {\n                    if (comment)\n                        return \"\";\n                    if (missingComma)\n                        return missingComma[0] + \",\" + missingComma.slice(1);\n                    return str || extraComma || '\"' + noQuote + '\":';\n            });\n            json = JSON.parse(xmlOrJSON);\n        } catch(e) {\n            json = cson.parse(xmlOrJSON);\n        }\n    }\n    callback && callback(json);\n    return json;\n};\n\n\nexports.formatJSON = function(object, initialIndent) {\n    return JSON.stringify(object, null, 4).replace(/^/gm, initialIndent||\"\");\n};\n\nexports.formatJS = function(object, initialIndent) {\n    return formatJS(object, 4, initialIndent);\n};\n\nfunction formatJS(object, indent, initialIndent) {\n    if (typeof  indent == \"number\")\n        indent = Array(indent + 1).join(\" \");\n    \n    function $format(buffer, totalIndent, state, o) {\n        if (typeof o != \"object\" || !o) {\n            if (typeof o == \"string\")\n                buffer.push(JSON.stringify(o));\n            else\n                buffer.push(\"\" + o);\n        }\n        else if (Array.isArray(o)) {\n            buffer.push(\"[\")\n            \n            var len = totalIndent.length\n            var oneLine = true;\n            for (var i = 0; i < o.length; i++) {\n                if (typeof o[i] == \"string\") {\n                    len += o[i].length + 2\n                } else if (!o[i]) {\n                    len += (o[i] + \"\").length\n                } else {\n                    oneLine = false;\n                    break;\n                }\n                len += 2;\n                if (len > 60) {\n                    oneLine = false;\n                    break;\n                }\n            }\n            \n            for (var i = 0; i < o.length; i++) {\n                if (o[i] && typeof o[i] == \"object\") {\n                    $format(buffer, totalIndent, state, o[i]);\n                    if (i < o.length - 1)\n                        buffer.push(\", \");\n                } else {\n                    if (oneLine)\n                        i && buffer.push(\" \");\n                    else\n                        buffer.push(\"\\n\", totalIndent + indent)\n                    $format(buffer, totalIndent + indent, state, o[i]);\n                    if (i < o.length - 1)\n                        buffer.push(\",\");\n                }\n                \n            }\n            if (!oneLine && buffer[buffer.length - 1] != \"}\")\n                buffer.push(\"\\n\" + totalIndent)\n            buffer.push(\"]\")\n        }\n        else {\n            var keys = Object.keys(o);\n            buffer.push(\"{\", \"\\n\");\n            for (var i = 0; i < keys.length; i++) {\n                buffer.push(totalIndent + indent);\n                if (/^\\w+$/.test(keys[i]))\n                    buffer.push(keys[i]);\n                else\n                    buffer.push(JSON.stringify(keys[i]));\n                buffer.push(\": \")\n\n                if (keys[i] == \"regex\" && typeof o[keys[i]] == \"string\") {\n                    try {\n                        var re = new RegExp(o[keys[i]]);\n                        buffer.push(\"/\" + re.source.replace(/\\\\.|\\//g, function(f) {\n                            return f.length == 1 ? \"\\\\\" + f : f;\n                        }) + \"/\");\n                    } catch(e) {\n                        $format(buffer, totalIndent + indent, state, o[keys[i]]);\n                    }\n                } else {\n                    $format(buffer, totalIndent + indent, state, o[keys[i]]);\n                }\n                \n                if (i < keys.length - 1)\n                    buffer.push(\",\", \"\\n\");\n            }\n            buffer.push(\"\\n\", totalIndent, \"}\");\n        }\n    }\n    var buffer = [];\n    $format(buffer, initialIndent || \"\", {}, object);\n    return buffer.join(\"\");\n}\n\nexports.fillTemplate = function(template, replacements) {\n    return template.replace(/%(.+?)%/g, function(str, m) {\n        return replacements[m] || \"\";\n    });\n};\n\nexports.hyphenate = function(str) {\n    return str.replace(/([A-Z])/g, \"-$1\").replace(/[_\\s\\-]+/g, \"-\").toLowerCase();\n};\n\nexports.camelCase = function(str) {\n    return str.replace(/[\\-_\\s]+(.?)/g, function(x, y) {return y.toUpperCase()});\n};\n\nexports.snakeCase = function(str) {\n    return str.replace(/([a-z])([A-Z])/g, \"$1-$2\").replace(/[_\\s\\-]+/g, \"_\").toLowerCase();\n};\n\nexports.quoteString = function(str) {\n    return '\"' + str.replace(/\\\\/, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\\\n\") + '\"';\n};\n\n\nexports.restoreJSONComments = function(objStr) {\n    return objStr.replace(/^(\\s*)comment: '(.*)'/gm, function(_, i, c) {\n        return i + \"//\" +  c.replace(/\\\\n(\\\\t)*/g, \"\\n\" + i + \"//\") + \"\\n\" + i;\n    }).replace(/ \\/\\/ ERROR/g, '\", // ERROR');\n};\n\n\nexports.download = function(href, callback) {\n\tvar options = url.parse(href);   \n\tvar protocol = options.protocol === \"https:\" ? https : http;\n\tconsole.log(\"connecting to \" + options.host + \" \" + options.path);\n\tvar request = protocol.get(options, function(res) {\n\t\tvar data = \"\";\n\t\tres.setEncoding(\"utf-8\");\n\n\t\tres.on(\"data\", function(chunk) {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\tres.on(\"end\", function(){\n\t\t\tcallback(data);\n\t\t});\n\t});\n};\n\n\nexports.AceRoot = __dirname + \"/../\";\nexports.AceLib = __dirname + \"/../lib/\";\n\n"
  },
  {
    "path": "tool/mode_creator.html",
    "content": "<!DOCTYPE html>\n\n<html lang=\"en\">\n<head>\n    <base href=\"../\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Ace Mode Creator</title>\n    <meta name=\"author\" content=\"Harutyun Amirjanyan\">\n    <style type=\"text/css\" >\n        body, html {\n            overflow: hidden;\n            height: 100%;\n            width: 100%;\n            margin: 0;\n            padding: 0;\n        }\n\n        #header {\n            border-bottom: solid 1px;\n        }\n        .separator-h {\n            padding: 0 10px;\n        }\n        #closeBtn {\n            background: rgba(245, 146, 146, 0.5);\n            border: 1px solid #F48A8A;\n            border-radius: 50%;\n            padding: 7px;\n            position: absolute;\n            right: -8px;\n            top: -8px;\n            z-index: 1000;\n        }\n        #closeBtn:hover {\n            background: rgba(245, 146, 146, 0.9);\n        }\n        #console{\n            /border: 1px solid lightblue;\n            bottom: 0;\n            height: 80px;\n            margin: 0 4%;\n            position: absolute;\n            width: 92%;\n            z-index: 1000;\n            box-shadow: 0 0 1px 2px gray\n        }\n        #consoleEditor{\n            height: 100%;\n            position: relative;\n            width: 100%;\n        }\n    </style>\n    <link href=\"../doc/site/images/favicon.ico\" rel=\"icon\" type=\"image/x-icon\">\n</head>\n<body>\n\n<div id=\"header\">\n    <label for=\"modeEl\">mode</label>\n    <select id=\"modeEl\" size=\"1\"></select>\n    <input type=\"button\" value=\"&#10227;\" title=\"sync\" id=\"syncToMode\"></select>\n    <span id=\"tablist\"></span>\n    <input type=\"button\" value=\"Save\" id=\"saveButton1\"></select>\n    <span class=\"separator-h\"></span>\n    <label for=\"autorunEl\">live preview</label>\n    <input type=\"checkbox\" label=\"autorun\" id=\"autorunEl\" checked>\n    <span class=\"separator-h\"></span>\n    <input type=\"button\" value=\"measure speed\" id=\"perfTest\"></select>\n\n\n    <div style='float:right'>\n        <label for=\"themeEl\">Theme</label>\n        <select id=\"themeEl\" size=\"1\" value=\"textmate\"></select>\n        <span class=\"separator-h\"></span>\n        <input type=\"button\" value=\"Save\" id=\"saveButton2\"></select>\n        <label for=\"doc\">Document</label>\n        <select id=\"doc\" size=\"1\"></select>\n    </div>\n</div>\n<div id=\"editor\"></div>\n<div id=\"console\" style=\"display:none\">\n    <span id=\"closeBtn\" onclick=\"this.parentNode.style.display='none'\"></span>\n    <div id=\"consoleEditor\"></div>\n</div>\n\n\n<script src=\"./demo/kitchen-sink/require.js\"></script>\n<script type=\"text/javascript\">\n  require.config({\n      paths: {\n          ace: \"../src\",\n          demo: \"../demo\",\n          tool: \"../tool\"\n      }\n  });\n  require([\"tool/mode_creator\"])\n</script>\n\n\n\n</body>\n</html>"
  },
  {
    "path": "tool/mode_creator.js",
    "content": "define(function(require, exports, module) {\n\n/** creates globals intentionally to make things easily accessible from console **/\n\nrequire(\"ace/ext/language_tools\");\nvar config = require(\"ace/config\");\nconfig.setDefaultValues(\"editor\", {\n    enableBasicAutocompletion: true,\n    enableSnippets: true\n});\nconfig.setLoader(function(moduleName, cb) {\n    require([moduleName], function(module) {\n        cb(null, module);\n    });\n});\n\nvar net = require(\"ace/lib/net\");\nvar Range = require(\"ace/range\").Range;\nvar util = require(\"demo/kitchen-sink/util\");\nvar layout = require(\"demo/kitchen-sink/layout\");\nvar modelist = require(\"ace/ext/modelist\");\nvar doclist = require(\"demo/kitchen-sink/doclist\");\nvar TokenTooltip = require(\"demo/kitchen-sink/token_tooltip\").TokenTooltip;\n\nvar EditSession = require(\"ace/edit_session\").EditSession;\nvar UndoManager = require(\"ace/undomanager\").UndoManager;\n\nvar DebugTokenizer = require(\"ace/tokenizer_dev\").Tokenizer;\nvar Tokenizer = require(\"ace/tokenizer\").Tokenizer;\n\nvar themelist = require(\"ace/ext/themelist\");\n\n// createEditor\nvar splitEditor = window.splitEditor = util.createSplitEditor(\"editor\");\n\nvar editor1 = window.editor1 = splitEditor.editor0;\nvar editor2 = window.editor2 = splitEditor.editor1;\nnew TokenTooltip(editor2);\n\nvar timeout = null;\nvar schedule = function() {\n    if (timeout != null) {\n        clearTimeout(timeout);\n    }\n    timeout = setTimeout(run, 800);\n};\n\n\nvar setAutorunEnabled = function(val) {\n    if (val)\n        editor1.on('change', schedule);\n    else\n        editor1.removeEventListener('change', schedule);\n};\n\nutil.bindCheckbox(\"autorunEl\", setAutorunEnabled);\n\n\nvar docEl = document.getElementById(\"doc\");\nutil.fillDropdown(docEl, doclist.docs);\nutil.bindDropdown(\"doc\", function(value) {\n    doclist.loadDoc(value, function(session) {\n        if (session) {\n            editor2.setSession(session);\n            updateSaveButtonState(null, editor2);\n        }\n    });\n});\n\nvar modeEl = document.getElementById(\"modeEl\");\nutil.fillDropdown(modeEl, modelist.modes);\nvar modeSessions = {};\n\nutil.bindDropdown(modeEl, function(value) {\n    if (modeSessions[value]) {\n        editor1.setSession(modeSessions[value]);\n        schedule();\n        return;\n    }\n    var hp = \"./src/mode/\" + value + \"_highlight_rules.js\";\n    net.get(hp, function(text) {\n        var session = new EditSession(text);\n        session.setUndoManager(new UndoManager());\n\n        modeSessions[value] = session;\n        session.setMode(\"ace/mode/javascript\", function() {\n            if (session.getLine(0).match(/^\\s*\\//))\n                session.toggleFoldWidget(0); // fold licence comment\n        });\n\n        editor1.setSession(modeSessions[value]);\n        updateSaveButtonState(null, editor1);\n        schedule();\n    });\n});\n\ndocument.getElementById(\"syncToMode\").onclick = function() {\n    docEl.value = modelist.modesByName[modeEl.value].desc;\n    docEl.onchange();\n    run();\n};\n\neditor1.saveButton = document.getElementById(\"saveButton1\");\neditor2.saveButton = document.getElementById(\"saveButton2\");\neditor1.saveButton.editor = editor1;\neditor2.saveButton.editor = editor2;\n\neditor1.saveButton.onclick = function() {\n    doclist.saveDoc({\n        path: \"./lib/ace/mode/\" + modeEl.value + \"_highlight_rules.js\",\n        session: editor1.session\n    }, function(err) {\n        handleSaveResult(err, editor1);\n    });\n};\neditor1.commands.bindKey({\n    win: \"Ctrl-S\", mac: \"Cmd-s\"\n}, editor1.saveButton.onclick);\neditor2.saveButton.onclick = function() {\n    doclist.saveDoc(docEl.value, function(err) {\n        handleSaveResult(err, editor2);\n    });\n};\neditor2.commands.bindKey({\n    win: \"Ctrl-S\", mac: \"Cmd-s\"\n}, editor2.saveButton.onclick);\nfunction updateSaveButtonState(e, editor){\n    editor.saveButton.disabled = editor.session.getUndoManager().isClean();\n}\neditor1.on(\"input\", updateSaveButtonState);\neditor2.on(\"input\", updateSaveButtonState);\n\nfunction handleSaveResult(err, editor) {\n    if (err) {\n        return log(\n            \"Write access to this file is disabled.\\n\"+\n            \"To enable saving your changes to disk, clone the Ace repository\\n\"+\n            \"and run the included web server with the --allow-save option\\n\"+\n            \"`node static.js --allow-save` or `static.py --puttable=*`\"\n        );\n    }\n    editor.session.getUndoManager().markClean();\n    updateSaveButtonState(null, editor);\n}\n\ndocument.getElementById(\"perfTest\").onclick = function() {\n    var lines = editor2.session.doc.getAllLines();\n    if (!lines.length)\n        return;\n    while (lines.length < 1000) {\n        lines = lines.concat(lines);\n    }\n\n    var tk = new Tokenizer(currentRules);\n    var testPerf = function(lines, tk) {\n        var state = \"start\";\n        for (var i=0, l = lines.length; i <l; i++) {\n            state = tk.getLineTokens(lines[i], state).state;\n        }\n    };\n\n    var t = performance.now();\n    testPerf(lines, tk);\n    t = t - performance.now(t);\n    log(\"tokenized \" + lines.length + \" lines in \" + t + \" ms\");\n};\n\nvar themes = { Bright: [], Dark: [] };\nthemelist.themes.forEach(function(x) {\n    themes[x.isDark ? \"Dark\" : \"Bright\"].push({ caption: x.caption, value: x.name });\n});\nutil.fillDropdown(\"themeEl\", themes);\n\nutil.bindDropdown(\"themeEl\", function(value) {\n    if (!value)\n        return;\n    editor1.setTheme(\"ace/theme/\" + value);\n    editor2.setTheme(\"ace/theme/\" + value);\n});\n\n\nfunction getDeps(src, path) {\n    var deps = [];\n    src.replace(/require\\((['\"])(.*?)\\1/g, function(a,b,c) {\n        if (c[0] == \".\") {\n            var base = path.split(\"/\");\n            c.split(\"/\").forEach(function(part) {\n                if (part == \".\") {\n                    base.pop();\n                } else if (part == \"..\") {\n                    base.pop();\n                    base.pop();\n                } else {\n                    base.push(part);\n                }\n            });\n            c = base.join(\"/\");\n        }\n        deps.push('\"' + c + '\"');\n    });\n\n    return deps;\n}\nfunction run() {\n    var src = editor1.getValue();\n    var path = \"ace/mode/new\";\n    var deps = getDeps(src, path);\n    window.require.undef(path);\n    if (!/\\bdefine\\s*\\(/.test(src)) {\n        src = \"define(function(require, exports, module) {\" + src + \"\\n});\";\n    }\n    src = src.replace(\"define(\", 'define(\"' + path +'\", [\"require\",\"exports\",\"module\",' + deps +'],');\n    try {\n        eval(src);\n        require([path], function(e) {\n            try {\n                continueRun(e);\n            } catch(e) {\n                log(e);\n            }\n        }, function(e) {\n            log(e);\n            window.require.undef(path);\n        });\n        hideLog();\n    } catch(e) {\n        log(e);\n    }\n}\nvar currentRules;\nvar continueRun = function(rules) {\n    for (var i in rules) {\n        if (typeof rules[i] == \"function\" && /rules/i.test(i)) {\n            rules = rules[i];\n            break;\n        }\n    }\n    currentRules = new rules().getRules();\n    var Tokenizer = DebugTokenizer;\n    var Mode = require(editor2.session.$mode.$id).Mode;\n    editor2.session.$mode = new Mode();\n    var tk = new Tokenizer(currentRules);\n    editor2.session.$mode.$tokenizer = tk;\n    editor2.session.bgTokenizer.setTokenizer(tk);\n    editor2.renderer.updateText();\n};\n\neditor1.commands.bindKey(\"ctrl-Return\", run);\n\nvar logEditor;\nfunction log(e) {\n    console.log(e);\n    if (!logEditor) {\n        logEditor = util.createEditor(document.getElementById(\"consoleEditor\"));\n        logEditor.session.setMode(\"ace/mode/javascript\");\n        logEditor.session.setUseWorker(false);\n    }\n    logEditor.container.parentNode.style.display = '';\n    logEditor.resize();\n    logEditor.navigateFileEnd(e);\n    logEditor.insert(e + \"\\n\");\n}\nfunction hideLog() {\n    if (logEditor)\n        logEditor.container.parentNode.style.display = 'none';\n}\n\n});\n\n"
  },
  {
    "path": "tool/modes-declaration-generator.js",
    "content": "var ts = require(\"typescript\");\nvar fs = require(\"fs\");\nvar path = require(\"path\");\n\nconst modeDirPath = __dirname + \"/../src/mode\";\nconst outputFilePath = __dirname + \"/../ace-modes.d.ts\";\nconst moduleNamePrefix = \"ace-code\";\n\nfunction processFile(program, filePath) {\n    const sourceFile = program.getSourceFile(filePath);\n    const checker = program.getTypeChecker();\n    if (!sourceFile) return;\n\n    var statements = [];\n    const excludeTypes = [\n        \"() => void\", \"any\", \"typeof FoldMode\", \"(voidElements: any, optionalTags: any) => void\",\n        \"typeof LiveScriptMode\"\n    ];\n\n    function visit(node) {\n        // Check for variable statements that might contain exports\n        if (ts.isVariableStatement(node)) {\n            node.declarationList.declarations.forEach(declaration => {\n                if (declaration.initializer && ts.isBinaryExpression(declaration.initializer)\n                    && ts.isPropertyAccessExpression(declaration.initializer.left)\n                    && declaration.initializer.left.expression.getText() === \"exports\") {\n                    // Extract the export name\n                    const exportName = declaration.initializer.left.name.text;\n\n                    const symbol = checker.getSymbolAtLocation(declaration.name);\n                    let typeNode = undefined;\n                    if (symbol) {\n                        const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);\n                        if (!excludeTypes.includes(checker.typeToString(type))) {\n                            typeNode = checker.typeToTypeNode(type, undefined, undefined);\n                        }\n                    }\n                    const exportAssignment = createExportStatement(exportName, typeNode);\n                    statements.push(exportAssignment);\n                }\n            });\n        }\n        else if (ts.isExpressionStatement(node) && ts.isBinaryExpression(node.expression)) {\n            const binaryExpression = node.expression;\n            // Check for \"exports.<identifier> = <identifier>;\" pattern\n            if (ts.isPropertyAccessExpression(binaryExpression.left) && binaryExpression.left.expression.getText()\n                === \"exports\" && binaryExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken) {\n                const exportName = binaryExpression.left.name.text;\n\n                let typeNode = undefined;\n                const symbol = checker.getSymbolAtLocation(node.expression.left);\n                if (symbol) {\n                    const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);\n                    if (!excludeTypes.includes(checker.typeToString(type))) {\n                        typeNode = checker.typeToTypeNode(type, undefined, undefined);\n                    }\n                }\n                const exportAssignment = createExportStatement(exportName, typeNode);\n                statements.push(exportAssignment);\n            }\n        }\n\n        ts.forEachChild(node, visit);\n    }\n\n    visit(sourceFile);\n    return statements;\n}\n\nfunction createExportStatement(exportName, type) {\n    const exportType = getExportType(exportName);\n    return ts.factory.createVariableStatement([ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n        ts.factory.createVariableDeclarationList([\n            ts.factory.createVariableDeclaration(ts.factory.createIdentifier(exportName), undefined,\n                type || ts.factory.createConstructorTypeNode(undefined, undefined, [], exportType), undefined\n            )\n        ], ts.NodeFlags.Const)\n    );\n}\n\nfunction getExportType(exportName) {\n    var aceType = \"\";\n    if (/highlight|rules/i.test(exportName)) {\n        aceType = \"HighlightRules\";\n    }\n    else if (/behaviour/i.test(exportName)) {\n        //TODO: we need options for behaviours\n        aceType = \"Behaviour\";\n    }\n    else if (/completion/i.test(exportName)) {\n        aceType = \"Completion\";\n    }\n    else if (/fold/i.test(exportName)) {\n        aceType = \"Folding\";\n    }\n    else if (/mode/i.test(exportName)) {\n        aceType = \"SyntaxMode\";\n    }\n    else if (/outdent/i.test(exportName)) {\n        aceType = \"Outdent\";\n    }\n\n    return ts.factory.createImportTypeNode(\n        ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(\"ace-code\")),\n        undefined,\n        ts.factory.createQualifiedName(ts.factory.createIdentifier(\"Ace\"), ts.factory.createIdentifier(aceType)),\n        undefined, false\n    );\n}\n\nfunction generateModuleDeclarations(dirPath) {\n    const program = createProgram(dirPath);\n    const filePaths = program.getRootFileNames();\n\n    return filePaths.sort((a, b) => a.localeCompare(b)).map(filePath => {\n        let normalizedFilePath = filePath.replace(/\\\\/g, \"/\").replace(/.*(?=src\\/mode)/, \"\").replace(/\\.js$/, \"\");\n\n        const moduleName = moduleNamePrefix + \"/\" + normalizedFilePath;\n        const statements = processFile(program, filePath);\n        const moduleBody = ts.factory.createModuleBlock(statements);\n        return ts.factory.createModuleDeclaration([ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)],\n            ts.factory.createStringLiteral(moduleName), moduleBody,\n            ts.NodeFlags.ExportContext | ts.NodeFlags.JavaScriptFile | ts.NodeFlags.Ambient | ts.NodeFlags.ContextFlags\n        );\n    });\n}\n\nfunction getAllFiles(dirPath) {\n    let files = [];\n\n    const entries = fs.readdirSync(dirPath);\n\n    entries.sort().forEach(entry => {\n        const fullPath = path.join(dirPath, entry);\n        const stat = fs.statSync(fullPath);\n\n        if (stat.isDirectory()) {\n            files = files.concat(getAllFiles(fullPath));\n        }\n        else if (stat.isFile()) {\n            files.push(fullPath);\n        }\n    });\n\n    return files;\n}\n\nfunction createProgram(dirPath) {\n    const fileNames = getAllFiles(dirPath).filter(file => /\\.js$/.test(file) && !/test\\.js$/.test(file));\n\n    const program = ts.createProgram(fileNames, {\n        target: ts.ScriptTarget.ES5,\n        module: ts.ModuleKind.CommonJS,\n        allowJs: true\n    });\n\n    return program;\n}\n\nfunction generateModesDeclarationFile() {\n    const moduleDeclarations = generateModuleDeclarations(modeDirPath);\n    const printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed});\n    const resultFile = ts.createSourceFile(outputFilePath, \"\", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);\n    const result = moduleDeclarations.map(\n        declaration => printer.printNode(ts.EmitHint.Unspecified, declaration, resultFile)).join('\\n\\n');\n    fs.writeFileSync(outputFilePath, result);\n}\n\ngenerateModesDeclarationFile();\n"
  },
  {
    "path": "tool/package.json",
    "content": "{\n  \"name\": \"ace-tools\",\n  \"version\": \"0.1.0\",\n  \"dependencies\": {\n    \"amd-loader\": \"~0.0.4\",\n    \"browser-pack\": \"5.0.1\",\n    \"browserify\": \"10.2.4\",\n    \"cson\": \"3.0.1\",\n    \"css-parse\": \"1.0.3\",\n    \"css-stringify\": \"1.0.3\",\n    \"deps-sort\": \"1.3.9\",\n    \"derequire\": \"2.0.0\",\n    \"plist\": \"3.0.5\"\n  }\n}\n"
  },
  {
    "path": "tool/perf-test.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html lang=\"en\">\n<head>\n    <base href=\"..\">\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Ace Profile  util</title>\n    <link rel=\"stylesheet\" href=\"demo/kitchen-sink/styles.css\" type=\"text/css\" media=\"screen\" charset=\"utf-8\">\n    <link href=\"../doc/site/images/favicon.ico\" rel=\"icon\" type=\"image/x-icon\">\n</head>\n<body>\n<div style=\"position:absolute;height:100%;width:260px\">\n  <div style=\"position: absolute; overflow: hidden; top:20px; bottom:0\">\n  <div style=\"width: 120%; height:100%; overflow-y: scroll\">\n\n  <table>\n    <tr>\n      <td colspan=\"2\">\n        <label for=\"profile\">profile</label>\n        <input type=\"checkbox\" checked id=\"profile\"></input>\n        <label for=\"timeout\">delay</label>\n        <input id=\"timeout\" type=\"text\" value=\"3\" style=\"width:10em\"></input>\n      </td>\n    </tr>\n    <tr>\n      <td colspan=\"2\">\n        <button onclick = \"start(this.textContent)\">scroll</button>\n        <button onclick = \"start(this.textContent)\">select</button>\n        <button onclick = \"start(this.textContent)\">type</button>\n        <button onclick = \"start(this.textContent)\">selectH</button>\n      </td>\n    </tr>\n    <tr>\n      <td colspan=\"2\">\n        <button onclick = \"start(this.textContent)\">tokenize</button>\n      </td>\n    </tr>\n\n  </table>\n  <div id=\"optionsPanel\"></div>\n\n  </div>\n  </div>\n</div>\n  <div id=\"editor-container\"></div>\n\n<!--DEVEL-->\n  <script type=\"text/javascript\">\n      var require = {\n          baseUrl: window.location.protocol + \"//\" + window.location.host + window.location.pathname.split(\"/\").slice(0, -1).join(\"/\"),\n          paths: {\n              ace: \"../lib/ace\"\n          }\n      };\n  </script>\n  <script src=\"demo/kitchen-sink/require.js\" data-main=\"../demo/kitchen-sink/demo\" type=\"text/javascript\"></script>\n\n  <script>\n    if (!Date.now) {\n        Date.now = function() { return (new Date()).getTime() };\n    }\n\n\n    var scrollTop, startTime;\n    var timeout, speed, next\n    var editor, shouldProfile;\n\n    function start(testName) {\n        editor = env.editor\n        timeout = parseInt(document.getElementById(\"timeout\").value);\n        shouldProfile = document.getElementById(\"profile\").checked;\n\n        startTime = Date.now()\n        shouldProfile && console.profile()\n\n        speed = 10;\n        next = window[testName + \"Next\"];\n\n        window[testName + \"Start\"] && window[testName + \"Start\"]()\n        setTimeout(next, 1);\n    }\n    function end(){\n        shouldProfile && console.profileEnd()\n        var dt = startTime - Date.now()\n        console.log(dt)\n        ace.cmdLine.setValue(dt+\"\", 1)\n    }\n\n    /*editor.renderer.scrollToY(0);\n    editor.navigateFileStart(0);\n    */\n\n    var scrollNext = function() {\n        var r = editor.renderer\n        for (var i = speed; i--; )\n            r.scrollBy(0, 1)\n        if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)\n            end()\n        else\n            setTimeout(next, timeout, speed++)\n    }\n\n    var selectNext = function() {\n        var r = editor.renderer\n        for (var i = speed; i-- > 0; )\n            editor.selection.selectDown()\n        editor.renderer.scrollCursorIntoView()\n        if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)\n            end()\n        else\n            setTimeout(next, timeout, speed+=0.1)\n    }\n\n    var selectHNext = function() {\n        var r = editor.renderer\n        for (var i = speed; i-- > 0; )\n            editor.selection.selectRight()\n        if (r.scrollTop + r.layerConfig.height > r.layerConfig.maxHeight - 20)\n            end()\n        else\n            setTimeout(next, timeout, speed+=0.1)\n    }\n\n    var typeChars = start.toString().split(\"\")\n    var typeNext = function() {\n        var r = editor.renderer\n        for (var i = speed; i--; )\n            editor.insert(typeChars[i % typeChars.length])\n        if (speed == 100)\n            end()\n        else\n            setTimeout(next, timeout, speed++)\n    }\n\n    var tokenizer, state, lines, chunk\n    var tokenizeStart = function() {\n        var b = ace.session.bgTokenizer\n        state = null\n        tokenizer = b.tokenizer\n        lines = b.doc.getAllLines()\n        chunk = 1000\n    }\n    \n    var tokenizeNext = function() {\n        var states = []\n        for (var i = 0, l = lines.length; i < l; i++) {\n            state = tokenizer.getLineTokens(lines[i], state).state\n        }\n        states.push(state)\n        if (speed-- > 3)\n            setTimeout(next, timeout)\n        else\n            end()\n    }\n\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "tool/regexp_to_keywords.js",
    "content": "\nvar tokenize = require(\"./regexp_tokenizer\").tokenize;\n\nfunction parse(str) {\n    var tokens = tokenize(str);\n    var node = addChild();\n    var root = node;\n    for (var i = 0; i < tokens.length; i++) {\n        var t = tokens[i];\n        switch (t.type) {\n            case \"group.start\": \n                node = addChild(node);\n                break;\n            case \"group.end\": \n                if (node.alternation) {\n                    addChild(node, node.children, node.alternation);\n                    node.children = node.alternation;\n                    node.alternation = true;\n                }\n                node = node.parent;\n                break;\n            case \"alternation\":\n                if (!node.alternation) {\n                    node.alternation = [];\n                }\n                addChild(node, node.children, node.alternation);\n                node.children = [];\n                break; \n            case \"text\": \n                node.children.push(t.value);\n                break; \n            case \"anchor\": \n                node.children.push(t);\n                break;\n            case \"quantifier\":\n                var last = node.children[node.children.length - 1];\n                if (last.type == \"string\" || t.value != \"?\") {\n                    console.error(node);\n                    throw new Error(\"Unsupported \" + t.type);\n                }\n                last.optional = true;\n                break;\n            default:\n                console.error(t, node)\n                throw new Error(\"Unsupported \" + t.type)\n        \n        }\n    }\n    if (root != node) {\n        throw new Error(\"Expected groups to match\");\n    }\n    return root\n\n    function addChild(parent, children, targetArray) {\n        var newNode = {children: children || [], parent: parent};\n        children && children.forEach(element => {\n            element.parent = newNode;\n        });\n        if (parent) {\n            (targetArray || parent.children).push(newNode);\n        }\n        return newNode;\n    }\n}\n\nvar HighlightRules = require(\"../src/mode/objectivec_highlight_rules\").ObjectiveCHighlightRules;\n\n\nvar rules = new HighlightRules().$rules.start\n    .filter(x => /support.function.C99.c/.test(x.token))\n\n\nvar words = {};\nrules.forEach(function(rule) {\n    var tree = parse(rule.regex)\n\n    var flattened = flatten(tree);\n\n    words[rule.token] = flattened.join(\"|\");\n\n    function flatten(node) {\n        if (typeof node == \"string\") {\n            return node;\n        } else if (node.children) {\n            var flatNode = node.children.map(flatten);\n            var result;\n            if (node.alternation) {\n                result = flatNode.flat();\n            } else {\n                var result = [\"\"]\n                for (var i = 0; i < flatNode.length; i++) {\n                    var toAdd = flatNode[i]\n                    var base = result;\n                    var result = [];\n                    if (typeof toAdd == \"string\") {\n                        for (var j = 0; j < base.length; j++) {\n                            result.push(base[j] + toAdd)\n                        }\n                    } else {\n                        for (var j = 0; j < base.length; j++) {\n                            for (var k = 0; k < toAdd.length; k++) {\n                                result.push(base[j] + toAdd[k])\n                            }\n                        }\n                        if (toAdd.optional)\n                            result = base.concat(result)\n\n                    }\n                }\n            }\n            if (node.optional) {\n                result.optional = true;\n            }\n            return result;\n        }\n        return [\"\"]\n    }\n});\n\n\nrequire(\"fs\").writeFileSync(__dirname + \"/_flattened.js\", JSON.stringify(words, null, 4), \"utf8\")"
  },
  {
    "path": "tool/regexp_tokenizer.js",
    "content": "/***** regexp tokenizer */\nrequire(\"amd-loader\");\n\nvar Tokenizer = require(\"../src/tokenizer\").Tokenizer;\nvar TextHighlightRules = require(\"../src/mode/text_highlight_rules\").TextHighlightRules;\n\nvar r = new TextHighlightRules()\nr.$rules = {\n    start: [\n        {token: \"anchor\", regex: /[\\^\\$]|\\\\[bBAZzG]/, merge:false},\n        {token: \"backRef\", regex: /\\\\([1-9]|k(<\\w+\\b[+-]?\\d>|'\\w+\\b[+-]?\\d'))/, merge:false},\n        {include: \"charTypes\", merge:false},\n        {token: \"charclass\", regex: /\\[\\^?/, push: \"charclass\", merge:false},\n        {token: \"alternation\", regex: /\\|/, merge:false},\n        {include: \"quantifiers\", merge:false},\n        {include: \"groups\", merge:false},\n        {include: \"xGroup\", merge:true}\n    ],\n    charTypes: [\n        {token: \"char\", regex: /\\\\([tvnrbfae]|[0-8]{1,3}|x[\\dA-Fa-f]{2}|x7[\\dA-Fa-f]{7})/, merge:false}, // todo \\cx\n        {token: \"charType\", regex: /\\.|\\\\[wWsSdDhH]/, merge:false},\n        {token: \"charProperty\", regex: /\\\\p{\\w+}/, merge:false},\n        {token: \"char\", regex: /\\\\./, merge:false},\n    ],\n    quantifiers: [\n        {token: \"quantifier\", regex: /([?*+]|{\\d+\\b,?\\d*}|{,\\d+})[?+]?/, merge:false}\n    ],\n    charclass: [\n        {include: \"charTypes\", merge:false},\n        {token: \"charclass.start\", regex: /\\[\\^?/, push: \"charclass\", merge:false},\n        {token: \"charclass.end\", regex: /\\]/, next: \"pop\", merge:false}\n    ],\n    groups: [\n        {token: \"group\", regex: /[(]([?](#|[imx\\-]+:?|:|=|!|<=|<!|>|<\\w+>|'\\w+'|))?|[)]/,\n            onMatch: function(val, state, stack) {\n                if (!stack.groupNumber)\n                    stack.groupNumber = 1;\n\n                var isStart = val !== \")\";\n                var t = {depth:0,type: isStart ? \"group.start\" : \"group.end\", value: val};\n                t.groupType = val[2];\n\n                if (val == \"(\") {\n                    t.number = stack.groupNumber++;\n                    t.isGroup = true\n                } else if (t.groupType == \"'\" || (t.groupType == \"<\" && val.slice(-1) == \">\")) {\n                    t.name = val.slice(2, -1)\n                    t.isGroup = true\n                } else if (t.groupType == \":\") {\n                    t.isGroup = true\n                }\n\n                if (t.groupType && val.indexOf(\"x\") != -1) {\n                    var minus = val.indexOf(\"-\");\n                    if (minus == -1 || minus > val.indexOf(\"x\"))\n                        stack.xGroup = t;\n                    else\n                        stack.xGroup = null;\n                } else if (!isStart && stack.xGroup && stack.xGroup == stack[0]) {\n                    if (stack.xGroup.value.slice(-1) == \":\")\n                        stack.xGroup = null;\n                }\n\n                if (isStart) {\n                    if (stack.groupDepth) {\n                        stack[0].hasChildren = true\n                    }\n                    stack.groupDepth = (stack.groupDepth||0)+1;\n                    stack.unshift(t)\n                } else {\n                    stack.groupDepth --;\n                    t.start = stack.shift(t)\n                    t.start.end = t\n                }\n                return [t]\n            }, merge:false\n        }\n    ],\n    xGroup: [\n        {token: \"text\", regex:/\\s+/, onMatch: function(val, state, stack) {\n            return stack.xGroup ? [] : \"text\"\n        }, merge: true},\n        {token: \"text\", regex: /#/, onMatch: function(val, state, stack) {\n            if (stack.xGroup) {\n                this.next = \"comment\";\n                stack.unshift(state);\n                return  [];\n            }\n            this.next = \"\";\n            return \"text\";\n        }, merge: true}\n    ],\n    comment: [{\n        regex: \"[^\\n\\r]*|^\", token: \"\",  onMatch: function(val, state, stack) {\n            this.next = stack.shift();\n            return [];\n        }\n    }]\n}\nr.normalizeRules()\nvar tmReTokenizer = new Tokenizer(r.getRules());\n\nfunction tokenize(str) {\n    tmReTokenizer.$setMaxTokenCount(2 * str.length);\n    return tmReTokenizer.getLineTokens(str).tokens;\n}\n\nfunction toStr(tokens) { return tokens.map(function(x){return x.value}).join(\"\")}\n\n\nexports.tokenize = tokenize;\nexports.toStr = toStr;\nexports.tmReTokenizer = tmReTokenizer;"
  },
  {
    "path": "tool/regexp_tokenizer_test.js",
    "content": "require(\"amd-loader\");\nvar assert = require(\"assert\");\n\nvar tk = require(\"./regexp_tokenizer\");\nvar tokenize = tk.tokenize;\nvar toStr = tk.toStr;\n\nvar logTokens = function(tokens) {\n    tokens.forEach(function(x) {\n        delete x.end\n        delete x.start\n    })\n    console.log(tokens)\n}\n\nassert.equal(toStr(\n    tokenize(\"(?x)c + +\\n\\\n    # comment\\n\\\n    (?-x)  #  (?x:  1 \\n\\\n        (2) [ ]   # a    \\n\\\n        3  4)  c#\"\n    )),    \n    \"(?x)c++(?-x)  #  (?x:1(2)[ ]34)  c#\"\n )\nassert.equal(toStr(\n    tokenize(\"(?x)\\n\\\n        u  # comment\\n\\\n    \")),\n    \"(?x)u\"\n )\n"
  },
  {
    "path": "tool/release-api-docs.sh",
    "content": "#!/bin/bash\nset -e\n\n\ncd `dirname $0`/..\nSOURCE=`pwd`\n\nmkdir -p .apigenerator\n\n# check if api dir is clean\nif ! [ -f .apigenerator/.git/HEAD ]; then\n    git clone git@github.com:ajaxorg/ace-api-docs.git .apigenerator\nfi\n\npushd .apigenerator\ngit pull origin master # fetch\n\nrm -rf ./doc\n\nnpm i\nexport ACE_VERSION=\"v$(node -p 'require(\"../package.json\").version')\"\nnode generateDoc.js ./doc\n\nrm -rf ./doc-repo\ngit worktree prune\ngit worktree add --force --no-checkout doc-repo origin/gh-pages\n\ncd doc-repo\nmv ../doc/* .\ngit reset origin/gh-pages\ngit add .\n\nif [ \"$(git status --porcelain)\" ];  then\n    git commit -m \"build api reference $ACE_VERSION\"\n    git push origin HEAD:gh-pages --force\nfi\n\npopd\n\n\n\ngit worktree prune\nrm -rf .apigenerator/ace-gh-pages\ngit worktree add --force --no-checkout .apigenerator/ace-gh-pages HEAD\n\n\npushd .apigenerator/ace-gh-pages\ngit reset > /dev/null\ngit rm -rf api  || :\nmv ../doc-repo ./api\necho '[submodule \"doc/wiki\"]\n        path = doc/wiki\n        url = https://github.com/ajaxorg/ace.wiki.git\n[submodule \"build\"]\n        path = build\n        url = https://github.com/ajaxorg/ace-builds.git\n[submodule \"api\"]\n        path = api\n        url = https://github.com/ajaxorg/ace-api-docs.git' > .gitmodules\ngit add .gitmodules api\n\ngit commit -m \"build api reference $ACE_VERSION\"\n\ngit push --progress \"origin\"  HEAD:refs/heads/gh-pages --force\n\npopd\n"
  },
  {
    "path": "tool/release.sh",
    "content": "#!/bin/bash\nset -e\n\npause() {\n    while true; do\n        read -p \"$1 \" yn\n        case $yn in\n            [Yy]* ) break;;\n            [Nn]* ) exit;;\n            * ) echo \"Please answer yes or no.\";;\n        esac\n    done\n}\n\n\n\ncd `dirname $0`/..\nSOURCE=`pwd`\n\n# check if build dir is clean\nif ! [ -f build/.git/HEAD ]; then\n    git clone git@github.com:ajaxorg/ace-builds.git build\nfi\npushd build\ngit fetch\nif [ \"$(git rev-parse --revs-only HEAD)\" != \"$(git rev-parse --revs-only refs/remotes/origin/master)\" ]; then \n    echo build directory not clean; \n    exit 1\nfi\nif [ \"$(git ls-files --others --exclude-standard)\" ];  then\n    echo untracked files;\n    git ls-files --others --exclude-standard\n    exit 1\nfi\npopd\n\n# clean untracked files from modes and themes\nwhile read line; do\n    if [ -f \"$line\" ]; then\n        mkdir -p \"_$(dirname \"$line\")\"; \n        echo \"$line\"; \n        mv \"$line\" \"_$line\";\n    fi\ndone <<< \"$(git ls-files --others --exclude-standard lib/ace)\"\n\n\n# show history\ngit checkout refs/remotes/origin/master -- package.json\nCUR_VERSION=`node -e 'console.log(require(\"./package.json\").version)'`\ngit --no-pager log --color --first-parent --oneline v$CUR_VERSION..master | \n    sed -e s\"/^/https:\\/\\/github.com\\/ajaxorg\\/ace\\/commit\\//\"\necho \"current version is $CUR_VERSION\"\n\n# get new version number\ngit checkout -- package.json\ngit checkout -- CHANGELOG.md\nnpm run changelog\nVERSION_NUM=\"$(node -p \"require('./package.json').version\")\";\necho \"recommended version number for the build is\" $VERSION_NUM \n\nread -p \"do you want to continue with the recommended version number? [y/n] \" yn\n\nif [[ $yn == \"n\" ]]; then \n    read -p \"what should the new version be? (Example: 1.2.3) \" VERSION_NUM \nfi\n\n# update version number everywhere\nnode -e \"\n    var fs = require('fs');\n    var version = '$VERSION_NUM';\n    function replaceVersion(str) {\n        return str.replace(/(['\\\"]?version['\\\"]?\\s*[:=]\\s*['\\\"])[\\\\d.\\\\w\\\\-]+(['\\\"])/, function(_, m1, m2) {\n            return m1 + version + m2;\n        });\n    }\n    function update(path, replace) {\n        var pkg = fs.readFileSync(path, 'utf8');\n        pkg = (replace || replaceVersion)(pkg);\n        fs.writeFileSync(path, pkg, 'utf8');\n    }\n    update('package.json');\n    update('build/package.json');\n    update('./src/config.js');\n    update('ace.d.ts');\n    update('./types/ace-modules.d.ts');\n\"\n\npause \"versions updated to $VERSION_NUM. do you want to start build script? [y/n]\"\n\nnode Makefile.dryice.js full\ncd build\ngit add .\ngit commit --all -m \"package `date +%d.%m.%y`\"\n\n\necho \"build task completed.\"\npause \"continue creating the tag for v$VERSION_NUM [y/n]\"\nif [[ ${VERSION_NUM} != *\"-\"* ]]; then\n    git tag \"v\"$VERSION_NUM\nfi\n\npause \"continue pushing to github? [y/n]\"\n\ngit push --progress \"origin\" HEAD:gh-pages HEAD:master refs/tags/\"v\"$VERSION_NUM:refs/tags/\"v\"$VERSION_NUM\n\necho \"build repository updated\"\n\npause \"continue update ace repo? [y/n]\"\ncd ..\n\ngit commit -a -m \"release v$VERSION_NUM\"\n\necho \"new commit added\"\npause \"continue creating the tag for v$VERSION_NUM [y/n]\"\nif [[ ${VERSION_NUM} != *\"-\"* ]]; then\n    git tag \"v\"$VERSION_NUM\nfi\n\npause \"continue pushing to github? [y/n]\"\n\ngit push --progress \"origin\" HEAD:master refs/tags/\"v\"$VERSION_NUM:refs/tags/\"v\"$VERSION_NUM\n\n\npause \"update api docs [y/n]\"\nbash tool/release-api-docs.sh\n\necho \"All done!\"\npause \"May I go now? [y/n]\"\n\n"
  },
  {
    "path": "tool/templates/dummy.JSON-tmLanguage",
    "content": "// [PackageDev] target_format: plist, ext: tmLanguage\n{ \n\t\"name\": \"Dummy\",\n  \t\"scopeName\": \"source.dummy\",\n  \t\"fileTypes\": [\"dummy\"],\n  \t\"patterns\": [\n\t    {\n            \"include\": \"#string\"\n        }, {\n            \"include\": \"#escapes\"\n        }\n  \t],\n  \t\"repository\": {\n  \t\t\"escapes\": {\n            \"patterns\": [\n  \t\t\t\t{\n                    \"match\": \"\\\\\\\\[nrt\\\\\\\\\\\\$\\\\\\\"']\", \n                    \"name\": \"keyword.dummy\"\n                }\n            ]\n        },\n        \"string\": {\n        \t\"beginCaptures\": {\n                \"0\": {\n                    \"name\": \"punctuation.definition.string.begin.dummy\"\n                }\n            }, \n            \"endCaptures\": {\n                \"0\": {\n                    \"name\": \"punctuation.definition.string.end.dummy\"\n                }\n            }, \n            \"contentName\": \"meta.string-contents.quoted.double.dummy\", \n            \"name\": \"string.quoted.double.dummy\", \n            \"end\": \"'''\", \n            \"begin\": \"'''\", \n            \"patterns\": [\n                {\n                    \"include\": \"#escapes\"\n                }\n            ], \n            \"comment\": \"This is a comment\"\n        }\n  \t}\n}"
  },
  {
    "path": "tool/templates/highlight_rules.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/* This file was autogenerated from %name% (uuid: %uuid%) */\n/****************************************************************************************\n * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *\n * fileTypes                                                                            *\n ****************************************************************************************/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\n\nvar %language%HighlightRules = function() {\n    // regexp must not have capturing parentheses. Use (?:) instead.\n    // regexps are ordered -> the first match is used\n\n    this.$rules = %languageTokens%\n    \n    this.normalizeRules();\n};\n\n%language%HighlightRules.metaData = %metaData%\n\n\noop.inherits(%language%HighlightRules, TextHighlightRules);\n\nexports.%language%HighlightRules = %language%HighlightRules;"
  },
  {
    "path": "tool/templates/mode.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2012, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*\n  THIS FILE WAS AUTOGENERATED BY mode.tmpl.js\n*/\n\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar TextMode = require(\"./text\").Mode;\nvar %language%HighlightRules = require(\"./%languageHighlightFilename%_highlight_rules\").%language%HighlightRules;\n// TODO: pick appropriate fold mode\nvar FoldMode = require(\"./folding/cstyle\").FoldMode;\n\nvar Mode = function() {\n    this.HighlightRules = %language%HighlightRules;\n    this.foldingRules = new FoldMode();\n};\noop.inherits(Mode, TextMode);\n\n(function() {\n    // this.lineCommentStart = \"%lineCommentStart%\";\n    // this.blockComment = {start: \"%blockCommentStart%\", end: \"%blockCommentEnd%\"};\n    // Extra logic goes here.\n    this.$id = \"ace/mode/%languageHighlightFilename%\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;"
  },
  {
    "path": "tool/templates/snippets.js",
    "content": "\"use strict\";\n\nexports.snippetText = require(\"../requirejs/text!./%modeName%.snippets\");\nexports.scope = \"%modeName%\";"
  },
  {
    "path": "tool/templates/theme.css",
    "content": "/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: %uuid%) */\n\n.%cssClass% .ace_gutter {\n  background: %gutterBg%;\n  color: %gutterFg%;\n}\n\n.%cssClass% .ace_print-margin {\n  width: 1px;\n  background: %printMargin%;\n}\n\n.%cssClass% {\n  background-color: %background%;\n  color: %foreground%;\n}\n\n.%cssClass% .ace_cursor {\n  color: %cursor%;\n}\n\n.%cssClass% .ace_marker-layer .ace_selection {\n  background: %selection%;\n}\n\n.%cssClass%.ace_multiselect .ace_selection.ace_start {\n  box-shadow: 0 0 3px 0px %background%;\n  border-radius: 2px;\n}\n\n.%cssClass% .ace_marker-layer .ace_step {\n  background: %step%;\n}\n\n.%cssClass% .ace_marker-layer .ace_bracket {\n  margin: -1px 0 0 -1px;\n  border: 1px solid %bracket%;\n}\n\n.%cssClass% .ace_marker-layer .ace_active-line {\n  background: %active_line%;\n}\n\n.%cssClass% .ace_gutter-active-line {\n  background-color: %active_line%;\n}\n\n.%cssClass% .ace_marker-layer .ace_selected-word {\n  %selected_word_highlight%\n}\n\n.%cssClass% .ace_fold {\n    background-color: %fold%;\n    border-color: %foreground%;\n}\n\n\n\n\n\n"
  },
  {
    "path": "tool/templates/theme.js",
    "content": "/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n\nexports.isDark = %isDark%;\nexports.cssClass = \"%cssClass%\";\nexports.cssText = %css%;\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass, false);\n"
  },
  {
    "path": "tool/test-ace-builds-package.sh",
    "content": "#!/bin/bash\nset -euxo pipefail\n\ncd \"$(dirname \"$0\")/..\"\nREPO_ROOT=\"$(pwd)\"\n\nnpm install\n\nrm -rf ../ace-builds\nnode ./Makefile.dryice.js full --target ../ace-builds\n\ncat > ../ace-builds/package.json <<'EOF'\n{\n    \"name\": \"ace-builds\",\n    \"main\": \"./src-noconflict/ace.js\",\n    \"typings\": \"ace.d.ts\",\n    \"version\": \"1.38.0\",\n    \"description\": \"Ace (Ajax.org Cloud9 Editor)\",\n    \"scripts\": {\n        \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n    },\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/ajaxorg/ace-builds.git\"\n    },\n    \"author\": \"\",\n    \"license\": \"BSD-3-Clause\",\n    \"bugs\": {\n        \"url\": \"https://github.com/ajaxorg/ace-builds/issues\"\n    },\n    \"homepage\": \"https://github.com/ajaxorg/ace-builds\"\n}\nEOF\n\ncd ../ace-builds\nnpm pack\n\nrm -f \"$REPO_ROOT/ace-builds-latest.tgz\"\n\nPACKAGE_FILE=$(ls ace-builds-*.tgz | sort -V | tail -n 1)\n\nmv \"$PACKAGE_FILE\" \"$REPO_ROOT/ace-builds-latest.tgz\"\n\ncd \"$REPO_ROOT/demo/test_ace_builds\"\n\nrm -rf node_modules\nrm -f package-lock.json\n\nnpm install \"$REPO_ROOT/ace-builds-latest.tgz\"\n\nnpm i typescript@latest\n\nrm -f index.js\nnpm run build\nnpm run test\n\ncd \"$REPO_ROOT\"\nrm -f ace-builds-latest.tgz"
  },
  {
    "path": "tool/test-npm-package.sh",
    "content": "#!/bin/bash\nset -euxo pipefail\n\n# Navigate to the ace repository root\ncd \"$(dirname \"$0\")/..\"\n\n# npm pack the ace repository\nnpm pack\n\nrm -f ace-code-latest.tgz\n\n# Get the name of the packed file\nPACKAGE_FILE=$(ls ace-*.tgz | sort -V | tail -n 1)\n\nmv \"$PACKAGE_FILE\" ace-code-latest.tgz\n\n\ncd demo/test_package\n\n# Clean up previous installation\nrm -rf node_modules\nrm -f package-lock.json\n\n\n# Install the ace package from the npm pack result\nnpm i ../../ace-code-latest.tgz \n\n# Install TypeScript\nnpm i typescript@latest\nrm -f index.js \nnpm run build\nnpm run test\n\n# Install old version of TypeScript\nnpm i typescript@3.7\nrm -f index.js \nnpm run build\nnpm run test\n\n# Clean up\ncd ../..\nrm ace-code-latest.tgz\n"
  },
  {
    "path": "tool/tmlanguage.js",
    "content": "require(\"amd-loader\");\n\nvar fs = require(\"fs\");\nvar util = require(\"util\");\nvar lib = require(\"./lib\");\nvar pathlib = require(\"path\");\nvar parseLanguage = lib.parsePlist;\n\nvar tk = require(\"./regexp_tokenizer\");\nvar tokenize = tk.tokenize;\nvar toStr = tk.toStr;\n\nfunction last(array) {return array[array.length - 1]}\n\nfunction convertHexEscape(tokens) {\n    var inChClass = false;\n    tokens.forEach(function(t) {\n        if (t.type == \"charclass\")\n            inChClass = true;\n        else if (t.type == \"charclass.end\")\n            inChClass = false;\n        else if (t.type == \"charType\"){\n            if (t.value == \"\\\\h\") {\n                t.type = \"text\";\n                t.value = inChClass ? \"\\\\da-fA-F\" : \"[\\\\da-fA-F]\";\n            }\n            else if (t.value == \"\\\\H\") {\n                if (inChClass) {\n                    console.warn(\"can't convert \\\\H in charclass\");\n                    return;\n                }\n                t.type = \"text\";\n                t.value = \"[^\\\\da-fA-F]\";\n            }\n        }\n    });\n    return tokens;\n}\n\nfunction convertNewLinesTo$(str) {\n    var tokens = tokenize(str);\n    for (var i = 0; i < tokens.length; i++) {\n        var t= tokens[i];\n        if (t.type == \"char\" && t.value == \"\\\\n\") {\n            var p = tokens[i + 1] || {};\n            if (p.type != \"quantifier\") {\n                t.value = \"$\";\n                while (p.value == \"\\\\n\" || p.type == \"quantifier\") {\n                    p.value = \"\";\n                    p = tokens[++i + 1] || {};\n                }\n            } else if (/\\?|\\*|{,|{0,/.test(p.value)) {\n                t.value = p.value = \"\";\n            } else\n                p.value = \"\";\n        }\n    }\n    return toStr(tokens).replace(/[$]+/g, \"$\");\n}\n\nfunction convertCharacterTypes(str) {\n    var tokens = tokenize(str);\n    tokens = convertHexEscape(tokens);\n\n    var warn = false;\n    tokens.forEach(function(t){\n        if (t.type == \"quantifier\") {\n            var val = t.value;\n            if (val.slice(-1) == \"+\" && val.length > 1) {\n                t.value = val.slice(0, -1);\n                warn = val;\n            }\n        }\n    });\n    if (warn)\n        console.log(\"converted possesive quantifier \" + warn + \" to *\");\n    return toStr(tokens);\n}\n\nfunction removeInlineFlags(str, rule) {\n    var tokens = tokenize(str);\n    var caseInsensitive = false;\n    tokens.forEach(function(t, i) {\n        if (t.type == \"group.start\" && /[imsx]/.test(t.value)) {\n            if (/i/.test(t.value))\n                caseInsensitive = true;\n            t.value = t.value.replace(/[imsx\\-]/g, \"\");\n            var next = tokens[i + 1];\n            if (next && next.type == \"group.end\") {\n                t.value = next.value = \"\";\n            }\n        }\n    });\n    if (caseInsensitive && rule)\n        rule.caseInsensitive = true;\n    return toStr(tokens);\n}\n\nfunction convertToNonCapturingGroups(str) {\n    var tokens = tokenize(str);\n    tokens.forEach(function(t, i) {\n        if (t.type == \"group.start\" && t.value == \"(\")\n            t.value += \"?:\";\n    });\n    return toStr(tokens);\n}\n\nfunction simplifyNonCapturingGroups(str) {\n    var tokens = tokenize(str);\n    var t = tokens[0] || {};\n    if (t.type == \"group.start\" && t.value == \"(?:\"\n        && t.end == last(tokens)) {\n        t.value = t.end.value = \"\";\n    }\n    var i = 0;\n    function iter(f) {\n        for (i = 0; i < tokens.length; i++)\n            f(tokens[i]);\n    }\n    function iterGroup(end, f) {\n        for (var i1 = i + 1; i1 < tokens.length; i1++) {\n            var t = tokens[i1];\n            if (t == end)\n                break;\n            var index = f && f(t);\n            if (index > i1)\n                i1 = index;\n        }\n        return i1;\n    }\n\n    iter(function (t) {\n        if (t.type == \"group.start\" && t.value == \"(?:\") {\n            if (!t.end)\n                return console.error(\"malformed regex: \" + str);\n\n            var canRemove = true;\n            var next = tokens[tokens.indexOf(t.end, i) + 1];\n            if (next && next.type == \"quantifier\")\n                return;\n            iterGroup(t.end, function(t) {\n                if (t.type == \"alternation\")\n                    canRemove = false;\n                else if (t.type == \"group.start\" && t.end)\n                    return iterGroup(t.end);\n            });\n            if (canRemove)\n                t.value = t.end.value = \"\";\n        }\n    });\n\n    return toStr(tokens);\n}\n\nfunction removeLookBehinds(str) {\n    var tokens = tokenize(str);\n    var toRemove = null;\n    tokens.forEach(function(t, i) {\n        if (!toRemove && t.type == \"group.start\" && /</.test(t.value)) {\n            toRemove = t.end;\n            toRemove.content = [];\n        }\n        if (toRemove) {\n            toRemove.content.push(t.value);\n            t.value = \"\";\n        }\n        if (t == toRemove) {\n            var c = toRemove.content.slice(1, -1).join(\"\");\n            if (/\\^/.test(c))\n                toRemove.value = \"(?:\" + c +\")\";\n\n            toRemove = null;\n        }\n    });\n    return toStr(tokens);\n}\n\nfunction convertBeginEndBackrefs(rule) {\n    if (!/\\\\\\d/.test(rule.end))\n        return;\n    var startTokens = tokenize(rule.begin);\n    var endTokens = tokenize(rule.end);\n\n\n    var groups = {};\n    startTokens.forEach(function(t, i) {\n        if (t.number && t.end && t.type == \"group.start\") {\n            var endIndex = startTokens.indexOf(t.end, i + 1);\n            var content = startTokens.slice(i+1, endIndex);\n            groups[t.number] = toStr(content);\n        }\n    });\n\n    endTokens.forEach(function(t) {\n        if (t.type == \"backRef\") {\n            var num = t.value.substr(1);\n            if (groups[num])\n                t.value = \"(?:\" + groups[num] + \")\";\n        }\n    });\n\n    rule.end = toStr(endTokens);\n\n    console.warn(\"Begin-End-Backreference is detected\", rule);\n}\n\nfunction checkForNamedCaptures(str) {\n    var tokens = tokenize(str);\n    tokens.forEach(function(t) {\n        if (t.type == \"group.start\" && t.name)\n            console.warn(\"named capture not implemented\", str);\n        if (t.type == \"backRef\")\n            console.warn(\"backRef not implemented \", str);\n    });\n}\n\nfunction fixGroups(captures, defaultName, regex) {\n    var tokens = tokenize(regex);\n\n    var opened = [], isStart = true, i = 0;\n    function open() {\n        var t = {value: \"(\", type: \"group.start\", isGroup: true};\n        opened.push(t);\n        tokens.splice(i++, 0, t);\n    }\n    function close() {\n        var t = {value: \")\", type: \"group.start\"};\n        t.start = opened.pop();\n        t.start.end = t;\n        tokens.splice(i++, 0, t);\n    }\n    function tryOpen(){if (isStart) {open(); isStart = false}}\n    function tryClose(){if (opened.length) close()}\n    function skip(t) {\n        var i1 = tokens.indexOf(t.end, i);\n        if (i1 > i)\n            i = i1;\n    }\n    function lst(t) {return t[t.length - 1]}\n    function iter(f) {\n        for (i = 0; i < tokens.length; i++)\n            f(tokens[i]);\n    }\n    function iterGroup(end, f) {\n        for (var i1 = i + 1; i1 < tokens.length; i1++) {\n            var t = tokens[i1];\n            if (t == end)\n                break;\n            f(t);\n        }\n    }\n    function peek() { return tokens[i + 1] || {}}\n\n    // groupify\n    iter(function(t){\n        if (t.type == \"group.start\") {\n            tryClose();\n            isStart = true;\n            if (!t.hasChildren || t.isSpecial)\n                skip(t);\n        } else if (t.type == \"group.end\") {\n            isStart = true;\n            tryClose();\n        } else if (t.type == \"alternation\") {\n            isStart = true;\n            tryClose();\n        } else if (t.type != \"anchor\" && t.type != \"quantifier\"){\n            tryOpen();\n        }\n    });\n    tryClose();\n\n    // remove redundand groups\n    var names = [defaultName];\n    iter(function(t){\n        if (t.type == \"group.start\" && !t.isSpecial) {\n            var captureName = captures[t.number];\n\n            if (!t.hasChildren) {\n                t.tokenName = captureName || lst(names);\n                skip(t);\n            }  else {\n                var hasCapture = false;\n                iterGroup(t.end, function(t1) {\n                    if (t1.type == \"group.start\" && captures[t1.number])\n                        hasCapture = true;\n                });\n                if (hasCapture) {\n                    t.value = \"(?:\";\n                    if (captureName) {\n                        names.push(captureName);\n                        t.isTokenGroup = true;\n                    }\n                } else {\n                    t.tokenName = captureName || lst(names);\n                    iterGroup(t.end, function(t1) {\n                        if (t1.value == \"(\")\n                            t1.value = \"(?:\";\n                    });\n                }\n            }\n        } else if (t.type == \"group.end\") {\n            if (t.start.isTokenGroup)\n                names.pop();\n        }\n    });\n\n    // wrap capturing groups with quantifier\n    iter(function(t){\n        if (t.type == \"group.end\" && t.start.value == \"(\" && peek().type == \"quantifier\") {\n            peek().value += \")\";\n            t.start.value += \"(?:\";\n        }\n    });\n\n    names = [];\n    tokens.forEach(function(t) {\n        if (t.value == \"(\" || t.value == \"((?:\" )\n            t.tokenName && names.push(t.tokenName);\n    });\n    return {\n        names: names,\n        regex: toStr(tokens)\n    };\n}\n\n/***** converter */\n\nfunction logDebug(string, obj) {\n    console.log(string, obj);\n}\n\n\n// tmLanguage processor\n\n// for tracking token states\nvar states = {start: []};\n\nfunction processRules(rules){\n    if (rules.patterns)\n        states.start = processPatterns(rules.patterns);\n    if (rules.repository)\n        processRepository(rules.repository);\n    return states;\n}\nfunction processRepository(r) {\n    for (var key in r) {\n        var p = r[key];\n        if (p.begin)\n            var stateObj = [processPattern(r[key])];\n        else if (p.patterns && !p.repository)\n            var stateObj = processPatterns(p.patterns);\n        else\n            var stateObj = [processPattern(r[key])];\n\n        if (stateObj)\n            states[\"#\" + key] = stateObj;\n    }\n}\nfunction processPatterns(pl) {\n    return pl.map(processPattern);\n}\nfunction processPattern(p) {\n    if (p.end == \"(?!\\\\G)\" && p.patterns && p.patterns.length == 1) {\n        var rule = processPattern(p.patterns[0]);\n    }\n    else if (p.begin != null && p.end != null) {\n        convertBeginEndBackrefs(p);\n\n        var rule = simpleRule(p.begin, p.name, p.beginCaptures || p.captures);\n\n        var next = processPatterns(p.patterns || []);\n        var endRule = simpleRule(p.end, p.name, p.endCaptures || p.captures);\n        endRule.next = \"pop\";\n        if (p.applyEndPatternLast)\n            next.push(endRule);\n        else\n            next.unshift(endRule);\n\n        if (p.name || p.contentName)\n            next.push({defaultToken: p.name || p.contentName});\n\n        rule.push = next;\n\n        rule = removeIncludeSelf(rule);\n    }\n    else if (p.match) {\n        var rule = simpleRule(p.match, p.name, p.captures);\n    }\n    else if (p.include) {\n        var rule =  {include: p.include};\n    }\n    else {\n        var rule =  {todo: p};\n    }\n\n    if (p.comment)\n        rule.comment = (rule.comment || \"\") +  p.comment;\n\n    if (p.repository)\n        processRepository(p.repository);\n    return rule;\n}\nfunction simpleRule(regex, name, captures) {\n    name = name || \"text\";\n    var rule = {token: \"\", regex: \"\"};\n\n    var origRegex = regex;\n    regex = transformRegExp(origRegex, rule);\n    if (captures) {\n        var tokenArray = [];\n        Object.keys(captures).forEach(function(x){\n            tokenArray[x] = captures[x] && captures[x].name;\n        });\n\n        if (tokenArray.length == 1) {\n            name = tokenArray[0];\n        } else {\n            var fixed = fixGroups(tokenArray, name, regex);\n            name = fixed.names;\n            regex = fixed.regex;\n            if (name.length == 1)\n                name = name[0];\n        }\n    }\n\n    if (typeof name == \"string\")\n        regex = convertToNonCapturingGroups(regex);\n\n    regex = simplifyNonCapturingGroups(regex);\n\n    try {new RegExp(regex);} catch(e) {\n        rule.TODO = \"FIXME: regexp doesn't have js equivalent\";\n        rule.originalRegex = origRegex;\n\n        // lookbehinds are mostly used to force ordering\n        // regex = removeLookBehinds(regex);\n    }\n    rule.token = name;\n    rule.regex = regex;\n    return rule;\n}\n\nfunction removeIncludeSelf(rule) {\n    if (!rule.push)\n        return rule;\n    var hasSelfInclude = false;\n    var escapeRule = null;\n    var complexSelfInclude = false;\n    rule.push.forEach(function(sub) {\n        if (sub.include == \"$self\") {\n            hasSelfInclude = true;\n        } else if (sub.defaultToken) {\n            return;\n        } else if (sub.next == \"pop\") {\n            escapeRule = sub;\n        } else\n            complexSelfInclude = true;\n    });\n\n    if (hasSelfInclude) {\n        console.warn(\"can't convert include $self\");\n        return {todo: rule};\n        \n        if (complexSelfInclude) {\n            console.warn(\"can't convert include $self\");\n            rule.toDo = \"include $self not fully supported\";\n            return rule;\n        }\n        console.warn(\"include $self not fully supported\");\n        delete rule.push;\n        delete escapeRule.next;\n        rule.includeSelf = true;\n        escapeRule.includeSelf = true;\n        return [rule, escapeRule];\n    }\n    return rule;\n}\n\n// regex transformation\n\nfunction removeXFlag(str) {\n    var tokens = tokenize(str);\n    return toStr(tokens);\n}\n\nfunction transformRegExp(str, rule) {\n    str = convertNewLinesTo$(str);\n\n    str = removeInlineFlags(str, rule);\n\n    str = str.replace(/(\\\\[xu]){([a-fA-F\\d]+)}/g, '$1$2');\n\n    str = convertCharacterTypes(str);\n\n    checkForNamedCaptures(str);\n\n    return str;\n}\n\n//\nfunction extractPatterns(tmRules) {\n    return  processRules(tmRules);\n}\n\n\nfunction detectLoops(states) {\n    var data = {};\n    var keys = Object.keys(states);\n    var flattenedStates = {};\n    function addRef(item, name) {\n        if (item.refs.indexOf(name) == -1)\n            item.refs.push(name);\n    }\n    function anonStateId(name, next) {\n        var i = 0, old = name;\n        while (flattenedStates[name] || states[name]) {\n            name = old + \"_\" + i++;\n        }\n        // console.log(old, name)\n        return name;\n    }\n    function addState(key, rules) {\n        if (rules && !flattenedStates[key])\n            flattenedStates[key] = rules;\n        return rules || flattenedStates[key];\n    }\n    \n    \n    for (var i = 0; i < keys.length; i++) {\n        var key = keys[i];\n        var state = addState(key, states[key]);\n        \n        var item = data[key] || (data[key] = {/* name: key, */ refs: []});\n        state.forEach(function(rule) {\n            var next = rule.push || rule.next;\n            if (next == \"pop\") {\n                // nothing\n            } else if (typeof next == \"string\") {\n                addRef(item, next);\n            } else if (next) {\n                var anonId = anonStateId(key, next);\n                addState(anonId, next);\n                if (rule.push)\n                    addRef(item, anonId);\n                keys.push(anonId);\n            } else if (rule.include) {\n                addRef(item, rule.include);\n            }\n        });\n    }\n    \n    \n    var cycles = [];\n    function addPath(start, path) {\n        var node = data[start];\n        path.push(start);\n        if (!node || !node.refs)\n            console.log(start);\n        var i = path.indexOf(start);\n        if (i > -1 && i != path.length - 1 || start == \"$self\" || start == \"$base\") {\n            if (i != -1)\n                path = path.slice(i);\n            for (var j = 0; j < cycles.length; j++) {\n                if (cycles[j] + \"\" == path + \"\")\n                    return;\n            }\n            return cycles.push(path);\n        }\n        \n        if (!node || !node.refs || !node.refs.length || path.length>30)\n            return;\n        node.refs.forEach(function(x) {\n            addPath(x, path.concat());\n        });\n    }\n    addPath(\"start\", []);\n    \n    console.error(cycles.join(\"\\n\"));\n}\n\n\nfunction test(fileName) {\n    console.log(\"testing highlighter\");\n    try {\n        var module = require(fileName);\n        var Mode = module[Object.keys(module)[0]];\n        var mode = new Mode();\n        mode.getTokenizer().getLineTokens(\"hello world\");\n    } catch(e) {\n        console.log(e);\n    }\n}\n\nfunction guessComment(patterns) {\n    var comment = {};\n    for (var i in patterns) {\n        var state = patterns[i];\n        state.forEach(function(r) {\n            if (typeof r.token == \"string\") {\n                if (/\\bcomment\\b/.test(r.token)) {\n                    comment.line = r.regex;\n                }\n            }\n        });\n    }\n\n    return comment;\n}\n\n// cli stuff\nvar modeTemplate = fs.readFileSync(__dirname + \"/templates/mode.js\", \"utf8\");\nvar modeHighlightTemplate = fs.readFileSync(__dirname + \"/templates/highlight_rules.js\", \"utf8\");\n\nfunction fetchAndConvert(name) {\n    console.log(\"Converting \" + name);\n    if (/^http/.test(name)) {\n        if (/:\\/\\/github.com/.test(name)) {\n            name = name.replace(/\\/blob\\//, \"/\").replace(\"github.com\", \"raw.github.com\");\n        }\n        return lib.download(name, function(data) {\n            convertTmLanguage(name, data);\n        });\n    }\n    var path = /^(\\/|\\w:)/.test(name) ? name : process.cwd() + \"/\" + name;\n    var langStr = fs.readFileSync(path, \"utf8\");\n    convertTmLanguage(name, langStr);\n}\n\n\nfunction convertTmLanguage(name, langStr) {\n    parseLanguage(langStr, function(language) {\n        var highlighterFilename = lib.snakeCase(language.name).replace(/[^\\w]/g, \"\");\n        var languageNameSanitized = lib.camelCase(language.name).replace(/[^\\w]/g, \"\");\n        \n        require(\"./add_mode\")(languageNameSanitized, (language.fileTypes || []).join(\"|\"));\n\n        var highlighterFile = pathlib.normalize(lib.AceRoot + \"src/mode/\" + highlighterFilename + \"_highlight_rules.js\");\n        var modeFile = pathlib.normalize(lib.AceRoot + \"src/mode/\" + highlighterFilename + \".js\");\n\n        if (devMode) {\n            console.log(util.inspect(language.patterns, false, 4));\n            console.log(util.inspect(language.repository, false, 4));\n        }\n\n        var patterns = extractPatterns(language);\n        detectLoops(patterns);\n        \n        // var uuid = language.uuid\n        delete language.uuid;\n        delete language.patterns;\n        delete language.repository;\n\n        var comment = guessComment(patterns);\n        var languageMode = lib.fillTemplate(modeTemplate, {\n            language: languageNameSanitized,\n            languageHighlightFilename: highlighterFilename,\n            lineCommentStart: JSON.stringify(comment.line || \"//\"),\n            blockCommentStart: JSON.stringify(comment.start || \"/*\"),\n            blockCommentEnd: JSON.stringify(comment.end || \"*/\")\n        });\n\n        var languageHighlightRules = lib.fillTemplate(modeHighlightTemplate, {\n            language: languageNameSanitized,\n            languageTokens: lib.formatJS(patterns, \"    \").trim(),\n            uuid: language.uuid,\n            name: name,\n            metaData: lib.formatJS(language, \"\").trim()\n        });\n\n        if (devMode) {\n            console.log(languageMode);\n            console.log(languageHighlightRules);\n            console.log(\"Not writing, 'cause we're in dev mode, baby.\");\n        }\n        else {\n            fs.writeFileSync(highlighterFile, languageHighlightRules);\n            fs.writeFileSync(modeFile, languageMode);\n            console.log(\"created file \" + highlighterFile);\n            test(modeFile);\n        }\n    });\n}\n\nif (!module.parent) {\n    var args = process.argv.splice(2);\n    var devMode = args[0] == \"--dev\";\n    if (devMode)\n        args.shift();\n    if (args.length < 1) {\n        console.error(\"Usage: node tmlanguage.js [--dev] path/or/url/to/syntax.file ...\");\n        process.exit(1);\n    }\n    args.forEach(fetchAndConvert);\n} else {\n    exports.fetchAndConvert = fetchAndConvert;\n}\n"
  },
  {
    "path": "tool/tmsnippets.js",
    "content": "var fs = require('fs')\nvar plist = require('plist')\n\nvar snippets = [];\nvar path = process.argv[2] || process.cwd();\nfunction readSnippet(path, name) {\n    if (name)\n        path += name\n    console.log(name)\n    if (!/\\.(tmSnippet|sublime-snippet|plist)$/i.test(path))\n        return\n    console.log(name)\n    var plistString = fs.readFileSync(path, \"utf8\");\n    plist.parseString(plistString, function(_, plist){\n        snippets.push(plist)\n    })\n}\n\n// read\nfunction readDir(path) {\n    if (fs.statSync(path).isDirectory()) {\n        path += \"/\"\n        fs.readdirSync(path).forEach(function(name) {        \n            if (/snippets/i.test(name))\n                readSnippetsInDir(path + name)\n            else\n                readDir(path + name)\n        })\n    }\n}\nfunction readSnippetsInDir(path) {\n    if (fs.statSync(path).isDirectory()) {\n        path += \"/\"\n        snippets.push(path)\n        fs.readdirSync(path).forEach(function(name) {\n            readSnippet(path, name)\n        })\n    } else {\n        readSnippet(path)\n    }\n}\nreadDir(path) \n// transform\nsnippets = snippets.map(function(s) {\n    if (s.length == 1)\n        s = s[0]\n    if (s.scope)\n        s.scope = s.scope.replace(/source\\./g, \"\")\n    delete s.uuid\n    return s\n})\n\n// stringify\nvar indent = \"\"\nvar text = JSON.stringify(snippets, null, 1)\n    // .replace(/(\\n\\s*)\"(\\w+)\"\\:/g, \"$1$2:\")\n    .replace(/(\\n\\s*)\\},\\n\\s*{/g, \"$1}, {\")\n    .replace(/\\[\\n\\s*\\{\\n/g, \"[{\\n\").replace(/(\\n\\s*)\\}\\n\\s*\\]/g, \"$1}]\")\n    .replace(/\\[\\n\\s*[^\\[\\{\\}\\]]{0,100}\\]/g, function(x){return x.replace(/\\n\\s*/g, \" \")})\n    .replace(/\\:\\s*\\{\\n\\s*(.*)\\n\\s*\\}/g, \": {$1}\")\n    .split(/\\n\\s*/).map(function(x){\n        if (x[0] == \"}\" || x[0] == \"]\")\n            indent = indent.substr(1)\n            \n        if (x.slice(-1) == \"{\" || x.slice(-1) == \"[\") {        \n            indent += \"\\t\"\n            return  indent.substr(1) + x\n        }\n        return indent +x\n    }).join(\"\\n\")\n    .replace(/\\\\[\\\\tnr]/g, function(a){\n        if (a[1] == \"\\\\\")\n            return a\n        else if (a[1] == \"t\")\n            return \"\\t\"\n        else\n            return \"\\\\n\"+\"\\\\\" + \"\\n\"\n    })\n\nfs.writeFileSync(path += \"/./ace.snippets.js\", text)\n\nconsole.log(path)"
  },
  {
    "path": "tool/tmtheme.js",
    "content": "var fs = require(\"fs\");\nvar path = require(\"path\");\nvar util = require(\"util\");\nvar cssParse = require(\"css-parse\");\nvar cssStringify = require(\"css-stringify\");\n\nvar parse = require(\"plist\").parse;\nfunction parseTheme(themeXml, callback) {\n    callback(parse(themeXml));\n}\n\nvar unsupportedScopes = { };\n\nvar supportedScopes = {\n   \"keyword\": \"keyword\",\n   \"keyword.operator\": \"keyword.operator\",\n   \"keyword.other.unit\": \"keyword.other.unit\",\n\n   \"constant\": \"constant\",\n   \"constant.language\": \"constant.language\",\n   \"constant.library\": \"constant.library\",\n   \"constant.numeric\": \"constant.numeric\",\n   \"constant.character\" : \"constant.character\",\n   \"constant.character.escape\" : \"constant.character.escape\",\n   \"constant.character.entity\": \"constant.character.entity\",\n   \"constant.other\" : \"constant.other\",\n\n   \"support\": \"support\",\n   \"support.function\": \"support.function\",\n   \"support.function.dom\": \"support.function.dom\",\n   \"support.function.firebug\": \"support.firebug\",\n   \"support.function.constant\": \"support.function.constant\",\n   \"support.constant\": \"support.constant\",\n   \"support.constant.property-value\": \"support.constant.property-value\",\n   \"support.class\": \"support.class\",\n   \"support.type\": \"support.type\",\n   \"support.other\": \"support.other\",\n\n   \"function\": \"function\",\n   \"function.buildin\": \"function.buildin\",\n\n   \"storage\": \"storage\",\n   \"storage.type\": \"storage.type\",\n\n   \"invalid\": \"invalid\",\n   \"invalid.illegal\": \"invalid.illegal\",\n   \"invalid.deprecated\": \"invalid.deprecated\",\n\n   \"string\": \"string\",\n   \"string.regexp\": \"string.regexp\",\n\n   \"comment\": \"comment\",\n   \"comment.documentation\": \"comment.doc\",\n   \"comment.documentation.tag\": \"comment.doc.tag\",\n\n   \"variable\": \"variable\",\n   \"variable.language\": \"variable.language\",\n   \"variable.parameter\": \"variable.parameter\",\n\n   \"meta\": \"meta\",\n   \"meta.tag.sgml.doctype\": \"xml-pe\",\n   \"meta.tag\": \"meta.tag\",\n   \"meta.selector\": \"meta.selector\",\n   \n   \"entity.other.attribute-name\": \"entity.other.attribute-name\",\n   \"entity.name.function\": \"entity.name.function\",\n   \"entity.name\": \"entity.name\",\n   \"entity.name.tag\": \"entity.name.tag\",\n\n   \"markup.heading\": \"markup.heading\",\n   \"markup.heading.1\": \"markup.heading.1\",\n   \"markup.heading.2\": \"markup.heading.2\",\n   \"markup.heading.3\": \"markup.heading.3\",\n   \"markup.heading.4\": \"markup.heading.4\",\n   \"markup.heading.5\": \"markup.heading.5\",\n   \"markup.heading.6\": \"markup.heading.6\",\n   \"markup.list\": \"markup.list\",\n\n   \"collab.user1\": \"collab.user1\"\n};\n\nvar fallbackScopes = {\n    \"keyword\": \"meta\",\n    \"support.type\": \"storage.type\",\n    \"variable\": \"entity.name.function\"\n};\n\n// Taken from .ace-tm\nvar defaultGlobals = {\n    \"printMargin\": \"#e8e8e8\",\n    \"background\": \"#ffffff\",\n    \"foreground\": \"#000000\",\n    \"gutter\": \"#f0f0f0\",\n    \"selection\": \"rgb(181, 213, 255)\",\n    \"step\": \"rgb(198, 219, 174)\",\n    \"bracket\": \"rgb(192, 192, 192)\",\n    \"active_line\": \"rgba(0, 0, 0, 0.07)\",\n    \"cursor\": \"#000000\",\n    \"invisible\": \"rgb(191, 191, 191)\",\n    \"fold\": \"#6b72e6\"\n};\n\nfunction extractStyles(theme) {\n    var globalSettings = theme.settings[0].settings;\n\n    var colors = {\n        \"printMargin\": defaultGlobals.printMargin,\n        \"background\": parseColor(globalSettings.background) || defaultGlobals.background,\n        \"foreground\": parseColor(globalSettings.foreground) || defaultGlobals.foreground,\n        \"gutter\": defaultGlobals.gutter,\n        \"selection\": parseColor(globalSettings.selection) || defaultGlobals.selection,\n        \"step\": defaultGlobals.step,\n        \"bracket\": parseColor(globalSettings.invisibles) || defaultGlobals.bracket,\n        \"active_line\": parseColor(globalSettings.lineHighlight) || defaultGlobals.active_line,\n        \"cursor\": parseColor(globalSettings.caret) || defaultGlobals.cursor,\n        \"invisible\": \"color: \" + (parseColor(globalSettings.invisibles) || defaultGlobals.invisible) + \";\"\n    };\n\n    for (var i=1; i<theme.settings.length; i++) {\n        var element = theme.settings[i];\n        if (!element.scope || !element.settings)\n            continue;\n        var scopes = element.scope.split(/\\s*[|,]\\s*/g);\n        for (var j = 0; j < scopes.length; j++) {\n            var scope = scopes[j];\n            var style = parseStyles(element.settings);\n        \n            var aceScope = supportedScopes[scope];\n            if (aceScope) {\n                colors[aceScope] = style;\n            }\n            else if (style) {\n                unsupportedScopes[scope] = (unsupportedScopes[scope] || 0) + 1;\n            }\n        }        \n    }\n    \n    for (var i in fallbackScopes) {\n        if (!colors[i])\n            colors[i] = colors[fallbackScopes[i]];\n    }\n\n    if (!colors.fold) {\n        var foldSource = colors[\"entity.name.function\"] || colors.keyword;\n        if (foldSource) {\n            colors.fold = foldSource.match(/\\:([^;]+)/)[1];\n        } else {\n            colors.fold = defaultGlobals.fold;\n        }\n    }\n    \n    colors.gutterBg = colors.background\n    colors.gutterFg = mix(colors.foreground, colors.background, 0.5)\n\n    if (!colors.selected_word_highlight)\n        colors.selected_word_highlight =  \"border: 1px solid \" + colors.selection + \";\";\n\n    colors.isDark = (luma(colors.background) < 0.5) + \"\";\n    \n    return colors;\n};\n\nfunction mix(c1, c2, a1, a2) {\n    c1 = rgbColor(c1);\n    c2 = rgbColor(c2);\n    if (a2 === undefined)\n        a2 = 1 - a1\n    return \"rgb(\" + [\n        Math.round(a1*c1[0] + a2*c2[0]),\n        Math.round(a1*c1[1] + a2*c2[1]),\n        Math.round(a1*c1[2] + a2*c2[2])\n    ].join(\",\") + \")\";\n}\n\nfunction rgbColor(color) {\n    if (typeof color == \"object\")\n        return color;\n    if (color[0]==\"#\")\n        return color.match(/^#(..)(..)(..)/).slice(1).map(function(c) {\n            return parseInt(c, 16);\n        });\n    else\n        return color.match(/\\(([^,]+),([^,]+),([^,]+)/).slice(1).map(function(c) {\n            return parseInt(c, 10);\n        });\n}\nfunction luma(color) {\n    var rgb = rgbColor(color);\n    return (0.21 * rgb[0] + 0.72 * rgb[1] + 0.07 * rgb[2]) / 255;\n}\n\nfunction parseColor(color) {\n    if (!color.length) return null;\n    if (color.length == 4)\n        color = color.replace(/[a-fA-F\\d]/g, \"$&$&\");\n    if (color.length == 7)\n        return color;\n    else {\n        if (!color.match(/^#(..)(..)(..)(..)$/))\n            console.error(\"can't parse color\", color);\n        var rgba = color.match(/^#(..)(..)(..)(..)$/).slice(1).map(function(c) {\n            return parseInt(c, 16);\n        });\n        rgba[3] = (rgba[3] / 0xFF).toPrecision(2);\n        return \"rgba(\" + rgba.join(\", \") + \")\";\n    }\n}\n\nfunction parseStyles(styles) {\n    var css = [];\n    var fontStyle = styles.fontStyle || \"\";\n    if (fontStyle.indexOf(\"underline\") !== -1) {\n        css.push(\"text-decoration:underline;\");\n    }\n    if (fontStyle.indexOf(\"italic\") !== -1) {\n        css.push(\"font-style:italic;\");\n    }\n\n    if (styles.foreground) {\n        css.push(\"color:\" + parseColor(styles.foreground) + \";\");\n    }\n    if (styles.background) {\n        css.push(\"background-color:\" + parseColor(styles.background) + \";\");\n    }\n\n    return css.join(\"\\n\");\n}\n\nfunction fillTemplate(template, replacements) {\n    return template.replace(/%(.+?)%/g, function(str, m) {\n        return replacements[m] || \"\";\n    });\n}\n\nfunction hyphenate(str) {\n    return str.replace(/([A-Z])/g, \"-$1\").replace(/_/g, \"-\").toLowerCase();\n}\n\nfunction quoteString(str) {\n    return '\"' + str.replace(/\\\\/, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\\\n\") + '\"';\n}\n\nvar cssTemplate = fs.readFileSync(__dirname + \"/templates/theme.css\", \"utf8\");\nvar jsTemplate = fs.readFileSync(__dirname + \"/templates/theme.js\", \"utf8\");\n\nfunction normalizeStylesheet(rules) {\n    for (var i = rules.length; i--; ) {\n        var s = JSON.stringify(rules[i].declarations);\n        for (var j = i; j --; ) {\n            if (s == JSON.stringify(rules[j].declarations)) {\n            console.log(rules[j].selectors, rules[i].selectors)\n            console.log(i, j)\n                rules[j].selectors = rules[i].selectors.concat(rules[j].selectors);\n                rules.splice(i, 1);\n                break;\n            }\n        }\n    }\n    for (var i = rules.length; i--; ) {\n        var s = rules[i].selectors.sort();\n        rules[i].selectors = s.filter(function(x, i) {\n            return x && x != s[i + 1];\n        });                \n    }\n    return rules;\n}\n\nvar themes = {\n    //\"chrome\": \"Chrome DevTools\",\n    \"clouds\": \"Clouds\",\n    \"clouds_midnight\": \"Clouds Midnight\",\n    \"cobalt\": \"Cobalt\",\n    //\"crimson_editor\": \"Crimson Editor\",\n    \"dawn\": \"Dawn\",\n    //\"dreamweaver\": \"Dreamweaver\",\n    //\"eclipse\": \"Eclipse\",\n    //\"github\": \"GitHub\",\n    \"idle_fingers\": \"idleFingers\",\n    \"kr_theme\": \"krTheme\",\n    \"merbivore\": \"Merbivore\",\n    \"merbivore_soft\": \"Merbivore Soft\",\n    \"mono_industrial\": \"monoindustrial\",\n    \"monokai\": \"Monokai\",\n    \"nord_dark\": \"Nord Dark\",\n    \"one_dark\": \"One Dark\",\n    \"pastel_on_dark\": \"Pastels on Dark\",\n    \"solarized_dark\": \"Solarized-dark\",\n    \"solarized_light\": \"Solarized-light\",\n    \"katzenmilch\": \"Katzenmilch\",\n    \"kuroir\": \"Kuroir Theme\",\n    \"gruvbox_dark_hard\": \"gruvboxDarkHard\",\n    \"gruvbox_light_hard\": \"gruvboxLightHard\",\n    //\"textmate\": \"Textmate (Mac Classic)\",\n    \"tomorrow\": \"Tomorrow\",\n    \"tomorrow_night\": \"Tomorrow-Night\",\n    \"tomorrow_night_blue\": \"Tomorrow-Night-Blue\",\n    \"tomorrow_night_bright\": \"Tomorrow-Night-Bright\",\n    \"tomorrow_night_eighties\": \"Tomorrow-Night-Eighties\",\n    \"twilight\": \"Twilight\",\n    \"vibrant_ink\": \"Vibrant Ink\",\n    \"xcode\": \"Xcode_default\"\n};\n\nfunction convertBuiltinTheme(name) {\n    return convertTheme(name, __dirname + \"/tmthemes/\" + themes[name] + \".tmTheme\", __dirname + \"/../lib/ace/theme\");\n}\n\nfunction convertTheme(name, tmThemePath, outputDirectory) {\n    console.log(\"Converting \" + name);\n    var tmTheme = fs.readFileSync(tmThemePath, \"utf8\");\n    parseTheme(tmTheme, function(theme) {\n        var styles = extractStyles(theme);\n\n        styles.cssClass = \"ace-\" + hyphenate(name);\n        styles.uuid = theme.uuid;\n        var css = fillTemplate(cssTemplate, styles);\n        css = css.replace(/[^\\{\\}]+{\\s*}/g, \"\");\n        \n        for (var i in supportedScopes) {\n            if (!styles[i])\n                continue;\n            css += \".\" + styles.cssClass + \" \" +\n                i.replace(/^|\\./g, \".ace_\") + \"{\" + styles[i] + \"}\";\n        }\n\n        // we're going to look for NEW rules in the parsed content only\n        // if such a rule exists, add it to the destination file\n        // this way, we preserve all hand-modified rules in the <theme>.css rules,\n        // (because some exist, for collab1 and ace_indentation_guide\n        try {\n            var outThemeCss = fs.readFileSync(outputDirectory + \"/\" + name + \".css\");\n            var oldRules = cssParse(outThemeCss).stylesheet.rules;\n            var newRules = cssParse(css).stylesheet.rules;\n\n\n            for (var i = 0; i < newRules.length; i++) {\n                var newSelectors = newRules[i].selectors;\n\n                for (var j = 0; j < oldRules.length; j++) {\n                    var oldSelectors = oldRules[j].selectors;\n                    newSelectors = newSelectors.filter(function(s) {\n                        return oldSelectors.indexOf(s) == -1;\n                    })\n                    if (!newSelectors.length)\n                        break;\n                }\n                if (newSelectors.length) {\n                    newRules[i].selectors = newSelectors;\n                    console.log(\"Adding NEW rule: \", newRules[i])\n                    oldRules.splice(i, 0, newRules[i]);\n                }\n            }\n            \n            oldRules = normalizeStylesheet(oldRules);\n            \n            css = cssStringify({stylesheet: {rules: oldRules}}, { compress: false });\n        } catch(e) {\n            console.log(\"Creating new file: \" +  name + \".css\")\n            css = cssStringify(cssParse(css), { compress: false });\n        }\n        \n        var js = fillTemplate(jsTemplate, {\n            name: name,\n            css: 'require(\"../requirejs/text!./' + name + '.css\")', // quoteString(css), //\n            cssClass: \"ace-\" + hyphenate(name),\n            isDark: styles.isDark\n        });\n\n        fs.writeFileSync(outputDirectory + \"/\" + name + \".js\", js);\n        fs.writeFileSync(outputDirectory + \"/\" + name + \".css\", css);\n    })\n}\n\nif (process.argv.length > 2) {\n    var args = process.argv.splice(2);\n    if (args.length < 3) {\n        console.error(\"Usage: node tmtheme.js [theme_name, path/to/theme.tmTheme path/to/output/directory]\");\n        process.exit(1);\n    }\n    var name = args[0];\n    var themePath = args[1];\n    var outputDirectory = args[2];\n    convertTheme(name, themePath, outputDirectory);\n} else {\n    for (var name in themes) {\n        convertBuiltinTheme(name);\n    }\n}\n\nif (Object.keys(unsupportedScopes).length > 0) {\n    var sortedUnsupportedScopes = {};\n    for (var u in unsupportedScopes) {\n        var value = unsupportedScopes[u];\n        if (sortedUnsupportedScopes[value] === undefined) {\n            sortedUnsupportedScopes[value] = [];\n        }\n        sortedUnsupportedScopes[value].push(u);\n    }\n    console.log(\"I found these unsupported scopes:\");\n    console.log(sortedUnsupportedScopes);\n    console.log(\"It's safe to ignore these, but they may affect your syntax highlighting if your mode depends on any of these rules.\");\n    console.log(\"Refer to the docs on ace.c9.io for information on how to add a scope to the CSS generator.\");\n}\n\n\n/*** TODO: generate images for indent guides in node\n\nvar indentGuideColor = \"#2D2D2D\"\nvar canvas = document.createElement(\"canvas\")\ncanvas.width = 1; canvas.height = 2;\nvar ctx = canvas.getContext(\"2d\")\nimageData = ctx.getImageData(0,0,1,2)\n\nfunction getColor(color) {\n    ctx.fillStyle = color;\n    ctx.fillRect(0,0,1,2);\n    return Array.slice(ctx.getImageData(0,0,1,2).data).slice(0,4)    \n}\nbgColor = getComputedStyle(ace.renderer.scroller).backgroundColor\nvar a = [].concat(getColor(bgColor), getColor(indentGuideColor));\na.forEach(function(val,i){imageData.data[i] = val})\n\nctx.putImageData(imageData,0,0)\nimage = canvas.toDataURL(\"png\")\n\nvar rule = \".\"+ace.renderer.$theme +\" .ace_indent-guide {\\n\\\n  background: url(\" + image +\") right repeat-y;\\n\\\n}\"\nconsole.log(rule)\nrequire(\"ace/lib/dom\").importCssString(rule)\n\n*/\n"
  },
  {
    "path": "tool/tmthemes/Active4D.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Active4D</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B3B3B</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#BAD6FD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html source.active4d</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#E2E9FF5E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Plain XML text</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.xml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Line comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AF82D4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Block comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment.block</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AF82D4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#666666</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Interpolated entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.interpolated variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66CCFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A8017E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Date/time literal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.other.date, constant.other.time</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66CCFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Local variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other.local</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6392FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0053FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Table/field</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other.table-field</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6988AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#006699</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF5600</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#21439C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#21439C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag container</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7A7A7A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#016CFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#963DFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Command/method</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#45AE34</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Named constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B7734C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#656565</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff line range</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff.range</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#1B63FF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff deleted line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted.diff</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FF7880</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff inserted line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted.diff</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#98FF9A</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff unchanged line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.diff</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5E5E5E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>7D2863D0-473C-47A0-B03B-92880559EBA9</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Amy.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Amy</string>\n\t<key>author</key>\n\t<string>William D. Neumann</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#200020</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#7070FF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D0D0FF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#80000040</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#80000080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment.block</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#200020</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#404080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#707090</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Integer</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7090B0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Int32 constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.integer.int32</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Int64 constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.integer.int64</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Nativeint constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.integer.nativeint</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.floating-point.ocaml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Character constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#666666</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Boolean constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language.boolean</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8080A0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#008080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A080FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A0A0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword decorator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.decorator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D0D0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point infix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.infix.floating-point.ocaml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point prefix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.prefix.floating-point.ocaml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Compiler directives</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.directive</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C080C0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Line-number directives</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.directive.line-number</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C080C0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Control keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.control</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80A0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B0FFF0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.variant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#60B0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Polymorphic variants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type.variant.polymorphic, entity.name.type.variant.polymorphic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#60B0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Module definitions</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.module</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B000B0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Module type definitions</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.module-type.ocaml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B000B0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support modules</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A00050</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#70E080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.class-type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#70E0A0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#50A0A0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80B0B0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Token definition (ocamlyacc)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.token</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3080A0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Token reference (ocamlyacc)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.token.reference</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3CB0D0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Non-terminal definition (ocamlyacc)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function.non-terminal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#90E0E0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Non-terminal reference (ocamlyacc)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function.non-terminal.reference</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C0F0F0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009090</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#200020</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#200020</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid - illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFF00</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#400080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid - depricated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#CC66FF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#200020</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Camlp4 code</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.camlp4.embedded</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#40008054</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Camlp4 temp (parser)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.camlp4.embedded.parser.ocaml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#805080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>3C01FADD-7592-49DD-B7A5-1B82CA4E57B5</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Blackboard.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Blackboard</string>\n\t<key>author</key>\n\t<string>Domenico Carbotta</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0C1021</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFFFFA6</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#FFFFFF40</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#FFFFFF0F</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#253B76</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AEAEAE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D8FA3C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF6400</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FBDE2D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FBDE2D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, meta.verbatim</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#61CE3C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DA6CE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AB2A1D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#9D1E15</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Superclass</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF6400</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant.other.placeholder</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF6400</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>meta.function-call.py</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.function-call.py</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BECDE6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>meta.tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7F90AA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>entity.name.section</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml variant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.type.variant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D5E0F3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml infix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.infix</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DA6CE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml prefix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.prefix</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DA6CE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml f-p infix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.infix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml f-p prefix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.prefix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml f-p constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml constant.numeric.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>LaTeX environment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.tex.latex meta.function.environment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF08</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>LaTeX environment (nested)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.tex.latex meta.function.environment meta.function.environment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#7A96FA08</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Latex support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.tex.latex support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FBDE2D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>PList unquoted string</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.plist string.unquoted, source.plist keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>A2C6BAA7-90D0-4147-BBF5-96B0CD92D109</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Clouds.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Clouds</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#FFFBD1</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#BDD5FC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BCC8BA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5D90CD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#46A609</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#39946A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, support.constant.property-value, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AF956F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword -&gt; Unit</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#96DC5F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword -&gt; Operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#484848</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C52727</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#858585</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#606060</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>HTML Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character.entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BF78CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>JS Support Class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class.js</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BF78CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#606060</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>CSS Selector</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css, entity.name.tag.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C52727</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>CSS Property</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-name.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#484848</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C52727</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FF002A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation/Widgets</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.section.embedded</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C52727</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation (Tags)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.definition.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#606060</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword -&gt; CSS</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.other.color.rgb-value.css, support.constant.property-value.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BF78CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>47536290-6FC1-4B09-A08F-B219909E1A69</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Cobalt.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Jacob Rus</string>\n\t<key>comment</key>\n\t<string>Created by Jacob Rus.  Based on ‘Slate’ by Wilson Miner</string>\n\t<key>name</key>\n\t<string>Cobalt</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#002240</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#FFFFFF26</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000059</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#B36539BF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation - (punctuation.definition.string | punctuation.definition.comment)</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E1EFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF628C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFDD00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF9D00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFEE80</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string -string.unquoted.old-plist -string.unquoted.heredoc, string.unquoted.heredoc string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3AD900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0088FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80FFBB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCCCC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Lang Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF80E1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function Call</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.function-call</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFEE80</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#800F00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded Source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source, string.unquoted.heredoc, source source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#223545</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity inherited-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80FCFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String embedded-source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.quoted source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9EFF80</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80FF82</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String.regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80FFC2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EDEF7D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFB054</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EB939A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF1E00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>C/C++ Preprocessor Line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8996A8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>C/C++ Preprocessor Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AFC4DB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Doctype/XML Processing</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#73817D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Meta.tag.A</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9EFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css tag-name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9EFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css#id</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.id</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFB454</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css.class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5FE461</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property-name:</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.property-name.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9DF39F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property-value;</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F6F080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css @at-rule</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.at-rule keyword.control.at-rule</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F6AA11</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css additional-constants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-value support.constant.named-color.css, meta.property-value constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EDF080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css constructor.argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.constructor.argument.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EB939A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff, meta.diff.header</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#000E1A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#4C0900</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.changed</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.changed</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#806F00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#154F00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Raw Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.raw</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#8FDDF630</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Block Quote</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.quote</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#004480</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#130D26</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Bold Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C1AFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Italic Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.italic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B8FFD9</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Heading Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#001221</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C8E4FD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>06CD1FB2-A00A-4F8C-97B2-60E131980454</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Dawn.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>David Powers</string>\n\t<key>comment</key>\n\t<string>Dawn</string>\n\t<key>name</key>\n\t<string>Dawn</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#F9F9F9</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#080808</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#4B4B7E80</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#2463B41F</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#275FFF4D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5A525F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#811F24</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BF4F24</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#794938</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A71D5D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string | punctuation.definition.string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0B6125</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#691C97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#234A97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation.separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#794938</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B52A1D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B52A1D</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String embedded-source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#6F8BBA26</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#080808</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#696969</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#234A97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String.regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF5628</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String.regexp.«special»</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp.character-class, string.regexp constant.character.escaped, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF5628</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String.regexp constant.character.escape</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp constant.character.escape</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#811F24</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded Source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#6F8BBA26</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#693A17</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B4371F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#234A97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.list</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#693A17</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading | markup.heading entity.name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#19356D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.quote</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.quote</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#BBBBBB30</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0B6125</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.italic</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.italic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#080808</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.bold</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#080808</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.underline</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.underline</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#080808</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.link</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.link</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#234A97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.raw</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.raw</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#BBBBBB30</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#234A97</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#59140E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Meta.separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#DCDCDC</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#19356D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>E7E82498-F9EA-49A6-A0D8-12327EA46B01</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Dreamweaver.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>By Jim Isaacs - jimisaacs.com</string>\n\t<key>name</key>\n\t<string>Dreamweaver</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#5EA0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>text</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>constant numeric</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric - source.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EE000B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>comment general</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9A9A9A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html meta</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html meta.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#00359E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html string</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html.basic meta.tag string.quoted - source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#001EFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html contstant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html.basic constant.character.entity.html</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html a tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html meta.tag.a - string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#106800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html img tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html meta.tag.img - string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6D232E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html form tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html meta.tag.form - string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF9700</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>html table</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html meta.tag.table - string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009079</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js.embedded.html punctuation.definition.tag - source.php, source.js.embedded.html entity.name.tag.script, source.js.embedded entity.other.attribute-name - source.js string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#842B44</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js comment - source.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9A9A9A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js meta function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js meta.function - source.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js instance / support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js meta.class - source.php, source.js support.function - source.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#24C696</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js string</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js string - source.php, source.js keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0035FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7E00B7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js storage (not function) / bool / new / braces</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js storage - storage.type.function - source.php, source.js constant - source.php, source.js keyword - source.php, source.js variable.language, source.js meta.brace, source.js punctuation.definition.parameters.begin, source.js punctuation.definition.parameters.end</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#05208C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>js regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.js string.regexp, source.js string.regexp constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#106800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css.embedded.html punctuation.definition.tag, source.css.embedded.html entity.name.tag.style, source.css.embedded entity.other.attribute-name - meta.selector</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8D00B7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css @import</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css meta.at-rule.import.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009C7F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css @important</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css keyword.other.important</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EE000B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css @media</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css meta.at-rule.media</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#430303</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css string</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#106800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css selector/prop-list</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css meta.selector, source.css meta.property-list, source.css meta.at-rule</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DA29FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css punctuation.separator - source.php, source.css punctuation.terminator - source.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DA29FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css meta.property-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#05208C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property value</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.css meta.property-value</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0035FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php begin/end block</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php punctuation.section.embedded.begin, source.php punctuation.section.embedded.end</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EE000B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php - punctuation.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php varaible</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php variable, source.php meta.function.arguments</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php punctuation - string - variable - meta.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#05208C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php storage.type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php storage.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#24BF96</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php keyword general / storage misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php keyword - comment, source.php storage.type.class, source.php storage.type.interface, source.php storage.modifier, source.php constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009714</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php support / storage / operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php support , source.php storage, source.php keyword.operator, source.php storage.type.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0035FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php varaible global</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php variable.other.global</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0092F2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php support constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php support.constant, source.php constant.language.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#551D02</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php string</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php string, source.php string keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E20000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php string variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php string.quoted.double variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF6200</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>php comment general</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.php comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF9404</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#EFFF8A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EE000B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>4C43099A-C325-4F56-BACB-F332209207B0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Eiffel.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Eiffel</string>\n\t<key>author</key>\n\t<string>Ian Joyner</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#C3DCFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#00B418</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0206FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0100B6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CD0000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C5060B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#585CF6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D80800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character.escape, string source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#26B31A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Preprocessor line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#1A921C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Preprocessor directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.control.import</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0C450D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, keyword.other.name-of-parameter.objc</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0000A2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function parameter</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument and result types</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type.method</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#70727E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Section</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.section entity.name.section, declaration.section entity.name.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3C4C72</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library object</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class, support.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6D79DE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#06960E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#21439C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>JS: Operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.js</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#687687</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid trailing whitespace</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated.trailing-whitespace</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFD0D0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source, string.unquoted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#427FF530</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup XML declaration</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.xml-processing, declaration.xml-processing</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#68685B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup DOCTYPE</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.doctype, declaration.doctype</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#888888</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup DTD</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.doctype.DTD, declaration.doctype.DTD</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#1C02FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup name of tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0C07FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Quote</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.quote</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B90690</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>ADD7FDE7-C6BE-454B-A71A-7951ED54FB04</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/GitHub.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Martin Kühl</string>\n\t<key>comment</key>\n\t<string>A theme based on the GitHub code stylesheet.</string>\n\t<key>name</key>\n\t<string>GitHub</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>comment</key>\n\t\t\t<string>\nbackground              #files .file .data background-color\ncaret                   #files .file .meta color\ninvisibles              .syntax .w\nlineHighlight   #FFFEEB #files .file .private background-color\n    alt:        #FFFFCC colour that gets added via javascript\nselection       #B4D5FE handmade :-)\n    alt:        #FFFFCC colour that gets added via javascript\n                #EAF2F5 #header .userbox background-color\n                #EAEAEA #files .file background-color\n                #DEDEDE #files .file border-color\n                #F9EA86 Mac OS X system selection colour “Gold”\n\t\t\t</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#F8F8FF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#666666</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BBBBBB</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#FFFEEB</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#B4D5FE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>comment</key>\n\t\t\t<string>.syntax .c, .syntax .c[ml]</string>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999988</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment.Preproc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment.block.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .cp</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment.Special</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment.documentation, comment.block.documentation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .cs</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Error</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#E3D2D2</string>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .err</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A61717</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>comment</key>\n\t\t\t<string>.syntax .k, .syntax .k[dpr]</string>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>comment</key>\n\t\t\t<string>.syntax .o, .syntax .ow</string>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword.Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language, support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .kc</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword.Type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type, support.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .kt</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#445588</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .na</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#008080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Builtin</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nb</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0086B3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Builtin.Pseudo</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .bp</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>comment</key>\n\t\t\t<string>TODO: support.class is styled as Name.Constant on GitHub.</string>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type, entity.other.inherited-class, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nc</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#445588</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .no</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#008080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character.entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .ni</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#800080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .ne</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, support.function, keyword.other.name-of-parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nf</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Namespace</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nn</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#555555</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nt</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Name.Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter, support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .nv, .style .v[cgi]</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#008080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Literal.Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .m, .style .m[fhio], .style .il</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Literal.String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string - string source, constant.character</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .s[bcd2ehixl]</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DD1144</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Literal.String.Regex</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .sr</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009926</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Literal.String.Symbol</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.other.symbol</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.style .ss</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990073</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFDDDD</string>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gd</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Emph</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.italic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .ge</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Error</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.error</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gr</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AA0000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading.1</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gh</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#DDFFDD</string>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gi</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Output</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.output, markup.raw</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .go</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#888888</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Prompt</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.prompt</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gp</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#555555</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Strong</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gs</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Subheading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gu</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AAAAAA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Traceback</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.traceback</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gt</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AA0000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Generic.Underline</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.underline</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Extra: Diff Range</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff.range, meta.diff.index, meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#EAF2F5</string>\n\t\t\t\t<key>comment</key>\n\t\t\t\t<string>.syntax .gc</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Extra: Diff From</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff.header.from-file</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFDDDD</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Extra: Diff To</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff.header.to-file</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#DDFFDD</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Extra: Link</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.link</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#4183C4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>FDD6F02A-74F7-4B6C-97F1-857D792EC90E</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/IDLE.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Domenico Carbotta</string>\n\t<key>name</key>\n\t<string>IDLE</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#BAD6FD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#919191</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#00A33F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF5600</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF5600</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#21439C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#21439C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A535AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.other.placeholder.py</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>DDC0CBE1-442B-4CB5-80E4-26E4CFB3A277</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Katzenmilch.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist\n  PUBLIC '-//Apple//DTD PLIST 1.0//EN'\n  'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>\n<plist version=\"1.0\">\n\t<dict>\n\t\t<key>name</key>\n\t\t<string>Katzen-Milch</string>\n\t\t<key>comment</key>\n\t\t<string>Those silly germans and their cat milk! Ghee wizz!</string>\n\t\t<key>settings</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#f3f2f3</string>\n\t\t\t\t\t<key>caret</key>\n\t\t\t\t\t<string>#100011</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#0f0009ff</string>\n\t\t\t\t\t<key>invisibles</key>\n\t\t\t\t\t<string>#000000</string>\n\t\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t\t<string>#ffffff</string>\n\t\t\t\t\t<key>selection</key>\n\t\t\t\t\t<string>#6405D044</string>\n\t\t\t\t\t<key>selectionBorder</key>\n\t\t\t\t\t<string>#8425f0</string>\n\t\t\t\t\t<key>bracketContentsOptions</key>\n\t\t\t\t\t<string>underline</string>\n\t\t\t\t\t<key>tagsForeground</key>\n\t\t\t\t\t<string>#0f0009ff</string>\n\t\t\t\t\t<key>tagsOptions</key>\n\t\t\t\t\t<string>underline</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Parenthesis</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>punctuation.definition.list</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string/>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#940494</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#4444940a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Comment</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>comment</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>italic</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#404f50aa</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#5f0fff02</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>String</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>string</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#5a5f9b</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#aaafdb09</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Number</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>constant.numeric</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#4f827bee</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#77c2bb0f</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>User-defined Constant</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>constant.character, constant.other</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#025f69ff</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#7f229910</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Built-in Constant</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>constant.language</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string/>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#7D7e52</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#bDbe820f</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Storage Modifier</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>storage.modifier</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>bold</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#7B5D8f</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#9B9FfD0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Storage</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>storage</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>bold</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#7B5cbfff</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#8B5Ddf0d</string>\n\t\t\t\t\t\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Function Name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.function</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string></string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#025f49f7</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#22ff491f</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Support Function</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>support.function</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#9D7e62</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#bDbe820a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Misc Function</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.function.misc</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#939469</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#E3E4A90a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Predicate Function</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.function.predicate</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#856F63</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#A5DF930a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Input/Output Function</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.function.io</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#aF938C</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#DFB3AC0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>External Symbol</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>variable.other.external-symbol</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#7BaFaD</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#BBDFDD0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Variable</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>variable.language, variable.other</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#316fcf</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#3aafff0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Parameter Variable</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>variable.parameter</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>italic</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#33969fdd</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#05d6f90b</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Keyword</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>keyword</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#674Aa8</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#A3AAD80e</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Class Name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.class</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>bold</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#B9986F</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#B998DF22</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Structure Name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.structure</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#22af9d</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#B998DF0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Type Name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.type</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#af47a9</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#af77a90d</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Class name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.class, entity.name.type.class</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#cc4357</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#ffddff92</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Support Class</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>support.class</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#ef6aa7ff</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#ef6aa710</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Invalid</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>invalid</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#CC1B27</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#DFDFD5</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>♦ String embedded-source</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>string source</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string>italic</string>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#13499fdd</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#0099ff0a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Tag name</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.name.tag</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#3976a2</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#49a6d20a</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>name</key>\n\t\t\t\t<string>Tag attribute</string>\n\t\t\t\t<key>scope</key>\n\t\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t\t<key>settings</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>fontStyle</key>\n\t\t\t\t\t<string/>\n\t\t\t\t\t<key>foreground</key>\n\t\t\t\t\t<string>#4946c2ee</string>\n\t\t\t\t\t<key>background</key>\n\t\t\t\t\t<string>#4986c209</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t</array>\n\t</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/LAZY.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Domenico Carbotta</string>\n\t<key>name</key>\n\t<string>LAZY</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#7C7C7C</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#B6B6B6</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#EFFCA68F</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#E3FC8D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8C868F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Latex Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.tex.latex entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D62A28</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF7800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, meta.verbatim</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#409B1C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#9D1E15</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Superclass</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant.other.placeholder</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#671EBB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>meta.function-call.py</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.function-call.py</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3E4558</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>meta.tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3A4A64</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml variant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.type.variant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7F90AA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml infix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.infix</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml prefix operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.prefix</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3B5BB5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml infix f-p operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.infix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml prefix f-p operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.prefix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>OCaml f-p constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml constant.numeric.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>A1E55FCB-3CD2-4811-9E73-D9B87419443A</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/LICENSE",
    "content": "If not otherwise specified (see below), files in this directory fall under the following license:\n\n   Permission to copy, use, modify, sell and distribute this\n   software is granted. This software is provided \"as is\" without\n   express or implied warranty, and with no claim as to its\n   suitability for any purpose.\n\nAn exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”."
  },
  {
    "path": "tool/tmthemes/Merbivore.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Merbivore</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#161616</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6E1DC</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#404040</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#333435</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#454545</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AD2EA4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FC6F09</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function (definition)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, keyword.other.name-of-parameter.objc</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class (definition)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class inheritence</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FC83FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#58C554</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#1EDAFB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant (other variable)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant lib</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.library</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DFF0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>support function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FC6F09</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant (built-in)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FDC251</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DFF0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#1EDAFB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8DFF0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, declaration.tag, entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FC6F09</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFF89</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character.escaped, constant.character.escape, string source, string source.ruby</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#519F50</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Diff Add</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#144212</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6E1DC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Diff Remove</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#660000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6E1DC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Diff Header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff.header, meta.separator.diff, meta.diff.index, meta.diff.range</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#2F33AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>2ABC646D-06F3-48A5-94E9-18EF34474C97</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Monokai.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Monokai</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#272822</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#F8F8F0</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F2</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#3B3A32</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#3E3D32</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#49483E</string>\n\t\t\t\t<key>findHighlight</key>\n\t\t\t\t<string>#FFE792</string>\n\t\t\t\t<key>findHighlightForeground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>selectionBorder</key>\n\t\t\t\t<string>#222218</string>\n\t\t\t\t<key>activeGuide</key>\n\t\t\t\t<string>#9D550FB0</string>\n\n\t\t\t\t<key>bracketsForeground</key>\n\t\t\t\t<string>#F8F8F2A5</string>\n\t\t\t\t<key>bracketsOptions</key>\n\t\t\t\t<string>underline</string>\n\n\t\t\t\t<key>bracketContentsForeground</key>\n\t\t\t\t<string>#F8F8F2A5</string>\n\t\t\t\t<key>bracketContentsOptions</key>\n\t\t\t\t<string>underline</string>\n\n\t\t\t\t<key>tagsOptions</key>\n\t\t\t\t<string>stippled_underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#75715E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6DB74</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AE81FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AE81FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AE81FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F92672</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F92672</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66D9EF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A6E22E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A6E22E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A6E22E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FD971F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F92672</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A6E22E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66D9EF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66D9EF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66D9EF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#F92672</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#AE81FF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>JSON String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.structure.dictionary.json string.quoted.double.json</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CFCFC2</string>\n\t\t\t</dict>\n\t\t</dict>\n\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff, meta.diff.header</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#75715E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F92672</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A6E22E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.changed</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.changed</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6DB74</string>\n\t\t\t</dict>\n\t\t</dict>\n\n\t\t<dict>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.line-number.find-in-files - match</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AE81FFA0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.filename.find-in-files</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E6DB74</string>\n\t\t\t</dict>\n\t\t</dict>\n\n\t</array>\n\t<key>uuid</key>\n\t<string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Solarized-dark.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Solarized (dark)</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#002B36</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#93A1A180</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#073642</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#073642</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#657B83</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#2AA198</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D33682</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable start</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.definition.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded code markers</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.section.embedded.begin, punctuation.section.embedded.end</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language, meta.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B58900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.construct</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function.construct, keyword.other.new</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6C71C4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag start/end</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.definition.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#657B83</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Continuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.separator.continuation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>F930B0BF-AA03-4232-A30F-CEF749FF8E72</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Solarized-light.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Solarized (light)</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FDF6E3</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#586E75</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#93A1A180</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#EEE8D5</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#073642</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#2AA198</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D33682</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#073642</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable start</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.definition.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded code markers</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.section.embedded.begin, punctuation.section.embedded.end</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language, meta.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B58900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.construct</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function.construct, keyword.other.new</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag start/end</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.definition.tag.begin, punctuation.definition.tag.end</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#93A1A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#268BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Continuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation.separator.continuation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D30102</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#859900</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CB4B16</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>38E819D9-AE02-452F-9231-ECC3B204AFD7</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/SpaceCadet.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Alex Ross</string>\n\t<key>comment</key>\n\t<string>Created by Alex Ross</string>\n\t<key>name</key>\n\t<string>SpaceCadet</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0D0D0D</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#7F005D</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DDE6CF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#40002F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#473C45</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#805978</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A8885A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#596380</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword - keyword.operator, keyword.operator.logical</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#728059</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9EBF60</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6078BF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8A4B66</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#893062</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#5F0047</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>- Meta</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>  function.section</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.function.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#371D28</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>2C24E84F-F9FE-4C2E-92D2-F52198BA7E41</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Sunburst.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Stanley Rost</string>\n\t<key>comment</key>\n\t<string>(π) Soryu, 2005</string>\n\t<key>name</key>\n\t<string>Sunburst</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#A7A7A7</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#CAE2FB3D</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#FFFFFF1A</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#DDF0FF33</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AEAEAE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3387CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#89BDFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E28964</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#99CF50</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#65B042</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B859D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3E87E3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FD5FF1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#562D56BF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FD5FF1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>-----------------------------------</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Embedded Source (Bright)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B1B3BA08</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Entity inherited-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B5C2E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String embedded-source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.quoted source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DAEFA3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DDF2A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String.regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E9C062</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String.regexp.«special»</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF7D34</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8A9A95</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DAD085</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Support.constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF6A4C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>c C/C++ Preprocessor Line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8996A8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>c C/C++ Preprocessor Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AFC4DB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>j Entity Name Type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>j Cast</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.cast</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#676767</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Doctype/XML Processing</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#494949</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Meta.tag.«all»</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#89BDFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Meta.tag.inline</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source entity.name.tag, source entity.other.attribute-name, meta.tag.inline, meta.tag.inline entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E0C589</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Namespaces</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag.namespace, entity.other.attribute-name.namespace</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E18964</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css tag-name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDA869</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css:pseudo-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.tag.pseudo-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8F9D6A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css#id</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.id</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8B98AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css.class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B703F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css property-name:</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.property-name.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C5AF75</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css property-value;</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F9EE98</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css @at-rule</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.at-rule keyword.control.at-rule</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8693A5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css additional-constants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-value support.constant.named-color.css, meta.property-value constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DD7B3B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css constructor.argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.constructor.argument.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8F9D6A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff, meta.diff.header</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0E2231</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#420E09</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.changed</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.changed</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#4A410D</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#253B22</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>--------------------------------</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Italic</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.italic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E9C062</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Bold</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E9C062</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Underline</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.underline</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E18964</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Quote</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.quote</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FEE09C12</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E1D4B9</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading, markup.heading entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#632D04</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FEDCC5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E1D4B9</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Raw</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.raw</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B1B3BA08</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#578BB3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F67B37</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#242424</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#60A633</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Log Entry</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.line.entry.logfile, meta.line.exit.logfile</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#EEEEEE29</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Log Entry Error</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.line.error.logfile</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#751012</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>C8C58F9A-35FE-44A4-9BC2-2F3C343DC81D</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Tomorrow-Night-Blue.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>http://chriskempson.com</string>\n\t<key>name</key>\n\t<string>Tomorrow Night - Blue</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#002451</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#404F7D</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00346E</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#003F8E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7285B7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Foreground, Operator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.class, keyword.operator, constant.other, source.php.embedded.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable, String Link, Regular Expression, Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF9DA4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFC58F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class, Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class, support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFEEAD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String, Symbols, Inherited Class, Markup Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D1F1A9</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator, Misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#99FFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function, Special Method, Block Level</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BBDAFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword, Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage, storage.type, entity.name.tag.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EBBBFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#F99DA5</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#BBDAFE</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#EBBBFF</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>3F4BB232-3C3A-4396-99C0-06A9573715E9</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Tomorrow-Night-Bright.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>http://chriskempson.com</string>\n\t<key>name</key>\n\t<string>Tomorrow Night - Bright</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#9F9F9F</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DEDEDE</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#343434</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#2A2A2A</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#424242</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#969896</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Foreground</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.class, constant.other, source.php.embedded.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EEEEEE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable, String Link, Regular Expression, Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D54E53</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E78C45</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class, Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class, support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E7C547</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String, Symbols, Inherited Class, Markup Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B9CA4A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator, Misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#70C0B1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function, Special Method, Block Level</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7AA6DA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword, Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage, storage.type, entity.name.tag.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C397D8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#DF5F5F</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#82A3BF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B798BF</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>33D8C715-AD3A-455B-8DF2-56F708909FFE</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Tomorrow-Night-Eighties.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>http://chriskempson.com</string>\n\t<key>name</key>\n\t<string>Tomorrow Night - Eighties</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#2D2D2D</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#CCCCCC</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCCCC</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#6A6A6A</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#393939</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#515151</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999999</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Foreground</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.class, constant.other, source.php.embedded.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCCCC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable, String Link, Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable, support.other.variable, string.other.link, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F2777A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F99157</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class, Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class, support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFCC66</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String, Symbols, Inherited Class, Markup Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#99CC99</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator, Misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#66CCCC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function, Special Method, Block Level</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6699CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword, Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage, storage.type, entity.name.tag.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CC99CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#F2777A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDCDCD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#99CCCC</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDCDCD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#CC99CC</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDCDCD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>DE477E5B-BD4D-46B0-BF80-2EA32A2814D5</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Tomorrow-Night.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>http://chriskempson.com</string>\n\t<key>name</key>\n\t<string>Tomorrow Night</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#1D1F21</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#AEAFAD</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C5C8C6</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#4B4E55</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#282A2E</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#373B41</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#969896</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Foreground</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.class, constant.other, source.php.embedded.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED1CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable, String Link, Regular Expression, Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CC6666</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DE935F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class, Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class, support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F0C674</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String, Symbols, Inherited Class, Markup Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B5BD68</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator, Misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8ABEB7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function, Special Method, Block Level</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#81A2BE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword, Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage, storage.type, entity.name.tag.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B294BB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#DF5F5F</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#82A3BF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B798BF</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CED2CF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>F96223EB-1A60-4617-92F3-D24D4F13DB09</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Tomorrow.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>http://chriskempson.com</string>\n\t<key>name</key>\n\t<string>Tomorrow</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#AEAFAD</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#4D4D4C</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#D1D1D1</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#EFEFEF</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#D6D6D6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8E908C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Foreground</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator.class, constant.other, source.php.embedded.line</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#666969</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable, String Link, Regular Expression, Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C82829</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F5871F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class, Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class, entity.name.type.class, support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C99E00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String, Symbols, Inherited Class, Markup Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#718C00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operator, Misc</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator, constant.other.color</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3E999F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function, Special Method, Block Level</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#4271AE</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword, Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage, storage.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8959A8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#C82829</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Separator</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#4271AE</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#8959A8</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>82CCD69C-F1B1-4529-B39E-780F91F07604</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Twilight.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Michael Sheets</string>\n\t<key>name</key>\n\t<string>Twilight</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#141414</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#A7A7A7</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#FFFFFF40</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#FFFFFF08</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#DDF0FF33</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5F5A60</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF6A4C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B703F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDA869</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F9EE98</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8F9D6A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B859D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7587A6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Deprecated</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D2A8A1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid – Illegal</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.illegal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#562D56BF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>-----------------------------------</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Embedded Source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B0B3BA14</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Embedded Source (Bright)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text.html.ruby source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#B1B3BA21</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Entity inherited-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B5C2E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String embedded-source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DAEFA3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DDF2A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String.regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E9C062</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String.regexp.«special»</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF7D34</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ String variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8A9A95</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DAD085</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>♦ Support.constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF6A4C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>c C/C++ Preprocessor Line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8996A8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>c C/C++ Preprocessor Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AFC4DB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Doctype/XML Processing</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag.sgml.doctype, meta.tag.sgml.doctype entity, meta.tag.sgml.doctype string, meta.tag.preprocessor.xml, meta.tag.preprocessor.xml entity, meta.tag.preprocessor.xml string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#494949</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Meta.tag.«all»</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.tag, declaration.tag entity, meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AC885B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>✘ Meta.tag.inline</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.tag.inline, declaration.tag.inline entity, source entity.name.tag, source entity.other.attribute-name, meta.tag.inline, meta.tag.inline entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E0C589</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css tag-name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDA869</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, support.function.any-method</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AC885B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css:pseudo-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.tag.pseudo-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8F9D6A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css#id</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.id</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8B98AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css.class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9B703F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css property-name:</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.property-name.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C5AF75</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css property-value;</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F9EE98</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css @at-rule</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.at-rule keyword.control.at-rule</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8693A5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css additional-constants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-value support.constant.named-color.css, meta.property-value constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CA7840</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>§ css constructor.argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.constructor.argument.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8F9D6A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff, meta.diff.header, meta.separator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0E2231</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#420E09</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.changed</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.changed</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#4A410D</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>⎇ diff.inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#253B22</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F9EE98</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup: Heading</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CF6A4C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>766026CB-703D-4610-B070-8DE07D967C5F</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Xcode_default.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>Carmine Paolino</string>\n\t<key>name</key>\n\t<string>Xcode default</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#BFBFBF</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#00000012</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#B5D5FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#008E00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Preprocessor Statements</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor, keyword.control.import</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7D4726</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DF0002</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3A00DC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C800A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#275A5E</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C800A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C800A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C900A4</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#438288</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#790EAD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#450084</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#450084</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#450084</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#790EAD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#790EAD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>EE3AD170-2B7F-4DE1-B724-C75F13FE0085</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/Zenburnesque.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>William D. Neumann</string>\n\t<key>name</key>\n\t<string>Zenburnesque</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#404040</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFF66</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#DEDEDE</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#A8A8A8</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#A0804026</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#A0A0C0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#709070</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.directive</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Line-number directives</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.other.directive.line-number</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Characters</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF8080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF2020</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#22C0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point numbers</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Built-in constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User-defined constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character, constant.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Language Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFA0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Module Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.module,  support.other.module</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF8000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Operators</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword.operator</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFA0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point infix operators</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.infix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Floating-point prefix operators</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ocaml keyword.operator.symbol.prefix.floating-point</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage Types</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6080FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variant Types</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class.variant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#4080A0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F09040</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFCC66</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type.user-defined</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFE000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type.class.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F4A020</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library class/type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type, support.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>8D4988B9-ADD8-436F-B388-BC1360F8504B</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/gruvboxDarkHard.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>comment</key>\n    <string>Based on gruvbox for Vim (https://github.com/morhetz/gruvbox)</string>\n    <key>originalAuthor</key>\n    <string>Pavel Pertsev (https://github.com/morhetz)</string>\n    <key>author</key>\n    <string>Brian Reilly (https://github.com/Briles/gruvbox)</string>\n    <key>name</key>\n    <string>gruvbox (Dark) (Hard)</string>\n    <key>colorSpaceName</key>\n    <string>sRGB</string>\n    <key>settings</key>\n    <array>\n      <dict>\n        <key>settings</key>\n        <dict>\n          <key>background</key>\n          <string>#1d2021</string>\n          <key>caret</key>\n          <string>#a89984</string>\n          <key>foreground</key>\n          <string>#ebdbb280</string>\n          <key>invisibles</key>\n          <string>#ebdbb226</string>\n          <key>lineHighlight</key>\n          <string>#3c3836</string>\n          <key>selection</key>\n          <string>#3c3836</string>\n          <key>inactiveSelection</key>\n          <string>#3c3836</string>\n          <key>guide</key>\n          <string>#ebdbb226</string>\n          <key>activeGuide</key>\n          <string>#ebdbb280</string>\n          <key>stackGuide</key>\n          <string>#ebdbb240</string>\n          <key>bracketContentsOptions</key>\n          <string>underline</string>\n          <key>bracketContentsForeground</key>\n          <string>#bdae93</string>\n          <key>bracketsOptions</key>\n          <string>underline</string>\n          <key>bracketsForeground</key>\n          <string>#bdae93</string>\n          <key>gutterForeground</key>\n          <string>#928374</string>\n          <key>highlight</key>\n          <string>#f9f5d7</string>\n          <key>highlightForeground</key>\n          <string>#f9f5d7</string>\n          <key>findHighlight</key>\n          <string>#d79921</string>\n          <key>findHighlightForeground</key>\n          <string>#1d2021</string>\n          <key>tagsOptions</key>\n          <string>underline</string>\n          <key>selectionBorder</key>\n          <string>#3c3836</string>\n          <key>popupCss</key>\n          <string>\n            html {\n              background-color: #111313;\n              color: #f9f5d7;\n              padding: 12px;\n            }\n\n            a {\n              color: #8ec07c;\n            }\n\n            .error, .deleted {\n              color: #fb4934;\n            }\n\n            .success, .inserted, .name {\n              color: #b8bb26;\n            }\n\n            .warning, .modified {\n              color: #fabd2f;\n            }\n\n            .type {\n              color: #fabd2f;\n              font-style: italic;\n            }\n\n            .param {\n              color: #f9f5d7;\n            }\n\n            .current {\n              text-decoration: underline;\n            }\n          </string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Text and Source Base Colors</string>\n        <key>scope</key>\n        <string>meta.group, meta.method-call.source.cs, meta.method.attribute.source.cs, meta.method.body.java, meta.method.body.source.cs, meta.method.source.cs, none, source, text</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Punctuation</string>\n        <key>scope</key>\n        <string>entity.quasi.element meta.group.braces, keyword.operator keyword.operator.neon, keyword.operator operator.neon, keyword.operator.accessor, keyword.other.accessor, meta.attribute-selector keyword.operator.stylus, meta.brace, meta.delimiter, meta.group.braces, meta.punctuation.separator, meta.separator, punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Comments</string>\n        <key>scope</key>\n        <string>comment, comment text, markup.strikethrough, punctuation.definition.comment, punctuation.whitespace.comment, string.comment, text.cancelled</string>\n        <key>settings</key>\n        <dict>\n          <key>fontStyle</key>\n          <string>italic</string>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Keywords Inside Comments</string>\n        <key>scope</key>\n        <string>comment.keyword, comment.keyword.punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d5c4a1</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>DocBlockr &amp; Other Keywords Inside Comments</string>\n        <key>scope</key>\n        <string>comment.parameter, comment.punctuation, comment.string, comment.type, keyword.other.phpdoc.php, punctuation.definition.keyword.javadoc, source.groovy keyword.other.documentation, source.java keyword.other.documentation, storage.type.annotation.coffeescript, storage.type.class.jsdoc</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Entity</string>\n        <key>scope</key>\n        <string>constant.language.name, entity.name.type, entity.other.inherited-class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Template String Punctuation</string>\n        <key>scope</key>\n        <string>constant.other.placeholder, entity.name.tag.mustache, entity.tag.tagbraces, punctuation.definition.string.template, punctuation.definition.template-expression, punctuation.quasi, punctuation.section.embedded, string.interpolated, variable.other.interpolation.scss</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Keywords</string>\n        <key>scope</key>\n        <string>js.embedded.control.flow keyword.operator.js, keyword, keyword.control, keyword.operator.logical.python, meta.at-rule.media support.function.misc, meta.prolog.haml, meta.tag.sgml.doctype.html, storage.type.function.jade, storage.type.function.pug, storage.type.import.haxe, storage.type.import.include.jade, storage.type.import.include.pug, support.keyword.timing-direction, variable.documentroot</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS At-Rule Punctuation (@) &amp; At-Rule Vendor Prefixes</string>\n        <key>scope</key>\n        <string>keyword.control.at-rule support.type.property-vendor, punctuation.definition.keyword</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#cc241d</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Operators</string>\n        <key>scope</key>\n        <string>keyword.control.new, keyword.control.operator, keyword.operator, keyword.other.arrow, keyword.other.double-colon, punctuation.operator</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Constants Punctuation</string>\n        <key>scope</key>\n        <string>constant.other.color punctuation.definition.constant, constant.other.symbol punctuation.definition.constant, constant.other.unit, keyword.other.unit, punctuation.section.flowtype, support.constant.unicode-range.prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Storage</string>\n        <key>scope</key>\n        <string>storage, storage.type.annotation, storage.type.primitive</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>storage.modifier.import, storage.modifier.package, storage.type.import, variable.import, variable.package</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Keyword</string>\n        <key>scope</key>\n        <string>entity.quasi.tag.name, meta.function storage.type.matlab, storage.type.function</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Variables</string>\n        <key>scope</key>\n        <string>entity.name.val.declaration, entity.name.variable, meta.definition.variable, storage.type.variable, support.type.custom-property, support.type.variable-name, variable, variable.interpolation variable, variable.other.interpolation variable, variable.parameter.dosbatch, variable.parameter.output.function.matlab, variable.parameter.sass</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Variable - Punctuation</string>\n        <key>scope</key>\n        <string>keyword.other.custom-property.prefix, punctuation.definition.custom-property, punctuation.definition.variable, support.constant.custom-property-name.prefix, variable.interpolation, variable.other.dollar punctuation.dollar, variable.other.object.dollar punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Declaration - Punctuation</string>\n        <key>scope</key>\n        <string>entity.name.function punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Object Properties</string>\n        <key>scope</key>\n        <string>meta.property.object</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Object Literal Properties</string>\n        <key>scope</key>\n        <string>constant.other.object.key string, meta.object-literal.key</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Parameters</string>\n        <key>scope</key>\n        <string>meta.parameters, variable.parameter</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SASS Import URL</string>\n        <key>scope</key>\n        <string>variable.parameter.url</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Language Constants</string>\n        <key>scope</key>\n        <string>constant, constant.numeric, constant.other, constant.other.color, constant.other.symbol, support.constant, support.constant.color, support.constant.font-name, support.constant.media, support.constant.prototype, variable.language</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Language Constants Punctuation</string>\n        <key>scope</key>\n        <string>variable.language punctuation.definition.variable</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>User-Defined Constants</string>\n        <key>scope</key>\n        <string>entity.name.constant, variable.other.constant</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Escaped Characters</string>\n        <key>scope</key>\n        <string>constant.character.escape, constant.character.escaped, constant.character.quoted, constant.other.character-class.escape</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Invalids and Illegals</string>\n        <key>scope</key>\n        <string>invalid</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n          <key>background</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Inner Scopes of Invalids and Illegals</string>\n        <key>scope</key>\n        <string>invalid keyword.other.custom-property.prefix, invalid support.type.custom-property.name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Errors</string>\n        <key>scope</key>\n        <string>message.error</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Strings</string>\n        <key>scope</key>\n        <string>meta.object-literal.key string, string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>JSON Keys</string>\n        <key>scope</key>\n        <string>meta.structure.dictionary.key.json string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Text</string>\n        <key>scope</key>\n        <string>source.regexp, string.regexp</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Start &amp; End Punctuation</string>\n        <key>scope</key>\n        <string>string.regexp punctuation.definition.string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Character Class Punctuation ([])</string>\n        <key>scope</key>\n        <string>keyword.control.set.regexp, punctuation.definition.character-class, string.regexp.character-class.ruby</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Capturing Group</string>\n        <key>scope</key>\n        <string>string.regexp.group</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Assertions</string>\n        <key>scope</key>\n        <string>constant.other.assertion.regexp, punctuation.definition.group.assertion.regexp, punctuation.definition.group.capture.regexp</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Character Class</string>\n        <key>scope</key>\n        <string>constant.other.character-class.escape.backslash.regexp, keyword.control.character-class.regexp, string.regexp.character-class constant.character.escape</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Quantifiers &amp; Operators</string>\n        <key>scope</key>\n        <string>string.regexp.arbitrary-repetition, string.regexp.arbitrary-repetition punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Hyperlinks</string>\n        <key>scope</key>\n        <string>constant.other.reference.link, string.other.link</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Hyperlink Punctuation</string>\n        <key>scope</key>\n        <string>meta.image.inline punctuation.definition.string, meta.link.inline punctuation.definition.string, meta.link.reference punctuation.definition.constant, meta.link.reference.literal punctuation.definition.constant, meta.link.reference.literal punctuation.definition.string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#689d6a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markup Tag Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Heading</string>\n        <key>scope</key>\n        <string>markup.heading</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Heading Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.heading, punctuation.definition.identity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Bold Text</string>\n        <key>scope</key>\n        <string>markup.bold</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fe8019</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Bold Text Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bold</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d65d0e</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Italic Text</string>\n        <key>scope</key>\n        <string>markup.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n          <key>fontStyle</key>\n          <string>italic</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Italic Text Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#cc241d</string>\n          <key>fontStyle</key>\n          <string>italic</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Inline Code</string>\n        <key>scope</key>\n        <string>markup.raw.inline</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Inline Code Punctuation</string>\n        <key>scope</key>\n        <string>markup.raw.inline punctuation.definition.raw</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Quoted</string>\n        <key>scope</key>\n        <string>markup.quote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Quoted Punctuation</string>\n        <key>scope</key>\n        <string>markup.quote punctuation.definition.blockquote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown List</string>\n        <key>scope</key>\n        <string>markup.list</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown List Punctuation</string>\n        <key>scope</key>\n        <string>markup.list punctuation.definition.list_item</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Separators</string>\n        <key>scope</key>\n        <string>meta.separator.markdown</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Support</string>\n        <key>scope</key>\n        <string>meta.function-call.constructor variable.type, support.class, support.type, variable.other.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Supporting Type - Dollar Punctuation</string>\n        <key>scope</key>\n        <string>support.class punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Calls</string>\n        <key>scope</key>\n        <string>entity.name.function.jade, entity.name.function.pug, keyword.other.special-method, meta.function-call variable.function, meta.function-call variable.other.dollar.only punctuation.dollar, support.function</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Method Calls</string>\n        <key>scope</key>\n        <string>meta.function-call.method support.function, meta.function-call.method variable.function, meta.function-call.static variable.function, meta.method-call, meta.method-call support.function, meta.method-call variable.function, support.function.mutator</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#689d6a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Special Variables</string>\n        <key>scope</key>\n        <string>support.module</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Entities</string>\n        <key>scope</key>\n        <string>entity.name.accessor, entity.name.function, entity.name.label, entity.name.section</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Modules</string>\n        <key>scope</key>\n        <string>entity.name.module</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fe8019</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS ID</string>\n        <key>scope</key>\n        <string>constant.id.tag, entity.name.tag.id, entity.other.attribute-name.id</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fe8019</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS ID Punctuation (#)</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.id punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d65d0e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS Class</string>\n        <key>scope</key>\n        <string>entity.name.tag.class, entity.other.attribute-name.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS Class Punctuation (.)</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.class punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Attribute Selector Attribute Name</string>\n        <key>scope</key>\n        <string>meta.attribute-selector entity.other.attribute-name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; XML Entity Punctuation</string>\n        <key>scope</key>\n        <string>constant.character.entity punctuation.definition.constant, constant.character.entity punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>entity.name.class, entity.name.type.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markup Tag</string>\n        <key>scope</key>\n        <string>entity.name.function.neon, entity.name.namespace.wildcard, entity.name.tag, entity.tag, keyword.control.untitled, keyword.doctype.xml, keyword.operator support.other.neon, punctuation.definition.prolog.haml, source.less keyword.control.html.elements</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML Attribute Names</string>\n        <key>scope</key>\n        <string>entity.name.attribute-name, entity.other.attribute-name, meta.section.attributes.haml constant.other.symbol.ruby</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Pseudo Elements/Classes &amp; Vendor Prefixes</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.placeholder punctuation.definition.entity, entity.other.attribute-name.pseudo-class, entity.other.attribute-name.pseudo-element, entity.other.attribute-name.tag.pseudo-class, entity.other.attribute-name.tag.pseudo-element, entity.other.pseudo-class, entity.other.pseudo-element, support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Animations / Keyframes</string>\n        <key>scope</key>\n        <string>entity.function-name.stylus, entity.other.animation-keyframe.stylus, entity.other.animation-name, keyword.language.function.misc.stylus, meta.at-rule.keyframes entity.name.function, variable.other.animation-name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Author-Defined Names</string>\n        <key>scope</key>\n        <string>entity.other.namespace-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>meta.class.body, meta.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Image &amp; Hyperlink</string>\n        <key>scope</key>\n        <string>meta.image, meta.link</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Image &amp; Hyperlink Punctuation</string>\n        <key>scope</key>\n        <string>meta.image punctuation.definition.metadata, meta.link punctuation.definition.metadata</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>meta.require</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Call Braces</string>\n        <key>scope</key>\n        <string>constant.name.attribute.tag.jade, constant.name.attribute.tag.pug, meta.brace.round, meta.function-call meta.group punctuation.definition.group, punctuation.definition.method-parameters, punctuation.definition.parameters</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Names</string>\n        <key>scope</key>\n        <string>meta.property-name, support.type.property-name, support.type.shape.definition support.constant.property-value</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Name Vendor Prefixes</string>\n        <key>scope</key>\n        <string>meta.property-name support.type.vendor-prefix, support.type.property-name.media support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Values</string>\n        <key>scope</key>\n        <string>constant.string.sass, meta.property-value, support.constant.property-value</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Value Vendor Prefixes</string>\n        <key>scope</key>\n        <string>meta.property-value support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Foreground Text</string>\n        <key>scope</key>\n        <string>source.diff</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#a89984</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text From</string>\n        <key>scope</key>\n        <string>meta.diff.header.from-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text From Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.from-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text To</string>\n        <key>scope</key>\n        <string>meta.diff.header.to-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text To Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.to-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Additions &amp; Deletions Stats</string>\n        <key>scope</key>\n        <string>meta.diff.range, meta.toc-list.line-number</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Additions &amp; Deletions Stats Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.range.diff</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Line Number</string>\n        <key>scope</key>\n        <string>constant.numeric.line-number</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Line Number Matched</string>\n        <key>scope</key>\n        <string>constant.numeric.line-number.match</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Filename</string>\n        <key>scope</key>\n        <string>entity.name.filename</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Deleted</string>\n        <key>scope</key>\n        <string>markup.deleted, punctuation.definition.deleted</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Inserted</string>\n        <key>scope</key>\n        <string>markup.inserted, punctuation.definition.inserted</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Changed</string>\n        <key>scope</key>\n        <string>markup.changed, punctuation.definition.changed</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter ignored</string>\n        <key>scope</key>\n        <string>markup.ignored</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter untracked</string>\n        <key>scope</key>\n        <string>markup.untracked</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Tag</string>\n        <key>scope</key>\n        <string>brackethighlighter.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Curly</string>\n        <key>scope</key>\n        <string>brackethighlighter.curly</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Round</string>\n        <key>scope</key>\n        <string>brackethighlighter.round</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Square</string>\n        <key>scope</key>\n        <string>brackethighlighter.square</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Angle</string>\n        <key>scope</key>\n        <string>brackethighlighter.angle</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Quote</string>\n        <key>scope</key>\n        <string>brackethighlighter.quote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Unmatched</string>\n        <key>scope</key>\n        <string>brackethighlighter.unmatched</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Error</string>\n        <key>scope</key>\n        <string>sublimelinter.mark.error</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Gutter Mark</string>\n        <key>scope</key>\n        <string>sublimelinter.gutter-mark</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Warning</string>\n        <key>scope</key>\n        <string>sublimelinter.mark.warning</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Upper Byte Nibble</string>\n        <key>scope</key>\n        <string>raw.nibble.upper</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Lower Byte Nibble</string>\n        <key>scope</key>\n        <string>raw.nibble.lower</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Highlight</string>\n        <key>scope</key>\n        <string>hexviewer.highlight</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n          <key>background</key>\n          <string>#fabd2f</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Edited Highlight</string>\n        <key>scope</key>\n        <string>hexviewer.highlight.edited</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n          <key>background</key>\n          <string>#fe8019</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Raw New Line: Carriage Return</string>\n        <key>scope</key>\n        <string>glyph.carriage-return</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#ebdbb226</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Raw New Line: New Line Glyph</string>\n        <key>scope</key>\n        <string>glyph.new-line</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#ebdbb226</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Header</string>\n        <key>scope</key>\n        <string>keyword.control.header.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b8bb26</string>\n          <key>background</key>\n          <string>#2e3234</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Notes</string>\n        <key>scope</key>\n        <string>notes.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#bdae93</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Punctuation</string>\n        <key>scope</key>\n        <string>text.todo punctuation.definition.bold, text.todo punctuation.definition.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#7c6f64</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Pending</string>\n        <key>scope</key>\n        <string>meta.item.todo.pending</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Pending Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.pending.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Completed Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.completed.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8ec07c</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Cancelled Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.cancelled.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Critical</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.critical</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fb4934</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag High</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.high</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fe8019</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Low</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.low</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Today</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.today</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#fabd2f</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag</string>\n        <key>scope</key>\n        <string>meta.tag.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d3869b</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: URL</string>\n        <key>scope</key>\n        <string>punctuation.definition.url, todo.url</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#83a598</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Separator</string>\n        <key>scope</key>\n        <string>meta.punctuation.archive.todo, meta.punctuation.separator.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>fontStyle</key>\n          <string>italic</string>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n    </array>\n  </dict>\n</plist>"
  },
  {
    "path": "tool/tmthemes/gruvboxLightHard.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>comment</key>\n    <string>Based on gruvbox for Vim (https://github.com/morhetz/gruvbox)</string>\n    <key>originalAuthor</key>\n    <string>Pavel Pertsev (https://github.com/morhetz)</string>\n    <key>author</key>\n    <string>Brian Reilly (https://github.com/Briles/gruvbox)</string>\n    <key>name</key>\n    <string>gruvbox (Light) (Hard)</string>\n    <key>colorSpaceName</key>\n    <string>sRGB</string>\n    <key>settings</key>\n    <array>\n      <dict>\n        <key>settings</key>\n        <dict>\n          <key>background</key>\n          <string>#f9f5d7</string>\n          <key>caret</key>\n          <string>#7c6f64</string>\n          <key>foreground</key>\n          <string>#3c383680</string>\n          <key>invisibles</key>\n          <string>#3c383626</string>\n          <key>lineHighlight</key>\n          <string>#ebdbb2</string>\n          <key>selection</key>\n          <string>#ebdbb2</string>\n          <key>inactiveSelection</key>\n          <string>#ebdbb2</string>\n          <key>guide</key>\n          <string>#3c383626</string>\n          <key>activeGuide</key>\n          <string>#3c383680</string>\n          <key>stackGuide</key>\n          <string>#3c383640</string>\n          <key>bracketContentsOptions</key>\n          <string>underline</string>\n          <key>bracketContentsForeground</key>\n          <string>#665c54</string>\n          <key>bracketsOptions</key>\n          <string>underline</string>\n          <key>bracketsForeground</key>\n          <string>#665c54</string>\n          <key>gutterForeground</key>\n          <string>#928374</string>\n          <key>highlight</key>\n          <string>#1d2021</string>\n          <key>highlightForeground</key>\n          <string>#1d2021</string>\n          <key>findHighlight</key>\n          <string>#d79921</string>\n          <key>findHighlightForeground</key>\n          <string>#f9f5d7</string>\n          <key>tagsOptions</key>\n          <string>underline</string>\n          <key>selectionBorder</key>\n          <string>#ebdbb2</string>\n          <key>popupCss</key>\n          <string>\n            html {\n              background-color: #f6efc1;\n              color: #1d2021;\n              padding: 12px;\n            }\n\n            a {\n              color: #427b58;\n            }\n\n            .error, .deleted {\n              color: #9d0006;\n            }\n\n            .success, .inserted, .name {\n              color: #79740e;\n            }\n\n            .warning, .modified {\n              color: #b57614;\n            }\n\n            .type {\n              color: #b57614;\n              font-style: italic;\n            }\n\n            .param {\n              color: #1d2021;\n            }\n\n            .current {\n              text-decoration: underline;\n            }\n          </string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Text and Source Base Colors</string>\n        <key>scope</key>\n        <string>meta.group, meta.method-call.source.cs, meta.method.attribute.source.cs, meta.method.body.java, meta.method.body.source.cs, meta.method.source.cs, none, source, text</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Punctuation</string>\n        <key>scope</key>\n        <string>entity.quasi.element meta.group.braces, keyword.operator keyword.operator.neon, keyword.operator operator.neon, keyword.operator.accessor, keyword.other.accessor, meta.attribute-selector keyword.operator.stylus, meta.brace, meta.delimiter, meta.group.braces, meta.punctuation.separator, meta.separator, punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Comments</string>\n        <key>scope</key>\n        <string>comment, comment text, markup.strikethrough, punctuation.definition.comment, punctuation.whitespace.comment, string.comment, text.cancelled</string>\n        <key>settings</key>\n        <dict>\n          <key>fontStyle</key>\n          <string>italic</string>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Keywords Inside Comments</string>\n        <key>scope</key>\n        <string>comment.keyword, comment.keyword.punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#504945</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>DocBlockr &amp; Other Keywords Inside Comments</string>\n        <key>scope</key>\n        <string>comment.parameter, comment.punctuation, comment.string, comment.type, keyword.other.phpdoc.php, punctuation.definition.keyword.javadoc, source.groovy keyword.other.documentation, source.java keyword.other.documentation, storage.type.annotation.coffeescript, storage.type.class.jsdoc</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Entity</string>\n        <key>scope</key>\n        <string>constant.language.name, entity.name.type, entity.other.inherited-class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Template String Punctuation</string>\n        <key>scope</key>\n        <string>constant.other.placeholder, entity.name.tag.mustache, entity.tag.tagbraces, punctuation.definition.string.template, punctuation.definition.template-expression, punctuation.quasi, punctuation.section.embedded, string.interpolated, variable.other.interpolation.scss</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Keywords</string>\n        <key>scope</key>\n        <string>js.embedded.control.flow keyword.operator.js, keyword, keyword.control, keyword.operator.logical.python, meta.at-rule.media support.function.misc, meta.prolog.haml, meta.tag.sgml.doctype.html, storage.type.function.jade, storage.type.function.pug, storage.type.import.haxe, storage.type.import.include.jade, storage.type.import.include.pug, support.keyword.timing-direction, variable.documentroot</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS At-Rule Punctuation (@) &amp; At-Rule Vendor Prefixes</string>\n        <key>scope</key>\n        <string>keyword.control.at-rule support.type.property-vendor, punctuation.definition.keyword</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#cc241d</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Operators</string>\n        <key>scope</key>\n        <string>keyword.control.new, keyword.control.operator, keyword.operator, keyword.other.arrow, keyword.other.double-colon, punctuation.operator</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Constants Punctuation</string>\n        <key>scope</key>\n        <string>constant.other.color punctuation.definition.constant, constant.other.symbol punctuation.definition.constant, constant.other.unit, keyword.other.unit, punctuation.section.flowtype, support.constant.unicode-range.prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Storage</string>\n        <key>scope</key>\n        <string>storage, storage.type.annotation, storage.type.primitive</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>storage.modifier.import, storage.modifier.package, storage.type.import, variable.import, variable.package</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Keyword</string>\n        <key>scope</key>\n        <string>entity.quasi.tag.name, meta.function storage.type.matlab, storage.type.function</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Variables</string>\n        <key>scope</key>\n        <string>entity.name.val.declaration, entity.name.variable, meta.definition.variable, storage.type.variable, support.type.custom-property, support.type.variable-name, variable, variable.interpolation variable, variable.other.interpolation variable, variable.parameter.dosbatch, variable.parameter.output.function.matlab, variable.parameter.sass</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Variable - Punctuation</string>\n        <key>scope</key>\n        <string>keyword.other.custom-property.prefix, punctuation.definition.custom-property, punctuation.definition.variable, support.constant.custom-property-name.prefix, variable.interpolation, variable.other.dollar punctuation.dollar, variable.other.object.dollar punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Declaration - Punctuation</string>\n        <key>scope</key>\n        <string>entity.name.function punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Object Properties</string>\n        <key>scope</key>\n        <string>meta.property.object</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Object Literal Properties</string>\n        <key>scope</key>\n        <string>constant.other.object.key string, meta.object-literal.key</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Parameters</string>\n        <key>scope</key>\n        <string>meta.parameters, variable.parameter</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SASS Import URL</string>\n        <key>scope</key>\n        <string>variable.parameter.url</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Language Constants</string>\n        <key>scope</key>\n        <string>constant, constant.numeric, constant.other, constant.other.color, constant.other.symbol, support.constant, support.constant.color, support.constant.font-name, support.constant.media, support.constant.prototype, variable.language</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Language Constants Punctuation</string>\n        <key>scope</key>\n        <string>variable.language punctuation.definition.variable</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>User-Defined Constants</string>\n        <key>scope</key>\n        <string>entity.name.constant, variable.other.constant</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Escaped Characters</string>\n        <key>scope</key>\n        <string>constant.character.escape, constant.character.escaped, constant.character.quoted, constant.other.character-class.escape</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Invalids and Illegals</string>\n        <key>scope</key>\n        <string>invalid</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n          <key>background</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Inner Scopes of Invalids and Illegals</string>\n        <key>scope</key>\n        <string>invalid keyword.other.custom-property.prefix, invalid support.type.custom-property.name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Errors</string>\n        <key>scope</key>\n        <string>message.error</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Strings</string>\n        <key>scope</key>\n        <string>meta.object-literal.key string, string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>JSON Keys</string>\n        <key>scope</key>\n        <string>meta.structure.dictionary.key.json string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Text</string>\n        <key>scope</key>\n        <string>source.regexp, string.regexp</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Start &amp; End Punctuation</string>\n        <key>scope</key>\n        <string>string.regexp punctuation.definition.string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Character Class Punctuation ([])</string>\n        <key>scope</key>\n        <string>keyword.control.set.regexp, punctuation.definition.character-class, string.regexp.character-class.ruby</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Capturing Group</string>\n        <key>scope</key>\n        <string>string.regexp.group</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Assertions</string>\n        <key>scope</key>\n        <string>constant.other.assertion.regexp, punctuation.definition.group.assertion.regexp, punctuation.definition.group.capture.regexp</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Character Class</string>\n        <key>scope</key>\n        <string>constant.other.character-class.escape.backslash.regexp, keyword.control.character-class.regexp, string.regexp.character-class constant.character.escape</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Regular Expressions Quantifiers &amp; Operators</string>\n        <key>scope</key>\n        <string>string.regexp.arbitrary-repetition, string.regexp.arbitrary-repetition punctuation</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Hyperlinks</string>\n        <key>scope</key>\n        <string>constant.other.reference.link, string.other.link</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Hyperlink Punctuation</string>\n        <key>scope</key>\n        <string>meta.image.inline punctuation.definition.string, meta.link.inline punctuation.definition.string, meta.link.reference punctuation.definition.constant, meta.link.reference.literal punctuation.definition.constant, meta.link.reference.literal punctuation.definition.string</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#689d6a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markup Tag Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Heading</string>\n        <key>scope</key>\n        <string>markup.heading</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Heading Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.heading, punctuation.definition.identity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Bold Text</string>\n        <key>scope</key>\n        <string>markup.bold</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#af3a03</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Bold Text Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bold</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d65d0e</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Italic Text</string>\n        <key>scope</key>\n        <string>markup.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n          <key>fontStyle</key>\n          <string>italic</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Italic Text Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#cc241d</string>\n          <key>fontStyle</key>\n          <string>italic</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Inline Code</string>\n        <key>scope</key>\n        <string>markup.raw.inline</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Inline Code Punctuation</string>\n        <key>scope</key>\n        <string>markup.raw.inline punctuation.definition.raw</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Quoted</string>\n        <key>scope</key>\n        <string>markup.quote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Quoted Punctuation</string>\n        <key>scope</key>\n        <string>markup.quote punctuation.definition.blockquote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown List</string>\n        <key>scope</key>\n        <string>markup.list</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown List Punctuation</string>\n        <key>scope</key>\n        <string>markup.list punctuation.definition.list_item</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Separators</string>\n        <key>scope</key>\n        <string>meta.separator.markdown</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Support</string>\n        <key>scope</key>\n        <string>meta.function-call.constructor variable.type, support.class, support.type, variable.other.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Supporting Type - Dollar Punctuation</string>\n        <key>scope</key>\n        <string>support.class punctuation.dollar</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Calls</string>\n        <key>scope</key>\n        <string>entity.name.function.jade, entity.name.function.pug, keyword.other.special-method, meta.function-call variable.function, meta.function-call variable.other.dollar.only punctuation.dollar, support.function</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Method Calls</string>\n        <key>scope</key>\n        <string>meta.function-call.method support.function, meta.function-call.method variable.function, meta.function-call.static variable.function, meta.method-call, meta.method-call support.function, meta.method-call variable.function, support.function.mutator</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#689d6a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Special Variables</string>\n        <key>scope</key>\n        <string>support.module</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Entities</string>\n        <key>scope</key>\n        <string>entity.name.accessor, entity.name.function, entity.name.label, entity.name.section</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Modules</string>\n        <key>scope</key>\n        <string>entity.name.module</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#af3a03</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS ID</string>\n        <key>scope</key>\n        <string>constant.id.tag, entity.name.tag.id, entity.other.attribute-name.id</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#af3a03</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS ID Punctuation (#)</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.id punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d65d0e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS Class</string>\n        <key>scope</key>\n        <string>entity.name.tag.class, entity.other.attribute-name.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; CSS Class Punctuation (.)</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.class punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Attribute Selector Attribute Name</string>\n        <key>scope</key>\n        <string>meta.attribute-selector entity.other.attribute-name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML &amp; XML Entity Punctuation</string>\n        <key>scope</key>\n        <string>constant.character.entity punctuation.definition.constant, constant.character.entity punctuation.definition.entity</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>entity.name.class, entity.name.type.class</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markup Tag</string>\n        <key>scope</key>\n        <string>entity.name.function.neon, entity.name.namespace.wildcard, entity.name.tag, entity.tag, keyword.control.untitled, keyword.doctype.xml, keyword.operator support.other.neon, punctuation.definition.prolog.haml, source.less keyword.control.html.elements</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HTML Attribute Names</string>\n        <key>scope</key>\n        <string>entity.name.attribute-name, entity.other.attribute-name, meta.section.attributes.haml constant.other.symbol.ruby</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Pseudo Elements/Classes &amp; Vendor Prefixes</string>\n        <key>scope</key>\n        <string>entity.other.attribute-name.placeholder punctuation.definition.entity, entity.other.attribute-name.pseudo-class, entity.other.attribute-name.pseudo-element, entity.other.attribute-name.tag.pseudo-class, entity.other.attribute-name.tag.pseudo-element, entity.other.pseudo-class, entity.other.pseudo-element, support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Animations / Keyframes</string>\n        <key>scope</key>\n        <string>entity.function-name.stylus, entity.other.animation-keyframe.stylus, entity.other.animation-name, keyword.language.function.misc.stylus, meta.at-rule.keyframes entity.name.function, variable.other.animation-name</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Author-Defined Names</string>\n        <key>scope</key>\n        <string>entity.other.namespace-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>meta.class.body, meta.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Image &amp; Hyperlink</string>\n        <key>scope</key>\n        <string>meta.image, meta.link</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Markdown Image &amp; Hyperlink Punctuation</string>\n        <key>scope</key>\n        <string>meta.image punctuation.definition.metadata, meta.link punctuation.definition.metadata</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>scope</key>\n        <string>meta.require</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Function Call Braces</string>\n        <key>scope</key>\n        <string>constant.name.attribute.tag.jade, constant.name.attribute.tag.pug, meta.brace.round, meta.function-call meta.group punctuation.definition.group, punctuation.definition.method-parameters, punctuation.definition.parameters</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Names</string>\n        <key>scope</key>\n        <string>meta.property-name, support.type.property-name, support.type.shape.definition support.constant.property-value</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Name Vendor Prefixes</string>\n        <key>scope</key>\n        <string>meta.property-name support.type.vendor-prefix, support.type.property-name.media support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#98971a</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Values</string>\n        <key>scope</key>\n        <string>constant.string.sass, meta.property-value, support.constant.property-value</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>CSS Property Value Vendor Prefixes</string>\n        <key>scope</key>\n        <string>meta.property-value support.type.vendor-prefix</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Foreground Text</string>\n        <key>scope</key>\n        <string>source.diff</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#7c6f64</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text From</string>\n        <key>scope</key>\n        <string>meta.diff.header.from-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text From Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.from-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#458588</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text To</string>\n        <key>scope</key>\n        <string>meta.diff.header.to-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Header Text To Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.to-file</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b16286</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Additions &amp; Deletions Stats</string>\n        <key>scope</key>\n        <string>meta.diff.range, meta.toc-list.line-number</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Diff Additions &amp; Deletions Stats Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.range.diff</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#d79921</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Line Number</string>\n        <key>scope</key>\n        <string>constant.numeric.line-number</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Line Number Matched</string>\n        <key>scope</key>\n        <string>constant.numeric.line-number.match</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>FiF Filename</string>\n        <key>scope</key>\n        <string>entity.name.filename</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Deleted</string>\n        <key>scope</key>\n        <string>markup.deleted, punctuation.definition.deleted</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Inserted</string>\n        <key>scope</key>\n        <string>markup.inserted, punctuation.definition.inserted</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter &amp; Diff Changed</string>\n        <key>scope</key>\n        <string>markup.changed, punctuation.definition.changed</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter ignored</string>\n        <key>scope</key>\n        <string>markup.ignored</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>GitGutter untracked</string>\n        <key>scope</key>\n        <string>markup.untracked</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Tag</string>\n        <key>scope</key>\n        <string>brackethighlighter.tag</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Curly</string>\n        <key>scope</key>\n        <string>brackethighlighter.curly</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Round</string>\n        <key>scope</key>\n        <string>brackethighlighter.round</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Square</string>\n        <key>scope</key>\n        <string>brackethighlighter.square</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Angle</string>\n        <key>scope</key>\n        <string>brackethighlighter.angle</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Quote</string>\n        <key>scope</key>\n        <string>brackethighlighter.quote</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Bracket Unmatched</string>\n        <key>scope</key>\n        <string>brackethighlighter.unmatched</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Error</string>\n        <key>scope</key>\n        <string>sublimelinter.mark.error</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Gutter Mark</string>\n        <key>scope</key>\n        <string>sublimelinter.gutter-mark</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>SublimeLinter Warning</string>\n        <key>scope</key>\n        <string>sublimelinter.mark.warning</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Upper Byte Nibble</string>\n        <key>scope</key>\n        <string>raw.nibble.upper</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Lower Byte Nibble</string>\n        <key>scope</key>\n        <string>raw.nibble.lower</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Highlight</string>\n        <key>scope</key>\n        <string>hexviewer.highlight</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n          <key>background</key>\n          <string>#b57614</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>HexViewer Edited Highlight</string>\n        <key>scope</key>\n        <string>hexviewer.highlight.edited</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#f9f5d7</string>\n          <key>background</key>\n          <string>#af3a03</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Raw New Line: Carriage Return</string>\n        <key>scope</key>\n        <string>glyph.carriage-return</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#3c383626</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>Raw New Line: New Line Glyph</string>\n        <key>scope</key>\n        <string>glyph.new-line</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#3c383626</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Header</string>\n        <key>scope</key>\n        <string>keyword.control.header.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#79740e</string>\n          <key>background</key>\n          <string>#fefdf6</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Notes</string>\n        <key>scope</key>\n        <string>notes.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#665c54</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Punctuation</string>\n        <key>scope</key>\n        <string>text.todo punctuation.definition.bold, text.todo punctuation.definition.italic</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#a89984</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Pending</string>\n        <key>scope</key>\n        <string>meta.item.todo.pending</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#1d2021</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Pending Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.pending.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Completed Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.completed.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#427b58</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Task Cancelled Punctuation</string>\n        <key>scope</key>\n        <string>punctuation.definition.bullet.cancelled.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Critical</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.critical</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#9d0006</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag High</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.high</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#af3a03</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Low</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.low</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag Today</string>\n        <key>scope</key>\n        <string>string.other.tag.todo.today</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#b57614</string>\n          <key>fontStyle</key>\n          <string>bold</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Tag</string>\n        <key>scope</key>\n        <string>meta.tag.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#8f3f71</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: URL</string>\n        <key>scope</key>\n        <string>punctuation.definition.url, todo.url</string>\n        <key>settings</key>\n        <dict>\n          <key>foreground</key>\n          <string>#076678</string>\n        </dict>\n      </dict>\n      <dict>\n        <key>name</key>\n        <string>PlainTasks: Separator</string>\n        <key>scope</key>\n        <string>meta.punctuation.archive.todo, meta.punctuation.separator.todo</string>\n        <key>settings</key>\n        <dict>\n          <key>fontStyle</key>\n          <string>italic</string>\n          <key>foreground</key>\n          <string>#928374</string>\n        </dict>\n      </dict>\n    </array>\n  </dict>\n</plist>"
  },
  {
    "path": "tool/tmthemes/iPlastic.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>author</key>\n\t<string>Jeroen van der Ham</string>\n\t<key>name</key>\n\t<string>iPlastic</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#EEEEEEEB</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#B3B3B3F4</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#0000001A</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#BAD6FD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#009933</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0066FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Regular expression</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF0080</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0000FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Identifier</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9700CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#990000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF8000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Arguments</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0066FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#E71A114D</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF0000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Trailing whitespace</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.deprecated.trailing-whitespace</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#E71A1100</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FAFAFAFC</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#0033CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant, support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6782D3</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3333FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Section name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Frame title</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function.frame</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>XML Declaration</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag.preprocessor.xml</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#333333</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag Attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#3366CC</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>4FCFA210-B247-11D9-9D00-000D93347A42</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/idleFingers.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>idleFingers</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#323232</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#91FF00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#404040</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#353637</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#5A647EE0</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>text</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Source base</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#282828</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CDCDCD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BC9458</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Html Tags</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, declaration.tag, meta.doctype</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFE5BB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFC66D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Ruby Function Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source.ruby entity.name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFF980</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Other Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B7DFF8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Ruby Class Name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class.ruby</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCC33</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant, support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6C99BB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CC7833</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Pre-processor Line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>other.preprocessor.c</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D0D0FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Pre-processor Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Block comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>source comment.block</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#575757</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A5C261</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String escapes</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant.character.escape</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AAAAAA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String (executed)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.interpolated</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#CCCC33</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Regular expression</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCC33</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String (literal)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.literal</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CCCC33</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String escapes (executed)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.interpolated constant.character.escape</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#787878</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class inheritance</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic underline</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B83426</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Textile List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list.unnumbered.textile</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6EA533</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Textile Numbered list</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list.numbered.textile</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#6EA533</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Textile Bold</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold.textile</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C2C2C2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FF0000</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>User1</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>collab.user1</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFF980</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#323232</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>95BEF169-A2E5-4041-A84A-AAFC1DD61558</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/krTheme.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>comment</key>\n\t<string>Created by Kenneth Reitz, inspired by minimal design</string>\n\t<key>name</key>\n\t<string>krTheme</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0B0A09</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FF9900</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FCFFE0</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#FFB16F52</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#38403D</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#AA00FF73</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D27518C2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A89100B5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity Other</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BA6912</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#949C8B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Storage</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFEE80</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string -string.unquoted.old-plist -string.unquoted.heredoc, string.unquoted.heredoc string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C7A4A1B5</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#706D5B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9FC28A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D1A796</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Lang Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF80E1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function Call</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.function-call</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFEE80</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#A41300</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded Source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>text source, string.unquoted.heredoc, source source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#24231D4D</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#D9D59F</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Entity inherited-class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7EFCFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String embedded-source</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.quoted source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#439740BA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#60DB5DBA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String.regexp</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.regexp</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7DFFC0A6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#B8B960</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#85873A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Support.constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C27E66</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Exception</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class.exception</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FF1E00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>C/C++ Preprocessor Line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#8996A8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>C/C++ Preprocessor Directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.c keyword</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AFC4DB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Doctype/XML Processing</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#73817D</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Meta.tag.A</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.tag, meta.tag entity</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#BABD9C</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css tag-name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#99A190</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css#id</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.id</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CC8844</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css.class</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.selector.css entity.other.attribute-name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#CFB958</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property-name:</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.type.property-name.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E0DDAD</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css property-value;</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#AEB14B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css @at-rule</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.preprocessor.at-rule keyword.control.at-rule</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFB010</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css additional-constants</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.property-value support.constant.named-color.css, meta.property-value constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#999179</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>css constructor.argument</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.constructor.argument.css</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#EB939A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.header</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.diff, meta.diff.header</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#000E1A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.deleted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.deleted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#800F00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.changed</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.changed</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#806F00</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>diff.inserted</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.inserted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#228000</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#F8F8F8</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Raw Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.raw</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#8FDDF630</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Block Quote</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.quote</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#005BAA</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>List</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.list</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#0F0040</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Bold Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.bold</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9D80FF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Italic Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.italic</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>italic</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#80FFBB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Heading Markup</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>markup.heading</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string>bold</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>87F051F7-B6FB-408C-96F9-467B66C14E9F</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/tmthemes/monoindustrial.tmTheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>monoindustrial</string>\n\t<key>settings</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#222C28</string>\n\t\t\t\t<key>caret</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t\t<key>invisibles</key>\n\t\t\t\t<string>#666C6880</string>\n\t\t\t\t<key>lineHighlight</key>\n\t\t\t\t<string>#0C0D0C40</string>\n\t\t\t\t<key>selection</key>\n\t\t\t\t<string>#91999466</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Comment</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>comment</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#151C19</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#666C68</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Type</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage, support.type</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C23B00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Embedded code</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string.unquoted.embedded, text source, string.unquoted</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#151C19</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String interpolation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.character.escaped, string source - string.unquoted.embedded, string string source</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#1A0700</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E9470000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>String</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>string - string source, string source string, meta.scope.heredoc</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#1A0700</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C23800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Number</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant.numeric</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E98800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.language, variable.other</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#648BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#E98800</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Preprocessor line</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>other.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#161D1A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A8B3AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Preprocessor directive</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.preprocessor</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#161D1A</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A8B3AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.function, keyword.operator, keyword.other.name-of-parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A8B3AB</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#9A2F00</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function parameter</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>variable.parameter</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#648BD2</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Function argument and result types</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>storage.type.method</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#666C68</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Keyword</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>keyword, storage.type.function.php</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A39E64</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#990000AD</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Invalid trailing whitespace</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>invalid.trailing-whitespace</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#FFD0D0</string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#000000</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library function</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.function</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#588E60</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library object</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.class, support.type, entity.name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5778B6</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library constant</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.constant</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#C87500</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Library variable</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>support.other.variable</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#5879B7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup XML declaration</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.xml-processing</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#68685B</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup DOCTYPE</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.doctype</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#888888</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup DTD</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.doctype.DTD</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#888888</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>declaration.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A65EFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup name of tag</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.name.tag</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#A65EFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Markup tag attribute</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.attribute-name</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#909993</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Punctuation</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>punctuation</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#90999380</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Inherited class name</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>entity.other.inherited-class</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#7642B7</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Changed files (Subversion)</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.scope.changed-files.svn, markup.inserted.svn, markup.changed.svn, markup.deleted.svn</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#00000059</string>\n\t\t\t\t<key>fontStyle</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>foreground</key>\n\t\t\t\t<string>#FFFFFF</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blocks, Expressions 1</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#78807B0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blocks, Expressions 2</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.section meta.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#78807B0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blocks, Expressions 3</string>\n\t\t\t<key>scope</key>\n\t\t\t<string>meta.section meta.section meta.section</string>\n\t\t\t<key>settings</key>\n\t\t\t<dict>\n\t\t\t\t<key>background</key>\n\t\t\t\t<string>#78807B0A</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n\t<key>uuid</key>\n\t<string>EEA328BA-54E5-49DC-81F3-1F25BF8AF163</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "tool/unicode.js",
    "content": "\"use strict\";\n\n/*\nXRegExp Unicode plugin pack: Categories 1.0\n(c) 2010 Steven Levithan\nMIT License\n<http://xregexp.com>\nUses the Unicode 5.2 character database\n\nThis package for the XRegExp Unicode plugin enables the following Unicode categories (aka properties):\n\nL - Letter (the top-level Letter category is included in the Unicode plugin base script)\n    Ll - Lowercase letter\n    Lu - Uppercase letter\n    Lt - Titlecase letter\n    Lm - Modifier letter\n    Lo - Letter without case\nM - Mark\n    Mn - Non-spacing mark\n    Mc - Spacing combining mark\n    Me - Enclosing mark\nN - Number\n    Nd - Decimal digit\n    Nl - Letter number\n    No -  Other number\nP - Punctuation\n    Pd - Dash punctuation\n    Ps - Open punctuation\n    Pe - Close punctuation\n    Pi - Initial punctuation\n    Pf - Final punctuation\n    Pc - Connector punctuation\n    Po - Other punctuation\nS - Symbol\n    Sm - Math symbol\n    Sc - Currency symbol\n    Sk - Modifier symbol\n    So - Other symbol\nZ - Separator\n    Zs - Space separator\n    Zl - Line separator\n    Zp - Paragraph separator\nC - Other\n    Cc - Control\n    Cf - Format\n    Co - Private use\n    Cs - Surrogate\n    Cn - Unassigned\n\nExample usage:\n\n    \\p{N}\n    \\p{Cn}\n*/\n\n\n// will be populated by addUnicodePackage\nvar packages = {\n    L:  \"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n    Ll: \"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A\",\n    Lu: \"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A\",\n    Lt: \"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC\",\n    Lm: \"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F\",\n    Lo: \"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n    M:  \"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26\",\n    Mn: \"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26\",\n    Mc: \"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC\",\n    Me: \"0488048906DE20DD-20E020E2-20E4A670-A672\",\n    N:  \"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n    Nd: \"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n    Nl: \"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF\",\n    No: \"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835\",\n    P:  \"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65\",\n    Pd: \"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D\",\n    Ps: \"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62\",\n    Pe: \"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63\",\n    Pi: \"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20\",\n    Pf: \"00BB2019201D203A2E032E052E0A2E0D2E1D2E21\",\n    Pc: \"005F203F20402054FE33FE34FE4D-FE4FFF3F\",\n    Po: \"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65\",\n    S:  \"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD\",\n    Sm: \"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC\",\n    Sc: \"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6\",\n    Sk: \"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3\",\n    So: \"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD\",\n    Z:  \"002000A01680180E2000-200A20282029202F205F3000\",\n    Zs: \"002000A01680180E2000-200A202F205F3000\",\n    Zl: \"2028\",\n    Zp: \"2029\",\n    C:  \"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF\",\n    Cc: \"0000-001F007F-009F\",\n    Cf: \"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB\",\n    Co: \"E000-F8FF\",\n    Cs: \"D800-DFFF\",\n    Cn: \"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF\"\n};\n\nfunction mergeRanges(charString) {\n    function toChar(code) {\n        var str = code.toString(16);\n        return \"0\".repeat(4 - str.length) + str;\n    }\n    var ranges = [];\n    charString.replace(/(\\w{4})(?:-(\\w{4}))?/g, function(_, a, b) {\n        ranges.push([parseInt(a, 16), parseInt(b || a, 16)]);\n    });\n    ranges = ranges.sort(function(a, b) { return a[0] - b[0] });\n    for (var i = 1; i < ranges.length; i++) {\n        if (ranges[i - 1][1] + 1 >= ranges[i][0]) {\n            ranges[i] = [ranges[i - 1][0], Math.max(ranges[i - 1][1], ranges[i][1])];\n            ranges[i - 1] = null;\n        }\n    }\n    return ranges.map(function(r) {\n        if (!r) \n            return \"\";\n        if (r[0] == r[1])\n            return toChar(r[1]);\n        return toChar(r[0]) + \"-\" + toChar(r[1]);\n    }).join(\"\");\n}\n\nfunction test() {\n    function toRegex(chars) { \n        return new RegExp(\"^[\" + chars.replace(/\\w{4}/g, \"\\\\u$&\") + \"]\");\n    }\n\n    var re1 = toRegex(wordChars)\n    var re2 = toRegex(wordCharsMerged)\n    var re3 = RegExp(\"^[\" + unicode.wordChars + \"]\");\n\n\n    for (var i = 0; i < 0xffff; i++) {\n        var ch = String.fromCharCode(i);\n        if (re1.test(ch) != re2.test(ch)) {\n            throw new Error(\"char: \" + ch + \", code: \" + i);\n        }\n        if (re3.test(ch) != re2.test(ch)) {\n            throw new Error(\"char: \" + ch + \", code: \" + i);\n        }\n    }\n}\n\nfunction toRollingSum(str) {\n    var charCodes = [];\n    str.replace(/(\\w{4})(?:-(\\w{4}))?/g, function(_, a, b) {\n        charCodes.push(parseInt(a, 16)); \n        charCodes.push(parseInt(b, 16) || 0) \n    });\n    var sum = 0; \n    return charCodes.map(function(c) { \n        if (c) { \n            var c1 = c;\n            c = c - sum;\n            sum = c1;  \n        }\n        return c;\n    });\n}\n \nvar wordChars = packages.L\n    + packages.Mn + packages.Mc\n    + packages.Nd\n    + packages.Pc;\n\nvar wordCharsMerged = mergeRanges(wordChars);\nvar wordCharCodes = toRollingSum(wordCharsMerged);\n\nvar fs = require(\"fs\");\nvar path = __dirname + \"/../lib/ace/unicode.js\"\nvar value = fs.readFileSync(path, \"utf8\");\nvalue = value.replace(/(var wordChars = )[\\[\"].*[\"\\]](;)/, function(_, $1, $2) {\n    return $1 + JSON.stringify(wordCharCodes) + $2;\n});\n\nfs.writeFileSync(path, value, \"utf8\");\n\nrequire(\"amd-loader\")\nvar unicode = require(path);\ntest();\n\n\n\n\n"
  },
  {
    "path": "tool/update_deps.js",
    "content": "var https = require(\"https\");\nvar http = require(\"http\");\nvar url = require(\"url\");\nvar fs = require(\"fs\");\n\nvar Path = require(\"path\");\nvar spawn = require(\"child_process\").spawn;\nvar async = require(\"asyncjs\");\nvar rootDir = __dirname + \"/../lib/ace/\";\n\nvar SKIP_NPM = false;\n\nvar deps = {\n    csslint: {\n        path: \"mode/css/csslint.js\",\n        // url: \"https://raw.github.com/stubbornella/csslint/master/release/csslint.js\",\n        browserify: {\n            npmModule: \"git+https://github.com/CSSLint/csslint.git#master\",\n            path: \"jshint/src/jshint.js\",\n            exports: \"jshint\"\n        },\n        fetch: browserify,\n        wrapAmd: true\n    }, \n    requirejs: {\n        path: \"../../demo/kitchen-sink/require.js\",\n        url: \"https://raw.github.com/jrburke/requirejs/master/require.js\",\n        wrapAmd: false\n    },\n    luaparse: {\n        path: \"mode/lua/luaparse.js\",\n        url: \"https://raw.githubusercontent.com/fstirlitz/luaparse/master/luaparse.js\",\n        wrapAmd: true,\n        postProcess: function(src) {\n            return src.replace(\n                /\\(function\\s*\\(root,\\s*name,\\s*factory\\)\\s*{[\\s\\S]*?}\\(this,\\s*'luaparse',/,\n                \"(function (root, name, factory) {\\n   factory(exports)\\n}(this, 'luaparse',\"\n            )\n        }\n    },\n    html5: {\n        path: \"mode/html/saxparser.js\",\n        browserify: {\n            npmModule: \"git+https://github.com/aredridel/html5.git#master\",\n            path: \"html5/lib/sax/SAXParser.js\",  \n            exports: \"SAXParser\"\n        },\n        fetch: browserify,\n        wrapAmd: true,\n        postProcess: function(src) {\n            return src;\n        }\n    },\n    xquery: {\n       path: \"mode/xquery/xquery_lexer.js\",\n       browserify: {\n           npmModule: \"git+https://github.com/wcandillon/xqlint.git#master\",\n           path: \"xqlint/lib/lexers/xquery_lexer.js\",\n           exports: \"XQueryLexer\"\n       },\n       fetch: browserify,\n       wrapAmd: true,\n       postProcess: function(src){\n           return src;\n       }\n    },\n    jsoniq: {\n       path: \"mode/xquery/jsoniq_lexer.js\",\n       browserify: {\n           npmModule: \"git+https://github.com/wcandillon/xqlint.git#master\",\n           path: \"xqlint/lib/lexers/jsoniq_lexer.js\",\n           exports: \"JSONiqLexer\"\n       },\n       fetch: browserify,\n       wrapAmd: true,\n       postProcess: function(src){\n           return src;\n       }\n    },\n    xqlint: {\n       path: \"mode/xquery/xqlint.js\",\n       browserify: {\n           npmModule: \"git+https://github.com/wcandillon/xqlint.git#master\",\n           path: \"xqlint/lib/xqlint.js\",\n           exports: \"XQLint\"\n       },\n       fetch: browserify,\n       wrapAmd: true,\n       postProcess: function(src){\n           return src;\n       }\n    },\n    jshint: {\n        path: \"mode/javascript/jshint.js\",\n        browserify: {\n            npmModule: \"git+https://github.com/ajaxorg/jshint.git#master\",\n            path: \"jshint/src/jshint.js\",\n            exports: \"jshint\"\n        },\n        fetch: browserify,\n        wrapAmd: true,\n        postProcess: function(src) {\n            src = src.replace(\n                /\"Expected a conditional expression and instead saw an assignment.\"/g,\n                '\"Assignment in conditional expression\"'\n            );\n            src = src.replace(/var defaultMaxListeners = 10;/, function(a) {return a.replace(\"10\", \"200\")});\n            return src;\n        }\n    }, \n    emmet: {\n        path: \"ext/emmet core.js\",\n        url: [\n            \"https://raw.github.com/sergeche/emmet-sublime/master/emmet/emmet-app.js\",\n            \"https://raw.github.com/sergeche/emmet-sublime/master/emmet/snippets.json\"\n        ],\n        postProcess: function(data) {\n            return data[0]\n                .replace(\"define(emmet)\", \"define('emmet', [], emmet)\")\n                .replace(/(emmet.define\\('bootstrap'.*)[\\s\\S]*$/, function(_, x) {\n                    return x + \"\\n\" +\n                        \"var snippets = \" + data[1] + \";\\n\" +\n                        \"var res = require('resources');\\n\" +\n                        \"var userData = res.getVocabulary('user') || {};\\n\" +\n                        \"res.setVocabulary(require('utils').deepMerge(userData, snippets), 'user');\\n\" +\n                        \"});\";\n            });\n        }\n    },\n    vim: {\n        fetch: function(){\n            var rootHref = \"https://raw.githubusercontent.com/codemirror/CodeMirror/master/\"\n            var fileMap = {\"keymap/vim.js\": \"keyboard/vim.js\", \"test/vim_test.js\": \"keyboard/vim_test.js\"};\n            async.forEach(Object.keys(fileMap), function(x, next) {\n                download(rootHref + x, function(e, d) {\n                    d = d.replace(/^\\(function.*{[^{}]+^}[^{}]+{/m, \"define(function(require, exports, module) {\");\n                    d = d.replace(/^\\s*return vimApi;\\s*};/gm, \"  //};\")\n                        .replace(\"var Vim = function() {\", \"$& return vimApi; } //{\")\n                    fs.writeFile(rootDir + fileMap[x], d, next)\n                })\n            }, function() {\n                console.log(\"done\")\n            });\n        }\n    },\n    liveScript: {\n        path: \"mode/livescript.js\",\n        url: \"https://raw.githubusercontent.com/gkz/LiveScript/master/lib/mode-ls.js\"        \n    },\n    coffee: {\n        path: \"mode/coffee/coffee.js\",\n        url: \"https://raw.githubusercontent.com/jashkenas/coffeescript/master/extras/coffee-script.js\",    \n        wrapAmd: true,\n        postProcess: function(src){\n            return \"function define(f) { module.exports = f() }; define.amd = {};\\n\"\n                + dereqire(src);\n        }\n    },\n    xmldom: {\n        fetch: function() {\n            var rootHref = \"https://raw.githubusercontent.com/iDeBugger/xmldom/master/\"\n            var fileMap = {\n               \"sax.js\": \"mode/xml/sax.js\",\n               \"dom-parser.js\": \"mode/xml/dom-parser.js\",\n               \"dom.js\": \"mode/xml/dom.js\"\n            };\n            async.forEach(Object.keys(fileMap), function(x, next) {\n                download(rootHref + x, function(e, d) {\n                    fs.writeFile(rootDir + fileMap[x], d, next)\n                })\n            }, function() {\n                console.log(\"XmlDOM updating done\")\n            });\n        }\n    },\n};\n\nvar download = function(href, callback) {\n    if (Array.isArray(href))\n        return async.map(href, download, callback);\n\n    var options = url.parse(href);\n    var protocol = options.protocol === \"https:\" ? https : http;\n    console.log(\"connecting to \" + options.host + \" \" + options.path);\n    protocol.get(options, function(res) {\n        var data = \"\";\n        res.setEncoding(\"utf-8\");\n\n        res.on(\"data\", function(chunk){\n            data += chunk;\n        });\n\n        res.on(\"end\", function(){\n            callback(null, data);\n        });\n    });\n};\n\nvar getDep = function(dep) {\n    if (!dep.fetch)\n        dep.fetch = download\n    dep.fetch(dep.url, function(err, data) {\n        if (dep.postProcess)\n            data = dep.postProcess(data);\n        if (dep.wrapAmd)\n            data = \"define(function(require, exports, module) {\\n\"\n                + data\n                + \"\\n});\";\n\n        fs.writeFile(rootDir + dep.path, data, \"utf-8\", function(err){\n            if (err) throw err;\n            console.log(\"File \" + dep.path + \" saved.\");\n        });\n    });\n};\n\nfunction run(cmd, cb) {\n\tvar proc = process.platform == \"win32\"\n        ? spawn(\"cmd\", [\"/c\", cmd], {cwd: __dirname})\n        : spawn(\"bash\", [\"-c\", cmd], {cwd: __dirname});\n\n    var result = \"\", err = \"\";\n\tproc.stderr.setEncoding(\"utf8\");    \n\tproc.stderr.on('data', function (data) {\n        err += data;\n\t});\n\n\tproc.stdout.setEncoding(\"utf8\");\n\tproc.stdout.on('data', function (data) {\n        result += data;\n\t});\n\n    proc.on('close', done);\n    function done(code) {\n        if (code !== 0) {\n            console.error(cmd + '::: process exited with code :::' + code);\n            console.error(err)\n        }\n        cb(err, result)\n    }\n}\n\nfunction unquote(str) {\n    return str.replace(/\\\\(.)/g, function(x, a) {\n        return a == \"n\" ? \"\\n\" \n            : a == \"t\" ? \"\\t\" \n            : a == \"r\" ? \"\\r\"\n            : a\n    });\n}\n\nfunction dereqire(src) {\n    return require(\"derequire\")(src, [\n        {from: 'require', to: '_dereq_'},\n        {from: 'define', to: '_defi_'}\n    ]);\n}\n\nfunction browserify(_, cb) {\n    var br = this.browserify;\n    var path = Path.join(\"node_modules\", br.path)\n    process.chdir(__dirname);\n    if (Path.sep == \"\\\\\" && !Path._relative) {\n        Path._relative = Path.relative;\n        Path.relative = function() {\n            var v = Path._relative.apply(this, arguments);\n            return v.replace(/\\\\/g, \"/\");\n        }\n    }\n    function done() {\n        var browserify = require('browserify');\n        var absPath = require.resolve(__dirname + \"/\" + path);\n        var defaultPreludePath = Path.join(require.resolve(\"browser-pack\"), \"../prelude.js\");\n        var defaultPrelude = \"module.exports = \" + fs.readFileSync(defaultPreludePath, 'utf8')\n            .replace(/^[ \\t]*\\/\\/.*/gm, \"\")\n            .replace(/^\\s*\\n\\r?/gm, \"\")\n            .replace(/return newRequire;/, \"return newRequire(entry[0]);\")\n        var opts = {\n            expose: br.exports,\n            prelude: defaultPrelude,\n            exposeAll: true\n        }\n        var b = browserify(opts);\n        b.plugin(require(\"deps-sort\"), opts);\n        b.add(absPath);\n        var p = b.bundle();\n        var buffer = \"\";\n        p.on(\"data\", function(e) { buffer += e; });\n        p.on(\"end\", function() {\n            var src = dereqire(buffer);\n            cb(null, src);\n        });\n    }\n    if (SKIP_NPM) return done();\n    run(\"npm install \" + br.npmModule,  done);\n}\n\nvar args = process.argv.slice(2);\nSKIP_NPM = args.indexOf(\"--skip-npm\") != -1;\nargs = args.filter(function(x) {return x[0] != \"-\" });\nif (!args.length)\n    args = Object.keys(deps);\n    \nargs.forEach(function(key) {\n    getDep(deps[key])\n});\n\n"
  },
  {
    "path": "tool/wrap_keyword_regexp.js",
    "content": "// a little script to turn giant keyword regexps into\n// something that ace can use; for example: \n//\n// \\b(NS(Rect(ToCGRect|FromCGRect)|MakeCollectable|S(tringFromProtocol))\\b\n// \n// into\n//\n// (?:\\\\b)(NS(?:Rect(?:ToCGRect|FromCGRect)|MakeCollectable|S(?:tringFromProtocol))(?:\\b)\n\nvar inputString = process.argv.splice(2)[0];\n\n// solve word boundaries\nvar outputString = inputString.replace(/\\\\b/g, \"(?:\\\\\\\\b)\");\n\n// I apparently need to do this, instead of something clever, because the regexp\n// lastIndex is screwing up my positional\noutputString = outputString.split(\"b)(\");\n\noutputString = outputString[0] + \"b)(\" + outputString[1].replace(/\\(([^\\?])/g, \"(?:$1\");\n\nconsole.log(\"\\n\\n\" + outputString + \"\\n\\n\");"
  },
  {
    "path": "translations/Readme.md",
    "content": "### Generating new translation file\n- Create a `JSON` file in this folder named `<language_id>.json`.\n- Add `{\"$id\": \"<language_id>\"}` to the empty file.\n- Run `node Makefile.dryice.js nls` in the root of the repository to generate empty translation file."
  },
  {
    "path": "translations/am.json",
    "content": "{\n    \"$id\": \"am\",\n    \"autocomplete.popup.aria-roledescription\": \"Ավտոմատ լրացման առաջարկներ\",\n    \"autocomplete.popup.aria-label\": \"\",\n    \"autocomplete.popup.item.aria-roledescription\": \"\",\n    \"autocomplete.loading\": \"Բեռնվում է...\",\n    \"editor.scroller.aria-roledescription\": \"\",\n    \"editor.scroller.aria-label\": \"\",\n    \"editor.gutter.aria-roledescription\": \"\",\n    \"editor.gutter.aria-label\": \"\",\n    \"error-marker.good-state\": \"Սխալ չկա\",\n    \"prompt.recently-used\": \"Վերջերս օգտագործված\",\n    \"prompt.other-commands\": \"Այլ հրամաններ\",\n    \"prompt.no-matching-commands\": \"Չկան համապատասխան հրամաններ\",\n    \"search-box.find.placeholder\": \"Փնտրել\",\n    \"search-box.find-all.text\": \"Բոլորը\",\n    \"search-box.replace.placeholder\": \"Փոխարինել\",\n    \"search-box.replace-next.text\": \"Փոխարինել\",\n    \"search-box.replace-all.text\": \"\",\n    \"search-box.toggle-replace.title\": \"\",\n    \"search-box.toggle-regexp.title\": \"Փնտրել ռեգեքսպով\",\n    \"search-box.toggle-case.title\": \"\",\n    \"search-box.toggle-whole-word.title\": \"Ամբողջ բառեր\",\n    \"search-box.toggle-in-selection.title\": \"Փնտրել նշվածում\",\n    \"search-box.search-counter\": \"$1-ից $0\",\n    \"text-input.aria-roledescription\": \"\",\n    \"text-input.aria-label\": \"\",\n    \"gutter.code-folding.range.aria-label\": \"\",\n    \"gutter.code-folding.closed.aria-label\": \"\",\n    \"gutter.code-folding.open.aria-label\": \"\",\n    \"gutter.code-folding.closed.title\": \"\",\n    \"gutter.code-folding.open.title\": \"\",\n    \"gutter.annotation.aria-label.error\": \"\",\n    \"gutter.annotation.aria-label.warning\": \"\",\n    \"gutter.annotation.aria-label.info\": \"\",\n    \"inline-fold.closed.title\": \"\",\n    \"gutter-tooltip.aria-label.error.singular\": \"սխալ\",\n    \"gutter-tooltip.aria-label.error.plural\": \"սխալներ\",\n    \"gutter-tooltip.aria-label.warning.singular\": \"նախազգուշացում\",\n    \"gutter-tooltip.aria-label.warning.plural\": \"նախազգուշացումներ\",\n    \"gutter-tooltip.aria-label.info.singular\": \"տեղեկատվություն\",\n    \"gutter-tooltip.aria-label.info.plural\": \"տեղեկատվություններ\",\n    \"gutter.annotation.aria-label.security\": \"\",\n    \"gutter.annotation.aria-label.hint\": \"\",\n    \"gutter-tooltip.aria-label.security.singular\": \"\",\n    \"gutter-tooltip.aria-label.security.plural\": \"\",\n    \"gutter-tooltip.aria-label.hint.singular\": \"\",\n    \"gutter-tooltip.aria-label.hint.plural\": \"\"\n}"
  },
  {
    "path": "translations/es.json",
    "content": "{\n    \"$id\": \"es\",\n    \"autocomplete.popup.aria-roledescription\": \"Sugerencias de autocompletar\",\n    \"autocomplete.popup.aria-label\": \"Sugerencias de autocompletar\",\n    \"autocomplete.popup.item.aria-roledescription\": \"\",\n    \"autocomplete.loading\": \"Cargando...\",\n    \"editor.scroller.aria-roledescription\": \"editor\",\n    \"editor.scroller.aria-label\": \"Contenido del editor, presiona Entrar para empezar a editar, presiona Escape para salir\",\n    \"editor.gutter.aria-roledescription\": \"editor\",\n    \"editor.gutter.aria-label\": \"Canaleta de editor, presiona Entrar para por, presiona Escape para salir\",\n    \"error-marker.good-state\": \"¡Parece bien!\",\n    \"prompt.recently-used\": \"Usado recientemente\",\n    \"prompt.other-commands\": \"Otros mandos\",\n    \"prompt.no-matching-commands\": \"No hay mandos que hacen juego\",\n    \"search-box.find.placeholder\": \"Todo\",\n    \"search-box.find-all.text\": \"\",\n    \"search-box.replace.placeholder\": \"Reemplazar con\",\n    \"search-box.replace-next.text\": \"Reemplazar\",\n    \"search-box.replace-all.text\": \"Todo\",\n    \"search-box.toggle-replace.title\": \"Pasar el modo de reemplazar\",\n    \"search-box.toggle-regexp.title\": \"Búsqueda de RegExp\",\n    \"search-box.toggle-case.title\": \"Búsqueda sensible a mayúsculas y minúsculas\",\n    \"search-box.toggle-whole-word.title\": \"Búsqueda de palabras enteras\",\n    \"search-box.toggle-in-selection.title\": \"Buscar en la selección\",\n    \"search-box.search-counter\": \"$0 de $1\",\n    \"text-input.aria-roledescription\": \"editor\",\n    \"text-input.aria-label\": \"Cursor en row $0\",\n    \"gutter.code-folding.range.aria-label\": \"\",\n    \"gutter.code-folding.closed.aria-label\": \"\",\n    \"gutter.code-folding.open.aria-label\": \"\",\n    \"gutter.code-folding.closed.title\": \"Desplegar el codigo\",\n    \"gutter.code-folding.open.title\": \"Plegar el codigo\",\n    \"gutter.annotation.aria-label.error\": \"Leer anotaciones fila $0\",\n    \"gutter.annotation.aria-label.warning\": \"Leer anotaciones fila $0\",\n    \"gutter.annotation.aria-label.info\": \"Leer anotaciones fila $0\",\n    \"inline-fold.closed.title\": \"Desplegar el codigo\",\n    \"gutter-tooltip.aria-label.error.singular\": \"error\",\n    \"gutter-tooltip.aria-label.error.plural\": \"errores\",\n    \"gutter-tooltip.aria-label.warning.singular\": \"advertencia\",\n    \"gutter-tooltip.aria-label.warning.plural\": \"advertencias\",\n    \"gutter-tooltip.aria-label.info.singular\": \"mensaje de informacion\",\n    \"gutter-tooltip.aria-label.info.plural\": \"mensajes de informacion\",\n    \"gutter.annotation.aria-label.security\": \"\",\n    \"gutter.annotation.aria-label.hint\": \"\",\n    \"gutter-tooltip.aria-label.security.singular\": \"\",\n    \"gutter-tooltip.aria-label.security.plural\": \"\",\n    \"gutter-tooltip.aria-label.hint.singular\": \"\",\n    \"gutter-tooltip.aria-label.hint.plural\": \"\"\n}"
  },
  {
    "path": "translations/ru.json",
    "content": "{\n    \"$id\": \"ru\",\n    \"autocomplete.popup.aria-roledescription\": \"\",\n    \"autocomplete.popup.aria-label\": \"Предложения автозаполнения\",\n    \"autocomplete.popup.item.aria-roledescription\": \"\",\n    \"autocomplete.loading\": \"Загрузка...\",\n    \"editor.scroller.aria-roledescription\": \"\",\n    \"editor.scroller.aria-label\": \"\",\n    \"editor.gutter.aria-roledescription\": \"\",\n    \"editor.gutter.aria-label\": \"\",\n    \"error-marker.good-state\": \"Нет ошибок\",\n    \"prompt.recently-used\": \"Недавно использованные\",\n    \"prompt.other-commands\": \"Другие команды\",\n    \"prompt.no-matching-commands\": \"Нет подходящих команд\",\n    \"search-box.find.placeholder\": \"Найти\",\n    \"search-box.find-all.text\": \"Все\",\n    \"search-box.replace.placeholder\": \"Заменить\",\n    \"search-box.replace-next.text\": \"Заменить\",\n    \"search-box.replace-all.text\": \"\",\n    \"search-box.toggle-replace.title\": \"Перейти в режим поиска\",\n    \"search-box.toggle-regexp.title\": \"Поиск по регулярному выражению\",\n    \"search-box.toggle-case.title\": \"\",\n    \"search-box.toggle-whole-word.title\": \"\",\n    \"search-box.toggle-in-selection.title\": \"Искать в выделенном\",\n    \"search-box.search-counter\": \"$0 из $1\",\n    \"text-input.aria-roledescription\": \"\",\n    \"text-input.aria-label\": \"\",\n    \"gutter.code-folding.range.aria-label\": \"\",\n    \"gutter.code-folding.closed.aria-label\": \"\",\n    \"gutter.code-folding.open.aria-label\": \"\",\n    \"gutter.code-folding.closed.title\": \"\",\n    \"gutter.code-folding.open.title\": \"\",\n    \"gutter.annotation.aria-label.error\": \"\",\n    \"gutter.annotation.aria-label.warning\": \"\",\n    \"gutter.annotation.aria-label.info\": \"\",\n    \"inline-fold.closed.title\": \"\",\n    \"gutter-tooltip.aria-label.error.singular\": \"ошибка\",\n    \"gutter-tooltip.aria-label.error.plural\": \"ошибки\",\n    \"gutter-tooltip.aria-label.warning.singular\": \"предупреждение\",\n    \"gutter-tooltip.aria-label.warning.plural\": \"предупреждения\",\n    \"gutter-tooltip.aria-label.info.singular\": \"информационное сообщение\",\n    \"gutter-tooltip.aria-label.info.plural\": \"информационные сообщения\",\n    \"gutter.annotation.aria-label.security\": \"\",\n    \"gutter.annotation.aria-label.hint\": \"\",\n    \"gutter-tooltip.aria-label.security.singular\": \"\",\n    \"gutter-tooltip.aria-label.security.plural\": \"\",\n    \"gutter-tooltip.aria-label.hint.singular\": \"\",\n    \"gutter-tooltip.aria-label.hint.plural\": \"\"\n}"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"strict\": false,\n    \"noImplicitAny\": false,\n    \"skipDefaultLibCheck\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es2019\",\n    \"allowJs\": true,\n    \"checkJs\": true,\n    \"declaration\": true,\n    \"noEmit\": true,\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"src/test\",\n    \"src/**/*_test.js\",\n    \"src/keyboard/vim.js\",\n    \"src/keyboard/emacs.js\",\n    \"src/keyboard/sublime.js\",\n    \"src/keyboard/vscode.js\",\n    \"src/mode\",\n    \"./ace-internal.d.ts\",\n    \"./ace-modes.d.ts\",\n    \"src/**/* *\"\n  ],\n  \"include\": [\n    \"./src/**/*\",\n    \"./ace.d.ts\",\n    \"./types/ace_*.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "types/ace-ext.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\ndeclare module \"ace-code/src/ext/command_bar\" {\n    /**\n     * Displays a command tooltip above the currently active line selection, with clickable elements.\n     *\n     * Internally it is a composite of two tooltips, one for the main tooltip and one for the\n     * overflowing commands.\n     * The commands are added sequentially in registration order.\n     * When attached to an editor, it is either always shown or only when the active line is hovered\n     * with mouse, depending on the alwaysShow property.\n     */\n    export class CommandBarTooltip {\n        constructor(parentNode: HTMLElement, options?: Partial<import(\"ace-code\").Ace.CommandBarOptions>);\n        parentNode: HTMLElement;\n        tooltip: Tooltip;\n        moreOptions: Tooltip;\n        maxElementsOnTooltip: number;\n        eventListeners: {};\n        elements: {};\n        commands: {};\n        tooltipEl: HTMLDivElement;\n        moreOptionsEl: HTMLDivElement;\n        /**\n         * Registers a command on the command bar tooltip.\n         *\n         * The commands are added in sequential order. If there is not enough space on the main\n         * toolbar, the remaining elements are added to the overflow menu.\n         *\n         */\n        registerCommand(id: string, command: TooltipCommand): void;\n        isShown(): boolean;\n        isMoreOptionsShown(): boolean;\n        getAlwaysShow(): boolean;\n        /**\n         * Sets the display mode of the tooltip\n         *\n         * When true, the tooltip is always displayed while it is attached to an editor.\n         * When false, the tooltip is displayed only when the mouse hovers over the active editor line.\n         *\n         */\n        setAlwaysShow(alwaysShow: boolean): void;\n        /**\n         * Attaches the clickable command bar tooltip to an editor\n         *\n         * Depending on the alwaysShow parameter it either displays the tooltip immediately,\n         * or subscribes to the necessary events to display the tooltip on hover.\n         *\n         */\n        attach(editor: Editor): void;\n        editor: import(\"ace-code/src/editor\").Editor;\n        /**\n         * Updates the position of the command bar tooltip. It aligns itself above the active line in the editor.\n         */\n        updatePosition(): void;\n        /**\n         * Updates each command element in the tooltip.\n         *\n         * This is automatically called on certain events, but can be called manually as well.\n         */\n        update(): void;\n        /**\n         * Detaches the tooltip from the editor.\n         */\n        detach(): void;\n        destroy(): void;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type TooltipCommand = import(\"ace-code\").Ace.TooltipCommand;\n    import { Tooltip } from \"ace-code/src/tooltip\";\n    export var TOOLTIP_CLASS_NAME: string;\n    export var BUTTON_CLASS_NAME: string;\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type CommandBarEvents = import(\"ace-code\").Ace.CommandBarEvents;\n    }\n    export interface CommandBarTooltip extends Ace.EventEmitter<Ace.CommandBarEvents> {\n    }\n}\ndeclare module \"ace-code/src/ext/language_tools\" {\n    export function setCompleters(val?: import(\"ace-code\").Ace.Completer[]): void;\n    export function addCompleter(completer: import(\"ace-code\").Ace.Completer): void;\n    import textCompleter = require(\"ace-code/src/autocomplete/text_completer\");\n    export var keyWordCompleter: import(\"ace-code\").Ace.Completer;\n    export var snippetCompleter: import(\"ace-code\").Ace.Completer;\n    import { MarkerGroup } from \"ace-code/src/marker_group\";\n    export { textCompleter, MarkerGroup };\n}\ndeclare module \"ace-code/src/ext/inline_autocomplete\" {\n    /**\n     * This class controls the inline-only autocompletion components and their lifecycle.\n     * This is more lightweight than the popup-based autocompletion, as it can only work with exact prefix matches.\n     * There is an inline ghost text renderer and an optional command bar tooltip inside.\n     */\n    export class InlineAutocomplete {\n        constructor(editor: Editor);\n        editor: Editor;\n        keyboardHandler: HashHandler;\n        blurListener(e: any): void;\n        changeListener(e: any): void;\n        changeTimer: {\n            (timeout?: number): void;\n            delay(timeout?: number): void;\n            schedule: any;\n            call(): void;\n            cancel(): void;\n            isPending(): any;\n        };\n        getInlineRenderer(): AceInline;\n        inlineRenderer: AceInline;\n        getInlineTooltip(): CommandBarTooltip;\n        inlineTooltip: CommandBarTooltip;\n        /**\n         * This function is the entry point to the class. This triggers the gathering of the autocompletion and displaying the results;\n         */\n        show(options: import(\"ace-code\").Ace.CompletionOptions): void;\n        activated: boolean;\n        insertMatch(): boolean;\n        goTo(where: import(\"ace-code\").Ace.InlineAutocompleteAction): void;\n        getLength(): any;\n        getData(index?: number): import(\"ace-code\").Ace.Completion | undefined;\n        getIndex(): number;\n        isOpen(): boolean;\n        setIndex(value: number): void;\n        getCompletionProvider(initialPosition: any): CompletionProvider;\n        completionProvider: CompletionProvider;\n        updateCompletions(options?: import(\"ace-code\").Ace.CompletionOptions): void;\n        base: import(\"ace-code/src/anchor\").Anchor;\n        completions: FilteredList;\n        detach(): void;\n        destroy(): void;\n        updateDocTooltip(): void;\n        commands: {\n            [key: string]: import(\"ace-code\").Ace.Command;\n        };\n    }\n    export namespace InlineAutocomplete {\n        function _for(editor: any): any;\n        export { _for as for };\n        export namespace startCommand {\n            let name: string;\n            function exec(editor: any, options: any): void;\n            export namespace bindKey {\n                let win: string;\n                let mac: string;\n            }\n        }\n        /**\n         * Factory method to create a command bar tooltip for inline autocomplete.\n         *\n         * @param {HTMLElement} parentEl  The parent element where the tooltip HTML elements will be added.\n         * @returns {CommandBarTooltip}   The command bar tooltip for inline autocomplete\n         */\n        export function createInlineTooltip(parentEl: HTMLElement): CommandBarTooltip;\n    }\n    import { Editor } from \"ace-code/src/editor\";\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n    import { AceInline } from \"ace-code/src/autocomplete/inline\";\n    import { CommandBarTooltip } from \"ace-code/src/ext/command_bar\";\n    import { CompletionProvider } from \"ace-code/src/autocomplete\";\n    import { FilteredList } from \"ace-code/src/autocomplete\";\n}\ndeclare module \"ace-code/src/ext/searchbox-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/ext/searchbox\" {\n    export function Search(editor: Editor, isReplace?: boolean): void;\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export class SearchBox {\n        constructor(editor: Editor, range?: never, showReplaceForm?: never);\n        activeInput: HTMLInputElement;\n        element: HTMLDivElement;\n        setSession(e: any): void;\n        setEditor(editor: Editor): void;\n        editor: Editor;\n        searchRange: any;\n        onEditorInput(): void;\n        searchBox: HTMLElement;\n        replaceBox: HTMLElement;\n        searchOption: HTMLInputElement;\n        replaceOption: HTMLInputElement;\n        regExpOption: HTMLInputElement;\n        caseSensitiveOption: HTMLInputElement;\n        wholeWordOption: HTMLInputElement;\n        searchInput: HTMLInputElement;\n        replaceInput: HTMLInputElement;\n        searchCounter: HTMLElement;\n        /**\n         * \n         * @external\n        */\n        $onChange: {\n            schedule: (timeout?: number) => void;\n        };\n        setSearchRange(range: any): void;\n        searchRangeMarker: number;\n        /**\n         * @external\n         */\n        $syncOptions(preventScroll?: boolean): void;\n        highlight(re?: RegExp): void;\n        find(skipCurrent: boolean, backwards: boolean, preventScroll?: any): void;\n        updateCounter(): void;\n        findNext(): void;\n        findPrev(): void;\n        findAll(): void;\n        replace(): void;\n        replaceAndFindNext(): void;\n        replaceAll(): void;\n        hide(): void;\n        active: boolean;\n        show(value: string, isReplace?: boolean): void;\n        isFocused(): boolean;\n    }\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n}\ndeclare module \"ace-code/src/ext/diff/scroll_diff_decorator\" {\n    export class ScrollDiffDecorator extends Decorator {\n        constructor(scrollbarV: import(\"ace-code\").Ace.VScrollbar, renderer: import(\"ace-code/src/virtual_renderer\").VirtualRenderer, forInlineDiff?: boolean);\n        addZone(startRow: number, endRow: number, type: \"delete\" | \"insert\"): void;\n        setSessions(sessionA: import(\"ace-code/src/edit_session\").EditSession, sessionB: import(\"ace-code/src/edit_session\").EditSession): void;\n        sessionA: import(\"ace-code/src/edit_session\").EditSession;\n        sessionB: import(\"ace-code/src/edit_session\").EditSession;\n    }\n    import { Decorator } from \"ace-code/src/layer/decorators\";\n}\ndeclare module \"ace-code/src/ext/diff/styles-css\" {\n    export const cssText: \"\\n/*\\n * Line Markers\\n */\\n.ace_diff {\\n    position: absolute;\\n    z-index: 0;\\n}\\n.ace_diff.inline {\\n    z-index: 20;\\n}\\n/*\\n * Light Colors \\n */\\n.ace_diff.insert {\\n    background-color: #EFFFF1;\\n}\\n.ace_diff.delete {\\n    background-color: #FFF1F1;\\n}\\n.ace_diff.aligned_diff {\\n    background: rgba(206, 194, 191, 0.26);\\n    background: repeating-linear-gradient(\\n                45deg,\\n              rgba(122, 111, 108, 0.26),\\n              rgba(122, 111, 108, 0.26) 5px,\\n              rgba(0, 0, 0, 0) 5px,\\n              rgba(0, 0, 0, 0) 10px \\n    );\\n}\\n\\n.ace_diff.insert.inline {\\n    background-color:  rgb(74 251 74 / 18%); \\n}\\n.ace_diff.delete.inline {\\n    background-color: rgb(251 74 74 / 15%);\\n}\\n\\n.ace_diff.delete.inline.empty {\\n    background-color: rgba(255, 128, 79, 0.7);\\n    width: 2px !important;\\n}\\n\\n.ace_diff.insert.inline.empty {\\n    background-color: rgba(49, 230, 96, 0.7);\\n    width: 2px !important;\\n}\\n\\n.ace_diff-active-line {\\n    border-bottom: 1px solid;\\n    border-top: 1px solid;\\n    background: transparent;\\n    position: absolute;\\n    box-sizing: border-box;\\n    border-color: #9191ac;\\n}\\n\\n.ace_dark .ace_diff-active-line {\\n    background: transparent;\\n    border-color: #75777a;\\n}\\n \\n\\n/* gutter changes */\\n.ace_mini-diff_gutter-enabled > .ace_gutter-cell,\\n.ace_mini-diff_gutter-enabled > .ace_gutter-cell_svg-icons {\\n    padding-right: 13px;\\n}\\n\\n.ace_mini-diff_gutter_other > .ace_gutter-cell,\\n.ace_mini-diff_gutter_other > .ace_gutter-cell_svg-icons  {\\n    display: none;\\n}\\n\\n.ace_mini-diff_gutter_other {\\n    pointer-events: none;\\n}\\n\\n\\n.ace_mini-diff_gutter-enabled > .mini-diff-added {\\n    background-color: #EFFFF1;\\n    border-left: 3px solid #2BB534;\\n    padding-left: 16px;\\n    display: block;\\n}\\n\\n.ace_mini-diff_gutter-enabled > .mini-diff-deleted {\\n    background-color: #FFF1F1;\\n    border-left: 3px solid #EA7158;\\n    padding-left: 16px;\\n    display: block;\\n}\\n\\n\\n.ace_mini-diff_gutter-enabled > .mini-diff-added:after {\\n    position: absolute;\\n    right: 2px;\\n    content: \\\"+\\\";\\n    background-color: inherit;\\n}\\n\\n.ace_mini-diff_gutter-enabled > .mini-diff-deleted:after {\\n    position: absolute;\\n    right: 2px;\\n    content: \\\"-\\\";\\n    background-color: inherit;\\n}\\n.ace_fade-fold-widgets:hover > .ace_folding-enabled > .mini-diff-added:after,\\n.ace_fade-fold-widgets:hover > .ace_folding-enabled > .mini-diff-deleted:after {\\n    display: none;\\n}\\n\\n.ace_diff_other .ace_selection {\\n    filter: drop-shadow(1px 2px 3px darkgray);\\n}\\n\\n.ace_hidden_marker-layer .ace_bracket,\\n.ace_hidden_marker-layer .ace_error_bracket {\\n    display: none;\\n}\\n\\n\\n\\n/*\\n * Dark Colors \\n */\\n\\n.ace_dark .ace_diff.insert {\\n    background-color: #212E25;\\n}\\n.ace_dark .ace_diff.delete {\\n    background-color: #3F2222;\\n}\\n\\n.ace_dark .ace_mini-diff_gutter-enabled > .mini-diff-added {\\n    background-color: #212E25;\\n    border-left-color:#00802F;\\n}\\n\\n.ace_dark .ace_mini-diff_gutter-enabled > .mini-diff-deleted {\\n    background-color: #3F2222;\\n    border-left-color: #9C3838;\\n}\\n\\n\";\n}\ndeclare module \"ace-code/src/ext/diff/gutter_decorator\" {\n    export class MinimalGutterDiffDecorator {\n        constructor(editor: import(\"ace-code/src/editor\").Editor, type: number);\n        gutterClass: string;\n        gutterCellsClasses: {\n            add: string;\n            delete: string;\n        };\n        editor: import(\"ace-code/src/editor\").Editor;\n        type: number;\n        chunks: any[];\n        attachToEditor(): void;\n        renderGutters(e: any, gutterLayer: any): void;\n        setDecorations(changes: any): void;\n        dispose(): void;\n    }\n}\ndeclare module \"ace-code/src/ext/diff/inline_diff_view\" {\n    export class InlineDiffView extends BaseDiffView {\n        /**\n         * Constructs a new inline DiffView instance.\n         * @param {import(\"ace-code/src/diff\").DiffModel} [diffModel] - The model for the diff view.\n         * @param {HTMLElement} [container] - optional container element for the DiffView.\n         */\n        constructor(diffModel?: import(\"ace-code/src/ext/diff\").DiffModel, container?: HTMLElement);\n        init(diffModel: any): void;\n        onAfterRender(changes: number, renderer: import(\"ace-code\").VirtualRenderer): void;\n        textLayer: any;\n        markerLayer: any;\n        gutterLayer: any;\n        cursorLayer: any;\n        initRenderer(restore: any): void;\n        initTextLayer(): void;\n        initTextInput(restore: any): void;\n        othertextInput: any;\n        otherEditorContainer: any;\n        selectEditor(editor: any): void;\n        removeBracketHighlight(editor: any): void;\n        initMouse(): void;\n        onMouseDetach: () => void;\n    }\n    import { BaseDiffView } from \"ace-code/src/ext/diff/base_diff_view\";\n}\ndeclare module \"ace-code/src/ext/diff/split_diff_view\" {\n    export class SplitDiffView extends BaseDiffView {\n        /**\n         * Constructs a new side by side DiffView instance.\n         *\n         * @param {import(\"ace-code/src/diff\").DiffModel} [diffModel] - The model for the diff view.\n         */\n        constructor(diffModel?: import(\"ace-code/src/ext/diff\").DiffModel);\n        init(diffModel: any): void;\n        onMouseWheel(ev: any): any;\n        onScroll(e: any, session: any): void;\n        onChangeWrapLimit(): void;\n        syncScroll(renderer: import(\"ace-code/src/virtual_renderer\").VirtualRenderer): void;\n        scrollA: any;\n        scrollB: any;\n        scrollSetBy: any;\n        scrollSetAt: number;\n    }\n    import { BaseDiffView } from \"ace-code/src/ext/diff/base_diff_view\";\n}\ndeclare module \"ace-code/src/ext/diff/providers/default\" {\n    export function computeDiff(originalLines: any, modifiedLines: any, options: any): any;\n    /**\n     * VSCode’s computeDiff provider\n     */\n    export class DiffProvider {\n        compute(originalLines: any, modifiedLines: any, opts: any): any;\n    }\n}\ndeclare module \"ace-code/src/ext/diff\" {\n    /**\n     * Interface representing a model for handling differences between two views or states.\n     */\n    export type DiffModel = {\n        /**\n         * - The editor for the original view.\n         */\n        editorA?: import(\"ace-code/src/editor\").Editor;\n        /**\n         * - The editor for the edited view.\n         */\n        editorB?: import(\"ace-code/src/editor\").Editor;\n        /**\n         * - The edit session for the original view.\n         */\n        sessionA?: import(\"ace-code/src/edit_session\").EditSession;\n        /**\n         * - The edit session for the edited view.\n         */\n        sessionB?: import(\"ace-code/src/edit_session\").EditSession;\n        /**\n         * - The original content.\n         */\n        valueA?: string;\n        /**\n         * - The modified content.\n         */\n        valueB?: string;\n        /**\n         * - Whether to show the original view(\"a\") or modified view(\"b\") for inline diff view\n         */\n        inline?: \"a\" | \"b\";\n        /**\n         * - Provider for computing differences between original and modified content.\n         */\n        diffProvider?: IDiffProvider;\n    };\n    export type DiffViewOptions = {\n        /**\n         * - Whether to show line numbers in the other editor's gutter\n         */\n        showOtherLineNumbers?: boolean;\n        /**\n         * - Whether to enable code folding widgets\n         */\n        folding?: boolean;\n        /**\n         * - Whether to synchronize selections between both editors\n         */\n        syncSelections?: boolean;\n        /**\n         * - Whether to ignore trimmed whitespace when computing diffs\n         */\n        ignoreTrimWhitespace?: boolean;\n        /**\n         * - Whether to enable word wrapping in both editors\n         */\n        wrap?: boolean;\n        /**\n         * - Maximum number of diffs to compute before failing silently\n         */\n        maxDiffs?: number;\n        /**\n         * - Theme to apply to both editors\n         */\n        theme?: string | import(\"ace-code\").Ace.Theme;\n    };\n    export type IDiffProvider = {\n        /**\n         * - Computes differences between original and modified lines\n         */\n        compute: (originalLines: string[], modifiedLines: string[], opts?: any) => import(\"ace-code/src/ext/diff/base_diff_view\").DiffChunk[];\n    };\n    import { InlineDiffView } from \"ace-code/src/ext/diff/inline_diff_view\";\n    import { SplitDiffView } from \"ace-code/src/ext/diff/split_diff_view\";\n    import { DiffProvider } from \"ace-code/src/ext/diff/providers/default\";\n    /**\n     * Interface representing a model for handling differences between two views or states.\n     * @property {import(\"ace-code/src/editor\").Editor} [editorA] - The editor for the original view.\n     * @property {import(\"ace-code/src/editor\").Editor} [editorB] - The editor for the edited view.\n     * @property {import(\"ace-code/src/edit_session\").EditSession} [sessionA] - The edit session for the original view.\n     * @property {import(\"ace-code/src/edit_session\").EditSession} [sessionB] - The edit session for the edited view.\n     * @property {string} [valueA] - The original content.\n     * @property {string} [valueB] - The modified content.\n     * @property {\"a\"|\"b\"} [inline] - Whether to show the original view(\"a\") or modified view(\"b\") for inline diff view\n     * @property {IDiffProvider} [diffProvider] - Provider for computing differences between original and modified content.\n     */\n    /**\n     * @property {boolean} [showOtherLineNumbers=true] - Whether to show line numbers in the other editor's gutter\n     * @property {boolean} [folding] - Whether to enable code folding widgets\n     * @property {boolean} [syncSelections] - Whether to synchronize selections between both editors\n     * @property {boolean} [ignoreTrimWhitespace] - Whether to ignore trimmed whitespace when computing diffs\n     * @property {boolean} [wrap] - Whether to enable word wrapping in both editors\n     * @property {number} [maxDiffs=5000] - Maximum number of diffs to compute before failing silently\n     * @property {string|import(\"ace-code\").Ace.Theme} [theme] - Theme to apply to both editors\n     */\n    /**\n     * @property {(originalLines: string[], modifiedLines: string[], opts?: any) => import(\"ace-code/src/diff/base_diff_view\").DiffChunk[]} compute - Computes differences between original and modified lines\n     */\n    /**\n     * Creates a diff view for comparing code.\n     * @param {DiffModel} [diffModel] model for the diff view\n     * @param {DiffViewOptions} [options] options for the diff view\n     * @returns {InlineDiffView|SplitDiffView} Configured diff view instance\n     */\n    export function createDiffView(diffModel?: DiffModel, options?: DiffViewOptions): InlineDiffView | SplitDiffView;\n    export { InlineDiffView, SplitDiffView, DiffProvider };\n}\ndeclare module \"ace-code/src/ext/diff/base_diff_view\" {\n    export class BaseDiffView {\n        /**\n         * Constructs a new base DiffView instance.\n         * @param {boolean} [inlineDiffEditor] - Whether to use an inline diff editor.\n         * @param {HTMLElement} [container] - optional container element for the DiffView.\n         */\n        constructor(inlineDiffEditor?: boolean, container?: HTMLElement);\n        onChangeTheme(e: any): void;\n        onInput(): void;\n        onChangeFold(ev: any, session: EditSession): void;\n        realign(): void;\n        onSelect(e: any, selection: any): void;\n        onChangeWrapLimit(e: any, session: any): void;\n        realignPending: boolean;\n        diffSession: {\n            sessionA: EditSession;\n            sessionB: EditSession;\n            chunks: DiffChunk[];\n        };\n        /**@type DiffChunk[]*/ chunks: DiffChunk[];\n        inlineDiffEditor: boolean;\n        currentDiffIndex: number;\n        diffProvider: {\n            compute: (val1: any, val2: any, options: any) => any[];\n        };\n        container: HTMLElement;\n        markerB: DiffHighlight;\n        markerA: DiffHighlight;\n        showSideA: boolean;\n        savedOptionsA: Partial<import(\"ace-code\").Ace.EditorOptions>;\n        savedOptionsB: Partial<import(\"ace-code\").Ace.EditorOptions>;\n        editorA: any;\n        editorB: any;\n        activeEditor: any;\n        otherSession: EditSession;\n        otherEditor: any;\n        addGutterDecorators(): void;\n        gutterDecoratorA: MinimalGutterDiffDecorator;\n        gutterDecoratorB: MinimalGutterDiffDecorator;\n        foldUnchanged(): boolean;\n        unfoldUnchanged(): void;\n        toggleFoldUnchanged(): void;\n        setDiffSession(session: {\n            sessionA: any;\n            sessionB: EditSession;\n            chunks: DiffChunk[];\n        }): void;\n        sessionA: EditSession;\n        sessionB: EditSession;\n        getDiffSession(): {\n            sessionA: EditSession;\n            sessionB: EditSession;\n            chunks: DiffChunk[];\n        };\n        setTheme(theme: any): void;\n        getTheme(): any;\n        resize(force: any): void;\n        scheduleOnInput(): void;\n        selectionRangeA: any;\n        selectionRangeB: any;\n        setupScrollbars(): void;\n        updateScrollBarDecorators(): void;\n        setProvider(provider: import(\"ace-code/src/ext/diff\").DiffProvider): void;\n        /**\n         * scroll locking\n         * @abstract\n         **/\n        align(): void;\n        syncSelect(selection: any): void;\n        updateSelectionMarker(marker: any, session: any, range: any): void;\n        scheduleRealign(): void;\n        detach(): void;\n        destroy(): void;\n        gotoNext(dir: any): void;\n        firstDiffSelected(): boolean;\n        lastDiffSelected(): boolean;\n        transformRange(range: Range, isOriginal: boolean): Range;\n        transformPosition(pos: import(\"ace-code\").Ace.Point, isOriginal: boolean): import(\"ace-code\").Ace.Point;\n        printDiffs(): void;\n        findChunkIndex(chunks: DiffChunk[], row: number, isOriginal: boolean): number;\n        searchHighlight(selection: any): void;\n        initSelectionMarkers(): void;\n        syncSelectionMarkerA: SyncSelectionMarker;\n        syncSelectionMarkerB: SyncSelectionMarker;\n        clearSelectionMarkers(): void;\n    }\n    import { EditSession } from \"ace-code/src/edit_session\";\n    export class DiffChunk {\n        /**\n         * @param {{originalStartLineNumber: number, originalStartColumn: number,\n         * originalEndLineNumber: number, originalEndColumn: number, modifiedStartLineNumber: number,\n         * modifiedStartColumn: number, modifiedEndLineNumber: number, modifiedEndColumn: number}[]} [charChanges]\n         */\n        constructor(originalRange: Range, modifiedRange: Range, charChanges?: {\n            originalStartLineNumber: number;\n            originalStartColumn: number;\n            originalEndLineNumber: number;\n            originalEndColumn: number;\n            modifiedStartLineNumber: number;\n            modifiedStartColumn: number;\n            modifiedEndLineNumber: number;\n            modifiedEndColumn: number;\n        }[]);\n        old: Range;\n        new: Range;\n        charChanges: DiffChunk[];\n    }\n    export class DiffHighlight {\n        constructor(diffView: import(\"ace-code/src/ext/diff/base_diff_view\").BaseDiffView, type: any);\n        id: number;\n        diffView: BaseDiffView;\n        type: any;\n        update(html: any, markerLayer: any, session: any, config: any): void;\n    }\n    import { MinimalGutterDiffDecorator } from \"ace-code/src/ext/diff/gutter_decorator\";\n    import { Editor } from \"ace-code/src/editor\";\n    import { Range } from \"ace-code/src/range\";\n    class SyncSelectionMarker {\n        id: number;\n        type: string;\n        clazz: string;\n        update(html: any, markerLayer: any, session: any, config: any): void;\n        setRange(range: Range): void;\n        range: Range;\n    }\n    namespace Ace {\n        type OptionsProvider<T> = import(\"ace-code\").Ace.OptionsProvider<T>;\n    }\n    export interface BaseDiffView extends Ace.OptionsProvider<import(\"ace-code/src/ext/diff\").DiffViewOptions> {\n    }\n}\ndeclare module \"ace-code/src/ext/elastic_tabstops_lite\" {\n    export class ElasticTabstopsLite {\n        constructor(editor: Editor);\n        onAfterExec: () => void;\n        onExec: () => void;\n        onChange: (delta: any) => void;\n        processRows(rows: number[]): void;\n    }\n    import { Editor } from \"ace-code/src/editor\";\n}\ndeclare module \"ace-code/src/ext/menu_tools/settings_menu.css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/ext/menu_tools/overlay_page\" {\n    export function overlayPage(editor: import(\"ace-code/src/editor\").Editor, contentElement: HTMLElement, callback?: () => void): {\n        close: () => void;\n        setIgnoreFocusOut: (ignore: boolean) => void;\n    };\n}\ndeclare module \"ace-code/src/ext/modelist\" {\n    /**\n     * Suggests a mode based on the file extension present in the given path\n     * @param {string} path The path to the file\n     * @returns {Mode} Returns an object containing information about the\n     *  suggested mode.\n     */\n    export function getModeForPath(path: string): Mode;\n    /**\n     * Represents an array to store various syntax modes.\n     *\n     * \n     */\n    export var modes: Mode[];\n    /**\n     * An object that serves as a mapping of mode names to their corresponding mode data.\n     * The keys of this object are mode names (as strings), and the values are expected\n     * to represent data associated with each mode.\n     *\n     * This structure can be used for quick lookups of mode information by name.\n     * \n     */\n    export var modesByName: Record<string, Mode>;\n    class Mode {\n        constructor(name: string, caption: string, extensions: string);\n        name: string;\n        caption: string;\n        mode: string;\n        extensions: string;\n        extRe: RegExp;\n        supportsFile(filename: string): RegExpMatchArray | null;\n    }\n}\ndeclare module \"ace-code/src/ext/themelist\" {\n    export const themesByName: {\n        [x: string]: Theme;\n    };\n    export const themes: Theme[];\n    export type Theme = {\n        /**\n         * - The display caption of the theme.\n         */\n        caption: string;\n        /**\n         * - The path or identifier for the ACE theme.\n         */\n        theme: string;\n        /**\n         * - Indicates whether the theme is dark or light.\n         */\n        isDark: boolean;\n        /**\n         * - The normalized name used as the key.\n         */\n        name: string;\n    };\n}\ndeclare module \"ace-code/src/ext/options\" {\n    /**\n     * Option panel component for configuring settings or options.\n     * The panel is designed to integrate with an editor and render various UI controls based on provided configuration.\n     */\n    export class OptionPanel {\n        constructor(editor: Editor, element?: HTMLElement);\n        editor: import(\"ace-code/src/editor\").Editor;\n        container: HTMLElement;\n        groups: any[];\n        options: {};\n        add(config: any): void;\n        render(): void;\n        renderOptionGroup(group: any): any[];\n        renderOptionControl(key: string, option: any): any;\n        renderOption(key: any, option: any): (string | any[] | {\n            class: string;\n        })[];\n        setOption(option: string | number | any, value: string | number | boolean): void;\n        getOption(option: any): any;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export namespace optionGroups {\n        let Main: {\n            Mode: {\n                path: string;\n                type: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            Theme: {\n                path: string;\n                type: string;\n                items: {\n                    Bright: any[];\n                    Dark: any[];\n                };\n            };\n            Keybinding: {\n                type: string;\n                path: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            \"Font Size\": {\n                path: string;\n                type: string;\n                defaultValue: number;\n                defaults: {\n                    caption: string;\n                    value: number;\n                }[];\n            };\n            \"Soft Wrap\": {\n                type: string;\n                path: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            \"Cursor Style\": {\n                path: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            Folding: {\n                path: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            \"Soft Tabs\": ({\n                path: string;\n                ariaLabel?: undefined;\n                type?: undefined;\n                values?: undefined;\n            } | {\n                ariaLabel: string;\n                path: string;\n                type: string;\n                values: number[];\n            })[];\n            Overscroll: {\n                type: string;\n                path: string;\n                items: {\n                    caption: string;\n                    value: number;\n                }[];\n            };\n        };\n        let More: {\n            \"Atomic soft tabs\": {\n                path: string;\n            };\n            \"Enable Behaviours\": {\n                path: string;\n            };\n            \"Wrap with quotes\": {\n                path: string;\n            };\n            \"Enable Auto Indent\": {\n                path: string;\n            };\n            \"Full Line Selection\": {\n                type: string;\n                values: string;\n                path: string;\n            };\n            \"Highlight Active Line\": {\n                path: string;\n            };\n            \"Show Invisibles\": {\n                path: string;\n            };\n            \"Show Indent Guides\": {\n                path: string;\n            };\n            \"Highlight Indent Guides\": {\n                path: string;\n            };\n            \"Persistent HScrollbar\": {\n                path: string;\n            };\n            \"Persistent VScrollbar\": {\n                path: string;\n            };\n            \"Animate scrolling\": {\n                path: string;\n            };\n            \"Show Gutter\": {\n                path: string;\n            };\n            \"Show Line Numbers\": {\n                path: string;\n            };\n            \"Relative Line Numbers\": {\n                path: string;\n            };\n            \"Fixed Gutter Width\": {\n                path: string;\n            };\n            \"Show Print Margin\": ({\n                path: string;\n                ariaLabel?: undefined;\n                type?: undefined;\n            } | {\n                ariaLabel: string;\n                type: string;\n                path: string;\n            })[];\n            \"Indented Soft Wrap\": {\n                path: string;\n            };\n            \"Highlight selected word\": {\n                path: string;\n            };\n            \"Fade Fold Widgets\": {\n                path: string;\n            };\n            \"Use textarea for IME\": {\n                path: string;\n            };\n            \"Merge Undo Deltas\": {\n                path: string;\n                items: {\n                    caption: string;\n                    value: string;\n                }[];\n            };\n            \"Elastic Tabstops\": {\n                path: string;\n            };\n            \"Incremental Search\": {\n                path: string;\n            };\n            \"Read-only\": {\n                path: string;\n            };\n            \"Copy without selection\": {\n                path: string;\n            };\n            \"Live Autocompletion\": {\n                path: string;\n            };\n            \"Custom scrollbar\": {\n                path: string;\n            };\n            \"Use SVG gutter icons\": {\n                path: string;\n            };\n            \"Annotations for folded lines\": {\n                path: string;\n            };\n            \"Keyboard Accessibility Mode\": {\n                path: string;\n            };\n        };\n    }\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type OptionPanelEvents = import(\"ace-code\").Ace.OptionPanelEvents;\n    }\n    export interface OptionPanel extends Ace.EventEmitter<Ace.OptionPanelEvents> {\n    }\n}\ndeclare module \"ace-code/src/ext/error_marker\" {\n    export function showErrorMarker(editor: import(\"ace-code/src/editor\").Editor, dir: number): void;\n}\ndeclare module \"ace-code/src/ext/beautify\" {\n    export const singletonTags: string[];\n    export const blockTags: string[];\n    export const formatOptions: {\n        lineBreaksAfterCommasInCurlyBlock?: boolean;\n    };\n    export function beautify(session: import(\"ace-code/src/edit_session\").EditSession): void;\n    export const commands: import(\"ace-code\").Ace.Command[];\n}\ndeclare module \"ace-code/src/ext/code_lens\" {\n    export function setLenses(session: EditSession, lenses: import(\"ace-code\").Ace.CodeLense[]): number;\n    export function registerCodeLensProvider(editor: import(\"ace-code/src/editor\").Editor, codeLensProvider: import(\"ace-code\").Ace.CodeLenseProvider): void;\n    export function clear(session: EditSession): void;\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type VirtualRenderer = import(\"ace-code/src/virtual_renderer\").VirtualRenderer & {\n    };\n    export type CodeLenseCommand = import(\"ace-code\").Ace.CodeLenseCommand;\n    export type CodeLense = import(\"ace-code\").Ace.CodeLense;\n    import { Editor } from \"ace-code/src/editor\";\n}\ndeclare module \"ace-code/src/ext/emmet\" {\n    export const commands: HashHandler;\n    export function runEmmetCommand(editor: Editor): ReturnType<typeof setTimeout> | boolean;\n    export function updateCommands(editor: Editor, enabled?: boolean): void;\n    export function isSupportedMode(mode: any | string): boolean;\n    export function isAvailable(editor: Editor, command: string): boolean;\n    export function load(cb?: Function): boolean;\n    export function setCore(e: string | any): void;\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n    import { Editor } from \"ace-code/src/editor\";\n    /**\n     * Implementation of {@link IEmmetEditor} interface for Ace\n     */\n    export class AceEmmetEditor {\n        setupContext(editor: Editor): void;\n        ace: Editor;\n        indentation: string;\n        /**\n         * Returns character indexes of selected text: object with <code>start</code>\n         * and <code>end</code> properties. If there's no selection, should return\n         * object with <code>start</code> and <code>end</code> properties referring\n         * to current caret position\n         * @example\n         * var selection = editor.getSelectionRange();\n         * alert(selection.start + ', ' + selection.end);\n         */\n        getSelectionRange(): any;\n        /**\n         * Creates selection from <code>start</code> to <code>end</code> character\n         * indexes. If <code>end</code> is ommited, this method should place caret\n         * and <code>start</code> index\n         * @example\n         * editor.createSelection(10, 40);\n         *\n         * //move caret to 15th character\n         * editor.createSelection(15);\n         */\n        createSelection(start: number, end?: number): void;\n        /**\n         * Returns current line's start and end indexes as object with <code>start</code>\n         * and <code>end</code> properties\n         * @example\n         * var range = editor.getCurrentLineRange();\n         * alert(range.start + ', ' + range.end);\n         */\n        getCurrentLineRange(): any;\n        /**\n         * Returns current caret position\n         */\n        getCaretPos(): number | null;\n        /**\n         * Set new caret position\n         * @param {Number} index Caret position\n         */\n        setCaretPos(index: number): void;\n        /**\n         * Returns content of current line\n         */\n        getCurrentLine(): string;\n        /**\n         * Replace editor's content or it's part (from <code>start</code> to\n         * <code>end</code> index). If <code>value</code> contains\n         * <code>caret_placeholder</code>, the editor will put caret into\n         * this position. If you skip <code>start</code> and <code>end</code>\n         * arguments, the whole target's content will be replaced with\n         * <code>value</code>.\n         *\n         * If you pass <code>start</code> argument only,\n         * the <code>value</code> will be placed at <code>start</code> string\n         * index of current content.\n         *\n         * If you pass <code>start</code> and <code>end</code> arguments,\n         * the corresponding substring of current target's content will be\n         * replaced with <code>value</code>.\n         * @param {String} value Content you want to paste\n         * @param {Number} [start] Start index of editor's content\n         * @param {Number} [end] End index of editor's content\n         * @param {Boolean} [noIndent] Do not auto indent <code>value</code>\n         */\n        replaceContent(value: string, start?: number, end?: number, noIndent?: boolean): void;\n        /**\n         * Returns editor's content\n         */\n        getContent(): string;\n        /**\n         * Returns current editor's syntax mode\n         */\n        getSyntax(): string;\n        /**\n         * Returns current output profile name (@see emmet#setupProfile)\n         */\n        getProfileName(): string;\n        /**\n         * Ask user to enter something\n         * @param {String} title Dialog title\n         * @return {String} Entered data\n         * @since 0.65\n         */\n        prompt(title: string): string;\n        /**\n         * Returns current selection\n         * @since 0.65\n         */\n        getSelection(): string;\n        /**\n         * Returns current editor's file path\n         * @since 0.65\n         */\n        getFilePath(): string;\n    }\n}\ndeclare module \"ace-code/src/ext/hardwrap\" {\n    /**\n     * Wraps lines at specified column limits and optionally merges short adjacent lines.\n     *\n     * Processes text within the specified row range, breaking lines that exceed the maximum column\n     * width at appropriate word boundaries while preserving indentation. When merge is enabled,\n     * combines short consecutive lines that can fit within the column limit. Automatically adjusts\n     * the end row when new line breaks are inserted to ensure all affected content is processed.\n     *\n     * @param {import(\"ace-code/src/editor\").Editor} editor - The editor instance containing the text to wrap\n     * @param {import(\"ace-code\").Ace.HardWrapOptions} options - Configuration options for wrapping behavior\n     */\n    export function hardWrap(editor: import(\"ace-code/src/editor\").Editor, options: import(\"ace-code\").Ace.HardWrapOptions): void;\n    import { Editor } from \"ace-code/src/editor\";\n}\ndeclare module \"ace-code/src/ext/menu_tools/get_editor_keyboard_shortcuts\" {\n    export function getEditorKeybordShortcuts(editor: import(\"ace-code/src/editor\").Editor): any[];\n}\ndeclare module \"ace-code/src/ext/keybinding_menu\" {\n    export function init(editor: Editor): void;\n    import { Editor } from \"ace-code/src/editor\";\n}\ndeclare module \"ace-code/src/ext/linking\" { }\ndeclare module \"ace-code/src/ext/prompt\" {\n    export type PromptOptions = {\n        /**\n         * Prompt name.\n         */\n        name: string;\n        /**\n         * Defines which part of the predefined value should be highlighted.\n         */\n        selection: [\n            number,\n            number\n        ];\n        /**\n         * Set to true if prompt has description below input box.\n         */\n        hasDescription: boolean;\n        /**\n         * Description below input box.\n         */\n        prompt: string;\n        /**\n         * Placeholder for value.\n         */\n        placeholder: string;\n        /**\n         * Set to true to keep the prompt open when focus moves to another part of the editor.\n         */\n        ignoreFocusOut: boolean;\n        /**\n         * Function for defining list of options for value.\n         */\n        getCompletions: Function;\n        /**\n         * Function for defining current value prefix.\n         */\n        getPrefix: Function;\n        /**\n         * Function called when Enter is pressed.\n         */\n        onAccept: Function;\n        /**\n         * Function called when input is added to prompt input box.\n         */\n        onInput: Function;\n        /**\n         * Function called when Esc|Shift-Esc is pressed.\n         */\n        onCancel: Function;\n        /**\n         * Function for defining history list.\n         */\n        history: Function;\n        maxHistoryCount: number;\n        addToHistory: Function;\n    };\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    /**\n     * @property {String} name             Prompt name.\n     * @property {String} $type            Use prompt of specific type (gotoLine|commands|modes or default if empty).\n     * @property {[number, number]} selection  Defines which part of the predefined value should be highlighted.\n     * @property {Boolean} hasDescription  Set to true if prompt has description below input box.\n     * @property {String} prompt           Description below input box.\n     * @property {String} placeholder      Placeholder for value.\n     * @property {Object} $rules           Specific rules for input like password or regexp.\n     * @property {Boolean} ignoreFocusOut  Set to true to keep the prompt open when focus moves to another part of the editor.\n     * @property {Function} getCompletions Function for defining list of options for value.\n     * @property {Function} getPrefix      Function for defining current value prefix.\n     * @property {Function} onAccept       Function called when Enter is pressed.\n     * @property {Function} onInput        Function called when input is added to prompt input box.\n     * @property {Function} onCancel       Function called when Esc|Shift-Esc is pressed.\n     * @property {Function} history        Function for defining history list.\n     * @property {number} maxHistoryCount\n     * @property {Function} addToHistory\n     */\n    /**\n     * Prompt plugin is used for getting input from user.\n     *\n     * @param {Editor} editor                   Ouside editor related to this prompt. Will be blurred when prompt is open.\n     * @param {String | Partial<PromptOptions>} message                  Predefined value of prompt input box.\n     * @param {Partial<PromptOptions>} options                  Cusomizable options for this prompt.\n     * @param {Function} [callback]               Function called after done.\n     * */\n    export function prompt(editor: Editor, message: string | Partial<PromptOptions>, options: Partial<PromptOptions>, callback?: Function): any;\n    export namespace prompt {\n        /**\n         * Displays a \"Go to Line\" prompt for navigating to specific line and column positions with selection support.\n         *\n         * @param {Editor} editor - The editor instance to navigate within\n         */\n        function gotoLine(editor: Editor, callback?: Function): void;\n        /**\n         * Displays a searchable command palette for executing editor commands with keyboard shortcuts and history.\n         *\n         * @param {Editor} editor - The editor instance to execute commands on\n         */\n        function commands(editor: Editor, callback?: Function): void;\n        /**\n         * Shows an interactive prompt containing all available syntax highlighting modes\n         * that can be applied to the editor session. Users can type to filter through the modes list\n         * and select one to change the editor's syntax highlighting mode. The prompt includes real-time\n         * filtering based on mode names and captions.\n         *\n         * @param {Editor} editor - The editor instance to change the language mode for\n         */\n        function modes(editor: Editor, callback?: Function): void;\n    }\n}\ndeclare module \"ace-code/src/ext/rtl\" {\n}\ndeclare module \"ace-code/src/ext/settings_menu\" {\n    export function init(): void;\n}\ndeclare module \"ace-code/src/ext/simple_tokenizer\" {\n    /**\n     * Parses provided content according to provided highlighting rules and return tokens.\n     * Tokens either have the className set according to Ace themes or have no className if they are just pure text tokens.\n     * Result is a list of list of tokens, where each line from the provided content is a separate list of tokens.\n     *\n     * @param {string} content to tokenize\n     * @param {import(\"ace-code\").Ace.HighlightRules} highlightRules defining the language grammar\n     * @returns {import(\"ace-code\").Ace.TokenizeResult} tokenization result containing a list of token for each of the lines from content\n     */\n    export function tokenize(content: string, highlightRules: import(\"ace-code\").Ace.HighlightRules): import(\"ace-code\").Ace.TokenizeResult;\n}\ndeclare module \"ace-code/src/ext/spellcheck\" {\n    export function contextMenuHandler(e: any): void;\n}\ndeclare module \"ace-code/src/ext/split\" {\n    const _exports: typeof import(\"ace-code/src/split\");\n    export = _exports;\n}\ndeclare module \"ace-code/src/ext/static-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/ext/static_highlight\" {\n    /**\n     * Applies syntax highlighting to an HTML element containing code.\n     *\n     * Automatically detects the language from CSS class names (e.g., 'lang-javascript') or uses\n     * the specified mode. Transforms the element's content into syntax-highlighted HTML with\n     * CSS styling and preserves any existing child elements by repositioning them after highlighting.\n     *\n     * @param {HTMLElement} el - The HTML element containing code to highlight\n     * @param {import(\"ace-code\").Ace.StaticHighlightOptions} opts - Highlighting options\n     * @param {function} [callback] - Optional callback executed after highlighting is complete\n     * @returns {boolean} Returns false if no valid mode is found, otherwise true\n     */\n    function highlight(el: HTMLElement, opts: import(\"ace-code\").Ace.StaticHighlightOptions, callback?: Function): boolean;\n    export namespace highlight {\n        export { render, renderSync, highlight, SyntaxMode, Theme };\n    }\n    /**\n     * Transforms a given input code snippet into HTML using the given mode\n     *\n     * @param {string} input Code snippet\n     * @param {string | SyntaxMode} mode String specifying the mode to load such as\n     *  `ace/mode/javascript` or, a mode loaded from `/ace/mode`\n     *  (use 'ServerSideHiglighter.getMode').\n     * @param {string | Theme} theme String specifying the theme to load such as\n     *  `ace/theme/twilight` or, a theme loaded from `/ace/theme`.\n     * @param {number} lineStart A number indicating the first line number. Defaults\n     *  to 1.\n     * @param {boolean} disableGutter Specifies whether or not to disable the gutter.\n     *  `true` disables the gutter, `false` enables the gutter. Defaults to `false`.\n     * @param {function} [callback] When specifying the mode or theme as a string,\n     *  this method has no return value and you must specify a callback function. The\n     *  callback will receive the rendered object containing the properties `html`\n     *  and `css`.\n     * @returns {object} An object containing the properties `html` and `css`.\n     */\n    function render(input: string, mode: string | SyntaxMode, theme: string | Theme, lineStart: number, disableGutter: boolean, callback?: Function): object;\n    /**\n     * Transforms a given input code snippet into HTML using the given mode\n     * @param {string} input Code snippet\n     * @param {SyntaxMode | string} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode')\n     * @returns {object} An object containing: html, css\n     */\n    function renderSync(input: string, mode: SyntaxMode | string, theme: Theme, lineStart: any, disableGutter: boolean): object;\n    type SyntaxMode = import(\"ace-code\").Ace.SyntaxMode;\n    type Theme = import(\"ace-code\").Ace.Theme;\n}\ndeclare module \"ace-code/src/ext/statusbar\" {\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    /** simple statusbar **/\n    export class StatusBar {\n        constructor(editor: Editor, parentNode: HTMLElement);\n        element: HTMLDivElement;\n        updateStatus(editor: Editor): void;\n    }\n}\ndeclare module \"ace-code/src/ext/whitespace\" {\n    export function $detectIndentation(lines: string[], fallback?: any): {\n        ch?: string;\n        length?: number;\n    };\n    export function detectIndentation(session: EditSession): {\n        ch?: string;\n        length?: number;\n    } | {};\n    export function trimTrailingSpace(session: EditSession, options: {\n        trimEmpty?: boolean;\n        keepCursorPosition?: boolean;\n    }): void;\n    export function convertIndentation(session: EditSession, ch: string, len: number): void;\n    export function $parseStringArg(text: string): {};\n    export function $parseArg(arg: any): any;\n    export const commands: {\n        name: string;\n        description: string;\n        exec: (editor: any, args: any) => void;\n    }[];\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n}\ndeclare module \"ace-code/src/ext/whitespaces_in_selection\" {\n}\n"
  },
  {
    "path": "types/ace-lib.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\ndeclare module \"ace-code/src/lib/useragent\" {\n    export namespace OS {\n        let LINUX: string;\n        let MAC: string;\n        let WINDOWS: string;\n    }\n    export function getOS(): string;\n    export const isWin: boolean;\n    export const isMac: boolean;\n    export const isLinux: boolean;\n    export const isIE: number;\n    export const isOldIE: boolean;\n    export const isGecko: any;\n    export const isMozilla: any;\n    export const isOpera: boolean;\n    export const isWebKit: number;\n    export const isChrome: number;\n    export const isSafari: true;\n    export const isEdge: number;\n    export const isAIR: boolean;\n    export const isAndroid: boolean;\n    export const isChromeOS: boolean;\n    export const isIOS: boolean;\n    export const isMobile: boolean;\n}\ndeclare module \"ace-code/src/lib/dom\" {\n    /**\n     * @overload\n     */\n    export function buildDom<K extends keyof HTMLElementTagNameMap>(arr: [\n        K,\n        ...any[]\n    ], parent?: HTMLElement, refs?: Record<string, Node>): HTMLElementTagNameMap[K];\n    /**\n     * @overload\n     */\n    export function buildDom(arr: any, parent?: HTMLElement, refs?: any): HTMLElement | Text | any[];\n    export function getDocumentHead(doc?: Document): HTMLHeadElement | HTMLElement;\n    export function createElement<T extends keyof HTMLElementTagNameMap>(tag: T | string, ns?: string): HTMLElementTagNameMap[T];\n    export function removeChildren(element: HTMLElement): void;\n    export function createTextNode(textContent: string, element?: HTMLElement): Text;\n    export function createFragment(element?: HTMLElement): DocumentFragment;\n    export function hasCssClass(el: HTMLElement, name: string): boolean;\n    export function addCssClass(el: HTMLElement, name: string): void;\n    export function removeCssClass(el: HTMLElement, name: string): void;\n    export function toggleCssClass(el: HTMLElement, name: string): boolean;\n    export function setCssClass(node: HTMLElement, className: string, include: boolean): void;\n    export function hasCssString(id: string, doc?: Document): boolean;\n    export function removeElementById(id: string, doc?: Document): void;\n    export function useStrictCSP(value: any): void;\n    export function importCssStylsheet(uri: string, doc?: Document): void;\n    export function $fixPositionBug(el: HTMLElement): void;\n    export function scrollbarWidth(doc?: Document): number;\n    export function computedStyle(element: Element, style?: any): Partial<CSSStyleDeclaration>;\n    export function setStyle(styles: CSSStyleDeclaration, property: string, value: string): void;\n    export const HAS_CSS_ANIMATION: boolean;\n    export const HAS_CSS_TRANSFORMS: boolean;\n    export const HI_DPI: boolean;\n    export function translate(element: any, tx: any, ty: any): void;\n    export function importCssString(cssText: string, id?: string, target?: any): number;\n}\ndeclare module \"ace-code/src/lib/oop\" {\n    export function inherits(ctor: any, superCtor: any): void;\n    export function mixin<T>(obj: T, mixin: any): T & any;\n    export function implement<T>(proto: T, mixin: any): T & any;\n}\ndeclare module \"ace-code/src/lib/deep_copy\" {\n    export function deepCopy(obj: any): any;\n}\ndeclare module \"ace-code/src/lib/lang\" {\n    export function last(a: any): any;\n    export function stringReverse(string: string): string;\n    export function stringRepeat(string: any, count: any): string;\n    export function stringTrimLeft(string: any): any;\n    export function stringTrimRight(string: any): any;\n    export function copyObject<T>(obj: T): T;\n    export function copyArray(array: any): any[];\n    export const deepCopy: (obj: any) => any;\n    export function arrayToMap(arr: any): {};\n    export function createMap(props: any): any;\n    export function arrayRemove(array: any, value: any): void;\n    export function escapeRegExp(str: any): any;\n    export function escapeHTML(str: any): string;\n    export function getMatchOffsets(string: any, regExp: any): any[];\n    export function deferredCall(fcn: any): {\n        (timeout: any): any;\n        schedule: any;\n        call(): any;\n        cancel(): any;\n        isPending(): any;\n    };\n    export function delayedCall(fcn: any, defaultTimeout?: number): {\n        (timeout?: number): void;\n        delay(timeout?: number): void;\n        schedule: any;\n        call(): void;\n        cancel(): void;\n        isPending(): any;\n    };\n    export function supportsLookbehind(): boolean;\n    export function skipEmptyMatch(line: any, last: any, supportsUnicodeFlag: any): 1 | 2;\n}\ndeclare module \"ace-code/src/lib/keys\" {\n    export function keyCodeToString(keyCode: number): string;\n}\ndeclare module \"ace-code/src/lib/event\" {\n    export function addListener(elem: any, type: string, callback: any, destroyer?: any): void;\n    export function removeListener(elem: any, type: any, callback: any): void;\n    export function stopEvent(e: any): boolean;\n    export function stopPropagation(e: any): void;\n    export function preventDefault(e: any): void;\n    export function getButton(e: any): any;\n    export function capture(el: any, eventHandler: any, releaseCaptureHandler: any): (e: any) => void;\n    export function addMouseWheelListener(el: any, callback: any, destroyer?: any): void;\n    export function addMultiMouseDownListener(elements: any, timeouts: any, eventHandler: any, callbackName: any, destroyer?: any): void;\n    export function getModifierString(e: KeyboardEvent | MouseEvent): any;\n    export function addCommandKeyListener(el: EventTarget, callback: (e: KeyboardEvent, hashId: number, keyCode: number) => void, destroyer?: any): void;\n    export function nextTick(callback: any, win: any): void;\n    export const $idleBlocked: boolean;\n    export function onIdle(cb: CallableFunction, timeout: number): ReturnType<typeof setTimeout>;\n    export const $idleBlockId: null | ReturnType<typeof setTimeout>;\n    export function blockIdle(delay?: null | number): void;\n    export const nextFrame: any;\n}\ndeclare module \"ace-code/src/lib/event_emitter\" {\n    export var EventEmitter: any;\n}\ndeclare module \"ace-code/src/lib/net\" {\n    export function get(url: any, callback: any): void;\n    export function loadScript(path: any, callback: any): void;\n    export function qualifyURL(url: any): string;\n}\ndeclare module \"ace-code/src/lib/report_error\" {\n    export function reportError(msg: any, data: any): void;\n}\ndeclare module \"ace-code/src/lib/default_english_messages\" {\n    export var defaultEnglishMessages: {\n        \"autocomplete.popup.aria-roledescription\": string;\n        \"autocomplete.popup.aria-label\": string;\n        \"autocomplete.popup.item.aria-roledescription\": string;\n        \"autocomplete.loading\": string;\n        \"editor.scroller.aria-roledescription\": string;\n        \"editor.scroller.aria-label\": string;\n        \"editor.gutter.aria-roledescription\": string;\n        \"editor.gutter.aria-label\": string;\n        \"error-marker.good-state\": string;\n        \"prompt.recently-used\": string;\n        \"prompt.other-commands\": string;\n        \"prompt.no-matching-commands\": string;\n        \"search-box.find.placeholder\": string;\n        \"search-box.find-all.text\": string;\n        \"search-box.replace.placeholder\": string;\n        \"search-box.replace-next.text\": string;\n        \"search-box.replace-all.text\": string;\n        \"search-box.toggle-replace.title\": string;\n        \"search-box.toggle-regexp.title\": string;\n        \"search-box.toggle-case.title\": string;\n        \"search-box.toggle-whole-word.title\": string;\n        \"search-box.toggle-in-selection.title\": string;\n        \"search-box.search-counter\": string;\n        \"text-input.aria-roledescription\": string;\n        \"text-input.aria-label\": string;\n        \"gutter.code-folding.range.aria-label\": string;\n        \"gutter.code-folding.closed.aria-label\": string;\n        \"gutter.code-folding.open.aria-label\": string;\n        \"gutter.code-folding.closed.title\": string;\n        \"gutter.code-folding.open.title\": string;\n        \"gutter.annotation.aria-label.error\": string;\n        \"gutter.annotation.aria-label.warning\": string;\n        \"gutter.annotation.aria-label.info\": string;\n        \"inline-fold.closed.title\": string;\n        \"gutter-tooltip.aria-label.error.singular\": string;\n        \"gutter-tooltip.aria-label.error.plural\": string;\n        \"gutter-tooltip.aria-label.warning.singular\": string;\n        \"gutter-tooltip.aria-label.warning.plural\": string;\n        \"gutter-tooltip.aria-label.info.singular\": string;\n        \"gutter-tooltip.aria-label.info.plural\": string;\n        \"gutter.annotation.aria-label.security\": string;\n        \"gutter.annotation.aria-label.hint\": string;\n        \"gutter-tooltip.aria-label.security.singular\": string;\n        \"gutter-tooltip.aria-label.security.plural\": string;\n        \"gutter-tooltip.aria-label.hint.singular\": string;\n        \"gutter-tooltip.aria-label.hint.plural\": string;\n        \"editor.tooltip.disable-editing\": string;\n    };\n}\ndeclare module \"ace-code/src/lib/app_config\" {\n    export class AppConfig {\n        defineOptions(obj: any, path: string, options: {\n            [key: string]: any;\n        }): import(\"ace-code\").Ace.AppConfig;\n        resetOptions(obj: any): void;\n        setDefaultValue(path: string, name: string, value: any): boolean;\n        setDefaultValues(path: string, optionHash: {\n            [key: string]: any;\n        }): void;\n        setMessages(value: any, options?: {\n            placeholders?: \"dollarSigns\" | \"curlyBrackets\";\n        }): void;\n        nls(key: string, defaultString: string, params?: {\n            [x: string]: any;\n        }): any;\n        warn: typeof warn;\n        reportError: (msg: any, data: any) => void;\n    }\n    function warn(message: any, ...args: any[]): void;\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n    }\n    export interface AppConfig extends Ace.EventEmitter<any> {\n    }\n}\ndeclare module \"ace-code/src/lib/scroll\" {\n    export function preventParentScroll(event: any): void;\n}\ndeclare module \"ace-code/src/lib/bidiutil\" {\n    export const ON_R: 3;\n    export const AN: 4;\n    export const R_H: 5;\n    export const B: 6;\n    export const RLE: 7;\n    export const DOT: \"·\";\n    export function doBidiReorder(text: string, textCharTypes: any[], isRtl: boolean): any;\n    export function hasBidiCharacters(text: string, textCharTypes: any[]): boolean;\n    export function getVisualFromLogicalIdx(logIdx: number, rowMap: any): number;\n    export var L: number;\n    export var R: number;\n    export var EN: number;\n}\ndeclare module \"ace-code/src/lib/fixoldbrowsers\" {\n}\n"
  },
  {
    "path": "types/ace-modules.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\ndeclare module \"ace-code/src/layer/font_metrics\" {\n    export class FontMetrics {\n        constructor(parentEl: HTMLElement);\n        el: HTMLDivElement;\n        checkForSizeChanges(size?: {\n            height: number;\n            width: number;\n        } | null): void;\n        charSizes: any;\n        allowBoldFonts: boolean;\n        setPolling(val: boolean): void;\n        getCharacterWidth(ch: any): any;\n        destroy(): void;\n        els: any[] | HTMLElement | Text;\n        transformCoordinates(clientPos: any, elPos: any): any[];\n    }\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type FontMetricsEvents = import(\"ace-code\").Ace.FontMetricsEvents;\n    }\n    export interface FontMetrics extends Ace.EventEmitter<Ace.FontMetricsEvents> {\n    }\n}\ndeclare module \"ace-code/src/apply_delta\" {\n    export function applyDelta(docLines: string[], delta: import(\"ace-code\").Ace.Delta, doNotValidate?: any): void;\n}\ndeclare module \"ace-code/src/document\" {\n    /**\n     * Contains the text of the document. Document can be attached to several [[EditSession `EditSession`]]s.\n     * At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.\n     **/\n    export class Document {\n        /**\n         *\n         * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.\n         * @param {String | String[]} textOrLines text The starting text\n         **/\n        constructor(textOrLines: string | string[]);\n        /**\n         * Replaces all the lines in the current `Document` with the value of `text`.\n         *\n         * @param {String} text The text to use\n         **/\n        setValue(text: string): void;\n        /**\n         * Returns all the lines in the document as a single string, joined by the new line character.\n         **/\n        getValue(): string;\n        /**\n         * Creates a new `Anchor` to define a floating point in the document.\n         * @param {Number} row The row number to use\n         * @param {Number} column The column number to use\n         **/\n        createAnchor(row: number, column: number): Anchor;\n        /**\n         * Returns the newline character that's being used, depending on the value of `newLineMode`.\n         * @returns {String} If `newLineMode == windows`, `\\r\\n` is returned.\n         *  If `newLineMode == unix`, `\\n` is returned.\n         *  If `newLineMode == auto`, the value of `autoNewLine` is returned.\n         *\n         **/\n        getNewLineCharacter(): string;\n        /**\n         * [Sets the new line mode.]{: #Document.setNewLineMode.desc}\n         * @param {NewLineMode} newLineMode [The newline mode to use; can be either `windows`, `unix`, or `auto`]\n         **/\n        setNewLineMode(newLineMode: NewLineMode): void;\n        /**\n         * Returns the type of newlines being used; either `windows`, `unix`, or `auto`\n         **/\n        getNewLineMode(): NewLineMode;\n        /**\n         * Returns `true` if `text` is a newline character (either `\\r\\n`, `\\r`, or `\\n`).\n         * @param {String} text The text to check\n         **/\n        isNewLine(text: string): boolean;\n        /**\n         * Returns a verbatim copy of the given line as it is in the document\n         * @param {Number} row The row index to retrieve\n         **/\n        getLine(row: number): string;\n        /**\n         * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.\n         * @param {Number} firstRow The first row index to retrieve\n         * @param {Number} lastRow The final row index to retrieve\n         **/\n        getLines(firstRow: number, lastRow: number): string[];\n        /**\n         * Returns all lines in the document as string array.\n         **/\n        getAllLines(): string[];\n        /**\n         * Returns the number of rows in the document.\n         **/\n        getLength(): number;\n        /**\n         * Returns all the text within `range` as a single string.\n         * @param {IRange} range The range to work with.\n         *\n         **/\n        getTextRange(range: IRange): string;\n        /**\n         * Returns all the text within `range` as an array of lines.\n         * @param {IRange} range The range to work with.\n         *\n         **/\n        getLinesForRange(range: IRange): string[];\n        /**\n         * @deprecated\n         */\n        insertLines(row: any, lines: any): void;\n        /**\n         * @deprecated\n         */\n        removeLines(firstRow: any, lastRow: any): string[];\n        /**\n         * @deprecated\n         */\n        insertNewLine(position: any): Point;\n        /**\n         * Inserts a block of `text` at the indicated `position`.\n         * @param {Point} position The position to start inserting at; it's an object that looks like `{ row: row, column: column}`\n         * @param {String} text A chunk of text to insert\n         * @returns {Point} The position ({row, column}) of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.\n         **/\n        insert(position: Point, text: string): Point;\n        /**\n         * Inserts `text` into the `position` at the current row. This method also triggers the `\"change\"` event.\n         *\n         * This differs from the `insert` method in two ways:\n         *   1. This does NOT handle newline characters (single-line text only).\n         *   2. This is faster than the `insert` method for single-line text insertions.\n         *\n         * @param {Point} position The position to insert at; it's an object that looks like `{ row: row, column: column}`\n         * @param {String} text A chunk of text without new lines\n         * @returns {Point} Returns the position of the end of the inserted text\n         **/\n        insertInLine(position: Point, text: string): Point;\n        clippedPos(row: number, column: number): Point;\n        clonePos(pos: Point): Point;\n        pos(row: number, column: number): Point;\n        /**\n         * Inserts the elements in `lines` into the document as full lines (does not merge with existing line), starting at the row index given by `row`. This method also triggers the `\"change\"` event.\n         * @param {Number} row The index of the row to insert at\n         * @param {string[]} lines An array of strings\n         **/\n        insertFullLines(row: number, lines: string[]): void;\n        /**\n         * Inserts the elements in `lines` into the document, starting at the position index given by `row`. This method also triggers the `\"change\"` event.\n         * @param {string[]} lines An array of strings\n         * @returns {Point} Contains the final row and column, like this:\n         *   ```\n         *   {row: endRow, column: 0}\n         *   ```\n         *   If `lines` is empty, this function returns an object containing the current row, and column, like this:\n         *   ```\n         *   {row: row, column: 0}\n         *   ```\n         **/\n        insertMergedLines(position: Point, lines: string[]): Point;\n        /**\n         * Removes the `range` from the document.\n         * @param {IRange} range A specified Range to remove\n         * @returns {Point} Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.\n         **/\n        remove(range: IRange): Point;\n        /**\n         * Removes the specified columns from the `row`. This method also triggers a `\"change\"` event.\n         * @param {Number} row The row to remove from\n         * @param {Number} startColumn The column to start removing at\n         * @param {Number} endColumn The column to stop removing at\n         * @returns {Point} Returns an object containing `startRow` and `startColumn`, indicating the new row and column values.<br/>If `startColumn` is equal to `endColumn`, this function returns nothing.\n         **/\n        removeInLine(row: number, startColumn: number, endColumn: number): Point;\n        /**\n         * Removes a range of full lines. This method also triggers the `\"change\"` event.\n         * @param {Number} firstRow The first row to be removed\n         * @param {Number} lastRow The last row to be removed\n         * @returns {String[]} Returns all the removed lines.\n         **/\n        removeFullLines(firstRow: number, lastRow: number): string[];\n        /**\n         * Removes the new line between `row` and the row immediately following it. This method also triggers the `\"change\"` event.\n         * @param {Number} row The row to check\n         *\n         **/\n        removeNewLine(row: number): void;\n        /**\n         * Replaces a range in the document with the new `text`.\n         * @param {Range | IRange} range A specified Range to replace\n         * @param {String} text The new text to use as a replacement\n         * @returns {Point} Returns an object containing the final row and column, like this:\n         *     {row: endRow, column: 0}\n         * If the text and range are empty, this function returns an object containing the current `range.start` value.\n         * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.\n         *\n         **/\n        replace(range: Range | IRange, text: string): Point;\n        /**\n         * Applies all changes in `deltas` to the document.\n         * @param {Delta[]} deltas An array of delta objects (can include \"insert\" and \"remove\" actions)\n         **/\n        applyDeltas(deltas: Delta[]): void;\n        /**\n         * Reverts all changes in `deltas` from the document.\n         * @param {Delta[]} deltas An array of delta objects (can include \"insert\" and \"remove\" actions)\n         **/\n        revertDeltas(deltas: Delta[]): void;\n        /**\n         * Applies `delta` to the document.\n         * @param {Delta} delta A delta object (can include \"insert\" and \"remove\" actions)\n         **/\n        applyDelta(delta: Delta, doNotValidate?: boolean): void;\n        /**\n         * Reverts `delta` from the document.\n         * @param {Delta} delta A delta object (can include \"insert\" and \"remove\" actions)\n         **/\n        revertDelta(delta: Delta): void;\n        /**\n         * Converts an index position in a document to a `{row, column}` object.\n         *\n         * Index refers to the \"absolute position\" of a character in the document. For example:\n         *\n         * ```javascript\n         * var x = 0; // 10 characters, plus one for newline\n         * var y = -1;\n         * ```\n         *\n         * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second.\n         *\n         * @param {Number} index An index to convert\n         * @param {Number} [startRow=0] The row from which to start the conversion\n         * @returns {Point} A `{row, column}` object of the `index` position\n         */\n        indexToPosition(index: number, startRow?: number): Point;\n        /**\n         * Converts the `{row, column}` position in a document to the character's index.\n         *\n         * Index refers to the \"absolute position\" of a character in the document. For example:\n         *\n         * ```javascript\n         * var x = 0; // 10 characters, plus one for newline\n         * var y = -1;\n         * ```\n         *\n         * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second.\n         *\n         * @param {Point} pos The `{row, column}` to convert\n         * @param {Number} [startRow=0] The row from which to start the conversion\n         * @returns {Number} The index position in the document\n         */\n        positionToIndex(pos: Point, startRow?: number): number;\n    }\n    export type Delta = import(\"ace-code\").Ace.Delta;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type IRange = import(\"ace-code\").Ace.IRange;\n    export type NewLineMode = import(\"ace-code\").Ace.NewLineMode;\n    import { Anchor } from \"ace-code/src/anchor\";\n    import { Range } from \"ace-code/src/range\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type DocumentEvents = import(\"ace-code\").Ace.DocumentEvents;\n    }\n    export interface Document extends Ace.EventEmitter<Ace.DocumentEvents> {\n    }\n}\ndeclare module \"ace-code/src/anchor\" {\n    /**\n     * Defines a floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the anchor is updated.\n     **/\n    export class Anchor {\n        /**\n         * Creates a new `Anchor` and associates it with a document.\n         *\n         * @param {Document} doc The document to associate with the anchor\n         * @param {Number|import(\"ace-code\").Ace.Point} row The starting row position\n         * @param {Number} [column] The starting column position\n         **/\n        constructor(doc: Document, row: number | import(\"ace-code\").Ace.Point, column?: number);\n        /**\n         * Returns an object identifying the `row` and `column` position of the current anchor.\n         **/\n        getPosition(): import(\"ace-code\").Ace.Point;\n        /**\n         *\n         * Returns the current document.\n         **/\n        getDocument(): Document;\n        /**\n         * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.\n         * @param {Number} row The row index to move the anchor to\n         * @param {Number} column The column index to move the anchor to\n         * @param {Boolean} [noClip] Identifies if you want the position to be clipped\n         **/\n        setPosition(row: number, column: number, noClip?: boolean): void;\n        row: any;\n        column: number;\n        /**\n         * When called, the `\"change\"` event listener is removed.\n         *\n         **/\n        detach(): void;\n        /**\n         * When called, the `\"change\"` event listener is appended.\n         * @param {Document} doc The document to associate with\n         *\n         **/\n        attach(doc: Document): void;\n        document: Document;\n        markerId?: number;\n    }\n    export type Document = import(\"ace-code/src/document\").Document;\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type AnchorEvents = import(\"ace-code\").Ace.AnchorEvents;\n        type Document = import(\"ace-code\").Ace.Document;\n    }\n    export interface Anchor extends Ace.EventEmitter<Ace.AnchorEvents> {\n        markerId?: number;\n        document: Ace.Document;\n    }\n}\ndeclare module \"ace-code/src/config\" {\n    const _exports: {\n        defineOptions(obj: any, path: string, options: {\n            [key: string]: any;\n        }): import(\"ace-code\").Ace.AppConfig;\n        resetOptions(obj: any): void;\n        setDefaultValue(path: string, name: string, value: any): boolean;\n        setDefaultValues(path: string, optionHash: {\n            [key: string]: any;\n        }): void;\n        setMessages(value: any, options?: {\n            placeholders?: \"dollarSigns\" | \"curlyBrackets\";\n        }): void;\n        nls(key: string, defaultString: string, params?: {\n            [x: string]: any;\n        }): any;\n        warn: (message: any, ...args: any[]) => void;\n        reportError: (msg: any, data: any) => void;\n        once<K extends string | number | symbol>(name: K, callback: any): void;\n        setDefaultHandler(name: string, callback: Function): void;\n        removeDefaultHandler(name: string, callback: Function): void;\n        on<K extends string | number | symbol>(name: K, callback: any, capturing?: boolean): any;\n        addEventListener<K extends string | number | symbol>(name: K, callback: any, capturing?: boolean): any;\n        off<K extends string | number | symbol>(name: K, callback: any): void;\n        removeListener<K extends string | number | symbol>(name: K, callback: any): void;\n        removeEventListener<K extends string | number | symbol>(name: K, callback: any): void;\n        removeAllListeners(name?: string): void;\n        /**\n         * @param {K} key - The key of the config option to retrieve.\n         * @returns {import(\"ace-code\").Ace.ConfigOptions[K]} - The value of the config option.\n         */\n        get: <K extends keyof import(\"ace-code\").Ace.ConfigOptions>(key: K) => import(\"ace-code\").Ace.ConfigOptions[K];\n        set: <K extends keyof import(\"ace-code\").Ace.ConfigOptions>(key: K, value: import(\"ace-code\").Ace.ConfigOptions[K]) => void;\n        all: () => import(\"ace-code\").Ace.ConfigOptions;\n        /**\n         * module loading\n         */\n        moduleUrl: (name: string, component?: string) => string;\n        setModuleUrl: (name: string, subst: string) => string;\n        /** @arg {(name: string, callback: (error: any, module: any) => void) => void} cb */\n        setLoader: (cb: (name: string, callback: (error: any, module: any) => void) => void) => void;\n        dynamicModules: any;\n        loadModule: (moduleId: string | [\n            string,\n            string\n        ], onLoad: (module: any) => void) => void;\n        setModuleLoader: (moduleName: any, onLoad: any) => void;\n        version: \"1.43.6\";\n    };\n    export = _exports;\n}\ndeclare module \"ace-code/src/layer/lines\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    export class Lines {\n        constructor(element: HTMLElement, canvasHeight?: number);\n        element: HTMLElement;\n        canvasHeight: number;\n        cells: any[];\n        cellCache: any[];\n        moveContainer(config: LayerConfig): void;\n        pageChanged(oldConfig: LayerConfig, newConfig: LayerConfig): boolean;\n        computeLineTop(row: number, config: Partial<LayerConfig>, session: EditSession): number;\n        computeLineHeight(row: number, config: LayerConfig, session: EditSession): number;\n        getLength(): number;\n        get(index: number): any;\n        shift(): void;\n        pop(): void;\n        push(cell: any): void;\n        unshift(cell: any): void;\n        last(): any;\n        createCell(row: any, config: any, session: any, initElement: any): any;\n    }\n}\ndeclare module \"ace-code/src/layer/gutter\" {\n    export class Gutter {\n        constructor(parentEl: HTMLElement);\n        element: HTMLDivElement;\n        gutterWidth: number;\n        setSession(session: EditSession): void;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        addGutterDecoration(row: number, className: string): void;\n        removeGutterDecoration(row: number, className: string): void;\n        setAnnotations(annotations: any[]): void;\n        update(config: LayerConfig): void;\n        config: import(\"ace-code\").Ace.LayerConfig;\n        oldLastRow: number;\n        updateLineHighlight(): void;\n        scrollLines(config: LayerConfig): void;\n        setHighlightGutterLine(highlightGutterLine: boolean): void;\n        setShowLineNumbers(show: boolean): void;\n        getShowLineNumbers(): boolean;\n        setShowFoldWidgets(show?: boolean): void;\n        getShowFoldWidgets(): boolean;\n        getRegion(point: {\n            x: number;\n        }): \"markers\" | \"foldWidgets\";\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    export type GutterRenderer = {\n        /**\n         * - Gets the text to display for a given row\n         */\n        getText: (session: EditSession, row: number) => string;\n        /**\n         * - Calculates the width needed for the gutter\n         */\n        getWidth: (session: EditSession, lastLineNumber: number, config: any) => number;\n        /**\n         * - Updates the gutter display\n         */\n        update?: (e: undefined, editor: Editor) => void;\n        /**\n         * - Attaches the renderer to an editor\n         */\n        attach?: (editor: Editor) => void;\n        /**\n         * - Detaches the renderer from an editor\n         */\n        detach?: (editor: Editor) => void;\n    };\n    import { Lines } from \"ace-code/src/layer/lines\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type GutterEvents = import(\"ace-code\").Ace.GutterEvents;\n    }\n    export interface Gutter extends Ace.EventEmitter<Ace.GutterEvents> {\n    }\n}\ndeclare module \"ace-code/src/layer/marker\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    export class Marker {\n        constructor(parentEl: HTMLElement);\n        element: HTMLDivElement;\n        setPadding(padding: number): void;\n        setSession(session: EditSession): void;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        setMarkers(markers: {\n            [x: number]: import(\"ace-code\").Ace.MarkerLike;\n        }): void;\n        markers: {\n            [x: number]: import(\"ace-code\").Ace.MarkerLike;\n        };\n        elt(className: string, css: string): void;\n        i: number;\n        update(config: LayerConfig): void;\n        config: import(\"ace-code\").Ace.LayerConfig;\n        drawTextMarker(stringBuilder: undefined, range: Range, clazz: string, layerConfig: Partial<LayerConfig>, extraStyle?: string): void;\n        drawMultiLineMarker(stringBuilder: undefined, range: Range, clazz: string, config: LayerConfig, extraStyle?: string): void;\n        drawSingleLineMarker(stringBuilder: undefined, range: Range, clazz: string, config: Partial<LayerConfig>, extraLength?: number, extraStyle?: string): void;\n        drawBidiSingleLineMarker(stringBuilder: undefined, range: Range, clazz: string, config: Partial<LayerConfig>, extraLength: number, extraStyle: string): void;\n        drawFullLineMarker(stringBuilder: undefined, range: Range, clazz: string, config: Partial<LayerConfig>, extraStyle?: undefined): void;\n        drawScreenLineMarker(stringBuilder: undefined, range: Range, clazz: string, config: Partial<LayerConfig>, extraStyle?: undefined): void;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/layer/text_util\" {\n    export function isTextToken(tokenType: any): boolean;\n}\ndeclare module \"ace-code/src/layer/text\" {\n    export class Text {\n        constructor(parentEl: HTMLElement);\n        dom: typeof dom;\n        element: HTMLDivElement;\n        EOL_CHAR: any;\n        setPadding(padding: number): void;\n        getLineHeight(): number;\n        getCharacterWidth(): number;\n        checkForSizeChanges(): void;\n        setSession(session: EditSession): void;\n        session: EditSession;\n        setShowInvisibles(showInvisibles: string): boolean;\n        showInvisibles: any;\n        showSpaces: boolean;\n        showTabs: boolean;\n        showEOL: boolean;\n        setDisplayIndentGuides(display: boolean): boolean;\n        displayIndentGuides: any;\n        setHighlightIndentGuides(highlight: boolean): boolean;\n        tabSize: number;\n        updateLines(config: LayerConfig, firstRow: number, lastRow: number): void;\n        config: import(\"ace-code\").Ace.LayerConfig;\n        scrollLines(config: LayerConfig): void;\n        update(config: LayerConfig): void;\n        renderIndentGuide(parent: any, value: any, max: any): any;\n        EOF_CHAR: string;\n        EOL_CHAR_LF: string;\n        EOL_CHAR_CRLF: string;\n        TAB_CHAR: string;\n        SPACE_CHAR: string;\n        MAX_LINE_LENGTH: number;\n        destroy: {};\n        onChangeTabSize: () => void;\n    }\n    export type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    type TextMarkersMixin = {\n    };\n    import dom = require(\"ace-code/src/lib/dom\");\n    import { Lines } from \"ace-code/src/layer/lines\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type TextEvents = import(\"ace-code\").Ace.TextEvents;\n        type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    }\n    export interface Text extends Ace.EventEmitter<Ace.TextEvents>, TextMarkersMixin {\n        config: Ace.LayerConfig;\n    }\n}\ndeclare module \"ace-code/src/layer/cursor\" {\n    export class Cursor {\n        constructor(parentEl: HTMLElement);\n        element: HTMLDivElement;\n        isVisible: boolean;\n        isBlinking: boolean;\n        blinkInterval: number;\n        smoothBlinking: boolean;\n        cursors: any[];\n        cursor: HTMLDivElement;\n        setPadding(padding: number): void;\n        setSession(session: EditSession): void;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        setBlinking(blinking: boolean): void;\n        setBlinkInterval(blinkInterval: number): void;\n        setSmoothBlinking(smoothBlinking: boolean): void;\n        addCursor(): HTMLDivElement;\n        removeCursor(): any;\n        hideCursor(): void;\n        showCursor(): void;\n        restartTimer(): void;\n        intervalId: ReturnType<typeof setInterval>;\n        getPixelPosition(position?: import(\"ace-code\").Ace.Point, onScreen?: boolean): {\n            left: number;\n            top: number;\n        };\n        isCursorInView(pixelPos: any, config: any): boolean;\n        update(config: any): void;\n        config: any;\n        overwrite: any;\n        destroy(): void;\n        drawCursor: any;\n        timeoutId?: number;\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export interface Cursor {\n        timeoutId?: number;\n    }\n}\ndeclare module \"ace-code/src/scrollbar\" {\n    const VScrollBar_base: typeof Scrollbar;\n    /**\n     * Represents a vertical scroll bar.\n     **/\n    export class VScrollBar extends Scrollbar {\n        /**\n         * Creates a new `VScrollBar`. `parent` is the owner of the scroll bar.\n         * @param {Element} parent A DOM element\n         * @param {Object} renderer An editor renderer\n         **/\n        constructor(parent: Element, renderer: any);\n        scrollTop: number;\n        scrollHeight: number;\n        width: number;\n        /**\n         * Returns the width of the scroll bar.\n         **/\n        getWidth(): number;\n        /**\n         * Sets the height of the scroll bar, in pixels.\n         * @param {Number} height The new height\n         **/\n        setHeight(height: number): void;\n        /**\n         * Sets the scroll height of the scroll bar, in pixels.\n         * @param {Number} height The new scroll height\n         **/\n        setScrollHeight(height: number): void;\n        /**\n         * Sets the scroll top of the scroll bar.\n         * @param {Number} scrollTop The new scroll top\n         **/\n        setScrollTop(scrollTop: number): void;\n        /**\n         * Sets the inner height of the scroll bar, in pixels.\n         * @param {Number} height The new inner height\n         * @deprecated Use setScrollHeight instead\n         **/\n        setInnerHeight: (height: number) => void;\n    }\n    const HScrollBar_base: typeof Scrollbar;\n    /**\n     * Represents a horisontal scroll bar.\n     **/\n    export class HScrollBar extends Scrollbar {\n        /**\n         * Creates a new `HScrollBar`. `parent` is the owner of the scroll bar.\n         * @param {Element} parent A DOM element\n         * @param {Object} renderer An editor renderer\n         **/\n        constructor(parent: Element, renderer: any);\n        scrollLeft: number;\n        height: any;\n        /**\n         * Returns the height of the scroll bar.\n         **/\n        getHeight(): number;\n        /**\n         * Sets the width of the scroll bar, in pixels.\n         * @param {Number} width The new width\n         **/\n        setWidth(width: number): void;\n        /**\n         * Sets the inner width of the scroll bar, in pixels.\n         * @param {Number} width The new inner width\n         * @deprecated Use setScrollWidth instead\n         **/\n        setInnerWidth(width: number): void;\n        /**\n         * Sets the scroll width of the scroll bar, in pixels.\n         * @param {Number} width The new scroll width\n         **/\n        setScrollWidth(width: number): void;\n        /**\n         * Sets the scroll left of the scroll bar.\n         * @param {Number} scrollLeft The new scroll left\n         **/\n        setScrollLeft(scrollLeft: number): void;\n    }\n    /**\n     * An abstract class representing a native scrollbar control.\n     **/\n    class Scrollbar {\n        /**\n         * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.\n         * @param {Element} parent A DOM element\n         **/\n        constructor(parent: Element, classSuffix: string);\n        element: HTMLDivElement;\n        inner: HTMLDivElement;\n        skipEvent: boolean;\n        setVisible(isVisible: any): void;\n        isVisible: any;\n        coeff: number;\n    }\n    export { VScrollBar as ScrollBar, VScrollBar as ScrollBarV, HScrollBar as ScrollBarH };\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type ScrollbarEvents = import(\"ace-code\").Ace.ScrollbarEvents;\n    }\n    export interface VScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n    export interface HScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n}\ndeclare module \"ace-code/src/scrollbar_custom\" {\n    const VScrollBar_base: typeof ScrollBar;\n    /**\n     * Represents a vertical scroll bar.\n     * @class VScrollBar\n     **/\n    /**\n     * Creates a new `VScrollBar`. `parent` is the owner of the scroll bar.\n     * @param {Element} parent A DOM element\n     * @param {Object} renderer An editor renderer\n     *\n     * @constructor\n     **/\n    export class VScrollBar extends ScrollBar {\n        constructor(parent: any, renderer: any);\n        scrollTop: number;\n        scrollHeight: number;\n        parent: any;\n        width: number;\n        renderer: any;\n        getHeight(): number;\n        /**\n         * Returns new top for scroll thumb\n         **/\n        scrollTopFromThumbTop(thumbTop: number): number;\n        /**\n         * Returns the width of the scroll bar.\n         **/\n        getWidth(): number;\n        /**\n         * Sets the height of the scroll bar, in pixels.\n         * @param {Number} height The new height\n         **/\n        setHeight(height: number): void;\n        height: number;\n        slideHeight: number;\n        viewHeight: number;\n        /**\n         * Sets the inner and scroll height of the scroll bar, in pixels.\n         * @param {Number} height The new inner height\n         *\n         * @param {boolean} force Forcely update height\n         **/\n        setScrollHeight(height: number, force: boolean): void;\n        pageHeight: any;\n        thumbHeight: number;\n        /**\n         * Sets the scroll top of the scroll bar.\n         * @param {Number} scrollTop The new scroll top\n         **/\n        setScrollTop(scrollTop: number): void;\n        thumbTop: number;\n        setInnerHeight: (height: number, force: boolean) => void;\n    }\n    const HScrollBar_base: typeof ScrollBar;\n    /**\n     * Represents a horizontal scroll bar.\n     **/\n    export class HScrollBar extends ScrollBar {\n        /**\n         * Creates a new `HScrollBar`. `parent` is the owner of the scroll bar.\n         * @param {Element} parent A DOM element\n         * @param {Object} renderer An editor renderer\n         **/\n        constructor(parent: Element, renderer: any);\n        scrollLeft: number;\n        scrollWidth: number;\n        height: number;\n        renderer: any;\n        /**\n         * Returns the height of the scroll bar.\n         **/\n        getHeight(): number;\n        /**\n         * Returns new left for scroll thumb\n         **/\n        scrollLeftFromThumbLeft(thumbLeft: number): number;\n        /**\n         * Sets the width of the scroll bar, in pixels.\n         * @param {Number} width The new width\n         **/\n        setWidth(width: number): void;\n        width: number;\n        slideWidth: number;\n        viewWidth: number;\n        /**\n         * Sets the inner and scroll width of the scroll bar, in pixels.\n         * @param {Number} width The new inner width\n         * @param {boolean} force Forcely update width\n         **/\n        setScrollWidth(width: number, force: boolean): void;\n        pageWidth: any;\n        thumbWidth: number;\n        /**\n         * Sets the scroll left of the scroll bar.\n         * @param {Number} scrollLeft The new scroll left\n         **/\n        setScrollLeft(scrollLeft: number): void;\n        thumbLeft: number;\n        setInnerWidth: (width: number, force: boolean) => void;\n    }\n    /**\n     * An abstract class representing a native scrollbar control.\n     **/\n    class ScrollBar {\n        /**\n         * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.\n         * @param {Element} parent A DOM element\n         **/\n        constructor(parent: Element, classSuffix: string);\n        element: HTMLDivElement;\n        inner: HTMLDivElement;\n        VScrollWidth: number;\n        HScrollHeight: number;\n        skipEvent: boolean;\n        setVisible(isVisible: any): void;\n        isVisible: any;\n        coeff: number;\n    }\n    export { VScrollBar as ScrollBar, VScrollBar as ScrollBarV, HScrollBar as ScrollBarH };\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type ScrollbarEvents = import(\"ace-code\").Ace.ScrollbarEvents;\n    }\n    export interface VScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n    export interface HScrollBar extends Ace.EventEmitter<Ace.ScrollbarEvents> {\n    }\n}\ndeclare module \"ace-code/src/renderloop\" {\n    /**\n     * Batches changes (that force something to be redrawn) in the background.\n     **/\n    export class RenderLoop {\n        constructor(onRender: any, win: any);\n        onRender: any;\n        pending: boolean;\n        changes: number;\n        window: any;\n        schedule(change: any): void;\n        clear(change: any): number;\n    }\n}\ndeclare module \"ace-code/src/css/editor-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/layer/decorators\" {\n    export class Decorator {\n        constructor(scrollbarV: import(\"ace-code\").Ace.VScrollbar, renderer: import(\"ace-code/src/virtual_renderer\").VirtualRenderer);\n        renderer: import(\"ace-code/src/virtual_renderer\").VirtualRenderer;\n        pixelRatio: number;\n        maxHeight: number;\n        lineHeight: number;\n        minDecorationHeight: number;\n        halfMinDecorationHeight: number;\n        colors: {};\n        canvas: HTMLCanvasElement;\n        setScrollBarV(scrollbarV: any): void;\n        scrollbarV: any;\n        getVerticalOffsetForRow(row: any): number;\n        setDimensions(config: any): void;\n        canvasHeight: any;\n        canvasWidth: any;\n        heightRatio: number;\n        setZoneWidth(): void;\n        oneZoneWidth: any;\n        destroy(): void;\n    }\n}\ndeclare module \"ace-code/src/virtual_renderer\" {\n    /**\n     * The class that is responsible for drawing everything you see on the screen!\n     * @related editor.renderer\n     **/\n    export class VirtualRenderer {\n        /**\n         * Constructs a new `VirtualRenderer` within the `container` specified, applying the given `theme`.\n         * @param {HTMLElement | null} [container] The root element of the editor\n         * @param {String} [theme] The starting theme\n         **/\n        constructor(container?: HTMLElement | null, theme?: string);\n        container: HTMLElement;\n        scroller: HTMLElement;\n        content: HTMLElement;\n        canvas: HTMLDivElement;\n        scrollBar: VScrollBar;\n        scrollBarV: import(\"ace-code\").Ace.VScrollbar;\n        scrollBarH: import(\"ace-code\").Ace.HScrollbar;\n        scrollTop: number;\n        scrollLeft: number;\n        cursorPos: {\n            row: number;\n            column: number;\n        };\n        layerConfig: {\n            width: number;\n            padding: number;\n            firstRow: number;\n            firstRowScreen: number;\n            lastRow: number;\n            lineHeight: number;\n            characterWidth: number;\n            minHeight: number;\n            maxHeight: number;\n            offset: number;\n            height: number;\n            gutterOffset: number;\n        };\n        scrollMargin: {\n            left: number;\n            right: number;\n            top: number;\n            bottom: number;\n            v: number;\n            h: number;\n        };\n        margin: {\n            left: number;\n            right: number;\n            top: number;\n            bottom: number;\n            v: number;\n            h: number;\n        };\n        updateCharacterSize(): void;\n        characterWidth: number;\n        lineHeight: number;\n        /**\n         *\n         * Associates the renderer with an [[EditSession `EditSession`]].\n         * @param {EditSession} session The session to associate with\n         **/\n        setSession(session: EditSession): void;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        /**\n         * Triggers a partial update of the text, from the range given by the two parameters.\n         * @param {Number} firstRow The first row to update\n         * @param {Number} lastRow The last row to update\n         **/\n        updateLines(firstRow: number, lastRow: number, force?: boolean): void;\n        /**\n         * Triggers a full update of the text, for all the rows.\n         **/\n        updateText(): void;\n        /**\n         * Triggers a full update of all the layers, for all the rows.\n         * @param {Boolean} [force] If `true`, forces the changes through\n         **/\n        updateFull(force?: boolean): void;\n        /**\n         * Updates the font size.\n         **/\n        updateFontSize(): void;\n        resizing: number;\n        gutterWidth: any;\n        /**\n         * Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.\n         **/\n        adjustWrapLimit(): boolean;\n        /**\n         * Identifies whether you want to have an animated scroll or not.\n         * @param {Boolean} shouldAnimate Set to `true` to show animated scrolls\n         **/\n        setAnimatedScroll(shouldAnimate: boolean): void;\n        /**\n         * Returns whether an animated scroll happens or not.\n         **/\n        getAnimatedScroll(): boolean;\n        /**\n         * Identifies whether you want to show invisible characters or not.\n         * @param {Boolean} showInvisibles Set to `true` to show invisibles\n         **/\n        setShowInvisibles(showInvisibles: boolean): void;\n        /**\n         * Returns whether invisible characters are being shown or not.\n         **/\n        getShowInvisibles(): boolean;\n        getDisplayIndentGuides(): boolean;\n        setDisplayIndentGuides(display: boolean): void;\n        getHighlightIndentGuides(): boolean;\n        setHighlightIndentGuides(highlight: boolean): void;\n        /**\n         * Identifies whether you want to show the print margin or not.\n         * @param {Boolean} showPrintMargin Set to `true` to show the print margin\n         **/\n        setShowPrintMargin(showPrintMargin: boolean): void;\n        /**\n         * Returns whether the print margin is being shown or not.\n         **/\n        getShowPrintMargin(): boolean;\n        /**\n         * Identifies whether you want to show the print margin column or not.\n         * @param {number} printMarginColumn Set to `true` to show the print margin column\n         **/\n        setPrintMarginColumn(printMarginColumn: number): void;\n        /**\n         * Returns whether the print margin column is being shown or not.\n         **/\n        getPrintMarginColumn(): number;\n        /**\n         * Returns `true` if the gutter is being shown.\n         **/\n        getShowGutter(): boolean;\n        /**\n         * Identifies whether you want to show the gutter or not.\n         * @param {Boolean} show Set to `true` to show the gutter\n         **/\n        setShowGutter(show: boolean): void;\n        getFadeFoldWidgets(): boolean;\n        setFadeFoldWidgets(show: boolean): void;\n        setHighlightGutterLine(shouldHighlight: boolean): void;\n        getHighlightGutterLine(): boolean;\n        /**\n         *\n         * Returns the root element containing this renderer.\n         **/\n        getContainerElement(): HTMLElement;\n        /**\n         *\n         * Returns the element that the mouse events are attached to\n         **/\n        getMouseEventTarget(): HTMLElement;\n        /**\n         *\n         * Returns the element to which the hidden text area is added.\n         **/\n        getTextAreaContainer(): HTMLElement;\n        /**\n         * [Returns the index of the first visible row.]{: #VirtualRenderer.getFirstVisibleRow}\n         **/\n        getFirstVisibleRow(): number;\n        /**\n         *\n         * Returns the index of the first fully visible row. \"Fully\" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.\n         **/\n        getFirstFullyVisibleRow(): number;\n        /**\n         *\n         * Returns the index of the last fully visible row. \"Fully\" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.\n         **/\n        getLastFullyVisibleRow(): number;\n        /**\n         *\n         * [Returns the index of the last visible row.]{: #VirtualRenderer.getLastVisibleRow}\n         **/\n        getLastVisibleRow(): number;\n        /**\n         * Sets the padding for all the layers.\n         * @param {Number} padding A new padding value (in pixels)\n         **/\n        setPadding(padding: number): void;\n        setScrollMargin(top?: number, bottom?: number, left?: number, right?: number): void;\n        setMargin(top?: number, bottom?: number, left?: number, right?: number): void;\n        /**\n         * Returns whether the horizontal scrollbar is set to be always visible.\n         **/\n        getHScrollBarAlwaysVisible(): boolean;\n        /**\n         * Identifies whether you want to show the horizontal scrollbar or not.\n         * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible\n         **/\n        setHScrollBarAlwaysVisible(alwaysVisible: boolean): void;\n        /**\n         * Returns whether the horizontal scrollbar is set to be always visible.\n         **/\n        getVScrollBarAlwaysVisible(): boolean;\n        /**\n         * Identifies whether you want to show the horizontal scrollbar or not.\n         * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible\n         **/\n        setVScrollBarAlwaysVisible(alwaysVisible: boolean): void;\n        freeze(): void;\n        unfreeze(): void;\n        desiredHeight: any;\n        /**\n         * Schedules an update to all the front markers in the document.\n         **/\n        updateFrontMarkers(): void;\n        /**\n         *\n         * Schedules an update to all the back markers in the document.\n         **/\n        updateBackMarkers(): void;\n        /**\n         *\n         * Deprecated; (moved to [[EditSession]])\n         * @deprecated\n         **/\n        addGutterDecoration(row: any, className: any): void;\n        /**\n         * Deprecated; (moved to [[EditSession]])\n         * @deprecated\n         **/\n        removeGutterDecoration(row: any, className: any): void;\n        /**\n         *\n         * Redraw breakpoints.\n         */\n        updateBreakpoints(rows?: any): void;\n        /**\n         * Sets annotations for the gutter.\n         * @param {import(\"ace-code\").Ace.Annotation[]} annotations An array containing annotations\n         *\n         **/\n        setAnnotations(annotations: import(\"ace-code\").Ace.Annotation[]): void;\n        /**\n         *\n         * Updates the cursor icon.\n         **/\n        updateCursor(): void;\n        /**\n         *\n         * Hides the cursor icon.\n         **/\n        hideCursor(): void;\n        /**\n         *\n         * Shows the cursor icon.\n         **/\n        showCursor(): void;\n        scrollSelectionIntoView(anchor: Point, lead: Point, offset?: number): void;\n        /**\n         *\n         * Scrolls the cursor into the first visibile area of the editor\n         */\n        scrollCursorIntoView(cursor?: Point, offset?: number, $viewMargin?: {\n            top?: any;\n            bottom?: any;\n        }): void;\n        /**\n         * {:EditSession.getScrollTop}\n         * @related EditSession.getScrollTop\n         **/\n        getScrollTop(): number;\n        /**\n         * {:EditSession.getScrollLeft}\n         * @related EditSession.getScrollLeft\n         **/\n        getScrollLeft(): number;\n        /**\n         * Returns the first visible row, regardless of whether it's fully visible or not.\n         **/\n        getScrollTopRow(): number;\n        /**\n         * Returns the last visible row, regardless of whether it's fully visible or not.\n         **/\n        getScrollBottomRow(): number;\n        /**\n         * Gracefully scrolls from the top of the editor to the row indicated.\n         * @param {Number} row A row id\n         *\n         * @related EditSession.setScrollTop\n         **/\n        scrollToRow(row: number): void;\n        alignCursor(cursor: Point, alignment?: number): number;\n        /**\n         * Gracefully scrolls the editor to the row indicated.\n         * @param {Number} line A line number\n         * @param {Boolean} center If `true`, centers the editor the to indicated line\n         * @param {Boolean} animate If `true` animates scrolling\n         * @param {() => void} [callback] Function to be called after the animation has finished\n         **/\n        scrollToLine(line: number, center: boolean, animate: boolean, callback?: () => void): void;\n        animateScrolling(fromValue: any, callback?: any): void;\n        /**\n         * Scrolls the editor to the y pixel indicated.\n         * @param {Number} scrollTop The position to scroll to\n         **/\n        scrollToY(scrollTop: number): void;\n        /**\n         * Scrolls the editor across the x-axis to the pixel indicated.\n         * @param {Number} scrollLeft The position to scroll to\n         **/\n        scrollToX(scrollLeft: number): void;\n        /**\n         * Scrolls the editor across both x- and y-axes.\n         * @param {Number} x The x value to scroll to\n         * @param {Number} y The y value to scroll to\n         **/\n        scrollTo(x: number, y: number): void;\n        /**\n         * Scrolls the editor across both x- and y-axes.\n         * @param {Number} deltaX The x value to scroll by\n         * @param {Number} deltaY The y value to scroll by\n         **/\n        scrollBy(deltaX: number, deltaY: number): void;\n        /**\n         * Returns `true` if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.\n         * @param {Number} deltaX The x value to scroll by\n         * @param {Number} deltaY The y value to scroll by\n         *\n         **/\n        isScrollableBy(deltaX: number, deltaY: number): boolean;\n        pixelToScreenCoordinates(x: number, y: number): import(\"ace-code\").Ace.ScreenCoordinates;\n        screenToTextCoordinates(x: number, y: number): Point;\n        /**\n         * Returns an object containing the `pageX` and `pageY` coordinates of the document position.\n         * @param {Number} row The document row position\n         * @param {Number} column The document column position\n         *\n         **/\n        textToScreenCoordinates(row: number, column: number): {\n            pageX: number;\n            pageY: number;\n        };\n        /**\n         *\n         * Focuses the current container.\n         **/\n        visualizeFocus(): void;\n        /**\n         *\n         * Blurs the current container.\n         **/\n        visualizeBlur(): void;\n        showComposition(composition: any): void;\n        /**\n         * @param {String} text A string of text to use\n         *\n         * Sets the inner text of the current composition to `text`.\n         **/\n        setCompositionText(text: string): void;\n        /**\n         *\n         * Hides the current composition.\n         **/\n        hideComposition(): void;\n        setGhostText(text: string, position?: Point): void;\n        removeGhostText(): void;\n        addToken(text: string, type: string, row: number, column?: number): void;\n        hideTokensAfterPosition(row: any, column: any): {\n            type: string;\n            value: string;\n        }[];\n        removeExtraToken(row: any, column: any): void;\n        /**\n         * [Sets a new theme for the editor. `theme` should exist, and be a directory path, like `ace/theme/textmate`.]{: #VirtualRenderer.setTheme}\n         * @param {String | Theme} [theme] The path to a theme\n         * @param {() => void} [cb] optional callback\n         **/\n        setTheme(theme?: string | Theme, cb?: () => void): void;\n        /**\n         * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme}\n         **/\n        getTheme(): string;\n        /**\n         * [Adds a new class, `style`, to the editor.]{: #VirtualRenderer.setStyle}\n         * @param {String} style A class name\n         **/\n        setStyle(style: string, include?: boolean): void;\n        /**\n         * [Removes the class `style` from the editor.]{: #VirtualRenderer.unsetStyle}\n         * @param {String} style A class name\n         *\n         **/\n        unsetStyle(style: string): void;\n        setCursorStyle(style: string): void;\n        /**\n         * @param {String} cursorStyle A css cursor style\n         **/\n        setMouseCursor(cursorStyle: string): void;\n        attachToShadowRoot(): void;\n        /**\n         * Destroys the text and cursor layers for this renderer.\n         **/\n        destroy(): void;\n        CHANGE_CURSOR: number;\n        CHANGE_MARKER: number;\n        CHANGE_GUTTER: number;\n        CHANGE_SCROLL: number;\n        CHANGE_LINES: number;\n        CHANGE_TEXT: number;\n        CHANGE_SIZE: number;\n        CHANGE_MARKER_BACK: number;\n        CHANGE_MARKER_FRONT: number;\n        CHANGE_FULL: number;\n        CHANGE_H_SCROLL: number;\n        STEPS: number;\n        textarea: HTMLTextAreaElement;\n        enableKeyboardAccessibility?: boolean;\n        showInvisibles?: boolean;\n        theme?: any;\n        destroyed?: boolean;\n        keyboardFocusClassName?: string;\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type Theme = import(\"ace-code\").Ace.Theme;\n    import { Gutter as GutterLayer } from \"ace-code/src/layer/gutter\";\n    import { Marker as MarkerLayer } from \"ace-code/src/layer/marker\";\n    import { Text as TextLayer } from \"ace-code/src/layer/text\";\n    import { Cursor as CursorLayer } from \"ace-code/src/layer/cursor\";\n    import { VScrollBar } from \"ace-code/src/scrollbar\";\n    import { FontMetrics } from \"ace-code/src/layer/font_metrics\";\n    import { RenderLoop } from \"ace-code/src/renderloop\";\n    import { Decorator } from \"ace-code/src/layer/decorators\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type VirtualRendererEvents = import(\"ace-code\").Ace.VirtualRendererEvents;\n        type OptionsProvider<T> = import(\"ace-code\").Ace.OptionsProvider<T>;\n        type VirtualRendererOptions = import(\"ace-code\").Ace.VirtualRendererOptions;\n        type EditSession = import(\"ace-code\").Ace.EditSession;\n    }\n    export interface VirtualRenderer extends Ace.EventEmitter<Ace.VirtualRendererEvents>, Ace.OptionsProvider<Ace.VirtualRendererOptions> {\n        textarea: HTMLTextAreaElement;\n        enableKeyboardAccessibility?: boolean;\n        showInvisibles?: boolean;\n        theme /**\n         * @overload\n         */? /**\n         * @overload\n         */: any;\n        destroyed?: boolean;\n        session: Ace.EditSession;\n        keyboardFocusClassName?: string;\n    }\n}\ndeclare module \"ace-code/src/selection\" {\n    export class Selection {\n        /**\n         * Creates a new `Selection` object.\n         * @param {EditSession} session The session to use\n         * @constructor\n         **/\n        constructor(session: EditSession);\n        session: EditSession;\n        doc: import(\"ace-code/src/document\").Document;\n        cursor: Anchor;\n        lead: Anchor;\n        anchor: Anchor;\n        /**\n         * Returns `true` if the selection is empty.\n         **/\n        isEmpty(): boolean;\n        /**\n         * Returns `true` if the selection is a multi-line.\n         **/\n        isMultiLine(): boolean;\n        /**\n         * Returns an object containing the `row` and `column` current position of the cursor.\n         **/\n        getCursor(): Point;\n        /**\n         * Sets the row and column position of the anchor. This function also emits the `'changeSelection'` event.\n         * @param {Number} row The new row\n         * @param {Number} column The new column\n         *\n         **/\n        setAnchor(row: number, column: number): void;\n        /**\n         * Returns an object containing the `row` and `column` of the calling selection anchor.\n         *\n         * @related Anchor.getPosition\n         **/\n        getAnchor(): Point;\n        /**\n         * Returns an object containing the `row` and `column` of the calling selection lead.\n         **/\n        getSelectionLead(): any;\n        /**\n         * Returns `true` if the selection is going backwards in the document.\n         **/\n        isBackwards(): boolean;\n        /**\n         * [Returns the [[Range]] for the selected text.]{: #Selection.getRange}\n         **/\n        getRange(): Range;\n        /**\n         * [Empties the selection (by de-selecting it). This function also emits the `'changeSelection'` event.]{: #Selection.clearSelection}\n         **/\n        clearSelection(): void;\n        /**\n         * Selects all the text in the document.\n         **/\n        selectAll(): void;\n        /**\n         * Sets the selection to the provided range.\n         * @param {import(\"ace-code\").Ace.IRange} range The range of text to select\n         * @param {Boolean} [reverse] Indicates if the range should go backwards (`true`) or not\n         **/\n        setRange(range: import(\"ace-code\").Ace.IRange, reverse?: boolean): void;\n        /**\n         * Moves the selection cursor to the indicated row and column.\n         * @param {Number} row The row to select to\n         * @param {Number} column The column to select to\n         **/\n        selectTo(row: number, column: number): void;\n        /**\n         * Moves the selection cursor to the row and column indicated by `pos`.\n         * @param {Point} pos An object containing the row and column\n         **/\n        selectToPosition(pos: Point): void;\n        /**\n         * Moves the selection cursor to the indicated row and column.\n         * @param {Number} row The row to select to\n         * @param {Number} column The column to select to\n         **/\n        moveTo(row: number, column: number): void;\n        /**\n         * Moves the selection cursor to the row and column indicated by `pos`.\n         * @param {Object} pos An object containing the row and column\n         **/\n        moveToPosition(pos: any): void;\n        /**\n         * Moves the selection up one row.\n         **/\n        selectUp(): void;\n        /**\n         * Moves the selection down one row.\n         **/\n        selectDown(): void;\n        /**\n         * Moves the selection right one column.\n         **/\n        selectRight(): void;\n        /**\n         * Moves the selection left one column.\n         **/\n        selectLeft(): void;\n        /**\n         * Moves the selection to the beginning of the current line.\n         **/\n        selectLineStart(): void;\n        /**\n         * Moves the selection to the end of the current line.\n         **/\n        selectLineEnd(): void;\n        /**\n         * Moves the selection to the end of the file.\n         **/\n        selectFileEnd(): void;\n        /**\n         * Moves the selection to the start of the file.\n         **/\n        selectFileStart(): void;\n        /**\n         * Moves the selection to the first word on the right.\n         **/\n        selectWordRight(): void;\n        /**\n         * Moves the selection to the first word on the left.\n         **/\n        selectWordLeft(): void;\n        /**\n         * Moves the selection to highlight the entire word.\n         * @related EditSession.getWordRange\n         **/\n        getWordRange(row: any, column: any): Range;\n        /**\n         * Selects an entire word boundary.\n         **/\n        selectWord(): void;\n        /**\n         * Selects a word, including its right whitespace.\n         * @related EditSession.getAWordRange\n         **/\n        selectAWord(): void;\n        getLineRange(row: any, excludeLastChar: any): Range;\n        /**\n         * Selects the entire line.\n         **/\n        selectLine(): void;\n        /**\n         * Moves the cursor up one row.\n         **/\n        moveCursorUp(): void;\n        /**\n         * Moves the cursor down one row.\n         **/\n        moveCursorDown(): void;\n        /**\n         *\n         * Returns `true` if moving the character next to the cursor in the specified direction is a soft tab.\n         * @param {Point} cursor the current cursor position\n         * @param {Number} tabSize the tab size\n         * @param {Number} direction 1 for right, -1 for left\n         */\n        wouldMoveIntoSoftTab(cursor: Point, tabSize: number, direction: number): boolean;\n        /**\n         * Moves the cursor left one column.\n         **/\n        moveCursorLeft(): void;\n        /**\n         * Moves the cursor right one column.\n         **/\n        moveCursorRight(): void;\n        /**\n         * Moves the cursor to the start of the line.\n         **/\n        moveCursorLineStart(): void;\n        /**\n         * Moves the cursor to the end of the line.\n         **/\n        moveCursorLineEnd(): void;\n        /**\n         * Moves the cursor to the end of the file.\n         **/\n        moveCursorFileEnd(): void;\n        /**\n         * Moves the cursor to the start of the file.\n         **/\n        moveCursorFileStart(): void;\n        /**\n         * Moves the cursor to the word on the right.\n         **/\n        moveCursorLongWordRight(): void;\n        /**\n        *\n        * Moves the cursor to the word on the left.\n        **/\n        moveCursorLongWordLeft(): void;\n        moveCursorShortWordRight(): void;\n        moveCursorShortWordLeft(): void;\n        moveCursorWordRight(): void;\n        moveCursorWordLeft(): void;\n        /**\n         * Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.\n         * @param {Number} rows The number of rows to move by\n         * @param {Number} chars The number of characters to move by\n         *\n         * @related EditSession.documentToScreenPosition\n         **/\n        moveCursorBy(rows: number, chars: number): void;\n        /**\n         * Moves the selection to the position indicated by its `row` and `column`.\n         * @param {Point} position The position to move to\n         **/\n        moveCursorToPosition(position: Point): void;\n        /**\n         * Moves the cursor to the row and column provided. [If `preventUpdateDesiredColumn` is `true`, then the cursor stays in the same column position as its original point.]{: #preventUpdateBoolDesc}\n         * @param {Number} row The row to move to\n         * @param {Number} column The column to move to\n         **/\n        moveCursorTo(row: number, column: number, keepDesiredColumn?: boolean): void;\n        /**\n         * Moves the cursor to the screen position indicated by row and column. {:preventUpdateBoolDesc}\n         * @param {Number} row The row to move to\n         * @param {Number} column The column to move to\n         **/\n        moveCursorToScreen(row: number, column: number, keepDesiredColumn: boolean): void;\n        detach(): void;\n        fromOrientedRange(range: Range & {\n            desiredColumn?: number;\n        }): void;\n        toOrientedRange(range?: Range & {\n            desiredColumn?: number;\n        }): Range & {\n            desiredColumn?: number;\n        };\n        /**\n         * Saves the current cursor position and calls `func` that can change the cursor\n         * postion. The result is the range of the starting and eventual cursor position.\n         * Will reset the cursor position.\n         * @param {Function} func The callback that should change the cursor position\n         **/\n        getRangeOfMovements(func: Function): Range;\n        toJSON(): Range | Range[];\n        fromJSON(data: any): void;\n        isEqual(data: any): boolean;\n        /**\n         * Left for backward compatibility\n         * @deprecated\n         */\n        setSelectionAnchor: (row: number, column: number) => void;\n        /**\n         * Left for backward compatibility\n         * @deprecated\n         */\n        getSelectionAnchor: () => Point;\n        setSelectionRange: (range: import(\"ace-code\").Ace.IRange, reverse?: boolean) => void;\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Anchor = import(\"ace-code/src/anchor\").Anchor;\n    export type Point = import(\"ace-code\").Ace.Point;\n    import { Range } from \"ace-code/src/range\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type MultiSelectionEvents = import(\"ace-code\").Ace.MultiSelectionEvents;\n        type MultiSelectProperties = import(\"ace-code\").Ace.MultiSelectProperties;\n    }\n    export interface Selection extends Ace.EventEmitter<Ace.MultiSelectionEvents>, Ace.MultiSelectProperties {\n    }\n}\ndeclare module \"ace-code/src/clipboard\" {\n    export let lineMode: string | false;\n    export function pasteCancelled(): boolean;\n    export function cancel(): void;\n}\ndeclare module \"ace-code/src/keyboard/textinput\" {\n    export function $setUserAgentForTests(_isMobile: any, _isIOS: any): void;\n    export class TextInput {\n        constructor(parentNode: HTMLElement, host: import(\"ace-code/src/editor\").Editor);\n        host: import(\"ace-code/src/editor\").Editor;\n        text: HTMLTextAreaElement & {\n            msGetInputContext?: () => {\n                compositionStartOffset: number;\n            };\n            getInputContext?: () => {\n                compositionStartOffset: number;\n            };\n        };\n        copied: boolean | string;\n        pasted: boolean;\n        inComposition: (boolean | any) & {\n            context?: any;\n            useTextareaForIME?: boolean;\n            selectionStart?: number;\n            markerRange?: any;\n        };\n        sendingText: boolean;\n        tempStyle: string;\n        commandMode: boolean;\n        ignoreFocusEvents: boolean;\n        lastValue: string;\n        lastSelectionStart: number;\n        lastSelectionEnd: number;\n        lastRestoreEnd: number;\n        rowStart: number;\n        rowEnd: number;\n        numberOfExtraLines: number;\n        resetSelection: (value: any) => void;\n        inputHandler: any;\n        afterContextMenu: boolean;\n        syncComposition: any;\n        onContextMenuClose(): void;\n        closeTimeout: number;\n        setHost(newHost: import(\"ace-code/src/editor\").Editor): void;\n        /**\n         * Sets the number of extra lines in the textarea to improve screen reader compatibility.\n         * Extra lines can help screen readers perform better when reading text.\n         *\n         * @param {number} number - The number of extra lines to add. Must be non-negative.\n         */\n        setNumberOfExtraLines(number: number): void;\n        setAriaLabel(): void;\n        setAriaOptions(options: import(\"ace-code\").Ace.TextInputAriaOptions): void;\n        focus(): void;\n        blur(): void;\n        isFocused(): boolean;\n        setInputHandler(cb: any): void;\n        getInputHandler(): any;\n        getElement(): HTMLTextAreaElement & {\n            msGetInputContext?: () => {\n                compositionStartOffset: number;\n            };\n            getInputContext?: () => {\n                compositionStartOffset: number;\n            };\n        };\n        /**\n         * allows to ignore composition (used by vim keyboard handler in the normal mode)\n         * this is useful on mac, where with some keyboard layouts (e.g swedish) ^ starts composition\n         */\n        setCommandMode(value: boolean): void;\n        setReadOnly(readOnly: any): void;\n        setCopyWithEmptySelection(value: any): void;\n        onContextMenu(e: any): void;\n        moveToMouse(e: any, bringToFront: boolean): void;\n        destroy(): void;\n    }\n}\ndeclare module \"ace-code/src/mouse/mouse_event\" {\n    export class MouseEvent {\n        constructor(domEvent: any, editor: any);\n        speed: number;\n        wheelX: number;\n        wheelY: number;\n        domEvent: any;\n        editor: any;\n        x: any;\n        clientX: any;\n        y: any;\n        clientY: any;\n        propagationStopped: boolean;\n        defaultPrevented: boolean;\n        stopPropagation(): void;\n        preventDefault(): void;\n        stop(): void;\n        /**\n         * Get the document position below the mouse cursor\n         *\n         * @return {Object} 'row' and 'column' of the document position\n         */\n        getDocumentPosition(): any;\n        /**\n         * Get the relative position within the gutter.\n         *\n         * @return {Number} 'row' within the gutter.\n         */\n        getGutterRow(): number;\n        /**\n         * Check if the mouse cursor is inside of the text selection\n         *\n         * @return {Boolean} whether the mouse cursor is inside of the selection\n         */\n        inSelection(): boolean;\n        /**\n         * Get the clicked mouse button\n         *\n         * @return {Number} 0 for left button, 1 for middle button, 2 for right button\n         */\n        getButton(): number;\n        /**\n         * @return {Boolean} whether the shift key was pressed when the event was emitted\n         */\n        getShiftKey(): boolean;\n        getAccelKey(): any;\n        time?: number;\n    }\n    export interface MouseEvent {\n        time?: number;\n    }\n}\ndeclare module \"ace-code/src/mouse/default_handlers\" {\n    export type MouseHandler = import(\"ace-code/src/mouse/mouse_handler\").MouseHandler;\n    export type MouseEvent = import(\"ace-code/src/mouse/mouse_event\").MouseEvent;\n    export class DefaultHandlers {\n        constructor(mouseHandler: MouseHandler);\n        onMouseDown(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, ev: MouseEvent): void;\n        mousedownEvent: import(\"ace-code/src/mouse/mouse_event\").MouseEvent;\n        startSelect(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, pos?: import(\"ace-code\").Ace.Position, waitForClickSelection?: boolean): void;\n        select(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler): void;\n        extendSelectionBy(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, unitName: string | number): void;\n        selectByLinesEnd(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler): void;\n        focusWait(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler): void;\n        onDoubleClick(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, ev: MouseEvent): void;\n        onTripleClick(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, ev: MouseEvent): void;\n        onQuadClick(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, ev: MouseEvent): void;\n        onMouseWheel(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, ev: MouseEvent): void;\n        selectEnd: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler) => void;\n        selectAllEnd: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler) => void;\n        selectByWordsEnd: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler) => void;\n    }\n}\ndeclare module \"ace-code/src/tooltip\" {\n    export class HoverTooltip extends Tooltip {\n        constructor(parentNode?: HTMLElement);\n        timeout: ReturnType<typeof setTimeout> | undefined;\n        lastT: number;\n        idleTime: number;\n        lastEvent: import(\"ace-code/src/mouse/mouse_event\").MouseEvent;\n        waitForHover(): void;\n        addToEditor(editor: Editor): void;\n        removeFromEditor(editor: Editor): void;\n        isOutsideOfText(e: MouseEvent): boolean;\n        setDataProvider(value: (event: MouseEvent, editor: Editor) => void): void;\n        showForRange(editor: Editor, range: Range, domNode: HTMLElement, startingEvent?: MouseEvent): void;\n        range: Range;\n        addMarker(range: Range, session?: EditSession): void;\n        marker: number;\n        row: number;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type MouseEvent = import(\"ace-code/src/mouse/mouse_event\").MouseEvent;\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export var popupManager: PopupManager;\n    export class Tooltip {\n        constructor(parentNode: Element);\n        isOpen: boolean;\n        getElement(): HTMLElement;\n        setText(text: string): void;\n        setHtml(html: string): void;\n        setPosition(x: number, y: number): void;\n        setClassName(className: string): void;\n        setTheme(theme: import(\"ace-code\").Ace.Theme): void;\n        theme: {\n            isDark: boolean;\n            cssClass: string;\n        };\n        show(text?: string, x?: number, y?: number): void;\n        hide(e: any): void;\n        getHeight(): number;\n        getWidth(): number;\n        destroy(): void;\n    }\n    import { Range } from \"ace-code/src/range\";\n    class PopupManager {\n        popups: Tooltip[];\n        addPopup(popup: Tooltip): void;\n        removePopup(popup: Tooltip): void;\n        updatePopups(): void;\n        doPopupsOverlap(popupA: Tooltip, popupB: Tooltip): boolean;\n    }\n    export interface HoverTooltip {\n        row: number;\n    }\n}\ndeclare module \"ace-code/src/mouse/default_gutter_handler\" {\n    export function GutterHandler(this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, mouseHandler: MouseHandler): void;\n    export interface GutterHandler {\n    }\n    export type MouseHandler = import(\"ace-code/src/mouse/mouse_handler\").MouseHandler;\n    export class GutterTooltip extends HoverTooltip {\n        static get annotationLabels(): {\n            error: {\n                singular: any;\n                plural: any;\n            };\n            security: {\n                singular: any;\n                plural: any;\n            };\n            warning: {\n                singular: any;\n                plural: any;\n            };\n            info: {\n                singular: any;\n                plural: any;\n            };\n            hint: {\n                singular: any;\n                plural: any;\n            };\n        };\n        static annotationsToSummaryString(annotations: any): string;\n        constructor(editor: import(\"ace-code/src/editor\").Editor);\n        id: string;\n        editor: import(\"ace-code/src/editor\").Editor;\n        visibleTooltipRow: number | undefined;\n        onDomMouseMove(domEvent: any): void;\n        onDomMouseOut(domEvent: any): void;\n        addToEditor(editor: any): void;\n        removeFromEditor(editor: any): void;\n        showTooltip(row: number): void;\n        /**\n         * Check if cursor is outside gutter\n         */\n        isOutsideOfText(e: any): boolean;\n    }\n    export namespace GutterTooltip {\n        let $uid: number;\n    }\n    import { HoverTooltip } from \"ace-code/src/tooltip\";\n    export interface GutterHandler {\n    }\n}\ndeclare module \"ace-code/src/mouse/dragdrop_handler\" {\n    export type MouseHandler = import(\"ace-code/src/mouse/mouse_handler\").MouseHandler;\n    export function DragdropHandler(mouseHandler: MouseHandler): void;\n    export class DragdropHandler {\n        constructor(mouseHandler: MouseHandler);\n        onDragStart: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, e: any) => any;\n        onDragEnd: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, e: any) => any;\n        onDragEnter: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, e: any) => any;\n        onDragOver: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, e: any) => any;\n        onDragLeave: (e: any) => void;\n        onDrop: (this: import(\"ace-code/src/mouse/mouse_handler\").MouseHandler, e: any) => any;\n    }\n}\ndeclare module \"ace-code/src/mouse/touch_handler\" {\n    export function addTouchListeners(el: any, editor: any): void;\n}\ndeclare module \"ace-code/src/mouse/mouse_handler\" {\n    export class MouseHandler {\n        constructor(editor: Editor);\n        mouseEvent: MouseEvent;\n        editor: import(\"ace-code/src/editor\").Editor;\n        onMouseEvent(name: any, e: any): void;\n        onMouseMove(name: any, e: any): void;\n        onMouseWheel(name: any, e: {\n            wheelX: number;\n            wheelY: number;\n        }): void;\n        setState(state: any): void;\n        state: any;\n        captureMouse(ev: MouseEvent, mouseMoveHandler?: any): ReturnType<typeof setTimeout> | undefined;\n        x: any;\n        y: any;\n        isMousePressed: boolean;\n        releaseMouse: (e: any) => void;\n        cancelContextMenu(): void;\n        destroy(): void;\n        cancelDrag?: boolean;\n        mousedownEvent?: import(\"ace-code\").Ace.MouseEvent;\n        startSelect?: (pos?: import(\"ace-code\").Ace.Point, waitForClickSelection?: boolean) => void;\n        select?: () => void;\n        selectEnd?: () => void;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    import { MouseEvent } from \"ace-code/src/mouse/mouse_event\";\n    namespace Ace {\n        type Range = import(\"ace-code\").Ace.Range;\n        type MouseEvent = import(\"ace-code\").Ace.MouseEvent;\n        type Point = import(\"ace-code\").Ace.Point;\n        type GutterTooltip = import(\"ace-code\").Ace.GutterTooltip;\n    }\n    export interface MouseHandler {\n        cancelDrag?: boolean;\n        mousedownEvent?: Ace.MouseEvent;\n        startSelect?: (pos?: Ace.Point, waitForClickSelection?: boolean) => void;\n        select?: () => void;\n        selectEnd?: () => void;\n    }\n}\ndeclare module \"ace-code/src/mouse/fold_handler\" {\n    export class FoldHandler {\n        constructor(editor: any);\n    }\n}\ndeclare module \"ace-code/src/keyboard/keybinding\" {\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type KeyboardHandler = import(\"ace-code\").Ace.KeyboardHandler;\n    export class KeyBinding {\n        constructor(editor: Editor);\n        setDefaultHandler(kb: KeyboardHandler): void;\n        setKeyboardHandler(kb: KeyboardHandler): void;\n        addKeyboardHandler(kb?: KeyboardHandler & {\n            attach?: (editor: any) => void;\n            detach?: (editor: any) => void;\n        }, pos?: number): void;\n        removeKeyboardHandler(kb: KeyboardHandler & {\n            attach?: (editor: any) => void;\n            detach?: (editor: any) => void;\n        }): boolean;\n        getKeyboardHandler(): KeyboardHandler;\n        getStatusText(): string;\n    }\n}\ndeclare module \"ace-code/src/search\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type SearchOptions = import(\"ace-code\").Ace.SearchOptions;\n    /**\n     * A class designed to handle all sorts of text searches within a [[Document `Document`]].\n     **/\n    export class Search {\n        /**\n         * Sets the search options via the `options` parameter.\n         * @param {Partial<SearchOptions>} options An object containing all the new search properties\n         * @chainable\n        **/\n        set(options: Partial<SearchOptions>): Search;\n        /**\n         * [Returns an object containing all the search options.]{: #Search.getOptions}\n        **/\n        getOptions(): Partial<SearchOptions>;\n        /**\n         * Sets the search options via the `options` parameter.\n         * @param {Partial<SearchOptions>} options object containing all the search propertie\n         * @related Search.set\n        **/\n        setOptions(options: Partial<SearchOptions>): void;\n        /**\n         * Searches for `options.needle`. If found, this method returns the [[Range `Range`]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.\n         * @param {EditSession} session The session to search with\n         **/\n        find(session: EditSession): Range | null | false;\n        /**\n         * Searches for all occurrances `options.needle`. If found, this method returns an array of [[Range `Range`s]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.\n         * @param {EditSession} session The session to search with\n        **/\n        findAll(session: EditSession): Range[];\n        parseReplaceString(replaceString: any): any;\n        /**\n         * Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.\n         * @param {String} input The text to search in\n         * @param {any} replacement The replacing text\n         * + (String): If `options.regExp` is `true`, this function returns `input` with the replacement already made. Otherwise, this function just returns `replacement`.<br/>\n         * If `options.needle` was not found, this function returns `null`.\n         *\n         *\n        **/\n        replace(input: string, replacement: any): string;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/keyboard/hash_handler\" {\n    export type Command = import(\"ace-code\").Ace.Command;\n    export type CommandLike = import(\"ace-code\").Ace.CommandLike;\n    export type Platform = \"win\" | \"mac\";\n    export class HashHandler extends MultiHashHandler {\n    }\n    export namespace HashHandler {\n        function call(thisArg: any, config: any, platform: any): void;\n    }\n    export class MultiHashHandler {\n        constructor(config?: Record<string, CommandLike> | Command[], platform?: Platform);\n        platform: Platform;\n        commands: Record<string, Command>;\n        commandKeyBinding: {};\n        addCommand(command: Command): void;\n        removeCommand(command: Command | string, keepCommand?: boolean): void;\n        bindKey(key: string | {\n            win?: string;\n            mac?: string;\n            position?: number;\n        }, command: CommandLike | string, position?: number): void;\n        addCommands(commands?: Record<string, CommandLike> | Command[]): void;\n        removeCommands(commands: Record<string, CommandLike | string>): void;\n        bindKeys(keyList: Record<string, CommandLike | string>): void;\n        /**\n         * Accepts keys in the form ctrl+Enter or ctrl-Enter\n         * keys without modifiers or shift only\n         */\n        parseKeys(keys: string): {\n            key: string;\n            hashId: number;\n        } | false;\n        findKeyCommand(hashId: number, keyString: string): Command;\n        handleKeyboard(data: any, hashId: number, keyString: string, keyCode: number): {\n            command: string;\n        } | void;\n        getStatusText(editor?: any, data?: any): string;\n    }\n    export namespace MultiHashHandler {\n        function call(thisArg: any, config: any, platform: any): void;\n    }\n}\ndeclare module \"ace-code/src/commands/command_manager\" {\n    const CommandManager_base: typeof MultiHashHandler;\n    export class CommandManager extends MultiHashHandler {\n        /**\n         * new CommandManager(platform, commands)\n         * @param {import(\"ace-code/src/keyboard/hash_handler\").Platform} platform Identifier for the platform; must be either `\"mac\"` or `\"win\"`\n         * @param {any[]} commands A list of commands\n         **/\n        constructor(platform: import(\"ace-code/src/keyboard/hash_handler\").Platform, commands: any[]);\n        byName: Record<string, import(\"ace-code\").Ace.Command>;\n        exec(command: string | string[] | import(\"ace-code\").Ace.Command, editor: Editor, args: any): boolean;\n        canExecute(command: string | import(\"ace-code\").Ace.Command, editor: Editor): boolean;\n        toggleRecording(editor: Editor): boolean;\n        macro: any;\n        recording: boolean;\n        oldMacro: any;\n        replay(editor: Editor): boolean;\n        trimMacro(m: any): any;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    import { MultiHashHandler } from \"ace-code/src/keyboard/hash_handler\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type CommandManagerEvents = import(\"ace-code\").Ace.CommandManagerEvents;\n    }\n    export interface CommandManager extends Ace.EventEmitter<Ace.CommandManagerEvents> {\n    }\n}\ndeclare module \"ace-code/src/commands/default_commands\" {\n    export const commands: import(\"ace-code\").Ace.Command[];\n}\ndeclare module \"ace-code/src/token_iterator\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    /**\n     * This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.\n     **/\n    export class TokenIterator {\n        /**\n         * Creates a new token iterator object. The inital token index is set to the provided row and column coordinates.\n         * @param {EditSession} session The session to associate with\n         * @param {Number} initialRow The row to start the tokenizing at\n         * @param {Number} initialColumn The column to start the tokenizing at\n         **/\n        constructor(session: EditSession, initialRow: number, initialColumn: number);\n        /**\n         * Moves iterator position to the start of previous token.\n         **/\n        stepBackward(): import(\"ace-code\").Ace.Token | null;\n        /**\n         * Moves iterator position to the start of next token.\n         **/\n        stepForward(): import(\"ace-code\").Ace.Token | null;\n        /**\n         *\n         * Returns current token.\n         **/\n        getCurrentToken(): import(\"ace-code\").Ace.Token;\n        /**\n         *\n         * Returns the current row.\n         **/\n        getCurrentTokenRow(): number;\n        /**\n         *\n         * Returns the current column.\n         **/\n        getCurrentTokenColumn(): number;\n        /**\n         * Return the current token position.\n         */\n        getCurrentTokenPosition(): import(\"ace-code\").Ace.Point;\n        /**\n         * Return the current token range.\n         */\n        getCurrentTokenRange(): Range;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/keyboard/gutter_handler\" {\n    export class GutterKeyboardHandler {\n        constructor(editor: any);\n        editor: any;\n        gutterLayer: any;\n        element: any;\n        lines: any;\n        activeRowIndex: any;\n        activeLane: string;\n        annotationTooltip: any;\n        addListener(): void;\n        removeListener(): void;\n        lane: any;\n    }\n    export class GutterKeyboardEvent {\n        constructor(domEvent: any, gutterKeyboardHandler: any);\n        gutterKeyboardHandler: any;\n        domEvent: any;\n        /**\n         * Returns the key that was presssed.\n         *\n         * @return {string} the key that was pressed.\n         */\n        getKey(): string;\n        /**\n         * Returns the row in the gutter that was focused after the keyboard event was handled.\n         *\n         * @return {number} the key that was pressed.\n         */\n        getRow(): number;\n        /**\n         * Returns whether focus is on the annotation lane after the keyboard event was handled.\n         *\n         * @return {boolean} true if focus was on the annotation lane after the keyboard event.\n         */\n        isInAnnotationLane(): boolean;\n        /**\n         * Returns whether focus is on the fold lane after the keyboard event was handled.\n         *\n         * @return {boolean} true if focus was on the fold lane after the keyboard event.\n         */\n        isInFoldLane(): boolean;\n    }\n}\ndeclare module \"ace-code/src/editor\" {\n    /**\n     * The main entry point into the Ace functionality.\n     *\n     * The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.\n     *\n     * Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.\n     **/\n    export class Editor {\n        /**\n         * Creates a new `Editor` object.\n         *\n         * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything\n         * @param {EditSession} [session] The `EditSession` to refer to\n         * @param {Partial<import(\"ace-code\").Ace.EditorOptions>} [options] The default options\n         **/\n        constructor(renderer: VirtualRenderer, session?: EditSession, options?: Partial<import(\"ace-code\").Ace.EditorOptions>);\n        id: string;\n        session: EditSession;\n        container: HTMLElement & {\n            env?: any;\n            value?: any;\n        };\n        renderer: VirtualRenderer;\n        commands: CommandManager;\n        textInput: TextInput;\n        keyBinding: KeyBinding;\n        startOperation(commandEvent: any): void;\n        /**\n         * @arg e\n         */\n        endOperation(e: any): void;\n        onStartOperation(commandEvent: any): void;\n        curOp: {};\n        prevOp: {};\n        previousCommand: any;\n        /**\n         * @arg e\n         */\n        onEndOperation(e: any): void;\n        mergeNextCommand: boolean;\n        sequenceStartTime: number;\n        /**\n         * Sets a new key handler, such as \"vim\" or \"windows\".\n         * @param {String | import(\"ace-code\").Ace.KeyboardHandler | null} keyboardHandler The new key handler\n         **/\n        setKeyboardHandler(keyboardHandler: string | import(\"ace-code\").Ace.KeyboardHandler | null, cb?: () => void): void;\n        /**\n         * Returns the keyboard handler, such as \"vim\" or \"windows\".\n         **/\n        getKeyboardHandler(): any;\n        /**\n         * Sets a new editsession to use. This method also emits the `'changeSession'` event.\n         * @param {EditSession|null} [session] The new session to use\n         **/\n        setSession(session?: EditSession | null): void;\n        selection: import(\"ace-code/src/selection\").Selection;\n        /**\n         * Returns the current session being used.\n         **/\n        getSession(): EditSession;\n        /**\n         * Sets the current document to `val`.\n         * @param {String} val The new value to set for the document\n         * @param {Number} [cursorPos] Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end\n         *\n         * @returns {String} The current document value\n         * @related Document.setValue\n         **/\n        setValue(val: string, cursorPos?: number): string;\n        /**\n         * Returns the current session's content.\n         *\n         * @related EditSession.getValue\n         **/\n        getValue(): string;\n        /**\n         *\n         * Returns the currently highlighted selection.\n         * @returns {Selection} The selection object\n         **/\n        getSelection(): Selection;\n        /**\n         * {:VirtualRenderer.onResize}\n         * @param {Boolean} [force] If `true`, recomputes the size, even if the height and width haven't changed\n         * @related VirtualRenderer.onResize\n         **/\n        resize(force?: boolean): void;\n        /**\n         * {:VirtualRenderer.setTheme}\n         * @param {string | import(\"ace-code\").Ace.Theme} theme The path to a theme\n         * @param {() => void} [cb] optional callback called when theme is loaded\n         **/\n        setTheme(theme: string | import(\"ace-code\").Ace.Theme, cb?: () => void): void;\n        /**\n         * {:VirtualRenderer.getTheme}\n         *\n         * @returns {String} The set theme\n         * @related VirtualRenderer.getTheme\n         **/\n        getTheme(): string;\n        /**\n         * {:VirtualRenderer.setStyle}\n         * @param {String} style A class name\n         * @param {boolean} [incluude] pass false to remove the class name\n         * @related VirtualRenderer.setStyle\n         **/\n        setStyle(style: string, incluude?: boolean): void;\n        /**\n         * {:VirtualRenderer.unsetStyle}\n         * @related VirtualRenderer.unsetStyle\n         */\n        unsetStyle(style: string): void;\n        /**\n         * Gets the current font size of the editor text.\n         */\n        getFontSize(): string | number;\n        /**\n         * Set a new font size (in pixels) for the editor text.\n         * @param {String | number} size A font size ( _e.g._ \"12px\")\n         **/\n        setFontSize(size: string | number): void;\n        /**\n         *\n         * Brings the current `textInput` into focus.\n         **/\n        focus(): void;\n        /**\n         * Returns `true` if the current `textInput` is in focus.\n         **/\n        isFocused(): boolean;\n        /**\n         *\n         * Blurs the current `textInput`.\n         **/\n        blur(): void;\n        /**\n         * Returns the string of text currently highlighted.\n         **/\n        getCopyText(): string;\n        execCommand(command: string | string[] | import(\"ace-code\").Ace.Command, args?: any): boolean;\n        /**\n         * Inserts `text` into wherever the cursor is pointing.\n         * @param {String} text The new text to add\n         **/\n        insert(text: string, pasted?: boolean): void;\n        autoIndent(): void;\n        applyComposition(text?: string, composition?: any): void;\n        /**\n         * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n         * @param {Boolean} overwrite Defines whether or not to set overwrites\n         * @related EditSession.setOverwrite\n         **/\n        setOverwrite(overwrite: boolean): void;\n        /**\n         * Returns `true` if overwrites are enabled; `false` otherwise.\n         * @related EditSession.getOverwrite\n         **/\n        getOverwrite(): boolean;\n        /**\n         * Sets the value of overwrite to the opposite of whatever it currently is.\n         * @related EditSession.toggleOverwrite\n         **/\n        toggleOverwrite(): void;\n        /**\n         * Sets how fast the mouse scrolling should do.\n         * @param {Number} speed A value indicating the new speed (in milliseconds)\n         **/\n        setScrollSpeed(speed: number): void;\n        /**\n         * Returns the value indicating how fast the mouse scroll speed is (in milliseconds).\n         **/\n        getScrollSpeed(): number;\n        /**\n         * Sets the delay (in milliseconds) of the mouse drag.\n         * @param {Number} dragDelay A value indicating the new delay\n         **/\n        setDragDelay(dragDelay: number): void;\n        /**\n         * Returns the current mouse drag delay.\n         **/\n        getDragDelay(): number;\n        /**\n         * Draw selection markers spanning whole line, or only over selected text. Default value is \"line\"\n         * @param {\"fullLine\" | \"screenLine\" | \"text\" | \"line\"} val The new selection style \"line\"|\"text\"\n         **/\n        setSelectionStyle(val: \"fullLine\" | \"screenLine\" | \"text\" | \"line\"): void;\n        /**\n         * Returns the current selection style.\n         **/\n        getSelectionStyle(): import(\"ace-code\").Ace.EditorOptions[\"selectionStyle\"];\n        /**\n         * Determines whether or not the current line should be highlighted.\n         * @param {Boolean} shouldHighlight Set to `true` to highlight the current line\n         **/\n        setHighlightActiveLine(shouldHighlight: boolean): void;\n        /**\n         * Returns `true` if current lines are always highlighted.\n         **/\n        getHighlightActiveLine(): boolean;\n        setHighlightGutterLine(shouldHighlight: boolean): void;\n        getHighlightGutterLine(): boolean;\n        /**\n         * Determines if the currently selected word should be highlighted.\n         * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word\n         **/\n        setHighlightSelectedWord(shouldHighlight: boolean): void;\n        /**\n         * Returns `true` if currently highlighted words are to be highlighted.\n         **/\n        getHighlightSelectedWord(): boolean;\n        setAnimatedScroll(shouldAnimate: boolean): void;\n        getAnimatedScroll(): boolean;\n        /**\n         * If `showInvisibles` is set to `true`, invisible characters&mdash;like spaces or new lines&mdash;are show in the editor.\n         * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters\n         **/\n        setShowInvisibles(showInvisibles: boolean): void;\n        /**\n         * Returns `true` if invisible characters are being shown.\n         **/\n        getShowInvisibles(): boolean;\n        setDisplayIndentGuides(display: boolean): void;\n        getDisplayIndentGuides(): boolean;\n        setHighlightIndentGuides(highlight: boolean): void;\n        getHighlightIndentGuides(): boolean;\n        /**\n         * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.\n         * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin\n         *\n         **/\n        setShowPrintMargin(showPrintMargin: boolean): void;\n        /**\n         * Returns `true` if the print margin is being shown.\n         **/\n        getShowPrintMargin(): boolean;\n        /**\n         * Sets the column defining where the print margin should be.\n         * @param {Number} showPrintMargin Specifies the new print margin\n         *\n         **/\n        setPrintMarginColumn(showPrintMargin: number): void;\n        /**\n         * Returns the column number of where the print margin is.\n         **/\n        getPrintMarginColumn(): number;\n        /**\n         * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.\n         * @param {Boolean} readOnly Specifies whether the editor can be modified or not\n         **/\n        setReadOnly(readOnly: boolean): void;\n        /**\n         * Returns `true` if the editor is set to read-only mode.\n         **/\n        getReadOnly(): boolean;\n        /**\n         * Specifies whether to use behaviors or not. [\"Behaviors\" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}\n         * @param {Boolean} enabled Enables or disables behaviors\n         **/\n        setBehavioursEnabled(enabled: boolean): void;\n        /**\n         * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}\n         **/\n        getBehavioursEnabled(): boolean;\n        /**\n         * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets\n         * when such a character is typed in.\n         * @param {Boolean} enabled Enables or disables wrapping behaviors\n         **/\n        setWrapBehavioursEnabled(enabled: boolean): void;\n        /**\n         * Returns `true` if the wrapping behaviors are currently enabled.\n         **/\n        getWrapBehavioursEnabled(): boolean;\n        /**\n         * Indicates whether the fold widgets should be shown or not.\n         * @param {Boolean} show Specifies whether the fold widgets are shown\n         **/\n        setShowFoldWidgets(show: boolean): void;\n        /**\n         * Returns `true` if the fold widgets are shown.\n         **/\n        getShowFoldWidgets(): boolean;\n        setFadeFoldWidgets(fade: boolean): void;\n        getFadeFoldWidgets(): boolean;\n        /**\n         * Removes the current selection or one character.\n         * @param {'left' | 'right'} [dir] The direction of the deletion to occur, either \"left\" or \"right\"\n         **/\n        remove(dir?: \"left\" | \"right\"): void;\n        /**\n         * Removes the word directly to the right of the current selection.\n         **/\n        removeWordRight(): void;\n        /**\n         * Removes the word directly to the left of the current selection.\n         **/\n        removeWordLeft(): void;\n        /**\n         * Removes all the words to the left of the current selection, until the start of the line.\n         **/\n        removeToLineStart(): void;\n        /**\n         * Removes all the words to the right of the current selection, until the end of the line.\n         **/\n        removeToLineEnd(): void;\n        /**\n         * Splits the line at the current selection (by inserting an `'\\n'`).\n         **/\n        splitLine(): void;\n        /**\n         * Set the \"ghost\" text in provided position. \"Ghost\" text is a kind of\n         * preview text inside the editor which can be used to preview some code\n         * inline in the editor such as, for example, code completions.\n         *\n         * @param {String} text Text to be inserted as \"ghost\" text\n         * @param {Point} [position] Position to insert text to\n         */\n        setGhostText(text: string, position?: Point): void;\n        /**\n         * Removes \"ghost\" text currently displayed in the editor.\n         */\n        removeGhostText(): void;\n        /**\n         * Transposes current line.\n         **/\n        transposeLetters(): void;\n        /**\n         * Converts the current selection entirely into lowercase.\n         **/\n        toLowerCase(): void;\n        /**\n         * Converts the current selection entirely into uppercase.\n         **/\n        toUpperCase(): void;\n        /**\n         * Inserts an indentation into the current cursor position or indents the selected lines.\n         *\n         * @related EditSession.indentRows\n         **/\n        indent(): void;\n        /**\n         * Indents the current line.\n         * @related EditSession.indentRows\n         **/\n        blockIndent(): void;\n        /**\n         * Outdents the current line.\n         * @related EditSession.outdentRows\n         **/\n        blockOutdent(): void;\n        sortLines(): void;\n        /**\n         * Given the currently selected range, this function either comments all the lines, or uncomments all of them.\n         **/\n        toggleCommentLines(): void;\n        toggleBlockComment(): void;\n        /**\n         * Works like [[EditSession.getTokenAt]], except it returns a number.\n         **/\n        getNumberAt(row: any, column: any): any;\n        /**\n         * If the character before the cursor is a number, this functions changes its value by `amount`.\n         * @param {Number} amount The value to change the numeral by (can be negative to decrease value)\n         **/\n        modifyNumber(amount: number): void;\n        toggleWord(): void;\n        /**\n         * Finds link at defined {row} and {column}\n         **/\n        findLinkAt(row: any, column: any): string;\n        /**\n         * Open valid url under cursor in another tab\n         **/\n        openLink(): boolean;\n        /**\n         * Removes all the lines in the current selection\n         * @related EditSession.remove\n         **/\n        removeLines(): void;\n        duplicateSelection(): void;\n        /**\n         * Shifts all the selected lines down one row.\n         *\n         * @related EditSession.moveLinesUp\n         **/\n        moveLinesDown(): void;\n        /**\n         * Shifts all the selected lines up one row.\n         * @related EditSession.moveLinesDown\n         **/\n        moveLinesUp(): void;\n        /**\n         * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n         * ```json\n         *    { row: newRowLocation, column: newColumnLocation }\n         * ```\n         * @param {Range} range The range of text you want moved within the document\n         * @param {Point} toPosition The location (row and column) where you want to move the text to\n         *\n         * @returns {Range} The new range where the text was moved to.\n         * @related EditSession.moveText\n         **/\n        moveText(range: Range, toPosition: Point, copy?: boolean): Range;\n        /**\n         * Copies all the selected lines up one row.\n         *\n         **/\n        copyLinesUp(): void;\n        /**\n         * Copies all the selected lines down one row.\n         * @related EditSession.duplicateLines\n         *\n         **/\n        copyLinesDown(): void;\n        inVirtualSelectionMode: boolean;\n        /**\n         * {:VirtualRenderer.getFirstVisibleRow}\n         *\n         * @related VirtualRenderer.getFirstVisibleRow\n         **/\n        getFirstVisibleRow(): number;\n        /**\n         * {:VirtualRenderer.getLastVisibleRow}\n         *\n         * @related VirtualRenderer.getLastVisibleRow\n         **/\n        getLastVisibleRow(): number;\n        /**\n         * Indicates if the row is currently visible on the screen.\n         * @param {Number} row The row to check\n         *\n         **/\n        isRowVisible(row: number): boolean;\n        /**\n         * Indicates if the entire row is currently visible on the screen.\n         * @param {Number} row The row to check\n         *\n         *\n         **/\n        isRowFullyVisible(row: number): boolean;\n        /**\n         * Selects the text from the current position of the document until where a \"page down\" finishes.\n         **/\n        selectPageDown(): void;\n        /**\n         * Selects the text from the current position of the document until where a \"page up\" finishes.\n         **/\n        selectPageUp(): void;\n        /**\n         * Shifts the document to wherever \"page down\" is, as well as moving the cursor position.\n         **/\n        gotoPageDown(): void;\n        /**\n         * Shifts the document to wherever \"page up\" is, as well as moving the cursor position.\n         **/\n        gotoPageUp(): void;\n        /**\n         * Scrolls the document to wherever \"page down\" is, without changing the cursor position.\n         **/\n        scrollPageDown(): void;\n        /**\n         * Scrolls the document to wherever \"page up\" is, without changing the cursor position.\n         **/\n        scrollPageUp(): void;\n        /**\n         * Moves the editor to the specified row.\n         * @related VirtualRenderer.scrollToRow\n         */\n        scrollToRow(row: number): void;\n        /**\n         * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).\n         * @param {Number} line The line to scroll to\n         * @param {Boolean} center If `true`\n         * @param {Boolean} animate If `true` animates scrolling\n         * @param {() => void} [callback] Function to be called when the animation has finished\n         *\n         * @related VirtualRenderer.scrollToLine\n         **/\n        scrollToLine(line: number, center: boolean, animate: boolean, callback?: () => void): void;\n        /**\n         * Attempts to center the current selection on the screen.\n         **/\n        centerSelection(): void;\n        /**\n         * Gets the current position of the cursor.\n         * @returns {Point} An object that looks something like this:\n         *\n         * ```json\n         * { row: currRow, column: currCol }\n         * ```\n         *\n         * @related Selection.getCursor\n         **/\n        getCursorPosition(): Point;\n        /**\n         * Returns the screen position of the cursor.\n         * @related EditSession.documentToScreenPosition\n         **/\n        getCursorPositionScreen(): Point;\n        /**\n         * {:Selection.getRange}\n         * @related Selection.getRange\n         **/\n        getSelectionRange(): Range;\n        /**\n         * Selects all the text in editor.\n         * @related Selection.selectAll\n         **/\n        selectAll(): void;\n        /**\n         * {:Selection.clearSelection}\n         * @related Selection.clearSelection\n         **/\n        clearSelection(): void;\n        /**\n         * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.\n         * @param {Number} row The new row number\n         * @param {Number} column The new column number\n         * @related Selection.moveCursorTo\n         **/\n        moveCursorTo(row: number, column: number): void;\n        /**\n         * Moves the cursor to the position indicated by `pos.row` and `pos.column`.\n         * @param {Point} pos An object with two properties, row and column\n         * @related Selection.moveCursorToPosition\n         **/\n        moveCursorToPosition(pos: Point): void;\n        /**\n         * Moves the cursor's row and column to the next matching bracket or HTML tag.\n         */\n        jumpToMatching(select?: boolean, expand?: boolean): void;\n        /**\n         * Moves the cursor to the specified line number, and also into the indicated column.\n         * @param {Number} lineNumber The line number to go to\n         * @param {Number} [column] A column number to go to\n         * @param {Boolean} [animate] If `true` animates scolling\n         **/\n        gotoLine(lineNumber: number, column?: number, animate?: boolean): void;\n        /**\n         * Moves the cursor to the specified row and column. Note that this does de-select the current selection.\n         * @param {Number} row The new row number\n         * @param {Number} column The new column number\n         *\n         * @related Editor.moveCursorTo\n         **/\n        navigateTo(row: number, column: number): void;\n        /**\n         * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.\n         * @param {Number} [times] The number of times to change navigation\n         *\n         **/\n        navigateUp(times?: number): void;\n        /**\n         * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.\n         * @param {Number} [times] The number of times to change navigation\n         *\n         **/\n        navigateDown(times?: number): void;\n        /**\n         * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.\n         * @param {Number} [times] The number of times to change navigation\n         *\n         **/\n        navigateLeft(times?: number): void;\n        /**\n         * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.\n         * @param {Number} [times] The number of times to change navigation\n         *\n         **/\n        navigateRight(times?: number): void;\n        /**\n         *\n         * Moves the cursor to the start of the current line. Note that this does de-select the current selection.\n         **/\n        navigateLineStart(): void;\n        /**\n         *\n         * Moves the cursor to the end of the current line. Note that this does de-select the current selection.\n         **/\n        navigateLineEnd(): void;\n        /**\n         *\n         * Moves the cursor to the end of the current file. Note that this does de-select the current selection.\n         **/\n        navigateFileEnd(): void;\n        /**\n         *\n         * Moves the cursor to the start of the current file. Note that this does de-select the current selection.\n         **/\n        navigateFileStart(): void;\n        /**\n         *\n         * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.\n         **/\n        navigateWordRight(): void;\n        /**\n         *\n         * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.\n         **/\n        navigateWordLeft(): void;\n        /**\n         * Replaces the first occurrence of `options.needle` with the value in `replacement`.\n         * @param {String} [replacement] The text to replace with\n         * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n         **/\n        replace(replacement?: string, options?: Partial<SearchOptions>): number;\n        /**\n         * Replaces all occurrences of `options.needle` with the value in `replacement`.\n         * @param {String} [replacement] The text to replace with\n         * @param {Partial<SearchOptions>} [options] The [[Search `Search`]] options to use\n         **/\n        replaceAll(replacement?: string, options?: Partial<SearchOptions>): number;\n        /**\n         * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].\n         * @related Search.getOptions\n         **/\n        getLastSearchOptions(): Partial<SearchOptions>;\n        /**\n         * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].\n         * @param {String|RegExp|Object} needle The text to search for (optional)\n         * @param {Partial<SearchOptions>} [options] An object defining various search properties\n         * @param {Boolean} [animate] If `true` animate scrolling\n         * @related Search.find\n         **/\n        find(needle: string | RegExp | any, options?: Partial<SearchOptions>, animate?: boolean): false | Range;\n        /**\n         * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].\n         * @param {Partial<SearchOptions>} [options] search options\n         * @param {Boolean} [animate] If `true` animate scrolling\n         *\n         * @related Editor.find\n         **/\n        findNext(options?: Partial<SearchOptions>, animate?: boolean): void;\n        /**\n         * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].\n         * @param {Partial<SearchOptions>} [options] search options\n         * @param {Boolean} [animate] If `true` animate scrolling\n         *\n         * @related Editor.find\n         **/\n        findPrevious(options?: Partial<SearchOptions>, animate?: boolean): void;\n        revealRange(range: Range, animate?: boolean): void;\n        /**\n         * {:UndoManager.undo}\n         * @related UndoManager.undo\n         **/\n        undo(): void;\n        /**\n         * {:UndoManager.redo}\n         * @related UndoManager.redo\n         **/\n        redo(): void;\n        /**\n         *\n         * Cleans up the entire editor.\n         **/\n        destroy(): void;\n        /** true if editor is destroyed */\n        destroyed: boolean;\n        /**\n         * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element\n         * @param {Boolean} enable default true\n         **/\n        setAutoScrollEditorIntoView(enable: boolean): void;\n        /**\n         * opens a prompt displaying message\n         **/\n        prompt(message: any, options: any, callback: any): void;\n        set hoverTooltip(value: any);\n        get hoverTooltip(): any;\n        env?: any;\n        widgetManager?: import(\"ace-code\").Ace.LineWidgets;\n        completer?: import(\"ace-code\").Ace.Autocomplete | import(\"ace-code\").Ace.InlineAutocomplete;\n        completers: import(\"ace-code\").Ace.Completer[];\n        showKeyboardShortcuts?: () => void;\n        showSettingsMenu?: () => void;\n        searchBox?: import(\"ace-code\").Ace.SearchBox;\n    }\n    export namespace Editor {\n        export { $uid };\n    }\n    export type VirtualRenderer = import(\"ace-code/src/virtual_renderer\").VirtualRenderer;\n    export type Selection = import(\"ace-code/src/selection\").Selection;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type SearchOptions = import(\"ace-code\").Ace.SearchOptions;\n    import { EditSession } from \"ace-code/src/edit_session\";\n    import { CommandManager } from \"ace-code/src/commands/command_manager\";\n    import { TextInput } from \"ace-code/src/keyboard/textinput\";\n    import { MouseHandler } from \"ace-code/src/mouse/mouse_handler\";\n    import { KeyBinding } from \"ace-code/src/keyboard/keybinding\";\n    import { Search } from \"ace-code/src/search\";\n    import { Range } from \"ace-code/src/range\";\n    var $uid: number;\n    namespace Ace {\n        type EditorMultiSelectProperties = import(\"ace-code\").Ace.EditorMultiSelectProperties;\n        type OptionsProvider<T> = import(\"ace-code\").Ace.OptionsProvider<T>;\n        type EditorOptions = import(\"ace-code\").Ace.EditorOptions;\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type EditorEvents = import(\"ace-code\").Ace.EditorEvents;\n        type CodeLenseEditorExtension = import(\"ace-code\").Ace.CodeLenseEditorExtension;\n        type ElasticTabstopsEditorExtension = import(\"ace-code\").Ace.ElasticTabstopsEditorExtension;\n        type TextareaEditorExtension = import(\"ace-code\").Ace.TextareaEditorExtension;\n        type PromptEditorExtension = import(\"ace-code\").Ace.PromptEditorExtension;\n        type OptionsEditorExtension = import(\"ace-code\").Ace.OptionsEditorExtension;\n        type EditSession = import(\"ace-code\").Ace.EditSession;\n        type LineWidgets = import(\"ace-code\").Ace.LineWidgets;\n        type Autocomplete = import(\"ace-code\").Ace.Autocomplete;\n        type InlineAutocomplete = import(\"ace-code\").Ace.InlineAutocomplete;\n        type Completer = import(\"ace-code\").Ace.Completer;\n        type SearchBox = import(\"ace-code\").Ace.SearchBox;\n    }\n    export interface Editor extends Ace.EditorMultiSelectProperties /**\n     * @overload\n     */, /**\n     * @overload\n     */ Ace\n            .OptionsProvider<Ace.EditorOptions>, Ace.\n                EventEmitter<Ace.EditorEvents>, Ace.CodeLenseEditorExtension, Ace.ElasticTabstopsEditorExtension, Ace.TextareaEditorExtension, Ace.PromptEditorExtension, Ace.OptionsEditorExtension {\n        session: Ace.EditSession;\n        env?: any;\n        widgetManager?: Ace.LineWidgets;\n        completer?: Ace.Autocomplete | Ace.InlineAutocomplete;\n        completers: Ace.Completer[];\n        showKeyboardShortcuts?: () => void;\n        showSettingsMenu?: () => void;\n        searchBox?: Ace.SearchBox;\n    }\n}\ndeclare module \"ace-code/src/undomanager\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Delta = import(\"ace-code\").Ace.Delta;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type IRange = import(\"ace-code\").Ace.IRange;\n    /**\n     * This object maintains the undo stack for an [[EditSession `EditSession`]].\n     **/\n    export class UndoManager {\n        addSession(session: EditSession): void;\n        /**\n         * Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements:\n         *\n         * - `args[0]` is an array of deltas\n         * - `args[1]` is the document to associate with\n         *\n         **/\n        add(delta: import(\"ace-code\").Ace.Delta, allowMerge: boolean, session?: EditSession): void;\n        lastDeltas: any[];\n        addSelection(selection: any, rev?: number): void;\n        startNewGroup(): any;\n        markIgnored(from: number, to?: number): void;\n        getSelection(rev: number, after?: boolean): {\n            value: string;\n            rev: number;\n        };\n        getRevision(): number;\n        getDeltas(from: number, to?: number): import(\"ace-code\").Ace.Delta[];\n        getChangedRanges(from: number, to?: number): void;\n        getChangedLines(from: number, to?: number): void;\n        /**\n         * [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo}\n         **/\n        undo(session: EditSession, dontSelect?: boolean): void;\n        /**\n         * [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo}\n         *\n         **/\n        redo(session: EditSession, dontSelect?: boolean): void;\n        /**\n         * Destroys the stack of undo and redo redo operations.\n         **/\n        reset(): void;\n        mark: number;\n        selections: any[];\n        /**\n         * Returns `true` if there are undo operations left to perform.\n         **/\n        canUndo(): boolean;\n        /**\n         * Returns `true` if there are redo operations left to perform.\n         **/\n        canRedo(): boolean;\n        /**\n         * Marks the current status clean\n         */\n        bookmark(rev?: number): void;\n        /**\n         * Returns if the current status is clean\n         **/\n        isAtBookmark(): boolean;\n        /**\n         * Returns an object which can be safely stringified into JSON\n         */\n        toJSON(): object;\n        /**\n         * Takes in an object which was returned from the toJSON method above,\n         * and resets the current undoManager instance to use the previously exported\n         * instance state.\n         */\n        fromJSON(json: object): void;\n        hasUndo: () => boolean;\n        hasRedo: () => boolean;\n        isClean: () => boolean;\n        markClean: (rev?: number) => void;\n    }\n}\ndeclare module \"ace-code/src/tokenizer\" {\n    /**\n     * This class takes a set of highlighting rules, and creates a tokenizer out of them. For more information, see [the wiki on extending highlighters](https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-extendingTheHighlighter).\n     **/\n    export class Tokenizer {\n        /**\n         * Constructs a new tokenizer based on the given rules and flags.\n         * @param {Object} rules The highlighting rules\n         **/\n        constructor(rules: any);\n        splitRegex: RegExp;\n        states: any;\n        regExps: {};\n        matchMappings: {};\n        removeCapturingGroups(src: string): string;\n        createSplitterRegexp(src: string, flag: string): RegExp;\n        /**\n         * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.\n         */\n        getLineTokens(line: string, startState: string | string[]): {\n            tokens: import(\"ace-code\").Ace.Token[];\n            state: string | string[];\n        };\n        reportError: (msg: any, data: any) => void;\n    }\n}\ndeclare module \"ace-code/src/autocomplete/popup\" {\n    /**\n     * This object is used in some places where needed to show popups - like prompt; autocomplete etc.\n     */\n    export class AcePopup {\n        /**\n         * Creates and renders single line editor in popup window. If `parentNode` param is isset, then attaching it to this element.\n         */\n        constructor(parentNode?: Element);\n        setSelectOnHover: (val: boolean) => void;\n        setRow: (line: number) => void;\n        getRow: () => number;\n        getHoveredRow: () => number;\n        filterText: string;\n        isOpen: boolean;\n        isTopdown: boolean;\n        autoSelect: boolean;\n        data: import(\"ace-code\").Ace.Completion[];\n        setData: (data: import(\"ace-code\").Ace.Completion[], filterText?: string) => void;\n        getData: (row: number) => import(\"ace-code\").Ace.Completion;\n        hide: () => void;\n        anchor: \"top\" | \"bottom\";\n        anchorPosition: import(\"ace-code\").Ace.Point;\n        tryShow: (pos: any, lineHeight: number, anchor: \"top\" | \"bottom\", forceShow?: boolean) => boolean;\n        show: (pos: any, lineHeight: number, topdownOnly?: boolean) => void;\n        goTo: (where: import(\"ace-code\").Ace.AcePopupNavigation) => void;\n        getTextLeftOffset: () => number;\n        anchorPos: any;\n        isMouseOver?: boolean;\n        selectedNode?: HTMLElement;\n    }\n    export function $singleLineEditor(el?: HTMLElement): Editor;\n    export function getAriaId(index: any): string;\n    import { Editor } from \"ace-code/src/editor\";\n    namespace Ace {\n        type AcePopupWithEditor = import(\"ace-code\").Ace.AcePopupWithEditor;\n        type Completion = import(\"ace-code\").Ace.Completion;\n        type Point = import(\"ace-code\").Ace.Point;\n        type AcePopupNavigation = import(\"ace-code\").Ace.AcePopupNavigation;\n    }\n    export interface AcePopup extends Ace.AcePopupWithEditor {\n        setSelectOnHover: (val: boolean) => void;\n        setRow: (line: number) => void;\n        getRow: () => number;\n        getHoveredRow: () => number;\n        filterText: string;\n        isOpen: boolean;\n        isTopdown: boolean;\n        autoSelect: boolean;\n        data: Ace.Completion[];\n        setData: (data: Ace.Completion[], filterText?: string) => void;\n        getData: (row: number) => Ace.Completion;\n        hide: () => void;\n        anchor: \"top\" | \"bottom\";\n        anchorPosition: Ace.Point;\n        tryShow: (pos: any, lineHeight: number,\n            /**\n             * @overload\n             */\n            anchor: \"top\" | \"bottom\", forceShow?: boolean) => boolean;\n        show: (pos: any, lineHeight: number, topdownOnly?: boolean) => void;\n        goTo: (where: Ace.AcePopupNavigation) => void;\n        getTextLeftOffset: () => number;\n        anchorPos: any;\n        isMouseOver?: boolean;\n        selectedNode?: HTMLElement;\n    }\n}\ndeclare module \"ace-code/src/range_list\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export class RangeList {\n        ranges: any[];\n        pointIndex(pos: Point, excludeEdges?: boolean, startIndex?: number): number;\n        add(range: Range): any[];\n        addList(list: Range[]): any[];\n        substractPoint(pos: Point): any[];\n        merge(): any[];\n        contains(row: number, column: number): boolean;\n        containsPoint(pos: Point): boolean;\n        rangeAtPoint(pos: Point): any;\n        clipRows(startRow: number, endRow: number): any[];\n        removeAll(): any[];\n        attach(session: EditSession): void;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        onChange: any;\n        detach(): void;\n        comparePoints: (p1: import(\"ace-code/src/range\").Point, p2: import(\"ace-code/src/range\").Point) => number;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/snippets\" {\n    export const snippetManager: SnippetManager;\n    export type Snippet = {\n        content?: string;\n        replaceBefore?: string;\n        replaceAfter?: string;\n        startRe?: RegExp;\n        endRe?: RegExp;\n        triggerRe?: RegExp;\n        endTriggerRe?: RegExp;\n        trigger?: string;\n        endTrigger?: string;\n        matchBefore?: string[];\n        matchAfter?: string[];\n        name?: string;\n        tabTrigger?: string;\n        guard?: string;\n        endGuard?: string;\n    };\n    class SnippetManager {\n        snippetMap: {};\n        snippetNameMap: {};\n        variables: {\n            CURRENT_WORD: (editor: any) => any;\n            SELECTION: (editor: any, name: any, indentation: any) => any;\n            CURRENT_LINE: (editor: any) => any;\n            PREV_LINE: (editor: any) => any;\n            LINE_INDEX: (editor: any) => any;\n            LINE_NUMBER: (editor: any) => any;\n            SOFT_TABS: (editor: any) => \"YES\" | \"NO\";\n            TAB_SIZE: (editor: any) => any;\n            CLIPBOARD: (editor: any) => any;\n            FILENAME: (editor: any) => string;\n            FILENAME_BASE: (editor: any) => string;\n            DIRECTORY: (editor: any) => string;\n            FILEPATH: (editor: any) => string;\n            WORKSPACE_NAME: () => string;\n            FULLNAME: () => string;\n            BLOCK_COMMENT_START: (editor: any) => any;\n            BLOCK_COMMENT_END: (editor: any) => any;\n            LINE_COMMENT: (editor: any) => any;\n            CURRENT_YEAR: any;\n            CURRENT_YEAR_SHORT: any;\n            CURRENT_MONTH: any;\n            CURRENT_MONTH_NAME: any;\n            CURRENT_MONTH_NAME_SHORT: any;\n            CURRENT_DATE: any;\n            CURRENT_DAY_NAME: any;\n            CURRENT_DAY_NAME_SHORT: any;\n            CURRENT_HOUR: any;\n            CURRENT_MINUTE: any;\n            CURRENT_SECOND: any;\n        };\n        getTokenizer(): Tokenizer;\n        createTokenizer(): any;\n        tokenizeTmSnippet(str: any, startState: any): (string | import(\"ace-code\").Ace.Token)[];\n        getVariableValue(editor: any, name: any, indentation: any): any;\n        tmStrFormat(str: any, ch: any, editor: any): any;\n        tmFormatFunction(str: any, ch: any, editor: any): any;\n        resolveVariables(snippet: any, editor: any): any[];\n        getDisplayTextForSnippet(editor: any, snippetText: any): any;\n        insertSnippetForSelection(editor: any, snippetText: any, options?: {}): void;\n        insertSnippet(editor: any, snippetText: any, options?: {}): void;\n        getActiveScopes(editor: any): any[];\n        expandWithTab(editor: any, options: any): any;\n        expandSnippetForSelection(editor: any, options: any): boolean;\n        findMatchingSnippet(snippetList: Snippet[], before: string, after: string): Snippet;\n        register(snippets: any[], scope: string): void;\n        unregister(snippets: any, scope: any): void;\n        parseSnippetFile(str: any): Snippet[];\n        getSnippetByName(name: any, editor: any): undefined;\n    }\n    import { Tokenizer } from \"ace-code/src/tokenizer\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n    }\n    interface SnippetManager extends Ace.EventEmitter<any> {\n    }\n}\ndeclare module \"ace-code/src/autocomplete/inline_screenreader\" {\n    /**\n     * This object is used to communicate inline code completions rendered into an editor with ghost text to screen reader users.\n     */\n    export class AceInlineScreenReader {\n        /**\n         * Creates the off-screen div in which the ghost text content in redered and which the screen reader reads.\n         */\n        constructor(editor: import(\"ace-code/src/editor\").Editor);\n        editor: import(\"ace-code/src/editor\").Editor;\n        screenReaderDiv: HTMLDivElement;\n        /**\n         * Set the ghost text content to the screen reader div\n         */\n        setScreenReaderContent(content: string): void;\n        popup: import(\"ace-code/src/autocomplete/popup\").AcePopup;\n        destroy(): void;\n        /**\n         * Take this._lines, render it as <code> blocks and add those to the screen reader div.\n         */\n        createCodeBlock(): HTMLPreElement;\n    }\n}\ndeclare module \"ace-code/src/autocomplete/inline\" {\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    /**\n     * This object is used to manage inline code completions rendered into an editor with ghost text.\n     */\n    export class AceInline {\n        editor: any;\n        /**\n         * Renders the completion as ghost text to the current cursor position\n         * @returns {boolean} True if the completion could be rendered to the editor, false otherwise\n         */\n        show(editor: Editor, completion: import(\"ace-code\").Ace.Completion, prefix: string): boolean;\n        inlineScreenReader: AceInlineScreenReader;\n        isOpen(): boolean;\n        hide(): boolean;\n        destroy(): void;\n    }\n    import { AceInlineScreenReader } from \"ace-code/src/autocomplete/inline_screenreader\";\n}\ndeclare module \"ace-code/src/autocomplete/util\" {\n    export function parForEach(array: any, fn: any, callback: any): void;\n    export function retrievePrecedingIdentifier(text: any, pos: any, regex: any): string;\n    export function retrieveFollowingIdentifier(text: any, pos: any, regex: any): any[];\n    export function getCompletionPrefix(editor: any): string;\n    export function triggerAutocomplete(editor: Editor, previousChar?: string): boolean;\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n}\ndeclare module \"ace-code/src/autocomplete\" {\n    /**\n     * This object controls the autocompletion components and their lifecycle.\n     * There is an autocompletion popup, an optional inline ghost text renderer and a docuent tooltip popup inside.\n     */\n    export class Autocomplete {\n        static get completionsForLoading(): {\n            caption: any;\n            value: string;\n        }[];\n        static for(editor: Editor): Autocomplete;\n        autoInsert: boolean;\n        autoSelect: boolean;\n        autoShown: boolean;\n        exactMatch: boolean;\n        inlineEnabled: boolean;\n        keyboardHandler: HashHandler;\n        parentNode: any;\n        setSelectOnHover: boolean;\n        /**\n         *  @property {Boolean} showLoadingState - A boolean indicating whether the loading states of the Autocompletion should be shown to the end-user. If enabled\n         * it shows a loading indicator on the popup while autocomplete is loading.\n         *\n         * Experimental: This visualisation is not yet considered stable and might change in the future.\n         */\n        showLoadingState: boolean;\n        /**\n         *  @property {number} stickySelectionDelay - a numerical value that determines after how many ms the popup selection will become 'sticky'.\n         *  Normally, when new elements are added to an open popup, the selection is reset to the first row of the popup. If sticky, the focus will remain\n         *  on the currently selected item when new items are added to the popup. Set to a negative value to disable this feature and never set selection to sticky.\n         */\n        stickySelectionDelay: number;\n        blurListener(e: any): void;\n        changeListener(e: any): void;\n        mousedownListener(e: any): void;\n        mousewheelListener(e: any): void;\n        changeTimer: {\n            (timeout?: number): void;\n            delay(timeout?: number): void;\n            schedule: any;\n            call(): void;\n            cancel(): void;\n            isPending(): any;\n        };\n        tooltipTimer: {\n            (timeout?: number): void;\n            delay(timeout?: number): void;\n            schedule: any;\n            call(): void;\n            cancel(): void;\n            isPending(): any;\n        };\n        popupTimer: {\n            (timeout?: number): void;\n            delay(timeout?: number): void;\n            schedule: any;\n            call(): void;\n            cancel(): void;\n            isPending(): any;\n        };\n        stickySelectionTimer: {\n            (timeout?: number): void;\n            delay(timeout?: number): void;\n            schedule: any;\n            call(): void;\n            cancel(): void;\n            isPending(): any;\n        };\n        popup: AcePopup;\n        inlineRenderer: AceInline;\n        getPopup(): AcePopup;\n        stickySelection: boolean;\n        observeLayoutChanges(): void;\n        unObserveLayoutChanges(): void;\n        openPopup(editor: Editor, prefix: string, keepPopupPosition?: boolean): void;\n        /**\n         * Detaches all elements from the editor, and cleans up the data for the session\n         */\n        detach(): void;\n        activated: boolean;\n        completionProvider: CompletionProvider;\n        completions: FilteredList;\n        base: import(\"ace-code/src/anchor\").Anchor;\n        mouseOutListener(e: any): void;\n        goTo(where: any): void;\n        insertMatch(data: Completion, options?: undefined): boolean | void;\n        /**\n         * This is the entry point for the autocompletion class, triggers the actions which collect and display suggestions\n         */\n        showPopup(editor: Editor, options?: CompletionOptions): void;\n        editor: import(\"ace-code/src/editor\").Editor;\n        getCompletionProvider(initialPosition?: {\n            pos: Position;\n            prefix: string;\n        }): CompletionProvider;\n        /**\n         * This method is deprecated, it is only kept for backwards compatibility.\n         * Use the same method include CompletionProvider instead for the same functionality.\n         * @deprecated\n         */\n        gatherCompletions(editor: any, callback: any): boolean;\n        updateCompletions(keepPopupPosition: boolean, options?: CompletionOptions): void;\n        cancelContextMenu(): void;\n        updateDocTooltip(): void;\n        showDocTooltip(item: any): void;\n        tooltipNode: HTMLDivElement;\n        hideDocTooltip(): void;\n        destroy(): void;\n        commands: {\n            Up: (editor: any) => void;\n            Down: (editor: any) => void;\n            \"Ctrl-Up|Ctrl-Home\": (editor: any) => void;\n            \"Ctrl-Down|Ctrl-End\": (editor: any) => void;\n            Esc: (editor: any) => void;\n            Return: (editor: any) => any;\n            \"Shift-Return\": (editor: any) => void;\n            Tab: (editor: any) => any;\n            Backspace: (editor: any) => void;\n            PageUp: (editor: any) => void;\n            PageDown: (editor: any) => void;\n        };\n        emptyMessage?: Function;\n    }\n    /**\n     * This class is responsible for providing completions and inserting them to the editor\n     */\n    export class CompletionProvider {\n        constructor(initialPosition?: {\n            pos: Position;\n            prefix: string;\n        });\n        initialPosition: {\n            pos: Position;\n            prefix: string;\n        };\n        active: boolean;\n        insertByIndex(editor: Editor, index: number, options?: CompletionProviderOptions): boolean;\n        insertMatch(editor: Editor, data: Completion, options?: CompletionProviderOptions): boolean;\n        gatherCompletions(editor: Editor, callback: import(\"ace-code\").Ace.CompletionCallbackFunction): boolean;\n        completers: import(\"ace-code\").Ace.Completer[];\n        /**\n         * This is the entry point to the class, it gathers, then provides the completions asynchronously via callback.\n         * The callback function may be called multiple times, the last invokation is marked with a `finished` flag\n         */\n        provideCompletions(editor: Editor, options: CompletionProviderOptions, callback: (err: Error | undefined, completions: FilteredList | [\n        ], finished: boolean) => void): void;\n        detach(): void;\n        completions: import(\"ace-code\").Ace.FilteredList;\n    }\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type CompletionProviderOptions = import(\"ace-code\").Ace.CompletionProviderOptions;\n    export type CompletionOptions = import(\"ace-code\").Ace.CompletionOptions;\n    export type Position = import(\"ace-code\").Ace.Position;\n    export type BaseCompletion = {\n        /**\n         * - a numerical value that determines the order in which completions would be displayed.\n         * A lower score means that the completion would be displayed further from the start\n         */\n        score?: number;\n        /**\n         * - a short description of the completion\n         */\n        meta?: string;\n        /**\n         * - the text that would be displayed in the completion list. If omitted, value or snippet\n         * would be shown instead.\n         */\n        caption?: string;\n        /**\n         * - an HTML string that would be displayed as an additional popup\n         */\n        docHTML?: string;\n        /**\n         * - a plain text that would be displayed as an additional popup. If `docHTML` exists,\n         * it would be used instead of `docText`.\n         */\n        docText?: string;\n        /**\n         * - the identifier of the completer\n         */\n        completerId?: string;\n        /**\n         * - a boolean value to decide if the popup item is going to skip the filtering process done using prefix text.\n         */\n        skipFilter?: boolean;\n        /**\n         * - An object specifying the range of text to be replaced with the new completion value (experimental)\n         */\n        range?: import(\"ace-code\").Ace.IRange;\n        /**\n         * - A command to be executed after the completion is inserted (experimental)\n         */\n        command?: any;\n        /**\n         * - a text snippet that would be inserted when the completion is selected\n         */\n        snippet?: string;\n        /**\n         * - The text that would be inserted when selecting this completion.\n         */\n        value?: string;\n        completer?: import(\"ace-code\").Ace.Completer;\n        hideInlinePreview?: boolean;\n    };\n    export type SnippetCompletion = BaseCompletion & {\n        snippet: string;\n    };\n    export type ValueCompletion = BaseCompletion & {\n        value: string;\n    };\n    /**\n     * Represents a suggested text snippet intended to complete a user's input\n     */\n    export type Completion = SnippetCompletion | ValueCompletion;\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n    import { AcePopup } from \"ace-code/src/autocomplete/popup\";\n    import { AceInline } from \"ace-code/src/autocomplete/inline\";\n    export class FilteredList {\n        constructor(array: any, filterText?: string);\n        all: any;\n        filtered: any;\n        filterText: string;\n        exactMatch: boolean;\n        ignoreCaption: boolean;\n        setFilter(str: any): void;\n        filterCompletions(items: any, needle: any): any[];\n    }\n    export namespace startCommand {\n        let name: string;\n        function exec(editor: any, options: any): void;\n        let bindKey: string;\n    }\n    namespace Ace {\n        type AcePopup = import(\"ace-code\").Ace.AcePopup;\n        type FilteredList = import(\"ace-code\").Ace.FilteredList;\n    }\n    export interface Autocomplete {\n        popup: Ace.AcePopup;\n        emptyMessage?: Function;\n    }\n    export interface CompletionProvider {\n        completions: Ace.FilteredList;\n    }\n}\ndeclare module \"ace-code/src/marker_group\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type MarkerGroupItem = {\n        range: import(\"ace-code/src/range\").Range;\n        className: string;\n    };\n    export type LayerConfig = import(\"ace-code\").Ace.LayerConfig;\n    export type Marker = import(\"ace-code/src/layer/marker\").Marker;\n    export class MarkerGroup {\n        /**\n         * @param {{markerType: \"fullLine\" | \"line\" | undefined}} [options] Options controlling the behvaiour of the marker.\n         * User `markerType` to control how the markers which are part of this group will be rendered:\n         * - `undefined`: uses `text` type markers where only text characters within the range will be highlighted.\n         * - `fullLine`: will fully highlight all the rows within the range, including the characters before and after the range on the respective rows.\n         * - `line`: will fully highlight the lines within the range but will only cover the characters between the start and end of the range.\n         */\n        constructor(session: EditSession, options?: {\n            markerType: \"fullLine\" | \"line\" | undefined;\n        });\n        markerType: \"line\" | \"fullLine\";\n        markers: import(\"ace-code\").Ace.MarkerGroupItem[];\n        session: EditSession;\n        /**\n         * Finds the first marker containing pos\n         */\n        getMarkerAtPosition(pos: import(\"ace-code\").Ace.Point): import(\"ace-code\").Ace.MarkerGroupItem | undefined;\n        /**\n         * Comparator for Array.sort function, which sorts marker definitions by their positions\n         *\n         * @param {MarkerGroupItem} a first marker.\n         * @param {MarkerGroupItem} b second marker.\n         * @returns {number} negative number if a should be before b, positive number if b should be before a, 0 otherwise.\n         */\n        markersComparator(a: MarkerGroupItem, b: MarkerGroupItem): number;\n        /**\n         * Sets marker definitions to be rendered. Limits the number of markers at MAX_MARKERS.\n         * @param {MarkerGroupItem[]} markers an array of marker definitions.\n         */\n        setMarkers(markers: MarkerGroupItem[]): void;\n        update(html: any, markerLayer: Marker, session: EditSession, config: LayerConfig): void;\n        MAX_MARKERS: number;\n    }\n}\ndeclare module \"ace-code/src/autocomplete/text_completer\" {\n    export const id: \"textCompleter\";\n    export function getCompletions(editor: any, session: any, pos: any, prefix: any, callback: any): void;\n}\ndeclare module \"ace-code/src/line_widgets\" {\n    export class LineWidgets {\n        constructor(session: EditSession);\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        updateOnChange(delta: import(\"ace-code\").Ace.Delta): void;\n        renderWidgets(e: any, renderer: VirtualRenderer): void;\n        measureWidgets(e: any, renderer: VirtualRenderer): void;\n        getRowLength(row: number): number;\n        attach(editor: Editor): void;\n        editor: Editor;\n        detach(e: any): void;\n        updateOnFold(e: any, session: EditSession): void;\n        addLineWidget(w: LineWidget): LineWidget;\n        removeLineWidget(w: LineWidget): void;\n        getWidgetsAtRow(row: number): LineWidget[];\n        firstRow: number;\n        lastRow: number;\n        lineWidgets: import(\"ace-code\").Ace.LineWidget[];\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type VirtualRenderer = import(\"ace-code/src/virtual_renderer\").VirtualRenderer;\n    export type LineWidget = import(\"ace-code\").Ace.LineWidget;\n    namespace Ace {\n        type LineWidget = import(\"ace-code\").Ace.LineWidget;\n        type Editor = import(\"ace-code\").Ace.Editor;\n    }\n    export interface LineWidgets {\n        lineWidgets: Ace.LineWidget[];\n        editor: Ace.Editor;\n    }\n}\ndeclare module \"ace-code/src/search_highlight\" {\n    export type Marker = import(\"ace-code/src/layer/marker\").Marker;\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export class SearchHighlight {\n        constructor(regExp: any, clazz: string, type?: string);\n        clazz: string;\n        type: string;\n        docLen: number;\n        setRegexp(regExp: any): void;\n        regExp: any;\n        cache: any[];\n        update(html: any, markerLayer: Marker, session: EditSession, config: Partial<import(\"ace-code\").Ace.LayerConfig>): void;\n        MAX_RANGES: number;\n    }\n}\ndeclare module \"ace-code/src/occur\" {\n    export type Editor = import(\"ace-code/src/editor\").Editor;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type SearchOptions = import(\"ace-code\").Ace.SearchOptions;\n    /**\n     * Finds all lines matching a search term in the current [[Document\n     * `Document`]] and displays them instead of the original `Document`. Keeps\n     * track of the mapping between the occur doc and the original doc.\n     **/\n    export class Occur extends Search {\n        /**\n         * Enables occur mode. expects that `options.needle` is a search term.\n         * This search term is used to filter out all the lines that include it\n         * and these are then used as the content of a new [[Document\n         * `Document`]]. The current cursor position of editor will be translated\n         * so that the cursor is on the matching row/column as it was before.\n         * @param {Object} options options.needle should be a String\n         * @return {Boolean} Whether occur activation was successful\n         *\n         **/\n        enter(editor: Editor, options: any): boolean;\n        /**\n         * Disables occur mode. Resets the [[Sessions `EditSession`]] [[Document\n         * `Document`]] back to the original doc. If options.translatePosition is\n         * truthy also maps the [[Editors `Editor`]] cursor position accordingly.\n         * @param {Object} options options.translatePosition\n         * @return {Boolean} Whether occur deactivation was successful\n         *\n         **/\n        exit(editor: Editor, options: any): boolean;\n        highlight(sess: EditSession, regexp: RegExp): void;\n        displayOccurContent(editor: Editor, options: Partial<SearchOptions>): void;\n        displayOriginalContent(editor: Editor): void;\n        /**\n        * Translates the position from the original document to the occur lines in\n        * the document or the beginning if the doc {row: 0, column: 0} if not\n        * found.\n        * @param {EditSession} session The occur session\n        * @param {Point} pos The position in the original document\n        * @return {Point} position in occur doc\n        **/\n        originalToOccurPosition(session: EditSession, pos: Point): Point;\n        /**\n        * Translates the position from the occur document to the original document\n        * or `pos` if not found.\n        * @param {EditSession} session The occur session\n        * @param {Point} pos The position in the occur session document\n        **/\n        occurToOriginalPosition(session: EditSession, pos: Point): Point;\n        matchingLines(session: EditSession, options: Partial<SearchOptions>): any[];\n    }\n    import { Search } from \"ace-code/src/search\";\n    import { EditSession } from \"ace-code/src/edit_session\";\n}\ndeclare module \"ace-code/src/mouse/multi_select_handler\" {\n    export function onMouseDown(e: any): any;\n}\ndeclare module \"ace-code/src/commands/multi_select_commands\" {\n    export const defaultCommands: import(\"ace-code\").Ace.Command[];\n    export const multiSelectCommands: import(\"ace-code\").Ace.Command[];\n    export const keyboardHandler: HashHandler;\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n}\ndeclare module \"ace-code/src/multi_select\" {\n    export const commands: import(\"ace-code\").Ace.Command[];\n    export const onSessionChange: (e: any) => void;\n    export type Anchor = import(\"ace-code/src/anchor\").Anchor;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type ScreenCoordinates = import(\"ace-code\").Ace.ScreenCoordinates;\n    export function MultiSelect(editor: Editor): void;\n    import { Editor } from \"ace-code/src/editor\";\n}\ndeclare module \"ace-code/src/background_tokenizer\" {\n    /**\n     * Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use.\n     *\n     * If a certain row is changed, everything below that row is re-tokenized.\n     **/\n    export class BackgroundTokenizer {\n        /**\n         * Creates a new `BackgroundTokenizer` object.\n         * @param {Tokenizer} tokenizer The tokenizer to use\n         * @param {EditSession} [session] The editor session to associate with\n         **/\n        constructor(tokenizer: Tokenizer, session?: EditSession);\n        running: false | ReturnType<typeof setTimeout>;\n        lines: any[];\n        states: string[] | string[][];\n        currentLine: number;\n        tokenizer: import(\"ace-code/src/tokenizer\").Tokenizer;\n        /**\n         * Sets a new tokenizer for this object.\n         * @param {Tokenizer} tokenizer The new tokenizer to use\n         **/\n        setTokenizer(tokenizer: Tokenizer): void;\n        /**\n         * Sets a new document to associate with this object.\n         * @param {Document} doc The new document to associate with\n         **/\n        setDocument(doc: Document): void;\n        doc: import(\"ace-code/src/document\").Document;\n        /**\n         * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated.\n         * @param {Number} firstRow The starting row region\n         * @param {Number} lastRow The final row region\n         **/\n        fireUpdateEvent(firstRow: number, lastRow: number): void;\n        /**\n         * Starts tokenizing at the row indicated.\n         * @param {Number} startRow The row to start at\n         **/\n        start(startRow: number): void;\n        /**\n         * Sets pretty long delay to prevent the tokenizer from interfering with the user\n         */\n        scheduleStart(): void;\n        /**\n         * Stops tokenizing.\n         **/\n        stop(): void;\n        /**\n         * Gives list of [[Token]]'s of the row. (tokens are cached)\n         * @param {Number} row The row to get tokens at\n         **/\n        getTokens(row: number): import(\"ace-code\").Ace.Token[];\n        /**\n         * Returns the state of tokenization at the end of a row.\n         * @param {Number} row The row to get state at\n         **/\n        getState(row: number): string | string[];\n        cleanup(): void;\n    }\n    export type Document = import(\"ace-code/src/document\").Document;\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Tokenizer = import(\"ace-code/src/tokenizer\").Tokenizer;\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type BackgroundTokenizerEvents = import(\"ace-code\").Ace.BackgroundTokenizerEvents;\n    }\n    export interface BackgroundTokenizer extends Ace.EventEmitter<Ace.BackgroundTokenizerEvents> {\n    }\n}\ndeclare module \"ace-code/src/placeholder\" {\n    export class PlaceHolder {\n        constructor(session: EditSession, length: number, pos: import(\"ace-code\").Ace.Point, others: any[], mainClass: string, othersClass: string);\n        length: number;\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        doc: import(\"ace-code/src/document\").Document;\n        mainClass: string;\n        othersClass: string;\n        /**\n         * PlaceHolder.setup()\n         *\n         * TODO\n         *\n         **/\n        setup(): void;\n        selectionBefore: Range | Range[];\n        pos: import(\"ace-code/src/anchor\").Anchor;\n        others: any[];\n        /**\n         * PlaceHolder.showOtherMarkers()\n         *\n         * TODO\n         *\n         **/\n        showOtherMarkers(): void;\n        othersActive: boolean;\n        /**\n         * PlaceHolder.hideOtherMarkers()\n         *\n         * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one.\n         *\n         **/\n        hideOtherMarkers(): void;\n        updateAnchors(delta: import(\"ace-code\").Ace.Delta): void;\n        updateMarkers(): void;\n        /**\n         * PlaceHolder.detach()\n         *\n         * TODO\n         *\n         **/\n        detach(): void;\n        /**\n         * PlaceHolder.cancel()\n         *\n         * TODO\n         *\n         **/\n        cancel(): void;\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    import { Range } from \"ace-code/src/range\";\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type PlaceHolderEvents = import(\"ace-code\").Ace.PlaceHolderEvents;\n    }\n    export interface PlaceHolder extends Ace.EventEmitter<Ace.PlaceHolderEvents> {\n    }\n}\ndeclare module \"ace-code/src/layer/text_markers\" {\n    export type TextMarker = {\n        range: import(\"ace-code\").Ace.IRange;\n        id: number;\n        className: string;\n        type?: string;\n    };\n    export type SelectionSegment = {\n        /**\n         * - Characters before selection\n         */\n        beforeSelection: number;\n        /**\n         * - Length of selection\n         */\n        selectionLength: number;\n        /**\n         * - Characters after selection\n         */\n        afterSelection: number;\n    };\n    export namespace textMarkerMixin {\n        function $removeClass(this: Text, className: string): void;\n        function $applyTextMarkers(this: Text): void;\n        /**\n         * Modifies the DOM for marker rendering.\n         * @param {HTMLElement} lineElement - The line element to modify\n         * @param {number} row - The row being processed\n         * @param {TextMarker} marker - The marker to apply\n         */\n        function $modifyDomForMarkers(lineElement: HTMLElement, row: number, marker: TextMarker): void;\n        /**\n         * Process text nodes for invisible markers (whitespace visualization)\n         * @param {Node} node - The DOM node to process\n         * @param {Node} parentNode - The parent node\n         * @param {object} marker - The marker being applied\n         */\n        function $processInvisibleMarker(node: Node, parentNode: Node, selectionSegment: SelectionSegment, marker: object): void;\n        /**\n         * Process nodes for regular markers (not invisible whitespace)\n         * @param {Node} node - The DOM node to process\n         * @param {Node} parentNode - The parent node\n         * @param {TextMarker} marker - The marker being applied\n         * @param {number} nodeStart - Starting column of the node\n         * @param {number} startCol - Starting column of the selection\n         * @param {number} endCol - Ending column of the selection\n         */\n        function $processRegularMarker(node: Node, parentNode: Node, selectionSegment: SelectionSegment, marker: TextMarker, nodeStart: number, startCol: number, endCol: number): void;\n    }\n    export namespace editSessionTextMarkerMixin {\n        /**\n         * Adds a text marker to the current edit session.\n         *\n         * @param {import(\"ace-code\").Ace.IRange} range - The range to mark in the document\n         * @param {string} className - The CSS class name to apply to the marked text\n         * @param {string} [type] - The type of marker (e.g. \"invisible\" for whitespace rendering)\n         * @returns {number} The unique identifier for the added text marker\n         *\n         */\n        function addTextMarker(this: EditSession, range: import(\"ace-code\").Ace.IRange, className: string, type?: string): number;\n        /**\n         * Removes a text marker from the current edit session.\n         *\n         * @param {number} markerId - The unique identifier of the text marker to remove\n         *\n         */\n        function removeTextMarker(this: EditSession, markerId: number): void;\n        /**\n         * Retrieves the text markers associated with the current edit session.\n         *\n         * @returns {TextMarker[]} An array of text markers, or an empty array if no markers exist\n         *\n         */\n        function getTextMarkers(this: EditSession): TextMarker[];\n    }\n    import { Text } from \"ace-code/src/layer/text\";\n    import { EditSession } from \"ace-code/src/edit_session\";\n}\ndeclare module \"ace-code/src/edit_session/fold\" {\n    export class Fold extends RangeList {\n        constructor(range: Range, placeholder: any);\n        foldLine: import(\"ace-code/src/edit_session/fold_line\").FoldLine;\n        placeholder: any;\n        range: import(\"ace-code/src/range\").Range;\n        start: import(\"ace-code\").Ace.Point;\n        end: import(\"ace-code\").Ace.Point;\n        sameRow: boolean;\n        subFolds: Fold[];\n        setFoldLine(foldLine: FoldLine): void;\n        clone(): Fold;\n        addSubFold(fold: Fold): any;\n        restoreRange(range: IRange): void;\n        collapseChildren?: number;\n    }\n    export type FoldLine = import(\"ace-code/src/edit_session/fold_line\").FoldLine;\n    export type Range = import(\"ace-code/src/range\").Range;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type IRange = import(\"ace-code\").Ace.IRange;\n    import { RangeList } from \"ace-code/src/range_list\";\n    export interface Fold {\n        collapseChildren?: number;\n    }\n}\ndeclare module \"ace-code/src/edit_session/fold_line\" {\n    export type Fold = import(\"ace-code/src/edit_session/fold\").Fold;\n    export class FoldLine {\n        /**\n         * If an array is passed in, the folds are expected to be sorted already.\n         */\n        constructor(foldData: FoldLine[], folds: Fold[] | Fold);\n        foldData: FoldLine[];\n        folds: Fold[];\n        range: Range;\n        start: import(\"ace-code\").Ace.Point;\n        end: import(\"ace-code\").Ace.Point;\n        /**\n         * Note: This doesn't update wrapData!\n         */\n        shiftRow(shift: number): void;\n        addFold(fold: Fold): void;\n        containsRow(row: number): boolean;\n        walk(callback: Function, endRow: number, endColumn: number): void;\n        getNextFoldTo(row: number, column: number): {\n            fold: Fold;\n            kind: string;\n        } | null;\n        addRemoveChars(row: number, column: number, len: number): void;\n        split(row: number, column: number): FoldLine | null;\n        merge(foldLineNext: FoldLine): void;\n        toString(): string;\n        idxToPosition(idx: number): import(\"ace-code\").Ace.Point;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/bidihandler\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    /**\n     * This object is used to ensure Bi-Directional support (for languages with text flowing from right to left, like Arabic or Hebrew)\n     * including correct caret positioning, text selection mouse and keyboard arrows functioning\n     **/\n    export class BidiHandler {\n        /**\n         * Creates a new `BidiHandler` object\n         * @param {EditSession} session The session to use\n         **/\n        constructor(session: EditSession);\n        session: import(\"ace-code/src/edit_session\").EditSession;\n        bidiMap: {};\n        currentRow: any;\n        bidiUtil: typeof bidiUtil;\n        charWidths: any[];\n        EOL: string;\n        showInvisibles: boolean;\n        isRtlDir: boolean;\n        line: string;\n        wrapIndent: number;\n        EOF: string;\n        RLE: string;\n        contentWidth: number;\n        fontMetrics: any;\n        rtlLineOffset: number;\n        wrapOffset: number;\n        isMoveLeftOperation: boolean;\n        seenBidi: boolean;\n        /**\n         * Returns 'true' if row contains Bidi characters, in such case\n         * creates Bidi map to be used in operations related to selection\n         * (keyboard arrays, mouse click, select)\n         * @param {Number} screenRow the screen row to be checked\n         * @param {Number} [docRow] the document row to be checked [optional]\n         * @param {Number} [splitIndex] the wrapped screen line index [ optional]\n        **/\n        isBidiRow(screenRow: number, docRow?: number, splitIndex?: number): any;\n        getDocumentRow(): number;\n        getSplitIndex(): number;\n        updateRowLine(docRow: any, splitIndex: any): void;\n        updateBidiMap(): void;\n        /**\n         * Resets stored info related to current screen row\n        **/\n        markAsDirty(): void;\n        /**\n         * Updates array of character widths\n         * @param {Object} fontMetrics metrics\n         *\n        **/\n        updateCharacterWidths(fontMetrics: any): void;\n        characterWidth: any;\n        setShowInvisibles(showInvisibles: any): void;\n        setEolChar(eolChar: any): void;\n        setContentWidth(width: any): void;\n        isRtlLine(row: any): boolean;\n        setRtlDirection(editor: any, isRtlDir: any): void;\n        /**\n         * Returns offset of character at position defined by column.\n         * @param {Number} col the screen column position\n         *\n         * @return {Number} horizontal pixel offset of given screen column\n         **/\n        getPosLeft(col: number): number;\n        /**\n         * Returns 'selections' - array of objects defining set of selection rectangles\n         * @param {Number} startCol the start column position\n         * @param {Number} endCol the end column position\n         *\n         * @return {Object[]} Each object contains 'left' and 'width' values defining selection rectangle.\n        **/\n        getSelections(startCol: number, endCol: number): any[];\n        /**\n         * Converts character coordinates on the screen to respective document column number\n         * @param {Number} posX character horizontal offset\n         *\n         * @return {Number} screen column number corresponding to given pixel offset\n        **/\n        offsetToCol(posX: number): number;\n    }\n    import bidiUtil = require(\"ace-code/src/lib/bidiutil\");\n}\ndeclare module \"ace-code/src/edit_session/folding\" {\n    export type IFolding = import(\"ace-code/src/edit_session\").EditSession & import(\"ace-code\").Ace.Folding;\n    export type Delta = import(\"ace-code\").Ace.Delta;\n    export function Folding(this: IFolding): void;\n    export class Folding {\n        /**\n         * Looks up a fold at a given row/column. Possible values for side:\n         *   -1: ignore a fold if fold.start = row/column\n         *   +1: ignore a fold if fold.end = row/column\n         **/\n        getFoldAt: (row: number, column: number, side?: number) => import(\"ace-code\").Ace.Fold;\n        /**\n         * Returns all folds in the given range. Note, that this will return folds\n         **/\n        getFoldsInRange: (range: import(\"ace-code\").Ace.Range | import(\"ace-code\").Ace.Delta) => import(\"ace-code\").Ace.Fold[];\n        getFoldsInRangeList: (ranges: import(\"ace-code\").Ace.Range[] | import(\"ace-code\").Ace.Range) => import(\"ace-code\").Ace.Fold[];\n        /**\n         * Returns all folds in the document\n         */\n        getAllFolds: () => import(\"ace-code\").Ace.Fold[];\n        /**\n         * Returns the string between folds at the given position.\n         * E.g.\n         *  foo<fold>b|ar<fold>wolrd -> \"bar\"\n         *  foo<fold>bar<fold>wol|rd -> \"world\"\n         *  foo<fold>bar<fo|ld>wolrd -> <null>\n         *\n         * where | means the position of row/column\n         *\n         * The trim option determs if the return string should be trimed according\n         * to the \"side\" passed with the trim value:\n         *\n         * E.g.\n         *  foo<fold>b|ar<fold>wolrd -trim=-1> \"b\"\n         *  foo<fold>bar<fold>wol|rd -trim=+1> \"rld\"\n         *  fo|o<fold>bar<fold>wolrd -trim=00> \"foo\"\n         */\n        getFoldStringAt: (row: number, column: number, trim?: number, foldLine?: import(\"ace-code\").Ace.FoldLine) => string | null;\n        getFoldLine: (docRow: number, startFoldLine?: import(\"ace-code\").Ace.FoldLine) => null | import(\"ace-code\").Ace.FoldLine;\n        /**\n         * Returns the fold which starts after or contains docRow\n         */\n        getNextFoldLine: (docRow: number, startFoldLine?: import(\"ace-code\").Ace.FoldLine) => null | import(\"ace-code\").Ace.FoldLine;\n        getFoldedRowCount: (first: number, last: number) => number;\n        /**\n         * Adds a new fold.\n         *\n         *      The new created Fold object or an existing fold object in case the\n         *      passed in range fits an existing fold exactly.\n         */\n        addFold: (placeholder: import(\"ace-code\").Ace.Fold | string, range?: import(\"ace-code\").Ace.Range) => import(\"ace-code\").Ace.Fold;\n        addFolds: (folds: import(\"ace-code\").Ace.Fold[]) => void;\n        removeFold: (fold: import(\"ace-code\").Ace.Fold) => void;\n        removeFolds: (folds: import(\"ace-code\").Ace.Fold[]) => void;\n        expandFold: (fold: import(\"ace-code\").Ace.Fold) => void;\n        expandFolds: (folds: import(\"ace-code\").Ace.Fold[]) => void;\n        unfold: (location?: number | null | import(\"ace-code\").Ace.Point | import(\"ace-code\").Ace.Range | import(\"ace-code\").Ace.Range[], expandInner?: boolean) => import(\"ace-code\").Ace.Fold[] | undefined;\n        /**\n         * Checks if a given documentRow is folded. This is true if there are some\n         * folded parts such that some parts of the line is still visible.\n         **/\n        isRowFolded: (docRow: number, startFoldRow?: import(\"ace-code\").Ace.FoldLine) => boolean;\n        getRowFoldEnd: (docRow: number, startFoldRow?: import(\"ace-code\").Ace.FoldLine) => number;\n        getRowFoldStart: (docRow: number, startFoldRow?: import(\"ace-code\").Ace.FoldLine) => number;\n        getFoldDisplayLine: (foldLine: import(\"ace-code\").Ace.FoldLine, endRow?: number | null, endColumn?: number | null, startRow?: number | null, startColumn?: number | null) => string;\n        getDisplayLine: (row: number, endColumn: number | null, startRow: number | null, startColumn: number | null) => string;\n        toggleFold: (tryToUnfold?: boolean) => void;\n        getCommentFoldRange: (row: number, column: number, dir?: number) => import(\"ace-code\").Ace.Range | undefined;\n        foldAll: (startRow?: number | null, endRow?: number | null, depth?: number | null, test?: Function) => void;\n        foldToLevel: (level: number) => void;\n        foldAllComments: () => void;\n        setFoldStyle: (style: string) => void;\n        getParentFoldRangeData: (row: number, ignoreCurrent?: boolean) => {\n            range?: import(\"ace-code\").Ace.Range;\n            firstRange?: import(\"ace-code\").Ace.Range;\n        };\n        onFoldWidgetClick: (row: number, e: any) => void;\n        toggleFoldWidget: (toggleParent?: boolean) => void;\n        updateFoldWidgets: (delta: import(\"ace-code\").Ace.Delta) => void;\n        tokenizerUpdateFoldWidgets: (e: any) => void;\n    }\n}\ndeclare module \"ace-code/src/edit_session/bracket_match\" {\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type Point = import(\"ace-code/src/edit_session\").Point;\n    export function BracketMatch(): void;\n    export class BracketMatch {\n        findMatchingBracket: (this: import(\"ace-code/src/edit_session\").EditSession, position: Point, chr?: string) => import(\"ace-code\").Ace.Point;\n        getBracketRange: (this: import(\"ace-code/src/edit_session\").EditSession, pos: Point) => null | Range;\n        /**\n         * Returns:\n         * * null if there is no any bracket at `pos`;\n         * * two Ranges if there is opening and closing brackets;\n         * * one Range if there is only one bracket\n         *\n         */\n        getMatchingBracketRanges: (this: import(\"ace-code/src/edit_session\").EditSession, pos: Point, isBackwards?: boolean) => null | Range[];\n        /**\n         * Returns [[Range]]'s for matching tags and tag names, if there are any\n         */\n        getMatchingTags: (this: import(\"ace-code/src/edit_session\").EditSession, pos: Point) => {\n            closeTag: Range;\n            closeTagName: Range;\n            openTag: Range;\n            openTagName: Range;\n        } | undefined;\n    }\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/edit_session\" {\n    /**\n     * Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.\n     *\n     * `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s.\n     **/\n    export class EditSession {\n        /**\n        * Returns a new instance of EditSession with state from JSON.\n        * @method fromJSON\n        * @param {string|object} session The EditSession state.\n        */\n        static fromJSON(session: string | object): EditSession;\n        /**\n         * Sets up a new `EditSession` and associates it with the given `Document` and `Mode`.\n         **/\n        constructor(text?: Document | string, mode?: SyntaxMode | string);\n        doc: Document;\n        prevOp: {};\n        id: string;\n        bgTokenizer: BackgroundTokenizer;\n        selection: Selection;\n        destroyed: boolean;\n        curOp: import(\"ace-code\").Ace.Operation | null;\n        /**\n         * Start an Ace operation, which will then batch all the subsequent changes (to either content or selection) under a single atomic operation.\n         * @param {{command?: {name?: string}, args?: any}|undefined} [commandEvent] Optional name for the operation\n         */\n        startOperation(commandEvent?: {\n            command?: {\n                name?: string;\n            };\n            args?: any;\n        } | undefined): void;\n        /**\n         * End current Ace operation.\n         * Emits \"beforeEndOperation\" event just before clearing everything, where the current operation can be accessed through `curOp` property.\n         */\n        endOperation(e?: any): void;\n        /**\n         * Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`.\n         *\n         * @param {Document} doc The new `Document` to use\n         *\n         **/\n        setDocument(doc: Document): void;\n        /**\n         * Returns the `Document` associated with this session.\n         **/\n        getDocument(): Document;\n        /**\n         * Set \"widgetManager\" in EditSession\n         *\n         */\n        set widgetManager(value: LineWidgets);\n        /**\n         * Get \"widgetManager\" from EditSession\n         *\n         */\n        get widgetManager(): LineWidgets;\n        resetCaches(): void;\n        mergeUndoDeltas: boolean;\n        onSelectionChange(): void;\n        /**\n         * Sets the session text.\n         * @param {String} text The new text to place\n         **/\n        setValue(text: string): void;\n        /**\n         * Returns the current edit session.\n         * @method toJSON\n         */\n        toJSON(): any;\n        /**\n         * Returns selection object.\n         **/\n        getSelection(): Selection;\n        /**\n         * {:BackgroundTokenizer.getState}\n         * @param {Number} row The row to start at\n         * @related BackgroundTokenizer.getState\n         **/\n        getState(row: number): string | string[];\n        /**\n         * Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.\n         * @param {Number} row The row to start at\n         **/\n        getTokens(row: number): import(\"ace-code\").Ace.Token[];\n        /**\n         * Returns an object indicating the token at the current row. The object has two properties: `index` and `start`.\n         * @param {Number} row The row number to retrieve from\n         * @param {Number} column The column number to retrieve from\n         *\n         **/\n        getTokenAt(row: number, column: number): import(\"ace-code\").Ace.Token;\n        /**\n         * Sets the undo manager.\n         * @param {UndoManager} undoManager The new undo manager\n         **/\n        setUndoManager(undoManager: UndoManager): void;\n        /**\n         * starts a new group in undo history\n         **/\n        markUndoGroup(): void;\n        /**\n         * Returns the current undo manager.\n         **/\n        getUndoManager(): UndoManager;\n        /**\n         * Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by [[EditSession.getTabSize `getTabSize()`]]); otherwise it's simply `'\\t'`.\n         **/\n        getTabString(): string;\n        /**\n         * Pass `true` to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character (`'\\t'`).\n         * @param {Boolean} val Value indicating whether or not to use soft tabs\n         **/\n        setUseSoftTabs(val: boolean): void;\n        /**\n         * Returns `true` if soft tabs are being used, `false` otherwise.\n         **/\n        getUseSoftTabs(): boolean;\n        /**\n         * Set the number of spaces that define a soft tab; for example, passing in `4` transforms the soft tabs to be equivalent to four spaces. This function also emits the `changeTabSize` event.\n         * @param {Number} tabSize The new tab size\n         **/\n        setTabSize(tabSize: number): void;\n        /**\n         * Returns the current tab size.\n         **/\n        getTabSize(): number;\n        /**\n         * Returns `true` if the character at the position is a soft tab.\n         * @param {Point} position The position to check\n         **/\n        isTabStop(position: Point): boolean;\n        /**\n         * Set whether keyboard navigation of soft tabs moves the cursor within the soft tab, rather than over\n         * @param {Boolean} navigateWithinSoftTabs Value indicating whether or not to navigate within soft tabs\n         **/\n        setNavigateWithinSoftTabs(navigateWithinSoftTabs: boolean): void;\n        /**\n         * Returns `true` if keyboard navigation moves the cursor within soft tabs, `false` if it moves the cursor over soft tabs.\n         **/\n        getNavigateWithinSoftTabs(): boolean;\n        /**\n         * Pass in `true` to enable overwrites in your session, or `false` to disable.\n         *\n         * If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emits the `changeOverwrite` event.\n         *\n         * @param {Boolean} overwrite Defines whether or not to set overwrites\n         *\n         **/\n        setOverwrite(overwrite: boolean): void;\n        /**\n         * Returns `true` if overwrites are enabled; `false` otherwise.\n         **/\n        getOverwrite(): boolean;\n        /**\n         * Sets the value of overwrite to the opposite of whatever it currently is.\n         **/\n        toggleOverwrite(): void;\n        /**\n         * Adds `className` to the `row`, to be used for CSS stylings and whatnot.\n         * @param {Number} row The row number\n         * @param {String} className The class to add\n         **/\n        addGutterDecoration(row: number, className: string): void;\n        /**\n         * Replaces the custom icon with the fold widget if present from a specific row in the gutter\n         * @param {number} row The row number for which to hide the custom icon\n         * @experimental\n         */\n        removeGutterCustomWidget(row: number): void;\n        /**\n         * Replaces the fold widget if present with the custom icon from a specific row in the gutter\n         * @param {number} row - The row number where the widget will be displayed\n         * @param {Object} attributes - Configuration attributes for the widget\n         * @param {string} attributes.className - CSS class name for styling the widget\n         * @param {string} attributes.label - Text label to display in the widget\n         * @param {string} attributes.title - Tooltip text for the widget\n         * @param {Object} attributes.callbacks - Event callback functions for the widget e.g onClick;\n         * @experimental\n        */\n        addGutterCustomWidget(row: number, attributes: {\n            className: string;\n            label: string;\n            title: string;\n            callbacks: any;\n        }): void;\n        /**\n         * Removes `className` from the `row`.\n         * @param {Number} row The row number\n         * @param {String} className The class to add\n         **/\n        removeGutterDecoration(row: number, className: string): void;\n        /**\n         * Returns an array of strings, indicating the breakpoint class (if any) applied to each row.\n         **/\n        getBreakpoints(): string[];\n        /**\n         * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event.\n         * @param {number[]} rows An array of row indices\n         **/\n        setBreakpoints(rows: number[]): void;\n        /**\n         * Removes all breakpoints on the rows. This function also emits the `'changeBreakpoint'` event.\n         **/\n        clearBreakpoints(): void;\n        /**\n         * Sets a breakpoint on the row number given by `row`. This function also emits the `'changeBreakpoint'` event.\n         * @param {Number} row A row index\n         * @param {String} className Class of the breakpoint\n         **/\n        setBreakpoint(row: number, className: string): void;\n        /**\n         * Removes a breakpoint on the row number given by `row`. This function also emits the `'changeBreakpoint'` event.\n         * @param {Number} row A row index\n         **/\n        clearBreakpoint(row: number): void;\n        /**\n         * Adds a new marker to the given `Range`. If `inFront` is `true`, a front marker is defined, and the `'changeFrontMarker'` event fires; otherwise, the `'changeBackMarker'` event fires.\n         * @param {Range} range Define the range of the marker\n         * @param {String} clazz Set the CSS class for the marker\n         * @param {import(\"ace-code\").Ace.MarkerRenderer | \"fullLine\" | \"screenLine\" | \"text\" | \"line\"} [type] Identify the renderer type of the marker. If string provided, corresponding built-in renderer is used. Supported string types are \"fullLine\", \"screenLine\", \"text\" or \"line\". If a Function is provided, that Function is used as renderer.\n         * @param {Boolean} [inFront] Set to `true` to establish a front marker\n         *\n         * @return {Number} The new marker id\n         **/\n        addMarker(range: Range, clazz: string, type?: import(\"ace-code\").Ace.MarkerRenderer | \"fullLine\" | \"screenLine\" | \"text\" | \"line\", inFront?: boolean): number;\n        /**\n         * Adds a dynamic marker to the session.\n         * @param {import(\"ace-code\").Ace.MarkerLike} marker object with update method\n         * @param {Boolean} [inFront] Set to `true` to establish a front marker\n         *\n         * @return {import(\"ace-code\").Ace.MarkerLike} The added marker\n         **/\n        addDynamicMarker(marker: import(\"ace-code\").Ace.MarkerLike, inFront?: boolean): import(\"ace-code\").Ace.MarkerLike;\n        /**\n         * Removes the marker with the specified ID. If this marker was in front, the `'changeFrontMarker'` event is emitted. If the marker was in the back, the `'changeBackMarker'` event is emitted.\n         * @param {Number} markerId A number representing a marker\n         **/\n        removeMarker(markerId: number): void;\n        /**\n         * Returns an object containing all of the markers, either front or back.\n         * @param {Boolean} [inFront] If `true`, indicates you only want front markers; `false` indicates only back markers\n         *\n         **/\n        getMarkers(inFront?: boolean): {\n            [id: number]: import(\"ace-code\").Ace.MarkerLike;\n        };\n        highlight(re: RegExp): void;\n        /**\n         * experimental\n         */\n        highlightLines(startRow: number, endRow: number, clazz: string, inFront?: boolean): Range;\n        /**\n         * Sets annotations for the `EditSession`. This functions emits the `'changeAnnotation'` event.\n         * @param {import(\"ace-code\").Ace.Annotation[]} annotations A list of annotations\n         **/\n        setAnnotations(annotations: import(\"ace-code\").Ace.Annotation[]): void;\n        /**\n         * Returns the annotations for the `EditSession`.\n         **/\n        getAnnotations(): import(\"ace-code\").Ace.Annotation[];\n        /**\n         * Clears all the annotations for this session. This function also triggers the `'changeAnnotation'` event.\n         **/\n        clearAnnotations(): void;\n        /**\n         * Given a starting row and column, this method returns the `Range` of the first word boundary it finds.\n         * @param {Number} row The row to start at\n         * @param {Number} column The column to start at\n         *\n         **/\n        getWordRange(row: number, column: number): Range;\n        /**\n         * Gets the range of a word, including its right whitespace.\n         * @param {Number} row The row number to start from\n         * @param {Number} column The column number to start from\n         *\n         **/\n        getAWordRange(row: number, column: number): Range;\n        /**\n         * {:Document.setNewLineMode.desc}\n         *\n         *\n         * @related Document.setNewLineMode\n         **/\n        setNewLineMode(newLineMode: import(\"ace-code\").Ace.NewLineMode): void;\n        /**\n         *\n         * Returns the current new line mode.\n         * @related Document.getNewLineMode\n         **/\n        getNewLineMode(): import(\"ace-code\").Ace.NewLineMode;\n        /**\n         * Identifies if you want to use a worker for the `EditSession`.\n         * @param {Boolean} useWorker Set to `true` to use a worker\n         **/\n        setUseWorker(useWorker: boolean): void;\n        /**\n         * Returns `true` if workers are being used.\n         **/\n        getUseWorker(): boolean;\n        /**\n         * Sets a new text mode for the `EditSession`. This method also emits the `'changeMode'` event. If a [[BackgroundTokenizer `BackgroundTokenizer`]] is set, the `'tokenizerUpdate'` event is also emitted.\n         * @param {SyntaxMode | string} mode Set a new text mode\n         * @param {() => void} [cb] optional callback\n         **/\n        setMode(mode: SyntaxMode | string, cb?: () => void): void;\n        tokenRe: RegExp;\n        nonTokenRe: RegExp;\n        /**\n         * Returns the current text mode.\n         * @returns {TextMode} The current text mode\n         **/\n        getMode(): TextMode;\n        /**\n         * This function sets the scroll top value. It also emits the `'changeScrollTop'` event.\n         * @param {Number} scrollTop The new scroll top value\n         **/\n        setScrollTop(scrollTop: number): void;\n        /**\n         * [Returns the value of the distance between the top of the editor and the topmost part of the visible content.]{: #EditSession.getScrollTop}\n         **/\n        getScrollTop(): number;\n        /**\n         * [Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.setScrollLeft}\n         */\n        setScrollLeft(scrollLeft: number): void;\n        /**\n         * [Returns the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.getScrollLeft}\n         **/\n        getScrollLeft(): number;\n        /**\n         * Returns the width of the screen.\n         **/\n        getScreenWidth(): number;\n        getLineWidgetMaxWidth(): number;\n        lineWidgetWidth: number;\n        screenWidth: any;\n        /**\n         * Returns a verbatim copy of the given line as it is in the document\n         * @param {Number} row The row to retrieve from\n         **/\n        getLine(row: number): string;\n        /**\n         * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.\n         * @param {Number} firstRow The first row index to retrieve\n         * @param {Number} lastRow The final row index to retrieve\n         *\n         *\n         **/\n        getLines(firstRow: number, lastRow: number): string[];\n        /**\n         * Returns the number of rows in the document.\n         **/\n        getLength(): number;\n        /**\n         * {:Document.getTextRange.desc}\n         * @param {IRange} [range] The range to work with\n         *\n         **/\n        getTextRange(range?: IRange): string;\n        /**\n         * Inserts a block of `text` and the indicated `position`.\n         * @param {Point} position The position {row, column} to start inserting at\n         * @param {String} text A chunk of text to insert\n         * @returns {Point} The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.\n         **/\n        insert(position: Point, text: string): Point;\n        /**\n         * Removes the `range` from the document.\n         * @param {IRange} range A specified Range to remove\n         * @returns {Point} The new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.\n         **/\n        remove(range: IRange): Point;\n        /**\n         * Removes a range of full lines. This method also triggers the `'change'` event.\n         * @param {Number} firstRow The first row to be removed\n         * @param {Number} lastRow The last row to be removed\n         * @returns {String[]} Returns all the removed lines.\n         *\n         * @related Document.removeFullLines\n         *\n         **/\n        removeFullLines(firstRow: number, lastRow: number): string[];\n        /**\n         * Reverts previous changes to your document.\n         * @param {Delta[]} deltas An array of previous changes\n         * @param {Boolean} [dontSelect] If `true`, doesn't select the range of where the change occured\n         **/\n        undoChanges(deltas: Delta[], dontSelect?: boolean): void;\n        /**\n         * Re-implements a previously undone change to your document.\n         * @param {Delta[]} deltas An array of previous changes\n         **/\n        redoChanges(deltas: Delta[], dontSelect?: boolean): void;\n        /**\n         * Enables or disables highlighting of the range where an undo occurred.\n         * @param {Boolean} enable If `true`, selects the range of the reinserted change\n         *\n         **/\n        setUndoSelect(enable: boolean): void;\n        /**\n         * Replaces a range in the document with the new `text`.\n         *\n         * @param {IRange} range A specified Range to replace\n         * @param {String} text The new text to use as a replacement\n         * @returns {Point} An object containing the final row and column, like this:\n         * ```\n         * {row: endRow, column: 0}\n         * ```\n         * If the text and range are empty, this function returns an object containing the current `range.start` value.\n         * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.\n         *\n         * @related Document.replace\n         **/\n        replace(range: IRange, text: string): Point;\n        /**\n         * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:\n         *  ```json\n         *    { row: newRowLocation, column: newColumnLocation }\n         *  ```\n         * @param {Range} fromRange The range of text you want moved within the document\n         * @param {Point} toPosition The location (row and column) where you want to move the text to\n         * @returns {Range} The new range where the text was moved to.\n         **/\n        moveText(fromRange: Range, toPosition: Point, copy?: boolean): Range;\n        /**\n         * Indents all the rows, from `startRow` to `endRow` (inclusive), by prefixing each row with the token in `indentString`.\n         *\n         * If `indentString` contains the `'\\t'` character, it's replaced by whatever is defined by [[EditSession.getTabString `getTabString()`]].\n         * @param {Number} startRow Starting row\n         * @param {Number} endRow Ending row\n         * @param {String} indentString The indent token\n         **/\n        indentRows(startRow: number, endRow: number, indentString: string): void;\n        /**\n         * Outdents all the rows defined by the `start` and `end` properties of `range`.\n         * @param {Range} range A range of rows\n         **/\n        outdentRows(range: Range): void;\n        /**\n         * Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`.\n         * @param {Number} firstRow The starting row to move up\n         * @param {Number} lastRow The final row to move up\n         * @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.\n         **/\n        moveLinesUp(firstRow: number, lastRow: number): number;\n        /**\n         * Shifts all the lines in the document down one, starting from `firstRow` and ending at `lastRow`.\n         * @param {Number} firstRow The starting row to move down\n         * @param {Number} lastRow The final row to move down\n         * @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.\n         **/\n        moveLinesDown(firstRow: number, lastRow: number): number;\n        /**\n         * Duplicates all the text between `firstRow` and `lastRow`.\n         * @param {Number} firstRow The starting row to duplicate\n         * @param {Number} lastRow The final row to duplicate\n         * @returns {Number} Returns the number of new rows added; in other words, `lastRow - firstRow + 1`.\n         **/\n        duplicateLines(firstRow: number, lastRow: number): number;\n        /**\n         * Sets whether or not line wrapping is enabled. If `useWrapMode` is different than the current value, the `'changeWrapMode'` event is emitted.\n         * @param {Boolean} useWrapMode Enable (or disable) wrap mode\n         **/\n        setUseWrapMode(useWrapMode: boolean): void;\n        /**\n         * Returns `true` if wrap mode is being used; `false` otherwise.\n         **/\n        getUseWrapMode(): boolean;\n        /**\n         * Sets the boundaries of wrap. Either value can be `null` to have an unconstrained wrap, or, they can be the same number to pin the limit. If the wrap limits for `min` or `max` are different, this method also emits the `'changeWrapMode'` event.\n         * @param {Number} min The minimum wrap value (the left side wrap)\n         * @param {Number} max The maximum wrap value (the right side wrap)\n         **/\n        setWrapLimitRange(min: number, max: number): void;\n        /**\n         * This should generally only be called by the renderer when a resize is detected.\n         * @param {Number} desiredLimit The new wrap limit\n         **/\n        adjustWrapLimit(desiredLimit: number, $printMargin?: any): boolean;\n        /**\n         * Returns the value of wrap limit.\n         * @returns {Number} The wrap limit.\n         **/\n        getWrapLimit(): number;\n        /**\n         * Sets the line length for soft wrap in the editor. Lines will break\n         *  at a minimum of the given length minus 20 chars and at a maximum\n         *  of the given number of chars.\n         * @param {number} limit The maximum line length in chars, for soft wrapping lines.\n         */\n        setWrapLimit(limit: number): void;\n        /**\n         * Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this:\n         *\n         *     { min: wrapLimitRange_min, max: wrapLimitRange_max }\n         *\n         **/\n        getWrapLimitRange(): {\n            min: number;\n            max: number;\n        };\n        /**\n         * Returns number of screenrows in a wrapped line.\n         * @param {Number} row The row number to check\n         **/\n        getRowLength(row: number): number;\n        getRowLineCount(row: number): number;\n        getRowWrapIndent(screenRow: number): number;\n        /**\n         * Returns the position (on screen) for the last character in the provided screen row.\n         * @param {Number} screenRow The screen row to check\n         *\n         * @related EditSession.documentToScreenColumn\n         **/\n        getScreenLastRowColumn(screenRow: number): number;\n        /**\n         * For the given document row and column, this returns the column position of the last screen row.\n         **/\n        getDocumentLastRowColumn(docRow: number, docColumn: number): number;\n        /**\n         * For the given document row and column, this returns the document position of the last row.\n         **/\n        getDocumentLastRowColumnPosition(docRow: number, docColumn: number): Point;\n        /**\n         * For the given row, this returns the split data.\n         */\n        getRowSplitData(row: number): string | undefined;\n        /**\n         * The distance to the next tab stop at the specified screen column.\n         * @param {Number} screenColumn The screen column to check\n         *\n         **/\n        getScreenTabSize(screenColumn: number): number;\n        screenToDocumentRow(screenRow: number, screenColumn: number): number;\n        screenToDocumentColumn(screenRow: number, screenColumn: number): number;\n        /**\n         * Converts characters coordinates on the screen to characters coordinates within the document. [This takes into account code folding, word wrap, tab size, and any other visual modifications.]{: #conversionConsiderations}\n         * @param {Number} screenRow The screen row to check\n         * @param {Number} screenColumn The screen column to check\n         * @param {Number} [offsetX] screen character x-offset [optional]\n         *\n         * @returns {Point} The object returned has two properties: `row` and `column`.\n         *\n         * @related EditSession.documentToScreenPosition\n         **/\n        screenToDocumentPosition(screenRow: number, screenColumn: number, offsetX?: number): Point;\n        /**\n         * Converts document coordinates to screen coordinates. {:conversionConsiderations}\n         * @param {Number|Point} docRow The document row to check\n         * @param {Number|undefined} [docColumn] The document column to check\n         * @returns {Point} The object returned by this method has two properties: `row` and `column`.\n         *\n         * @related EditSession.screenToDocumentPosition\n         **/\n        documentToScreenPosition(docRow: number | Point, docColumn?: number | undefined): Point;\n        /**\n         * For the given document row and column, returns the screen column.\n         **/\n        documentToScreenColumn(row: number | Point, docColumn?: number): number;\n        /**\n         * For the given document row and column, returns the screen row.\n         **/\n        documentToScreenRow(docRow: number | Point, docColumn?: number): number;\n        /**\n         * Returns the length of the screen.\n         **/\n        getScreenLength(): number;\n        /**\n         * @returns {string} the last character preceding the cursor in the editor\n         */\n        getPrecedingCharacter(): string;\n        destroy(): void;\n        /**\n         * Returns the current [[Document `Document`]] as a string.\n         * @method getValue\n         * @alias EditSession.toString\n         **/\n        getValue: () => string;\n        lineWidgets: null | import(\"ace-code\").Ace.LineWidget[];\n        isFullWidth: typeof isFullWidth;\n        lineWidgetsWidth?: number;\n        gutterRenderer?: any;\n        selectionMarkerCount?: number;\n        multiSelect?: any;\n        getSelectionMarkers(): any[];\n    }\n    export namespace EditSession {\n        export { $uid };\n    }\n    export type FontMetrics = import(\"ace-code/src/layer/font_metrics\").FontMetrics;\n    export type FoldLine = import(\"ace-code/src/edit_session/fold_line\").FoldLine;\n    export type Point = import(\"ace-code\").Ace.Point;\n    export type Delta = import(\"ace-code\").Ace.Delta;\n    export type IRange = import(\"ace-code\").Ace.IRange;\n    export type SyntaxMode = import(\"ace-code\").Ace.SyntaxMode;\n    export type LineWidget = import(\"ace-code\").Ace.LineWidget;\n    export type TextMode = SyntaxMode;\n    type TextMarker = {\n        range: IRange;\n        id: number;\n        className: string;\n        type?: string;\n    };\n    type TextMarkers = {\n        addTextMarker(this: EditSession, range: IRange, className: string, type?: string): number;\n        removeTextMarker(this: EditSession, markerId: number): void;\n        getTextMarkers(this: EditSession): TextMarker[];\n    } & {\n    };\n    import { Document } from \"ace-code/src/document\";\n    import { BackgroundTokenizer } from \"ace-code/src/background_tokenizer\";\n    import { Selection } from \"ace-code/src/selection\";\n    import { BidiHandler } from \"ace-code/src/bidihandler\";\n    import { Range } from \"ace-code/src/range\";\n    import { LineWidgets } from \"ace-code/src/line_widgets\";\n    import { UndoManager } from \"ace-code/src/undomanager\";\n    function isFullWidth(c: any): boolean;\n    var $uid: number;\n    namespace Ace {\n        type EventEmitter<T extends {\n            [K in keyof T]: (...args: any[]) => any;\n        }> = import(\"ace-code\").Ace.EventEmitter<T>;\n        type EditSessionEvents = import(\"ace-code\").Ace.EditSessionEvents;\n        type OptionsProvider<T> = import(\"ace-code\").Ace.OptionsProvider<T>;\n        type EditSessionOptions = import(\"ace-code\").Ace.EditSessionOptions;\n        type Folding = import(\"ace-code\").Ace.Folding;\n        type BracketMatch = import(\"ace-code\").Ace.BracketMatch;\n        type Document = import(\"ace-code\").Ace.Document;\n        type Point = import(\"ace-code\").Ace.Point;\n        type Occur = import(\"ace-code\").Ace.Occur;\n        type Operation = import(\"ace-code\").Ace.Operation;\n    }\n    export interface EditSession extends Ace.EventEmitter<Ace.EditSessionEvents>, Ace.OptionsProvider<Ace.EditSessionOptions>, Ace.Folding, Ace.\n        BracketMatch, TextMarkers {\n        doc: Ace.Document;\n        lineWidgetsWidth?: number;\n        gutterRenderer?: any;\n        selectionMarkerCount?: number;\n        multiSelect?: any;\n        curOp: Ace.Operation | null;\n        getSelectionMarkers(): any[];\n    }\n}\ndeclare module \"ace-code/src/range\" {\n    /**\n     * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogous to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.\n     **/\n    export class Range {\n        /**\n         * Creates a new `Range` object with the given starting and ending rows and columns.\n         * @param {Number} [startRow] The starting row\n         * @param {Number} [startColumn] The starting column\n         * @param {Number} [endRow] The ending row\n         * @param {Number} [endColumn] The ending column\n         * @constructor\n         **/\n        constructor(startRow?: number, startColumn?: number, endRow?: number, endColumn?: number);\n        start: Point;\n        end: Point;\n        /**\n         * Returns `true` if and only if the starting row and column, and ending row and column, are equivalent to those given by `range`.\n         * @param {IRange} range A range to check against\n         **/\n        isEqual(range: IRange): boolean;\n        /**\n         * Returns a string containing the range's row and column information, given like this:\n         * ```\n         *    [start.row/start.column] -> [end.row/end.column]\n         * ```\n         **/\n        toString(): string;\n        /**\n         * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:\n         * ```javascript\n         *    this.start.row <= row <= this.end.row &&\n         *    this.start.column <= column <= this.end.column\n         * ```\n         * @param {Number} row A row to check for\n         * @param {Number} column A column to check for\n         * @related [[Range.compare]]\n         **/\n        contains(row: number, column: number): boolean;\n        /**\n         * Compares `this` range (A) with another range (B).\n         * @param {IRange} range A range to compare with\n         * @related [[Range.compare]]\n         * @returns {Number} This method returns one of the following numbers:\n         * * `-2`: (B) is in front of (A), and doesn't intersect with (A)\n         * * `-1`: (B) begins before (A) but ends inside of (A)\n         * * `0`: (B) is completely inside of (A)\n         * * `+1`: (B) begins inside of (A) but ends outside of (A)\n         * * `+2`: (B) is after (A) and doesn't intersect with (A)\n         * * `42`: FTW state: (B) ends in (A) but starts outside of (A)\n         **/\n        compareRange(range: IRange): number;\n        /**\n         * Compares the row and column of `p` with the starting and ending [[Point]]'s of the calling range (by calling [[Range.compare]]).\n         * @param {Point} p A point to compare with\n         * @related [[Range.compare]]\n         **/\n        comparePoint(p: Point): number;\n        /**\n         * Checks the start and end [[Point]]'s of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.\n         * @param {IRange} range A range to compare with\n         * @related [[Range.comparePoint]]\n         **/\n        containsRange(range: IRange): boolean;\n        /**\n         * Returns `true` if passed in `range` intersects with the one calling this method.\n         * @param {IRange} range A range to compare with\n         **/\n        intersects(range: IRange): boolean;\n        /**\n         * Returns `true` if the caller's ending row is the same as `row`, and if the caller's ending column is the same as `column`.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         **/\n        isEnd(row: number, column: number): boolean;\n        /**\n         * Returns `true` if the caller's starting row is the same as `row`, and if the caller's starting column is the same as `column`.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         **/\n        isStart(row: number, column: number): boolean;\n        /**\n         * Sets the starting row and column for the range.\n         * @param {Number|Point} row A row to set\n         * @param {Number} [column] A column to set\n         *\n         **/\n        setStart(row: number | Point, column?: number): void;\n        /**\n         * Sets the starting row and column for the range.\n         * @param {Number|Point} row A row to set\n         * @param {Number} [column] A column to set\n         *\n         **/\n        setEnd(row: number | Point, column?: number): void;\n        /**\n         * Returns `true` if the `row` and `column` are within the given range.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @related [[Range.compare]]\n         **/\n        inside(row: number, column: number): boolean;\n        /**\n         * Returns `true` if the `row` and `column` are within the given range's starting [[Point]].\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @related [[Range.compare]]\n         **/\n        insideStart(row: number, column: number): boolean;\n        /**\n         * Returns `true` if the `row` and `column` are within the given range's ending [[Point]].\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @related [[Range.compare]]\n         *\n         **/\n        insideEnd(row: number, column: number): boolean;\n        /**\n         * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @returns {Number} This method returns one of the following numbers:\n         * * `1` if `row` is greater than the calling range\n         * * `-1` if `row` is less then the calling range\n         * * `0` otherwise\n         *\n         * If the starting row of the calling range is equal to `row`, and:\n         * * `column` is greater than or equal to the calling range's starting column, this returns `0`\n         * * Otherwise, it returns -1\n         *\n         * If the ending row of the calling range is equal to `row`, and:\n         * * `column` is less than or equal to the calling range's ending column, this returns `0`\n         * * Otherwise, it returns 1\n         **/\n        compare(row: number, column: number): number;\n        /**\n         * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @returns {Number} This method returns one of the following numbers:\n         * * `-1` if calling range's starting column and calling range's starting row are equal `row` and `column`\n         * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n         **/\n        compareStart(row: number, column: number): number;\n        /**\n         * Compares the `row` and `column` with the starting and ending [[Point]]'s of the calling range.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @returns {Number} This method returns one of the following numbers:\n         * * `1` if calling range's ending column and calling range's ending row are equal `row` and `column`.\n         * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n         */\n        compareEnd(row: number, column: number): number;\n        /**\n         * Compares the `row` and `column` with the start and end [[Point]]'s of the calling range.\n         * @param {Number} row A row to compare with\n         * @param {Number} column A column to compare with\n         * @returns {Number} This method returns one of the following numbers:\n         * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`\n         * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`\n         * * Otherwise, it returns the value after calling [[Range.compare `compare()`]].\n         **/\n        compareInside(row: number, column: number): number;\n        /**\n         * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.\n         * @param {Number} firstRow The starting row\n         * @param {Number} lastRow The ending row\n        **/\n        clipRows(firstRow: number, lastRow: number): Range;\n        /**\n         * Changes the `row` and `column` for the calling range for both the starting and ending [[Point]]'s.\n         * @param {Number} row A new row to extend to\n         * @param {Number} column A new column to extend to\n         * @returns {Range} The original range with the new row\n        **/\n        extend(row: number, column: number): Range;\n        /**\n         * Returns `true` if the calling range is empty (starting [[Point]] == ending [[Point]]).\n         **/\n        isEmpty(): boolean;\n        /**\n         * Returns `true` if the range spans across multiple lines.\n        **/\n        isMultiLine(): boolean;\n        /**\n         * Returns a duplicate of the calling range.\n        **/\n        clone(): Range;\n        /**\n         * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.\n        **/\n        collapseRows(): Range;\n        /**\n         * Given the current `Range`, this function converts those starting and ending [[Point]]'s into screen positions, and then returns a new `Range` object.\n         * @param {EditSession} session The `EditSession` to retrieve coordinates from\n        **/\n        toScreenRange(session: EditSession): Range;\n        /**\n         * Shift the calling range by `row` and `column` values.\n         * @experimental\n         */\n        moveBy(row: number, column: number): void;\n        id?: number;\n        cursor?: import(\"ace-code\").Ace.Point;\n        isBackwards?: boolean;\n    }\n    export namespace Range {\n        export { fromPoints, comparePoints };\n    }\n    export type EditSession = import(\"ace-code/src/edit_session\").EditSession;\n    export type IRange = import(\"ace-code\").Ace.IRange;\n    export type Point = import(\"ace-code\").Ace.Point;\n    /**\n     * Creates and returns a new `Range` based on the `start` [[Point]] and `end` [[Point]] of the given parameters.\n     * @param {Point} start A starting point to use\n     * @param {Point} end An ending point to use\n    **/\n    function fromPoints(start: Point, end: Point): Range;\n    /**\n     * Compares `p1` and `p2` [[Point]]'s, useful for sorting\n     */\n    function comparePoints(p1: Point, p2: Point): number;\n    namespace Ace {\n        type Point = import(\"ace-code\").Ace.Point;\n    }\n    export interface Range {\n        id?: number;\n        cursor?: Ace.Point;\n        isBackwards?: boolean;\n    }\n}\ndeclare module \"ace-code/src/worker/worker_client\" {\n    export var WorkerClient: any;\n}\ndeclare module \"ace-code/src/commands/occur_commands\" {\n    export namespace occurStartCommand {\n        let name: string;\n        function exec(editor: any, options: any): void;\n        let readOnly: boolean;\n    }\n}\ndeclare module \"ace-code/src/commands/incremental_search_commands\" {\n    export const iSearchStartCommands: ({\n        name: string;\n        bindKey: {\n            win: string;\n            mac: string;\n        };\n        exec: (editor: any, options: any) => void;\n        readOnly: boolean;\n    } | {\n        name: string;\n        exec: (editor: any, jumpToNext: any) => void;\n        readOnly: boolean;\n        bindKey?: undefined;\n    })[];\n    export const iSearchCommands: ({\n        name: string;\n        bindKey: {\n            win: string;\n            mac: string;\n        };\n        exec: (iSearch: any, options: any) => void;\n    } | {\n        name: string;\n        exec: (iSearch: any, string: any) => void;\n        bindKey?: undefined;\n    } | {\n        name: string;\n        bindKey: string;\n        exec: (iSearch: any) => void;\n    })[];\n    export function IncrementalSearchKeyboardHandler(iSearch: any): void;\n    export class IncrementalSearchKeyboardHandler {\n        constructor(iSearch: any);\n    }\n}\ndeclare module \"ace-code/src/incremental_search\" {\n    /**\n     * Implements immediate searching while the user is typing. When incremental\n     * search is activated, keystrokes into the editor will be used for composing\n     * a search term. Immediately after every keystroke the search is updated:\n     * - so-far-matching characters are highlighted\n     * - the cursor is moved to the next match\n     *\n     **/\n    export class IncrementalSearch extends Search {\n        activate(editor: any, backwards: boolean): void;\n        deactivate(reset?: boolean): void;\n        selectionFix(editor: Editor): void;\n        highlight(regexp: RegExp): void;\n        cancelSearch(reset?: boolean): Range;\n        highlightAndFindWithNeedle(moveToNext: boolean, needleUpdateFunc: Function): false | Range;\n        addString(s: string): false | Range;\n        removeChar(c: any): false | Range;\n        next(options: any): false | Range;\n        convertNeedleToRegExp(): false | Range;\n        convertNeedleToString(): false | Range;\n        statusMessage(found: any): void;\n        message(msg: any): void;\n    }\n    import { Search } from \"ace-code/src/search\";\n    import iSearchCommandModule = require(\"ace-code/src/commands/incremental_search_commands\");\n    import { Editor } from \"ace-code/src/editor\";\n    import { Range } from \"ace-code/src/range\";\n}\ndeclare module \"ace-code/src/split\" {\n    export type ISplit = import(\"ace-code\").Ace.EventEmitter<any> & {\n        [key: string]: any;\n    };\n    export var Split: any;\n}\ndeclare module \"ace-code/src/tokenizer_dev\" {\n    export class Tokenizer extends BaseTokenizer {\n        /**\n         * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.\n         **/\n        getLineTokens(line: any, startState: any): any;\n    }\n    import { Tokenizer as BaseTokenizer } from \"ace-code/src/tokenizer\";\n}\ndeclare module \"ace-code/src/unicode\" {\n    export const wordChars: any;\n}\ndeclare module \"ace-code/src/keyboard/textarea\" {\n    export const handler: HashHandler;\n    import { HashHandler } from \"ace-code/src/keyboard/hash_handler\";\n}\n"
  },
  {
    "path": "types/ace-snippets.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\ndeclare module \"ace-code/src/snippets/abc.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/abc\" {\n    export const snippetText: string;\n    export const scope: \"abc\";\n}\ndeclare module \"ace-code/src/snippets/actionscript.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/actionscript\" {\n    export const snippetText: string;\n    export const scope: \"actionscript\";\n}\ndeclare module \"ace-code/src/snippets/c_cpp.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/c_cpp\" {\n    export const snippetText: string;\n    export const scope: \"c_cpp\";\n}\ndeclare module \"ace-code/src/snippets/clojure.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/clojure\" {\n    export const snippetText: string;\n    export const scope: \"clojure\";\n}\ndeclare module \"ace-code/src/snippets/coffee.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/coffee\" {\n    export const snippetText: string;\n    export const scope: \"coffee\";\n}\ndeclare module \"ace-code/src/snippets/csound_document.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/csound_document\" {\n    export const snippetText: string;\n    export const scope: \"csound_document\";\n}\ndeclare module \"ace-code/src/snippets/csound_orchestra.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/csound_orchestra\" {\n    export const snippetText: string;\n    export const scope: \"csound_orchestra\";\n}\ndeclare module \"ace-code/src/snippets/css.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/css\" {\n    export const snippetText: string;\n    export const scope: \"css\";\n}\ndeclare module \"ace-code/src/snippets/dart.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/dart\" {\n    export const snippetText: string;\n    export const scope: \"dart\";\n}\ndeclare module \"ace-code/src/snippets/diff.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/diff\" {\n    export const snippetText: string;\n    export const scope: \"diff\";\n}\ndeclare module \"ace-code/src/snippets/django.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/django\" {\n    export const snippetText: string;\n    export const scope: \"django\";\n}\ndeclare module \"ace-code/src/snippets/drools.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/drools\" {\n    export const snippetText: string;\n    export const scope: \"drools\";\n}\ndeclare module \"ace-code/src/snippets/edifact.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/edifact\" {\n    export const snippetText: string;\n    export const scope: \"edifact\";\n}\ndeclare module \"ace-code/src/snippets/erlang.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/erlang\" {\n    export const snippetText: string;\n    export const scope: \"erlang\";\n}\ndeclare module \"ace-code/src/snippets/fsl.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/fsl\" {\n    export const snippetText: string;\n    export const scope: \"fsl\";\n}\ndeclare module \"ace-code/src/snippets/gobstones.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/gobstones\" {\n    export const snippetText: string;\n    export const scope: \"gobstones\";\n}\ndeclare module \"ace-code/src/snippets/graphqlschema.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/graphqlschema\" {\n    export const snippetText: string;\n    export const scope: \"graphqlschema\";\n}\ndeclare module \"ace-code/src/snippets/haml.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/haml\" {\n    export const snippetText: string;\n    export const scope: \"haml\";\n}\ndeclare module \"ace-code/src/snippets/haskell.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/haskell\" {\n    export const snippetText: string;\n    export const scope: \"haskell\";\n}\ndeclare module \"ace-code/src/snippets/html.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/html\" {\n    export const snippetText: string;\n    export const scope: \"html\";\n}\ndeclare module \"ace-code/src/snippets/io\" {\n    export const snippets: ({\n        content: string;\n        name: string;\n        scope: string;\n        tabTrigger: string;\n        keyEquivalent?: undefined;\n    } | {\n        content: string;\n        keyEquivalent: string;\n        name: string;\n        scope: string;\n        tabTrigger: string;\n    } | {\n        content: string;\n        keyEquivalent: string;\n        name: string;\n        scope: string;\n        tabTrigger?: undefined;\n    })[];\n    export const scope: \"io\";\n}\ndeclare module \"ace-code/src/snippets/java.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/java\" {\n    export const snippetText: string;\n    export const scope: \"java\";\n}\ndeclare module \"ace-code/src/snippets/javascript.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/javascript\" {\n    export const snippetText: string;\n    export const scope: \"javascript\";\n}\ndeclare module \"ace-code/src/snippets/jsp.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/jsp\" {\n    export const snippetText: string;\n    export const scope: \"jsp\";\n}\ndeclare module \"ace-code/src/snippets/liquid.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/liquid\" {\n    export const snippetText: string;\n    export const scope: \"liquid\";\n}\ndeclare module \"ace-code/src/snippets/lsl.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/lsl\" {\n    export const snippetText: string;\n    export const scope: \"lsl\";\n}\ndeclare module \"ace-code/src/snippets/lua.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/lua\" {\n    export const snippetText: string;\n    export const scope: \"lua\";\n}\ndeclare module \"ace-code/src/snippets/makefile.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/makefile\" {\n    export const snippetText: string;\n    export const scope: \"makefile\";\n}\ndeclare module \"ace-code/src/snippets/markdown.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/markdown\" {\n    export const snippetText: string;\n    export const scope: \"markdown\";\n}\ndeclare module \"ace-code/src/snippets/maze.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/maze\" {\n    export const snippetText: string;\n    export const scope: \"maze\";\n}\ndeclare module \"ace-code/src/snippets/perl.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/perl\" {\n    export const snippetText: string;\n    export const scope: \"perl\";\n}\ndeclare module \"ace-code/src/snippets/php.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/php\" {\n    export const snippetText: string;\n    export const scope: \"php\";\n}\ndeclare module \"ace-code/src/snippets/python.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/python\" {\n    export const snippetText: string;\n    export const scope: \"python\";\n}\ndeclare module \"ace-code/src/snippets/r.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/r\" {\n    export const snippetText: string;\n    export const scope: \"r\";\n}\ndeclare module \"ace-code/src/snippets/razor.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/razor\" {\n    export const snippetText: string;\n    export const scope: \"razor\";\n}\ndeclare module \"ace-code/src/snippets/robot.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/robot\" {\n    export const snippetText: string;\n    export const scope: \"robot\";\n}\ndeclare module \"ace-code/src/snippets/rst.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/rst\" {\n    export const snippetText: string;\n    export const scope: \"rst\";\n}\ndeclare module \"ace-code/src/snippets/ruby.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/ruby\" {\n    export const snippetText: string;\n    export const scope: \"ruby\";\n}\ndeclare module \"ace-code/src/snippets/sh.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/sh\" {\n    export const snippetText: string;\n    export const scope: \"sh\";\n}\ndeclare module \"ace-code/src/snippets/snippets.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/snippets\" {\n    export const snippetText: string;\n    export const scope: \"snippets\";\n}\ndeclare module \"ace-code/src/snippets/sql.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/sql\" {\n    export const snippetText: string;\n    export const scope: \"sql\";\n}\ndeclare module \"ace-code/src/snippets/sqlserver.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/sqlserver\" {\n    export const snippetText: string;\n    export const scope: \"sqlserver\";\n}\ndeclare module \"ace-code/src/snippets/tcl.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/tcl\" {\n    export const snippetText: string;\n    export const scope: \"tcl\";\n}\ndeclare module \"ace-code/src/snippets/tex.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/tex\" {\n    export const snippetText: string;\n    export const scope: \"tex\";\n}\ndeclare module \"ace-code/src/snippets/textile.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/textile\" {\n    export const snippetText: string;\n    export const scope: \"textile\";\n}\ndeclare module \"ace-code/src/snippets/vala\" {\n    export const snippets: {\n        content: string;\n        name: string;\n        scope: string;\n        tabTrigger: string;\n    }[];\n    export const scope: \"\";\n}\ndeclare module \"ace-code/src/snippets/velocity.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/velocity\" {\n    export const snippetText: string;\n    export const scope: \"velocity\";\n    export const includeScopes: string[];\n}\ndeclare module \"ace-code/src/snippets/wollok.snippets\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/snippets/wollok\" {\n    export const snippetText: string;\n    export const scope: \"wollok\";\n}\n"
  },
  {
    "path": "types/ace-theme.d.ts",
    "content": "/* This file is generated using `npm run update-types` */\n\ndeclare module \"ace-code/src/theme/textmate-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/textmate\" {\n    export const isDark: false;\n    export const cssClass: \"ace-tm\";\n    export const cssText: string;\n    export const $id: \"ace/theme/textmate\";\n}\ndeclare module \"ace-code/src/theme/ambiance-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/ambiance\" {\n    export const isDark: true;\n    export const cssClass: \"ace-ambiance\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/chaos-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/chaos\" {\n    export const isDark: true;\n    export const cssClass: \"ace-chaos\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/chrome-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/chrome\" {\n    export const isDark: false;\n    export const cssClass: \"ace-chrome\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/cloud9_day-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cloud9_day\" {\n    export const isDark: false;\n    export const cssClass: \"ace-cloud9-day\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/cloud9_night-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cloud9_night\" {\n    export const isDark: true;\n    export const cssClass: \"ace-cloud9-night\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/cloud9_night_low_color-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cloud9_night_low_color\" {\n    export const isDark: true;\n    export const cssClass: \"ace-cloud9-night-low-color\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/cloud_editor-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cloud_editor\" {\n    export const isDark: false;\n    export const cssClass: \"ace-cloud_editor\";\n    export const cssText: string;\n    export const $showGutterCursorMarker: true;\n}\ndeclare module \"ace-code/src/theme/cloud_editor_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cloud_editor_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-cloud_editor_dark\";\n    export const cssText: string;\n    export const $showGutterCursorMarker: true;\n}\ndeclare module \"ace-code/src/theme/clouds-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/clouds\" {\n    export const isDark: false;\n    export const cssClass: \"ace-clouds\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/clouds_midnight-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/clouds_midnight\" {\n    export const isDark: true;\n    export const cssClass: \"ace-clouds-midnight\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/cobalt-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/cobalt\" {\n    export const isDark: true;\n    export const cssClass: \"ace-cobalt\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/crimson_editor-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/crimson_editor\" {\n    export const isDark: false;\n    export const cssText: string;\n    export const cssClass: \"ace-crimson-editor\";\n}\ndeclare module \"ace-code/src/theme/dawn-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/dawn\" {\n    export const isDark: false;\n    export const cssClass: \"ace-dawn\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/dracula-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/dracula\" {\n    export const isDark: true;\n    export const cssClass: \"ace-dracula\";\n    export const cssText: string;\n    export const $selectionColorConflict: true;\n}\ndeclare module \"ace-code/src/theme/dreamweaver-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/dreamweaver\" {\n    export const isDark: false;\n    export const cssClass: \"ace-dreamweaver\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/eclipse-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/eclipse\" {\n    export const isDark: false;\n    export const cssText: string;\n    export const cssClass: \"ace-eclipse\";\n}\ndeclare module \"ace-code/src/theme/github-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/github\" {\n    export const isDark: false;\n    export const cssClass: \"ace-github\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/github_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/github_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-github-dark\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/github_light_default-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/github_light_default\" {\n    export const isDark: false;\n    export const cssClass: \"ace-github-light-default\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/gob-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/gob\" {\n    export const isDark: true;\n    export const cssClass: \"ace-gob\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/gruvbox-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/gruvbox\" {\n    export const isDark: true;\n    export const cssClass: \"ace-gruvbox\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/gruvbox_dark_hard-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/gruvbox_dark_hard\" {\n    export const isDark: true;\n    export const cssClass: \"ace-gruvbox-dark-hard\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/gruvbox_light_hard-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/gruvbox_light_hard\" {\n    export const isDark: false;\n    export const cssClass: \"ace-gruvbox-light-hard\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/idle_fingers-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/idle_fingers\" {\n    export const isDark: true;\n    export const cssClass: \"ace-idle-fingers\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/iplastic-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/iplastic\" {\n    export const isDark: false;\n    export const cssClass: \"ace-iplastic\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/katzenmilch-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/katzenmilch\" {\n    export const isDark: false;\n    export const cssClass: \"ace-katzenmilch\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/kr_theme-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/kr_theme\" {\n    export const isDark: true;\n    export const cssClass: \"ace-kr-theme\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/kuroir-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/kuroir\" {\n    export const isDark: false;\n    export const cssClass: \"ace-kuroir\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/merbivore-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/merbivore\" {\n    export const isDark: true;\n    export const cssClass: \"ace-merbivore\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/merbivore_soft-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/merbivore_soft\" {\n    export const isDark: true;\n    export const cssClass: \"ace-merbivore-soft\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/mono_industrial-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/mono_industrial\" {\n    export const isDark: true;\n    export const cssClass: \"ace-mono-industrial\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/monokai-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/monokai\" {\n    export const isDark: true;\n    export const cssClass: \"ace-monokai\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/nord_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/nord_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-nord-dark\";\n    export const cssText: string;\n    export const $selectionColorConflict: true;\n}\ndeclare module \"ace-code/src/theme/one_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/one_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-one-dark\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/pastel_on_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/pastel_on_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-pastel-on-dark\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/solarized_dark-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/solarized_dark\" {\n    export const isDark: true;\n    export const cssClass: \"ace-solarized-dark\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/solarized_light-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/solarized_light\" {\n    export const isDark: false;\n    export const cssClass: \"ace-solarized-light\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/sqlserver-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/sqlserver\" {\n    export const isDark: false;\n    export const cssClass: \"ace-sqlserver\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/terminal-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/terminal\" {\n    export const isDark: true;\n    export const cssClass: \"ace-terminal-theme\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/tomorrow-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/tomorrow\" {\n    export const isDark: false;\n    export const cssClass: \"ace-tomorrow\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night\" {\n    export const isDark: true;\n    export const cssClass: \"ace-tomorrow-night\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_blue-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_blue\" {\n    export const isDark: true;\n    export const cssClass: \"ace-tomorrow-night-blue\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_bright-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_bright\" {\n    export const isDark: true;\n    export const cssClass: \"ace-tomorrow-night-bright\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_eighties-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/tomorrow_night_eighties\" {\n    export const isDark: true;\n    export const cssClass: \"ace-tomorrow-night-eighties\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/twilight-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/twilight\" {\n    export const isDark: true;\n    export const cssClass: \"ace-twilight\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/vibrant_ink-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/vibrant_ink\" {\n    export const isDark: true;\n    export const cssClass: \"ace-vibrant-ink\";\n    export const cssText: string;\n}\ndeclare module \"ace-code/src/theme/xcode-css\" {\n    const _exports: string;\n    export = _exports;\n}\ndeclare module \"ace-code/src/theme/xcode\" {\n    export const isDark: false;\n    export const cssClass: \"ace-xcode\";\n    export const cssText: string;\n}\n"
  },
  {
    "path": "version.js",
    "content": "#!/usr/bin/env node\nvar x;\nx = require('./package');\nconsole.log(x.version);\n"
  }
]